Index: trunk/core/kernel/startup.php =================================================================== diff -u -N -r4135 -r4758 --- trunk/core/kernel/startup.php (.../startup.php) (revision 4135) +++ trunk/core/kernel/startup.php (.../startup.php) (revision 4758) @@ -1,7 +1,9 @@ profileStart('inc_globals', KERNEL_PATH.'/globals.php', $globals_start); + $debugger->profileFinish('inc_globals', KERNEL_PATH.'/globals.php', $globals_end); + $debugger->profilerAddTotal('includes', 'inc_globals'); - k4_include_once(KERNEL_PATH.'/processors/tag_processor.php'); - k4_include_once(KERNEL_PATH."/db/db_tag_processor.php"); + $debugger->profileStart('inc_debugger', KERNEL_PATH.'/utility/debugger.php', $debugger_start); + $debugger->profileFinish('inc_debugger', KERNEL_PATH.'/utility/debugger.php', $debugger_end); + $debugger->profilerAddTotal('includes', 'inc_debugger'); + } + } - k4_include_once(KERNEL_PATH."/event_handler.php"); - k4_include_once(KERNEL_PATH.'/db/db_event_handler.php'); - k4_include_once(MODULES_PATH.'/kernel/units/general/inp_db_event_handler.php'); + $includes = Array( + KERNEL_PATH.'/application.php', + MODULES_PATH.'/kernel/units/general/my_application.php', + KERNEL_PATH.'/db/db_connection.php', + KERNEL_PATH."/kbase.php", + KERNEL_PATH.'/utility/event.php', + KERNEL_PATH."/utility/factory.php", + KERNEL_PATH."/languages/phrases_cache.php", + KERNEL_PATH."/db/dblist.php", + KERNEL_PATH."/db/dbitem.php", +// KERNEL_PATH.'/processors/tag_processor.php', +// KERNEL_PATH."/db/db_tag_processor.php", + KERNEL_PATH."/event_handler.php", + KERNEL_PATH.'/db/db_event_handler.php', + MODULES_PATH.'/kernel/units/general/inp_db_event_handler.php', + ); - k4_include_once(KERNEL_PATH."/utility/temp_handler.php"); // needed because of static calls from kBase + foreach ($includes as $a_file) { + k4_include_once($a_file); + } + + if (defined('DEBUG_MODE') && DEBUG_MODE) { + $debugger->AttachToApplication(); + } + + if( !function_exists('adodb_mktime') ) include_once(KERNEL_PATH.'/utility/adodb-time.inc.php'); + +// include_once(KERNEL_PATH."/utility/temp_handler.php"); // needed because of static calls from kBase // up to here // global constants Index: trunk/core/kernel/utility/formatters/multilang_formatter.php =================================================================== diff -u -N --- trunk/core/kernel/utility/formatters/multilang_formatter.php (revision 0) +++ trunk/core/kernel/utility/formatters/multilang_formatter.php (revision 4758) @@ -0,0 +1,118 @@ +Application->GetVar('m_lang'); + return 'l'.$lang.'_'.$field_name; + } + + function PrepareOptions($field_name, &$field_options, &$object) + { + if (getArrayValue($object->Fields, $field_name, 'master_field')) return; + + $lang_field_name = $this->LangFieldName($field_name); + + //substitude title field + $title_field = $this->Application->getUnitOption($object->Prefix, 'TitleField'); + if ($title_field == $field_name) { + $this->Application->setUnitOption($object->Prefix, 'TitleField', $lang_field_name); + } + + //substitude fields + $fields = $this->Application->getUnitOption($object->Prefix, 'Fields'); + if ( isset($fields[$field_name]) ) { + + $fields[$lang_field_name] = $fields[$field_name]; + $fields[$lang_field_name]['master_field'] = $field_name; + $object->Fields[$lang_field_name] = $fields[$lang_field_name]; + $fields[$field_name]['required'] = false; + $object->Fields[$field_name]['required'] = false; + $object->VirtualFields[$field_name] = $object->Fields[$field_name]; + } + $this->Application->setUnitOption($object->Prefix, 'Fields', $fields); + + //substitude virtual fields + $virtual_fields = $this->Application->getUnitOption($object->Prefix, 'VirtualFields'); + if ( isset($virtual_fields[$field_name]) ) { + $virtual_fields[$lang_field_name] = $virtual_fields[$field_name]; + $virtual_fields[$lang_field_name]['master_field'] = $field_name; + $object->VirtualFields[$lang_field_name] = $virtual_fields[$lang_field_name]; + $virtual_fields[$field_name]['required'] = false; + $object->VirtualFields[$field_name]['required'] = false; + } + $this->Application->setUnitOption($object->Prefix, 'VirtualFields', $virtual_fields); + + //substitude grid fields + $grids = $this->Application->getUnitOption($object->Prefix, 'Grids', Array()); + foreach ($grids as $name => $grid) { + if ( getArrayValue($grid, 'Fields', $field_name) ) { + array_rename_key($grids[$name]['Fields'], $field_name, $lang_field_name); + } + } + $this->Application->setUnitOption($object->Prefix, 'Grids', $grids); + + //substitude default sortings + $sortings = $this->Application->getUnitOption($object->Prefix, 'ListSortings', Array()); + foreach ($sortings as $special => $the_sortings) { + if (isset($the_sortings['ForcedSorting'])) { + array_rename_key($sortings[$special]['ForcedSorting'], $field_name, $lang_field_name); + } + if (isset($the_sortings['Sorting'])) { + array_rename_key($sortings[$special]['Sorting'], $field_name, $lang_field_name); + } + } + $this->Application->setUnitOption($object->Prefix, 'ListSortings', $sortings); + + //TODO: substitude possible language-fields sortings after changing language + } + + /*function UpdateSubFields($field, $value, &$options, &$object) + { + + } + + function UpdateMasterFields($field, $value, &$options, &$object) + { + + }*/ + + function Format($value, $field_name, &$object, $format=null) + { + $master_field = getArrayValue($object->Fields, $field_name, 'master_field'); + if (!$master_field) { // if THIS field is master it does NOT have reference to it's master_field + $lang = $this->Application->GetVar('m_lang'); + $value = $object->GetDBField('l'.$lang.'_'.$field_name); //getting value of current language + $master_field = $field_name; // THIS is master_field + } + if ( $value == '' && $format != 'no_default') { // try to get default language value + $def_lang_value = $object->GetDBField('l'.$this->Application->GetDefaultLanguageId().'_'.$master_field); + if ($def_lang_value == '') return NULL; + return $def_lang_value; //return value from default language + } + return $value; + } + + function Parse($value, $field_name, &$object) + { + $lang = $this->Application->GetVar('m_lang'); + $def_lang = $this->Application->GetDefaultLanguageId(); + $master_field = getArrayValue($object->Fields, $field_name, 'master_field'); + + if ( getArrayValue($object->Fields, $field_name, 'required') && ( (string) $value == '' ) ) { + $object->FieldErrors[$master_field]['pseudo'] = 'required'; + }; + + if (!$this->Application->GetVar('allow_translation') && $lang != $def_lang && getArrayValue($object->Fields, $field_name, 'required')) { + $def_lang_field = 'l'.$def_lang.'_'.$master_field; + if ( !$object->ValidateRequired($def_lang_field, $object->Fields[$field_name]) ) { + $object->FieldErrors[$master_field]['pseudo'] = 'primary_lang_required'; + } + } + + if ($value == '') return NULL; + return $value; + } +} \ No newline at end of file Index: trunk/core/units/configuration/configuration_event_handler.php =================================================================== diff -u -N -r4664 -r4758 --- trunk/core/units/configuration/configuration_event_handler.php (.../configuration_event_handler.php) (revision 4664) +++ trunk/core/units/configuration/configuration_event_handler.php (.../configuration_event_handler.php) (revision 4758) @@ -1,8 +1,8 @@ setEventParam('PermSection', $this->Application->GetVar('section')); return parent::CheckPermission($event); } - - + + /** * Apply any custom changes to list's sql query * @@ -25,10 +25,10 @@ function SetCustomQuery(&$event) { $object =& $event->getObject(); - + $module = $this->Application->GetVar('module'); $section = $this->Application->GetVar('section'); - + $object->addFilter('module_filter', '%1$s.ModuleOwner = '.$this->Conn->qstr($module)); $object->addFilter('section_filter', '%1$s.Section = '.$this->Conn->qstr($section)); } @@ -41,7 +41,7 @@ function OnBeforeItemUpdate(&$event) { $object =& $event->getObject(); - + // if password field is empty, then don't update if ($object->GetDBField('element_type') == 'password') { if (trim($object->GetDBField('VariableValue')) == '') { @@ -52,24 +52,24 @@ $object->SetDBField('VariableValue', md5($object->GetDBField('VariableValue'))); } } - + $field_values = $this->Application->GetVar($event->getPrefixSpecial(true)); - + $state_country_hash = Array( 'Comm_State' => 'Comm_Country', 'Comm_Shipping_State' => 'Comm_Shipping_Country' ); - + $field_name = $object->GetDBField('VariableName'); if (isset($state_country_hash[$field_name])) { // if this is state field $check_state = $object->GetDBField('VariableValue'); $check_country = $field_values[ $state_country_hash[$field_name] ]['VariableValue']; - + if (!($check_country && $check_state)) { return true; } - + $cs_helper =& $this->Application->recallObject('CountryStatesHelper'); $state_iso = $cs_helper->CheckState($check_state, $check_country); if ($state_iso !== false) { @@ -79,17 +79,17 @@ { $errormsgs = $this->Application->GetVar('errormsgs'); $errors = !$errormsgs || !isset($errormsgs[$event->Prefix_Special]) ? Array() : $errormsgs[$event->Prefix_Special]; - + $errors[$field_name] = 'la_InvalidState'; $errormsgs[$event->Prefix_Special] = $errors; - + $this->Application->SetVar('errormsgs', $errormsgs); $event->status = erFAIL; } } - + } - + /** * Enter description here... * @@ -105,8 +105,8 @@ $object->SetFieldOptions('VariableValue', $field_options); } } - } - + } + /** * Enter description here... * @@ -115,37 +115,41 @@ function OnUpdate(&$event) { if (!$this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1)) { - + // 1. save user selected module root category $items_info = $this->Application->GetVar($event->getPrefixSpecial(true)); $new_category_id = getArrayValue($items_info, 'ModuleRootCategory', 'VariableValue'); if ($new_category_id) { unset($items_info['ModuleRootCategory']); $this->Application->SetVar($event->getPrefixSpecial(true), $items_info); } - + parent::OnUpdate($event); - + if ($event->status == erSUCCESS && $new_category_id !== false) { // root category was submitted $module = $this->Application->GetVar('module'); $root_category_id = $this->Application->findModule('Name', $module, 'RootCat'); - + if ($root_category_id != $new_category_id) { // root category differs from one in db $fields_hash = Array('RootCat' => $new_category_id); $this->Conn->doUpdate($fields_hash, TABLE_PREFIX.'Modules', 'Name = '.$this->Conn->qstr($module)); } } + + if ($event->status == erSUCCESS) { // reset cache + $this->Application->UnitConfigReader->ResetParsedData(); + } } - + if ($this->Application->GetVar('errormsgs')) { // because we have list out there, and this is item $this->Application->removeObject($event->getPrefixSpecial()); $event->redirect = false; } } - + /** * Enter description here... * @@ -163,11 +167,11 @@ $array_records[$i]['VariableValue'] = $values['Comm_Country']['VariableValue']; } } - + $event->redirect_params = Array('opener' => 's', 'pass'=>'all,conf'); //stay! $event->redirect = false; }*/ - + /** * Allows to process module root category selection * @@ -176,10 +180,10 @@ function OnSelectItems(&$event) { $object =& $event->getObject( Array('skip_autoload' => true) ); - + $items_info = $this->Application->GetVar('c'); list($resource_id, $field_values) = each($items_info); - + if ($resource_id) { $sql = 'SELECT CategoryId FROM '.TABLE_PREFIX.'Category @@ -189,9 +193,9 @@ } $this->finalizePopup($event); } - + } - - + + ?> \ No newline at end of file Index: trunk/kernel/units/languages/languages_item.php =================================================================== diff -u -N -r4524 -r4758 --- trunk/kernel/units/languages/languages_item.php (.../languages_item.php) (revision 4524) +++ trunk/kernel/units/languages/languages_item.php (.../languages_item.php) (revision 4758) @@ -4,7 +4,7 @@ { function generateID() { - $sql = 'SELECT MAX('.$this->IDField.') FROM '.kTempTablesHandler::GetLiveName($this->TableName); + $sql = 'SELECT MAX('.$this->IDField.') FROM '.$this->Application->GetLiveName($this->TableName); return $this->Conn->GetOne($sql) + 1; } Index: trunk/kernel/units/users/users_event_handler.php =================================================================== diff -u -N -r4730 -r4758 --- trunk/kernel/units/users/users_event_handler.php (.../users_event_handler.php) (revision 4730) +++ trunk/kernel/units/users/users_event_handler.php (.../users_event_handler.php) (revision 4758) @@ -247,7 +247,7 @@ $event->SetRedirectParam('js_redirect', 1); } - $sync_manager =& $this->Application->recallObject('UsersSyncronizeManager', null, Array(), 'InPortalSyncronize'); + $sync_manager =& $this->Application->recallObjectP('UsersSyncronizeManager', null, Array(), 'InPortalSyncronize'); $sync_manager->performAction('LoginUser', $object->GetDBField('Login'), $password); } @@ -258,7 +258,7 @@ */ function OnInpLogin(&$event) { - $sync_manager =& $this->Application->recallObject('UsersSyncronizeManager', null, Array(), 'InPortalSyncronize'); + $sync_manager =& $this->Application->recallObjectP('UsersSyncronizeManager', null, Array(), 'InPortalSyncronize'); $sync_manager->performAction('LoginUser', $event->getEventParam('user'), $event->getEventParam('pass') ); } @@ -269,13 +269,13 @@ */ function OnInpLogout(&$event) { - $sync_manager =& $this->Application->recallObject('UsersSyncronizeManager', null, Array(), 'InPortalSyncronize'); + $sync_manager =& $this->Application->recallObjectP('UsersSyncronizeManager', null, Array(), 'InPortalSyncronize'); $sync_manager->performAction('LogoutUser'); } function OnLogout(&$event) { - $sync_manager =& $this->Application->recallObject('UsersSyncronizeManager', null, Array(), 'InPortalSyncronize'); + $sync_manager =& $this->Application->recallObjectP('UsersSyncronizeManager', null, Array(), 'InPortalSyncronize'); $sync_manager->performAction('LogoutUser'); $session =& $this->Application->recallObject('Session'); Index: trunk/core/kernel/db/dbitem.php =================================================================== diff -u -N -r4029 -r4758 --- trunk/core/kernel/db/dbitem.php (.../dbitem.php) (revision 4029) +++ trunk/core/kernel/db/dbitem.php (.../dbitem.php) (revision 4758) @@ -45,17 +45,17 @@ * @access public */ var $ID; - + function kDBItem() { parent::kDBBase(); - $this->ErrorMsgs['required'] = $this->Application->Phrase('la_err_required'); //'Field is required'; - $this->ErrorMsgs['unique'] = $this->Application->Phrase('la_err_unique'); //'Field value must be unique'; - $this->ErrorMsgs['value_out_of_range'] = $this->Application->Phrase('la_err_value_out_of_range'); //'Field is out of range, possible values from %s to %s'; - $this->ErrorMsgs['length_out_of_range'] = $this->Application->Phrase('la_err_length_out_of_range'); //'Field is out of range'; - $this->ErrorMsgs['bad_type'] = $this->Application->Phrase('la_err_bad_type'); //'Incorrect data format, please use %s'; - $this->ErrorMsgs['bad_date_format'] = $this->Application->Phrase('la_err_bad_date_format'); //'Incorrect date format, please use (%s) ex. (%s)'; - $this->ErrorMsgs['primary_lang_required'] = $this->Application->Phrase('la_err_primary_lang_required'); + $this->ErrorMsgs['required'] = '!la_err_required!'; //'Field is required'; + $this->ErrorMsgs['unique'] = '!la_err_unique!'; //'Field value must be unique'; + $this->ErrorMsgs['value_out_of_range'] = '!la_err_value_out_of_range!'; //'Field is out of range, possible values from %s to %s'; + $this->ErrorMsgs['length_out_of_range'] = '!la_err_length_out_of_range!'; //'Field is out of range'; + $this->ErrorMsgs['bad_type'] = '!la_err_bad_type!'; //'Incorrect data format, please use %s'; + $this->ErrorMsgs['bad_date_format'] = '!la_err_bad_date_format!'; //'Incorrect date format, please use (%s) ex. (%s)'; + $this->ErrorMsgs['primary_lang_required'] = '!la_err_primary_lang_required!'; } function SetDirtyField($field_name, $field_value) @@ -372,7 +372,7 @@ if (!$system_update && $affected == 1){ $this->setModifiedFlag(); } - + $this->saveCustomFields(); $this->raiseEvent('OnAfterItemUpdate'); return true; @@ -531,7 +531,7 @@ $res_temp = $this->Conn->GetOne( str_replace('%s', $this->TableName, $sql) ); $current_table_only = getArrayValue($params, 'current_table_only'); // check unique record only in current table - $res_live = $current_table_only ? 0 : $this->Conn->GetOne( str_replace('%s', kTempTablesHandler::GetLiveName($this->TableName), $sql) ); + $res_live = $current_table_only ? 0 : $this->Conn->GetOne( str_replace('%s', $this->Application->GetLiveName($this->TableName), $sql) ); $res = ($res_temp == 0) && ($res_live == 0); @@ -612,7 +612,6 @@ if( isset($this->Fields[$field]['error_msgs'][$err]) ) { $msg = $this->Fields[$field]['error_msgs'][$err]; - $msg = $this->Application->ReplaceLanguageTags($msg, $force_escape); } else //fall back to defaults { @@ -622,6 +621,7 @@ } $msg = $this->ErrorMsgs[$err]; } + $msg = $this->Application->ReplaceLanguageTags($msg, $force_escape); if ( isset($this->FieldErrors[$field]['params']) ) { @@ -890,20 +890,20 @@ } trigger_error('Query method is called in class '.get_class($this).' for prefix '.$this->getPrefixSpecial().'', E_USER_ERROR); } - + function saveCustomFields() { if (!$this->customFields) { return true; } - + $cdata_key = rtrim($this->Prefix.'-cdata.'.$this->Special, '.'); $cdata =& $this->Application->recallObject($cdata_key, null, Array('skip_autoload' => true)); - + $resource_id = $this->GetDBField('ResourceId'); $cdata->Load($resource_id, 'ResourceId'); $cdata->SetDBField('ResourceId', $resource_id); - + $ml_formatter =& $this->Application->recallObject('kMultiLanguage'); foreach ($this->customFields as $custom_id => $custom_name) { $cdata->SetDBField($ml_formatter->LangFieldName('cust_'.$custom_id), $this->GetDBField('cust_'.$custom_name)); Index: trunk/core/units/languages/languages_event_handler.php =================================================================== diff -u -N -r4712 -r4758 --- trunk/core/units/languages/languages_event_handler.php (.../languages_event_handler.php) (revision 4712) +++ trunk/core/units/languages/languages_event_handler.php (.../languages_event_handler.php) (revision 4758) @@ -15,11 +15,11 @@ 'OnImportLanguage' => Array('self' => 'advanced:import'), 'OnExportLanguage' => Array('self' => 'advanced:export'), 'OnExportProgress' => Array('self' => 'advanced:export'), - + ); $this->permMapping = array_merge($this->permMapping, $permissions); } - + /** * Updates table structure on new language adding/removing language * @@ -29,8 +29,8 @@ { $ml_helper =& $this->Application->recallObject('kMultiLanguageHelper'); - $unit_config_reader =& $this->Application->recallObject('kUnitConfigReader'); - foreach ($unit_config_reader->configData as $prefix => $config_data) { + $this->Application->UnitConfigReader->includeConfigFiles(); //make sure to re-read all configs + foreach ($this->Application->UnitConfigReader->configData as $prefix => $config_data) { $ml_helper->createFields($prefix); } } @@ -130,7 +130,7 @@ // 1. phrases import $phrases_live = $this->Application->getUnitOption('phrases','TableName'); - $phrases_temp = kTempTablesHandler::GetTempName($phrases_live); + $phrases_temp = $this->Application->GetTempName($phrases_live); $sql = 'INSERT INTO '.$phrases_temp.' SELECT Phrase, Translation, PhraseType, 0-PhraseId, '.$lang_id.', '.adodb_mktime().', "", Module FROM '.$phrases_live.' @@ -139,7 +139,7 @@ // 2. events import $em_table_live = $this->Application->getUnitOption('emailmessages','TableName'); - $em_table_temp = kTempTablesHandler::GetTempName($em_table_live); + $em_table_temp = $this->Application->GetTempName($em_table_live); $sql = 'SELECT * FROM '.$em_table_live.' WHERE LanguageId = '.$from_lang_id; $email_messages = $this->Conn->Query($sql); @@ -177,7 +177,7 @@ $object =& $event->getObject(); $object->SetDBField('CopyLabels', 1); - $live_table = kTempTablesHandler::GetLiveName($object->TableName); + $live_table = $this->Application->GetLiveName($object->TableName); $primary_lang_id = $this->Conn->GetOne('SELECT '.$object->IDField.' FROM '.$live_table.' WHERE PrimaryLang = 1'); $object->SetDBField('CopyFromLanguage', $primary_lang_id); @@ -247,7 +247,7 @@ $import_start = (int)$this->Application->GetVar('start'); $id_field = $this->Application->getUnitOption($import_prefix,'IDField'); $dst_table = $this->Application->getUnitOption($import_prefix,'TableName'); - $src_table = kTempTablesHandler::GetTempName($dst_table); + $src_table = $this->Application->GetTempName($dst_table); $import_total = $this->Application->GetVar('total'); if(!$import_total) $import_total = $this->Conn->GetOne('SELECT COUNT(*) FROM '.$src_table); @@ -266,7 +266,7 @@ $import_start = 0; $id_field = $this->Application->getUnitOption($import_prefix,'IDField'); $dst_table = $this->Application->getUnitOption($import_prefix,'TableName'); - $src_table = kTempTablesHandler::GetTempName($dst_table); + $src_table = $this->Application->GetTempName($dst_table); $import_total = $this->Conn->GetOne('SELECT COUNT(*) FROM '.$src_table); } Index: trunk/core/units/languages/languages_config.php =================================================================== diff -u -N -r4670 -r4758 --- trunk/core/units/languages/languages_config.php (.../languages_config.php) (revision 4670) +++ trunk/core/units/languages/languages_config.php (.../languages_config.php) (revision 4758) @@ -1,5 +1,5 @@ 'lang', 'ItemClass' => Array('class'=>'LanguagesItem','file'=>'languages_item.php','build_event'=>'OnItemBuild'), @@ -9,9 +9,9 @@ 'RegisterClasses' => Array( Array('pseudo'=>'LangXML','class'=>'LangXML_Parser','file'=>'import_xml.php'), ), - + 'AutoLoad' => true, - 'Hooks' => Array( + 'Hooks' => Array( Array( 'Mode' => hAFTER, 'Conditional' => false, @@ -22,7 +22,7 @@ 'DoSpecial' => '', 'DoEvent' => 'OnReflectMultiLingualFields', ), - + Array( 'Mode' => hAFTER, 'Conditional' => false, @@ -33,7 +33,7 @@ 'DoSpecial' => '', 'DoEvent' => 'OnCopyLabels', ), - + Array( 'Mode' => hAFTER, 'Conditional' => false, @@ -52,44 +52,44 @@ 4 => 'mode', ), 'IDField' => 'LanguageId', - + 'StatusField' => Array('Enabled','PrimaryLang'), // field, that is affected by Approve/Decline events - + 'TitleField' => 'PackName', // field, used in bluebar when editing existing item - + 'TitlePresets' => Array( 'default' => Array( 'new_status_labels' => Array('lang'=>'!la_title_Adding_Language!'), 'edit_status_labels' => Array('lang'=>'!la_title_Editing_Language!'), 'new_titlefield' => Array('lang'=>'!la_title_New_Language!'), ), - + 'languages_list' => Array( 'prefixes' => Array('lang_List'), 'format' => "!la_title_Configuration! - !la_title_LanguagePacks! (#lang_recordcount#)"), - + 'languages_edit_general' => Array( 'prefixes' => Array('lang'), 'format' => "#lang_status# '#lang_titlefield#' - !la_title_General!"), - + 'phrases_list' => Array( 'prefixes' => Array('lang','phrases_List'), 'format' => "#lang_status# '#lang_titlefield#' - !la_title_Labels! (#phrases_recordcount#)"), - + 'import_language' => Array( 'prefixes' => Array('phrases.import'), 'format' => "!la_title_InstallLanguagePackStep1!"), - + 'import_language_step2' => Array( 'prefixes' => Array('phrases.import'), 'format' => "!la_title_InstallLanguagePackStep2!"), - + 'export_language' => Array( 'prefixes' => Array('phrases.export'), 'format' => "!la_title_ExportLanguagePackStep1!"), - + 'export_language_results' => Array( 'prefixes' => Array('phrases.export'), 'format' => "!la_title_ExportLanguagePackResults!"), - + 'events_list' => Array( 'prefixes' => Array('lang','emailevents_List'), 'format' => "#lang_status# '#lang_titlefield#' - !la_title_EmailEvents! (#emailevents_recordcount#)"), - + 'event_edit' => Array( 'prefixes' => Array('emailevents'), 'edit_status_labels' => Array('emailevents' => '!la_title_Editing_EmailEvent!'), 'format' => '#emailevents_status# - #emailevents_titlefield#'), - + 'email_messages_edit' => Array( 'prefixes' => Array('lang','emailmessages'), 'new_titlefield' => Array('emailmessages' => '!la_NoSubject!'), 'format' => "#lang_status# '#lang_titlefield#' - !la_title_EditingEmailEvent! '#emailmessages_titlefield#'"), ), - + 'PermSection' => Array('main' => 'in-portal:configure_lang'), - + 'Sections' => Array( 'in-portal:configure_lang' => Array( 'parent' => 'in-portal:system', @@ -100,36 +100,36 @@ 'priority' => 4, 'type' => stTREE, ), - + ), - + 'TableName' => TABLE_PREFIX.'Language', 'SubItems' => Array('phrases','emailmessages'), - + 'FilterMenu' => Array( 'Groups' => Array( Array('mode' => 'AND', 'filters' => Array(0,1), 'type' => WHERE_FILTER), ), - + 'Filters' => Array( 0 => Array('label' =>'la_Enabled', 'on_sql' => '', 'off_sql' => '%1$s.Enabled != 1' ), 1 => Array('label' => 'la_Disabled', 'on_sql' => '', 'off_sql' => '%1$s.Enabled != 0' ), ) ), - + 'AutoDelete' => true, - + 'AutoClone' => true, - + 'ListSQLs' => Array( ''=>'SELECT * FROM %s', ), // key - special, value - list select sql 'ItemSQLs' => Array( ''=>'SELECT * FROM %s', ), - 'ListSortings' => Array( + 'ListSortings' => Array( '' => Array( 'Sorting' => Array('PackName' => 'asc'), ) - ), + ), 'Fields' => Array( 'LanguageId' => Array(), 'PackName' => Array('type' => 'string','not_null' => '1','default' => '','required'=>1), @@ -151,7 +151,7 @@ 'CopyLabels' => Array('type' => 'int', 'default' => 0), 'CopyFromLanguage' => Array('type' => 'int', 'formatter' => 'kOptionsFormatter', 'options_sql' => 'SELECT %s FROM '.TABLE_PREFIX.'Language ORDER BY PackName', 'option_title_field' => 'PackName', 'option_key_field' => 'LanguageId'), ), - + 'Grids' => Array( 'Default' => Array( 'Icons' => Array('default'=>'icon16_custom.gif','0_0'=>'icon16_language_disabled.gif','1_0'=>'icon16_language.gif','0_1'=>'icon16_language_disabled.gif','1_1'=>'icon16_language_primary.gif'), @@ -160,7 +160,7 @@ 'LocalName' => Array( 'title'=>'la_col_LocalName' ), 'Enabled' => Array( 'title'=>'la_col_Status' ), ), - + ), ), ); Index: trunk/kernel/units/users/users_syncronize.php =================================================================== diff -u -N -r3834 -r4758 --- trunk/kernel/units/users/users_syncronize.php (.../users_syncronize.php) (revision 3834) +++ trunk/kernel/units/users/users_syncronize.php (.../users_syncronize.php) (revision 4758) @@ -53,7 +53,7 @@ foreach ($this->syncClasses as $class_name => $class_info) { if ($class_name == $this->skipClass) continue; $this->Application->registerClass($class_name, $class_info['file']); - $sync_object =& $this->Application->recallObject($class_name, null, Array(), $class_info['sub_folder'], $class_name); + $sync_object =& $this->Application->recallObjectP($class_name, null, Array(), $class_info['sub_folder'], $class_name); call_user_func_array( Array(&$sync_object, $action), $args); } } Index: trunk/core/units/visits/visits_event_handler.php =================================================================== diff -u -N -r4490 -r4758 --- trunk/core/units/visits/visits_event_handler.php (.../visits_event_handler.php) (revision 4490) +++ trunk/core/units/visits/visits_event_handler.php (.../visits_event_handler.php) (revision 4758) @@ -1,7 +1,7 @@ Application->RecallVar('visit_id')) { + return true; + } $object =& $event->getObject( Array('skip_autoload'=>true) ); $object->SetDBField('VisitDate_date', adodb_mktime() ); $object->SetDBField('VisitDate_time', adodb_mktime() ); @@ -24,7 +27,7 @@ $this->Application->SetVar('visits_id', $object->GetID() ); } } - + /** * Apply any custom changes to list's sql query * @@ -35,29 +38,29 @@ function SetCustomQuery(&$event) { $object =& $event->getObject(); - + $types = $event->getEventParam('types'); if($types == 'myvisitors') { - + $user_id = $this->Application->GetVar('u_id'); $object->addFilter('myitems_user1','au.PortalUserId = '.$user_id); $object->addFilter('myitems_user2','au.PortalUserId >0'); //$object->AddGroupByField('VisitDate'); $object->AddGroupByField('%1$s.VisitId'); } - + if($types == 'myvisitororders' && $event->Special == 'incommerce') { $user_id = $this->Application->GetVar('u_id'); $object->addFilter('myitems_orders','ord.OrderId IS NOT NULL'); $object->addFilter('myitems_user1','au.PortalUserId = '.$user_id); $object->addFilter('myitems_user2','au.PortalUserId >0'); $object->addFilter('myitems_orders_processed','ord.Status = 4'); - } - } - + } + } + /** * Apply some special processing to * object beeing recalled before using @@ -78,13 +81,13 @@ $object->addCalculatedField('OrderAffiliateCommissionSum', 'SUM( IF(ord.Status = 4,ord.AffiliateCommission,0))'); $object->addCalculatedField('OrderCountByVisit', 'SUM( IF(ord.Status = 4, 1, 0) )'); } - + if (!$types){ $object->AddGroupByField('%1$s.VisitId'); } - } + } } - + } ?> \ No newline at end of file Index: trunk/core/kernel/utility/formatters/serialized_formatter.php =================================================================== diff -u -N --- trunk/core/kernel/utility/formatters/serialized_formatter.php (revision 0) +++ trunk/core/kernel/utility/formatters/serialized_formatter.php (revision 4758) @@ -0,0 +1,11 @@ +Application->recallObject('lang.current'); + $add_fields = Array(); + $options_a = Array('type' => 'int','error_field' => $field_name,'master_field' => $field_name,'format' => '%d' ); + $options_b = Array('type' => 'double','error_field' => $field_name,'master_field' => $field_name,'format' => '%0.2f' ); + switch( $regional->GetDBField('UnitSystem') ) + { + case 2: // US/UK + $field_options_copy = $field_options; + unset($field_options_copy['min_value_exc']); + $add_fields[$field_name.'_a'] = array_merge_recursive2($field_options_copy, $options_a); + $add_fields[$field_name.'_b'] = array_merge_recursive2($field_options_copy, $options_b); + break; + default: + } + $add_fields = array_merge_recursive2($add_fields, $object->VirtualFields); + $object->setVirtualFields($add_fields); + } + } + + function UpdateMasterFields($field, $value, &$options, &$object) + { + if( !isset($options['master_field']) ) + { + $regional =& $this->Application->recallObject('lang.current'); + switch( $regional->GetDBField('UnitSystem') ) + { + case 2: // US/UK + $major = $object->GetDirtyField($field.'_a'); + $minor = $object->GetDirtyField($field.'_b'); + if($major === '' && $minor === '') + { + $value = null; + } + elseif($major === null && $minor === null) + { + unset($object->Fields[$field]); + return; + } + else + { + $value = Pounds2Kg($major, $minor); + } + break; + default: + } + $object->SetDBField($field, $value); + } + } + + function UpdateSubFields($field, $value, &$options, &$object) + { + if( !isset($options['master_field']) ) + { + $regional =& $this->Application->recallObject('lang.current'); + switch( $regional->GetDBField('UnitSystem') ) + { + case 2: // US/UK + if($value === null) + { + $major = null; + $minor = null; + } + else + { + list($major,$minor) = Kg2Pounds($value); + /*$major = floor( $value / 0.5 ); + $minor = ($value - $major * 0.5) * 32;*/ + } + $object->SetDBField($field.'_a', $major); + $object->SetDBField($field.'_b', $minor); + break; + default: + } + } + } +} \ No newline at end of file Index: trunk/core/units/custom_data/custom_data_config.php =================================================================== diff -u -N -r4287 -r4758 --- trunk/core/units/custom_data/custom_data_config.php (.../custom_data_config.php) (revision 4287) +++ trunk/core/units/custom_data/custom_data_config.php (.../custom_data_config.php) (revision 4758) @@ -1,52 +1,48 @@ '', - + 'Prefix' => 'cdata', + 'Clones' => Array( - + 'u-cdata' => Array( 'TableName' => TABLE_PREFIX.'PortalUserCustomData', 'ParentPrefix' => 'u', ), - + 'c-cdata' => Array( 'TableName' => TABLE_PREFIX.'CategoryCustomData', 'ParentPrefix' => 'c', ), - - 'l-cdata' => Array( - 'TableName' => TABLE_PREFIX.'LinkCustomData', - 'ParentPrefix' => 'l', - ), - + + 'n-cdata' => Array( 'TableName' => TABLE_PREFIX.'NewsCustomData', 'ParentPrefix' => 'n', ), - + 'bb-cdata' => Array( 'TableName' => TABLE_PREFIX.'TopicCustomData', 'ParentPrefix' => 'bb', ), - + 'p-cdata' => Array( 'TableName' => TABLE_PREFIX.'ProductsCustomData', 'ParentPrefix' => 'p', ), ), - + 'QueryString' => Array( 1 => 'id', 2 => 'event', ), - + '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, - + 'Hooks' => Array( Array( 'Mode' => hAFTER, @@ -59,26 +55,26 @@ 'DoEvent' => 'OnCreateCustomFields', ), ), - + 'IDField' => 'CustomDataId', - + 'ParentTableKey' => 'ResourceId', 'ForeignKey' => 'ResourceId', 'AutoDelete' => true, 'AutoClone' => false, - + 'CalculatedFields' => Array( '' => Array(), ), 'ListSQLs' => Array('' => 'SELECT %1$s.* %2$s FROM %1$s'), 'ItemSQLs' => Array('' => 'SELECT %1$s.* %2$s FROM %1$s'), - + 'Fields' => Array( 'CustomDataId' => Array(), 'ResourceId' => Array('type' => 'int', 'not_null' => 1, 'default' => 0), ), ); - + ?> \ No newline at end of file Index: trunk/core/kernel/utility/debugger.php =================================================================== diff -u -N -r4712 -r4758 --- trunk/core/kernel/utility/debugger.php (.../debugger.php) (revision 4712) +++ trunk/core/kernel/utility/debugger.php (.../debugger.php) (revision 4758) @@ -92,8 +92,9 @@ function Debugger() { $this->dummyImage = PROTOCOL.SERVER_NAME.(defined('PORT')?':'.PORT : '').rtrim(BASE_PATH, '/').'/'.'kernel/admin_templates/img/spacer.gif'; - $this->profileStart('kernel4_startup', 'Startup and Initialization of kernel4'); - $this->profileStart('script_runtime', 'Script runtime'); + global $start; + $this->profileStart('kernel4_startup', 'Startup and Initialization of kernel4', $start); + $this->profileStart('script_runtime', 'Script runtime', $start); ini_set('display_errors', dbg_ConstOn('DBG_ZEND_PRESENT') ? 0 : 1); $this->memoryUsage['error_handling'] = 0; // memory amount used by error handler @@ -224,9 +225,10 @@ $total = $this->ProfilerTotals[$totals_key]; $div_width = Array(); - $div_width['before'] = ($total_before / $total) * $this->getWindowWidth(); - $div_width['current'] = ($runtime / $total) * $this->getWindowWidth(); - $div_width['left'] = (($total - $total_before - $runtime) / $total) * $this->getWindowWidth(); + $total_width = ($this->getWindowWidth()-10); + $div_width['before'] = round(($total_before / $total) * $total_width); + $div_width['current'] = round(($runtime / $total) * $total_width); + $div_width['left'] = round((($total - $total_before - $runtime) / $total) * $total_width); $ret = 'Name: '.$Data['description'].'
'; $ret .= 'Runtime: '.$runtime.'s'; @@ -249,7 +251,7 @@ function getWindowWidth() { - return DBG_WINDOW_WIDTH - $this->scrollbarWidth; + return DBG_WINDOW_WIDTH - $this->scrollbarWidth - 8; } function isApplication(&$object) @@ -480,9 +482,11 @@ } } - function profileStart($key, $description = null) + function profileStart($key, $description = null, $timeStamp=null) { - $timeStamp = $this->getMoment(); + if (!isset($timeStamp)) { + $timeStamp = $this->getMoment(); + } $this->ProfilerData[$key] = Array('begins' => $timeStamp, 'ends' => 5000, 'debuggerRowID' => count($this->Data)); if (isset($description)) { $this->ProfilerData[$key]['description'] = $description; @@ -491,9 +495,12 @@ $this->Data[] = array('profile_key' => $key, 'debug_type' => 'profiler'); } - function profileFinish($key, $description = null) + function profileFinish($key, $description = null, $timeStamp=null) { - $this->ProfilerData[$key]['ends'] = $this->getMoment(); + if (!isset($timeStamp)) { + $timeStamp = $this->getMoment(); + } + $this->ProfilerData[$key]['ends'] = $timeStamp; if (isset($description)) { $this->ProfilerData[$key]['description'] = $description; @@ -603,44 +610,51 @@ $this->appendHTML('SQL Total time: '.$this->ProfilerTotals['sql'].' Number of queries: '.$this->ProfilerTotalCount['sql']); } + if( dbg_ConstOn('DBG_PROFILE_INCLUDES') && isset($this->ProfilerTotals['includes']) ) + { + $this->appendHTML('Included Files Total time: '.$this->ProfilerTotals['includes'].' Number of includes: '.$this->ProfilerTotalCount['includes']); + } + if( dbg_ConstOn('DBG_PROFILE_MEMORY') ) { $this->appendHTML('Memory used by Objects: '.round($this->ProfilerTotals['objects']/1024, 2).'Kb'); } - if( dbg_ConstOn('DBG_INCLUDED_FILES') ) + /*if( dbg_ConstOn('DBG_INCLUDED_FILES') ) { $files = get_included_files(); $this->appendHTML('Included files:'); foreach ($files as $file) { $this->appendHTML($this->getFileLink($this->getLocalFile($file)).' ('.round(filesize($file)/1024, 2).'Kb)'); } - } + }*/ - if( dbg_ConstOn('DBG_PROFILE_INCLUDES') ) + /*if( dbg_ConstOn('DBG_PROFILE_INCLUDES') ) { $this->appendHTML('Included files statistics:'.( dbg_ConstOn('DBG_SORT_INCLUDES_MEM') ? ' (sorted by memory usage)':'')); $totals = Array( 'mem' => 0, 'time' => 0); $totals_configs = Array( 'mem' => 0, 'time' => 0); - if ( dbg_ConstOn('DBG_SORT_INCLUDES_MEM') ) { - array_multisort($this->IncludesData['mem'], SORT_DESC, $this->IncludesData['file'], $this->IncludesData['time'], $this->IncludesData['level']); - } - foreach ($this->IncludesData['file'] as $key => $file_name) { - $this->appendHTML( str_repeat(' -> ', ($this->IncludesData['level'][$key] >= 0 ? $this->IncludesData['level'][$key] : 0)).$file_name.' Mem: '.sprintf("%.4f Kb", $this->IncludesData['mem'][$key]/1024).' Time: '.sprintf("%.4f", $this->IncludesData['time'][$key])); - if ($this->IncludesData['level'][$key] == 0) { - $totals['mem'] += $this->IncludesData['mem'][$key]; - $totals['time'] += $this->IncludesData['time'][$key]; + if (is_array($this->IncludesData['mem'])) { + if ( dbg_ConstOn('DBG_SORT_INCLUDES_MEM') ) { + array_multisort($this->IncludesData['mem'], SORT_DESC, $this->IncludesData['file'], $this->IncludesData['time'], $this->IncludesData['level']); } - else if ($this->IncludesData['level'][$key] == -1) { - $totals_configs['mem'] += $this->IncludesData['mem'][$key]; - $totals_configs['time'] += $this->IncludesData['time'][$key]; + foreach ($this->IncludesData['file'] as $key => $file_name) { + $this->appendHTML( str_repeat(' -> ', ($this->IncludesData['level'][$key] >= 0 ? $this->IncludesData['level'][$key] : 0)).$file_name.' Mem: '.sprintf("%.4f Kb", $this->IncludesData['mem'][$key]/1024).' Time: '.sprintf("%.4f", $this->IncludesData['time'][$key])); + if ($this->IncludesData['level'][$key] == 0) { + $totals['mem'] += $this->IncludesData['mem'][$key]; + $totals['time'] += $this->IncludesData['time'][$key]; + } + else if ($this->IncludesData['level'][$key] == -1) { + $totals_configs['mem'] += $this->IncludesData['mem'][$key]; + $totals_configs['time'] += $this->IncludesData['time'][$key]; + } } + $this->appendHTML('Sub-Total classes: '.' Mem: '.sprintf("%.4f Kb", $totals['mem']/1024).' Time: '.sprintf("%.4f", $totals['time'])); + $this->appendHTML('Sub-Total configs: '.' Mem: '.sprintf("%.4f Kb", $totals_configs['mem']/1024).' Time: '.sprintf("%.4f", $totals_configs['time'])); + $this->appendHTML('Grand Total: '.' Mem: '.sprintf("%.4f Kb", ($totals['mem']+$totals_configs['mem'])/1024).' Time: '.sprintf("%.4f", $totals['time']+$totals_configs['time'])); } - $this->appendHTML('Sub-Total classes: '.' Mem: '.sprintf("%.4f Kb", $totals['mem']/1024).' Time: '.sprintf("%.4f", $totals['time'])); - $this->appendHTML('Sub-Total configs: '.' Mem: '.sprintf("%.4f Kb", $totals_configs['mem']/1024).' Time: '.sprintf("%.4f", $totals_configs['time'])); - $this->appendHTML('Grand Total: '.' Mem: '.sprintf("%.4f Kb", ($totals['mem']+$totals_configs['mem'])/1024).' Time: '.sprintf("%.4f", $totals['time']+$totals_configs['time'])); - } + }*/ $i = 0; $lineCount = count($this->Data); @@ -650,9 +664,11 @@ .dbg_profiler { margin-top: 5px; + padding: 0px; height: 10px; border: 1px solid #000000; float: left; + display: inline; } .dbg_flat_table { @@ -953,6 +969,9 @@ { $ret[]=''.$title.':'.$this->formatSize($this->memoryUsage[$value_key]).''; } + $Data =& $this->ProfilerData['script_runtime']; + $runtime = ($Data['ends'] - $Data['begins']); // in seconds + $ret[] = 'Script runtime:'.sprintf('%.5f', $runtime).''; return ''.implode('',$ret).'
'; } @@ -1086,6 +1105,23 @@ $ret .= ''; $this->appendHTML($ret); } + + function AttachToApplication() { + if( dbg_ConstOn('DBG_HANDLE_ERRORS') ) + { + if( class_exists('kApplication') ) + { + restore_error_handler(); + $application =& kApplication::Instance(); + $application->Debugger =& $this; + $application->errorHandlers[] = Array(&$this, 'saveError'); + } + else + { + set_error_handler( Array(&$this, 'saveError') ); + } + } + } } if( !function_exists('memory_get_usage') ) @@ -1098,20 +1134,6 @@ $debugger = new Debugger(); } - if( dbg_ConstOn('DBG_HANDLE_ERRORS') ) - { - if( class_exists('kApplication') ) - { - $application =& kApplication::Instance(); - $application->Debugger =& $debugger; - $application->errorHandlers[] = Array(&$debugger, 'saveError'); - } - else - { - set_error_handler( Array(&$debugger, 'saveError') ); - } - } - if( dbg_ConstOn('DBG_USE_SHUTDOWN_FUNC') ) register_shutdown_function( Array(&$debugger, 'printReport') ); } ?> \ No newline at end of file Index: trunk/core/units/categories/categories_item.php =================================================================== diff -u -N -r4243 -r4758 --- trunk/core/units/categories/categories_item.php (.../categories_item.php) (revision 4243) +++ trunk/core/units/categories/categories_item.php (.../categories_item.php) (revision 4758) @@ -99,7 +99,7 @@ $found_temp_ids = $this->Conn->GetCol($sql_temp); // check live table - $sql_live = 'SELECT '.$this->IDField.' FROM '.kTempTablesHandler::GetLiveName($this->TableName).' WHERE Filename = '.$this->Conn->qstr($filename); + $sql_live = 'SELECT '.$this->IDField.' FROM '.$this->Application->GetLiveName($this->TableName).' WHERE Filename = '.$this->Conn->qstr($filename); $found_live_ids = $this->Conn->GetCol($sql_live); $found_item_ids = array_unique( array_merge($found_temp_ids, $found_live_ids) ); @@ -118,7 +118,7 @@ // check live & temp table $sql_temp = 'SELECT '.$this->IDField.' FROM '.$this->TableName.' WHERE (Filename = %s) AND ('.$this->IDField.' != '.$item_id.')'; - $sql_live = 'SELECT '.$this->IDField.' FROM '.kTempTablesHandler::GetLiveName($this->TableName).' WHERE (Filename = %s) AND ('.$this->IDField.' != '.$item_id.')'; + $sql_live = 'SELECT '.$this->IDField.' FROM '.$this->Application->GetLiveName($this->TableName).' WHERE (Filename = %s) AND ('.$this->IDField.' != '.$item_id.')'; while ( $this->Conn->GetOne( sprintf($sql_temp, $this->Conn->qstr($filename.$append)) ) > 0 || $this->Conn->GetOne( sprintf($sql_live, $this->Conn->qstr($filename.$append)) ) > 0 ) { Index: trunk/core/kernel/db/db_event_handler.php =================================================================== diff -u -N -r4730 -r4758 --- trunk/core/kernel/db/db_event_handler.php (.../db_event_handler.php) (revision 4730) +++ trunk/core/kernel/db/db_event_handler.php (.../db_event_handler.php) (revision 4758) @@ -78,15 +78,15 @@ } } } - + if ($event->Name == 'OnPreCreate') { // save category_id before item create (for item category selector not to destroy permission checking category) $this->Application->LinkVar('m_cat_id'); } - + return parent::CheckPermission($event); } - + /** * Allows to override standart permission mapping * @@ -102,42 +102,42 @@ 'OnDelete' => Array('self' => 'delete', 'subitem' => 'add|edit'), 'OnMassDelete' => Array('self' => 'delete', 'subitem' => 'add|edit'), 'OnMassClone' => Array('self' => 'add', 'subitem' => 'add|edit'), - + 'OnSelectItems' => Array('self' => 'add|edit', 'subitem' => 'add|edit'), 'OnSelectUser' => Array('self' => 'add|edit', 'subitem' => 'add|edit'), - + 'OnMassApprove' => Array('self' => 'advanced:approve|add|edit', 'subitem' => 'advanced:approve|add|edit'), 'OnMassDecline' => Array('self' => 'advanced:decline|add|edit', 'subitem' => 'advanced:decline|add|edit'), 'OnMassMoveUp' => Array('self' => 'advanced:move_up|add|edit', 'subitem' => 'advanced:move_up|add|edit'), 'OnMassMoveDown' => Array('self' => 'advanced:move_down|add|edit', 'subitem' => 'advanced:move_down|add|edit'), - + 'OnPreCreate' => Array('self' => 'add'), 'OnEdit' => Array('self' => 'edit'), - - - + + + // theese event do not harm, but just in case check them too :) 'OnCancelEdit' => Array('self' => 'add|edit'), 'OnCancel' => Array('self' => 'add|edit', 'subitem' => 'add|edit'), - + 'OnSetSorting' => Array('self' => 'view', 'subitem' => 'view'), 'OnSetSortingDirect' => Array('self' => 'view', 'subitem' => 'view'), - + 'OnSetFilter' => Array('self' => 'view', 'subitem' => 'view'), 'OnApplyFilters' => Array('self' => 'view', 'subitem' => 'view'), 'OnRemoveFilters' => Array('self' => 'view', 'subitem' => 'view'), - + 'OnSetPerPage' => Array('self' => 'view', 'subitem' => 'view'), - + 'OnSearch' => Array('self' => 'view', 'subitem' => 'view'), 'OnSearchReset' => Array('self' => 'view', 'subitem' => 'view'), - + 'OnGoBack' => Array('self' => true, 'subitem' => true), ); $this->permMapping = array_merge($this->permMapping, $permissions); } - + function mapEvents() { $events_map = Array('OnRemoveFilters' => 'FilterAction', @@ -370,7 +370,7 @@ */ function TablePrefix(&$event) { - return $this->UseTempTables($event) ? kTempTablesHandler::GetTempTablePrefix().TABLE_PREFIX : TABLE_PREFIX; + return $this->UseTempTables($event) ? $this->Application->GetTempTablePrefix().TABLE_PREFIX : TABLE_PREFIX; } function LoadItem(&$event) @@ -775,7 +775,7 @@ } -/* Edit Events mostly used in Admin */ + /* Edit Events mostly used in Admin */ /** * Creates new kDBItem @@ -912,12 +912,12 @@ $delete_ids[] = $id; } } - + if ($delete_ids) { $temp->DeleteItems($event->Prefix, $event->Special, $delete_ids); } } - + $event->redirect_params = Array('opener'=>'u'); } @@ -961,7 +961,7 @@ function OnEdit(&$event) { $this->StoreSelectedIDs($event); - + $temp =& $this->Application->recallObject($event->getPrefixSpecial().'_TempHandler', 'kTempTablesHandler'); $temp->PrepareEdit(); @@ -988,7 +988,7 @@ $event->redirect_params = Array('opener' => 'u'); $this->Application->RemoveVar($event->getPrefixSpecial().'_modified'); - + // all temp tables are deleted here => all after hooks should think, that it's live mode now $this->Application->SetVar($event->Prefix.'_mode', ''); } @@ -1010,7 +1010,7 @@ $this->Application->RemoveVar($event->getPrefixSpecial().'_modified'); } - + /** * Allows to determine if we are creating new item or editing already created item * @@ -1022,7 +1022,7 @@ $item_id = $this->getPassedID($event); return ($item_id == '') ? true : false; } - + /** * Saves edited item into temp table * If there is no id, new item is created in temp table @@ -1036,15 +1036,15 @@ if (is_object($event->MasterEvent)) { $event->MasterEvent->setEventParam('IsNew',false); } - + if ($this->isNewItemCreate($event)) { $event->CallSubEvent('OnPreSaveCreated'); if (is_object($event->MasterEvent)) { $event->MasterEvent->setEventParam('IsNew',true); } return; } - + $this->Application->setUnitOption($event->Prefix,'AutoLoad',false); $object =& $event->getObject(); @@ -1126,7 +1126,7 @@ $this->Application->setUnitOption($event->Prefix,'AutoLoad',false); $object =& $event->getObject(); - + $temp =& $this->Application->recallObject($event->Prefix.'_TempHandler', 'kTempTablesHandler'); $temp->PrepareEdit(); @@ -1399,10 +1399,10 @@ $t = $this->Application->RecallVar('return_template'); $this->Application->RemoveVar('return_template'); } - + $pass_events = $event->getEventParam('pass_events'); $redirect_params = array_merge_recursive2($event->redirect_params, Array('m_opener' => 'u', '__URLENCODE__' => 1)); - + $new_level = 'index4.php|'.ltrim($this->Application->BuildEnv($t, $redirect_params, 'all', $pass_events), ENV_VAR_NAME.'='); array_push($opener_stack, $new_level); $this->Application->StoreVar('opener_stack', serialize($opener_stack)); @@ -1422,7 +1422,7 @@ $search_keyword = $this->Application->GetVar( $event->getPrefixSpecial(true).'_search_keyword'); $this->Application->StoreVar( $event->getPrefixSpecial().'_search_keyword', $search_keyword); $search_keyword = str_replace('*', '%', $search_keyword); - + $custom_filters = $this->Application->RecallVar( $event->getPrefixSpecial().'_custom_filters'); $custom_filters = $custom_filters ? unserialize($custom_filters) : Array(); @@ -1457,7 +1457,7 @@ $search_filter = Array(); $search_helper =& $this->Application->recallObject('SearchHelper'); $search_keywords = $search_helper->splitKeyword($search_keyword); - + foreach($search_fields as $search_field) { $filter_type = isset($object->VirtualFields[$search_field]) ? 'having' : 'where'; @@ -1495,7 +1495,7 @@ continue; } } - + if ($sign == '+' || $sign == '') { $search_keys[$key] = $this->Conn->qstr($key); } @@ -1506,11 +1506,11 @@ } } } - + if ($search_keys) { $filter_value = $table_name.'`'.$search_field.'` IN ('.implode(',', $search_keys).')'; } - + $field_processed = true; break; @@ -1561,7 +1561,7 @@ if (!is_numeric($keyword) || ($sign == '-')) continue; $search_keys[] = $this->Conn->qstr($keyword); } - + if ($search_keys) { $filter_value = $table_name.'`'.$search_field.'` IN ('.implode(',', $search_keys).')'; } @@ -1576,7 +1576,7 @@ if (!is_numeric($keyword) || ($sign == '-')) continue; $search_keys[] = 'ABS('.$table_name.'`'.$search_field.'` - '.$this->Conn->qstr($keyword).') <= 0.0001'; } - + if ($search_keys) { $filter_value = '('.implode(') OR (', $search_keys).')'; } @@ -1587,7 +1587,7 @@ break; } } - + if ($filter_value) { $search_filter[$search_field] = Array('type' => $filter_type, 'value' => $filter_value); } @@ -1690,7 +1690,7 @@ } } } - + /** * Dynamically fills customdata config * @@ -1699,12 +1699,13 @@ function OnCreateCustomFields(&$event) { $main_prefix = $this->Application->getUnitOption($event->Prefix, 'ParentPrefix'); + if (!$main_prefix) return false; $item_type = $this->Application->getUnitOption($main_prefix, 'ItemType'); if (!$item_type) { // no main config of such type return false; } - + // 1. get custom field information $sql = 'SELECT FieldName, CustomFieldId FROM '.TABLE_PREFIX.'CustomField @@ -1715,19 +1716,19 @@ // config doesn't have custom fields return false; } - + // 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_id] = $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()); - + $ml_formatter =& $this->Application->recallObject('kMultiLanguage'); $field_options = Array('type' => 'string', 'not_null' => 1, 'default' => ''); foreach ($custom_fields as $custom_id => $custom_name) { @@ -1741,7 +1742,7 @@ $this->Application->setUnitOption($main_prefix.'.', 'CalculatedFields', $calculated_fields); $this->Application->setUnitOption($main_prefix, 'VirtualFields', $virtual_fields); } - + /** * Saves selected user in needed field * @@ -1752,20 +1753,20 @@ $items_info = $this->Application->GetVar('u'); if ($items_info) { $user_id = array_shift( array_keys($items_info) ); - + $object =& $event->getObject(); $this->RemoveRequiredFields($object); - + $is_new = !$object->isLoaded(); $is_main = $this->Application->GetVar($event->Prefix.'_mode') == 't'; - + if ($is_new) { $new_event = $is_main ? 'OnPreCreate' : 'OnNew'; $event->CallSubEvent($new_event); } - + $object->SetDBField($this->Application->RecallVar('dst_field'), $user_id); - + if ($is_new) { $object->Create(); if (!$is_main && $object->IsTempTable()) { @@ -1776,7 +1777,7 @@ $object->Update(); } } - + $event->SetRedirectParam($event->getPrefixSpecial().'_id', $object->GetID()); $this->finalizePopup($event); } Index: trunk/core/kernel/utility/formatters/formatter.php =================================================================== diff -u -N --- trunk/core/kernel/utility/formatters/formatter.php (revision 0) +++ trunk/core/kernel/utility/formatters/formatter.php (revision 4758) @@ -0,0 +1,141 @@ +GetFieldOptions($field_name); + if ( isset($format) ) $options['format'] = $format; + $tc_value = $this->TypeCast($value,$options); + if( ($tc_value === false) || ($tc_value != $value) ) return $value; // for leaving badly formatted date on the form + + if (isset($options['format'])) return sprintf($options['format'], $tc_value); + + return $tc_value; + } + +//function Parse($value, $options, &$errors) + function Parse($value, $field_name, &$object) + { + if ($value == '') return NULL; + + $options = $object->GetFieldOptions($field_name); + $tc_value = $this->TypeCast($value,$options); + if($tc_value === false) return $value; // for leaving badly formatted date on the form + + if( isset($options['type']) ) + { + if( preg_match('#double|float|real|numeric#', $options['type']) ) $tc_value = str_replace(',', '.', $tc_value); + } + + if( isset($options['regexp']) ) + { + if( !preg_match($options['regexp'], $value) ) + { + $object->FieldErrors[$field_name]['pseudo'] = 'invalid_format'; + } + } + + return $tc_value; + } + + function HumanFormat($format) + { + return $format; + } + + + /** + * The method is supposed to alter config options or cofigure object in some way based on its usage of formatters + * The methods is called for every field with formatter defined when configuring item. + * Could be used for adding additional VirtualFields to an object required by some special Formatter + * + * @param string $field_name + * @param array $field_options + * @param kDBBase $object + */ + function PrepareOptions($field_name, &$field_options, &$object) + { + + } + + /** + * Used for split fields like timestamp -> date, time + * Called from DBItem to update sub fields values after loading item + * + * @param unknown_type $field + * @param unknown_type $value + * @param unknown_type $options + * @param unknown_type $object + */ + function UpdateSubFields($field, $value, &$options, &$object) + { + + } + + /** + * Used for split fields like timestamp -> date, time + * Called from DBItem Validate (before validation) to get back master field value from its sub_fields + * + * @param unknown_type $field + * @param unknown_type $value + * @param unknown_type $options + * @param unknown_type $object + */ + function UpdateMasterFields($field, $value, &$options, &$object) + { + + } + +/* function GetErrorMsg($pseudo_error, $options) + { + if ( isset($options['error_msgs'][$pseudo_error]) ) { + return $options['error_msgs'][$pseudo_error]; + } + else { + return $this->ErrorMsgs[$pseudo_error]; + } + }*/ + + function GetSample($field, &$options, &$object) + { + + } + +} \ No newline at end of file Index: trunk/core/units/categories/categories_tag_processor.php =================================================================== diff -u -N -r4446 -r4758 --- trunk/core/units/categories/categories_tag_processor.php (.../categories_tag_processor.php) (revision 4446) +++ trunk/core/units/categories/categories_tag_processor.php (.../categories_tag_processor.php) (revision 4758) @@ -279,6 +279,11 @@ $special = crc32($types.$except.$parent_cat_id); return $special; } + + function IsCurrent($params) + { + return false; + } } Index: trunk/core/kernel/utility/formatters/ccdate_formatter.php =================================================================== diff -u -N --- trunk/core/kernel/utility/formatters/ccdate_formatter.php (revision 0) +++ trunk/core/kernel/utility/formatters/ccdate_formatter.php (revision 4758) @@ -0,0 +1,59 @@ + ''); + while($i <= 12) + { + $options[ sprintf('%02d',$i) ] = sprintf('%02d',$i); + $i++; + } + $add_fields[ $field_options['month_field'] ] = Array('formatter'=>'kOptionsFormatter', 'options' => $options, 'not_null' => true, 'default' => '00'); + $add_fields[ $field_options['year_field'] ] = Array('type' => 'string', 'default' => ''); + + $add_fields = array_merge_recursive2($add_fields, $object->VirtualFields); + $object->setVirtualFields($add_fields); + } + + function UpdateSubFields($field, $value, &$options, &$object) + { + if(!$value) return false; + $date = explode('/', $value); + $object->SetDBField( $options['month_field'], $date[0] ); + $object->SetDBField( $options['year_field'], $date[1] ); + } + + /** + * Will work in future if we could attach 2 formatters to one field + * + * @param string $value + * @param string $field_name + * @param kDBase $object + * @return string + */ + function Parse($value, $field_name, &$object) + { +// if ( is_null($value) ) return ''; + + $options = $object->GetFieldOptions($field_name); + + $month = $object->GetDirtyField($options['month_field']); + $year = $object->GetDirtyField($options['year_field']); + + if( !(int)$month && !(int)$year ) return NULL; + $is_valid = ($month >= 1 && $month <= 12) && ($year >= 0 && $year <= 99); + + if(!$is_valid) $object->FieldErrors[$field_name]['pseudo'] = 'bad_type'; + return $month.'/'.$year; + } + +} \ No newline at end of file Index: trunk/core/kernel/db/db_connection.php =================================================================== diff -u -N -r4446 -r4758 --- trunk/core/kernel/db/db_connection.php (.../db_connection.php) (revision 4446) +++ trunk/core/kernel/db/db_connection.php (.../db_connection.php) (revision 4758) @@ -1,11 +1,11 @@ errorHandler = Array(&$this,'handleError'); } - else + else { $this->errorHandler=$errorHandler; } } - + /** * Set's custom error * @@ -106,9 +106,9 @@ function setError($code,$msg) { $this->errorCode=$code; - $this->errorMessage=$msg; + $this->errorMessage=$msg; } - + /** * Checks if previous query execution * raised an error. @@ -118,9 +118,9 @@ */ function hasError() { - return !($this->errorCode == 0); + return !($this->errorCode == 0); } - + /** * Caches function specific to requested * db type @@ -134,14 +134,14 @@ { case 'mysql': $ret = Array(); // only define functions, that name differs from "dbType_" - + break; - - + + } $this->metaFunctions = $ret; - } - + } + /** * Get's function for specific db type * based on it's meta name @@ -154,16 +154,16 @@ { if( !isset($this->metaFunctions[$name]) ) { - if(function_exists($this->dbType.'_'.$name)) return $this->dbType.'_'.$name; + if(function_exists($this->dbType.'_'.$name)) return $this->dbType.'_'.$name; } - else + else { return $this->dbType.$name; } return false; } - - + + /** * Try to connect to database server * using specified parameters and set @@ -185,14 +185,14 @@ $this->showError(); } } - + function ReConnect($host,$user,$pass,$db) { $func = $this->getMetaFunction('close'); $func($this->connectionID); $this->Connect($host,$user,$pass,$db); } - + /** * Shows error message from previous operation * if it failed @@ -213,7 +213,7 @@ $func = $this->errorHandler[1]; $ret = $this->errorHandler[0]->$func($this->errorCode,$this->errorMessage,$sql); } - else + else { $func = $this->errorHandler; $ret = $func($this->errorCode,$this->errorMessage,$sql); @@ -222,7 +222,7 @@ } } } - + /** * Default error handler for sql errors * @@ -238,7 +238,7 @@ echo 'Error ('.$code.'): '.$msg.'
'; return false; } - + /** * Set's database name for connection * to $new_name @@ -253,12 +253,12 @@ $func = $this->getMetaFunction('select_db'); return $func($new_name); } - + /** * Returns first field of first line * of recordset if query ok or false * otherwise - * + * * @param string $sql * @param int $offset * @return string @@ -268,14 +268,14 @@ { $row = $this->GetRow($sql, $offset); if(!$row) return false; - + return array_shift($row); } - + /** * Returns first row of recordset * if query ok, false otherwise - * + * * @param stirng $sql * @param int $offset * @return Array @@ -285,11 +285,11 @@ { $sql .= ' '.$this->getLimitClause($offset, 1); $ret = $this->Query($sql); - if(!$ret) return false; - + if(!$ret) return false; + return array_shift($ret); } - + /** * Returns 1st column of recordset as * one-dimensional array or false otherwise @@ -306,7 +306,7 @@ { $rows = $this->Query($sql); if(!$rows) return $rows; - + $i = 0; $row_count = count($rows); $ret = Array(); if(isset($key_field)) @@ -317,7 +317,7 @@ $i++; } } - else + else { while ($i < $row_count) { @@ -327,7 +327,7 @@ } return $ret; } - + /** * Queries db with $sql query supplied * and returns rows selected if any, false @@ -356,7 +356,7 @@ $ret[$row[$key_field]] = $row; } } - else + else { while( ($row = $fetch_func($this->queryID)) ) { @@ -369,18 +369,18 @@ $this->showError($sql); return false; } - + function ChangeQuery($sql) { $this->Query($sql); return $this->errorCode==0 ? true : false; } - + function debugQuery($sql, $key_field = null) { global $debugger; $query_func = $this->getMetaFunction('query'); - + // set 1st checkpoint: begin $isSkipTable=true; $profileSQLs=defined('DBG_SQL_PROFILE')&&DBG_SQL_PROFILE; @@ -394,16 +394,9 @@ } } // set 1st checkpoint: end - + $this->queryID = $query_func($sql,$this->connectionID); - - // set 2nd checkpoint: begin - if(!$isSkipTable) { - $debugger->profileFinish('sql_'.$queryID); - $debugger->profilerAddTotal('sql', 'sql_'.$queryID); - } - // set 2nd checkpoint: end - + if( is_resource($this->queryID) ) { $ret = Array(); @@ -415,20 +408,34 @@ $ret[$row[$key_field]] = $row; } } - else + else { while( ($row = $fetch_func($this->queryID)) ) { $ret[] = $row; } } + // set 2nd checkpoint: begin + if(!$isSkipTable) { + $debugger->profileFinish('sql_'.$queryID); + $debugger->profilerAddTotal('sql', 'sql_'.$queryID); + } $this->Destroy(); + // set 2nd checkpoint: end return $ret; } + else { + // set 2nd checkpoint: begin + if(!$isSkipTable) { + $debugger->profileFinish('sql_'.$queryID); + $debugger->profilerAddTotal('sql', 'sql_'.$queryID); + } + // set 2nd checkpoint: end + } $this->showError($sql); return false; } - + /** * Free memory used to hold recordset handle * @@ -438,12 +445,12 @@ { if($this->queryID) { - $free_func = $this->getMetaFunction('free_result'); + $free_func = $this->getMetaFunction('free_result'); $free_func($this->queryID); $this->queryID = null; } } - + /** * Returns auto increment field value from * insert like operation if any, zero otherwise @@ -456,7 +463,7 @@ $func = $this->getMetaFunction('insert_id'); return $func($this->connectionID); } - + /** * Returns row count affected by last query * @@ -466,9 +473,9 @@ function getAffectedRows() { $func = $this->getMetaFunction('affected_rows'); - return $func($this->connectionID); + return $func($this->connectionID); } - + /** * Returns LIMIT sql clause part for specific db * @@ -480,20 +487,20 @@ function getLimitClause($offset, $rows) { if(!($rows > 0)) return ''; - + switch ($this->dbType) { - + default: return 'LIMIT '.$offset.','.$rows; break; } } - + /** * Correctly quotes a string so that all strings are escaped. We prefix and append * to the string single-quotes. * An example is $db->qstr("Don't bother",magic_quotes_runtime()); - * + * * @param s the string to quote * @param [magic_quotes] if $s is GET/POST var, set to get_magic_quotes_gpc(). * This undoes the stupidity of magic quotes for GPC. @@ -527,7 +534,7 @@ return "'".str_replace("\\'",$replaceQuote,$s)."'"; } } - + /** * Returns last error code occured * @@ -537,7 +544,7 @@ { return $this->errorCode; } - + /** * Returns last error message * @@ -548,7 +555,7 @@ { return $this->errorMessage; } - + function doInsert($fields_hash, $table, $type = 'INSERT') { $fields_sql = ''; @@ -557,27 +564,27 @@ $fields_sql .= '`'.$field_name.'`,'; $values_sql .= $this->qstr($field_value).','; } - + $fields_sql = preg_replace('/(.*),$/', '\\1', $fields_sql); $values_sql = preg_replace('/(.*),$/', '\\1', $values_sql); $sql = strtoupper($type).' INTO `'.$table.'` ('.$fields_sql.') VALUES ('.$values_sql.')'; - + return $this->ChangeQuery($sql); } - + function doUpdate($fields_hash, $table, $key_clause) { if (!$fields_hash) return true; - + $fields_sql = ''; foreach ($fields_hash as $field_name => $field_value) { $fields_sql .= '`'.$field_name.'` = '.$this->qstr($field_value).','; } - + $fields_sql = preg_replace('/(.*),$/', '\\1', $fields_sql); - + $sql = 'UPDATE `'.$table.'` SET '.$fields_sql.' WHERE '.$key_clause; - + return $this->ChangeQuery($sql); } } Index: trunk/kernel/include/debugger.php =================================================================== diff -u -N -r3863 -r4758 --- trunk/kernel/include/debugger.php (.../debugger.php) (revision 3863) +++ trunk/kernel/include/debugger.php (.../debugger.php) (revision 4758) @@ -2,157 +2,5 @@ if( !class_exists('Debugger') ) { include_once KERNEL_PATH.'/utility/debugger.php'; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - } ?> \ No newline at end of file Index: trunk/core/kernel/session/session.php =================================================================== diff -u -N -r4630 -r4758 --- trunk/core/kernel/session/session.php (.../session.php) (revision 4630) +++ trunk/core/kernel/session/session.php (.../session.php) (revision 4758) @@ -63,6 +63,9 @@ var $Expiration; var $SessionTimeout=0; + var $DirectVars = Array(); + var $ChangedDirectVars = Array(); + var $OriginalData=Array(); var $TimestampField; @@ -93,7 +96,7 @@ if ($additional_fields) { $fields_hash = array_merge_recursive2($fields_hash, $additional_fields); } - + $this->Conn->doInsert($fields_hash, $this->TableName); } @@ -110,18 +113,21 @@ function UpdateSession(&$session, $timeout=0) { + $this->SetField($session, $this->TimestampField, $session->Expiration); $query = ' UPDATE '.$this->TableName.' SET '.$this->TimestampField.' = '.$session->Expiration.' WHERE '.$this->IDField.' = '.$this->Conn->qstr($session->SID); $this->Conn->Query($query); } function LocateSession($sid) { - $query = ' SELECT '.$this->TimestampField.' FROM '.$this->TableName.' WHERE '.$this->IDField.' = '.$this->Conn->qstr($sid); - $result = $this->Conn->GetOne($query); + $query = ' SELECT * FROM '.$this->TableName.' WHERE '.$this->IDField.' = '.$this->Conn->qstr($sid); + $result = $this->Conn->GetRow($query); if($result===false) return false; - $this->Expiration = $result; + $this->DirectVars = $result; + + $this->Expiration = $result[$this->TimestampField]; return true; } @@ -146,12 +152,18 @@ */ function GetField(&$session, $var_name) { - return $this->Conn->GetOne('SELECT '.$var_name.' FROM '.$this->TableName.' WHERE `'.$this->IDField.'` = '.$this->Conn->qstr($session->GetID()) ); + return $this->DirectVars[$var_name]; + //return $this->Conn->GetOne('SELECT '.$var_name.' FROM '.$this->TableName.' WHERE `'.$this->IDField.'` = '.$this->Conn->qstr($session->GetID()) ); } function SetField(&$session, $var_name, $value) { - return $this->Conn->Query('UPDATE '.$this->TableName.' SET '.$var_name.' = '.$this->Conn->qstr($value).' WHERE '.$this->IDField.' = '.$this->Conn->qstr($session->GetID()) ); + if ($this->DirectVars[$var_name] != $value) { + $this->DirectVars[$var_name] = $value; + $this->ChangedDirectVars[] = $var_name; + $this->ChangedDirectVars = array_unique($this->ChangedDirectVars); + } + //return $this->Conn->Query('UPDATE '.$this->TableName.' SET '.$var_name.' = '.$this->Conn->qstr($value).' WHERE '.$this->IDField.' = '.$this->Conn->qstr($session->GetID()) ); } function SaveData(&$session) @@ -180,6 +192,15 @@ $query = ' REPLACE INTO '.$this->SessionDataTable. ' ('.$this->IDField.', '.$this->DataVarField.', '.$this->DataValueField.') VALUES '.$replace; $this->Conn->Query($query); } + + if ($this->ChangedDirectVars) { + $changes = array(); + foreach ($this->ChangedDirectVars as $var) { + $changes[] = $var.' = '.$this->Conn->qstr($this->DirectVars[$var]); + } + $query = 'UPDATE '.$this->TableName.' SET '.implode(',', $changes).' WHERE '.$this->IDField.' = '.$this->Conn->qstr($session->GetID()); + $this->Conn->Query($query); + } } function RemoveFromData(&$session, $var) @@ -194,7 +215,7 @@ { return getArrayValue($this->OriginalData, $var); } - + function GetExpiredSIDs() { $query = ' SELECT '.$this->IDField.' FROM '.$this->TableName.' WHERE '.$this->TimestampField.' > '.adodb_mktime(); @@ -240,6 +261,11 @@ var $SID; + /** + * Enter description here... + * + * @var SessionStorage + */ var $Storage; var $CachedNeedQueryString = null; @@ -299,17 +325,18 @@ $tmp_sid = $this->GetPassedSIDValue(); + $check = $this->Check(); if( !(defined('IS_INSTALL') && IS_INSTALL) ) { $expired_sids = $this->DeleteExpired(); - if( ( $expired_sids && in_array($tmp_sid,$expired_sids) ) || ( $tmp_sid && !$this->Check() ) ) + if( ( $expired_sids && in_array($tmp_sid,$expired_sids) ) || ( $tmp_sid && !$check ) ) { $this->SetSession(); $this->Application->HandleEvent($event, 'u:OnSessionExpire'); } } - if ($this->Check()) { + if ($check) { $this->SID = $this->GetPassedSIDValue(); $this->Refresh(); $this->LoadData(); @@ -560,7 +587,6 @@ break; } $this->Storage->StoreSession($this); - $this->Application->HandleEvent( new kEvent('visits:OnRegisterVisit') ); } function SetSessionCookie() @@ -697,7 +723,7 @@ { return $this->StoreVar($name, $this->Storage->GetFromData($this, $name)); } - + function GetField($var_name) { return $this->Storage->GetField($this, $var_name); Index: trunk/core/units/languages/languages_item.php =================================================================== diff -u -N -r4524 -r4758 --- trunk/core/units/languages/languages_item.php (.../languages_item.php) (revision 4524) +++ trunk/core/units/languages/languages_item.php (.../languages_item.php) (revision 4758) @@ -4,7 +4,7 @@ { function generateID() { - $sql = 'SELECT MAX('.$this->IDField.') FROM '.kTempTablesHandler::GetLiveName($this->TableName); + $sql = 'SELECT MAX('.$this->IDField.') FROM '.$this->Application->GetLiveName($this->TableName); return $this->Conn->GetOne($sql) + 1; } Index: trunk/core/kernel/utility/formatters/formatters_config.php =================================================================== diff -u -N --- trunk/core/kernel/utility/formatters/formatters_config.php (revision 0) +++ trunk/core/kernel/utility/formatters/formatters_config.php (revision 4758) @@ -0,0 +1,19 @@ + 'formatters', + 'RegisterClasses' => Array( + Array('pseudo'=>'kFormatter','class'=>'kFormatter','file'=>'formatter.php','build_event'=>'','require_classes'=>''), + Array('pseudo'=>'kOptionsFormatter','class'=>'kOptionsFormatter','file'=>'options_formatter.php','build_event'=>'','require_classes'=>'kFormatter'), + Array('pseudo'=>'kLEFTFormatter','class'=>'kLEFTFormatter','file'=>'left_formatter.php','build_event'=>'','require_classes'=>'kFormatter'), + Array('pseudo'=>'kDateFormatter','class'=>'kDateFormatter','file'=>'date_formatter.php','build_event'=>'','require_classes'=>'kFormatter'), + Array('pseudo'=>'kUploadFormatter','class'=>'kUploadFormatter','file'=>'upload_formatter.php','build_event'=>'','require_classes'=>'kFormatter'), + Array('pseudo'=>'kPictureFormatter','class'=>'kPictureFormatter','file'=>'upload_formatter.php','build_event'=>'','require_classes'=>'kUploadFormatter'), + Array('pseudo'=>'kMultiLanguage','class'=>'kPictureFormatter','file'=>'multilang_formatter.php','build_event'=>'','require_classes'=>'kFormatter'), + Array('pseudo'=>'kPasswordFormatter','class'=>'kPasswordFormatter','file'=>'password_formatter.php','build_event'=>'','require_classes'=>'kFormatter'), + Array('pseudo'=>'kCCDateFormatter','class'=>'kCCDateFormatter','file'=>'ccdate_formatter.php','build_event'=>'','require_classes'=>'kFormatter'), + Array('pseudo'=>'kUnitFormatter','class'=>'kUnitFormatter','file'=>'unit_formatter.php','build_event'=>'','require_classes'=>'kFormatter'), + Array('pseudo'=>'kFilesizeFormatter','class'=>'kFilesizeFormatter','file'=>'filesize_formatter.php','build_event'=>'','require_classes'=>'kFormatter'), + Array('pseudo'=>'kSerializedFormatter','class'=>'kSerializedFormatter','file'=>'serialized_formatter.php','build_event'=>'','require_classes'=>'kFormatter'), + ), + ); Index: trunk/core/units/users/users_event_handler.php =================================================================== diff -u -N -r4730 -r4758 --- trunk/core/units/users/users_event_handler.php (.../users_event_handler.php) (revision 4730) +++ trunk/core/units/users/users_event_handler.php (.../users_event_handler.php) (revision 4758) @@ -247,7 +247,7 @@ $event->SetRedirectParam('js_redirect', 1); } - $sync_manager =& $this->Application->recallObject('UsersSyncronizeManager', null, Array(), 'InPortalSyncronize'); + $sync_manager =& $this->Application->recallObjectP('UsersSyncronizeManager', null, Array(), 'InPortalSyncronize'); $sync_manager->performAction('LoginUser', $object->GetDBField('Login'), $password); } @@ -258,7 +258,7 @@ */ function OnInpLogin(&$event) { - $sync_manager =& $this->Application->recallObject('UsersSyncronizeManager', null, Array(), 'InPortalSyncronize'); + $sync_manager =& $this->Application->recallObjectP('UsersSyncronizeManager', null, Array(), 'InPortalSyncronize'); $sync_manager->performAction('LoginUser', $event->getEventParam('user'), $event->getEventParam('pass') ); } @@ -269,13 +269,13 @@ */ function OnInpLogout(&$event) { - $sync_manager =& $this->Application->recallObject('UsersSyncronizeManager', null, Array(), 'InPortalSyncronize'); + $sync_manager =& $this->Application->recallObjectP('UsersSyncronizeManager', null, Array(), 'InPortalSyncronize'); $sync_manager->performAction('LogoutUser'); } function OnLogout(&$event) { - $sync_manager =& $this->Application->recallObject('UsersSyncronizeManager', null, Array(), 'InPortalSyncronize'); + $sync_manager =& $this->Application->recallObjectP('UsersSyncronizeManager', null, Array(), 'InPortalSyncronize'); $sync_manager->performAction('LogoutUser'); $session =& $this->Application->recallObject('Session'); Index: trunk/kernel/units/users/users_item.php =================================================================== diff -u -N -r4524 -r4758 --- trunk/kernel/units/users/users_item.php (.../users_item.php) (revision 4524) +++ trunk/kernel/units/users/users_item.php (.../users_item.php) (revision 4758) @@ -106,7 +106,7 @@ $ret = parent::Create($force_id, $system_create); if ($ret) { // find out how to syncronize user only when it's copied to live table - $sync_manager =& $this->Application->recallObject('UsersSyncronizeManager', null, Array(), 'InPortalSyncronize'); + $sync_manager =& $this->Application->recallObjectP('UsersSyncronizeManager', null, Array(), 'InPortalSyncronize'); $sync_manager->performAction('createUser', $this->FieldValues); } return $ret; @@ -118,7 +118,7 @@ $ret = parent::Update($id, $system_update); if ($ret) { // find out how to syncronize user only when it's copied to live table - $sync_manager =& $this->Application->recallObject('UsersSyncronizeManager', null, Array(), 'InPortalSyncronize'); + $sync_manager =& $this->Application->recallObjectP('UsersSyncronizeManager', null, Array(), 'InPortalSyncronize'); $sync_manager->performAction('updateUser', $this->FieldValues); } return $ret; @@ -134,7 +134,7 @@ { $ret = parent::Delete($id); if ($ret) { - $sync_manager =& $this->Application->recallObject('UsersSyncronizeManager', null, Array(), 'InPortalSyncronize'); + $sync_manager =& $this->Application->recallObjectP('UsersSyncronizeManager', null, Array(), 'InPortalSyncronize'); $sync_manager->performAction('deleteUser', $this->FieldValues); } Index: trunk/core/units/users/users_syncronize.php =================================================================== diff -u -N -r3834 -r4758 --- trunk/core/units/users/users_syncronize.php (.../users_syncronize.php) (revision 3834) +++ trunk/core/units/users/users_syncronize.php (.../users_syncronize.php) (revision 4758) @@ -53,7 +53,7 @@ foreach ($this->syncClasses as $class_name => $class_info) { if ($class_name == $this->skipClass) continue; $this->Application->registerClass($class_name, $class_info['file']); - $sync_object =& $this->Application->recallObject($class_name, null, Array(), $class_info['sub_folder'], $class_name); + $sync_object =& $this->Application->recallObjectP($class_name, null, Array(), $class_info['sub_folder'], $class_name); call_user_func_array( Array(&$sync_object, $action), $args); } } Index: trunk/core/kernel/globals.php =================================================================== diff -u -N -r4735 -r4758 --- trunk/core/kernel/globals.php (.../globals.php) (revision 4735) +++ trunk/core/kernel/globals.php (.../globals.php) (revision 4758) @@ -18,7 +18,8 @@ if (!is_array($paArray1) or !is_array($paArray2)) { return $paArray2; } foreach ($paArray2 AS $sKey2 => $sValue2) { - $paArray1[$sKey2] = array_merge_recursive2( getArrayValue($paArray1,$sKey2), $sValue2); + $paArray1[$sKey2] = isset($paArray1[$sKey2]) ? array_merge_recursive2($paArray1[$sKey2], $sValue2) : $sValue2; +// $paArray1[$sKey2] = array_merge_recursive2( getArrayValue($paArray1,$sKey2), $sValue2); } return $paArray1; } @@ -50,7 +51,7 @@ $application =& kApplication::Instance(); $is_debug = $application->isDebugMode(); } - + if ($is_debug) { if ($label) $application->Debugger->appendHTML(''.$label.''); $application->Debugger->dumpVars($data); @@ -183,26 +184,29 @@ { function k4_include_once($file) { - if ( constOn('DEBUG_MODE') && isset($debugger) && constOn('DBG_PROFILE_INCLUDES') ) + global $debugger; + if ( defined('DEBUG_MODE') && DEBUG_MODE && isset($debugger) && constOn('DBG_PROFILE_INCLUDES') ) { if ( in_array($file, get_required_files()) ) return; global $debugger; - $debugger->IncludeLevel++; - $before_time = getmicrotime(); +/* $debugger->IncludeLevel++; $before_mem = memory_get_usage(); +*/ + $debugger->ProfileStart('inc_'.crc32($file), $file); include_once($file); - $used_time = getmicrotime() - $before_time; - $used_mem = memory_get_usage() - $before_mem; + $debugger->ProfileFinish('inc_'.crc32($file)); + $debugger->profilerAddTotal('includes', 'inc_'.crc32($file)); +/* $used_mem = memory_get_usage() - $before_mem; $debugger->IncludeLevel--; $debugger->IncludesData['file'][] = str_replace(FULL_PATH, '', $file); $debugger->IncludesData['mem'][] = $used_mem; $debugger->IncludesData['time'][] = $used_time; $debugger->IncludesData['level'][] = $debugger->IncludeLevel; +*/ - } else { @@ -252,8 +256,6 @@ $comb='4'; // the amount of combinations you made above (and did not comment out) - - for ($p=0;$p<$pass_length;) { mt_srand((double)microtime()*1000000); @@ -333,7 +335,7 @@ curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $post); } - + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch,CURLOPT_REFERER, PROTOCOL.SERVER_NAME); @@ -465,7 +467,7 @@ $line = $enclosure.implode($enclosure.$delimiter.$enclosure, $data).$enclosure.$recordSeparator; fwrite($filePointer, $line); } - + /** * Allows to replace #section# within any string with current section * @@ -485,4 +487,23 @@ return $string; } + /** + * Return live table name based on temp table name + * + * @param string $temp_table + * @return string + */ + function GetLiveName($temp_table) + { + $application =& kApplication::Instance(); + if( preg_match('/'.TABLE_PREFIX.'ses_'.$application->GetSID().'_edit_(.*)/',$temp_table,$rets) ) + { + return $rets[1]; + } + else + { + return $temp_table; + } + } + ?> \ No newline at end of file Index: trunk/kernel/include/portaluser.php =================================================================== diff -u -N -r4077 -r4758 --- trunk/kernel/include/portaluser.php (.../portaluser.php) (revision 4077) +++ trunk/kernel/include/portaluser.php (.../portaluser.php) (revision 4758) @@ -32,7 +32,7 @@ if ($ret && $this->isLiveTable()) { $application =& kApplication::Instance(); - $sync_manager =& $application->recallObject('UsersSyncronizeManager', null, Array(), 'InPortalSyncronize'); + $sync_manager =& $application->recallObjectP('UsersSyncronizeManager', null, Array(), 'InPortalSyncronize'); $sync_manager->performAction('createUser', $this->Data); } return $ret; @@ -44,7 +44,7 @@ if ($ret && $this->isLiveTable()) { $application =& kApplication::Instance(); - $sync_manager =& $application->recallObject('UsersSyncronizeManager', null, Array(), 'InPortalSyncronize'); + $sync_manager =& $application->recallObjectP('UsersSyncronizeManager', null, Array(), 'InPortalSyncronize'); $sync_manager->performAction('updateUser', $this->Data); } return $ret; @@ -63,7 +63,7 @@ if($ret && $this->isLiveTable()) { $application =& kApplication::Instance(); - $sync_manager =& $application->recallObject('UsersSyncronizeManager', null, Array(), 'InPortalSyncronize'); + $sync_manager =& $application->recallObjectP('UsersSyncronizeManager', null, Array(), 'InPortalSyncronize'); $sync_manager->performAction('deleteUser', $this->Data); } Index: trunk/core/kernel/utility/formatters/options_formatter.php =================================================================== diff -u -N --- trunk/core/kernel/utility/formatters/options_formatter.php (revision 0) +++ trunk/core/kernel/utility/formatters/options_formatter.php (revision 4758) @@ -0,0 +1,46 @@ +GetFieldOptions($field_name); + + $label = getArrayValue($options['options'], $value); + if ($label !== false) { + if (getArrayValue($options, 'use_phrases')) { + return $this->Application->Phrase($label); + } + else { + return $label; + } + } + else { + return $value; + } + } + + function Parse($value, $field_name, &$object) + { + if ($value == '') return NULL; + + $options = $object->GetFieldOptions($field_name); + $use_phrases = getArrayValue($options, 'use_phrases'); + + $found = false; + foreach ($options['options'] as $option_key => $option_value) { + if ($use_phrases) { + $option_value = $this->Application->Phrase($option_value); + } + + if ($option_value == $value) { + $found = true; + break; + } + } + + return $found ? $option_key : $value; + } +} \ No newline at end of file Index: trunk/kernel/units/general/cat_dbitem.php =================================================================== diff -u -N -r4314 -r4758 --- trunk/kernel/units/general/cat_dbitem.php (.../cat_dbitem.php) (revision 4314) +++ trunk/kernel/units/general/cat_dbitem.php (.../cat_dbitem.php) (revision 4758) @@ -32,8 +32,8 @@ $ret = parent::Create(); if($ret) { - if ( kTempTablesHandler::IsTempTable($this->TableName) ) { - $table = kTempTablesHandler::GetTempName(TABLE_PREFIX.'CategoryItems'); + if ( $this->Application->IsTempTable($this->TableName) ) { + $table = $this->Application->GetTempName(TABLE_PREFIX.'CategoryItems'); } else { $table = TABLE_PREFIX.'CategoryItems'; @@ -218,7 +218,7 @@ $found_temp_ids = $this->Conn->GetCol($sql_temp); // check live table - $sql_live = 'SELECT '.$this->IDField.' FROM '.kTempTablesHandler::GetLiveName($this->TableName).' WHERE Filename = '.$this->Conn->qstr($filename); + $sql_live = 'SELECT '.$this->IDField.' FROM '.$this->Application->GetLiveName($this->TableName).' WHERE Filename = '.$this->Conn->qstr($filename); $found_live_ids = $this->Conn->GetCol($sql_live); $found_item_ids = array_unique( array_merge($found_temp_ids, $found_live_ids) ); @@ -237,7 +237,7 @@ // check live & temp table $sql_temp = 'SELECT '.$this->IDField.' FROM '.$this->TableName.' WHERE (Filename = %s) AND ('.$this->IDField.' != '.$item_id.')'; - $sql_live = 'SELECT '.$this->IDField.' FROM '.kTempTablesHandler::GetLiveName($this->TableName).' WHERE (Filename = %s) AND ('.$this->IDField.' != '.$item_id.')'; + $sql_live = 'SELECT '.$this->IDField.' FROM '.$this->Application->GetLiveName($this->TableName).' WHERE (Filename = %s) AND ('.$this->IDField.' != '.$item_id.')'; while ( $this->Conn->GetOne( sprintf($sql_temp, $this->Conn->qstr($filename.$append)) ) > 0 || $this->Conn->GetOne( sprintf($sql_live, $this->Conn->qstr($filename.$append)) ) > 0 ) { Index: trunk/kernel/units/general/inp_ses_storage.php =================================================================== diff -u -N -r3887 -r4758 --- trunk/kernel/units/general/inp_ses_storage.php (.../inp_ses_storage.php) (revision 3887) +++ trunk/kernel/units/general/inp_ses_storage.php (.../inp_ses_storage.php) (revision 4758) @@ -54,19 +54,20 @@ function LocateSession($sid) { - $query = ' SELECT '.$this->TimestampField.' FROM '.$this->TableName.' WHERE '.$this->IDField.' = '.$this->Conn->qstr($sid); - $result = $this->Conn->GetOne($query); - - if($result===false) return false; - - $this->Expiration = $result + $this->SessionTimeout; - return true; + $res = parent::LocateSession($sid); + if ($res) { + $this->Expiration += $this->SessionTimeout; + } + return $res; } function UpdateSession(&$session) { - $query = ' UPDATE '.$this->TableName.' SET '.$this->TimestampField.' = unix_timestamp() WHERE '.$this->IDField.' = '.$this->Conn->qstr($session->SID); - $this->Conn->Query($query); + $time = adodb_mktime(); + // Update LastAccessed only if it's newer than 1/10 of session timeout - perfomance optimization to eliminate needless updates on every click + if ($time - $this->DirectVars['LastAccessed'] > $this->SessionTimeout/10) { + $this->SetField($session, $this->TimestampField, $time); + } } @@ -78,15 +79,15 @@ 'IpAddress' => $_SERVER['REMOTE_ADDR'], 'GroupList' => $this->Application->ConfigValue('User_GuestGroup'), 'CurrentTempKey'=> $session->SID, - + ); - + parent::StoreSession($session, $fields_hash); } function GetExpiredSIDs() { - $query = ' SELECT '.$this->IDField.' FROM '.$this->TableName.' WHERE '.adodb_mktime().' - '.$this->TimestampField.' > '.$this->SessionTimeout; + $query = ' SELECT '.$this->IDField.' FROM '.$this->TableName.' WHERE '.$this->TimestampField.' < '.(adodb_mktime()-$this->SessionTimeout); $ret = $this->Conn->GetCol($query); if($ret) { $this->DeleteEditTables(); Index: trunk/core/kernel/utility/formatters/date_formatter.php =================================================================== diff -u -N --- trunk/core/kernel/utility/formatters/date_formatter.php (revision 0) +++ trunk/core/kernel/utility/formatters/date_formatter.php (revision 4758) @@ -0,0 +1,333 @@ +ErrorMsgs['bad_dformat'] = 'Please use correct date format (%s) ex. (%s)'; + } + */ + + function PrepareOptions($field_name, &$field_options, &$object) + { + $date_format = getArrayValue($field_options, 'date_format'); + $time_format = getArrayValue($field_options, 'time_format'); + + $language =& $this->Application->recallObject('lang.current'); + + if ($date_format === false) $date_format = $language->GetDBField('DateFormat'); + if ($time_format === false) $time_format = $language->GetDBField('TimeFormat'); + + $input_format['date'] = $language->GetDBField('InputDateFormat'); + $input_format['time'] = $language->GetDBField('InputTimeFormat'); + + if (!isset($field_options['date_time_separator'])) $field_options['date_time_separator'] = ' '; + $field_options['format'] = $date_format.$field_options['date_time_separator'].$time_format; + $field_options['input_format'] = $input_format['date'].$field_options['date_time_separator'].$input_format['time']; + + $field_options['sub_fields'] = Array('date' => $field_name.'_date', 'time' => $field_name.'_time'); + + $add_fields = Array(); + + $opts = Array('master_field' => $field_name, 'formatter'=>'kDateFormatter', 'format' => $date_format, 'input_format' => $input_format['date']); + if ( isset($field_options['default']) ) $opts['default'] = $field_options['default']; + if ( isset($field_options['required']) ) $opts['required'] = $field_options['required']; + + $add_fields[$field_name.'_date'] = $opts; + $opts['format'] = $time_format; + $opts['input_format'] = $input_format['time']; + $add_fields[$field_name.'_time'] = $opts; + + $filter_type = getArrayValue($field_options, 'filter_type'); + if($filter_type == 'range') + { + $opts['format'] = $field_options['format']; + $add_fields[$field_name.'_rangefrom'] = $opts; + $add_fields[$field_name.'_rangeto'] = $opts; + } + + if ( !isset($object->VirtualFields[$field_name]) ) { + // adding caluclated field to format date directly in the query + if ( !isset($object->CalculatedFields) || !is_array($object->CalculatedFields) ) { + $object->CalculatedFields = Array(); + } + $object->CalculatedFields[$field_name.'_formatted'] = 'FROM_UNIXTIME('.'`%1$s`.'.$field_name.', \''.$this->SQLFormat($field_options['format']).'\')'; + $opts['format'] = $field_options['format']; + $opts['required'] = 0; + unset($opts['master_field']); + $add_fields[$field_name.'_formatted'] = $opts; + } + + $add_fields = array_merge_recursive2($add_fields, $object->VirtualFields); + $object->setVirtualFields($add_fields); + } + + function UpdateSubFields($field, $value, &$options, &$object) + { + if ( $sub_fields = getArrayValue($options, 'sub_fields') ) { + if( isset($value) && $value ) + { + $object->SetDBField( $sub_fields['date'], $value ); + $object->SetDBField( $sub_fields['time'], $value ); + } + } + } + + function UpdateMasterFields($field, $value, &$options, &$object) + { + // when in master field - set own value from sub_fields + if ( $sub_fields = getArrayValue($options, 'sub_fields') ) { + // if date is not empty, but time is empty - set time to 0, otherwise master field fomratter will complain + // when we have only date field on form, we need time hidden field always empty, don't ask me why! + if ( $object->GetDBField($sub_fields['date']) != '' && $object->GetDBField($sub_fields['time']) == '' ) { + $empty_time = getArrayValue($options,'empty_time'); + if($empty_time === false) $empty_time = adodb_mktime(0,0,0); + $object->SetDBField($sub_fields['time'], $empty_time); + } + + $input_format['date'] = $object->Fields[ $sub_fields['date'] ]['input_format']; + $input_format['time'] = $object->Fields[ $sub_fields['time'] ]['input_format']; + + $object->SetField($field, $object->GetField($sub_fields['date'], $input_format['date']).$options['date_time_separator'].$object->GetField($sub_fields['time'], $input_format['time'])); + } + // when in one of sub_fields - call update for master_field to update its value from sub_fields [are you following ? :) ] + elseif ($master_field = getArrayValue($options, 'master_field') ) { + $opt = $object->GetFieldOptions($master_field); + $this->UpdateMasterFields($master_field, null, $opt, $object); + } + } + +//function Format($value, $options, &$errors) + function Format($value, $field_name, &$object, $format=null) + { + if ( is_null($value) ) return ''; + if ( !is_numeric($value) ) return $value; // for leaving badly formatted date on the form + settype($value, 'int'); + if ( !is_int($value) ) return $value; + + $options = $object->GetFieldOptions($field_name); + if ( isset($format) ) $options['format'] = $format; + + return adodb_date($options['format'], $value); + } + + function HumanFormat($format) + { + $patterns = Array('/m/', + '/n/', + '/d/', + '/j/', + '/y/', + '/Y/', + '/h|H/', + '/g|G/', + '/i/', + '/s/', + '/a|A/'); + $replace = Array( 'mm', + 'm', + 'dd', + 'd', + 'yy', + 'yyyy', + 'hh', + 'h', + 'mm', + 'ss', + 'AM'); + $res = preg_replace($patterns, $replace, $format); + return $res; + } + + function SQLFormat($format) + { + $mapping = Array( + '/%/' => '%%', + '/(? '%p', // Lowercase Ante meridiem and Post meridiem => MySQL provides only uppercase + '/(? '%p', // Uppercase Ante meridiem and Post meridiem + '/(? '%d', // Day of the month, 2 digits with leading zeros + '/(? '%a', // A textual representation of a day, three letters + '/(? '%M', // A full textual representation of a month, such as January or March + '/(? '%l', // 12-hour format of an hour without leading zeros + '/(? '%k', // 24-hour format of an hour without leading zeros + '/(? '%h', // 12-hour format of an hour with leading zeros + '/(? '%H', // 24-hour format of an hour with leading zeros + '/(? '%i', // Minutes with leading zeros + '/(? 'N/A', // Whether or not the date is in daylights savings time + + '/(? 'N/A', // English ordinal suffix for the day of the month, 2 characters, see below + '/jS/' => '%D', // MySQL can't return separate suffix, but could return date with suffix + '/(? '%e', // Day of the month without leading zeros + '/(? '%W', // A full textual representation of the day of the week + '/(? 'N/A', // Whether it's a leap year + '/(? '%m', // Numeric representation of a month, with leading zeros + '/(? '%b', // A short textual representation of a month, three letters + '/(? '%c', // Numeric representation of a month, without leading zeros + '/(? 'N/A', // Difference to Greenwich time (GMT) in hours + '/(? 'N/A', // RFC 2822 formatted date + '/(? '%s', // Seconds, with leading zeros + // S and jS moved before j - see above + '/(? 'N/A', // Number of days in the given month + '/(? 'N/A', // Timezone setting of this machine + '/(? 'N/A', // Seconds since the Unix Epoch (January 1 1970 00:00:00 GMT) + '/(? '%w', // Numeric representation of the day of the week + '/(? '%v', // ISO-8601 week number of year, weeks starting on Monday (added in PHP 4.1.0) + '/(? '%Y', // A full numeric representation of a year, 4 digits + '/(? '%y', // A two digit representation of a year + '/(? 'N/A', // The day of the year (starting from 0) => MySQL starts from 1 + '/(? 'N/A', // Timezone offset in seconds. The offset for timezones west of UTC is always negative, and for those east of UTC is always positive. + ); + + $patterns = array_keys($mapping); + $replacements = array_values($mapping); + + $res = preg_replace($patterns, $replacements, $format); + return $res; + } + +//function Parse($value, $options, &$errors) + function Parse($value, $field_name, &$object) + { + $options = $object->GetFieldOptions($field_name); + + $dt_separator = getArrayValue($options,'date_time_separator'); + if($dt_separator) $value = trim($value, $dt_separator); + if($value == '') return NULL; + //return strtotime($value); + + $format = $options['input_format']; + if($dt_separator) $format = trim($format, $dt_separator); + + $object->FieldErrors[$field_name]['params'] = Array( $this->HumanFormat($format), adodb_date($format) ); + $object->FieldErrors[$field_name]['value'] = $value; + + $hour = 0; + $minute = 0; + $second = 0; + $month = 1; + $day = 1; + $year = 1970; + + $patterns['n'] = '([0-9]{1,2})'; + $patterns['m'] = '([0-9]{1,2})'; + $patterns['d'] = '([0-9]{1,2})'; + $patterns['j'] = '([0-9]{1,2})'; + $patterns['Y'] = '([0-9]{4})'; + $patterns['y'] = '([0-9]{2})'; + $patterns['G'] = '([0-9]{1,2})'; + $patterns['g'] = '([0-9]{1,2})'; + $patterns['H'] = '([0-9]{2})'; + $patterns['h'] = '([0-9]{2})'; + $patterns['i'] = '([0-9]{2})'; + $patterns['s'] = '([0-9]{2})'; + $patterns['a'] = '(am|pm)'; + $patterns['A'] = '(AM|PM)'; + + $holders_mask = eregi_replace('[a-zA-Z]{1}', '([a-zA-Z]{1})', $format); + if (!ereg($holders_mask, $format, $holders)) { + $object->FieldErrors[$field_name]['pseudo'] = 'bad_date_format'; + return $value; + } + + $values_mask = '/^'.str_replace('/','\/',$format).'$/'; + foreach ($patterns as $key => $val) { + $values_mask = ereg_replace($key, $val, $values_mask); + } + // echo " values_mask : $values_mask
"; + + if (!preg_match($values_mask, $value, $values)) { + $object->FieldErrors[$field_name]['pseudo'] = 'bad_date_format'; + return $value; + } + + for ($i = 1; $i < count($holders); $i++) { + switch ($holders[$i]) { + case 'n': + case 'm': + $month = $values[$i]; + $month = ereg_replace("^0{1}", '', $month); + break; + case 'd': + $day = $values[$i]; + $day = ereg_replace("^0{1}", '', $day); + break; + case 'Y': + $year = $values[$i]; + break; + case 'y': + $year = $values[$i] >= 70 ? 1900 + $values[$i] : 2000 + $values[$i]; + break; + case 'H': + case 'h': + case 'G': + case 'g': + $hour = $values[$i]; + $hour = ereg_replace("^0{1}", '', $hour); + break; + case 'i': + $minute = $values[$i]; + $minute = ereg_replace("^0{1}", '', $minute); + break; + case 's': + $second = $values[$i]; + $second = ereg_replace("^0{1}", '', $second); + break; + case 'a': + case 'A': + if ($hour <= 12) { // if AM/PM used with 24-hour - could happen :) + if ($values[$i] == 'pm' || $values[$i] == 'PM') { + $hour += 12; + if ($hour == 24) $hour = 12; + } + elseif ($values[$i] == 'am' || $values[$i] == 'AM') { + if ($hour == 12) $hour = 0; + } + } + break; + } + } + + //echo "day: $day, month: $month, year: $year, hour: $hour, minute: $minute
"; + + /*if (!($year >= 1970 && $year <= 2037)) { + $object->FieldErrors[$field_name]['pseudo'] = 'bad_date_format'; + return $value; + }*/ + + if (!($month >= 1 && $month <= 12)) { + $object->FieldErrors[$field_name]['pseudo'] = 'bad_date_format'; + return $value; + } + + $months_days = Array ( 1 => 31,2 => 28, 3 => 31, 4 => 30,5 => 31,6 => 30, 7 => 31, 8 => 31,9 => 30,10 => 31,11 => 30,12 => 31); + if ($year % 4 == 0) $months_days[2] = 29; + + if (!($day >=1 && $day <= $months_days[$month])) { + $object->FieldErrors[$field_name]['pseudo'] = 'bad_date_format'; + return $value; + } + + if (!($hour >=0 && $hour <= 23)) { + $object->FieldErrors[$field_name]['pseudo'] = 'bad_date_format'; + return $value; + } + + if (!($minute >=0 && $minute <= 59)) { + $object->FieldErrors[$field_name]['pseudo'] = 'bad_date_format'; + return $value; + } + + if (!($second >=0 && $second <= 59)) { + $object->FieldErrors[$field_name]['pseudo'] = 'bad_date_format'; + return $value; + } + // echo "day: $day, month: $month, year: $year, hour: $hour, minute: $minute
"; + return adodb_mktime($hour, $minute, $second, $month, $day, $year); + } + + function GetSample($field, &$options, &$object) + { + return $this->Format( adodb_mktime(), $field, $object, $options['input_format']); + } +} \ No newline at end of file Index: trunk/kernel/include/customfield.php =================================================================== diff -u -N -r4446 -r4758 --- trunk/kernel/include/customfield.php (.../customfield.php) (revision 4446) +++ trunk/kernel/include/customfield.php (.../customfield.php) (revision 4758) @@ -107,7 +107,7 @@ $table = $this->Application->getUnitOption($main_prefix.'-cdata', 'TableName'); if ($temp_table) { - $table = kTempTablesHandler::GetTempName($table); + $table = $this->Application->GetTempName($table); } $sql = 'SELECT * Index: trunk/kernel/units/modules/modules_event_handler.php =================================================================== diff -u -N -r4625 -r4758 --- trunk/kernel/units/modules/modules_event_handler.php (.../modules_event_handler.php) (revision 4625) +++ trunk/kernel/units/modules/modules_event_handler.php (.../modules_event_handler.php) (revision 4758) @@ -12,8 +12,8 @@ { $this->Application->SetVar($event->getPrefixSpecial(true).'_id', $event->Special); parent::OnItemBuild($event); - } - + } + /** * List with one record if special passed * @@ -26,14 +26,14 @@ $object->addFilter('current_module', 'Name = '.$event->Special); } } - + function mapEvents() { parent::mapEvents(); $this->eventMethods['OnMassApprove'] = 'moduleAction'; $this->eventMethods['OnMassDecline'] = 'moduleAction'; } - + /** * Disabled modules, but not In-Portal * @@ -44,13 +44,13 @@ if ($this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1)) { return; } - + $object =& $event->getObject( Array('skip_autoload' => true) ); $ids = $this->StoreSelectedIDs($event); - - + + if (!$ids) return true; - + $status_field = array_shift( $this->Application->getUnitOption($event->Prefix, 'StatusField') ); foreach($ids as $id) @@ -69,10 +69,11 @@ break; } } - + + $this->Application->UnitConfigReader->ResetParsedData(true); //true to reset sections cache also $event->SetRedirectParam('RefreshTree', 1); } - + } ?> \ No newline at end of file Index: trunk/admin/include/sections.php =================================================================== diff -u -N -r4446 -r4758 --- trunk/admin/include/sections.php (.../sections.php) (revision 4446) +++ trunk/admin/include/sections.php (.../sections.php) (revision 4758) @@ -379,7 +379,13 @@ } } } + + + + + + function page_title() { global $imagesURL,$adminURL, $objConfig; Index: trunk/core/kernel/utility/http_query.php =================================================================== diff -u -N -r4645 -r4758 --- trunk/core/kernel/utility/http_query.php (.../http_query.php) (revision 4645) +++ trunk/core/kernel/utility/http_query.php (.../http_query.php) (revision 4758) @@ -89,7 +89,7 @@ function Init($prefix, $special) { $this->AddAllVars(); - + $this->specialsToRemove = $this->Get('remove_specials'); if($this->specialsToRemove) { @@ -158,6 +158,13 @@ } } +// $this->AfterInit(); + } + function AfterInit() + { +// $this->processQueryString(); +// $this->convertPostEvents(); + // if ($this->Application->RewriteURLs()) { if ($this->Application->RewriteURLs() || $this->Get('_mod_rw_url_')) { if( $this->Application->isDebugMode() ) { @@ -288,8 +295,9 @@ foreach ($passed as $passed_prefix) { $event_manger->setQueryMap($passed_prefix); } + $this->Set('passed', implode(',', array_keys($event_manger->queryMaps))); } - + // get joined version (env var + mod rewrite parsed) $passed = $this->Application->GetVar('passed'); $env = $this->Application->BuildEnv( $this->Get('t'), $module_params, $passed, false, false ); @@ -299,297 +307,8 @@ function processRewriteURL() { - // directory_1_2_3/sc1/inlink/detail/3/l1_ka_asd.html - - $url = $this->Get('_mod_rw_url_'); - if( substr($url, -5) == '.html' ) $url = substr($url, 0, strlen($url) - 5 ); - - $url_parts = $url ? explode('/', $url) : Array(); - - $process_module = true; - if($this->Get('rewrite') == 'on' || !$url_parts) - { - // set default values - $defaults = Array('m_cat_id' => 0, 'm_cat_page' => 1, 'm_opener' => 's'); - foreach ($defaults as $default_key => $default_value) - { - if ($this->Get($default_key) == null) { - $this->Set($default_key, $default_value); - } - } - } - - if(!$url_parts) - { - $this->Application->Phrases = new PhrasesCache(); - $this->Application->VerifyLanguageId(); - $this->Application->Phrases->Init('phrases'); - $this->Application->VerifyThemeId(); - - $this->Set('t', $this->getDefaultTemplate('') ); - $this->finalizeParsing(Array('m')); - return false; - } - else - { - $this->Set('t', ''); - } - - $url_part = array_shift($url_parts); - - // match language - $sql = 'SELECT LanguageId FROM '.TABLE_PREFIX.'Language WHERE LOWER(PackName) = '.$this->Conn->qstr($url_part).' AND Enabled = 1'; - $language_id = $this->Conn->GetOne($sql); - $this->Application->Phrases = new PhrasesCache(); - if($language_id) - { - $this->Set('m_lang', $language_id); - $url_part = $url_parts ? array_shift($url_parts) : ''; // prepare next url part for parsing - } - - $this->Application->VerifyLanguageId(); - - // $this->Get('m_lang') ); - - // match theme - if($url_part) - { - $sql = 'SELECT ThemeId FROM '.TABLE_PREFIX.'Theme WHERE LOWER(Name) = '.$this->Conn->qstr($url_part).' AND Enabled = 1'; - $theme_id = $this->Conn->GetOne($sql); - if($theme_id) - { - $this->Set('m_theme', $theme_id); - $url_part = $url_parts ? array_shift($url_parts) : ''; // prepare next url part for parsing - } - } - $this->Application->VerifyThemeId(); // verify anyway - will set default if not found!!! - - // match category - $category_id = 0; - if($url_part) - { - $category_stack = Array(); - $category_found = false; - $category_path = ''; - $rets = Array(); // just in case someone has used this variable before - do - { - $category_path = trim($category_path.'/'.$url_part, '/'); - - if( preg_match('/(.*)_([\d]+)$/', $category_path, $rets) ) - { - $category_path = $rets[1]; - $this->Set('m_cat_page', $rets[2]); - } - - $sql = 'SELECT CategoryId - FROM '.TABLE_PREFIX.'Category - WHERE NamedParentPath = '.$this->Conn->qstr($category_path); - array_push($category_stack, $this->Conn->GetOne($sql) ); - $category_found = end($category_stack); - if($category_found) $url_part = array_shift($url_parts); - - }while ($category_found && $url_part); - - if (count($category_stack)) { - $category_id = array_pop($category_stack); // remove last not found category - if($category_id === false) - { - $category_id = array_pop($category_stack); - } - if($category_id) - { - $this->Set('m_cat_id', $category_id); - } - } - elseif (!$category_found && getArrayValue($rets, 2)) { - $url_part = array_shift($url_parts); - } - } - - - if (!$url_part) { - // no more parts left in url - $process_module = false; - $sql = 'SELECT CachedCategoryTemplate - FROM '.TABLE_PREFIX.'Category - WHERE CategoryId = '.$category_id; - $category_template = $this->Conn->GetOne($sql); - if ($category_template) { - $category_template = explode('/', $category_template); - $url_part = array_shift($category_template); - $url_parts = $category_template; - } - else { - $url_part = 'index'; - } - } - elseif ($url_part && count($url_parts) <= 1 && $category_id) { - // only filename left, no other parts - $process_module = false; - $sql = 'SELECT ParentPath, CachedItemTemplate, CachedCategoryTemplate - FROM '.TABLE_PREFIX.'Category - WHERE CategoryId = '.$category_id; - $category_data = $this->Conn->GetRow($sql); - - $root_category_id = array_shift( explode('|', substr($category_data['ParentPath'], 1, -1)) ); - $module_info = $this->Application->findModule('RootCat', $root_category_id); - if ($module_info) { - $module_prefix = $module_info['Var']; - $module_event = new kEvent($module_prefix.':ParseEnv', Array('url_parts' => array_merge(Array($url_part), $url_parts)) ); - $this->Application->HandleEvent($module_event); - - if ($module_event->status == erSUCCESS && $this->Get($module_prefix.'_id')) { - $item_template = $category_data['CachedItemTemplate']; - if ($item_template) { - $url_parts = explode('/', $item_template); - array_push($url_parts, $url_part); // save item's filename as not processed - $url_part = array_shift($url_parts); - } - } - elseif (!$module_event->getEventParam('url_parts')) { - // parseEnv has processed that param - $url_part = ''; - $category_template = $category_data['CachedCategoryTemplate']; - if ($category_template) { - $category_template = explode('/', $category_template); - $url_part = array_shift($category_template); - $url_parts = $category_template; - } - else { - $url_part = 'index'; - } - } - } - } - - // match module - $next_template = $this->Get('next_template'); - if($url_part || $next_template) - { - if($next_template) - { - $next_template_parts = explode('/', $next_template); - $module_folder = array_shift($next_template_parts); - } - else - { - $module_folder = $url_part; - } - - foreach ($this->Application->ModuleInfo as $module_name => $module_data) - { - if( trim($module_data['TemplatePath'], '/') == $module_folder ) - { - $module_prefix = $module_data['Var']; - break; - } - } - } - - // match template - $template_path = ''; - $template_found = false; - if($url_part) - { - // search for template in real template records - array_unshift($url_parts, $url_part); - $template_parts = $url_parts; - $url_parts = Array(); - do - { - $template_path = implode('/', $template_parts); - - $t_parts['path'] = dirname($template_path) == '.' ? '' : '/'.dirname($template_path); - $t_parts['file'] = basename($template_path); - - $sql = 'SELECT FileId - FROM '.TABLE_PREFIX.'ThemeFiles - WHERE (FilePath = '.$this->Conn->qstr($t_parts['path']).') AND - (FileName = '.$this->Conn->qstr($t_parts['file'].'.tpl').') AND - (ThemeId = '.$this->Get('m_theme').')'; - -// $sql = 'SELECT FileId FROM '.TABLE_PREFIX.'ThemeFiles WHERE CONCAT(FilePath, "/", FileName) = '.$this->Conn->qstr('/'.$template_path.'.tpl'); - $template_found = $this->Conn->GetOne($sql); - if(!$template_found) - { - array_unshift( $url_parts, array_pop($template_parts) ); - } - - }while (!$template_found && $template_parts); - - // try to find template in virtual templates in case if such ability exists - if ($this->Application->isModuleEnabled('In-CMS') && !$template_found) { - - $template_parts = $url_parts; - $url_parts = Array(); - do - { - $template_path = implode('/', $template_parts); - - $sql = 'SELECT PageId FROM '.TABLE_PREFIX.'Pages WHERE Path = '.$this->Conn->qstr($template_path); - $template_found = $this->Conn->GetOne($sql); - if(!$template_found) - { - array_unshift( $url_parts, array_pop($template_parts) ); - } - - }while (!$template_found && $template_parts); - - if (!$template_found && $this->Application->GetVar('admin')) { - // used when admin is clicking on non-existing in-cms page - $template_found = true; - $template_path = implode('/', $url_parts); - } - - } - } - - // guess template if no existing template found - if(!$template_found && isset($module_folder) && $module_folder) - { - // 1. try index template of module - $sql = 'SELECT FileId FROM '.TABLE_PREFIX.'ThemeFiles WHERE CONCAT(FilePath, "/", FileName) = '.$this->Conn->qstr('/'.$module_folder.'/index.tpl'); - $template_found = $this->Conn->GetOne($sql); - if($template_found) - { - $template_path = $module_folder.'/index'; - array_shift($url_parts); - } - else - { - // 2. return error template then - $template_found = true; - $template_path = $this->Application->ConfigValue('ErrorTemplate'); - if(!$template_path) $template_path = 'error_notfound'; - - header('HTTP/1.0 404 Not Found'); - } - } - - $this->Set('t', $this->getDefaultTemplate($template_found ? $template_path : '') ); - - // pass params left to module - - $this->Application->Phrases->Init('phrases'); - $passed = Array('m'); - $module_params = Array(); - if ( isset($module_prefix) ) { - $passed[] = $module_prefix; - $module_event = new kEvent($module_prefix.':ParseEnv', Array('url_parts' => $url_parts) ); - if ($process_module) { - $this->Application->HandleEvent($module_event); - } - $item_id = $this->Get($module_prefix.'_id'); - $module_params = Array($module_prefix.'_id' => $item_id ? $item_id : '0' ); - - if ($module_event->status == erFAIL) { - $not_found = $this->Application->ConfigValue('ErrorTemplate'); - $this->Set('t', $not_found ? $not_found : 'error_notfound' ); - } - } - - $this->finalizeParsing($passed, $module_params); + $mod_rw_helper = $this->Application->recallObject('ModRewriteHelper'); + $mod_rw_helper->processRewriteURL(); } function getDefaultTemplate($t) @@ -674,7 +393,8 @@ $prefix_special = array_shift($mixed_part); // l.pick, l $query_map = $event_manger->setQueryMap($prefix_special); - + $this->Set('passed', implode(',', array_keys($event_manger->queryMaps))); + // if config is not defined for prefix in QueryString, then don't process it if ($query_map) { foreach($query_map as $index => $var_name) @@ -759,7 +479,7 @@ else { // $value = iconv('UTF-8', 'windows-1257', $value); - + if( get_magic_quotes_gpc() ) $value = stripslashes($value); if(!$this->Admin) $value = htmlspecialchars($value); $array[$key] = $value; @@ -768,7 +488,7 @@ } return $array; } - + /** * Returns all $_GET array excluding system parameters, that are not allowed to be passed through generated urls * @@ -784,7 +504,7 @@ } return $ret; } - + function writeRequestLog($filename) { $folder_path = dirname(FULL_PATH.'/'.$filename); @@ -794,17 +514,17 @@ $session =& $this->Application->recallObject('Session'); $user_id = $session->GetField('PortalUserId'); $admin_mark = $this->Application->IsAdmin() ? 'ADMIN' : 'FRONT'; - + $data = '['.date('D M d H:i:s Y').'] '.$admin_mark.'; ip: '.$_SERVER['REMOTE_ADDR'].'; user_id: '.$user_id.'; sid: '.$this->Application->GetSID().'; request: '."\n"; if ($this->Get) { $data .= "_GET:\n".print_r($this->Get, true); } - + if ($this->Post) { $data .= "_POST:\n".print_r($this->Post, true); } $data .= str_repeat('=', 100)."\n"; - + fwrite($fp, $data); fclose($fp); } @@ -816,7 +536,7 @@ trigger_error('Requrest Log directory not writable', E_USER_WARNING); } } - + } ?> \ No newline at end of file Index: trunk/core/units/users/users_item.php =================================================================== diff -u -N -r4524 -r4758 --- trunk/core/units/users/users_item.php (.../users_item.php) (revision 4524) +++ trunk/core/units/users/users_item.php (.../users_item.php) (revision 4758) @@ -106,7 +106,7 @@ $ret = parent::Create($force_id, $system_create); if ($ret) { // find out how to syncronize user only when it's copied to live table - $sync_manager =& $this->Application->recallObject('UsersSyncronizeManager', null, Array(), 'InPortalSyncronize'); + $sync_manager =& $this->Application->recallObjectP('UsersSyncronizeManager', null, Array(), 'InPortalSyncronize'); $sync_manager->performAction('createUser', $this->FieldValues); } return $ret; @@ -118,7 +118,7 @@ $ret = parent::Update($id, $system_update); if ($ret) { // find out how to syncronize user only when it's copied to live table - $sync_manager =& $this->Application->recallObject('UsersSyncronizeManager', null, Array(), 'InPortalSyncronize'); + $sync_manager =& $this->Application->recallObjectP('UsersSyncronizeManager', null, Array(), 'InPortalSyncronize'); $sync_manager->performAction('updateUser', $this->FieldValues); } return $ret; @@ -134,7 +134,7 @@ { $ret = parent::Delete($id); if ($ret) { - $sync_manager =& $this->Application->recallObject('UsersSyncronizeManager', null, Array(), 'InPortalSyncronize'); + $sync_manager =& $this->Application->recallObjectP('UsersSyncronizeManager', null, Array(), 'InPortalSyncronize'); $sync_manager->performAction('deleteUser', $this->FieldValues); } Index: trunk/kernel/units/languages/import_xml.php =================================================================== diff -u -N -r4712 -r4758 --- trunk/kernel/units/languages/import_xml.php (.../import_xml.php) (revision 4712) +++ trunk/kernel/units/languages/import_xml.php (.../import_xml.php) (revision 4758) @@ -166,7 +166,7 @@ $sql = 'SELECT %s FROM %s WHERE PackName = %s'; $sql = sprintf( $sql, $this->lang_object->IDField, - kTempTablesHandler::GetLiveName($this->lang_object->TableName), + $this->Application->GetLiveName($this->lang_object->TableName), $this->Conn->qstr($this->current_language['PackName']) ); $language_id = $this->Conn->GetOne($sql); if($language_id) Index: trunk/core/kernel/event_manager.php =================================================================== diff -u -N -r4689 -r4758 --- trunk/core/kernel/event_manager.php (.../event_manager.php) (revision 4689) +++ trunk/core/kernel/event_manager.php (.../event_manager.php) (revision 4758) @@ -70,9 +70,9 @@ */ var $afterHooks = Array(); - + var $recursionStack = Array(); - + function kEventManager() { parent::kBase(); @@ -107,7 +107,8 @@ unset($this->queryMaps[$prefix]); } - $this->Application->SetVar('passed', implode(',', array_keys($this->queryMaps)) ); +// 'passed' is set later in ProcessRequest - do we really need it here? (it breakes HTTPQuery initialization...) +// $this->Application->SetVar('passed', implode(',', array_keys($this->queryMaps)) ); return $query_map; } @@ -165,18 +166,18 @@ $event_key = $event->getPrefixSpecial().':'.$event->Name; return in_array($event_key, $this->recursionStack) ? true : false; } - + function pushEvent(&$event) { $event_key = $event->getPrefixSpecial().':'.$event->Name; array_push($this->recursionStack, $event_key); } - + function popEvent() { array_pop($this->recursionStack); } - + /** * Allows to process any type of event * @@ -188,11 +189,17 @@ if ($this->isRecursion($event)) { return true; } - + $this->pushEvent($event); - + if( !$this->Application->prefixRegistred($event->Prefix) ) { + $unit_config_reader =& $this->Application->recallObject('kUnitConfigReader'); + $unit_config_reader->loadConfig($event->Prefix); + } + + if( !$this->Application->prefixRegistred($event->Prefix) ) + { trigger_error('Prefix '.$event->Prefix.' not registred (requested event '.$event->Name.')', E_USER_NOTICE); return false; } @@ -211,14 +218,14 @@ } $this->popEvent(); - + return true; } function ProcessRequest() { $this->processOpener(); - + // 1. get events from $_POST $events = $this->Application->GetVar('events'); if ($events === false) $events = Array(); @@ -263,22 +270,22 @@ $event->redirect_params = Array('opener'=>'s', 'pass'=>'all'); $event->redirect = true; - + $event_handler =& $this->Application->recallObject($event->Prefix.'_EventHandler'); $event->setEventParam('top_prefix', $this->Application->GetTopmostPrefix($event->Prefix)); if (($this->Application->GetVar('u_id') == -1) || $event_handler->CheckPermission($event)) { $this->HandleEvent($event); } - + if ($event->status == erPERM_FAIL) { $event->redirect = $this->Application->IsAdmin() ? 'no_permission' : $this->Application->ConfigValue('NoPermissionTemplate'); - + // restore stuff, that processOpener() changed $this->Application->RestoreVar('opener_stack'); // don't save last_template, because no_permission template does js history.back and could cause invalid opener_stack content $this->Application->SetVar('skip_last_template', 1); } - + // should do redirect but to no_permissions template if ( ($event->status == erSUCCESS || $event->status == erPERM_FAIL) && ($event->redirect === true || strlen($event->redirect) > 0)) { $this->Application->Redirect($event->redirect, $event->redirect_params, null, $event->redirect_script); @@ -319,7 +326,7 @@ default: // "s/0," stay on same deep level break; } - + if (!$this->Application->GetVar('skip_last_template')) { $this->Application->SetVar('m_opener', 's'); } @@ -397,7 +404,7 @@ // use same special as master event $hook['DoSpecial'] = $event->Special; } - + $prefix_special = rtrim($hook['DoPrefix'].'_'.$hook['DoSpecial'], '_'); if ( $hook['Conditional'] && !$this->Application->GetVar($prefix_special) ) { continue; @@ -463,7 +470,7 @@ $sql = 'REPLACE INTO '.TABLE_PREFIX.'Cache (VarName,Data,Cached) VALUES (%s,%s,%s)'; $this->Conn->Query( sprintf($sql, $this->Conn->qstr('RegularEventRuns'), $this->Conn->qstr(serialize($event_last_runs)), adodb_mktime() ) ); } - + /** * Allows to determine, that required event is beeing processed right now * Index: trunk/kernel/units/general/helpers/sections_helper.php =================================================================== diff -u -N -r4702 -r4758 --- trunk/kernel/units/general/helpers/sections_helper.php (.../sections_helper.php) (revision 4702) +++ trunk/kernel/units/general/helpers/sections_helper.php (.../sections_helper.php) (revision 4758) @@ -5,14 +5,14 @@ * */ class kSectionsHelper extends kHelper { - + /** * Holds information about all sections * * @var Array */ var $Tree = Array(); - + /** * Set's prefix and special * @@ -33,8 +33,21 @@ */ function BuildTree() { + $unit_config_reader = false; + if (defined('CACHE_PARSED_CONFIGS') && CACHE_PARSED_CONFIGS) { + $data = $this->Conn->GetRow('SELECT Data, Cached FROM '.TABLE_PREFIX.'Cache WHERE VarName = "sections_parsed"'); + if ($data) { + $this->Tree = unserialize($data['Data']); + return ; + } + $this->Application->UnitConfigReader->includeConfigFiles(); + } + $this->Tree = Array(); - $unit_config_reader =& $this->Application->recallObject('kUnitConfigReader'); + if (!$unit_config_reader) { + $unit_config_reader =& $this->Application->recallObject('kUnitConfigReader'); + } + $prefixes = array_keys($unit_config_reader->configData); foreach ($prefixes as $prefix) { $config =& $unit_config_reader->configData[$prefix]; @@ -47,9 +60,9 @@ // we could also skip not allowed sections here in future $section_params['SectionPrefix'] = $prefix; $section_params['url']['m_opener'] = 'r'; - + $pass_section = getArrayValue($section_params, 'url', 'pass_section'); - + if ($pass_section) { unset($section_params['url']['pass_section']); $section_params['url']['section'] = $section_name; @@ -73,8 +86,13 @@ } } } + + if (defined('CACHE_PARSED_CONFIGS') && CACHE_PARSED_CONFIGS) { + $this->Conn->Query('REPLACE '.TABLE_PREFIX.'Cache (VarName, Data, Cached) VALUES ("sections_parsed", '.$this->Conn->qstr(serialize($this->Tree)).', '.adodb_mktime().')'); + } + } - + /** * Returns details information about section * Index: trunk/core/kernel/utility/formatters/filesize_formatter.php =================================================================== diff -u -N --- trunk/core/kernel/utility/formatters/filesize_formatter.php (revision 0) +++ trunk/core/kernel/utility/formatters/filesize_formatter.php (revision 4758) @@ -0,0 +1,26 @@ += 1099511627776) { + $return = round($value / 1024 / 1024 / 1024 / 1024, 2); + $suffix = "Tb"; + } elseif ($value >= 1073741824) { + $return = round($value / 1024 / 1024 / 1024, 2); + $suffix = "Gb"; + } elseif ($value >= 1048576) { + $return = round($value / 1024 / 1024, 2); + $suffix = "Mb"; + } elseif ($value >= 1024) { + $return = round($value / 1024, 2); + $suffix = "Kb"; + } else { + $return = $value; + $suffix = "B"; + } + $return .= ' '.$suffix; + return $return; + } +} \ No newline at end of file Index: trunk/core/kernel/utility/formatters/upload_formatter.php =================================================================== diff -u -N --- trunk/core/kernel/utility/formatters/upload_formatter.php (revision 0) +++ trunk/core/kernel/utility/formatters/upload_formatter.php (revision 4758) @@ -0,0 +1,129 @@ +DestinationPath) + { + $this->FullPath = FULL_PATH.$this->DestinationPath; + } + parent::kBase(); + } + + +//function Parse($value, $options, &$errors) + function Parse($value, $field_name, &$object) + { + $ret = ''; + $options = $object->GetFieldOptions($field_name); + + if(getArrayValue($options, 'upload_dir')) + { + $this->DestinationPath = $options['upload_dir']; + $this->FullPath = FULL_PATH.$this->DestinationPath; + } + + if (getArrayValue($value, 'upload') && getArrayValue($value, 'error') == UPLOAD_ERR_NO_FILE) + { + return getArrayValue($value, 'upload'); + } + + if ( is_array($value) && $value['size'] ) + { + if ( is_array($value) && $value['error'] === UPLOAD_ERR_OK ) + { + if ( getArrayValue($options, 'allowed_types') && !in_array($value['type'], $options['allowed_types']) ) + { + $object->FieldErrors[$field_name]['pseudo'] = 'bad_file_format'; + } + elseif ( $value['size'] > ($options['max_size'] ? $options['max_size'] : MAX_UPLOAD_SIZE) ) + { + $object->FieldErrors[$field_name]['pseudo'] = 'bad_file_size'; + } + elseif ( !is_writable($this->FullPath) ) + { + $object->FieldErrors[$field_name]['pseudo'] = 'cant_save_file'; + } + else + { + $real_name = $this->ValidateFileName($this->FullPath, $value['name']); + $file_name = $this->FullPath.$real_name; + if ( !move_uploaded_file($value['tmp_name'], $file_name) ) + { + $object->FieldErrors[$field_name]['pseudo'] = 'cant_save_file'; + } + else + { + @chmod($file_name, 0666); + if(getArrayValue($options, 'size_field')) + { + $object->SetDBField($options['size_field'], $value['size']); + } + if(getArrayValue($options, 'orig_name_field')) + { + $object->SetDBField($options['orig_name_field'], $value['name']); + } + if(getArrayValue($options, 'content_type_field')) + { + $object->SetDBField($options['content_type_field'], $value['type']); + } + $ret = getArrayValue($options, 'upload_dir') ? $real_name : $this->DestinationPath.$real_name; + } + } + } + else + { + $object->FieldErrors[$field_name]['pseudo'] = 'cant_save_file'; + } + } + else + { + if(getArrayValue($options, 'required')) + { + $object->FieldErrors[$field_name]['pseudo'] = 'required'; + } + } + + if ($value['error'] && !( $value['error'] == UPLOAD_ERR_NO_FILE ) && !$object->FieldErrors[$field_name]['pseudo']) + { + $object->FieldErrors[$field_name]['pseudo'] = 'cant_save_file'; + } + + return $ret; + } + + function ValidateFileName($path, $name) + { + $parts = pathinfo($name); + $ext = '.'.$parts['extension']; + $filename = substr($parts['basename'], 0, -strlen($ext)); + $new_name = $filename.$ext; + while ( file_exists($path.'/'.$new_name) ) + { + if ( preg_match("/({$filename}_)([0-9]*)($ext)/", $new_name, $regs) ) { + $new_name = $regs[1].($regs[2]+1).$regs[3]; + } + else { + $new_name = $filename.'_1'.$ext; + } + } + return $new_name; + } + +} + +class kPictureFormatter extends kUploadFormatter +{ + + function kPictureFormatter() + { + $this->NakeLookupPath = IMAGES_PATH; + $this->DestinationPath = IMAGES_PENDING_PATH; + parent::kUploadFormatter(); + } + +} \ No newline at end of file Index: trunk/core/kernel/application.php =================================================================== diff -u -N -r4674 -r4758 --- trunk/core/kernel/application.php (.../application.php) (revision 4674) +++ trunk/core/kernel/application.php (.../application.php) (revision 4758) @@ -63,6 +63,14 @@ var $ConfigHash = Array(); /** + * Ids of config variables used in current run (for caching) + * + * @var Array + * @access private + */ + var $ConfigCacheIds = array(); + + /** * Reference to debugger * * @var Debugger @@ -90,15 +98,47 @@ * @var kDBConnection */ var $Conn = null; - + /** * Maintains list of user-defined error handlers * * @var Array */ var $errorHandlers = Array(); + + // performance needs: /** + * Holds a refererence to httpquery + * + * @var kHttpQuery + */ + var $HttpQuery = null; + + /** + * Holds a reference to UnitConfigReader + * + * @var kUnitConfigReader + */ + var $UnitConfigReader = null; + + /** + * Holds a reference to Session + * + * @var kSession + */ + var $Session = null; + + /** + * Holds a ref to kEventManager + * + * @var kEventManager + */ + var $EventManager = null; + + var $Application = null; + + /** * Returns kApplication instance anywhere in the script. * * This method should be used to get single kApplication object instance anywhere in the @@ -128,6 +168,7 @@ safeDefine('APPLICATION_CLASS', 'kApplication'); $class = APPLICATION_CLASS; $instance = new $class(); + $instance->Application =& $instance; } return $instance; } @@ -138,22 +179,32 @@ * @param string $field * @param mixed $value * @param string field value to returns, if not specified, then return all fields + * @param string field to return + * @param string field case-insensitive compare * @return Array */ - function findModule($field, $value, $return_field = null) + function findModule($field, $value, $return_field = null, $ci=false) { $found = false; foreach ($this->ModuleInfo as $module_name => $module_info) { - if ($module_info[$field] == $value) { - $found = true; - break; + if ($ci) { + if (strtolower($module_info[$field]) == strtolower($value)) { + $found = true; + break; + } } + else { + if ($module_info[$field] == $value) { + $found = true; + break; + } + } } - + if ($found) { return isset($return_field) ? $module_info[$return_field] : $module_info; } - + return false; } @@ -170,17 +221,15 @@ { if($this->InitDone) return false; - if( $this->isDebugMode() && dbg_ConstOn('DBG_PROFILE_MEMORY') ) + if( defined('DEBUG_MODE') && $this->isDebugMode() && dbg_ConstOn('DBG_PROFILE_MEMORY') ) { $this->Debugger->appendMemoryUsage('Application before Init:'); } - if( !$this->isDebugMode() && !constOn('DBG_ZEND_PRESENT') ) { error_reporting(0); ini_set('display_errors', 0); } - if( !constOn('DBG_ZEND_PRESENT') ) { $error_handler = set_error_handler( Array(&$this,'handleError') ); @@ -190,31 +239,44 @@ $this->Conn = new kDBConnection(SQL_TYPE, Array(&$this, 'handleSQLError') ); $this->Conn->Connect(SQL_SERVER, SQL_USER, SQL_PASS, SQL_DB); $this->Conn->debugMode = $this->isDebugMode(); - - $this->ConfigHash = $this->Conn->GetCol('SELECT VariableValue, VariableName FROM '.TABLE_PREFIX.'ConfigurationValues', 'VariableName'); + $this->Factory = new kFactory(); + $this->registerDefaultClasses(); + $this->Phrases = new PhrasesCache(); + $this->EventManager =& $this->Factory->makeClass('EventManager'); + $this->Factory->Storage['EventManager'] =& $this->EventManager; + $this->RegisterDefaultBuildEvents(); + $this->SetDefaultConstants(); + + $this->UnitConfigReader =& $this->recallObject('kUnitConfigReader'); + $this->UnitConfigReader->scanModules(MODULES_PATH); + $this->registerModuleConstants(); + + // extracted out of SetDefaultConstants because it uses ConfigValue which is read only in UnitConfigReader (optimization) + $this->SetAdminDirectory(); + $rewrite_on = $this->ConfigValue('UseModRewrite'); // admin=1 - when front is browsed using admin session $admin_on = getArrayValue($_REQUEST, 'admin') || $this->IsAdmin(); define('MOD_REWRITE', $rewrite_on && !$admin_on ? 1 : 0); - $this->Factory = new kFactory(); - - $this->registerDefaultClasses(); - $this->refreshModuleInfo(); - $this->SetDefaultConstants(); - - // 1. to read configs before doing any recallObject - $config_reader =& $this->recallObject('kUnitConfigReader'); + $this->HttpQuery =& $this->recallObject('HTTPQuery'); + $this->Session =& $this->recallObject('Session'); + $this->HttpQuery->AfterInit(); + + $this->LoadCache(); + $this->InitConfig(); + // Module items are recalled during url parsing & PhrasesCache is needed already there, // because it's used in their build events. That's why phrases cache initialization is // called from kHTTPQuery in case when mod_rewrite is used if (!$this->RewriteURLs()) { $this->Phrases = new PhrasesCache(); - $this->Phrases->Init('phrases'); } - + + $this->Phrases->Init('phrases'); + if(!$this->RecallVar('UserGroups')) { $session =& $this->recallObject('Session'); $user_groups = trim($session->GetField('GroupList'), ','); @@ -229,6 +291,8 @@ $language =& $this->recallObject( 'lang.current', null, Array('live_table' => true) ); + $this->HandleEvent( new kEvent('visits:OnRegisterVisit') ); + $this->ValidateLogin(); if($this->isDebugMode()) { @@ -246,30 +310,35 @@ FROM '.TABLE_PREFIX.'Modules WHERE '.$modules_helper->getWhereClause().' ORDER BY LoadOrder'; - + $this->ModuleInfo = $this->Conn->Query($sql, 'Name'); + $this->registerModuleConstants(); } - + /** * Checks if passed language id if valid and sets it to primary otherwise * */ function VerifyLanguageId() { $language_id = $this->GetVar('m_lang'); - if ($language_id) { - $table = $this->getUnitOption('lang', 'TableName'); - $id_field = $this->getUnitOption('lang', 'IDField'); - $sql = 'SELECT '.$id_field.' - FROM '.$table.' - WHERE Enabled = 1'; - $language_ids = $this->Conn->GetCol($sql); + if (!$language_id) { + $language_id = $this->GetDefaultLanguageId(); + if (!$language_id) { + if (!$this->Application->IsAdmin()) { + die ('No Primary Language Selected'); + } + else { + $language_id = 1; + } + } } - - if (!$language_id || !in_array($language_id, $language_ids)) { - $this->SetVar('m_lang', $this->GetDefaultLanguageId() ); + $this->SetVar('lang.current_id', $language_id ); + $this->SetVar('m_lang', $language_id ); + $lang =& $this->recallObject('lang.current'); + if ( !$lang->IsLoaded() || (!$this->Application->IsAdmin() && !$lang->GetDBField('Enabled')) ) { + die ('Unknown or disabled language'); } - $this->SetVar('lang.current_id', $this->GetVar('m_lang') ); } /** @@ -278,20 +347,21 @@ */ function VerifyThemeId() { + if ($this->Application->IsAdmin()) return; + $theme_id = $this->GetVar('m_theme'); - if ($theme_id) { - $table = $this->getUnitOption('theme', 'TableName'); - $id_field = $this->getUnitOption('theme', 'IDField'); - $sql = 'SELECT '.$id_field.' - FROM '.$table.' - WHERE Enabled = 1'; - $theme_ids = $this->Conn->GetCol($sql); + if (!$theme_id) { + $theme_id = $this->GetDefaultThemeId(); + if (!$theme_id) { + die('No Primary Theme Selected'); + } } - - if (!$theme_id || !in_array($theme_id, $theme_ids)) { - $this->SetVar('m_theme', $this->GetDefaultThemeId() ); + $this->SetVar('m_theme', $theme_id); + $this->SetVar('theme.current_id', $theme_id ); // KOSTJA: this is to fool theme' getPassedId + $theme =& $this->recallObject('theme.current'); + if (!$theme->IsLoaded() || !$theme->GetDBField('Enabled')) { + die('Unknown or disabled theme'); } - $this->SetVar('theme.current_id', $this->GetVar('m_theme') ); } function GetDefaultLanguageId() @@ -350,6 +420,11 @@ */ function RegisterDefaultClasses() { + + $this->registerClass('kTempTablesHandler', KERNEL_PATH.'/utility/temp_handler.php'); + $this->registerClass('kEventManager', KERNEL_PATH.'/event_manager.php', 'EventManager'); + $this->registerClass('kUnitConfigReader', KERNEL_PATH.'/utility/unit_config_reader.php'); + $this->registerClass('kArray', KERNEL_PATH.'/utility/params.php'); $this->registerClass('Params', KERNEL_PATH.'/utility/params.php'); @@ -359,12 +434,11 @@ $this->registerClass('Session', KERNEL_PATH.'/session/session.php'); $this->registerClass('SessionStorage', KERNEL_PATH.'/session/session.php'); - $this->registerClass('kEventManager', KERNEL_PATH.'/event_manager.php', 'EventManager'); - $this->registerClass('kUnitConfigReader', KERNEL_PATH.'/utility/unit_config_reader.php'); + $this->registerClass('Params', KERNEL_PATH.'/utility/params.php', 'kActions'); - $this->registerClass('kFormatter', KERNEL_PATH.'/utility/formatters.php'); + /*$this->registerClass('kFormatter', KERNEL_PATH.'/utility/formatters.php'); $this->registerClass('kOptionsFormatter', KERNEL_PATH.'/utility/formatters.php'); $this->registerClass('kUploadFormatter', KERNEL_PATH.'/utility/formatters.php'); $this->registerClass('kPictureFormatter', KERNEL_PATH.'/utility/formatters.php'); @@ -375,26 +449,22 @@ $this->registerClass('kCCDateFormatter', KERNEL_PATH.'/utility/formatters.php'); $this->registerClass('kUnitFormatter', KERNEL_PATH.'/utility/formatters.php'); $this->registerClass('kFilesizeFormatter', KERNEL_PATH.'/utility/formatters.php'); - $this->registerClass('kSerializedFormatter', KERNEL_PATH.'/utility/formatters.php'); + $this->registerClass('kSerializedFormatter', KERNEL_PATH.'/utility/formatters.php');*/ - $this->registerClass('kTempTablesHandler', KERNEL_PATH.'/utility/temp_handler.php'); - $event_manager =& $this->recallObject('EventManager'); - $event_manager->registerBuildEvent('kTempTablesHandler', 'OnTempHandlerBuild'); - - $this->registerClass('TemplatesCache', KERNEL_PATH.'/parser/template.php'); - $this->registerClass('Template', KERNEL_PATH.'/parser/template.php'); - $this->registerClass('TemplateParser', KERNEL_PATH.'/parser/template_parser.php'); - - $this->registerClass('kMainTagProcessor', KERNEL_PATH.'/processors/main_processor.php','m_TagProcessor'); - $this->registerClass('kMultipleFilter', KERNEL_PATH.'/utility/filters.php'); $this->registerClass('kDBList', KERNEL_PATH.'/db/dblist.php'); $this->registerClass('kDBItem', KERNEL_PATH.'/db/dbitem.php'); $this->registerClass('kDBEventHandler', KERNEL_PATH.'/db/db_event_handler.php'); - $this->registerClass('kDBTagProcessor', KERNEL_PATH.'/db/db_tag_processor.php'); $this->registerClass('kTagProcessor', KERNEL_PATH.'/processors/tag_processor.php'); + $this->registerClass('kMainTagProcessor', KERNEL_PATH.'/processors/main_processor.php','m_TagProcessor', 'kTagProcessor'); + $this->registerClass('kDBTagProcessor', KERNEL_PATH.'/db/db_tag_processor.php', null, 'kTagProcessor'); + + $this->registerClass('TemplatesCache', KERNEL_PATH.'/parser/template.php'); + $this->registerClass('Template', KERNEL_PATH.'/parser/template.php'); + $this->registerClass('TemplateParser', KERNEL_PATH.'/parser/template_parser.php',null, 'kDBTagProcessor'); + $this->registerClass('kEmailMessage', KERNEL_PATH.'/utility/email.php'); $this->registerClass('kSmtpClient', KERNEL_PATH.'/utility/smtp_client.php'); @@ -405,6 +475,12 @@ $this->registerClass('FCKeditor', FULL_PATH.'/admin/editor/cmseditor/fckeditor.php'); // need this? } + function RegisterDefaultBuildEvents() + { + $event_manager =& $this->recallObject('EventManager'); + $event_manager->registerBuildEvent('kTempTablesHandler', 'OnTempHandlerBuild'); + } + /** * Returns item's filename that corresponds id passed. If possible, then get it from cache * @@ -418,13 +494,13 @@ if ($filename === false) { $table = $this->getUnitOption($prefix, 'TableName'); $id_field = $this->getUnitOption($prefix, 'IDField'); - + if ($prefix == 'c') { if(!$id) { $this->setCache('filenames', $prefix.'_'.$id, ''); return ''; } - + // this allows to save 2 sql queries for each category $sql = 'SELECT NamedParentPath, CachedCategoryTemplate, CachedItemTemplate FROM '.$table.' @@ -444,8 +520,8 @@ } return $filename; } - - + + /** * Adds new value to cache $cache_name and identified by key $key * @@ -458,7 +534,7 @@ $cache =& $this->recallObject('Cache'); $cache->setCache($cache_name, $key, $value); } - + /** * Returns cached $key value from cache named $cache_name * @@ -480,12 +556,13 @@ function SetDefaultConstants() { safeDefine('SERVER_NAME', $_SERVER['HTTP_HOST']); + } + function SetAdminDirectory() + { $admin_dir = $this->ConfigValue('AdminDirectory'); if(!$admin_dir) $admin_dir = 'admin'; safeDefine('ADMIN_DIR', $admin_dir); - - $this->registerModuleConstants(); } /** @@ -541,14 +618,14 @@ // for permission checking in events & templates $this->LinkVar('module'); // for common configuration templates $this->LinkVar('section'); // for common configuration templates - + if ($this->GetVar('m_opener') == 'p') { $this->LinkVar('main_prefix'); // window prefix, that opened selector $this->LinkVar('dst_field'); // field to set value choosed in selector $this->LinkVar('return_template'); // template to go, when something was coosen from popup (from finalizePopup) } } - + if (!$this->RequestProcessed) $this->ProcessRequest(); $this->InitParser(); @@ -606,15 +683,15 @@ //eval("?".">".$this->HTML); echo $this->HTML; - $this->Phrases->UpdateCache(); + $this->UpdateCache(); flush(); - + if ($this->isDebugMode() && dbg_ConstOn('DBG_CACHE')) { $cache =& $this->recallObject('Cache'); $cache->printStatistics(); } - + $event_manager =& $this->recallObject('EventManager'); $event_manager->RunRegularEvents(reAFTER); @@ -661,8 +738,8 @@ */ function GetVar($name, $default = false) { - $http_query =& $this->recallObject('HTTPQuery'); - return $http_query->Get($name, $default); +// $http_query =& $this->recallObject('HTTPQuery'); + return isset($this->HttpQuery->_Params[$name]) ? $this->HttpQuery->_Params[$name] : $default; } /** @@ -673,8 +750,7 @@ */ function GetVars() { - $http_query =& $this->recallObject('HTTPQuery'); - return $http_query->GetParams(); + return $this->HttpQuery->GetParams(); } /** @@ -692,42 +768,39 @@ */ function SetVar($var,$val) { - $http_query =& $this->recallObject('HTTPQuery'); - $http_query->Set($var,$val); +// $http_query =& $this->recallObject('HTTPQuery'); + return $this->HttpQuery->Set($var,$val); } /** - * Deletes Session variable + * Deletes kHTTPQuery variable * * @param string $var + * @todo think about method name */ - function RemoveVar($var) + function DeleteVar($var) { - $session =& $this->recallObject('Session'); - return $session->RemoveVar($var); + return $this->HttpQuery->Remove($var); } /** - * Restores Session variable to it's db version + * Deletes Session variable * * @param string $var */ - function RestoreVar($var) + function RemoveVar($var) { - $session =& $this->recallObject('Session'); - return $session->RestoreVar($var); + return $this->Session->RemoveVar($var); } - + /** - * Deletes kHTTPQuery variable + * Restores Session variable to it's db version * * @param string $var - * @todo think about method name */ - function DeleteVar($var) + function RestoreVar($var) { - $http_query =& $this->recallObject('HTTPQuery'); - return $http_query->Remove($var); + return $this->Session->RestoreVar($var); } /** @@ -743,8 +816,7 @@ */ function RecallVar($var,$default=false) { - $session =& $this->recallObject('Session'); - return $session->RecallVar($var,$default); + return $this->Session->RecallVar($var,$default); } /** @@ -759,13 +831,13 @@ function StoreVar($var, $val) { $session =& $this->recallObject('Session'); - $session->StoreVar($var, $val); + $this->Session->StoreVar($var, $val); } function StoreVarDefault($var, $val) { $session =& $this->recallObject('Session'); - $session->StoreVarDefault($var, $val); + $this->Session->StoreVarDefault($var, $val); } /** @@ -871,19 +943,19 @@ unset($params['index_file']); return $index_file; } - + if (isset($index_file)) { return $index_file; } - + if (defined('INDEX_FILE')) { return INDEX_FILE; } $cut_prefix = trim(BASE_PATH, '/').'/'.trim($prefix, '/'); return trim(preg_replace('/'.preg_quote($cut_prefix, '/').'(.*)/', '\\1', $_SERVER['PHP_SELF']), '/'); } - + /** * Return href for template * @@ -909,9 +981,9 @@ if ( $this->IsAdmin() && $prefix == '') $prefix = '/admin'; if ( $this->IsAdmin() && $prefix == '_FRONT_END_') $prefix = ''; - + $index_file = $this->getIndexFile($prefix, $index_file, $params); - + $ssl = isset($params['__SSL__']) ? $params['__SSL__'] : null; if ($ssl !== null) { $session =& $this->recallObject('Session'); @@ -987,7 +1059,7 @@ return $ret; } - + /** * Returns sorted array of passed prefixes (to build url from) * @@ -997,14 +1069,14 @@ function getPassInfo($pass = 'all') { $pass = str_replace('all', trim($this->GetVar('passed'), ','), $pass); - + if (!$pass) { return Array(); } - + $pass_info = array_unique( explode(',', $pass) ); // array( prefix[.special], prefix[.special] ... sort($pass_info, SORT_STRING); // to be prefix1,prefix1.special1,prefix1.special2,prefix3.specialX - + // ensure that "m" prefix is at the beginning $main_index = array_search('m', $pass_info); if ($main_index !== false) { @@ -1013,7 +1085,7 @@ } return $pass_info; } - + function BuildEnv_NEW($t, $params, $pass = 'all', $pass_events = false) { // $session =& $this->recallObject('Session'); @@ -1059,7 +1131,7 @@ } } $ret = $this->BuildModuleEnv_NEW('m', $params, $pass_events).$ret; - + $ret = trim($ret, '/').'.html'; if($env) $params[ENV_VAR_NAME] = ltrim($env, ':'); } @@ -1087,21 +1159,21 @@ return $ret; } - + function BuildModuleEnv_NEW($prefix_special, &$params, $pass_events = false) { $event_params = Array('pass_events' => $pass_events, 'url_params' => $params); $event = new kEvent($prefix_special.':BuildEnv', $event_params); $this->HandleEvent($event); $params = $event->getEventParam('url_params'); // save back unprocessed parameters - + $ret = ''; if ($event->getEventParam('env_string')) { $ret = trim( $event->getEventParam('env_string'), '/'); } return $ret; } - + /** * Builds env part that corresponds prefix passed * @@ -1155,7 +1227,7 @@ if ($env_var) { $ret = ENV_VAR_NAME.'='; } - + $ret .= $sid.(constOn('INPORTAL_ENV') ? '-' : ':'); $encode = false; @@ -1170,7 +1242,7 @@ $env_string = ''; $category_id = isset($params['m_cat_id']) ? $params['m_cat_id'] : $this->GetVar('m_cat_id'); - + $item_id = 0; $pass_info = $this->getPassInfo($pass); if ($pass_info) { @@ -1184,7 +1256,7 @@ $env_string .= ':'.$this->BuildModuleEnv($pass_element, $params, $pass_events); } } - + if (strtolower($t) == '__default__') { // to put category & item templates into cache $filename = $this->getFilename('c', $category_id); @@ -1198,9 +1270,9 @@ $t = 'index'; } } - + $ret .= $t.':'.$this->BuildModuleEnv('m', $params, $pass_events).$env_string; - + unset($params['pass']); unset($params['opener']); unset($params['m_event']); @@ -1336,18 +1408,66 @@ if (!$user_id && $user_id != -1) $user_id = -2; $this->SetVar('u_id', $user_id); $this->StoreVar('user_id', $user_id); - + if ($this->GetVar('expired') == 1) { $user =& $this->recallObject('u'); $user->SetError('ValidateLogin', 'session_expired', 'la_text_sess_expired'); } - + if (($user_id != -2) && constOn('DBG_REQUREST_LOG') ) { $http_query =& $this->recallObject('HTTPQuery'); $http_query->writeRequestLog(DBG_REQUREST_LOG); } } + function LoadCache() { + $cache_key = $this->GetVar('t').$this->GetVar('m_theme').$this->GetVar('m_lang').$this->IsAdmin(); + $query = sprintf("SELECT PhraseList, ConfigVariables FROM %s WHERE Template = %s", + TABLE_PREFIX.'PhraseCache', + $this->Conn->Qstr(md5($cache_key))); + $res = $this->Conn->GetRow($query); + + if ($res) { + $this->Caches['PhraseList'] = $res['PhraseList'] ? explode(',', $res['PhraseList']) : array(); + + $config_ids = $res['ConfigVariables'] ? explode(',', $res['ConfigVariables']) : array(); + $config_ids = array_diff($config_ids, $this->Caches['ConfigVariables']); + } + else { + $config_ids = array(); + } + $this->Caches['ConfigVariables'] = $config_ids; + $this->ConfigCacheIds = $config_ids; + } + + function UpdateCache() + { + $update = false; + //something changed + $update = $update || $this->Phrases->NeedsCacheUpdate(); + $update = $update || (count($this->ConfigCacheIds) && $this->ConfigCacheIds != $this->Caches['ConfigVariables']); + if ($update) { + $cache_key = $this->GetVar('t').$this->GetVar('m_theme').$this->GetVar('m_lang').$this->IsAdmin(); + $query = sprintf("REPLACE %s (PhraseList, CacheDate, Template, ConfigVariables) + VALUES (%s, %s, %s, %s)", + TABLE_PREFIX.'PhraseCache', + $this->Conn->Qstr(join(',', $this->Phrases->Ids)), + adodb_mktime(), + $this->Conn->Qstr(md5($cache_key)), + $this->Conn->qstr(implode(',', array_unique($this->ConfigCacheIds)))); + $this->Conn->Query($query); + } + } + + function InitConfig() + { + if (isset($this->Caches['ConfigVariables']) && count($this->Caches['ConfigVariables']) > 0) { + $this->ConfigHash = array_merge($this->ConfigHash, $this->Conn->GetCol( + 'SELECT VariableValue, VariableName FROM '.TABLE_PREFIX.'ConfigurationValues + WHERE VariableId IN ('.implode(',', $this->Caches['ConfigVariables']).')', 'VariableName')); + } + } + /** * Returns configuration option value by name * @@ -1356,9 +1476,25 @@ */ function ConfigValue($name) { - return getArrayValue($this->ConfigHash, $name); + $res = isset($this->ConfigHash[$name]) ? $this->ConfigHash[$name] : false; + if ($res !== false) return $res; + + $res = $this->Conn->GetRow('SELECT VariableId, VariableValue FROM '.TABLE_PREFIX.'ConfigurationValues WHERE VariableName = '.$this->Conn->qstr($name)); + if ($res) { + $this->ConfigHash[$name] = $res['VariableValue']; + $this->ConfigCacheIds[] = $res['VariableId']; + return $res['VariableValue']; + } + return false; } + function UpdateConfigCache() + { + if ($this->ConfigCacheIds) { + + } + } + /** * Allows to process any type of event * @@ -1371,8 +1507,12 @@ if ( isset($params) ) { $event = new kEvent( $params, $specificParams ); } - $event_manager =& $this->recallObject('EventManager'); - $event_manager->HandleEvent($event); + + if (!isset($this->EventManager)) { + $this->EventManager =& $this->recallObject('EventManager'); + } + + $this->EventManager->HandleEvent($event); } /** @@ -1448,8 +1588,24 @@ */ function &recallObject($name,$pseudo_class=null,$event_params=Array()) { + $result =& $this->Factory->getObject($name, $pseudo_class, $event_params); + return $result; + } + + /** + * Returns object using Variable number of params, + * all params starting with 4th are passed to object consturctor + * + * @param string $name + * @param string $pseudo_class + * @param Array $event_params + * @return Object + * @author Alex + */ + function &recallObjectP($name,$pseudo_class=null,$event_params=Array()) + { $func_args = func_get_args(); - $result =& ref_call_user_func_array( Array(&$this->Factory, 'getObject'), $func_args ); + $result =& ref_call_user_func_array( Array(&$this->Factory, 'getObjectP'), $func_args ); return $result; } @@ -1464,7 +1620,7 @@ $result =& $this->recallObject($prefix.'_TagProcessor'); return $result; } - + /** * Checks if object with prefix passes was already created in factory * @@ -1516,7 +1672,7 @@ */ function isDebugMode($check_debugger = true) { - $debug_mode = constOn('DEBUG_MODE'); + $debug_mode = defined('DEBUG_MODE') && DEBUG_MODE; if($check_debugger) { $debug_mode = $debug_mode && is_object($this->Debugger); @@ -1547,12 +1703,12 @@ // we want to create https link from http mode // we want to create https link from https mode // conditions: ($ssl || PROTOCOL == 'https://') && $this->ConfigValue('UseModRewriteWithSSL') - + // case #2,#3: // we want to create http link from https mode // we want to create http link from http mode // conditions: !$ssl && (PROTOCOL == 'https://' || PROTOCOL == 'http://') - + $allow_rewriting = (!$ssl && (PROTOCOL == 'https://' || PROTOCOL == 'http://')) // always allow mod_rewrite for http || // or allow rewriting for redirect TO httpS or when already in httpS @@ -1573,8 +1729,10 @@ */ function getUnitOption($prefix, $option, $default = false) { - $unit_config_reader =& $this->recallObject('kUnitConfigReader'); - return $unit_config_reader->getUnitOption($prefix, $option, $default); + /*if (!isset($this->UnitConfigReader)) { + $this->UnitConfigReader =& $this->recallObject('kUnitConfigReader'); + }*/ + return $this->UnitConfigReader->getUnitOption($prefix, $option, $default); } /** @@ -1588,8 +1746,8 @@ */ function setUnitOption($prefix, $option, $value) { - $unit_config_reader =& $this->recallObject('kUnitConfigReader'); - return $unit_config_reader->setUnitOption($prefix,$option,$value); +// $unit_config_reader =& $this->recallObject('kUnitConfigReader'); + return $this->UnitConfigReader->setUnitOption($prefix,$option,$value); } /** @@ -1602,8 +1760,8 @@ */ function getUnitOptions($prefix) { - $unit_config_reader =& $this->recallObject('kUnitConfigReader'); - return $unit_config_reader->getUnitOptions($prefix); +// $unit_config_reader =& $this->recallObject('kUnitConfigReader'); + return $this->UnitConfigReader->getUnitOptions($prefix); } /** @@ -1614,8 +1772,10 @@ */ function prefixRegistred($prefix) { - $unit_config_reader =& $this->recallObject('kUnitConfigReader'); - return $unit_config_reader->prefixRegistred($prefix); + /*if (!isset($this->UnitConfigReader)) { + $this->UnitConfigReader =& $this->recallObject('kUnitConfigReader'); + }*/ + return $this->UnitConfigReader->prefixRegistred($prefix); } /** @@ -1790,7 +1950,7 @@ { $user =& $this->recallObject('u'); $user_id = $user->GetID(); - + $ret = $user_id > 0; if ($this->IsAdmin() && ($user_id == -1)) { $ret = true; @@ -1810,18 +1970,18 @@ { if ($this->GetVar('u_id') == -1) { // "root" is allowed anywhere - return $name == 'SYSTEM_ACCESS.READONLY' ? 0 : 1; - } - - if ($type == 1) { - // "system" permission are always checked per "Home" category (ID = 0) - $cat_id = 0; - } - + return $name == 'SYSTEM_ACCESS.READONLY' ? 0 : 1; + } + + if ($type == 1) { + // "system" permission are always checked per "Home" category (ID = 0) + $cat_id = 0; + } + if (!isset($cat_id)) { $cat_id = $this->GetVar('m_cat_id'); } - + if ($cat_id == 0) { $cat_hierarchy = Array(0); } @@ -1874,7 +2034,7 @@ { return $this->InitDone && (count($this->ModuleInfo) > 0); } - + /** * Allows to determine if module is installed & enabled * @@ -1884,15 +2044,55 @@ function isModuleEnabled($module_name) { return $this->findModule('Name', $module_name); - + } - + function reportError($class, $method) { $this->Debugger->appendTrace(); trigger_error('depricated method '.$class.'->'.$method.'(...)', E_USER_ERROR); } + + /** + * Get temp table name + * + * @param string $table + * @return string + */ + function GetTempName($table) + { + return TABLE_PREFIX.'ses_'.$this->GetSID().'_edit_'.$table; + } + + function GetTempTablePrefix() + { + return TABLE_PREFIX.'ses_'.$this->GetSID().'_edit_'; + } + + function IsTempTable($table) + { + return strpos($table, TABLE_PREFIX.'ses_'.$this->GetSID().'_edit_') !== false; + } + + /** + * Return live table name based on temp table name + * + * @param string $temp_table + * @return string + */ + function GetLiveName($temp_table) + { + if( preg_match('/'.TABLE_PREFIX.'ses_'.$this->GetSID().'_edit_(.*)/',$temp_table,$rets) ) + { + return $rets[1]; + } + else + { + return $temp_table; + } + } + } ?> \ No newline at end of file Index: trunk/core/kernel/utility/temp_handler.php =================================================================== diff -u -N -r4287 -r4758 --- trunk/core/kernel/utility/temp_handler.php (.../temp_handler.php) (revision 4287) +++ trunk/core/kernel/utility/temp_handler.php (.../temp_handler.php) (revision 4758) @@ -27,14 +27,14 @@ var $CopiedTables = Array(); - + /** * IDs of newly cloned items (key - prefix.special, value - array of ids) * * @var Array */ var $savedIDs = Array(); - + /** * Description * @@ -61,7 +61,7 @@ { $this->savedIDs[$prefix.($special ? '.' : '').$special][] = $id; } - + /** * Get temp table name * @@ -70,13 +70,12 @@ */ function GetTempName($table) { - // function is sometimes called as static, so we CAN'T use $this->GetTempTablePrefix() here - return TABLE_PREFIX.'ses_'.$this->Application->GetSID().'_edit_'.$table; + return $this->Application->GetTempName($table); } function GetTempTablePrefix() { - return TABLE_PREFIX.'ses_'.$this->Application->GetSID().'_edit_'; + return $this->Application->GetTempTablePrefix(); } /** @@ -87,19 +86,12 @@ */ function GetLiveName($temp_table) { - if( preg_match('/'.TABLE_PREFIX.'ses_'.$this->Application->GetSID().'_edit_(.*)/',$temp_table,$rets) ) - { - return $rets[1]; - } - else - { - return $temp_table; - } + return $this->Application->GetLiveName($temp_table); } function IsTempTable($table) { - return strpos($table, TABLE_PREFIX.'ses_'.$this->Application->GetSID().'_edit_') !== false; + return $this->Application->IsTempTable($table); } /** @@ -132,16 +124,16 @@ 'Prefix' => $prefix, 'TableId' => $this->TableIdCounter++, ); - + $parent_prefix = $this->Application->getUnitOption($prefix, 'ParentPrefix'); if ($parent_prefix) { $tables['ForeignKey'] = $this->Application->getUnitOption($prefix, 'ForeignKey'); $tables['ParentPrefix'] = $parent_prefix; $tables['ParentTableKey'] = $this->Application->getUnitOption($prefix, 'ParentTableKey'); } - + $this->FinalRefs[ $tables['TableName'] ] = $tables['TableId']; // don't forget to add main table to FinalRefs too - + $SubItems = $this->Application->getUnitOption($prefix,'SubItems'); if (is_array($SubItems)) { foreach ($SubItems as $prefix) { @@ -199,7 +191,7 @@ if (!preg_match('/(.*)-item$/', $special)) { $special .= '-item'; } - + $object =& $this->Application->recallObject($prefix.'.'.$special, $prefix, Array('skip_autoload' => true)); foreach ($ids as $id) { @@ -272,11 +264,11 @@ } } } - + if (!$ids) { $this->savedIDs[$prefix.($special ? '.' : '').$special] = Array(); } - + return $this->savedIDs[$prefix.($special ? '.' : '').$special]; } @@ -604,13 +596,13 @@ function RaiseEvent($name, $prefix, $special, $ids, $foreign_key = null, $add_params = null) { if ( !is_array($ids) ) return ; - + $event_key = $prefix.($special ? '.' : '').$special.':'.$name; $event = new kEvent($event_key); if (isset($foreign_key)) { $event->setEventParam('foreign_key', $foreign_key); } - + foreach($ids as $id) { $event->setEventParam('id', $id); Index: trunk/core/units/general/cat_dbitem.php =================================================================== diff -u -N -r4314 -r4758 --- trunk/core/units/general/cat_dbitem.php (.../cat_dbitem.php) (revision 4314) +++ trunk/core/units/general/cat_dbitem.php (.../cat_dbitem.php) (revision 4758) @@ -32,8 +32,8 @@ $ret = parent::Create(); if($ret) { - if ( kTempTablesHandler::IsTempTable($this->TableName) ) { - $table = kTempTablesHandler::GetTempName(TABLE_PREFIX.'CategoryItems'); + if ( $this->Application->IsTempTable($this->TableName) ) { + $table = $this->Application->GetTempName(TABLE_PREFIX.'CategoryItems'); } else { $table = TABLE_PREFIX.'CategoryItems'; @@ -218,7 +218,7 @@ $found_temp_ids = $this->Conn->GetCol($sql_temp); // check live table - $sql_live = 'SELECT '.$this->IDField.' FROM '.kTempTablesHandler::GetLiveName($this->TableName).' WHERE Filename = '.$this->Conn->qstr($filename); + $sql_live = 'SELECT '.$this->IDField.' FROM '.$this->Application->GetLiveName($this->TableName).' WHERE Filename = '.$this->Conn->qstr($filename); $found_live_ids = $this->Conn->GetCol($sql_live); $found_item_ids = array_unique( array_merge($found_temp_ids, $found_live_ids) ); @@ -237,7 +237,7 @@ // check live & temp table $sql_temp = 'SELECT '.$this->IDField.' FROM '.$this->TableName.' WHERE (Filename = %s) AND ('.$this->IDField.' != '.$item_id.')'; - $sql_live = 'SELECT '.$this->IDField.' FROM '.kTempTablesHandler::GetLiveName($this->TableName).' WHERE (Filename = %s) AND ('.$this->IDField.' != '.$item_id.')'; + $sql_live = 'SELECT '.$this->IDField.' FROM '.$this->Application->GetLiveName($this->TableName).' WHERE (Filename = %s) AND ('.$this->IDField.' != '.$item_id.')'; while ( $this->Conn->GetOne( sprintf($sql_temp, $this->Conn->qstr($filename.$append)) ) > 0 || $this->Conn->GetOne( sprintf($sql_live, $this->Conn->qstr($filename.$append)) ) > 0 ) { Index: trunk/core/kernel/utility/formatters/left_formatter.php =================================================================== diff -u -N --- trunk/core/kernel/utility/formatters/left_formatter.php (revision 0) +++ trunk/core/kernel/utility/formatters/left_formatter.php (revision 4758) @@ -0,0 +1,52 @@ +GetFieldOptions($field_name); + if ( isset($format) ) $options['format'] = $format; + + if( !isset($options['options'][$value]) ) + { + // required option is not defined in config => query for it + $db =& $this->Application->GetADODBConnection(); + $sql = sprintf($options['left_sql'],$options['left_title_field'],$options['left_key_field'],$value); + $options['options'][$value] = $db->GetOne($sql); + } + return $options['options'][$value]; + } + +//function Parse($value, $options, &$errors) + function Parse($value, $field_name, &$object) + { + if ($value == '') return NULL; + + $options = $object->GetFieldOptions($field_name); + if( !array_search($value,$options['options']) ) + { + // required option is not defined in config => query for it + $db =& $this->Application->GetADODBConnection(); + $sql = sprintf($options['left_sql'],$options['left_key_field'],$options['left_title_field'],$value); + $found = $db->GetOne($sql); + if($found !== false) $options['options'][$found] = $value; + } + else + { + $found = array_search($value,$options['options']); + } + if($found === false) $found = $options['default']; + return $found; + } +} \ No newline at end of file Index: trunk/core/kernel/utility/unit_config_reader.php =================================================================== diff -u -N -r4594 -r4758 --- trunk/core/kernel/utility/unit_config_reader.php (.../unit_config_reader.php) (revision 4594) +++ trunk/core/kernel/utility/unit_config_reader.php (.../unit_config_reader.php) (revision 4758) @@ -13,6 +13,8 @@ var $CacheExpired = false; + var $prefixFiles = array(); + /** * Scan kernel and user classes * for available configs @@ -22,7 +24,6 @@ function Init($prefix,$special) { parent::Init($prefix,$special); - $this->scanModules(MODULES_PATH); } /** @@ -38,7 +39,8 @@ foreach($this->Application->ModuleInfo as $module_name => $module_info) { $module_path = '/'.$module_info['Path']; - if (substr($config_path, 0, strlen($module_path)) == $module_path) { + if (preg_match('/^'.preg_quote($module_path, '/').'/', $config_path)) { +// if (substr($config_path, 0, strlen($module_path)) == $module_path) { // config file path starts with module folder path $module_found = true; break; @@ -81,17 +83,17 @@ if ( in_array($file, get_required_files()) ) return; global $debugger; - $debugger->IncludeLevel++; + /*$debugger->IncludeLevel++; $before_time = getmicrotime(); - $before_mem = memory_get_usage(); - include_once(FULL_PATH.$file); - $used_time = getmicrotime() - $before_time; + $before_mem = memory_get_usage();*/ + k4_include_once(FULL_PATH.$file); + /*$used_time = getmicrotime() - $before_time; $used_mem = memory_get_usage() - $before_mem; $debugger->IncludeLevel--; $debugger->IncludesData['file'][] = str_replace(FULL_PATH, '', $file); $debugger->IncludesData['mem'][] = $used_mem; $debugger->IncludesData['time'][] = $used_time; - $debugger->IncludesData['level'][] = -1; + $debugger->IncludesData['level'][] = -1;*/ } else { include_once($file); @@ -105,7 +107,7 @@ } } } - + function postProcessConfig($prefix, $config_key, $dst_prefix_var) { $main_config =& $this->configData[$prefix]; @@ -114,27 +116,36 @@ return false; } unset($main_config[$config_key]); - + foreach ($sub_configs as $sub_prefix => $sub_config) { + if ($config_key == 'AggregateConfigs' && !isset($this->configData[$sub_prefix])) { + $this->loadConfig($sub_prefix); + } $sub_config['Prefix'] = $sub_prefix; $this->configData[$sub_prefix] = array_merge_recursive2($this->configData[$$dst_prefix_var], $sub_config); - + // when merging empty array to non-empty results non-empty array, but empty is required foreach ($sub_config as $sub_key => $sub_value) { if (!$sub_value) { unset($this->configData[$sub_prefix][$sub_key]); } } + if ($config_key == 'Clones') { + $this->prefixFiles[$sub_prefix] = $this->prefixFiles[$prefix]; + } $this->postProcessConfig($sub_prefix, $config_key, $dst_prefix_var); + if ($config_key == 'AggregateConfigs') { + $this->postProcessConfig($sub_prefix, 'Clones', 'prefix'); + } } - + if (!$prefix) { // configs, that used only for cloning & not used ifself unset($this->configData[$prefix]); } } - + function ParseConfigs() { foreach ($this->configData as $prefix => $config) { @@ -144,12 +155,101 @@ $this->Application->HandleEvent( new kEvent('m:OnAfterConfigRead') ); } + function CacheParsedData() + { + $event_manager =& $this->Application->recallObject('EventManager'); + $aggregator =& $this->Application->recallObject('TagsAggregator', 'kArray'); + + $config_vars = Array( + 'SessionTimeout', + 'SessionCookieName', + 'SessionReferrerCheck', + 'CookieSessions', + 'UseCronForRegularEvent', + 'User_GuestGroup', + 'User_LoggedInGroup', + 'SessionTimeout', + 'UseModRewrite', + 'AdminDirectory', + ); + + foreach ($config_vars as $var) { + $this->Application->ConfigValue($var); + } + + $cache = Array( + 'Factory.Files' => $this->Application->Factory->Files, + 'Factory.realClasses' => $this->Application->Factory->realClasses, + 'Factory.Dependencies' => $this->Application->Factory->Dependencies, + 'ConfigReader.prefixFiles' => $this->prefixFiles, + 'EventManager.buildEvents' => $event_manager->buildEvents, + 'EventManager.beforeRegularEvents' => $event_manager->beforeRegularEvents, + 'EventManager.afterRegularEvents' => $event_manager->afterRegularEvents, + 'EventManager.beforeHooks' => $event_manager->beforeHooks, + 'EventManager.afterHooks' => $event_manager->afterHooks, + 'TagsAggregator.data' => $aggregator->_Array, + + // the following caches should be reset based on admin interaction (adjusting config, enabling modules etc) + 'Application.Caches.ConfigVariables' => $this->Application->Caches['ConfigVariables'], + 'Application.ConfigCacheIds' => $this->Application->ConfigCacheIds, + 'Application.ConfigHash' => $this->Application->ConfigHash, + 'Application.ModuleInfo' => $this->Application->ModuleInfo, + ); + + $conn =& $this->Application->GetADODBConnection(); + $conn->Query('REPLACE '.TABLE_PREFIX.'Cache (VarName, Data, Cached) VALUES ("configs_parsed", '.$conn->qstr(serialize($cache)).', '.adodb_mktime().')'); + } + + function ResetParsedData($include_sections=false) + { + $conn =& $this->Application->GetADODBConnection(); + $conn->Query('DELETE FROM '.TABLE_PREFIX.'Cache WHERE VarName = "configs_parsed"'); + + if ($include_sections) { + $conn->Query('DELETE FROM '.TABLE_PREFIX.'Cache WHERE VarName = "sections_parsed"'); + } + } + + function RestoreParsedData() + { + $conn =& $this->Application->GetADODBConnection(); + $data = $conn->GetRow('SELECT Data, Cached FROM '.TABLE_PREFIX.'Cache WHERE VarName = "configs_parsed"'); + if ($data && $data['Cached'] > 0 ) { + $cache = unserialize($data['Data']); + $this->Application->Factory->Files = $cache['Factory.Files']; + $this->Application->Factory->realClasses = $cache['Factory.realClasses']; + $this->Application->Factory->Dependencies = $cache['Factory.Dependencies']; + $this->prefixFiles = $cache['ConfigReader.prefixFiles']; + + $event_manager =& $this->Application->recallObject('EventManager'); + $event_manager->buildEvents = $cache['EventManager.buildEvents']; + $event_manager->beforeRegularEvents = $cache['EventManager.beforeRegularEvents']; + $event_manager->afterRegularEvents = $cache['EventManager.afterRegularEvents']; + $event_manager->beforeHooks = $cache['EventManager.beforeHooks']; + $event_manager->afterHooks = $cache['EventManager.afterHooks']; + + $aggregator =& $this->Application->recallObject('TagsAggregator', 'kArray'); + $aggregator->_Array = $cache['TagsAggregator.data']; + + $this->Application->ConfigHash = $cache['Application.ConfigHash']; + + $this->Application->Caches['ConfigVariables'] = $cache['Application.ConfigCacheIds']; + $this->Application->ConfigCacheIds = $cache['Application.ConfigCacheIds']; + + $this->Application->ModuleInfo = $cache['Application.ModuleInfo']; + + return true; + + } + else return false; + } + function findConfigFiles($folderPath) { // 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 - + $fh=opendir(FULL_PATH.$folderPath); while(($sub_folder=readdir($fh))) { @@ -169,116 +269,48 @@ function includeConfigFiles() { - $db =& $this->Application->GetADODBConnection(); - - foreach ($this->configFiles as $filename) - { - $config_found = file_exists(FULL_PATH.$filename) && $this->configAllowed($filename); - if( $this->Application->isDebugMode() && constOn('DBG_PROFILE_INCLUDES') ) - { - if ( in_array($filename, get_required_files()) ) return; - global $debugger; - $debugger->IncludeLevel++; - $before_time = getmicrotime(); - $before_mem = memory_get_usage(); - if($config_found) include_once(FULL_PATH.$filename); - $used_time = getmicrotime() - $before_time; - $used_mem = memory_get_usage() - $before_mem; - $debugger->IncludeLevel--; - $debugger->IncludesData['file'][] = str_replace(FULL_PATH, '', $filename); - $debugger->IncludesData['mem'][] = $used_mem; - $debugger->IncludesData['time'][] = $used_time; - $debugger->IncludesData['level'][] = -1; - } - else - { - if($config_found) include_once(FULL_PATH.$filename); - } - - if($config_found && isset($config) && $config) - { - $prefix = isset($config['Prefix']) ? $config['Prefix'] : ''; - - preg_match('/\/(.*)\//U', $filename, $rets); - $config['ModuleFolder'] = $rets[1]; - $config['BasePath'] = dirname(FULL_PATH.$filename); - $this->configData[$prefix] = $config; - - $this->postProcessConfig($prefix, 'AggregateConfigs', 'sub_prefix'); - $this->postProcessConfig($prefix, 'Clones', 'prefix'); - } - } - } - - function scanModules($folderPath) - { - global $debugger; - + $this->Application->refreshModuleInfo(); if (defined('CACHE_CONFIGS_FILES')) { $conn =& $this->Application->GetADODBConnection(); $data = $conn->GetRow('SELECT Data, Cached FROM '.TABLE_PREFIX.'Cache WHERE VarName = "config_files"'); -// if ($data && $data['Cached'] > (adodb_mktime() - 3600) ) { if ($data && $data['Cached'] > 0 ) { $this->configFiles = unserialize($data['Data']); $files_cached = $data['Cached']; } else { - $files_cached = 0; + $this->findConfigFiles($folderPath); } } else { - $files_cached = 0; + $this->findConfigFiles($folderPath); } - if (defined('CACHE_CONFIGS_DATA') && CACHE_CONFIGS_DATA) { - $conn =& $this->Application->GetADODBConnection(); - $data = $conn->GetRow('SELECT Data, Cached FROM '.TABLE_PREFIX.'Cache WHERE VarName = "config_data"'); - if ($data && $data['Cached'] > (adodb_mktime() - 3600) ) { - $this->configData = unserialize($data['Data']); - $data_cached = $data['Cached']; - } - else { - $data_cached = 0; - } - } - else { - $data_cached = 0; - } - if ( !defined('CACHE_CONFIGS_FILES') || $files_cached == 0 ) { - $this->findConfigFiles($folderPath); + foreach ($this->configFiles as $filename) + { + $this->loadConfigFile($filename); } + } - if ( !defined('CACHE_CONFIGS_DATA') || $data_cached == 0) { - $this->includeConfigFiles(); + function scanModules($folderPath) + { + if (defined('CACHE_PARSED_CONFIGS') && CACHE_PARSED_CONFIGS) { + $restored = $this->RestoreParsedData(); + if ($restored) return; } + $this->includeConfigFiles(); + $this->ParseConfigs(); - /*// && (adodb_mktime() - $cached) > 600) - to skip checking files modified dates - if ( !defined('CACHE_CONFIGS') ) { - $fh=opendir($folderPath); - while(($sub_folder=readdir($fh))) - { - $full_path=$folderPath.'/'.$sub_folder.'/units'; - if( $this->isDir($full_path) ) - { - $this->processFolder($full_path, $cached); - } - } - }*/ - - if (defined('CACHE_CONFIGS_DATA') && $data_cached == 0) { - $conn->Query('REPLACE '.TABLE_PREFIX.'Cache (VarName, Data, Cached) VALUES ("config_data", '.$conn->qstr(serialize($this->configData)).', '.adodb_mktime().')'); + if (defined('CACHE_PARSED_CONFIGS')) { + $this->CacheParsedData(); } - $this->ParseConfigs(); - if (defined('CACHE_CONFIGS_FILES') && $files_cached == 0) { + $conn =& $this->Application->GetADODBConnection(); $conn->Query('REPLACE '.TABLE_PREFIX.'Cache (VarName, Data, Cached) VALUES ("config_files", '.$conn->qstr(serialize($this->configFiles)).', '.adodb_mktime().')'); } unset($this->configFiles); -// unset($this->configData); - } /** @@ -330,16 +362,16 @@ if (isset($config['ParentPrefix']) && $hook['HookToPrefix'] == $config['ParentPrefix']) { trigger_error('Depricated Hook Usage [prefix: '.$config['Prefix'].'; do_prefix: '.$hook['DoPrefix'].'] use #PARENT# and HookToPrefix value where HookToPrefix is same as ParentPrefix', E_USER_NOTICE); } - + if ($hook['HookToPrefix'] == '') { $hook['HookToPrefix'] = $config['Prefix']; // new: set hooktoprefix to current prefix if not set } - + if (isset($config['ParentPrefix']) && $hook['HookToPrefix'] == '#PARENT#') { // new: allow to set hook to parent prefix what ever it is $hook['HookToPrefix'] = $config['ParentPrefix']; } - + $do_prefix = $hook['DoPrefix'] == '' ? $config['Prefix'] : $hook['DoPrefix']; if ( !is_array($hook['HookToEvent']) ) { @@ -395,6 +427,62 @@ } } + function loadConfigFile($filename) + { + $config_found = file_exists(FULL_PATH.$filename) && $this->configAllowed($filename); + + if( defined('DEBUG_MODE') && DEBUG_MODE && constOn('DBG_PROFILE_INCLUDES') ) + { + if ( in_array($filename, get_required_files()) ) return; + global $debugger; + /*$debugger->IncludeLevel++; + $before_time = getmicrotime(); + $before_mem = memory_get_usage();*/ + if($config_found) { + $file = FULL_PATH.$filename; + $debugger->ProfileStart('inc_'.crc32($file), $file); + include_once($file); + $debugger->ProfileFinish('inc_'.crc32($file)); + $debugger->profilerAddTotal('includes', 'inc_'.crc32($file)); + } + /*$used_time = getmicrotime() - $before_time; + $used_mem = memory_get_usage() - $before_mem; + $debugger->IncludeLevel--; + $debugger->IncludesData['file'][] = str_replace(FULL_PATH, '', $filename); + $debugger->IncludesData['mem'][] = $used_mem; + $debugger->IncludesData['time'][] = $used_time; + $debugger->IncludesData['level'][] = -1;*/ + } + else + { + if($config_found) include_once(FULL_PATH.$filename); + } + + if($config_found && isset($config) && $config) + { + $prefix = isset($config['Prefix']) ? $config['Prefix'] : ''; + + preg_match('/\/(.*)\//U', $filename, $rets); + $config['ModuleFolder'] = $rets[1]; + $config['BasePath'] = dirname(FULL_PATH.$filename); + $this->configData[$prefix] = $config; + $this->prefixFiles[$prefix] = $filename; + + $this->postProcessConfig($prefix, 'AggregateConfigs', 'sub_prefix'); + $this->postProcessConfig($prefix, 'Clones', 'prefix'); + } + } + + function loadConfig($prefix) + { + if (!isset($this->prefixFiles[$prefix])) { + trigger_error('Configuration file for prefix '.$prefix.' is unknown', E_USER_ERROR); + return ; + } + $file = $this->prefixFiles[$prefix]; + $this->loadConfigFile($file); + } + /** * Reads unit (specified by $prefix) * option specified by $option @@ -408,9 +496,15 @@ function getUnitOption($prefix, $name, $default = false) { if (preg_match('/(.*)\.(.*)/', $prefix, $rets)) { + if (!isset($this->configData[$rets[1]])) { + $this->loadConfig($rets[1]); + } $ret = getArrayValue($this->configData, $rets[1], $name, $rets[2]); } else { + if (!isset($this->configData[$prefix])) { + $this->loadConfig($prefix); + } $ret = getArrayValue($this->configData, $prefix, $name); } return $ret === false ? $default : $ret; Index: trunk/kernel/units/general/my_application.php =================================================================== diff -u -N -r4607 -r4758 --- trunk/kernel/units/general/my_application.php (.../my_application.php) (revision 4607) +++ trunk/kernel/units/general/my_application.php (.../my_application.php) (revision 4758) @@ -28,8 +28,9 @@ $this->registerClass('kSearchHelper', MODULES_PATH.'/kernel/units/general/helpers/search_helper.php', 'SearchHelper'); $this->registerClass('kSectionsHelper', MODULES_PATH.'/kernel/units/general/helpers/sections_helper.php', 'SectionsHelper'); $this->registerClass('kPermissionsHelper', MODULES_PATH.'/kernel/units/general/helpers/permissions_helper.php', 'PermissionsHelper'); - + $this->registerClass('kModulesHelper', MODULES_PATH.'/kernel/units/general/helpers/modules.php', 'ModulesHelper'); + $this->registerClass('kModRewriteHelper', MODULES_PATH.'/kernel/units/general/helpers/mod_rewrite_helper.php', 'ModRewriteHelper'); } function getUserGroups($user_id) Index: trunk/core/kernel/utility/formatters.php =================================================================== diff -u -N --- trunk/core/kernel/utility/formatters.php (revision 4645) +++ trunk/core/kernel/utility/formatters.php (revision 0) @@ -1,1090 +0,0 @@ -GetFieldOptions($field_name); - if ( isset($format) ) $options['format'] = $format; - $tc_value = $this->TypeCast($value,$options); - if( ($tc_value === false) || ($tc_value != $value) ) return $value; // for leaving badly formatted date on the form - - if (isset($options['format'])) return sprintf($options['format'], $tc_value); - - return $tc_value; - } - -//function Parse($value, $options, &$errors) - function Parse($value, $field_name, &$object) - { - if ($value == '') return NULL; - - $options = $object->GetFieldOptions($field_name); - $tc_value = $this->TypeCast($value,$options); - if($tc_value === false) return $value; // for leaving badly formatted date on the form - - if( isset($options['type']) ) - { - if( preg_match('#double|float|real|numeric#', $options['type']) ) $tc_value = str_replace(',', '.', $tc_value); - } - - if( isset($options['regexp']) ) - { - if( !preg_match($options['regexp'], $value) ) - { - $object->FieldErrors[$field_name]['pseudo'] = 'invalid_format'; - } - } - - return $tc_value; - } - - function HumanFormat($format) - { - return $format; - } - - - /** - * The method is supposed to alter config options or cofigure object in some way based on its usage of formatters - * The methods is called for every field with formatter defined when configuring item. - * Could be used for adding additional VirtualFields to an object required by some special Formatter - * - * @param string $field_name - * @param array $field_options - * @param kDBBase $object - */ - function PrepareOptions($field_name, &$field_options, &$object) - { - - } - - /** - * Used for split fields like timestamp -> date, time - * Called from DBItem to update sub fields values after loading item - * - * @param unknown_type $field - * @param unknown_type $value - * @param unknown_type $options - * @param unknown_type $object - */ - function UpdateSubFields($field, $value, &$options, &$object) - { - - } - - /** - * Used for split fields like timestamp -> date, time - * Called from DBItem Validate (before validation) to get back master field value from its sub_fields - * - * @param unknown_type $field - * @param unknown_type $value - * @param unknown_type $options - * @param unknown_type $object - */ - function UpdateMasterFields($field, $value, &$options, &$object) - { - - } - -/* function GetErrorMsg($pseudo_error, $options) - { - if ( isset($options['error_msgs'][$pseudo_error]) ) { - return $options['error_msgs'][$pseudo_error]; - } - else { - return $this->ErrorMsgs[$pseudo_error]; - } - }*/ - - function GetSample($field, &$options, &$object) - { - - } - -} - -class kOptionsFormatter extends kFormatter { - - function Format($value, $field_name, &$object, $format=null) - { - if ( is_null($value) ) return ''; - - $options = $object->GetFieldOptions($field_name); - - $label = getArrayValue($options['options'], $value); - if ($label !== false) { - if (getArrayValue($options, 'use_phrases')) { - return $this->Application->Phrase($label); - } - else { - return $label; - } - } - else { - return $value; - } - } - - function Parse($value, $field_name, &$object) - { - if ($value == '') return NULL; - - $options = $object->GetFieldOptions($field_name); - $use_phrases = getArrayValue($options, 'use_phrases'); - - $found = false; - foreach ($options['options'] as $option_key => $option_value) { - if ($use_phrases) { - $option_value = $this->Application->Phrase($option_value); - } - - if ($option_value == $value) { - $found = true; - break; - } - } - - return $found ? $option_key : $value; - } -} - -/** - * Replacement for kOptionsFormatter in case if options - * should be selected from database. Use this formatter - * only in case if formatter attached field is in edit form. - * - * For usage in grid just use LEFT JOIN clause to table - * where requested options are located. - */ -class kLEFTFormatter extends kFormatter { - -//function Format($value, $options, &$errors) - function Format($value, $field_name, &$object, $format=null) - { - if ( is_null($value) ) return ''; - - $options = $object->GetFieldOptions($field_name); - if ( isset($format) ) $options['format'] = $format; - - if( !isset($options['options'][$value]) ) - { - // required option is not defined in config => query for it - $db =& $this->Application->GetADODBConnection(); - $sql = sprintf($options['left_sql'],$options['left_title_field'],$options['left_key_field'],$value); - $options['options'][$value] = $db->GetOne($sql); - } - return $options['options'][$value]; - } - -//function Parse($value, $options, &$errors) - function Parse($value, $field_name, &$object) - { - if ($value == '') return NULL; - - $options = $object->GetFieldOptions($field_name); - if( !array_search($value,$options['options']) ) - { - // required option is not defined in config => query for it - $db =& $this->Application->GetADODBConnection(); - $sql = sprintf($options['left_sql'],$options['left_key_field'],$options['left_title_field'],$value); - $found = $db->GetOne($sql); - if($found !== false) $options['options'][$found] = $value; - } - else - { - $found = array_search($value,$options['options']); - } - if($found === false) $found = $options['default']; - return $found; - } -} - - -class kDateFormatter extends kFormatter { - -/* function kDateFormatter() - { - parent::kFormatter(); - $this->ErrorMsgs['bad_dformat'] = 'Please use correct date format (%s) ex. (%s)'; - } - */ - - function PrepareOptions($field_name, &$field_options, &$object) - { - $date_format = getArrayValue($field_options, 'date_format'); - $time_format = getArrayValue($field_options, 'time_format'); - - $language =& $this->Application->recallObject('lang.current'); - - if ($date_format === false) $date_format = $language->GetDBField('DateFormat'); - if ($time_format === false) $time_format = $language->GetDBField('TimeFormat'); - - $input_format['date'] = $language->GetDBField('InputDateFormat'); - $input_format['time'] = $language->GetDBField('InputTimeFormat'); - - if (!isset($field_options['date_time_separator'])) $field_options['date_time_separator'] = ' '; - $field_options['format'] = $date_format.$field_options['date_time_separator'].$time_format; - $field_options['input_format'] = $input_format['date'].$field_options['date_time_separator'].$input_format['time']; - - $field_options['sub_fields'] = Array('date' => $field_name.'_date', 'time' => $field_name.'_time'); - - $add_fields = Array(); - - $opts = Array('master_field' => $field_name, 'formatter'=>'kDateFormatter', 'format' => $date_format, 'input_format' => $input_format['date']); - if ( isset($field_options['default']) ) $opts['default'] = $field_options['default']; - if ( isset($field_options['required']) ) $opts['required'] = $field_options['required']; - - $add_fields[$field_name.'_date'] = $opts; - $opts['format'] = $time_format; - $opts['input_format'] = $input_format['time']; - $add_fields[$field_name.'_time'] = $opts; - - $filter_type = getArrayValue($field_options, 'filter_type'); - if($filter_type == 'range') - { - $opts['format'] = $field_options['format']; - $add_fields[$field_name.'_rangefrom'] = $opts; - $add_fields[$field_name.'_rangeto'] = $opts; - } - - if ( !isset($object->VirtualFields[$field_name]) ) { - // adding caluclated field to format date directly in the query - if ( !isset($object->CalculatedFields) || !is_array($object->CalculatedFields) ) { - $object->CalculatedFields = Array(); - } - $object->CalculatedFields[$field_name.'_formatted'] = 'FROM_UNIXTIME('.'`%1$s`.'.$field_name.', \''.$this->SQLFormat($field_options['format']).'\')'; - $opts['format'] = $field_options['format']; - $opts['required'] = 0; - unset($opts['master_field']); - $add_fields[$field_name.'_formatted'] = $opts; - } - - $add_fields = array_merge_recursive2($add_fields, $object->VirtualFields); - $object->setVirtualFields($add_fields); - } - - function UpdateSubFields($field, $value, &$options, &$object) - { - if ( $sub_fields = getArrayValue($options, 'sub_fields') ) { - if( isset($value) && $value ) - { - $object->SetDBField( $sub_fields['date'], $value ); - $object->SetDBField( $sub_fields['time'], $value ); - } - } - } - - function UpdateMasterFields($field, $value, &$options, &$object) - { - // when in master field - set own value from sub_fields - if ( $sub_fields = getArrayValue($options, 'sub_fields') ) { - // if date is not empty, but time is empty - set time to 0, otherwise master field fomratter will complain - // when we have only date field on form, we need time hidden field always empty, don't ask me why! - if ( $object->GetDBField($sub_fields['date']) != '' && $object->GetDBField($sub_fields['time']) == '' ) { - $empty_time = getArrayValue($options,'empty_time'); - if($empty_time === false) $empty_time = adodb_mktime(0,0,0); - $object->SetDBField($sub_fields['time'], $empty_time); - } - - $input_format['date'] = $object->Fields[ $sub_fields['date'] ]['input_format']; - $input_format['time'] = $object->Fields[ $sub_fields['time'] ]['input_format']; - - $object->SetField($field, $object->GetField($sub_fields['date'], $input_format['date']).$options['date_time_separator'].$object->GetField($sub_fields['time'], $input_format['time'])); - } - // when in one of sub_fields - call update for master_field to update its value from sub_fields [are you following ? :) ] - elseif ($master_field = getArrayValue($options, 'master_field') ) { - $opt = $object->GetFieldOptions($master_field); - $this->UpdateMasterFields($master_field, null, $opt, $object); - } - } - -//function Format($value, $options, &$errors) - function Format($value, $field_name, &$object, $format=null) - { - if ( is_null($value) ) return ''; - if ( !is_numeric($value) ) return $value; // for leaving badly formatted date on the form - settype($value, 'int'); - if ( !is_int($value) ) return $value; - - $options = $object->GetFieldOptions($field_name); - if ( isset($format) ) $options['format'] = $format; - - return adodb_date($options['format'], $value); - } - - function HumanFormat($format) - { - $patterns = Array('/m/', - '/n/', - '/d/', - '/j/', - '/y/', - '/Y/', - '/h|H/', - '/g|G/', - '/i/', - '/s/', - '/a|A/'); - $replace = Array( 'mm', - 'm', - 'dd', - 'd', - 'yy', - 'yyyy', - 'hh', - 'h', - 'mm', - 'ss', - 'AM'); - $res = preg_replace($patterns, $replace, $format); - return $res; - } - - function SQLFormat($format) - { - $mapping = Array( - '/%/' => '%%', - '/(? '%p', // Lowercase Ante meridiem and Post meridiem => MySQL provides only uppercase - '/(? '%p', // Uppercase Ante meridiem and Post meridiem - '/(? '%d', // Day of the month, 2 digits with leading zeros - '/(? '%a', // A textual representation of a day, three letters - '/(? '%M', // A full textual representation of a month, such as January or March - '/(? '%l', // 12-hour format of an hour without leading zeros - '/(? '%k', // 24-hour format of an hour without leading zeros - '/(? '%h', // 12-hour format of an hour with leading zeros - '/(? '%H', // 24-hour format of an hour with leading zeros - '/(? '%i', // Minutes with leading zeros - '/(? 'N/A', // Whether or not the date is in daylights savings time - - '/(? 'N/A', // English ordinal suffix for the day of the month, 2 characters, see below - '/jS/' => '%D', // MySQL can't return separate suffix, but could return date with suffix - '/(? '%e', // Day of the month without leading zeros - '/(? '%W', // A full textual representation of the day of the week - '/(? 'N/A', // Whether it's a leap year - '/(? '%m', // Numeric representation of a month, with leading zeros - '/(? '%b', // A short textual representation of a month, three letters - '/(? '%c', // Numeric representation of a month, without leading zeros - '/(? 'N/A', // Difference to Greenwich time (GMT) in hours - '/(? 'N/A', // RFC 2822 formatted date - '/(? '%s', // Seconds, with leading zeros - // S and jS moved before j - see above - '/(? 'N/A', // Number of days in the given month - '/(? 'N/A', // Timezone setting of this machine - '/(? 'N/A', // Seconds since the Unix Epoch (January 1 1970 00:00:00 GMT) - '/(? '%w', // Numeric representation of the day of the week - '/(? '%v', // ISO-8601 week number of year, weeks starting on Monday (added in PHP 4.1.0) - '/(? '%Y', // A full numeric representation of a year, 4 digits - '/(? '%y', // A two digit representation of a year - '/(? 'N/A', // The day of the year (starting from 0) => MySQL starts from 1 - '/(? 'N/A', // Timezone offset in seconds. The offset for timezones west of UTC is always negative, and for those east of UTC is always positive. - ); - - $patterns = array_keys($mapping); - $replacements = array_values($mapping); - - $res = preg_replace($patterns, $replacements, $format); - return $res; - } - -//function Parse($value, $options, &$errors) - function Parse($value, $field_name, &$object) - { - $options = $object->GetFieldOptions($field_name); - - $dt_separator = getArrayValue($options,'date_time_separator'); - if($dt_separator) $value = trim($value, $dt_separator); - if($value == '') return NULL; - //return strtotime($value); - - $format = $options['input_format']; - if($dt_separator) $format = trim($format, $dt_separator); - - $object->FieldErrors[$field_name]['params'] = Array( $this->HumanFormat($format), adodb_date($format) ); - $object->FieldErrors[$field_name]['value'] = $value; - - $hour = 0; - $minute = 0; - $second = 0; - $month = 1; - $day = 1; - $year = 1970; - - $patterns['n'] = '([0-9]{1,2})'; - $patterns['m'] = '([0-9]{1,2})'; - $patterns['d'] = '([0-9]{1,2})'; - $patterns['j'] = '([0-9]{1,2})'; - $patterns['Y'] = '([0-9]{4})'; - $patterns['y'] = '([0-9]{2})'; - $patterns['G'] = '([0-9]{1,2})'; - $patterns['g'] = '([0-9]{1,2})'; - $patterns['H'] = '([0-9]{2})'; - $patterns['h'] = '([0-9]{2})'; - $patterns['i'] = '([0-9]{2})'; - $patterns['s'] = '([0-9]{2})'; - $patterns['a'] = '(am|pm)'; - $patterns['A'] = '(AM|PM)'; - - $holders_mask = eregi_replace('[a-zA-Z]{1}', '([a-zA-Z]{1})', $format); - if (!ereg($holders_mask, $format, $holders)) { - $object->FieldErrors[$field_name]['pseudo'] = 'bad_date_format'; - return $value; - } - - $values_mask = '/^'.str_replace('/','\/',$format).'$/'; - foreach ($patterns as $key => $val) { - $values_mask = ereg_replace($key, $val, $values_mask); - } - // echo " values_mask : $values_mask
"; - - if (!preg_match($values_mask, $value, $values)) { - $object->FieldErrors[$field_name]['pseudo'] = 'bad_date_format'; - return $value; - } - - for ($i = 1; $i < count($holders); $i++) { - switch ($holders[$i]) { - case 'n': - case 'm': - $month = $values[$i]; - $month = ereg_replace("^0{1}", '', $month); - break; - case 'd': - $day = $values[$i]; - $day = ereg_replace("^0{1}", '', $day); - break; - case 'Y': - $year = $values[$i]; - break; - case 'y': - $year = $values[$i] >= 70 ? 1900 + $values[$i] : 2000 + $values[$i]; - break; - case 'H': - case 'h': - case 'G': - case 'g': - $hour = $values[$i]; - $hour = ereg_replace("^0{1}", '', $hour); - break; - case 'i': - $minute = $values[$i]; - $minute = ereg_replace("^0{1}", '', $minute); - break; - case 's': - $second = $values[$i]; - $second = ereg_replace("^0{1}", '', $second); - break; - case 'a': - case 'A': - if ($hour <= 12) { // if AM/PM used with 24-hour - could happen :) - if ($values[$i] == 'pm' || $values[$i] == 'PM') { - $hour += 12; - if ($hour == 24) $hour = 12; - } - elseif ($values[$i] == 'am' || $values[$i] == 'AM') { - if ($hour == 12) $hour = 0; - } - } - break; - } - } - - //echo "day: $day, month: $month, year: $year, hour: $hour, minute: $minute
"; - - /*if (!($year >= 1970 && $year <= 2037)) { - $object->FieldErrors[$field_name]['pseudo'] = 'bad_date_format'; - return $value; - }*/ - - if (!($month >= 1 && $month <= 12)) { - $object->FieldErrors[$field_name]['pseudo'] = 'bad_date_format'; - return $value; - } - - $months_days = Array ( 1 => 31,2 => 28, 3 => 31, 4 => 30,5 => 31,6 => 30, 7 => 31, 8 => 31,9 => 30,10 => 31,11 => 30,12 => 31); - if ($year % 4 == 0) $months_days[2] = 29; - - if (!($day >=1 && $day <= $months_days[$month])) { - $object->FieldErrors[$field_name]['pseudo'] = 'bad_date_format'; - return $value; - } - - if (!($hour >=0 && $hour <= 23)) { - $object->FieldErrors[$field_name]['pseudo'] = 'bad_date_format'; - return $value; - } - - if (!($minute >=0 && $minute <= 59)) { - $object->FieldErrors[$field_name]['pseudo'] = 'bad_date_format'; - return $value; - } - - if (!($second >=0 && $second <= 59)) { - $object->FieldErrors[$field_name]['pseudo'] = 'bad_date_format'; - return $value; - } - // echo "day: $day, month: $month, year: $year, hour: $hour, minute: $minute
"; - return adodb_mktime($hour, $minute, $second, $month, $day, $year); - } - - function GetSample($field, &$options, &$object) - { - return $this->Format( adodb_mktime(), $field, $object, $options['input_format']); - } -} - -class kUploadFormatter extends kFormatter -{ - var $DestinationPath; - var $FullPath; - - function kUploadFormatter() - { - if ($this->DestinationPath) - { - $this->FullPath = FULL_PATH.$this->DestinationPath; - } - parent::kBase(); - } - - -//function Parse($value, $options, &$errors) - function Parse($value, $field_name, &$object) - { - $ret = ''; - $options = $object->GetFieldOptions($field_name); - - if(getArrayValue($options, 'upload_dir')) - { - $this->DestinationPath = $options['upload_dir']; - $this->FullPath = FULL_PATH.$this->DestinationPath; - } - - if (getArrayValue($value, 'upload') && getArrayValue($value, 'error') == UPLOAD_ERR_NO_FILE) - { - return getArrayValue($value, 'upload'); - } - - if ( is_array($value) && $value['size'] ) - { - if ( is_array($value) && $value['error'] === UPLOAD_ERR_OK ) - { - if ( getArrayValue($options, 'allowed_types') && !in_array($value['type'], $options['allowed_types']) ) - { - $object->FieldErrors[$field_name]['pseudo'] = 'bad_file_format'; - } - elseif ( $value['size'] > ($options['max_size'] ? $options['max_size'] : MAX_UPLOAD_SIZE) ) - { - $object->FieldErrors[$field_name]['pseudo'] = 'bad_file_size'; - } - elseif ( !is_writable($this->FullPath) ) - { - $object->FieldErrors[$field_name]['pseudo'] = 'cant_save_file'; - } - else - { - $real_name = $this->ValidateFileName($this->FullPath, $value['name']); - $file_name = $this->FullPath.$real_name; - if ( !move_uploaded_file($value['tmp_name'], $file_name) ) - { - $object->FieldErrors[$field_name]['pseudo'] = 'cant_save_file'; - } - else - { - @chmod($file_name, 0666); - if(getArrayValue($options, 'size_field')) - { - $object->SetDBField($options['size_field'], $value['size']); - } - if(getArrayValue($options, 'orig_name_field')) - { - $object->SetDBField($options['orig_name_field'], $value['name']); - } - if(getArrayValue($options, 'content_type_field')) - { - $object->SetDBField($options['content_type_field'], $value['type']); - } - $ret = getArrayValue($options, 'upload_dir') ? $real_name : $this->DestinationPath.$real_name; - } - } - } - else - { - $object->FieldErrors[$field_name]['pseudo'] = 'cant_save_file'; - } - } - else - { - if(getArrayValue($options, 'required')) - { - $object->FieldErrors[$field_name]['pseudo'] = 'required'; - } - } - - if ($value['error'] && !( $value['error'] == UPLOAD_ERR_NO_FILE ) && !$object->FieldErrors[$field_name]['pseudo']) - { - $object->FieldErrors[$field_name]['pseudo'] = 'cant_save_file'; - } - - return $ret; - } - - function ValidateFileName($path, $name) - { - $parts = pathinfo($name); - $ext = '.'.$parts['extension']; - $filename = substr($parts['basename'], 0, -strlen($ext)); - $new_name = $filename.$ext; - while ( file_exists($path.'/'.$new_name) ) - { - if ( preg_match("/({$filename}_)([0-9]*)($ext)/", $new_name, $regs) ) { - $new_name = $regs[1].($regs[2]+1).$regs[3]; - } - else { - $new_name = $filename.'_1'.$ext; - } - } - return $new_name; - } - -} - -class kPictureFormatter extends kUploadFormatter -{ - - function kPictureFormatter() - { - $this->NakeLookupPath = IMAGES_PATH; - $this->DestinationPath = IMAGES_PENDING_PATH; - parent::kUploadFormatter(); - } - -} - -class kMultiLanguage extends kFormatter -{ - - function LangFieldName($field_name) - { - $lang = $this->Application->GetVar('m_lang'); - return 'l'.$lang.'_'.$field_name; - } - - function PrepareOptions($field_name, &$field_options, &$object) - { - if (getArrayValue($object->Fields, $field_name, 'master_field')) return; - - $lang_field_name = $this->LangFieldName($field_name); - - //substitude title field - $title_field = $this->Application->getUnitOption($object->Prefix, 'TitleField'); - if ($title_field == $field_name) { - $this->Application->setUnitOption($object->Prefix, 'TitleField', $lang_field_name); - } - - //substitude fields - $fields = $this->Application->getUnitOption($object->Prefix, 'Fields'); - if ( isset($fields[$field_name]) ) { - - $fields[$lang_field_name] = $fields[$field_name]; - $fields[$lang_field_name]['master_field'] = $field_name; - $object->Fields[$lang_field_name] = $fields[$lang_field_name]; - $fields[$field_name]['required'] = false; - $object->Fields[$field_name]['required'] = false; - $object->VirtualFields[$field_name] = $object->Fields[$field_name]; - } - $this->Application->setUnitOption($object->Prefix, 'Fields', $fields); - - //substitude virtual fields - $virtual_fields = $this->Application->getUnitOption($object->Prefix, 'VirtualFields'); - if ( isset($virtual_fields[$field_name]) ) { - $virtual_fields[$lang_field_name] = $virtual_fields[$field_name]; - $virtual_fields[$lang_field_name]['master_field'] = $field_name; - $object->VirtualFields[$lang_field_name] = $virtual_fields[$lang_field_name]; - $virtual_fields[$field_name]['required'] = false; - $object->VirtualFields[$field_name]['required'] = false; - } - $this->Application->setUnitOption($object->Prefix, 'VirtualFields', $virtual_fields); - - //substitude grid fields - $grids = $this->Application->getUnitOption($object->Prefix, 'Grids', Array()); - foreach ($grids as $name => $grid) { - if ( getArrayValue($grid, 'Fields', $field_name) ) { - array_rename_key($grids[$name]['Fields'], $field_name, $lang_field_name); - } - } - $this->Application->setUnitOption($object->Prefix, 'Grids', $grids); - - //substitude default sortings - $sortings = $this->Application->getUnitOption($object->Prefix, 'ListSortings', Array()); - foreach ($sortings as $special => $the_sortings) { - if (isset($the_sortings['ForcedSorting'])) { - array_rename_key($sortings[$special]['ForcedSorting'], $field_name, $lang_field_name); - } - if (isset($the_sortings['Sorting'])) { - array_rename_key($sortings[$special]['Sorting'], $field_name, $lang_field_name); - } - } - $this->Application->setUnitOption($object->Prefix, 'ListSortings', $sortings); - - //TODO: substitude possible language-fields sortings after changing language - } - - /*function UpdateSubFields($field, $value, &$options, &$object) - { - - } - - function UpdateMasterFields($field, $value, &$options, &$object) - { - - }*/ - - function Format($value, $field_name, &$object, $format=null) - { - $master_field = getArrayValue($object->Fields, $field_name, 'master_field'); - if (!$master_field) { // if THIS field is master it does NOT have reference to it's master_field - $lang = $this->Application->GetVar('m_lang'); - $value = $object->GetDBField('l'.$lang.'_'.$field_name); //getting value of current language - $master_field = $field_name; // THIS is master_field - } - if ( $value == '' && $format != 'no_default') { // try to get default language value - $def_lang_value = $object->GetDBField('l'.$this->Application->GetDefaultLanguageId().'_'.$master_field); - if ($def_lang_value == '') return NULL; - return $def_lang_value; //return value from default language - } - return $value; - } - - function Parse($value, $field_name, &$object) - { - $lang = $this->Application->GetVar('m_lang'); - $def_lang = $this->Application->GetDefaultLanguageId(); - $master_field = getArrayValue($object->Fields, $field_name, 'master_field'); - - if ( getArrayValue($object->Fields, $field_name, 'required') && ( (string) $value == '' ) ) { - $object->FieldErrors[$master_field]['pseudo'] = 'required'; - }; - - if (!$this->Application->GetVar('allow_translation') && $lang != $def_lang && getArrayValue($object->Fields, $field_name, 'required')) { - $def_lang_field = 'l'.$def_lang.'_'.$master_field; - if ( !$object->ValidateRequired($def_lang_field, $object->Fields[$field_name]) ) { - $object->FieldErrors[$master_field]['pseudo'] = 'primary_lang_required'; - } - } - - if ($value == '') return NULL; - return $value; - } - -} - - -class kPasswordFormatter extends kFormatter -{ - - function PrepareOptions($field_name, &$field_options, &$object) - { - if( isset( $field_options['verify_field'] ) ) - { - $add_fields = Array(); - $options = Array('master_field' => $field_name, 'formatter'=>'kPasswordFormatter'); - $add_fields[ $field_options['verify_field'] ] = $options; - - $add_fields[$field_name.'_plain'] = Array('type'=>'string', 'error_field'=>$field_name); - $add_fields[ $field_options['verify_field'].'_plain' ] = Array('type'=>'string', 'error_field'=>$field_options['verify_field'] ); - - $add_fields = array_merge_recursive2($add_fields, $object->VirtualFields); - $object->setVirtualFields($add_fields); - } - } - - function Format($value, $field_name, &$object, $format=null) - { - return $value; - } - - function Parse($value, $field_name, &$object) - { - $options = $object->GetFieldOptions($field_name); - - $fields = Array('master_field','verify_field'); - $fields_set = true; - $flip_count = 0; - while($flip_count < 2) - { - if( getArrayValue($options,$fields[0]) ) - { - $object->SetDBField($field_name.'_plain', $value); - if( !getArrayValue($object->Fields[ $options[ $fields[0] ] ], $fields[1].'_set') ) - { - $object->Fields[ $options[ $fields[0] ] ][$fields[1].'_set'] = true; - } - - $password_field = $options[ $fields[0] ]; - $verify_field = $field_name; - } - $fields = array_reverse($fields); - $flip_count++; - } - - if( getArrayValue($object->Fields[$password_field], 'verify_field_set') && getArrayValue($object->Fields[$verify_field], 'master_field_set') ) - { - $new_password = $object->GetDBField($password_field.'_plain'); - $verify_password = $object->GetDBField($verify_field.'_plain'); - - if($new_password == '' && $verify_password == '') - { - if( $object->GetDBField($password_field) != $this->EncryptPassword('') ) - { - return $this->EncryptPassword($value); - } - else - { - $object->Fields[$password_field.'_plain']['required'] = true; - $object->Fields[$verify_field.'_plain']['required'] = true; - return null; - } - } - - $min_length = $this->Application->ConfigValue('Min_Password'); - if( strlen($new_password) >= $min_length ) - { - if($new_password != $verify_password) - { - $object->ErrorMsgs['passwords_do_not_match'] = $this->Application->Phrase('lu_passwords_do_not_match'); - $object->FieldErrors[$password_field]['pseudo'] = 'passwords_do_not_match'; - $object->FieldErrors[$verify_field]['pseudo'] = 'passwords_do_not_match'; - } - } - else - { - $object->ErrorMsgs['passwords_min_length'] = sprintf($this->Application->Phrase('lu_passwords_too_short'), $min_length); - $object->FieldErrors[$password_field]['pseudo'] = 'passwords_min_length'; - $object->FieldErrors[$verify_field]['pseudo'] = 'passwords_min_length'; - } - } - if($value == '') return $object->GetDBField($field_name); - return $this->EncryptPassword($value); - } - - function EncryptPassword($value) - { - return md5($value); - } -} - - -/** - * Credit card expiration date formatter - * - */ -class kCCDateFormatter extends kFormatter -{ - function PrepareOptions($field_name, &$field_options, &$object) - { - $add_fields = Array(); - - $i = 1; - $options = Array('00' => ''); - while($i <= 12) - { - $options[ sprintf('%02d',$i) ] = sprintf('%02d',$i); - $i++; - } - $add_fields[ $field_options['month_field'] ] = Array('formatter'=>'kOptionsFormatter', 'options' => $options, 'not_null' => true, 'default' => '00'); - $add_fields[ $field_options['year_field'] ] = Array('type' => 'string', 'default' => ''); - - $add_fields = array_merge_recursive2($add_fields, $object->VirtualFields); - $object->setVirtualFields($add_fields); - } - - function UpdateSubFields($field, $value, &$options, &$object) - { - if(!$value) return false; - $date = explode('/', $value); - $object->SetDBField( $options['month_field'], $date[0] ); - $object->SetDBField( $options['year_field'], $date[1] ); - } - - /** - * Will work in future if we could attach 2 formatters to one field - * - * @param string $value - * @param string $field_name - * @param kDBase $object - * @return string - */ - function Parse($value, $field_name, &$object) - { -// if ( is_null($value) ) return ''; - - $options = $object->GetFieldOptions($field_name); - - $month = $object->GetDirtyField($options['month_field']); - $year = $object->GetDirtyField($options['year_field']); - - if( !(int)$month && !(int)$year ) return NULL; - $is_valid = ($month >= 1 && $month <= 12) && ($year >= 0 && $year <= 99); - - if(!$is_valid) $object->FieldErrors[$field_name]['pseudo'] = 'bad_type'; - return $month.'/'.$year; - } - -} - -class kUnitFormatter extends kFormatter { - - function PrepareOptions($field_name, &$field_options, &$object) - { - if( !isset($field_options['master_field']) ) - { - $regional =& $this->Application->recallObject('lang.current'); - $add_fields = Array(); - $options_a = Array('type' => 'int','error_field' => $field_name,'master_field' => $field_name,'format' => '%d' ); - $options_b = Array('type' => 'double','error_field' => $field_name,'master_field' => $field_name,'format' => '%0.2f' ); - switch( $regional->GetDBField('UnitSystem') ) - { - case 2: // US/UK - $field_options_copy = $field_options; - unset($field_options_copy['min_value_exc']); - $add_fields[$field_name.'_a'] = array_merge_recursive2($field_options_copy, $options_a); - $add_fields[$field_name.'_b'] = array_merge_recursive2($field_options_copy, $options_b); - break; - default: - } - $add_fields = array_merge_recursive2($add_fields, $object->VirtualFields); - $object->setVirtualFields($add_fields); - } - } - - function UpdateMasterFields($field, $value, &$options, &$object) - { - if( !isset($options['master_field']) ) - { - $regional =& $this->Application->recallObject('lang.current'); - switch( $regional->GetDBField('UnitSystem') ) - { - case 2: // US/UK - $major = $object->GetDirtyField($field.'_a'); - $minor = $object->GetDirtyField($field.'_b'); - if($major === '' && $minor === '') - { - $value = null; - } - elseif($major === null && $minor === null) - { - unset($object->Fields[$field]); - return; - } - else - { - $value = Pounds2Kg($major, $minor); - } - break; - default: - } - $object->SetDBField($field, $value); - } - } - - function UpdateSubFields($field, $value, &$options, &$object) - { - if( !isset($options['master_field']) ) - { - $regional =& $this->Application->recallObject('lang.current'); - switch( $regional->GetDBField('UnitSystem') ) - { - case 2: // US/UK - if($value === null) - { - $major = null; - $minor = null; - } - else - { - list($major,$minor) = Kg2Pounds($value); - /*$major = floor( $value / 0.5 ); - $minor = ($value - $major * 0.5) * 32;*/ - } - $object->SetDBField($field.'_a', $major); - $object->SetDBField($field.'_b', $minor); - break; - default: - } - } - } -} - -class kFilesizeFormatter extends kFormatter { - - function Format($value, $field_name, &$object, $format=null) - { - if ($value >= 1099511627776) { - $return = round($value / 1024 / 1024 / 1024 / 1024, 2); - $suffix = "Tb"; - } elseif ($value >= 1073741824) { - $return = round($value / 1024 / 1024 / 1024, 2); - $suffix = "Gb"; - } elseif ($value >= 1048576) { - $return = round($value / 1024 / 1024, 2); - $suffix = "Mb"; - } elseif ($value >= 1024) { - $return = round($value / 1024, 2); - $suffix = "Kb"; - } else { - $return = $value; - $suffix = "B"; - } - $return .= ' '.$suffix; - return $return; - } -} - -class kSerializedFormatter extends kFormatter { - - function Format($value, $field_name, $object, $format=null) - { - $data = unserialize($value); - return $data[$format]; - } - -} - -?> Index: trunk/kernel/units/configuration/configuration_event_handler.php =================================================================== diff -u -N -r4664 -r4758 --- trunk/kernel/units/configuration/configuration_event_handler.php (.../configuration_event_handler.php) (revision 4664) +++ trunk/kernel/units/configuration/configuration_event_handler.php (.../configuration_event_handler.php) (revision 4758) @@ -1,8 +1,8 @@ setEventParam('PermSection', $this->Application->GetVar('section')); return parent::CheckPermission($event); } - - + + /** * Apply any custom changes to list's sql query * @@ -25,10 +25,10 @@ function SetCustomQuery(&$event) { $object =& $event->getObject(); - + $module = $this->Application->GetVar('module'); $section = $this->Application->GetVar('section'); - + $object->addFilter('module_filter', '%1$s.ModuleOwner = '.$this->Conn->qstr($module)); $object->addFilter('section_filter', '%1$s.Section = '.$this->Conn->qstr($section)); } @@ -41,7 +41,7 @@ function OnBeforeItemUpdate(&$event) { $object =& $event->getObject(); - + // if password field is empty, then don't update if ($object->GetDBField('element_type') == 'password') { if (trim($object->GetDBField('VariableValue')) == '') { @@ -52,24 +52,24 @@ $object->SetDBField('VariableValue', md5($object->GetDBField('VariableValue'))); } } - + $field_values = $this->Application->GetVar($event->getPrefixSpecial(true)); - + $state_country_hash = Array( 'Comm_State' => 'Comm_Country', 'Comm_Shipping_State' => 'Comm_Shipping_Country' ); - + $field_name = $object->GetDBField('VariableName'); if (isset($state_country_hash[$field_name])) { // if this is state field $check_state = $object->GetDBField('VariableValue'); $check_country = $field_values[ $state_country_hash[$field_name] ]['VariableValue']; - + if (!($check_country && $check_state)) { return true; } - + $cs_helper =& $this->Application->recallObject('CountryStatesHelper'); $state_iso = $cs_helper->CheckState($check_state, $check_country); if ($state_iso !== false) { @@ -79,17 +79,17 @@ { $errormsgs = $this->Application->GetVar('errormsgs'); $errors = !$errormsgs || !isset($errormsgs[$event->Prefix_Special]) ? Array() : $errormsgs[$event->Prefix_Special]; - + $errors[$field_name] = 'la_InvalidState'; $errormsgs[$event->Prefix_Special] = $errors; - + $this->Application->SetVar('errormsgs', $errormsgs); $event->status = erFAIL; } } - + } - + /** * Enter description here... * @@ -105,8 +105,8 @@ $object->SetFieldOptions('VariableValue', $field_options); } } - } - + } + /** * Enter description here... * @@ -115,37 +115,41 @@ function OnUpdate(&$event) { if (!$this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1)) { - + // 1. save user selected module root category $items_info = $this->Application->GetVar($event->getPrefixSpecial(true)); $new_category_id = getArrayValue($items_info, 'ModuleRootCategory', 'VariableValue'); if ($new_category_id) { unset($items_info['ModuleRootCategory']); $this->Application->SetVar($event->getPrefixSpecial(true), $items_info); } - + parent::OnUpdate($event); - + if ($event->status == erSUCCESS && $new_category_id !== false) { // root category was submitted $module = $this->Application->GetVar('module'); $root_category_id = $this->Application->findModule('Name', $module, 'RootCat'); - + if ($root_category_id != $new_category_id) { // root category differs from one in db $fields_hash = Array('RootCat' => $new_category_id); $this->Conn->doUpdate($fields_hash, TABLE_PREFIX.'Modules', 'Name = '.$this->Conn->qstr($module)); } } + + if ($event->status == erSUCCESS) { // reset cache + $this->Application->UnitConfigReader->ResetParsedData(); + } } - + if ($this->Application->GetVar('errormsgs')) { // because we have list out there, and this is item $this->Application->removeObject($event->getPrefixSpecial()); $event->redirect = false; } } - + /** * Enter description here... * @@ -163,11 +167,11 @@ $array_records[$i]['VariableValue'] = $values['Comm_Country']['VariableValue']; } } - + $event->redirect_params = Array('opener' => 's', 'pass'=>'all,conf'); //stay! $event->redirect = false; }*/ - + /** * Allows to process module root category selection * @@ -176,10 +180,10 @@ function OnSelectItems(&$event) { $object =& $event->getObject( Array('skip_autoload' => true) ); - + $items_info = $this->Application->GetVar('c'); list($resource_id, $field_values) = each($items_info); - + if ($resource_id) { $sql = 'SELECT CategoryId FROM '.TABLE_PREFIX.'Category @@ -189,9 +193,9 @@ } $this->finalizePopup($event); } - + } - - + + ?> \ No newline at end of file Index: trunk/core/units/general/inp_ses_storage.php =================================================================== diff -u -N -r3887 -r4758 --- trunk/core/units/general/inp_ses_storage.php (.../inp_ses_storage.php) (revision 3887) +++ trunk/core/units/general/inp_ses_storage.php (.../inp_ses_storage.php) (revision 4758) @@ -54,19 +54,20 @@ function LocateSession($sid) { - $query = ' SELECT '.$this->TimestampField.' FROM '.$this->TableName.' WHERE '.$this->IDField.' = '.$this->Conn->qstr($sid); - $result = $this->Conn->GetOne($query); - - if($result===false) return false; - - $this->Expiration = $result + $this->SessionTimeout; - return true; + $res = parent::LocateSession($sid); + if ($res) { + $this->Expiration += $this->SessionTimeout; + } + return $res; } function UpdateSession(&$session) { - $query = ' UPDATE '.$this->TableName.' SET '.$this->TimestampField.' = unix_timestamp() WHERE '.$this->IDField.' = '.$this->Conn->qstr($session->SID); - $this->Conn->Query($query); + $time = adodb_mktime(); + // Update LastAccessed only if it's newer than 1/10 of session timeout - perfomance optimization to eliminate needless updates on every click + if ($time - $this->DirectVars['LastAccessed'] > $this->SessionTimeout/10) { + $this->SetField($session, $this->TimestampField, $time); + } } @@ -78,15 +79,15 @@ 'IpAddress' => $_SERVER['REMOTE_ADDR'], 'GroupList' => $this->Application->ConfigValue('User_GuestGroup'), 'CurrentTempKey'=> $session->SID, - + ); - + parent::StoreSession($session, $fields_hash); } function GetExpiredSIDs() { - $query = ' SELECT '.$this->IDField.' FROM '.$this->TableName.' WHERE '.adodb_mktime().' - '.$this->TimestampField.' > '.$this->SessionTimeout; + $query = ' SELECT '.$this->IDField.' FROM '.$this->TableName.' WHERE '.$this->TimestampField.' < '.(adodb_mktime()-$this->SessionTimeout); $ret = $this->Conn->GetCol($query); if($ret) { $this->DeleteEditTables(); Index: trunk/core/kernel/utility/cache.php =================================================================== diff -u -N -r4135 -r4758 --- trunk/core/kernel/utility/cache.php (.../cache.php) (revision 4135) +++ trunk/core/kernel/utility/cache.php (.../cache.php) (revision 4758) @@ -1,25 +1,25 @@ Conn =& $this->Application->GetADODBConnection(); - + $this->debugCache = $this->Application->isDebugMode() && dbg_ConstOn('DBG_CACHE'); } - + /** * Adds new value to cache $cache_name and identified by key $key * @@ -33,7 +33,7 @@ $cache[$key] = $value; $this->Set($cache_name, $cache); } - + /** * Returns cached $key value from cache named $cache_name * @@ -45,32 +45,32 @@ { $cache = $this->Get($cache_name, Array()); $ret = getArrayValue($cache, $key); - + $this->setStatistics($cache_name, $key, $ret); - + return $ret; } - + function setStatistics($cache_name, $key, $found) { if (!$this->debugCache) return true; - + if (!isset($this->statistics[$cache_name])) { $this->statistics[$cache_name] = Array(); } - + if (!isset($this->statistics[$cache_name][$key])) { $this->statistics[$cache_name][$key] = Array(); } - + $status_key = $found ? 'found' : 'not_found'; if (!isset($this->statistics[$cache_name][$key][$status_key])) { $this->statistics[$cache_name][$key][$status_key] = 0; } - + $this->statistics[$cache_name][$key][$status_key]++; } - + function printStatistics() { foreach ($this->statistics as $cache_name => $cache_data) { @@ -81,7 +81,7 @@ } } } - + print_pre($this->statistics); } } Index: trunk/core/units/modules/modules_event_handler.php =================================================================== diff -u -N -r4625 -r4758 --- trunk/core/units/modules/modules_event_handler.php (.../modules_event_handler.php) (revision 4625) +++ trunk/core/units/modules/modules_event_handler.php (.../modules_event_handler.php) (revision 4758) @@ -12,8 +12,8 @@ { $this->Application->SetVar($event->getPrefixSpecial(true).'_id', $event->Special); parent::OnItemBuild($event); - } - + } + /** * List with one record if special passed * @@ -26,14 +26,14 @@ $object->addFilter('current_module', 'Name = '.$event->Special); } } - + function mapEvents() { parent::mapEvents(); $this->eventMethods['OnMassApprove'] = 'moduleAction'; $this->eventMethods['OnMassDecline'] = 'moduleAction'; } - + /** * Disabled modules, but not In-Portal * @@ -44,13 +44,13 @@ if ($this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1)) { return; } - + $object =& $event->getObject( Array('skip_autoload' => true) ); $ids = $this->StoreSelectedIDs($event); - - + + if (!$ids) return true; - + $status_field = array_shift( $this->Application->getUnitOption($event->Prefix, 'StatusField') ); foreach($ids as $id) @@ -69,10 +69,11 @@ break; } } - + + $this->Application->UnitConfigReader->ResetParsedData(true); //true to reset sections cache also $event->SetRedirectParam('RefreshTree', 1); } - + } ?> \ No newline at end of file Index: trunk/core/units/languages/import_xml.php =================================================================== diff -u -N -r4712 -r4758 --- trunk/core/units/languages/import_xml.php (.../import_xml.php) (revision 4712) +++ trunk/core/units/languages/import_xml.php (.../import_xml.php) (revision 4758) @@ -166,7 +166,7 @@ $sql = 'SELECT %s FROM %s WHERE PackName = %s'; $sql = sprintf( $sql, $this->lang_object->IDField, - kTempTablesHandler::GetLiveName($this->lang_object->TableName), + $this->Application->GetLiveName($this->lang_object->TableName), $this->Conn->qstr($this->current_language['PackName']) ); $language_id = $this->Conn->GetOne($sql); if($language_id) Index: trunk/kernel/units/languages/languages_event_handler.php =================================================================== diff -u -N -r4712 -r4758 --- trunk/kernel/units/languages/languages_event_handler.php (.../languages_event_handler.php) (revision 4712) +++ trunk/kernel/units/languages/languages_event_handler.php (.../languages_event_handler.php) (revision 4758) @@ -15,11 +15,11 @@ 'OnImportLanguage' => Array('self' => 'advanced:import'), 'OnExportLanguage' => Array('self' => 'advanced:export'), 'OnExportProgress' => Array('self' => 'advanced:export'), - + ); $this->permMapping = array_merge($this->permMapping, $permissions); } - + /** * Updates table structure on new language adding/removing language * @@ -29,8 +29,8 @@ { $ml_helper =& $this->Application->recallObject('kMultiLanguageHelper'); - $unit_config_reader =& $this->Application->recallObject('kUnitConfigReader'); - foreach ($unit_config_reader->configData as $prefix => $config_data) { + $this->Application->UnitConfigReader->includeConfigFiles(); //make sure to re-read all configs + foreach ($this->Application->UnitConfigReader->configData as $prefix => $config_data) { $ml_helper->createFields($prefix); } } @@ -130,7 +130,7 @@ // 1. phrases import $phrases_live = $this->Application->getUnitOption('phrases','TableName'); - $phrases_temp = kTempTablesHandler::GetTempName($phrases_live); + $phrases_temp = $this->Application->GetTempName($phrases_live); $sql = 'INSERT INTO '.$phrases_temp.' SELECT Phrase, Translation, PhraseType, 0-PhraseId, '.$lang_id.', '.adodb_mktime().', "", Module FROM '.$phrases_live.' @@ -139,7 +139,7 @@ // 2. events import $em_table_live = $this->Application->getUnitOption('emailmessages','TableName'); - $em_table_temp = kTempTablesHandler::GetTempName($em_table_live); + $em_table_temp = $this->Application->GetTempName($em_table_live); $sql = 'SELECT * FROM '.$em_table_live.' WHERE LanguageId = '.$from_lang_id; $email_messages = $this->Conn->Query($sql); @@ -177,7 +177,7 @@ $object =& $event->getObject(); $object->SetDBField('CopyLabels', 1); - $live_table = kTempTablesHandler::GetLiveName($object->TableName); + $live_table = $this->Application->GetLiveName($object->TableName); $primary_lang_id = $this->Conn->GetOne('SELECT '.$object->IDField.' FROM '.$live_table.' WHERE PrimaryLang = 1'); $object->SetDBField('CopyFromLanguage', $primary_lang_id); @@ -247,7 +247,7 @@ $import_start = (int)$this->Application->GetVar('start'); $id_field = $this->Application->getUnitOption($import_prefix,'IDField'); $dst_table = $this->Application->getUnitOption($import_prefix,'TableName'); - $src_table = kTempTablesHandler::GetTempName($dst_table); + $src_table = $this->Application->GetTempName($dst_table); $import_total = $this->Application->GetVar('total'); if(!$import_total) $import_total = $this->Conn->GetOne('SELECT COUNT(*) FROM '.$src_table); @@ -266,7 +266,7 @@ $import_start = 0; $id_field = $this->Application->getUnitOption($import_prefix,'IDField'); $dst_table = $this->Application->getUnitOption($import_prefix,'TableName'); - $src_table = kTempTablesHandler::GetTempName($dst_table); + $src_table = $this->Application->GetTempName($dst_table); $import_total = $this->Conn->GetOne('SELECT COUNT(*) FROM '.$src_table); } Index: trunk/core/kernel/utility/factory.php =================================================================== diff -u -N -r4374 -r4758 --- trunk/core/kernel/utility/factory.php (.../factory.php) (revision 4374) +++ trunk/core/kernel/utility/factory.php (.../factory.php) (revision 4758) @@ -63,6 +63,7 @@ } $special= isset($tmp[0][1]) ? $tmp[0][1] : ''; $prefix_special.='.'.$special; // new2 + return Array('prefix'=>$prefix,'special'=>$special,'prefix_special'=>$prefix_special); } @@ -78,8 +79,61 @@ */ function &getObject($name,$pseudo_class='',$event_params=Array()) { + $name=rtrim($name,'.'); + if( isset($this->Storage[$name]) ) return $this->Storage[$name]; $ret=$this->processPrefix($name); if (!$pseudo_class) $pseudo_class = $ret['prefix']; + + if (!isset($this->realClasses[$pseudo_class])) + { + if( defined('DEBUG_MODE') && DEBUG_MODE ) $this->Application->Debugger->appendTrace(); + $error_level = $this->Application->isInstalled() ? E_USER_ERROR : E_USER_WARNING; + trigger_error('RealClass not defined for pseudo_class '.$pseudo_class.'', $error_level); + $false = false; + return $false; + } + + if ($this->Application->isDebugMode() && dbg_ConstOn('DBG_FACTORY')) { + global $debugger; + $debugger->appendHTML('Creating object: Pseudo class: '.$pseudo_class.' Prefix: '.$name); + $debugger->appendTrace(); + } + + $this->Storage[$name] =& $this->makeClass($pseudo_class); + $this->Storage[$name]->Init($ret['prefix'],$ret['special'],$event_params); + + $prefix=$this->Storage[$name]->Prefix; + $special=$this->Storage[$name]->Special; + +// $event_manager =& $this->Storage['EventManager']; + $event =& $this->Application->EventManager->getBuildEvent($pseudo_class); + if($event) + { + $event->Init($prefix,$special); + foreach($event_params as $param_name=>$param_value) + { + $event->setEventParam($param_name,$param_value); + } + $this->Application->HandleEvent($event); + } + + return $this->Storage[$name]; + } + + /** + * Returns object using Variable number of params specified, + * creates it if is required + * all params after 4th are passed to object constructor + * + * @param string $name + * @param string $pseudo_class + * @param Array $event_params + * @return Object + */ + function &getObjectP($name,$pseudo_class='',$event_params=Array()) + { + $ret=$this->processPrefix($name); + if (!$pseudo_class) $pseudo_class = $ret['prefix']; $name=rtrim($name,'.'); if( isset($this->Storage[$name]) ) return $this->Storage[$name]; @@ -146,9 +200,9 @@ if(!$this->Files[$real_class]) trigger_error('Real Class '.$real_class.' is not registered with the Factory', E_USER_ERROR); if(!file_exists($this->Files[$real_class])) trigger_error('Include file for class '.$real_class.' ('.$this->Files[$real_class].') does not exists', E_USER_ERROR); - if( $deps = getArrayValue($this->Dependencies, $real_class) ) + if( isset( $this->Dependencies[$real_class] ) ) { - foreach($deps as $dep_class_name) + foreach($this->Dependencies[$real_class] as $dep_class_name) { $this->includeClassFile($dep_class_name); } @@ -171,7 +225,7 @@ function &makeClass($pseudo_class) { $real_class = $this->realClasses[$pseudo_class]; - $this->includeClassFile($real_class); + if (!class_exists($real_class)) $this->includeClassFile($real_class); $mem_before = memory_get_usage(); $time_before = getmicrotime(); @@ -186,7 +240,7 @@ $pseudo_class = array_shift($func_args); $class =& ref_call_user_func_array( Array($real_class,'makeClass'), $func_args ); } - if( $this->Application->isDebugMode() && dbg_ConstOn('DBG_PROFILE_MEMORY') ) + if( defined('DEBUG_MODE') && DEBUG_MODE && dbg_ConstOn('DBG_PROFILE_MEMORY') ) { $mem_after = memory_get_usage(); $time_after = getmicrotime(); @@ -213,10 +267,10 @@ if(!isset($pseudo_class)) $pseudo_class = $real_class; if(!isset($this->Files[$real_class])) $this->Files[$real_class]=$file; - if (getArrayValue($this->realClasses, $pseudo_class)) { + if (isset($this->realClasses[$pseudo_class])) { $this->registerDependency($real_class, $pseudo_class); } - + if($dependecies) { if (!is_array($dependecies)) $dependecies = array($dependecies); @@ -239,11 +293,11 @@ function registerDependency($depended_class, $class_name) { $dependencies =& $this->Dependencies[$depended_class]; - + $conditions = Array(); $conditions['exists'] = is_array($dependencies) && in_array($this->realClasses[$class_name], $dependencies); $conditions['same_class'] = $this->realClasses[$class_name] == $depended_class; - + if (!$conditions['exists'] && !$conditions['same_class']) { $dependencies[] = $this->realClasses[$class_name]; } Index: trunk/core/kernel/languages/phrases_cache.php =================================================================== diff -u -N -r3282 -r4758 --- trunk/core/kernel/languages/phrases_cache.php (.../phrases_cache.php) (revision 3282) +++ trunk/core/kernel/languages/phrases_cache.php (.../phrases_cache.php) (revision 4758) @@ -1,23 +1,23 @@ LanguageId = $this->Application->GetVar('m_lang'); - $this->LoadPhrases( $this->GetCachedIds() ); + if (isset($this->Application->Caches['PhraseList'])) { + $this->LoadPhrases( $this->Application->Caches['PhraseList'] ); + } } - + function GetCachedIds() { - $query = sprintf("SELECT PhraseList FROM %s WHERE Template = %s", + $query = sprintf("SELECT PhraseList, ConfigVariables FROM %s WHERE Template = %s", TABLE_PREFIX.'PhraseCache', - $this->Conn->Qstr(md5($this->Application->GetVar('t')))); - $phrases_ids = $this->Conn->GetOne($query); - return ($phrases_ids === false) ? Array() : explode(',', $phrases_ids); + $this->Conn->Qstr(md5($this->Application->GetVar('t').$this->Application->GetVar('m_theme').$this->Application->GetVar('m_lang')))); + $res = $this->Conn->GetRow($query); + + if ($res && $res['ConfigVariables']) { + $this->Application->OriginalConfigCacheIds = explode(',', $res['ConfigVariables']); + $this->Application->ConfigCacheIds = $this->Application->OriginalConfigCacheIds; + } + + return ($res === false) ? Array() : explode(',', $res['PhraseList']); } - + function LoadPhrases($ids) { if ( !is_array($ids) || !implode('', $ids) ) return; - $query = sprintf("SELECT Translation,Phrase FROM %s WHERE LanguageId = %s AND PhraseId IN (%s)", + $query = sprintf("SELECT Translation,UPPER(Phrase) AS Phrase FROM %s WHERE LanguageId = %s AND PhraseId IN (%s)", TABLE_PREFIX.'Phrase', $this->LanguageId, join(',', $ids)); - $phrases = $this->Conn->GetCol($query,'Phrase'); - foreach($phrases as $phrase => $tanslation) + $this->Phrases = $this->Conn->GetCol($query,'Phrase'); + /*foreach($phrases as $phrase => $tanslation) { $this->AddCachedPhrase(strtoupper($phrase), $tanslation); - } + }*/ $this->Ids = $ids; $this->OriginalIds = $ids; } - + function AddCachedPhrase($label, $value) { $label = strtoupper($label); $this->Phrases[$label] = $value; } - + + function NeedsCacheUpdate() + { + return is_array($this->Ids) && count($this->Ids) > 0 && $this->Ids != $this->OriginalIds; + } + function UpdateCache() { - if (!is_array($this->Ids) || count($this->Ids) == 0) return; - if ($this->Ids == $this->OriginalIds) return; //nothing changed - $query = sprintf("REPLACE %s (PhraseList, CacheDate, Template) - VALUES (%s, %s, %s)", - TABLE_PREFIX.'PhraseCache', - $this->Conn->Qstr(join(',', $this->Ids)), - adodb_mktime(), - $this->Conn->Qstr(md5($this->Application->GetVar('t')))); - $this->Conn->Query($query); + $update = false; + //something changed + $update = $update || (is_array($this->Ids) && count($this->Ids) > 0 && $this->Ids != $this->OriginalIds); + $update = $update || (count($this->Application->ConfigCacheIds) && $this->Application->ConfigCacheIds != $this->Application->OriginalConfigCacheIds); + if ($update) { + $query = sprintf("REPLACE %s (PhraseList, CacheDate, Template, ConfigVariables) + VALUES (%s, %s, %s, %s)", + TABLE_PREFIX.'PhraseCache', + $this->Conn->Qstr(join(',', $this->Ids)), + adodb_mktime(), + $this->Conn->Qstr(md5($this->Application->GetVar('t').$this->Application->GetVar('m_theme').$this->Application->GetVar('m_lang'))), + $this->Conn->qstr(implode(',', array_unique($this->Application->ConfigCacheIds)))); + $this->Conn->Query($query); + } } - + function GetPhrase($label) { if (ereg("^!.+!$", $label) > 0) { $label = substr($label, 1, -1); //cut exclamation marks } - + if( strlen($label) == 0 ) return ''; - + $original_label = $label; $label = strtoupper($label); if( isset($this->Phrases[$label]) ) { $translated_label = $this->Phrases[$label]; - if($this->Application->isDebugMode() && dbg_ConstOn('DBG_PHRASES_HILIGHT') && !$this->Application->IsAdmin()) + if(defined('DEBUG_MODE') && DEBUG_MODE && dbg_ConstOn('DBG_PHRASES_HILIGHT') && !$this->Application->IsAdmin()) $translated_label = ''.$translated_label.' '.$original_label.''; return $translated_label; } - + $this->LoadPhraseByLabel($label, $original_label); return $this->GetPhrase($label); } - + function LoadPhraseByLabel($label, $original_label) { $query = sprintf("SELECT PhraseId, Translation FROM %s WHERE LanguageId = %s AND UPPER(Phrase) = UPPER(%s)", @@ -110,21 +128,21 @@ if( $this->Application->isDebugMode() && dbg_ConstOn('DBG_PHRASES') ) { list($edit_tpl, $index_file) = $this->Application->IsAdmin() ? Array('regional/phrases_edit', 'index4.php') : Array('phrases_edit', 'index.php'); - + $edit_url = $this->Application->HREF($edit_tpl,'',Array('m_opener'=>'d','phrases_label'=>$original_label,'phrases_event'=>'OnNew', 'pass'=>'all,phrases'), $index_file ); $translation = '!'.$label.'!'; if($this->fromTag) $translation = $this->escapeTagReserved($translation); } $this->AddCachedPhrase($label, $translation); //add it as already cached, as long as we dont need to cache not found phrase return false; } - + $this->Phrases[$label] = $res['Translation']; array_push($this->Ids, $res['PhraseId']); $this->Ids = array_unique($this->Ids); //just to make sure - return true; + return true; } - + /** * Sort params by name and then by length * @@ -140,7 +158,7 @@ if ($a_len == $b_len) return 0; return $a_len > $b_len ? -1 : 1; } - + /** * Replace language tags in exclamation marks found in text * @@ -156,7 +174,7 @@ preg_match_all("(!(la|lu)[^!]+!)", $text, $res, PREG_PATTERN_ORDER); $language_tags = $res[0]; uasort($language_tags, Array(&$this, 'CmpParams') ); - + $values = Array(); $i = 0; foreach ($language_tags as $label) { @@ -168,7 +186,7 @@ $this->fromTag = false; return preg_replace($language_tags, $values, $text); } - + /** * Escape chars in phrase translation, that could harm parser to process tag * Index: trunk/core/kernel/utility/formatters/password_formatter.php =================================================================== diff -u -N --- trunk/core/kernel/utility/formatters/password_formatter.php (revision 0) +++ trunk/core/kernel/utility/formatters/password_formatter.php (revision 4758) @@ -0,0 +1,97 @@ + $field_name, 'formatter'=>'kPasswordFormatter'); + $add_fields[ $field_options['verify_field'] ] = $options; + + $add_fields[$field_name.'_plain'] = Array('type'=>'string', 'error_field'=>$field_name); + $add_fields[ $field_options['verify_field'].'_plain' ] = Array('type'=>'string', 'error_field'=>$field_options['verify_field'] ); + + $add_fields = array_merge_recursive2($add_fields, $object->VirtualFields); + $object->setVirtualFields($add_fields); + } + } + + function Format($value, $field_name, &$object, $format=null) + { + return $value; + } + + function Parse($value, $field_name, &$object) + { + $options = $object->GetFieldOptions($field_name); + + $fields = Array('master_field','verify_field'); + $fields_set = true; + $flip_count = 0; + while($flip_count < 2) + { + if( getArrayValue($options,$fields[0]) ) + { + $object->SetDBField($field_name.'_plain', $value); + if( !getArrayValue($object->Fields[ $options[ $fields[0] ] ], $fields[1].'_set') ) + { + $object->Fields[ $options[ $fields[0] ] ][$fields[1].'_set'] = true; + } + + $password_field = $options[ $fields[0] ]; + $verify_field = $field_name; + } + $fields = array_reverse($fields); + $flip_count++; + } + + if( getArrayValue($object->Fields[$password_field], 'verify_field_set') && getArrayValue($object->Fields[$verify_field], 'master_field_set') ) + { + $new_password = $object->GetDBField($password_field.'_plain'); + $verify_password = $object->GetDBField($verify_field.'_plain'); + + if($new_password == '' && $verify_password == '') + { + if( $object->GetDBField($password_field) != $this->EncryptPassword('') ) + { + return $this->EncryptPassword($value); + } + else + { + $object->Fields[$password_field.'_plain']['required'] = true; + $object->Fields[$verify_field.'_plain']['required'] = true; + return null; + } + } + + $min_length = $this->Application->ConfigValue('Min_Password'); + if( strlen($new_password) >= $min_length ) + { + if($new_password != $verify_password) + { + $object->ErrorMsgs['passwords_do_not_match'] = $this->Application->Phrase('lu_passwords_do_not_match'); + $object->FieldErrors[$password_field]['pseudo'] = 'passwords_do_not_match'; + $object->FieldErrors[$verify_field]['pseudo'] = 'passwords_do_not_match'; + } + } + else + { + $object->ErrorMsgs['passwords_min_length'] = sprintf($this->Application->Phrase('lu_passwords_too_short'), $min_length); + $object->FieldErrors[$password_field]['pseudo'] = 'passwords_min_length'; + $object->FieldErrors[$verify_field]['pseudo'] = 'passwords_min_length'; + } + } + if($value == '') return $object->GetDBField($field_name); + return $this->EncryptPassword($value); + } + + function EncryptPassword($value) + { + return md5($value); + } +} \ No newline at end of file Index: trunk/core/units/general/helpers/sections_helper.php =================================================================== diff -u -N -r4702 -r4758 --- trunk/core/units/general/helpers/sections_helper.php (.../sections_helper.php) (revision 4702) +++ trunk/core/units/general/helpers/sections_helper.php (.../sections_helper.php) (revision 4758) @@ -5,14 +5,14 @@ * */ class kSectionsHelper extends kHelper { - + /** * Holds information about all sections * * @var Array */ var $Tree = Array(); - + /** * Set's prefix and special * @@ -33,8 +33,21 @@ */ function BuildTree() { + $unit_config_reader = false; + if (defined('CACHE_PARSED_CONFIGS') && CACHE_PARSED_CONFIGS) { + $data = $this->Conn->GetRow('SELECT Data, Cached FROM '.TABLE_PREFIX.'Cache WHERE VarName = "sections_parsed"'); + if ($data) { + $this->Tree = unserialize($data['Data']); + return ; + } + $this->Application->UnitConfigReader->includeConfigFiles(); + } + $this->Tree = Array(); - $unit_config_reader =& $this->Application->recallObject('kUnitConfigReader'); + if (!$unit_config_reader) { + $unit_config_reader =& $this->Application->recallObject('kUnitConfigReader'); + } + $prefixes = array_keys($unit_config_reader->configData); foreach ($prefixes as $prefix) { $config =& $unit_config_reader->configData[$prefix]; @@ -47,9 +60,9 @@ // we could also skip not allowed sections here in future $section_params['SectionPrefix'] = $prefix; $section_params['url']['m_opener'] = 'r'; - + $pass_section = getArrayValue($section_params, 'url', 'pass_section'); - + if ($pass_section) { unset($section_params['url']['pass_section']); $section_params['url']['section'] = $section_name; @@ -73,8 +86,13 @@ } } } + + if (defined('CACHE_PARSED_CONFIGS') && CACHE_PARSED_CONFIGS) { + $this->Conn->Query('REPLACE '.TABLE_PREFIX.'Cache (VarName, Data, Cached) VALUES ("sections_parsed", '.$this->Conn->qstr(serialize($this->Tree)).', '.adodb_mktime().')'); + } + } - + /** * Returns details information about section * Index: trunk/core/kernel/parser/template.php =================================================================== diff -u -N -r4567 -r4758 --- trunk/core/kernel/parser/template.php (.../template.php) (revision 4567) +++ trunk/core/kernel/parser/template.php (.../template.php) (revision 4758) @@ -44,10 +44,11 @@ trigger_error("Template file size is 0: $filename", ($silent ? E_USER_NOTICE : E_USER_ERROR) ); } - $handle = fopen ($filename, "r"); + $this->SetBody(file_get_contents($filename)); + /*$handle = fopen ($filename, "r"); $contents = fread ($handle, filesize ($filename)); $this->SetBody($contents); - fclose ($handle); + fclose ($handle);*/ return true; } else { @@ -83,7 +84,7 @@ $this->BasePath = FULL_PATH.THEMES_PATH; $conn =& $this->Application->GetADODBConnection(); - $this->ModulesCache = $conn->GetCol('SELECT LOWER(Name) FROM '.TABLE_PREFIX.'Modules'); +// $this->ModulesCache = $conn->GetCol('SELECT LOWER(Name) FROM '.TABLE_PREFIX.'Modules'); } function SetThemePath() @@ -117,7 +118,7 @@ $module_filename = $filename; } - if ( $this->Application->IsAdmin() && in_array(strtolower($first_dir), $this->ModulesCache)) { + if ( $this->Application->IsAdmin() && $this->Application->findModule('Name', $first_dir, null, true)) { $path = MODULES_PATH.'/'.strtolower($first_dir).'/admin_templates'; } else { @@ -140,7 +141,7 @@ $module_filename = $filename; } - if ( $this->Application->IsAdmin() && in_array(strtolower($first_dir), $this->ModulesCache)) { + if ( $this->Application->IsAdmin() && $this->Application->findModule('Name', $first_dir, null, true)) { $path = MODULES_PATH.'/'.strtolower($first_dir).'/admin_templates'; } else { Index: trunk/kernel/units/languages/languages_config.php =================================================================== diff -u -N -r4670 -r4758 --- trunk/kernel/units/languages/languages_config.php (.../languages_config.php) (revision 4670) +++ trunk/kernel/units/languages/languages_config.php (.../languages_config.php) (revision 4758) @@ -1,5 +1,5 @@ 'lang', 'ItemClass' => Array('class'=>'LanguagesItem','file'=>'languages_item.php','build_event'=>'OnItemBuild'), @@ -9,9 +9,9 @@ 'RegisterClasses' => Array( Array('pseudo'=>'LangXML','class'=>'LangXML_Parser','file'=>'import_xml.php'), ), - + 'AutoLoad' => true, - 'Hooks' => Array( + 'Hooks' => Array( Array( 'Mode' => hAFTER, 'Conditional' => false, @@ -22,7 +22,7 @@ 'DoSpecial' => '', 'DoEvent' => 'OnReflectMultiLingualFields', ), - + Array( 'Mode' => hAFTER, 'Conditional' => false, @@ -33,7 +33,7 @@ 'DoSpecial' => '', 'DoEvent' => 'OnCopyLabels', ), - + Array( 'Mode' => hAFTER, 'Conditional' => false, @@ -52,44 +52,44 @@ 4 => 'mode', ), 'IDField' => 'LanguageId', - + 'StatusField' => Array('Enabled','PrimaryLang'), // field, that is affected by Approve/Decline events - + 'TitleField' => 'PackName', // field, used in bluebar when editing existing item - + 'TitlePresets' => Array( 'default' => Array( 'new_status_labels' => Array('lang'=>'!la_title_Adding_Language!'), 'edit_status_labels' => Array('lang'=>'!la_title_Editing_Language!'), 'new_titlefield' => Array('lang'=>'!la_title_New_Language!'), ), - + 'languages_list' => Array( 'prefixes' => Array('lang_List'), 'format' => "!la_title_Configuration! - !la_title_LanguagePacks! (#lang_recordcount#)"), - + 'languages_edit_general' => Array( 'prefixes' => Array('lang'), 'format' => "#lang_status# '#lang_titlefield#' - !la_title_General!"), - + 'phrases_list' => Array( 'prefixes' => Array('lang','phrases_List'), 'format' => "#lang_status# '#lang_titlefield#' - !la_title_Labels! (#phrases_recordcount#)"), - + 'import_language' => Array( 'prefixes' => Array('phrases.import'), 'format' => "!la_title_InstallLanguagePackStep1!"), - + 'import_language_step2' => Array( 'prefixes' => Array('phrases.import'), 'format' => "!la_title_InstallLanguagePackStep2!"), - + 'export_language' => Array( 'prefixes' => Array('phrases.export'), 'format' => "!la_title_ExportLanguagePackStep1!"), - + 'export_language_results' => Array( 'prefixes' => Array('phrases.export'), 'format' => "!la_title_ExportLanguagePackResults!"), - + 'events_list' => Array( 'prefixes' => Array('lang','emailevents_List'), 'format' => "#lang_status# '#lang_titlefield#' - !la_title_EmailEvents! (#emailevents_recordcount#)"), - + 'event_edit' => Array( 'prefixes' => Array('emailevents'), 'edit_status_labels' => Array('emailevents' => '!la_title_Editing_EmailEvent!'), 'format' => '#emailevents_status# - #emailevents_titlefield#'), - + 'email_messages_edit' => Array( 'prefixes' => Array('lang','emailmessages'), 'new_titlefield' => Array('emailmessages' => '!la_NoSubject!'), 'format' => "#lang_status# '#lang_titlefield#' - !la_title_EditingEmailEvent! '#emailmessages_titlefield#'"), ), - + 'PermSection' => Array('main' => 'in-portal:configure_lang'), - + 'Sections' => Array( 'in-portal:configure_lang' => Array( 'parent' => 'in-portal:system', @@ -100,36 +100,36 @@ 'priority' => 4, 'type' => stTREE, ), - + ), - + 'TableName' => TABLE_PREFIX.'Language', 'SubItems' => Array('phrases','emailmessages'), - + 'FilterMenu' => Array( 'Groups' => Array( Array('mode' => 'AND', 'filters' => Array(0,1), 'type' => WHERE_FILTER), ), - + 'Filters' => Array( 0 => Array('label' =>'la_Enabled', 'on_sql' => '', 'off_sql' => '%1$s.Enabled != 1' ), 1 => Array('label' => 'la_Disabled', 'on_sql' => '', 'off_sql' => '%1$s.Enabled != 0' ), ) ), - + 'AutoDelete' => true, - + 'AutoClone' => true, - + 'ListSQLs' => Array( ''=>'SELECT * FROM %s', ), // key - special, value - list select sql 'ItemSQLs' => Array( ''=>'SELECT * FROM %s', ), - 'ListSortings' => Array( + 'ListSortings' => Array( '' => Array( 'Sorting' => Array('PackName' => 'asc'), ) - ), + ), 'Fields' => Array( 'LanguageId' => Array(), 'PackName' => Array('type' => 'string','not_null' => '1','default' => '','required'=>1), @@ -151,7 +151,7 @@ 'CopyLabels' => Array('type' => 'int', 'default' => 0), 'CopyFromLanguage' => Array('type' => 'int', 'formatter' => 'kOptionsFormatter', 'options_sql' => 'SELECT %s FROM '.TABLE_PREFIX.'Language ORDER BY PackName', 'option_title_field' => 'PackName', 'option_key_field' => 'LanguageId'), ), - + 'Grids' => Array( 'Default' => Array( 'Icons' => Array('default'=>'icon16_custom.gif','0_0'=>'icon16_language_disabled.gif','1_0'=>'icon16_language.gif','0_1'=>'icon16_language_disabled.gif','1_1'=>'icon16_language_primary.gif'), @@ -160,7 +160,7 @@ 'LocalName' => Array( 'title'=>'la_col_LocalName' ), 'Enabled' => Array( 'title'=>'la_col_Status' ), ), - + ), ), ); Index: trunk/kernel/units/visits/visits_event_handler.php =================================================================== diff -u -N -r4490 -r4758 --- trunk/kernel/units/visits/visits_event_handler.php (.../visits_event_handler.php) (revision 4490) +++ trunk/kernel/units/visits/visits_event_handler.php (.../visits_event_handler.php) (revision 4758) @@ -1,7 +1,7 @@ Application->RecallVar('visit_id')) { + return true; + } $object =& $event->getObject( Array('skip_autoload'=>true) ); $object->SetDBField('VisitDate_date', adodb_mktime() ); $object->SetDBField('VisitDate_time', adodb_mktime() ); @@ -24,7 +27,7 @@ $this->Application->SetVar('visits_id', $object->GetID() ); } } - + /** * Apply any custom changes to list's sql query * @@ -35,29 +38,29 @@ function SetCustomQuery(&$event) { $object =& $event->getObject(); - + $types = $event->getEventParam('types'); if($types == 'myvisitors') { - + $user_id = $this->Application->GetVar('u_id'); $object->addFilter('myitems_user1','au.PortalUserId = '.$user_id); $object->addFilter('myitems_user2','au.PortalUserId >0'); //$object->AddGroupByField('VisitDate'); $object->AddGroupByField('%1$s.VisitId'); } - + if($types == 'myvisitororders' && $event->Special == 'incommerce') { $user_id = $this->Application->GetVar('u_id'); $object->addFilter('myitems_orders','ord.OrderId IS NOT NULL'); $object->addFilter('myitems_user1','au.PortalUserId = '.$user_id); $object->addFilter('myitems_user2','au.PortalUserId >0'); $object->addFilter('myitems_orders_processed','ord.Status = 4'); - } - } - + } + } + /** * Apply some special processing to * object beeing recalled before using @@ -78,13 +81,13 @@ $object->addCalculatedField('OrderAffiliateCommissionSum', 'SUM( IF(ord.Status = 4,ord.AffiliateCommission,0))'); $object->addCalculatedField('OrderCountByVisit', 'SUM( IF(ord.Status = 4, 1, 0) )'); } - + if (!$types){ $object->AddGroupByField('%1$s.VisitId'); } - } + } } - + } ?> \ No newline at end of file Index: trunk/core/kernel/utility/adodb-time.inc.php =================================================================== diff -u -N -r3282 -r4758 --- trunk/core/kernel/utility/adodb-time.inc.php (.../adodb-time.inc.php) (revision 3282) +++ trunk/core/kernel/utility/adodb-time.inc.php (.../adodb-time.inc.php) (revision 4758) @@ -3,377 +3,24 @@ ADOdb Date Library, part of the ADOdb abstraction library Download: http://php.weblogs.com/adodb_date_time_library -PHP native date functions use integer timestamps for computations. -Because of this, dates are restricted to the years 1901-2038 on Unix -and 1970-2038 on Windows due to integer overflow for dates beyond -those years. This library overcomes these limitations by replacing the -native function's signed integers (normally 32-bits) with PHP floating -point numbers (normally 64-bits). - -Dates from 100 A.D. to 3000 A.D. and later -have been tested. The minimum is 100 A.D. as <100 will invoke the -2 => 4 digit year conversion. The maximum is billions of years in the -future, but this is a theoretical limit as the computation of that year -would take too long with the current implementation of adodb_mktime(). - -This library replaces native functions as follows: - -
	
-	getdate()  with  adodb_getdate()
-	date()     with  adodb_date() 
-	gmdate()   with  adodb_gmdate()
-	mktime()   with  adodb_mktime()
-	gmmktime() with  adodb_gmmktime()
-	strftime() with  adodb_strftime()
-	strftime() with  adodb_gmstrftime()
-
- -The parameters are identical, except that adodb_date() accepts a subset -of date()'s field formats. Mktime() will convert from local time to GMT, -and date() will convert from GMT to local time, but daylight savings is -not handled currently. - -This library is independant of the rest of ADOdb, and can be used -as standalone code. - -PERFORMANCE - -For high speed, this library uses the native date functions where -possible, and only switches to PHP code when the dates fall outside -the 32-bit signed integer range. - -GREGORIAN CORRECTION - -Pope Gregory shortened October of A.D. 1582 by ten days. Thursday, -October 4, 1582 (Julian) was followed immediately by Friday, October 15, -1582 (Gregorian). - -Since 0.06, we handle this correctly, so: - -adodb_mktime(0,0,0,10,15,1582) - adodb_mktime(0,0,0,10,4,1582) - == 24 * 3600 (1 day) - ============================================================================= COPYRIGHT -(c) 2003-2005 John Lim and released under BSD-style license except for code by +(c) 2003-2005 John Lim and released under BSD-style license except for code by jackbbs, which includes adodb_mktime, adodb_get_gmt_diff, adodb_is_leap_year and originally found at http://www.php.net/manual/en/function.mktime.php ============================================================================= -BUG REPORTS -These should be posted to the ADOdb forums at - - http://phplens.com/lens/lensforum/topics.php?id=4 - -============================================================================= - -FUNCTION DESCRIPTIONS - - -** FUNCTION adodb_getdate($date=false) - -Returns an array containing date information, as getdate(), but supports -dates greater than 1901 to 2038. The local date/time format is derived from a -heuristic the first time adodb_getdate is called. - - -** FUNCTION adodb_date($fmt, $timestamp = false) - -Convert a timestamp to a formatted local date. If $timestamp is not defined, the -current timestamp is used. Unlike the function date(), it supports dates -outside the 1901 to 2038 range. - -The format fields that adodb_date supports: - -
-	a - "am" or "pm" 
-	A - "AM" or "PM" 
-	d - day of the month, 2 digits with leading zeros; i.e. "01" to "31" 
-	D - day of the week, textual, 3 letters; e.g. "Fri" 
-	F - month, textual, long; e.g. "January" 
-	g - hour, 12-hour format without leading zeros; i.e. "1" to "12" 
-	G - hour, 24-hour format without leading zeros; i.e. "0" to "23" 
-	h - hour, 12-hour format; i.e. "01" to "12" 
-	H - hour, 24-hour format; i.e. "00" to "23" 
-	i - minutes; i.e. "00" to "59" 
-	j - day of the month without leading zeros; i.e. "1" to "31" 
-	l (lowercase 'L') - day of the week, textual, long; e.g. "Friday"  
-	L - boolean for whether it is a leap year; i.e. "0" or "1" 
-	m - month; i.e. "01" to "12" 
-	M - month, textual, 3 letters; e.g. "Jan" 
-	n - month without leading zeros; i.e. "1" to "12" 
-	O - Difference to Greenwich time in hours; e.g. "+0200" 
-	Q - Quarter, as in 1, 2, 3, 4 
-	r - RFC 822 formatted date; e.g. "Thu, 21 Dec 2000 16:01:07 +0200" 
-	s - seconds; i.e. "00" to "59" 
-	S - English ordinal suffix for the day of the month, 2 characters; 
-	   			i.e. "st", "nd", "rd" or "th" 
-	t - number of days in the given month; i.e. "28" to "31"
-	T - Timezone setting of this machine; e.g. "EST" or "MDT" 
-	U - seconds since the Unix Epoch (January 1 1970 00:00:00 GMT)  
-	w - day of the week, numeric, i.e. "0" (Sunday) to "6" (Saturday) 
-	Y - year, 4 digits; e.g. "1999" 
-	y - year, 2 digits; e.g. "99" 
-	z - day of the year; i.e. "0" to "365" 
-	Z - timezone offset in seconds (i.e. "-43200" to "43200"). 
-	   			The offset for timezones west of UTC is always negative, 
-				and for those east of UTC is always positive. 
-
- -Unsupported: -
-	B - Swatch Internet time 
-	I (capital i) - "1" if Daylight Savings Time, "0" otherwise.
-	W - ISO-8601 week number of year, weeks starting on Monday 
-
-
- - -** FUNCTION adodb_date2($fmt, $isoDateString = false) -Same as adodb_date, but 2nd parameter accepts iso date, eg. - - adodb_date2('d-M-Y H:i','2003-12-25 13:01:34'); - - -** FUNCTION adodb_gmdate($fmt, $timestamp = false) - -Convert a timestamp to a formatted GMT date. If $timestamp is not defined, the -current timestamp is used. Unlike the function date(), it supports dates -outside the 1901 to 2038 range. - - -** FUNCTION adodb_mktime($hr, $min, $sec[, $month, $day, $year]) - -Converts a local date to a unix timestamp. Unlike the function mktime(), it supports -dates outside the 1901 to 2038 range. All parameters are optional. - - -** FUNCTION adodb_gmmktime($hr, $min, $sec [, $month, $day, $year]) - -Converts a gmt date to a unix timestamp. Unlike the function gmmktime(), it supports -dates outside the 1901 to 2038 range. Differs from gmmktime() in that all parameters -are currently compulsory. - -** FUNCTION adodb_gmstrftime($fmt, $timestamp = false) -Convert a timestamp to a formatted GMT date. - -** FUNCTION adodb_strftime($fmt, $timestamp = false) - -Convert a timestamp to a formatted local date. Internally converts $fmt into -adodb_date format, then echo result. - -For best results, you can define the local date format yourself. Define a global -variable $ADODB_DATE_LOCALE which is an array, 1st element is date format using -adodb_date syntax, and 2nd element is the time format, also in adodb_date syntax. - - eg. $ADODB_DATE_LOCALE = array('d/m/Y','H:i:s'); - - Supported format codes: - -
-	%a - abbreviated weekday name according to the current locale 
-	%A - full weekday name according to the current locale 
-	%b - abbreviated month name according to the current locale 
-	%B - full month name according to the current locale 
-	%c - preferred date and time representation for the current locale 
-	%d - day of the month as a decimal number (range 01 to 31) 
-	%D - same as %m/%d/%y 
-	%e - day of the month as a decimal number, a single digit is preceded by a space (range ' 1' to '31') 
-	%h - same as %b
-	%H - hour as a decimal number using a 24-hour clock (range 00 to 23) 
-	%I - hour as a decimal number using a 12-hour clock (range 01 to 12) 
-	%m - month as a decimal number (range 01 to 12) 
-	%M - minute as a decimal number 
-	%n - newline character 
-	%p - either `am' or `pm' according to the given time value, or the corresponding strings for the current locale 
-	%r - time in a.m. and p.m. notation 
-	%R - time in 24 hour notation 
-	%S - second as a decimal number 
-	%t - tab character 
-	%T - current time, equal to %H:%M:%S 
-	%x - preferred date representation for the current locale without the time 
-	%X - preferred time representation for the current locale without the date 
-	%y - year as a decimal number without a century (range 00 to 99) 
-	%Y - year as a decimal number including the century 
-	%Z - time zone or name or abbreviation 
-	%% - a literal `%' character 
-
- - Unsupported codes: -
-	%C - century number (the year divided by 100 and truncated to an integer, range 00 to 99) 
-	%g - like %G, but without the century. 
-	%G - The 4-digit year corresponding to the ISO week number (see %V). 
-	     This has the same format and value as %Y, except that if the ISO week number belongs 
-		 to the previous or next year, that year is used instead. 
-	%j - day of the year as a decimal number (range 001 to 366) 
-	%u - weekday as a decimal number [1,7], with 1 representing Monday 
-	%U - week number of the current year as a decimal number, starting 
-	    with the first Sunday as the first day of the first week 
-	%V - The ISO 8601:1988 week number of the current year as a decimal number, 
-	     range 01 to 53, where week 1 is the first week that has at least 4 days in the 
-		 current year, and with Monday as the first day of the week. (Use %G or %g for 
-		 the year component that corresponds to the week number for the specified timestamp.) 
-	%w - day of the week as a decimal, Sunday being 0 
-	%W - week number of the current year as a decimal number, starting with the 
-	     first Monday as the first day of the first week 
-
- -============================================================================= - -NOTES - -Useful url for generating test timestamps: - http://www.4webhelp.net/us/timestamp.php - -Possible future optimizations include - -a. Using an algorithm similar to Plauger's in "The Standard C Library" -(page 428, xttotm.c _Ttotm() function). Plauger's algorithm will not -work outside 32-bit signed range, so i decided not to implement it. - -b. Implement daylight savings, which looks awfully complicated, see - http://webexhibits.org/daylightsaving/ - - -CHANGELOG - -- 18 July 2005 0.21 -- In PHP 4.3.11, the 'r' format has changed. Leading 0 in day is added. Changed for compat. -- Added support for negative months in adodb_mktime(). - -- 24 Feb 2005 0.20 -Added limited strftime/gmstrftime support. x10 improvement in performance of adodb_date(). - -- 21 Dec 2004 0.17 -In adodb_getdate(), the timestamp was accidentally converted to gmt when $is_gmt is false. -Also adodb_mktime(0,0,0) did not work properly. Both fixed thx Mauro. - -- 17 Nov 2004 0.16 -Removed intval typecast in adodb_mktime() for secs, allowing: - adodb_mktime(0,0,0 + 2236672153,1,1,1934); -Suggested by Ryan. - -- 18 July 2004 0.15 -All params in adodb_mktime were formerly compulsory. Now only the hour, min, secs is compulsory. -This brings it more in line with mktime (still not identical). - -- 23 June 2004 0.14 - -Allow you to define your own daylights savings function, adodb_daylight_sv. -If the function is defined (somewhere in an include), then you can correct for daylights savings. - -In this example, we apply daylights savings in June or July, adding one hour. This is extremely -unrealistic as it does not take into account time-zone, geographic location, current year. - -function adodb_daylight_sv(&$arr, $is_gmt) -{ - if ($is_gmt) return; - $m = $arr['mon']; - if ($m == 6 || $m == 7) $arr['hours'] += 1; -} - -This is only called by adodb_date() and not by adodb_mktime(). - -The format of $arr is -Array ( - [seconds] => 0 - [minutes] => 0 - [hours] => 0 - [mday] => 1 # day of month, eg 1st day of the month - [mon] => 2 # month (eg. Feb) - [year] => 2102 - [yday] => 31 # days in current year - [leap] => # true if leap year - [ndays] => 28 # no of days in current month - ) - - -- 28 Apr 2004 0.13 -Fixed adodb_date to properly support $is_gmt. Thx to Dimitar Angelov. - -- 20 Mar 2004 0.12 -Fixed month calculation error in adodb_date. 2102-June-01 appeared as 2102-May-32. - -- 26 Oct 2003 0.11 -Because of daylight savings problems (some systems apply daylight savings to -January!!!), changed adodb_get_gmt_diff() to ignore daylight savings. - -- 9 Aug 2003 0.10 -Fixed bug with dates after 2038. -See http://phplens.com/lens/lensforum/msgs.php?id=6980 - -- 1 July 2003 0.09 -Added support for Q (Quarter). -Added adodb_date2(), which accepts ISO date in 2nd param - -- 3 March 2003 0.08 -Added support for 'S' adodb_date() format char. Added constant ADODB_ALLOW_NEGATIVE_TS -if you want PHP to handle negative timestamps between 1901 to 1969. - -- 27 Feb 2003 0.07 -All negative numbers handled by adodb now because of RH 7.3+ problems. -See http://bugs.php.net/bug.php?id=20048&edit=2 - -- 4 Feb 2003 0.06 -Fixed a typo, 1852 changed to 1582! This means that pre-1852 dates -are now correctly handled. - -- 29 Jan 2003 0.05 - -Leap year checking differs under Julian calendar (pre 1582). Also -leap year code optimized by checking for most common case first. - -We also handle month overflow correctly in mktime (eg month set to 13). - -Day overflow for less than one month's days is supported. - -- 28 Jan 2003 0.04 - -Gregorian correction handled. In PHP5, we might throw an error if -mktime uses invalid dates around 5-14 Oct 1582. Released with ADOdb 3.10. -Added limbo 5-14 Oct 1582 check, when we set to 15 Oct 1582. - -- 27 Jan 2003 0.03 - -Fixed some more month problems due to gmt issues. Added constant ADODB_DATE_VERSION. -Fixed calculation of days since start of year for <1970. - -- 27 Jan 2003 0.02 - -Changed _adodb_getdate() to inline leap year checking for better performance. -Fixed problem with time-zones west of GMT +0000. - -- 24 Jan 2003 0.01 - -First implementation. -*/ - - /* Initialization */ /* Version Number */ define('ADODB_DATE_VERSION',0.21); -/* - This code was originally for windows. But apparently this problem happens - also with Linux, RH 7.3 and later! - - glibc-2.2.5-34 and greater has been changed to return -1 for dates < - 1970. This used to work. The problem exists with RedHat 7.3 and 8.0 - echo (mktime(0, 0, 0, 1, 1, 1960)); // prints -1 - - References: - http://bugs.php.net/bug.php?id=20048&edit=2 - http://lists.debian.org/debian-glibc/2002/debian-glibc-200205/msg00010.html -*/ - if (!defined('ADODB_ALLOW_NEGATIVE_TS')) define('ADODB_NO_NEGATIVE_TS',1); function adodb_date_test_date($y1,$m,$d=13) @@ -391,232 +38,74 @@ { $s1 = strftime($fmt); $s2 = adodb_strftime($fmt); - + if ($s1 == $s2) return true; - + echo "error for $fmt, strftime=$s1, $adodb=$s2
"; return false; } /** - Test Suite -*/ -function adodb_date_test() -{ - - error_reporting(E_ALL); - print "

Testing adodb_date and adodb_mktime. version=".ADODB_DATE_VERSION.' PHP='.PHP_VERSION."

"; - @set_time_limit(0); - $fail = false; - - // This flag disables calling of PHP native functions, so we can properly test the code - if (!defined('ADODB_TEST_DATES')) define('ADODB_TEST_DATES',1); - - adodb_date_test_strftime('%Y %m %x %X'); - adodb_date_test_strftime("%A %d %B %Y"); - adodb_date_test_strftime("%H %M S"); - - $t = adodb_mktime(0,0,0); - if (!(adodb_date('Y-m-d') == date('Y-m-d'))) print 'Error in '.adodb_mktime(0,0,0).'
'; - - $t = adodb_mktime(0,0,0,6,1,2102); - if (!(adodb_date('Y-m-d',$t) == '2102-06-01')) print 'Error in '.adodb_date('Y-m-d',$t).'
'; - - $t = adodb_mktime(0,0,0,2,1,2102); - if (!(adodb_date('Y-m-d',$t) == '2102-02-01')) print 'Error in '.adodb_date('Y-m-d',$t).'
'; - - - print "

Testing gregorian <=> julian conversion

"; - $t = adodb_mktime(0,0,0,10,11,1492); - //http://www.holidayorigins.com/html/columbus_day.html - Friday check - if (!(adodb_date('D Y-m-d',$t) == 'Fri 1492-10-11')) print 'Error in Columbus landing
'; - - $t = adodb_mktime(0,0,0,2,29,1500); - if (!(adodb_date('Y-m-d',$t) == '1500-02-29')) print 'Error in julian leap years
'; - - $t = adodb_mktime(0,0,0,2,29,1700); - if (!(adodb_date('Y-m-d',$t) == '1700-03-01')) print 'Error in gregorian leap years
'; - - print adodb_mktime(0,0,0,10,4,1582).' '; - print adodb_mktime(0,0,0,10,15,1582); - $diff = (adodb_mktime(0,0,0,10,15,1582) - adodb_mktime(0,0,0,10,4,1582)); - if ($diff != 3600*24) print " Error in gregorian correction = ".($diff/3600/24)." days
"; - - print " 15 Oct 1582, Fri=".(adodb_dow(1582,10,15) == 5 ? 'Fri' : 'Error')."
"; - print " 4 Oct 1582, Thu=".(adodb_dow(1582,10,4) == 4 ? 'Thu' : 'Error')."
"; - - print "

Testing overflow

"; - - $t = adodb_mktime(0,0,0,3,33,1965); - if (!(adodb_date('Y-m-d',$t) == '1965-04-02')) print 'Error in day overflow 1
'; - $t = adodb_mktime(0,0,0,4,33,1971); - if (!(adodb_date('Y-m-d',$t) == '1971-05-03')) print 'Error in day overflow 2
'; - $t = adodb_mktime(0,0,0,1,60,1965); - if (!(adodb_date('Y-m-d',$t) == '1965-03-01')) print 'Error in day overflow 3 '.adodb_date('Y-m-d',$t).'
'; - $t = adodb_mktime(0,0,0,12,32,1965); - if (!(adodb_date('Y-m-d',$t) == '1966-01-01')) print 'Error in day overflow 4 '.adodb_date('Y-m-d',$t).'
'; - $t = adodb_mktime(0,0,0,12,63,1965); - if (!(adodb_date('Y-m-d',$t) == '1966-02-01')) print 'Error in day overflow 5 '.adodb_date('Y-m-d',$t).'
'; - $t = adodb_mktime(0,0,0,13,3,1965); - if (!(adodb_date('Y-m-d',$t) == '1966-01-03')) print 'Error in mth overflow 1
'; - - print "Testing 2-digit => 4-digit year conversion

"; - if (adodb_year_digit_check(00) != 2000) print "Err 2-digit 2000
"; - if (adodb_year_digit_check(10) != 2010) print "Err 2-digit 2010
"; - if (adodb_year_digit_check(20) != 2020) print "Err 2-digit 2020
"; - if (adodb_year_digit_check(30) != 2030) print "Err 2-digit 2030
"; - if (adodb_year_digit_check(40) != 1940) print "Err 2-digit 1940
"; - if (adodb_year_digit_check(50) != 1950) print "Err 2-digit 1950
"; - if (adodb_year_digit_check(90) != 1990) print "Err 2-digit 1990
"; - - // Test string formating - print "

Testing date formating

"; - $fmt = '\d\a\t\e T Y-m-d H:i:s a A d D F g G h H i j l L m M n O \R\F\C822 r s t U w y Y z Z 2003'; - $s1 = date($fmt,0); - $s2 = adodb_date($fmt,0); - if ($s1 != $s2) { - print " date() 0 failed
$s1
$s2
"; - } - flush(); - for ($i=100; --$i > 0; ) { - - $ts = 3600.0*((rand()%60000)+(rand()%60000))+(rand()%60000); - $s1 = date($fmt,$ts); - $s2 = adodb_date($fmt,$ts); - //print "$s1
$s2

"; - $pos = strcmp($s1,$s2); - - if (($s1) != ($s2)) { - for ($j=0,$k=strlen($s1); $j < $k; $j++) { - if ($s1[$j] != $s2[$j]) { - print substr($s1,$j).' '; - break; - } - } - print "Error date(): $ts

 
-  \"$s1\" (date len=".strlen($s1).")
-  \"$s2\" (adodb_date len=".strlen($s2).")

"; - $fail = true; - } - - $a1 = getdate($ts); - $a2 = adodb_getdate($ts); - $rez = array_diff($a1,$a2); - if (sizeof($rez)>0) { - print "Error getdate() $ts
"; - print_r($a1); - print "
"; - print_r($a2); - print "

"; - $fail = true; - } - } - - // Test generation of dates outside 1901-2038 - print "

Testing random dates between 100 and 4000

"; - adodb_date_test_date(100,1); - for ($i=100; --$i >= 0;) { - $y1 = 100+rand(0,1970-100); - $m = rand(1,12); - adodb_date_test_date($y1,$m); - - $y1 = 3000-rand(0,3000-1970); - adodb_date_test_date($y1,$m); - } - print '

'; - $start = 1960+rand(0,10); - $yrs = 12; - $i = 365.25*86400*($start-1970); - $offset = 36000+rand(10000,60000); - $max = 365*$yrs*86400; - $lastyear = 0; - - // we generate a timestamp, convert it to a date, and convert it back to a timestamp - // and check if the roundtrip broke the original timestamp value. - print "Testing $start to ".($start+$yrs).", or $max seconds, offset=$offset: "; - $cnt = 0; - for ($max += $i; $i < $max; $i += $offset) { - $ret = adodb_date('m,d,Y,H,i,s',$i); - $arr = explode(',',$ret); - if ($lastyear != $arr[2]) { - $lastyear = $arr[2]; - print " $lastyear "; - flush(); - } - $newi = adodb_mktime($arr[3],$arr[4],$arr[5],$arr[0],$arr[1],$arr[2]); - if ($i != $newi) { - print "Error at $i, adodb_mktime returned $newi ($ret)"; - $fail = true; - break; - } - $cnt += 1; - } - echo "Tested $cnt dates
"; - if (!$fail) print "

Passed !

"; - else print "

Failed :-(

"; -} - -/** - Returns day of week, 0 = Sunday,... 6=Saturday. + Returns day of week, 0 = Sunday,... 6=Saturday. Algorithm from PEAR::Date_Calc */ function adodb_dow($year, $month, $day) { /* -Pope Gregory removed 10 days - October 5 to October 14 - from the year 1582 and -proclaimed that from that time onwards 3 days would be dropped from the calendar +Pope Gregory removed 10 days - October 5 to October 14 - from the year 1582 and +proclaimed that from that time onwards 3 days would be dropped from the calendar every 400 years. -Thursday, October 4, 1582 (Julian) was followed immediately by Friday, October 15, 1582 (Gregorian). +Thursday, October 4, 1582 (Julian) was followed immediately by Friday, October 15, 1582 (Gregorian). */ if ($year <= 1582) { - if ($year < 1582 || + if ($year < 1582 || ($year == 1582 && ($month < 10 || ($month == 10 && $day < 15)))) $greg_correction = 3; else $greg_correction = 0; } else $greg_correction = 0; - + if($month > 2) $month -= 2; else { $month += 10; $year--; } - + $day = floor((13 * $month - 1) / 5) + $day + ($year % 100) + floor(($year % 100) / 4) + floor(($year / 100) / 4) - 2 * floor($year / 100) + 77 + $greg_correction; - + return $day - 7 * floor($day / 7); } /** - Checks for leap year, returns true if it is. No 2-digit year check. Also + Checks for leap year, returns true if it is. No 2-digit year check. Also handles julian calendar correctly. */ -function _adodb_is_leap_year($year) +function _adodb_is_leap_year($year) { if ($year % 4 != 0) return false; - + if ($year % 400 == 0) { return true; // if gregorian calendar (>1582), century not-divisible by 400 is not leap } else if ($year > 1582 && $year % 100 == 0 ) { return false; - } - + } + return true; } /** checks for leap year, returns true if it is. Has 2-digit year check */ -function adodb_is_leap_year($year) +function adodb_is_leap_year($year) { return _adodb_is_leap_year(adodb_year_digit_check($year)); } @@ -625,13 +114,13 @@ Fix 2-digit years. Works for any century. Assumes that if 2-digit is more than 30 years in future, then previous century. */ -function adodb_year_digit_check($y) +function adodb_year_digit_check($y) { if ($y < 100) { - + $yr = (integer) date("Y"); $century = (integer) ($yr /100); - + if ($yr%100 > 50) { $c1 = $century + 1; $c0 = $century; @@ -651,11 +140,11 @@ /** get local time zone offset from GMT */ -function adodb_get_gmt_diff() +function adodb_get_gmt_diff() { static $TZ; if (isset($TZ)) return $TZ; - + $TZ = mktime(0,0,0,1,2,1970,0) - gmmktime(0,0,0,1,2,1970,0); return $TZ; } @@ -675,26 +164,7 @@ return _adodb_getdate($d); } -/* -// generate $YRS table for _adodb_getdate() -function adodb_date_gentable($out=true) -{ - for ($i=1970; $i >= 1600; $i-=10) { - $s = adodb_gmmktime(0,0,0,1,1,$i); - echo "$i => $s,
"; - } -} -adodb_date_gentable(); - -for ($i=1970; $i > 1500; $i--) { - -echo "
$i "; - adodb_date_test_date($i,1,1); -} - -*/ - /** Low-level function that returns the getdate() array. We have a special $fast flag, which if set to true, will return fewer array values, @@ -705,21 +175,21 @@ static $YRS; $d = $origd - ($is_gmt ? 0 : adodb_get_gmt_diff()); - + $_day_power = 86400; $_hour_power = 3600; $_min_power = 60; - - if ($d < -12219321600) $d -= 86400*10; // if 15 Oct 1582 or earlier, gregorian correction - + + if ($d < -12219321600) $d -= 86400*10; // if 15 Oct 1582 or earlier, gregorian correction + $_month_table_normal = array("",31,28,31,30,31,30,31,31,30,31,30,31); $_month_table_leaf = array("",31,29,31,30,31,30,31,31,30,31,30,31); - + $d366 = $_day_power * 366; $d365 = $_day_power * 365; - + if ($d < 0) { - + if (empty($YRS)) $YRS = array( 1970 => 0, 1960 => -315619200, @@ -761,28 +231,28 @@ 1600 => -11676096000); if ($is_gmt) $origd = $d; - // The valid range of a 32bit signed timestamp is typically from + // The valid range of a 32bit signed timestamp is typically from // Fri, 13 Dec 1901 20:45:54 GMT to Tue, 19 Jan 2038 03:14:07 GMT // - + # old algorithm iterates through all years. new algorithm does it in # 10 year blocks - + /* # old algo for ($a = 1970 ; --$a >= 0;) { $lastd = $d; - + if ($leaf = _adodb_is_leap_year($a)) $d += $d366; else $d += $d365; - + if ($d >= 0) { $year = $a; break; } } */ - + $lastsecs = 0; $lastyear = 1970; foreach($YRS as $year => $secs) { @@ -793,27 +263,27 @@ $lastsecs = $secs; $lastyear = $year; } - + $d -= $lastsecs; if (!isset($a)) $a = $lastyear; - + //echo ' yr=',$a,' ', $d,'.'; - + for (; --$a >= 0;) { $lastd = $d; - + if ($leaf = _adodb_is_leap_year($a)) $d += $d366; else $d += $d365; - + if ($d >= 0) { $year = $a; break; } } /**/ - + $secsInYear = 86400 * ($leaf ? 366 : 365) + $lastd; - + $d = $lastd; $mtab = ($leaf) ? $_month_table_leaf : $_month_table_normal; for ($a = 13 ; --$a > 0;) { @@ -825,17 +295,17 @@ break; } } - + $d = $lastd; $day = $ndays + ceil(($d+1) / ($_day_power)); $d += ($ndays - $day+1)* $_day_power; $hour = floor($d/$_hour_power); - + } else { for ($a = 1970 ;; $a++) { $lastd = $d; - + if ($leaf = _adodb_is_leap_year($a)) $d -= $d366; else $d -= $d365; if ($d < 0) { @@ -860,7 +330,7 @@ $d = $d - ($day-1) * $_day_power; $hour = floor($d /$_hour_power); } - + $d -= $hour * $_hour_power; $min = floor($d/$_min_power); $secs = $d - $min * $_min_power; @@ -877,8 +347,8 @@ 'ndays' => $ndays ); } - - + + $dow = adodb_dow($year,$month,$day); return array( @@ -905,17 +375,17 @@ function adodb_date2($fmt, $d=false, $is_gmt=false) { if ($d !== false) { - if (!preg_match( - "|^([0-9]{4})[-/\.]?([0-9]{1,2})[-/\.]?([0-9]{1,2})[ -]?(([0-9]{1,2}):?([0-9]{1,2}):?([0-9\.]{1,4}))?|", + if (!preg_match( + "|^([0-9]{4})[-/\.]?([0-9]{1,2})[-/\.]?([0-9]{1,2})[ -]?(([0-9]{1,2}):?([0-9]{1,2}):?([0-9\.]{1,4}))?|", ($d), $rr)) return adodb_date($fmt,false,$is_gmt); if ($rr[1] <= 100 && $rr[2]<= 1) return adodb_date($fmt,false,$is_gmt); - + // h-m-s-MM-DD-YY if (!isset($rr[5])) $d = adodb_mktime(0,0,0,$rr[2],$rr[3],$rr[1]); else $d = @adodb_mktime($rr[5],$rr[6],$rr[7],$rr[2],$rr[3],$rr[1]); } - + return adodb_date($fmt,$d,$is_gmt); } @@ -936,22 +406,22 @@ } } $_day_power = 86400; - + $arr = _adodb_getdate($d,true,$is_gmt); - + if (!isset($daylight)) $daylight = function_exists('adodb_daylight_sv'); if ($daylight) adodb_daylight_sv($arr, $is_gmt); - + $year = $arr['year']; $month = $arr['mon']; $day = $arr['mday']; $hour = $arr['hours']; $min = $arr['minutes']; $secs = $arr['seconds']; - + $max = strlen($fmt); $dates = ''; - + /* at this point, we have the following integer vars to manipulate: $year, $month, $day, $hour, $min, $secs @@ -962,21 +432,21 @@ // YEAR case 'L': $dates .= $arr['leap'] ? '1' : '0'; break; case 'r': // Thu, 21 Dec 2000 16:01:07 +0200 - + // 4.3.11 uses '04 Jun 2004' // 4.3.8 uses ' 4 Jun 2004' - $dates .= gmdate('D',$_day_power*(3+adodb_dow($year,$month,$day))).', ' + $dates .= gmdate('D',$_day_power*(3+adodb_dow($year,$month,$day))).', ' . ($day<10?'0'.$day:$day) . ' '.date('M',mktime(0,0,0,$month,2,1971)).' '.$year.' '; - - if ($hour < 10) $dates .= '0'.$hour; else $dates .= $hour; - + + if ($hour < 10) $dates .= '0'.$hour; else $dates .= $hour; + if ($min < 10) $dates .= ':0'.$min; else $dates .= ':'.$min; - + if ($secs < 10) $dates .= ':0'.$secs; else $dates .= ':'.$secs; - + $gmt = adodb_get_gmt_diff(); $dates .= sprintf(' %s%04d',($gmt<0)?'+':'-',abs($gmt)/36); break; - + case 'Y': $dates .= $year; break; case 'y': $dates .= substr($year,strlen($year)-2,2); break; // MONTH @@ -993,45 +463,45 @@ case 'D': $dates .= gmdate('D',$_day_power*(3+adodb_dow($year,$month,$day))); break; case 'j': $dates .= $day; break; case 'd': if ($day<10) $dates .= '0'.$day; else $dates .= $day; break; - case 'S': + case 'S': $d10 = $day % 10; if ($d10 == 1) $dates .= 'st'; else if ($d10 == 2 && $day != 12) $dates .= 'nd'; else if ($d10 == 3) $dates .= 'rd'; else $dates .= 'th'; break; - + // HOUR case 'Z': $dates .= ($is_gmt) ? 0 : -adodb_get_gmt_diff(); break; - case 'O': + case 'O': $gmt = ($is_gmt) ? 0 : adodb_get_gmt_diff(); $dates .= sprintf('%s%04d',($gmt<0)?'+':'-',abs($gmt)/36); break; - - case 'H': - if ($hour < 10) $dates .= '0'.$hour; - else $dates .= $hour; + + case 'H': + if ($hour < 10) $dates .= '0'.$hour; + else $dates .= $hour; break; - case 'h': - if ($hour > 12) $hh = $hour - 12; + case 'h': + if ($hour > 12) $hh = $hour - 12; else { - if ($hour == 0) $hh = '12'; + if ($hour == 0) $hh = '12'; else $hh = $hour; } - + if ($hh < 10) $dates .= '0'.$hh; else $dates .= $hh; break; - - case 'G': + + case 'G': $dates .= $hour; break; - + case 'g': - if ($hour > 12) $hh = $hour - 12; + if ($hour > 12) $hh = $hour - 12; else { - if ($hour == 0) $hh = '12'; - else $hh = $hour; + if ($hour == 0) $hh = '12'; + else $hh = $hour; } $dates .= $hh; break; @@ -1053,7 +523,7 @@ default: $dates .= $fmt[$i]; break; // ESCAPE - case "\\": + case "\\": $i++; if ($i < $max) $dates .= $fmt[$i]; break; @@ -1063,7 +533,7 @@ } /** - Returns a timestamp given a GMT/UTC time. + Returns a timestamp given a GMT/UTC time. Note that $is_dst is not implemented and is ignored. */ function adodb_gmmktime($hr,$min,$sec,$mon=false,$day=false,$year=false,$is_dst=false) @@ -1074,25 +544,25 @@ /** Return a timestamp given a local time. Originally by jackbbs. Note that $is_dst is not implemented and is ignored. - + Not a very fast algorithm - O(n) operation. Could be optimized to O(1). */ -function adodb_mktime($hr = null, $min = null, $sec = null, $mon = null, $day = null, $year = null,$is_dst=false,$is_gmt=false) +function adodb_mktime($hr = null, $min = null, $sec = null, $mon = null, $day = null, $year = null,$is_dst=false,$is_gmt=false) { if( !isset($hr) ) $hr = adodb_date('H'); if( !isset($min) ) $min = adodb_date('i'); if( !isset($sec) ) $sec = adodb_date('s'); if( !isset($mon) ) $mon = adodb_date('m'); if( !isset($day) ) $day = adodb_date('d'); if( !isset($year) ) $year = adodb_date('Y'); - + if (!defined('ADODB_TEST_DATES')) { if ($mon === false || !isset($mon) ) { return $is_gmt? @gmmktime($hr,$min,$sec): @mktime($hr,$min,$sec); } - - // for windows, we don't check 1970 because with timezone differences, + + // for windows, we don't check 1970 because with timezone differences, // 1 Jan 1970 could generate negative timestamp, which is illegal if (1971 < $year && $year < 2038 || !defined('ADODB_NO_NEGATIVE_TS') && (1901 < $year && $year < 2038) @@ -1102,7 +572,7 @@ @mktime($hr,$min,$sec,$mon,$day,$year); } } - + $gmt_different = ($is_gmt) ? 0 : adodb_get_gmt_diff(); /* @@ -1115,8 +585,8 @@ $mon = intval($mon); $day = intval($day); $year = intval($year); - - + + $year = adodb_year_digit_check($year); if ($mon > 12) { @@ -1128,14 +598,14 @@ $year -= $y; $mon += $y*12; } - + $_day_power = 86400; $_hour_power = 3600; $_min_power = 60; - + $_month_table_normal = array("",31,28,31,30,31,30,31,31,30,31,30,31); $_month_table_leaf = array("",31,29,31,30,31,30,31,31,30,31,30,31); - + $_total_date = 0; if ($year >= 1970) { for ($a = 1970 ; $a <= $year; $a++) { @@ -1147,7 +617,7 @@ $loop_table = $_month_table_normal; $_add_date = 365; } - if ($a < $year) { + if ($a < $year) { $_total_date += $_add_date; } else { for($b=1;$b<$mon;$b++) { @@ -1157,7 +627,7 @@ } $_total_date +=$day-1; $ret = $_total_date * $_day_power + $hr * $_hour_power + $min * $_min_power + $sec + $gmt_different; - + } else { for ($a = 1969 ; $a >= $year; $a--) { $leaf = _adodb_is_leap_year($a); @@ -1176,13 +646,13 @@ } } $_total_date += $loop_table[$mon] - $day; - + $_day_time = $hr * $_hour_power + $min * $_min_power + $sec; $_day_time = $_day_power - $_day_time; $ret = -( $_total_date * $_day_power + $_day_time - $gmt_different); if ($ret < -12220185600) $ret += 10*86400; // if earlier than 5 Oct 1582 - gregorian correction else if ($ret < -12219321600) $ret = -12219321600; // if in limbo, reset to 15 Oct 1582. - } + } //print " dmy=$day/$mon/$year $hr:$min:$sec => " .$ret; return $ret; } @@ -1204,16 +674,16 @@ } } - + if (empty($ADODB_DATE_LOCALE)) { $tstr = strtoupper(gmstrftime('%c',31366800)); // 30 Dec 1970, 1 am $sep = substr($tstr,2,1); $hasAM = strrpos($tstr,'M') !== false; - + $ADODB_DATE_LOCALE = array(); - $ADODB_DATE_LOCALE[] = strncmp($tstr,'30',2) == 0 ? 'd'.$sep.'m'.$sep.'y' : 'm'.$sep.'d'.$sep.'y'; + $ADODB_DATE_LOCALE[] = strncmp($tstr,'30',2) == 0 ? 'd'.$sep.'m'.$sep.'y' : 'm'.$sep.'d'.$sep.'y'; $ADODB_DATE_LOCALE[] = ($hasAM) ? 'h:i:s a' : 'H:i:s'; - + } $inpct = false; $fmtdate = ''; @@ -1226,7 +696,7 @@ } else $inpct = true; } else if ($inpct) { - + $inpct = false; switch($ch) { case '0': @@ -1242,9 +712,9 @@ case 'E': case 'O': /* ignore format modifiers */ - $inpct = true; + $inpct = true; break; - + case 'a': $fmtdate .= 'D'; break; case 'A': $fmtdate .= 'l'; break; case 'h': Index: trunk/kernel/units/custom_data/custom_data_config.php =================================================================== diff -u -N -r4287 -r4758 --- trunk/kernel/units/custom_data/custom_data_config.php (.../custom_data_config.php) (revision 4287) +++ trunk/kernel/units/custom_data/custom_data_config.php (.../custom_data_config.php) (revision 4758) @@ -1,52 +1,48 @@ '', - + 'Prefix' => 'cdata', + 'Clones' => Array( - + 'u-cdata' => Array( 'TableName' => TABLE_PREFIX.'PortalUserCustomData', 'ParentPrefix' => 'u', ), - + 'c-cdata' => Array( 'TableName' => TABLE_PREFIX.'CategoryCustomData', 'ParentPrefix' => 'c', ), - - 'l-cdata' => Array( - 'TableName' => TABLE_PREFIX.'LinkCustomData', - 'ParentPrefix' => 'l', - ), - + + 'n-cdata' => Array( 'TableName' => TABLE_PREFIX.'NewsCustomData', 'ParentPrefix' => 'n', ), - + 'bb-cdata' => Array( 'TableName' => TABLE_PREFIX.'TopicCustomData', 'ParentPrefix' => 'bb', ), - + 'p-cdata' => Array( 'TableName' => TABLE_PREFIX.'ProductsCustomData', 'ParentPrefix' => 'p', ), ), - + 'QueryString' => Array( 1 => 'id', 2 => 'event', ), - + '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, - + 'Hooks' => Array( Array( 'Mode' => hAFTER, @@ -59,26 +55,26 @@ 'DoEvent' => 'OnCreateCustomFields', ), ), - + 'IDField' => 'CustomDataId', - + 'ParentTableKey' => 'ResourceId', 'ForeignKey' => 'ResourceId', 'AutoDelete' => true, 'AutoClone' => false, - + 'CalculatedFields' => Array( '' => Array(), ), 'ListSQLs' => Array('' => 'SELECT %1$s.* %2$s FROM %1$s'), 'ItemSQLs' => Array('' => 'SELECT %1$s.* %2$s FROM %1$s'), - + 'Fields' => Array( 'CustomDataId' => Array(), 'ResourceId' => Array('type' => 'int', 'not_null' => 1, 'default' => 0), ), ); - + ?> \ No newline at end of file Index: trunk/admin/index.php =================================================================== diff -u -N -r4490 -r4758 --- trunk/admin/index.php (.../index.php) (revision 4490) +++ trunk/admin/index.php (.../index.php) (revision 4758) @@ -32,11 +32,11 @@ '; } -function getmicrotime() -{ - list($usec, $sec) = explode(" ", microtime()); - return ((float)$usec + (float)$sec); -} +function getmicrotime() +{ + list($usec, $sec) = explode(" ", microtime()); + return ((float)$usec + (float)$sec); +} //update_memory_check_script(); Index: trunk/core/units/general/my_application.php =================================================================== diff -u -N -r4607 -r4758 --- trunk/core/units/general/my_application.php (.../my_application.php) (revision 4607) +++ trunk/core/units/general/my_application.php (.../my_application.php) (revision 4758) @@ -28,8 +28,9 @@ $this->registerClass('kSearchHelper', MODULES_PATH.'/kernel/units/general/helpers/search_helper.php', 'SearchHelper'); $this->registerClass('kSectionsHelper', MODULES_PATH.'/kernel/units/general/helpers/sections_helper.php', 'SectionsHelper'); $this->registerClass('kPermissionsHelper', MODULES_PATH.'/kernel/units/general/helpers/permissions_helper.php', 'PermissionsHelper'); - + $this->registerClass('kModulesHelper', MODULES_PATH.'/kernel/units/general/helpers/modules.php', 'ModulesHelper'); + $this->registerClass('kModRewriteHelper', MODULES_PATH.'/kernel/units/general/helpers/mod_rewrite_helper.php', 'ModRewriteHelper'); } function getUserGroups($user_id) Index: trunk/kernel/units/categories/categories_tag_processor.php =================================================================== diff -u -N -r4446 -r4758 --- trunk/kernel/units/categories/categories_tag_processor.php (.../categories_tag_processor.php) (revision 4446) +++ trunk/kernel/units/categories/categories_tag_processor.php (.../categories_tag_processor.php) (revision 4758) @@ -279,6 +279,11 @@ $special = crc32($types.$except.$parent_cat_id); return $special; } + + function IsCurrent($params) + { + return false; + } } Index: trunk/kernel/units/categories/categories_item.php =================================================================== diff -u -N -r4243 -r4758 --- trunk/kernel/units/categories/categories_item.php (.../categories_item.php) (revision 4243) +++ trunk/kernel/units/categories/categories_item.php (.../categories_item.php) (revision 4758) @@ -99,7 +99,7 @@ $found_temp_ids = $this->Conn->GetCol($sql_temp); // check live table - $sql_live = 'SELECT '.$this->IDField.' FROM '.kTempTablesHandler::GetLiveName($this->TableName).' WHERE Filename = '.$this->Conn->qstr($filename); + $sql_live = 'SELECT '.$this->IDField.' FROM '.$this->Application->GetLiveName($this->TableName).' WHERE Filename = '.$this->Conn->qstr($filename); $found_live_ids = $this->Conn->GetCol($sql_live); $found_item_ids = array_unique( array_merge($found_temp_ids, $found_live_ids) ); @@ -118,7 +118,7 @@ // check live & temp table $sql_temp = 'SELECT '.$this->IDField.' FROM '.$this->TableName.' WHERE (Filename = %s) AND ('.$this->IDField.' != '.$item_id.')'; - $sql_live = 'SELECT '.$this->IDField.' FROM '.kTempTablesHandler::GetLiveName($this->TableName).' WHERE (Filename = %s) AND ('.$this->IDField.' != '.$item_id.')'; + $sql_live = 'SELECT '.$this->IDField.' FROM '.$this->Application->GetLiveName($this->TableName).' WHERE (Filename = %s) AND ('.$this->IDField.' != '.$item_id.')'; while ( $this->Conn->GetOne( sprintf($sql_temp, $this->Conn->qstr($filename.$append)) ) > 0 || $this->Conn->GetOne( sprintf($sql_live, $this->Conn->qstr($filename.$append)) ) > 0 ) { Index: trunk/core/kernel/processors/main_processor.php =================================================================== diff -u -N -r4723 -r4758 --- trunk/core/kernel/processors/main_processor.php (.../main_processor.php) (revision 4723) +++ trunk/core/kernel/processors/main_processor.php (.../main_processor.php) (revision 4758) @@ -524,17 +524,17 @@ $current_template = $this->Application->GetVar('t'); foreach ($this->Application->ModuleInfo as $module_name => $module_data) { $module_key = strtolower($module_name); - + if ($module_name == 'In-Portal') { $module_prefix = ''; } else { $module_prefix = $this->Application->IsAdmin() ? $module_key.'/' : $module_data['TemplatePath'].'/'; } - + $block_params['t'] = $module_prefix.$this->SelectParam($params, $module_key.'_template,'.$module_key.'_t,template,t'); if ($block_params['t'] == $current_template) continue; - + $no_data = $this->SelectParam($params, $module_key.'_block_no_data,block_no_data'); if ($no_data) { $block_params['block_no_data'] = $module_prefix.'/'.$no_data; @@ -754,7 +754,7 @@ if ( $this->Application->LoggedIn() && !$group_access) { $this->Application->Redirect( $params['no_group_perm_template'], Array('next_template'=>$t) ); } - + $redirect_params = Array('next_template' => $t); $session_expired = $this->Application->GetVar('expired'); if ($session_expired) { @@ -764,6 +764,18 @@ } } + function IsMember($params) + { + $group = getArrayValue($params, 'group'); + $conn =& $this->Application->DB; + $group_id = $conn->GetOne('SELECT GroupId FROM '.TABLE_PREFIX.'PortalGroup WHERE Name = '.$conn->qstr($group)); + if ($group_id) { + $groups = explode(',', $this->Application->RecallVar('UserGroups')); + $group_access = in_array($group_id, $groups); + } + return $group_access; + } + /** * Checks if SSL is on and redirects to SSL URL if needed * If SSL_URL is not defined in config - the tag does not do anything @@ -823,7 +835,7 @@ $module =& $this->Application->recallObject('mod.'.$module_name); $this->Application->SetVar('m_cat_id', $module->GetDBField('RootCat') ); } - + function XMLTemplate($params) { define('DBG_SKIP_REPORTING', 1); Index: trunk/core/kernel/kbase.php =================================================================== diff -u -N -r4284 -r4758 --- trunk/core/kernel/kbase.php (.../kbase.php) (revision 4284) +++ trunk/core/kernel/kbase.php (.../kbase.php) (revision 4758) @@ -157,7 +157,7 @@ * @var Array */ var $customFields = Array(); - + /** * All virtual field names * @@ -174,14 +174,14 @@ */ var $CalculatedFields = Array(); - + /** * Calculated fields, that contain aggregated functions, e.g. COUNT, SUM, etc. * * @var Array */ var $AggregatedCalculatedFields = Array(); - + /** * Description * @@ -234,7 +234,7 @@ function SwitchToTemp() { $this->TableName = $this->Application->getUnitOption($this->Prefix, 'TableName'); - $this->SetTableName( kTempTablesHandler::GetTempName($this->TableName) ); + $this->SetTableName( $this->Application->GetTempName($this->TableName) ); $this->mode = 't'; } @@ -245,7 +245,7 @@ */ function IsTempTable() { - return kTempTablesHandler::IsTempTable($this->TableName); + return $this->Application->IsTempTable($this->TableName); } /** @@ -270,7 +270,7 @@ return $query; } - + /** * Returns required mixing of aggregated & non-aggregated calculated fields * @@ -283,23 +283,23 @@ case 0: $fields = array_merge($this->CalculatedFields, $this->AggregatedCalculatedFields); break; - + case 1: $fields = $this->CalculatedFields; break; - + case 2: $fields = $this->AggregatedCalculatedFields; break; - + default: $fields = Array(); break; } - + return $fields; } - + /** * Insert calculated fields sql into query in place of %2$s, * return processed query. @@ -332,11 +332,11 @@ */ function replaceModePrefix($query) { - $live_table = substr(kTempTablesHandler::GetLiveName($this->TableName), strlen(TABLE_PREFIX)); + $live_table = substr(GetLiveName($this->TableName), strlen(TABLE_PREFIX)); preg_match('/'.preg_quote(TABLE_PREFIX, '/').'(.*)'.preg_quote($live_table, '/').'/', $this->TableName, $rets); return str_replace('%3$s', $rets[1], $query); } - + /** * Adds calculated field declaration to object. * @@ -395,7 +395,7 @@ { $this->AggregatedCalculatedFields = isset($fields[$this->Special]) ? $fields[$this->Special] : (isset($fields['']) ? $fields[''] : Array()); } - + /** * Set's field names from table * from config @@ -407,7 +407,7 @@ { $this->customFields = $fields; } - + /** * Set's field names from table * from config @@ -481,7 +481,13 @@ function GetFieldOptions($field) { - return isset($this->Fields[$field]) ? $this->Fields[$field] : Array(); + if (isset($this->Fields[$field])) { + $this->PrepareFieldOptions($field); + return $this->Fields[$field]; + } + else { + return Array(); + } } /** @@ -527,22 +533,27 @@ { foreach (array_keys($this->Fields) as $field_name) { - $field_options =& $this->Fields[$field_name]; - if( isset($field_options['options_sql']) ) - { - // replace with query result - $select_clause = $field_options['option_title_field'].','.$field_options['option_key_field']; - $sql = sprintf($field_options['options_sql'], $select_clause, $this->Application->GetVar('m_lang')); +// $this->PrepareFieldOptions($field_name); + $this->PrepareOptions($field_name); + } + } - $options_hash = getArrayValue($field_options,'options'); - if($options_hash === false) $options_hash = Array(); + function PrepareFieldOptions($field_name) + { + $field_options =& $this->Fields[$field_name]; + if( isset($field_options['options_sql']) ) + { + // replace with query result + $select_clause = $field_options['option_title_field'].','.$field_options['option_key_field']; + $sql = sprintf($field_options['options_sql'], $select_clause, $this->Application->GetVar('m_lang')); - $dynamic_options = $this->Conn->GetCol($sql, $field_options['option_key_field']); - $field_options['options'] = array_merge_recursive2($options_hash, $dynamic_options); + $options_hash = getArrayValue($field_options,'options'); + if($options_hash === false) $options_hash = Array(); - unset($field_options['options_sql']); - } - $this->PrepareOptions($field_name); + $dynamic_options = $this->Conn->GetCol($sql, $field_options['option_key_field']); + $field_options['options'] = array_merge_recursive2($options_hash, $dynamic_options); + + unset($field_options['options_sql']); } }