Index: trunk/core/units/config_search/config_search_event_handler.php =================================================================== diff -u -N -r3999 -r4000 --- trunk/core/units/config_search/config_search_event_handler.php (.../config_search_event_handler.php) (revision 3999) +++ trunk/core/units/config_search/config_search_event_handler.php (.../config_search_event_handler.php) (revision 4000) @@ -79,7 +79,6 @@ { $custom_field =& $event->MasterEvent->getObject(); - $sql = 'SELECT Module FROM '.TABLE_PREFIX.'ItemTypes WHERE ItemType = '.$custom_field->GetDBField('Type'); Index: trunk/kernel/units/custom_fields/custom_fields_event_handler.php =================================================================== diff -u -N -r3983 -r4000 --- trunk/kernel/units/custom_fields/custom_fields_event_handler.php (.../custom_fields_event_handler.php) (revision 3983) +++ trunk/kernel/units/custom_fields/custom_fields_event_handler.php (.../custom_fields_event_handler.php) (revision 4000) @@ -55,6 +55,23 @@ $this->Conn->Query($sql); } + /** + * Enter description here... + * + * @param kEvent $event + */ + function OnSaveCustomField(&$event) + { + $object =& $event->getObject(); + $sql = 'SELECT Prefix + FROM '.TABLE_PREFIX.'ItemTypes + WHERE ItemType = '.$object->GetDBField('Type'); + $main_prefix = $this->Conn->GetOne($sql); + + $ml_helper =& $this->Application->recallObject('kMultiLanguageHelper'); + $ml_helper->createFields($main_prefix.'-cdata'); + } + function OnMassDelete(&$event) { parent::OnMassDelete($event); Index: trunk/core/units/custom_fields/custom_fields_event_handler.php =================================================================== diff -u -N -r3983 -r4000 --- trunk/core/units/custom_fields/custom_fields_event_handler.php (.../custom_fields_event_handler.php) (revision 3983) +++ trunk/core/units/custom_fields/custom_fields_event_handler.php (.../custom_fields_event_handler.php) (revision 4000) @@ -55,6 +55,23 @@ $this->Conn->Query($sql); } + /** + * Enter description here... + * + * @param kEvent $event + */ + function OnSaveCustomField(&$event) + { + $object =& $event->getObject(); + $sql = 'SELECT Prefix + FROM '.TABLE_PREFIX.'ItemTypes + WHERE ItemType = '.$object->GetDBField('Type'); + $main_prefix = $this->Conn->GetOne($sql); + + $ml_helper =& $this->Application->recallObject('kMultiLanguageHelper'); + $ml_helper->createFields($main_prefix.'-cdata'); + } + function OnMassDelete(&$event) { parent::OnMassDelete($event); Index: trunk/kernel/units/languages/languages_event_handler.php =================================================================== diff -u -N -r3316 -r4000 --- trunk/kernel/units/languages/languages_event_handler.php (.../languages_event_handler.php) (revision 3316) +++ trunk/kernel/units/languages/languages_event_handler.php (.../languages_event_handler.php) (revision 4000) @@ -10,51 +10,12 @@ */ function OnReflectMultiLingualFields($event) { - $table_name = $this->Application->getUnitOption($event->Prefix,'TableName'); - $languages_count = $this->Conn->GetOne('SELECT COUNT(*) FROM '.$table_name); - $languages_count = $languages_count + 5 - ( $languages_count % 5 ? ($languages_count % 5) : 5 ); - - $sqls = Array(); - + $ml_helper =& $this->Application->recallObject('kMultiLanguageHelper'); + $unit_config_reader =& $this->Application->recallObject('kUnitConfigReader'); - - foreach($unit_config_reader->configData as $prefix => $config_data) - { - $table_name = getArrayValue($config_data,'TableName'); - $fields = getArrayValue($config_data,'Fields'); - if(!($table_name && $fields) ) continue; - - foreach($fields as $field_name => $field_options) - { - if( isset($field_options['formatter']) && $field_options['formatter'] == 'kMultiLanguage' ) - { - $describe = $this->Conn->Query('DESCRIBE '.$table_name.' \'l%_'.$field_name.'\''); - $created_count = count($describe); - if(!$describe) - { - // no multilingual fields at all - $describe = $this->Conn->Query('DESCRIBE '.$table_name.' \''.$field_name.'\''); - $created_count = 0; - } - if(!$describe) continue; - - $field_mask = 'l%s_'.$field_name.' '.$describe[0]['Type']; - $create_count = $languages_count - $created_count; - if($create_count > 0) - { - $sqls[] = 'ALTER TABLE '.$table_name.( $this->generateAlterSQL($field_mask, $created_count + 1, $create_count) ); - } - } - } + foreach ($unit_config_reader->configData as $prefix => $config_data) { + $ml_helper->createFields($prefix); } - - if($sqls) - { - foreach ($sqls as $sql_query) - { - $this->Conn->Query($sql_query); - } - } } /** @@ -72,31 +33,6 @@ } /** - * Returns ALTER statement part for adding required fields to table - * - * @param string $field_mask sql mask for creating field with correct definition (type & size) - * @param int $start_index add new fields starting from this index - * @param int $create_count create this much new multilingual field translations - * @return string - */ - function generateAlterSQL($field_mask, $start_index, $create_count) - { - $i_count = $start_index + $create_count; - $ret = ''; - while($start_index < $i_count) - { - list($prev_field,$type) = explode(' ', sprintf($field_mask, $start_index-1) ); - if( substr($prev_field, 0, 3) == 'l0_' ) - { - $prev_field = substr( $prev_field, 3, strlen($prev_field) ); - } - $ret .= ' ADD COLUMN '.sprintf($field_mask,$start_index).' AFTER `'.$prev_field.'`, '; - $start_index++; - } - return preg_replace('/, $/',';',$ret); - } - - /** * Copy labels from another language * * @param kEvent $event Index: trunk/core/units/languages/languages_event_handler.php =================================================================== diff -u -N -r3316 -r4000 --- trunk/core/units/languages/languages_event_handler.php (.../languages_event_handler.php) (revision 3316) +++ trunk/core/units/languages/languages_event_handler.php (.../languages_event_handler.php) (revision 4000) @@ -10,51 +10,12 @@ */ function OnReflectMultiLingualFields($event) { - $table_name = $this->Application->getUnitOption($event->Prefix,'TableName'); - $languages_count = $this->Conn->GetOne('SELECT COUNT(*) FROM '.$table_name); - $languages_count = $languages_count + 5 - ( $languages_count % 5 ? ($languages_count % 5) : 5 ); - - $sqls = Array(); - + $ml_helper =& $this->Application->recallObject('kMultiLanguageHelper'); + $unit_config_reader =& $this->Application->recallObject('kUnitConfigReader'); - - foreach($unit_config_reader->configData as $prefix => $config_data) - { - $table_name = getArrayValue($config_data,'TableName'); - $fields = getArrayValue($config_data,'Fields'); - if(!($table_name && $fields) ) continue; - - foreach($fields as $field_name => $field_options) - { - if( isset($field_options['formatter']) && $field_options['formatter'] == 'kMultiLanguage' ) - { - $describe = $this->Conn->Query('DESCRIBE '.$table_name.' \'l%_'.$field_name.'\''); - $created_count = count($describe); - if(!$describe) - { - // no multilingual fields at all - $describe = $this->Conn->Query('DESCRIBE '.$table_name.' \''.$field_name.'\''); - $created_count = 0; - } - if(!$describe) continue; - - $field_mask = 'l%s_'.$field_name.' '.$describe[0]['Type']; - $create_count = $languages_count - $created_count; - if($create_count > 0) - { - $sqls[] = 'ALTER TABLE '.$table_name.( $this->generateAlterSQL($field_mask, $created_count + 1, $create_count) ); - } - } - } + foreach ($unit_config_reader->configData as $prefix => $config_data) { + $ml_helper->createFields($prefix); } - - if($sqls) - { - foreach ($sqls as $sql_query) - { - $this->Conn->Query($sql_query); - } - } } /** @@ -72,31 +33,6 @@ } /** - * Returns ALTER statement part for adding required fields to table - * - * @param string $field_mask sql mask for creating field with correct definition (type & size) - * @param int $start_index add new fields starting from this index - * @param int $create_count create this much new multilingual field translations - * @return string - */ - function generateAlterSQL($field_mask, $start_index, $create_count) - { - $i_count = $start_index + $create_count; - $ret = ''; - while($start_index < $i_count) - { - list($prev_field,$type) = explode(' ', sprintf($field_mask, $start_index-1) ); - if( substr($prev_field, 0, 3) == 'l0_' ) - { - $prev_field = substr( $prev_field, 3, strlen($prev_field) ); - } - $ret .= ' ADD COLUMN '.sprintf($field_mask,$start_index).' AFTER `'.$prev_field.'`, '; - $start_index++; - } - return preg_replace('/, $/',';',$ret); - } - - /** * Copy labels from another language * * @param kEvent $event Index: trunk/core/kernel/application.php =================================================================== diff -u -N -r3863 -r4000 --- trunk/core/kernel/application.php (.../application.php) (revision 3863) +++ trunk/core/kernel/application.php (.../application.php) (revision 4000) @@ -1389,14 +1389,15 @@ * * @param string $prefix * @param string $option + * @param mixed $default * @return string * @access public * @author Alex */ - function getUnitOption($prefix,$option) + function getUnitOption($prefix, $option, $default = false) { $unit_config_reader =& $this->recallObject('kUnitConfigReader'); - return $unit_config_reader->getUnitOption($prefix,$option); + return $unit_config_reader->getUnitOption($prefix, $option, $default); } /** @@ -1408,7 +1409,7 @@ * @author Alex * @access public */ - function setUnitOption($prefix,$option,$value) + function setUnitOption($prefix, $option, $value) { $unit_config_reader =& $this->recallObject('kUnitConfigReader'); return $unit_config_reader->setUnitOption($prefix,$option,$value); Index: trunk/core/units/custom_fields/custom_fields_config.php =================================================================== diff -u -N -r3999 -r4000 --- trunk/core/units/custom_fields/custom_fields_config.php (.../custom_fields_config.php) (revision 3999) +++ trunk/core/units/custom_fields/custom_fields_config.php (.../custom_fields_config.php) (revision 4000) @@ -15,6 +15,20 @@ 4 => 'type', 5 => 'mode', ), + + 'Hooks' => Array( + Array( + 'Mode' => hAFTER, + 'Conditional' => false, + 'HookToPrefix' => 'cf', + 'HookToSpecial' => '*', + 'HookToEvent' => Array('OnSave'), // edit cloned fields to made alters :) + 'DoPrefix' => 'cf', + 'DoSpecial' => '*', + 'DoEvent' => 'OnSaveCustomField', + ), + ), + 'IDField' => 'CustomFieldId', 'TitleField' => 'FieldName', // field, used in bluebar when editing existing item Index: trunk/core/kernel/db/db_event_handler.php =================================================================== diff -u -N -r3983 -r4000 --- trunk/core/kernel/db/db_event_handler.php (.../db_event_handler.php) (revision 3983) +++ trunk/core/kernel/db/db_event_handler.php (.../db_event_handler.php) (revision 4000) @@ -1562,6 +1562,37 @@ } } } + + /** + * Dynamically fills customdata config + * + * @param kEvent $event + */ + function OnCreateCustomFields(&$event) + { + $main_prefix = $this->Application->getUnitOption($event->Prefix, 'ParentPrefix'); + + // 1. get custom field information + $item_type = $this->Application->getUnitOption($main_prefix, 'ItemType'); + $sql = 'SELECT FieldName, CustomFieldId + FROM '.TABLE_PREFIX.'CustomField + WHERE Type = '.$item_type; + $custom_fields = $this->Conn->GetCol($sql, 'CustomFieldId'); + + // 2. create fields (for customdata item) + $fields = $this->Application->getUnitOption($event->Prefix, 'Fields', Array()); + $field_options = Array('type' => 'string', 'formatter' => 'kMultiLanguage', 'not_null' => 1, 'db_type' => 'text', 'default' => ''); + foreach ($custom_fields as $custom_id => $custom_name) { + $fields['cust_'.$custom_name] = $field_options; + } + $this->Application->setUnitOption($event->Prefix, 'Fields', $fields); + + + /*// 3. create virtual & calculated fields (for main item) + $calculated_fields = $this->Application->getUnitOption($main_prefix.'.', 'CalculatedFields', Array()); + $virtual_fields = $this->Application->getUnitOption($main_prefix, 'VirtualFields', Array());*/ + + } } Index: trunk/kernel/units/custom_fields/custom_fields_config.php =================================================================== diff -u -N -r3999 -r4000 --- trunk/kernel/units/custom_fields/custom_fields_config.php (.../custom_fields_config.php) (revision 3999) +++ trunk/kernel/units/custom_fields/custom_fields_config.php (.../custom_fields_config.php) (revision 4000) @@ -15,6 +15,20 @@ 4 => 'type', 5 => 'mode', ), + + 'Hooks' => Array( + Array( + 'Mode' => hAFTER, + 'Conditional' => false, + 'HookToPrefix' => 'cf', + 'HookToSpecial' => '*', + 'HookToEvent' => Array('OnSave'), // edit cloned fields to made alters :) + 'DoPrefix' => 'cf', + 'DoSpecial' => '*', + 'DoEvent' => 'OnSaveCustomField', + ), + ), + 'IDField' => 'CustomFieldId', 'TitleField' => 'FieldName', // field, used in bluebar when editing existing item Index: trunk/core/units/general/my_application.php =================================================================== diff -u -N -r3863 -r4000 --- trunk/core/units/general/my_application.php (.../my_application.php) (revision 3863) +++ trunk/core/units/general/my_application.php (.../my_application.php) (revision 4000) @@ -24,6 +24,8 @@ $this->registerClass('kCountryStatesHelper',MODULES_PATH.'/kernel/units/general/country_states.php','CountryStatesHelper'); $this->registerClass('kBracketsHelper',MODULES_PATH.'/kernel/units/general/brackets.php','BracketsHelper'); $this->registerClass('kXMLHelper',MODULES_PATH.'/kernel/units/general/xml_helper.php','kXMLHelper'); + $this->registerClass('kMultiLanguageHelper',MODULES_PATH.'/kernel/units/general/helpers/multilanguage.php','kMultiLanguageHelper'); + } function getUserGroups($user_id) Index: trunk/core/kernel/utility/unit_config_reader.php =================================================================== diff -u -N -r3620 -r4000 --- trunk/core/kernel/utility/unit_config_reader.php (.../unit_config_reader.php) (revision 3620) +++ trunk/core/kernel/utility/unit_config_reader.php (.../unit_config_reader.php) (revision 4000) @@ -131,10 +131,11 @@ function ParseConfigs() { - foreach ($this->configData as $prefix => $config) - { + foreach ($this->configData as $prefix => $config) { $this->parseConfig($prefix); } + + $this->Application->HandleEvent( new kEvent('m:OnAfterConfigRead') ); } function findConfigFiles($folderPath) @@ -383,13 +384,20 @@ * option specified by $option * * @param string $prefix - * @param string $option + * @param string $name + * @param mixed $default * @return string * @access public */ - function getUnitOption($prefix,$name) + function getUnitOption($prefix, $name, $default = false) { - return isset($this->configData[$prefix][$name]) ? $this->configData[$prefix][$name] : false; + if (preg_match('/(.*)\.(.*)/', $prefix, $rets)) { + $ret = getArrayValue($this->configData, $rets[1], $name, $rets[2]); + } + else { + $ret = getArrayValue($this->configData, $prefix, $name); + } + return $ret === false ? $default : $ret; } /** @@ -412,9 +420,15 @@ * @param string $value * @access public */ - function setUnitOption($prefix,$name,$value) + function setUnitOption($prefix, $name, $value) { - $this->configData[$prefix][$name] = $value; + if (preg_match('/(.*)\.(.*)/', $prefix, $rets)) { + $this->configData[$rets[1]][$name][$rets[2]] = $value; + } + else { + $this->configData[$prefix][$name] = $value; + } + } function getPrefixByParamName($paramName,$prefix) Index: trunk/kernel/units/general/my_application.php =================================================================== diff -u -N -r3863 -r4000 --- trunk/kernel/units/general/my_application.php (.../my_application.php) (revision 3863) +++ trunk/kernel/units/general/my_application.php (.../my_application.php) (revision 4000) @@ -24,6 +24,8 @@ $this->registerClass('kCountryStatesHelper',MODULES_PATH.'/kernel/units/general/country_states.php','CountryStatesHelper'); $this->registerClass('kBracketsHelper',MODULES_PATH.'/kernel/units/general/brackets.php','BracketsHelper'); $this->registerClass('kXMLHelper',MODULES_PATH.'/kernel/units/general/xml_helper.php','kXMLHelper'); + $this->registerClass('kMultiLanguageHelper',MODULES_PATH.'/kernel/units/general/helpers/multilanguage.php','kMultiLanguageHelper'); + } function getUserGroups($user_id) Index: trunk/core/units/general/main_event_handler.php =================================================================== diff -u -N -r3559 -r4000 --- trunk/core/units/general/main_event_handler.php (.../main_event_handler.php) (revision 3559) +++ trunk/core/units/general/main_event_handler.php (.../main_event_handler.php) (revision 4000) @@ -105,6 +105,16 @@ $event->setEventParam('url_params', $url_params); $event->setEventParam('env_string', strtolower($ret) ); } + + /** + * Occurs, when all configs were read, allows to change config data dynamically + * + * @param kEvent $event + */ + function OnAfterConfigRead(&$event) + { + // readonly, for hooking only! + } } ?> \ No newline at end of file Index: trunk/kernel/units/general/main_event_handler.php =================================================================== diff -u -N -r3559 -r4000 --- trunk/kernel/units/general/main_event_handler.php (.../main_event_handler.php) (revision 3559) +++ trunk/kernel/units/general/main_event_handler.php (.../main_event_handler.php) (revision 4000) @@ -105,6 +105,16 @@ $event->setEventParam('url_params', $url_params); $event->setEventParam('env_string', strtolower($ret) ); } + + /** + * Occurs, when all configs were read, allows to change config data dynamically + * + * @param kEvent $event + */ + function OnAfterConfigRead(&$event) + { + // readonly, for hooking only! + } } ?> \ No newline at end of file Index: trunk/kernel/units/general/helpers/multilanguage.php =================================================================== diff -u -N --- trunk/kernel/units/general/helpers/multilanguage.php (revision 0) +++ trunk/kernel/units/general/helpers/multilanguage.php (revision 4000) @@ -0,0 +1,181 @@ +languageCount = $this->getLanguageCount(); + } + + /** + * Returns language count in system (always is divisible by 5) + * + */ + function getLanguageCount() + { + $table_name = $this->Application->getUnitOption('lang', 'TableName'); + $languages_count = $this->Conn->GetOne('SELECT COUNT(*) FROM '.$table_name); + return $languages_count + 5 - ( $languages_count % 5 ? ($languages_count % 5) : 5 ); + } + + + function scanTable($mask) + { + $i = 0; + $fields_found = 0; + $fields = array_keys($this->curStructure); + + foreach ($fields as $field_name) { + if (preg_match($mask, $field_name)) { + $fields_found++; + } + } + return $fields_found; + } + + function readTableStructure($table_name) + { + static $structure_status = Array(); + + if (!getArrayValue($structure_status, $table_name)) { + $this->curStructure = $this->Conn->Query('DESCRIBE '.$table_name, 'Field'); + $structure_status[$table_name] = true; + } + } + + /** + * Creates missing multilanguage fields in table by specified prefix + * + * @param string $prefix + */ + function createFields($prefix) + { + $table_name = $this->Application->getUnitOption($prefix, 'TableName'); + $this->curFields = $this->Application->getUnitOption($prefix, 'Fields'); + + if (!($table_name && $this->curFields) ) { + // invalid config found or prefix not found + return true; + } + + $sqls = Array(); + foreach($this->curFields as $field_name => $field_options) + { + if (getArrayValue($field_options, 'formatter') == 'kMultiLanguage') { + $this->readTableStructure($table_name); + + $created_count = $this->getCreatedCount($field_name); + $create_count = $this->languageCount - $created_count; + if ($create_count > 0) { + // `l77_Name` VARCHAR( 255 ) NULL DEFAULT '0'; + $field_mask = Array(); + $field_mask['name'] = 'l%s_'.$field_name; + $field_mask['null'] = getArrayValue($field_options, 'not_null') ? 'NOT NULL' : 'NULL'; + + if ($this->curSourceField) { + $default_value = $this->getFieldParam('Default') != 'NULL' ? $this->Conn->qstr($this->getFieldParam('Default')) : $this->getFieldParam('Default'); + $field_mask['type'] = $this->getFieldParam('Type'); + } + else { + $default_value = is_null($field_options['default']) ? 'NULL' : $this->Conn->qstr($field_options['default']); + $field_mask['type'] = $field_options['db_type']; + } + $field_mask['default'] = 'DEFAULT '.$default_value; + $field_mask = $field_mask['name'].' '.$field_mask['type'].' '.$field_mask['null'].' '.$field_mask['default']; + + $sqls[] = 'ALTER TABLE '.$table_name.( $this->generateAlterSQL($field_mask, $created_count + 1, $create_count) ); + } + } + } + + foreach ($sqls as $sql_query) { + $this->Conn->Query($sql_query); + } + } + + /** + * Returns parameter requested of current source field + * + * @param string $param_name + * @return string + */ + function getFieldParam($param_name) + { + return $this->curStructure[$this->curSourceField][$param_name]; + } + + function getCreatedCount($field_name) + { + $ret = $this->scanTable('/^l[\d]+_'.preg_quote($field_name, '/').'/'); + if (!$ret) { + // no multilingual fields at all (but we have such field without language prefix) + $original_found = $this->scanTable('/'.preg_quote($field_name, '/').'/'); + $this->curSourceField = $original_found ? $field_name : false; + } + else { + $this->curSourceField = 'l1_'.$field_name; + } + return $ret; + } + /** + * Returns ALTER statement part for adding required fields to table + * + * @param string $field_mask sql mask for creating field with correct definition (type & size) + * @param int $start_index add new fields starting from this index + * @param int $create_count create this much new multilingual field translations + * @return string + */ + function generateAlterSQL($field_mask, $start_index, $create_count) + { + $i_count = $start_index + $create_count; + $ret = ' '; + while ($start_index < $i_count) { + list($prev_field,$type) = explode(' ', sprintf($field_mask, $start_index - 1) ); + if (substr($prev_field, 0, 3) == 'l0_') { + $prev_field = substr($prev_field, 3, strlen($prev_field)); + if (!$this->curSourceField) { + // get field name before this one + $fields = array_keys($this->curFields); + $prev_field = $fields[array_search($prev_field, $fields) - 1]; + if (getArrayValue($this->curFields[$prev_field], 'formatter') == 'kMultiLanguage') { + $prev_field = 'l'.$this->languageCount.'_'.$prev_field; + } + } + } + $ret .= 'ADD COLUMN '.sprintf($field_mask, $start_index).' AFTER `'.$prev_field.'`, '; + $start_index++; + } + return preg_replace('/, $/',';',$ret); + } + } + + +?> \ No newline at end of file Index: trunk/kernel/units/config_search/config_search_event_handler.php =================================================================== diff -u -N -r3999 -r4000 --- trunk/kernel/units/config_search/config_search_event_handler.php (.../config_search_event_handler.php) (revision 3999) +++ trunk/kernel/units/config_search/config_search_event_handler.php (.../config_search_event_handler.php) (revision 4000) @@ -79,7 +79,6 @@ { $custom_field =& $event->MasterEvent->getObject(); - $sql = 'SELECT Module FROM '.TABLE_PREFIX.'ItemTypes WHERE ItemType = '.$custom_field->GetDBField('Type'); Index: trunk/core/units/general/helpers/multilanguage.php =================================================================== diff -u -N --- trunk/core/units/general/helpers/multilanguage.php (revision 0) +++ trunk/core/units/general/helpers/multilanguage.php (revision 4000) @@ -0,0 +1,181 @@ +languageCount = $this->getLanguageCount(); + } + + /** + * Returns language count in system (always is divisible by 5) + * + */ + function getLanguageCount() + { + $table_name = $this->Application->getUnitOption('lang', 'TableName'); + $languages_count = $this->Conn->GetOne('SELECT COUNT(*) FROM '.$table_name); + return $languages_count + 5 - ( $languages_count % 5 ? ($languages_count % 5) : 5 ); + } + + + function scanTable($mask) + { + $i = 0; + $fields_found = 0; + $fields = array_keys($this->curStructure); + + foreach ($fields as $field_name) { + if (preg_match($mask, $field_name)) { + $fields_found++; + } + } + return $fields_found; + } + + function readTableStructure($table_name) + { + static $structure_status = Array(); + + if (!getArrayValue($structure_status, $table_name)) { + $this->curStructure = $this->Conn->Query('DESCRIBE '.$table_name, 'Field'); + $structure_status[$table_name] = true; + } + } + + /** + * Creates missing multilanguage fields in table by specified prefix + * + * @param string $prefix + */ + function createFields($prefix) + { + $table_name = $this->Application->getUnitOption($prefix, 'TableName'); + $this->curFields = $this->Application->getUnitOption($prefix, 'Fields'); + + if (!($table_name && $this->curFields) ) { + // invalid config found or prefix not found + return true; + } + + $sqls = Array(); + foreach($this->curFields as $field_name => $field_options) + { + if (getArrayValue($field_options, 'formatter') == 'kMultiLanguage') { + $this->readTableStructure($table_name); + + $created_count = $this->getCreatedCount($field_name); + $create_count = $this->languageCount - $created_count; + if ($create_count > 0) { + // `l77_Name` VARCHAR( 255 ) NULL DEFAULT '0'; + $field_mask = Array(); + $field_mask['name'] = 'l%s_'.$field_name; + $field_mask['null'] = getArrayValue($field_options, 'not_null') ? 'NOT NULL' : 'NULL'; + + if ($this->curSourceField) { + $default_value = $this->getFieldParam('Default') != 'NULL' ? $this->Conn->qstr($this->getFieldParam('Default')) : $this->getFieldParam('Default'); + $field_mask['type'] = $this->getFieldParam('Type'); + } + else { + $default_value = is_null($field_options['default']) ? 'NULL' : $this->Conn->qstr($field_options['default']); + $field_mask['type'] = $field_options['db_type']; + } + $field_mask['default'] = 'DEFAULT '.$default_value; + $field_mask = $field_mask['name'].' '.$field_mask['type'].' '.$field_mask['null'].' '.$field_mask['default']; + + $sqls[] = 'ALTER TABLE '.$table_name.( $this->generateAlterSQL($field_mask, $created_count + 1, $create_count) ); + } + } + } + + foreach ($sqls as $sql_query) { + $this->Conn->Query($sql_query); + } + } + + /** + * Returns parameter requested of current source field + * + * @param string $param_name + * @return string + */ + function getFieldParam($param_name) + { + return $this->curStructure[$this->curSourceField][$param_name]; + } + + function getCreatedCount($field_name) + { + $ret = $this->scanTable('/^l[\d]+_'.preg_quote($field_name, '/').'/'); + if (!$ret) { + // no multilingual fields at all (but we have such field without language prefix) + $original_found = $this->scanTable('/'.preg_quote($field_name, '/').'/'); + $this->curSourceField = $original_found ? $field_name : false; + } + else { + $this->curSourceField = 'l1_'.$field_name; + } + return $ret; + } + /** + * Returns ALTER statement part for adding required fields to table + * + * @param string $field_mask sql mask for creating field with correct definition (type & size) + * @param int $start_index add new fields starting from this index + * @param int $create_count create this much new multilingual field translations + * @return string + */ + function generateAlterSQL($field_mask, $start_index, $create_count) + { + $i_count = $start_index + $create_count; + $ret = ' '; + while ($start_index < $i_count) { + list($prev_field,$type) = explode(' ', sprintf($field_mask, $start_index - 1) ); + if (substr($prev_field, 0, 3) == 'l0_') { + $prev_field = substr($prev_field, 3, strlen($prev_field)); + if (!$this->curSourceField) { + // get field name before this one + $fields = array_keys($this->curFields); + $prev_field = $fields[array_search($prev_field, $fields) - 1]; + if (getArrayValue($this->curFields[$prev_field], 'formatter') == 'kMultiLanguage') { + $prev_field = 'l'.$this->languageCount.'_'.$prev_field; + } + } + } + $ret .= 'ADD COLUMN '.sprintf($field_mask, $start_index).' AFTER `'.$prev_field.'`, '; + $start_index++; + } + return preg_replace('/, $/',';',$ret); + } + } + + +?> \ No newline at end of file