Page MenuHomeIn-Portal Phabricator

in-portal
No OneTemporary

File Metadata

Created
Tue, Feb 25, 5:31 AM

in-portal

Index: branches/5.3.x/core/kernel/utility/unit_config.php
===================================================================
--- branches/5.3.x/core/kernel/utility/unit_config.php (revision 15731)
+++ branches/5.3.x/core/kernel/utility/unit_config.php (revision 15732)
@@ -1,1029 +1,1380 @@
<?php
/**
* @version $Id$
* @package In-Portal
* @copyright Copyright (C) 1997 - 2012 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!');
/**
* TODO: Rename following settings
*
* ConfigMapping -> ConfigMappings
* StatusField -> StatusFields
* PermSection -> PermSections
*/
/**
* @method Array getFilterMenu(mixed $default = false)
* @method kUnitConfig setFilterMenu(Array $value)
*
* @method Array getConfigMapping(mixed $default = false)
* @method kUnitConfig setConfigMapping(Array $value)
*
*
* @method string getModuleFolder(mixed $default = false)
* @method kUnitConfig setModuleFolder(string $value)
*
* @method string getBasePath(mixed $default = false)
* @method kUnitConfig setBasePath(string $value)
*
* @method Array getEventHandlerClass(mixed $default = false)
* @method kUnitConfig setEventHandlerClass(Array $value)
*
* @method Array getTagProcessorClass(mixed $default = false)
* @method kUnitConfig setTagProcessorClass(Array $value)
*
* @method Array getItemClass(mixed $default = false)
* @method kUnitConfig setItemClass(Array $value)
*
* @method Array getListClass(mixed $default = false)
* @method kUnitConfig setListClass(Array $value)
*
* @method Array getValidatorClass(mixed $default = false)
* @method kUnitConfig setValidatorClass(Array $value)
*
* @method Array getQueryString(mixed $default = false)
* @method kUnitConfig setQueryString(Array $value)
*
* @method string getPermItemPrefix(mixed $default = false)
* @method kUnitConfig setPermItemPrefix(string $value)
*
* @method string getPermTabText(mixed $default = false)
* @method kUnitConfig setPermTabText(string $value)
*
* @method Array getPermSection(mixed $default = false)
* @method kUnitConfig setPermSection(Array $value)
*
* @method bool getAutoLoad(mixed $default = false)
* @method kUnitConfig setAutoLoad(bool $value)
*
* @method string getIDField(mixed $default = false)
* @method kUnitConfig setIDField(string $value)
*
* @method string getTableName(mixed $default = false)
* @method kUnitConfig setTableName(string $value)
*
* @method string getCustomDataTableName(mixed $default = false)
* @method kUnitConfig setCustomDataTableName(string $value)
*
* @method kUnitConfig setStatusField(Array $value)
*
* @method string getTitleField(mixed $default = false)
* @method kUnitConfig setTitleField(string $value)
*
* @method string getOrderField(mixed $default = false)
* @method kUnitConfig setOrderField(string $value)
*
* @method string getOwnerField(mixed $default = false)
* @method kUnitConfig setOwnerField(string $value)
*
* @method int getConfigPriority(mixed $default = false)
* @method kUnitConfig setConfigPriority(int $value)
*
* @method bool getCatalogItem(mixed $default = false)
* @method kUnitConfig setCatalogItem(bool $value)
*
* @method string getCatalogSelectorName(mixed $default = false)
* @method kUnitConfig setCatalogSelectorName(string $value)
*
* @method string getAdminTemplatePath(mixed $default = false)
* @method kUnitConfig setAdminTemplatePath(string $value)
*
* @method string getAdminTemplatePrefix(mixed $default = false)
* @method kUnitConfig setAdminTemplatePrefix(string $value)
*
* @method string getSearchConfigPostfix(mixed $default = false)
* @method kUnitConfig setSearchConfigPostfix(string $value)
*
* @method string getTitlePhrase(mixed $default = false)
* @method kUnitConfig setTitlePhrase(string $value)
*
* @method int getItemType(mixed $default = false)
* @method kUnitConfig setItemType(int $value)
*
* @method Array getStatisticsInfo(mixed $default = false)
* @method kUnitConfig setStatisticsInfo(Array $value)
*
* @method string getViewMenuPhrase(mixed $default = false)
* @method kUnitConfig setViewMenuPhrase(string $value)
*
* @method string getCatalogTabIcon(mixed $default = false)
* @method kUnitConfig setCatalogTabIcon(string $value)
*
* @method bool getCacheModRewrite(mixed $default = false)
* @method kUnitConfig setCacheModRewrite(bool $value)
*
* @method kUnitConfig setParentTableKey(mixed $value)
*
* @method kUnitConfig setForeignKey(mixed $value)
*
* @method string getConstrain(mixed $default = false)
* @method kUnitConfig setConstrain(string $value)
*
* @method bool getAutoDelete(mixed $default = false)
* @method kUnitConfig setAutoDelete(bool $value)
*
* @method bool getAutoClone(mixed $default = false)
* @method kUnitConfig setAutoClone(bool $value)
*
* @method string getParentPrefix(mixed $default = false)
* @method kUnitConfig setParentPrefix(string $value)
*
* @method bool getCheckSimulatniousEdit(mixed $default = false)
* @method kUnitConfig setCheckSimulatniousEdit(bool $value)
*
* @method bool getPortalStyleEnv(mixed $default = false)
* @method kUnitConfig setPortalStyleEnv(bool $value)
*
* @method int getRewritePriority(mixed $default = false)
* @method kUnitConfig setRewritePriority(int $value)
*
* @method Array getRewriteListener(mixed $default = false)
* @method kUnitConfig setRewriteListener(Array $value)
*
* @method bool getForceDontLogChanges(mixed $default = false)
* @method kUnitConfig setForceDontLogChanges(bool $value)
*
* @method Array getUserProfileMapping(mixed $default = false)
* @method kUnitConfig setUserProfileMapping(Array $value)
*
* @method bool getUsePendingEditing(mixed $default = false)
* @method kUnitConfig setUsePendingEditing(bool $value)
*
* @method string getNavigationSelectClause(mixed $default = false)
* @method kUnitConfig setNavigationSelectClause(string $value)
*
* @method bool getPopulateMlFields(bool $default = false)
* @method kUnitConfig setPopulateMlFields(bool $value)
*
* @method bool getLogChanges(bool $default = false)
* @method kUnitConfig setLogChanges(bool $value)
*
* @method int getFileCount(bool $default = false)
* @method kUnitConfig setFileCount(int $value)
*
* @method int getImageCount(bool $default = false)
* @method kUnitConfig setImageCount(int $value)
*
* @method string getDownloadHelperClass(bool $default = false)
* @method kUnitConfig setDownloadHelperClass(string $value)
*
* @method string getSectionPrefix(bool $default = false)
* @method kUnitConfig setSectionPrefix(string $value)
*
* @method bool getSiteConfigProcessed(bool $default = false)
* @method kUnitConfig setSiteConfigProcessed(bool $value)
*
*
* @method Array getRegisterClasses(mixed $default = false)
* @method kUnitConfig setRegisterClasses(Array $value)
* @method kUnitConfig addRegisterClasses(Array $value, string $name = null)
* @method kUnitConfig removeRegisterClasses(string $name = null)
*
* @method Array getScheduledTasks(mixed $default = false)
* @method Array getScheduledTaskByName(string $name, mixed $default = false)
* @method kUnitConfig setScheduledTasks(Array $value)
* @method kUnitConfig addScheduledTasks(Array $value, string $name = null)
* @method kUnitConfig removeScheduledTasks(string $name = null)
*
* @method Array getTitlePresets(mixed $default = false)
* @method Array getTitlePresetByName(string $name, mixed $default = false)
* @method kUnitConfig setTitlePresets(Array $value)
* @method kUnitConfig addTitlePresets(Array $value, string $name = null)
* @method kUnitConfig removeTitlePresets(string $name = null)
*
* @method Array getSections(mixed $default = false)
* @method Array getSectionByName(string $name, mixed $default = false)
* @method kUnitConfig setSections(Array $value)
* @method kUnitConfig addSections(Array $value, string $name = null)
* @method kUnitConfig removeSections(string $name = null)
*
* @method Array getFields(mixed $default = false)
* @method Array getFieldByName(string $name, mixed $default = false)
* @method kUnitConfig setFields(Array $value)
* @method kUnitConfig addFields(Array $value, string $name = null)
* @method kUnitConfig removeFields(string $name = null)
*
* @method Array getVirtualFields(mixed $default = false)
* @method Array getVirtualFieldByName(string $name, mixed $default = false)
* @method kUnitConfig setVirtualFields(Array $value)
* @method kUnitConfig addVirtualFields(Array $value, string $name = null)
* @method kUnitConfig removeVirtualFields(string $name = null)
*
* @method Array getGrids(mixed $default = false)
* @method Array getGridByName(string $name, mixed $default = false)
* @method kUnitConfig setGrids(Array $value)
* @method kUnitConfig addGrids(Array $value, string $name = null)
* @method kUnitConfig removeGrids(string $name = null)
*
* @method Array getHooks(mixed $default = false)
* @method kUnitConfig setHooks(Array $value)
* @method kUnitConfig addHooks(Array $value, string $name = null)
* @method kUnitConfig removeHooks(string $name = null)
*
* @method Array getAggregateTags(mixed $default = false)
* @method kUnitConfig setAggregateTags(Array $value)
* @method kUnitConfig addAggregateTags(Array $value, string $name = null)
* @method kUnitConfig removeAggregateTags(string $name = null)
*
* @method Array getEditTabPresets(mixed $default = false)
* @method Array getEditTabPresetByName(string $name, mixed $default = false)
* @method kUnitConfig setEditTabPresets(Array $value)
* @method kUnitConfig addEditTabPresets(Array $value, string $name = null)
* @method kUnitConfig removeEditTabPresets(string $name = null)
*
* @method Array getSubItems(mixed $default = false)
* @method kUnitConfig setSubItems(Array $value)
* @method kUnitConfig addSubItems(string $value, string $name = null)
* @method kUnitConfig removeSubItems(string $name = null)
*
* @method Array getCustomFields(mixed $default = false)
* @method string getCustomFieldByName(string $name, mixed $default = false)
* @method kUnitConfig setCustomFields(Array $value)
* @method kUnitConfig addCustomFields(Array $value, string $name = null)
* @method kUnitConfig removeCustomFields(string $name = null)
*
* @method Array getClones(mixed $default = false)
* @method Array getCloneByName(string $name, mixed $default = false)
* @method kUnitConfig setClones(Array $value)
* @method kUnitConfig addClones(Array $value, string $name = null)
* @method kUnitConfig removeClones(string $name = null)
*
* @method Array getProcessPrefixes(mixed $default = false)
* @method kUnitConfig setProcessPrefixes(Array $value)
* @method kUnitConfig addProcessPrefixes(string $value, string $name = null)
* @method kUnitConfig removeProcessPrefixes(string $name = null)
*
* @method Array getForms(mixed $default = false)
* @method Array getFormByName(string $name, mixed $default = false)
* @method kUnitConfig setForms(Array $value)
* @method kUnitConfig addForms(Array $value, string $name = null)
* @method kUnitConfig removeForms(string $name = null)
*
* @method Array getReplacementTemplates(mixed $default = false)
* @method string getReplacementTemplateByName(string $name, mixed $default = false)
* @method kUnitConfig setReplacementTemplates(Array $value)
* @method kUnitConfig addReplacementTemplates(string $value, string $name = null)
* @method kUnitConfig removeReplacementTemplates(string $name = null)
*
* @method Array getItemPropertyMappings(mixed $default = false)
* @method string getItemPropertyMappingByName(string $name, mixed $default = false)
* @method kUnitConfig setItemPropertyMappings(Array $value)
* @method kUnitConfig addItemPropertyMappings(string $value, string $name = null)
* @method kUnitConfig removeItemPropertyMappings(string $name = null)
*
* @method Array getSectionAdjustments(mixed $default = false)
* @method mixed getSectionAdjustmentByName(string $name, mixed $default = false)
* @method kUnitConfig setSectionAdjustments(Array $value)
* @method kUnitConfig addSectionAdjustments(mixed $value, string $name = null)
* @method kUnitConfig removeSectionAdjustments(string $name = null)
*
* @method Array getImportKeys(mixed $default = false)
* @method kUnitConfig setImportKeys(Array $value)
* @method kUnitConfig addImportKeys(mixed $value, string $name = null)
* @method kUnitConfig removeImportKeys(string $name = null)
*
*
* @method Array getCalculatedFieldSpecials(mixed $default = Array ())
* @method Array getCalculatedFieldsBySpecial(mixed $special, mixed $default = Array ())
* @method kUnitConfig setCalculatedFieldsBySpecial(mixed $special, Array $value)
* @method kUnitConfig addCalculatedFieldsBySpecial(mixed $special, mixed $value, string $name = null)
* @method kUnitConfig removeCalculatedFieldsBySpecial(mixed $special, string $name = null)
*
* @method Array getAggregatedCalculatedFieldSpecials(mixed $default = Array ())
* @method Array getAggregatedCalculatedFieldsBySpecial(mixed $special, mixed $default = Array ())
* @method kUnitConfig setAggregatedCalculatedFieldsBySpecial(mixed $special, Array $value)
* @method kUnitConfig addAggregatedCalculatedFieldsBySpecial(mixed $special, mixed $value, string $name = null)
* @method kUnitConfig removeAggregatedCalculatedFieldsBySpecial(mixed $special, string $name = null)
*
* @method Array getListSQLSpecials(mixed $default = Array ())
* @method string getListSQLsBySpecial(mixed $special, mixed $default = Array ())
* @method kUnitConfig setListSQLsBySpecial(mixed $special, string $value)
* @method kUnitConfig removeListSQLsBySpecial(mixed $special, string $name = null)
*
* @method Array getListSortingSpecials(mixed $default = Array ())
* @method Array getListSortingsBySpecial(mixed $special, mixed $default = Array ())
* @method kUnitConfig setListSortingsBySpecial(mixed $special, Array $value)
* @method kUnitConfig addListSortingsBySpecial(mixed $special, mixed $value, string $name = null)
* @method kUnitConfig removeListSortingsBySpecial(mixed $special, string $name = null)
*
* @method Array getItemSQLSpecials(mixed $default = Array ())
* @method string getItemSQLsBySpecial(mixed $special, mixed $default = Array ())
* @method kUnitConfig setItemSQLsBySpecial(mixed $special, string $value)
* @method kUnitConfig removeItemSQLsBySpecial(mixed $special, string $name = null)
*/
class kUnitConfig {
/**
+ * Reference to global kApplication instance
+ *
+ * @var kApplication
+ * @access protected
+ */
+ protected $Application = null;
+
+ /**
+ * Connection to database
+ *
+ * @var kDBConnection
+ * @access protected
+ */
+ protected $Conn = null;
+
+ /**
* Unit config prefix
*
* @var string
* @access protected
*/
protected $_prefix = '';
/**
+ * Filename, where unit config is stored
+ *
+ * @var string
+ * @access protected
+ */
+ protected $_filename = '';
+
+ /**
* Default unit config data
*
* @var Array
* @access protected
*/
protected static $_defaults = Array (
'ItemClass' => Array ('class' => 'kDBItem', 'file' => '', 'build_event' => 'OnItemBuild'),
'ListClass' => Array ('class' => 'kDBList', 'file' => '', 'build_event' => 'OnListBuild'),
'EventHandlerClass' => Array ('class' => 'kDBEventHandler', 'file' => '', 'build_event' => 'OnBuild'),
'TagProcessorClass' => Array ('class' => 'kDBTagProcessor', 'file' => '', 'build_event' => 'OnBuild'),
'AutoLoad' => true,
'QueryString' => Array (
1 => 'id',
2 => 'Page',
3 => 'PerPage',
4 => 'event',
5 => 'mode',
),
'ListSQLs' => Array (
'' => ' SELECT %1$s.* %2$s
FROM %1$s',
),
'Fields' => Array (),
);
/**
* Word endings, that are suffixed with "es" instead of just "s" during pluralisation
*
* @var string
* @access protected
*/
protected static $_singularEndingsRegExp = '/(x|s|z|sh|ch)$/';
/**
* Words, that ends with es/s, but are always singulars
*
* @var string
* @access protected
*/
protected static $_alwaysSingularRegExp = '/(class|LogChanges|ForceDontLogChanges|PopulateMlFields)$/i';
/**
* Unit config data
*
* @var Array
* @access protected
*/
protected $_data = Array ();
/**
* Unit config settings that can have different values based on special
*
* @var Array
* @access protected
*/
protected $_specialBased = Array (
'CalculatedFields', 'AggregatedCalculatedFields', 'ListSQLs', 'ListSortings', 'ItemSQLs',
);
/**
* Unit config settings, that allow data to be added without a key
*
* @var Array
* @access protected
*/
protected $_withoutKeys = Array (
'RegisterClasses', 'Hooks', 'AggregateTags'
);
/**
* Dynamic method name, that was called
*
* @var string
* @access protected
*/
protected $_currentMethodName = '';
/**
* Arguments given to dynamic method name, that was called
*
* @var Array
* @access protected
*/
protected $_currentArguments = Array ();
/**
* Creates new instance of kUnitConfig class
*
* @param string $prefix
* @param Array $defaults
* @param bool $use_global_defaults
* @access public
*/
public function __construct($prefix, $defaults = null, $use_global_defaults = true)
{
$this->_prefix = $prefix;
$merge_with = $use_global_defaults ? self::$_defaults : Array ();
$this->_data = array_merge($merge_with, isset($defaults) ? $defaults : Array ());
+
+ $this->Application =& kApplication::Instance();
+ $this->Conn =& $this->Application->GetADODBConnection();
+ }
+
+ /**
+ * Sets filename, where unit config is stored
+ *
+ * @param string $filename
+ * @return void
+ * @access public
+ */
+ public function setFilename($filename)
+ {
+ $this->_filename = $filename;
}
/**
* Returns unit config prefix
*
* @return string
* @access public
*/
public function getPrefix()
{
return $this->_prefix;
}
/**
* Ensures, that only unit config data is saved when object is serialized
*
* @return Array
* @access public
*/
public function __sleep()
{
- return Array ('_prefix', '_data');
+ return Array ('_prefix', '_data', 'Application', 'Conn');
}
/**
* Dumps unit config into a file
*
* @return void
* @access public
*/
public function dump()
{
kUtil::print_r($this->_data, 'Unit Config', true);
}
/**
* Returns unit config data in raw form
*
* @return Array
* @access public
*/
public function getRaw()
{
return $this->_data;
}
/**
* Processed dynamically created methods for changing unit config settings
*
* @param string $method_name
* @param Array $arguments
* @return mixed
* @throws InvalidArgumentException
* @throws RuntimeException
* @access public
*/
public function __call($method_name, $arguments)
{
// === regular ===
// get{SettingName}()
// set{SettingName}($value)
// add{SettingName}s(string $value, string $name = null)
// remove{SettingName}(string $name = null)
// === by special ===
// get{SettingName}Specials()
// get{SettingName}sBySpecial($special)
// set{SettingName}BySpecial($special, $value)
// add{SettingName}sBySpecial(string $special, Array $value, string $name = null)
// remove{SettingName}sBySpecial(string $special, $name = null)
if ( !preg_match('/^(get|set|add|remove)(.*?)(BySpecial|Specials|ByName)*$/', $method_name, $regs) ) {
throw new RuntimeException('Unknown method <strong>' . __CLASS__ . '::' . $this->_currentMethodName . '</strong>');
}
$this->_currentMethodName = $method_name;
$this->_currentArguments = $arguments;
$to_call = '_process' . ucfirst($regs[1]);
return $this->$to_call($regs[2], isset($regs[3]) ? $regs[3] : '');
}
/**
* Processes calls to "get*" methods
*
* @param string $setting_name
* @param string $suffix
* @return mixed
* @access protected
*/
protected function _processGet($setting_name, $suffix = '')
{
$is_plural = $this->_isPluralSetting($setting_name);
if ( $suffix == 'BySpecial' && $is_plural ) {
// get{SettingName}BySpecial($special, $default = false)
$this->_verifyArguments(Array ('special'));
return $this->getSetting($setting_name, $this->_getDefaultValue(1, Array ()), $this->_currentArguments[0]);
}
elseif ( $suffix == 'Specials' && !$is_plural ) {
// get{SettingName}Specials($default = Array ())
$result = $this->getSetting($this->_getPlural($setting_name), $this->_getDefaultValue(0, Array ()));
return array_keys($result);
}
elseif ( $suffix == 'ByName' && !$is_plural ) {
$sub_key = $this->_currentArguments[0];
$result = $this->getSetting($this->_getPlural($setting_name), Array ());
return isset($result[$sub_key]) ? $result[$sub_key] : $this->_getDefaultValue(1, false);
}
// get{SettingName}($default = false)
return $this->getSetting($setting_name, $this->_getDefaultValue(0, false));
}
/**
* Returns default value from given argument or false, when not passed
*
* @param int $arg_index
* @param mixed $default
* @return bool
* @access protected
*/
protected function _getDefaultValue($arg_index, $default = false)
{
return isset($this->_currentArguments[$arg_index]) ? $this->_currentArguments[$arg_index] : $default;
}
/**
* Processes calls to "set*" methods
*
* @param string $setting_name
* @param string $suffix
* @return kUnitConfig
* @access protected
*/
protected function _processSet($setting_name, $suffix = '')
{
$is_plural = $this->_isPluralSetting($setting_name);
if ( $suffix == 'BySpecial' && $is_plural ) {
// set{SettingName}BySpecial($special, $value)
$this->_verifyArguments(Array ('special', 'value'));
return $this->setSetting($setting_name, $this->_currentArguments[1], $this->_currentArguments[0]);
}
// set{SettingName}($value)
$this->_verifyArguments(Array ('value'));
return $this->setSetting($setting_name, $this->_currentArguments[0]);
}
/**
* Processes calls to "add*" method
*
* @param string $setting_name
* @param string $suffix
* @return kUnitConfig
* @access protected
* @throws InvalidArgumentException
*/
protected function _processAdd($setting_name, $suffix = '')
{
$arguments = $this->_currentArguments;
if ( !$this->_isPluralSetting($setting_name) ) {
throw new InvalidArgumentException('Setting "' . $setting_name . '" isn\'t plural');
}
if ( $suffix == 'BySpecial' ) {
// add{SettingName}BySpecial(string $special, string $value, string $name = null)
$this->_verifyArguments(Array ('special', 'value'));
if ( isset($arguments[2]) ) {
// add a single value
$this->_addToSetting($this->_getSingular($setting_name), $arguments[1], $arguments[2], $arguments[0]);
}
else {
// add multiple values
$this->_addToSetting($setting_name, $arguments[1], null, $arguments[0]);
}
}
else {
// add{SettingName}(string $value, string $name = null)
$this->_verifyArguments(Array ('value'));
if ( isset($arguments[1]) ) {
// add a single value
$this->_addToSetting($this->_getSingular($setting_name), $arguments[0], $arguments[1]);
}
else {
// add multiple value
$this->_addToSetting($setting_name, $arguments[0], null);
}
}
return $this;
}
/**
* Adds a value to a setting
*
* @param string $name
* @param mixed $value
* @param string $array_key
* @param string $special
* @return kUnitConfig
* @throws InvalidArgumentException
*/
protected function _addToSetting($name, $value, $array_key, $special = null)
{
if ( $this->_isPluralSetting($name) ) {
// multiple values given - merge with current values
if ( !is_array($value) ) {
throw new InvalidArgumentException('Argument $value must be an array');
}
$result = $this->getSetting($name, Array (), $special);
$this->setSetting($name, array_merge($result, $value), $special);
}
else {
// single value given
$result = $this->getSetting($this->_getPlural($name), Array (), $special);
if ( $this->_isWithoutKeySetting($name) ) {
$result[] = $value;
}
else {
$result[$array_key] = $value;
}
$this->setSetting($this->_getPlural($name), $result, $special);
}
return $this;
}
/**
* Processes calls to "remove*" method
*
* @param string $setting_name
* @param string $suffix
* @return kUnitConfig
* @access protected
* @throws InvalidArgumentException
*/
protected function _processRemove($setting_name, $suffix = '')
{
$arguments = $this->_currentArguments;
if ( !$this->_isPluralSetting($setting_name) ) {
throw new InvalidArgumentException('Setting "' . $setting_name . '" isn\'t plural');
}
if ( $suffix == 'BySpecial' ) {
// remove{SettingName}BySpecial(string $special, string $name = null)
$this->_verifyArguments(Array ('special'));
if ( isset($arguments[1]) ) {
// remove single value
$this->_removeFromSetting($this->_getSingular($setting_name), $arguments[1], $arguments[0]);
}
else {
// remove multiple value
$this->_removeFromSetting($setting_name, null, $arguments[0]);
}
}
else {
// remove{SettingName}(string $name = null)
if ( isset($arguments[0]) ) {
// remove single value
$this->_removeFromSetting($this->_getSingular($setting_name), $arguments[0]);
}
else {
// remove multiple values
$this->_removeFromSetting($setting_name, null);
}
}
return $this;
}
/**
* Removes a value from a setting
*
* @param string $name
* @param string $array_key
* @param string $special
* @return kUnitConfig
* @access protected
* @throws RuntimeException
*/
protected function _removeFromSetting($name, $array_key = null, $special = null)
{
if ( $this->_isPluralSetting($name) ) {
// remove multiple values
if ( $this->getSetting($name, false, $special) !== false ) {
$this->setSetting($name, null, $special);
}
}
else {
// remove single value
if ( $this->_isWithoutKeySetting($name) ) {
throw new RuntimeException('Unable to change setting without key');
}
$result = $this->getSetting($this->_getPlural($name), false, $special);
if ( $result !== false ) {
unset($result[$array_key]);
$this->setSetting($this->_getPlural($name), $result, $special);
}
}
return $this;
}
/**
* Verifies argument count given
*
* @param Array $argument_names
* @return void
* @access protected
* @throws InvalidArgumentException
*/
protected function _verifyArguments($argument_names)
{
if ( count($this->_currentArguments) < count($argument_names) ) {
throw new InvalidArgumentException('Method <strong>' . __CLASS__ . '::' . $this->_currentMethodName . '</strong> expects following arguments: <strong>$' . implode('</strong>, <strong>$', $argument_names) . '</strong>');
}
}
/**
* Returns setting value by name and filter by special (if passed)
*
* @param string $name
* @param mixed $default
* @param string|kBase $special
* @return mixed
* @access public
*/
public function getSetting($name, $default = false, $special = null)
{
if ( in_array($name, $this->_specialBased) && isset($special) ) {
$use_special = $this->_guessSpecial($name, $special);
return isset($this->_data[$name][$use_special]) ? $this->_data[$name][$use_special] : $default;
}
return isset($this->_data[$name]) ? $this->_data[$name] : $default;
}
/**
* Changes value of a setting
*
* @param string $name
* @param mixed $value
* @param string|kBase $special
* @return kUnitConfig
* @access public
*/
public function setSetting($name, $value, $special = null)
{
if ( in_array($name, $this->_specialBased) && isset($special) ) {
if ( !isset($this->_data[$name]) ) {
$this->_data[$name] = Array ();
}
$use_special = $this->_guessSpecial($name, $special);
if ( !isset($value) ) {
unset($this->_data[$name][$use_special]);
}
else {
$this->_data[$name][$use_special] = $value;
}
}
else {
if ( !isset($value) ) {
unset($this->_data[$name]);
}
else {
$this->_data[$name] = $value;
}
}
return $this;
}
/**
* Detects settings, that accept arrays
*
* @param string $name
* @return bool
* @access protected
*/
protected function _isPluralSetting($name)
{
if ( preg_match(self::$_alwaysSingularRegExp, $name) ) {
// simplified exceptions
return false;
}
return preg_match('/(es|s)$/', $name);
}
/**
* Detects anonymous settings
*
* @param string $name
* @return bool
* @access protected
*/
protected function _isWithoutKeySetting($name)
{
return in_array($this->_getPlural($name), $this->_withoutKeys);
}
/**
* Returns plural form given word
*
* @param string $name
* @return string
* @access protected
*/
protected function _getPlural($name)
{
return preg_match(self::$_singularEndingsRegExp, $name) ? $name . 'es' : $name . 's';
}
/**
* Returns singular form of given word
*
* @param $name
* @return mixed
* @throws InvalidArgumentException
*/
protected function _getSingular($name)
{
if ( !$this->_isPluralSetting($name) ) {
throw new InvalidArgumentException('Setting "' . $name . '" isn\'t plural');
}
return preg_replace('/(es|s)$/', '', $name);
}
/**
* Guesses special to be used by event
*
* @param string $setting_name
* @param string|kBase $special
* @return string
* @access protected
*/
protected function _guessSpecial($setting_name, $special)
{
$use_special = $special instanceof kBase ? $special->Special : $special;
$value = $this->getSetting($setting_name, Array ());
return isset($value[$use_special]) ? $use_special : '';
}
/**
* Adds new tab to existing edit tab preset
*
* @param string $preset_name
* @param Array $value
* @param string $name
* @return kUnitConfig
* @throws InvalidArgumentException
* @access public
*/
public function addEditTabPresetTabs($preset_name, $value, $name = null)
{
$preset = $this->getEditTabPresetByName($preset_name, false);
if ( $preset === false ) {
throw new InvalidArgumentException('Edit tab preset "' . $preset_name . '" not defined in "' . $this->_prefix . '" unit config');
}
if ( isset($name) ) {
$preset[$name] = $value;
}
else {
$preset = array_merge($preset, $value);
}
$this->addEditTabPresets($preset, $preset_name);
return $this;
}
public function addGridFields($grid_name, $value, $name = null)
{
$grid = $this->getGridByName($grid_name, false);
if ( $grid === false ) {
throw new InvalidArgumentException('Grid "' . $grid_name . '" not defined in "' . $this->_prefix . '" unit config');
}
if ( isset($name) ) {
$grid['Fields'][$name] = $value;
}
else {
$grid['Fields'] = array_merge($grid['Fields'], $value);
}
$this->addGrids($grid, $grid_name);
return $this;
}
/**
* Returns individual permission section
*
* @param string $name
* @param Array $default
* @return Array
* @access public
* @todo Rename setting to plural form and them remove this method
*/
public function getPermSectionByName($name, $default = Array ())
{
$perm_sections = $this->getPermSection(Array ());
return isset($perm_sections[$name]) ? $perm_sections[$name] : $default;
}
/**
* Returns foreign key by given prefix
*
* @param string $parent_prefix
* @param mixed $default
* @return string|bool
* @access public
*/
public function getForeignKey($parent_prefix = null, $default = false)
{
return $this->_getSettingByPrefix('ForeignKey', $parent_prefix, $default);
}
/**
* Returns parent table key by given prefix
*
* @param string $parent_prefix
* @param mixed $default
* @return string|bool
* @access public
*/
public function getParentTableKey($parent_prefix = null, $default = false)
{
return $this->_getSettingByPrefix('ParentTableKey', $parent_prefix, $default);
}
/**
* Returns value of a setting by prefix (special workaround for non-special settings)
*
* @param string $name
* @param string $prefix
* @param mixed $default
* @return mixed
* @access protected
*/
protected function _getSettingByPrefix($name, $prefix = null, $default = false)
{
$value = $this->getSetting($name, $default);
if ( !is_array($value) || !isset($prefix) ) {
return $value;
}
return isset($value[$prefix]) ? $value[$prefix] : $default;
}
/**
* Returns status field with option to get first field only
*
* @param bool $first_only
* @param mixed $default
* @return mixed
* @access public
*/
public function getStatusField($first_only = false, $default = false)
{
$value = $this->getSetting('StatusField', $default);
return $first_only ? $value[0] : $value;
}
+
+ /**
+ * Register necessary classes
+ * This method should only process the data which is cached!
+ *
+ * @return void
+ * @access public
+ */
+ public function parse()
+ {
+ $this->_parseClasses();
+ $this->_parseScheduledTasks();
+ $this->_parseHooks();
+ $this->_parseAggregatedTags();
+ }
+
+ protected function _parseClasses()
+ {
+ $register_classes = $this->_getClasses();
+
+ foreach ($register_classes as $class_info) {
+ $this->Application->registerClass(
+ $class_info['class'],
+ $this->getBasePath() . DIRECTORY_SEPARATOR . $class_info['file'],
+ $class_info['pseudo']
+ );
+
+ if ( isset($class_info['build_event']) && $class_info['build_event'] && $class_info['build_event'] != 'OnBuild' ) {
+ $this->Application->delayUnitProcessing('registerBuildEvent', Array ($class_info['pseudo'], $class_info['build_event']));
+ }
+ }
+ }
+
+ protected function _getClasses()
+ {
+ $register_classes = $this->getRegisterClasses();
+ $class_params = Array ('ItemClass', 'ListClass', 'EventHandlerClass', 'TagProcessorClass');
+
+ foreach ($class_params as $param_name) {
+ $value = $this->getSetting($param_name);
+
+ if ( !$value ) {
+ continue;
+ }
+
+ $value['pseudo'] = $this->_getPseudoByOptionName($param_name);
+ $this->setSetting($param_name, $value);
+
+ $register_classes[] = $value;
+ }
+
+ return $register_classes;
+ }
+
+ protected function _getPseudoByOptionName($option_name)
+ {
+ $pseudo_class_map = Array (
+ 'ItemClass' => '%s',
+ 'ListClass' => '%s_List',
+ 'EventHandlerClass' => '%s_EventHandler',
+ 'TagProcessorClass' => '%s_TagProcessor'
+ );
+
+ return sprintf($pseudo_class_map[$option_name], $this->_prefix);
+ }
+
+ protected function _parseScheduledTasks()
+ {
+ if ( !$this->getScheduledTasks() ) {
+ return ;
+ }
+
+ $scheduled_tasks = $this->getScheduledTasks();
+
+ 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, $this->_prefix . ':' . $scheduled_task_info['EventName'], $scheduled_task_info['RunSchedule'], $event_status));
+ }
+ }
+
+ protected function _parseHooks()
+ {
+ $hooks = $this->getHooks();
+
+ if ( !$hooks ) {
+ return;
+ }
+
+ foreach ($hooks as $hook) {
+ if ( $this->getParentPrefix() && ($hook['HookToPrefix'] == $this->getParentPrefix()) ) {
+ trigger_error('Deprecated Hook Usage [prefix: <strong>' . $this->_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'] = $this->_prefix;
+ }
+
+ if ( $this->getParentPrefix() ) {
+ // new: allow to set hook to parent prefix what ever it is
+ if ( $hook['HookToPrefix'] == '#PARENT#' ) {
+ $hook['HookToPrefix'] = $this->getParentPrefix();
+ }
+
+ if ( $hook['DoPrefix'] == '#PARENT#' ) {
+ $hook['DoPrefix'] = $this->getParentPrefix();
+ }
+ }
+ 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'] == '' ? $this->_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()
+ {
+ $aggregated_tags = $this->getAggregateTags();
+
+ if ( !$aggregated_tags ) {
+ return;
+ }
+
+ foreach ($aggregated_tags as $aggregate_tag) {
+ if ( $this->getParentPrefix() ) {
+ if ( $aggregate_tag['AggregateTo'] == $this->getParentPrefix() ) {
+ trigger_error('Deprecated Aggregate Tag Usage [prefix: <b>' . $this->_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'] = $this->getParentPrefix();
+ }
+ }
+
+ $aggregate_tag['LocalPrefix'] = $this->_prefix;
+ $this->Application->delayUnitProcessing('registerAggregateTag', Array ($aggregate_tag));
+ }
+ }
+
+ public function validate()
+ {
+ global $debugger;
+
+ $table_name = $this->getTableName();
+ $float_types = Array ('float', 'double', 'numeric');
+
+ $table_found = $this->Conn->Query('SHOW TABLES LIKE "' . $table_name . '"');
+
+ 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>$table_name</strong> missing, but prefix <b>" . $this->_prefix . "</b> requires it!");
+ $debugger->WarningCount++;
+
+ return;
+ }
+
+ $res = $this->Conn->Query('DESCRIBE ' . $table_name);
+ $config_link = $debugger->getFileLink(FULL_PATH . $this->_filename, 1, $this->_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 ();
+ $fields = $this->getFields();
+ $table_name = preg_replace('/^' . preg_quote(TABLE_PREFIX, '/') . '(.*)/', '\\1', $table_name); // remove table prefix
+
+ if ( $fields ) {
+ // validate unit config field declaration in relation to database table structure
+ foreach ($res as $field) {
+ $f_name = $field['Field'];
+
+ if ( preg_match('/l[\d]+_[\w]/', $f_name) ) {
+ // skip multilingual fields
+ continue;
+ }
+
+ if ( !array_key_exists($f_name, $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 = $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 != $this->getIDField() && !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 == $this->getIDField() && $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
+ $virtual_fields = $this->getVirtualFields();
+
+ if ( $virtual_fields ) {
+ foreach ($virtual_fields 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 ( $this->getCalculatedFieldSpecials() ) {
+ foreach ($this->getCalculatedFieldSpecials() as $special) {
+ foreach ($this->getCalculatedFieldsBySpecial($special) as $calculated_field => $calculated_field_expr) {
+ if ( !isset($virtual_fields[$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> (' . $table_name . ') 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++;
+ }
+ }
+
+ protected function _varDump($value)
+ {
+ return '<strong>' . var_export($value, true) . '</strong> of ' . gettype($value);
+ }
}
Index: branches/5.3.x/core/kernel/utility/unit_config_reader.php
===================================================================
--- branches/5.3.x/core/kernel/utility/unit_config_reader.php (revision 15731)
+++ branches/5.3.x/core/kernel/utility/unit_config_reader.php (revision 15732)
@@ -1,1009 +1,691 @@
<?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|kUnitConfig[]
* @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 ) {
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 ( $config->getConfigPriority() !== false ) {
$prioritized_configs[$prefix] = $config->getConfigPriority();
continue;
}
- $this->parseConfig($prefix);
+ $config->parse();
}
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);
+ $this->configData[$prefix]->parse();
}
}
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 ( !$config->getTableName() ) {
continue;
}
- $this->ValidateConfig($prefix);
+ $config->validate();
}
}
}
}
/**
* 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 ( $config->getReplacementTemplates() ) {
$this->Application->ReplacementTemplates = array_merge($this->Application->ReplacementTemplates, $config->getReplacementTemplates());
}
// collect rewrite listeners
if ( $config->getRewriteListener() ) {
$rewrite_listeners = $config->getRewriteListener();
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 = $config->getRewritePriority();
$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->getBasePath() . 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 ( !$config->getScheduledTasks() ) {
- return ;
- }
-
- $scheduled_tasks = $config->getScheduledTasks();
-
- 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->getPrefix() . ':' . $scheduled_task_info['EventName'], $scheduled_task_info['RunSchedule'], $event_status ));
- }
- }
-
- protected function parseHooks($prefix)
- {
- $config = $this->configData[$prefix];
-
- if ( !$config->getHooks() ) {
- return;
- }
-
- $hooks = $config->getHooks();
-
- foreach ($hooks as $hook) {
- if ( $config->getParentPrefix() && ($hook['HookToPrefix'] == $config->getParentPrefix()) ) {
- trigger_error('Deprecated Hook Usage [prefix: <strong>' . $config->getPrefix() . '</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->getPrefix();
- }
-
- if ( $config->getParentPrefix() ) {
- // new: allow to set hook to parent prefix what ever it is
- if ( $hook['HookToPrefix'] == '#PARENT#' ) {
- $hook['HookToPrefix'] = $config->getParentPrefix();
- }
-
- if ( $hook['DoPrefix'] == '#PARENT#' ) {
- $hook['DoPrefix'] = $config->getParentPrefix();
- }
- }
- 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->getPrefix() : $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 = $config->getAggregateTags();
-
- if ( !$aggregated_tags ) {
- return;
- }
-
- foreach ($aggregated_tags as $aggregate_tag) {
- if ( $config->getParentPrefix() ) {
- if ( $aggregate_tag['AggregateTo'] == $config->getParentPrefix() ) {
- trigger_error('Deprecated Aggregate Tag Usage [prefix: <b>' . $config->getPrefix() . '</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->getParentPrefix();
- }
- }
-
- $aggregate_tag['LocalPrefix'] = $config->getPrefix();
- $this->Application->delayUnitProcessing('registerAggregateTag', Array ($aggregate_tag));
- }
- }
-
- function ValidateConfig($prefix)
- {
- global $debugger;
-
- $config = $this->configData[$prefix];
-
- $table_name = $config->getTableName();
- $float_types = Array ('float', 'double', 'numeric');
-
- $table_found = $this->Conn->Query('SHOW TABLES LIKE "' . $table_name . '"');
- 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>$table_name</strong> missing, but prefix <b>" . $prefix . "</b> requires it!");
- $debugger->WarningCount++;
-
- return;
- }
-
- $res = $this->Conn->Query('DESCRIBE ' . $table_name);
- $config_link = $debugger->getFileLink(FULL_PATH . $this->prefixFiles[$prefix], 1, $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 ();
- $fields = $config->getFields();
- $table_name = preg_replace('/^' . preg_quote(TABLE_PREFIX, '/') . '(.*)/', '\\1', $table_name); // remove table prefix
-
- if ( $fields ) {
- // validate unit config field declaration in relation to database table structure
- foreach ($res as $field) {
- $f_name = $field['Field'];
-
- if ( preg_match('/l[\d]+_[\w]/', $f_name) ) {
- // skip multilingual fields
- continue;
- }
-
- if ( !array_key_exists($f_name, $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 = $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->getIDField() && !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->getIDField() && $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 ( $config->getVirtualFields() ) {
- foreach ($config->getVirtualFields() 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 ( $config->getCalculatedFieldSpecials() ) {
- $virtual_fields = $config->getVirtualFields();
-
- foreach ($config->getCalculatedFieldSpecials() as $special) {
- foreach ($config->getCalculatedFieldsBySpecial($special) as $calculated_field => $calculated_field_expr) {
- if ( !isset($virtual_fields[$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> (' . $table_name . ') 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 = $main_config->getSetting($config_key);
if ( !$sub_configs ) {
return Array ();
}
$processed = Array ();
$main_config->setSetting($config_key, null);
foreach ($sub_configs as $sub_prefix => $sub_config_data) {
if ( $config_key == 'AggregateConfigs' && !isset($this->configData[$sub_prefix]) ) {
$this->loadConfig($sub_prefix);
}
$sub_config_data['Prefix'] = $sub_prefix;
$sub_config_base = $this->configData[$$dst_prefix_var]->getRaw();
$sub_config = new kUnitConfig($sub_prefix, kUtil::array_merge_recursive($sub_config_base, $sub_config_data));
$this->configData[$sub_prefix] = $sub_config;
// when merging empty array to non-empty results non-empty array, but empty is required
foreach ($sub_config_data as $sub_key => $sub_value) {
if ( !$sub_value && is_array($sub_value) ) {
$sub_config->setSetting($sub_key, null);
}
}
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);
+ $this->configData[$sub_prefix]->parse();
}
array_push($processed, $sub_prefix);
}
if ( !$prefix ) {
// configs, that used only for cloning & not used itself
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 ) {
/* @var $config kUnitConfig|Array */
if ( isset($config) && $config ) {
// config file is included for 1st time -> save it's content for future processing
if ( !is_object($config) ) {
$prefix = array_key_exists('Prefix', $config) ? $config['Prefix'] : '';
$config = new kUnitConfig($prefix, $config);
}
else {
$prefix = $config->getPrefix();
}
preg_match($this->_moduleFolderRegExp, $filename, $regs);
$config->setModuleFolder(str_replace(DIRECTORY_SEPARATOR, '/', $regs[1]));
$config->setBasePath(dirname(FULL_PATH . $filename));
+ $config->setFilename($filename);
if ( $config->getAdminTemplatePath() !== false ) {
// append template base folder for admin templates path of this prefix
$module_templates = $regs[1] == 'core' ? '' : substr($regs[1], 8) . '/';
$config->setAdminTemplatePath($module_templates . $config->getAdminTemplatePath());
}
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
+ // hooks to it can define their clones
$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);
}
}
/**
* Returns unit config for given prefix
*
* @param string $prefix
* @return kUnitConfig
* @access public
*/
public function getUnitConfig($prefix = null)
{
if ( !isset($this->configData[$prefix]) ) {
$this->loadConfig($prefix);
}
return $this->configData[$prefix];
}
/**
* Returns prefixes of unit configs, that were registered
*
* @return Array
* @access public
*/
public function getPrefixes()
{
return array_keys($this->configData);
}
- protected function getClasses($prefix)
- {
- $config = $this->configData[$prefix];
- $class_params = Array ('ItemClass', 'ListClass', 'EventHandlerClass', 'TagProcessorClass');
- $register_classes = $config->getRegisterClasses();
-
- foreach ($class_params as $param_name) {
- $value = $config->getSetting($param_name);
-
- if ( !$value ) {
- continue;
- }
-
- $value['pseudo'] = $this->getPseudoByOptionName($param_name, $prefix);
- $config->setSetting($param_name, $value);
-
- $register_classes[] = $value;
- }
-
- 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) {
$callback_function[0]->$callback_function[1]($prefix, $config, $params);
}
}
}
\ No newline at end of file

Event Timeline