Index: trunk/core/kernel/utility/unit_config_reader.php =================================================================== diff -u -N -r8104 -r8402 --- trunk/core/kernel/utility/unit_config_reader.php (.../unit_config_reader.php) (revision 8104) +++ trunk/core/kernel/utility/unit_config_reader.php (.../unit_config_reader.php) (revision 8402) @@ -203,6 +203,7 @@ */ function ParseConfigs() { + // 1. process normal configs and their dependencies $prioritized_configs = array(); foreach ($this->configData as $prefix => $config) { if (isset($config['ConfigPriority'])) { @@ -218,10 +219,15 @@ $clones = $this->postProcessConfig($prefix, 'Clones', 'prefix'); } + // 2. process prioritized configs and their dependencies asort($prioritized_configs); foreach ($prioritized_configs as $prefix => $priority) { $this->parseConfig($prefix); } + + foreach ($prioritized_configs as $prefix => $priority) { + $this->ProcessDependencies($prefix); + } } function AfterConfigRead() @@ -233,10 +239,57 @@ $this->Application->HandleEvent( new kEvent($prefix.':OnAfterConfigRead') ); $this->AfterConfigProcessed[] = $prefix; } - if ($this->StoreCache) $this->CacheParsedData(); + + if ($this->StoreCache) { + $this->processDynamicClones(); + $this->CacheParsedData(); + + if ($this->Application->isDebugMode(false) && constOn('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); + } + } + } } /** + * Re-reads all configs + * + */ + function ReReadConfigs() + { + $this->includeConfigFiles(MODULES_PATH); + $this->ParseConfigs(); + $this->AfterConfigRead(); + $this->processDynamicClones(); + } + + /** + * 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); + } + } + + // call OnAfterConfigRead for cloned configs + $new_clones = array_unique($new_clones); + foreach ($new_clones as $prefix) { + if (in_array($prefix, $this->AfterConfigProcessed)) continue; + $this->Application->HandleEvent( new kEvent($prefix.':OnAfterConfigRead') ); + $this->AfterConfigProcessed[] = $prefix; + } + } + + /** * Register nessasary classes * This method should only process the data which is cached! * @@ -349,15 +402,14 @@ // replacement templates defined in this config $this->Application->ReplacementTemplates = array_merge_recursive2($this->Application->ReplacementTemplates, $config['ReplacementTemplates']); } - - if ( $this->Application->isDebugMode(false) && constOn('DBG_VALIDATE_CONFIGS') && isset($config['TableName']) ) { - $this->ValidateConfig($prefix); - } } + function ValidateConfig($prefix) { global $debugger; + $config =& $this->configData[$prefix]; + $tablename = $config['TableName']; $float_types = Array ('float', 'double', 'numeric'); $conn =& $this->Application->GetADODBConnection(); @@ -369,8 +421,10 @@ safeDefine('DBG_RAISE_ON_WARNINGS', 1); return ; } + $res = $conn->Query('DESCRIBE '.$tablename); $config_link = $debugger->getFileLink(FULL_PATH.$this->prefixFiles[$config['Prefix']], 1, $config['Prefix']); + $error_messages = Array ( 'field_not_found' => 'Field %s exists in the database, but is not defined in config', 'default_missing' => 'Default value for field %s not set in config', @@ -380,6 +434,7 @@ 'invalid_default' => 'Default value for field %s%s not sync. to db (in config = %s, in db = %s)', 'type_missing' => 'Type definition for field %s missing in config', ); + $config_errors = Array (); $tablename = preg_replace('/^'.preg_quote(TABLE_PREFIX, '/').'(.*)/', '\\1', $tablename); // remove table prefix @@ -391,6 +446,7 @@ // skip multilingual fields continue; } + if (!array_key_exists ($f_name, $config['Fields'])) { $config_errors[] = sprintf($error_messages['field_not_found'], $f_name); } @@ -405,6 +461,7 @@ $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']) ) { @@ -419,9 +476,11 @@ $config_errors[] = sprintf($error_messages['not_null_error3'], $f_name); } } + if (!array_key_exists('type', $options)) { $config_errors[] = sprintf($error_messages['type_missing'], $f_name); } + if (!$default_missing) { if ($f_name == $config['IDField'] && $options['type'] != 'string' && $options['default'] !== 0) { $config_errors[] = sprintf($error_messages['invalid_default'], 'IDField ', $f_name, $this->varDump($options['default']), $this->varDump($field['Default'])); @@ -433,18 +492,19 @@ } } } + if ($config_errors) { $error_prefix = 'Config Error'.(count($config_errors) > 1 ? 's' : '').': for prefix '.$config_link.' ('.$tablename.') in unit config:
'; $config_errors = $error_prefix.'   '.implode('
   ', $config_errors); + $debugger->appendHTML($config_errors); - safeDefine('DBG_RAISE_ON_WARNINGS', 1); - } + safeDefine('DBG_RAISE_ON_WARNINGS', 1); + } } function varDump($value) { return ''.var_export($value, true).' of '.gettype($value); - } function ProcessDependencies($prefix) @@ -464,7 +524,7 @@ function postProcessConfig($prefix, $config_key, $dst_prefix_var) { $main_config =& $this->configData[$prefix]; - $sub_configs = getArrayValue($main_config, $config_key); + $sub_configs = isset($main_config[$config_key]) && $main_config[$config_key] ? $main_config[$config_key] : false; // getArrayValue($main_config, $config_key); if (!$sub_configs) { return array(); }