Index: trunk/core/kernel/utility/formatters/multilang_formatter.php =================================================================== diff -u -N -r7635 -r7702 --- trunk/core/kernel/utility/formatters/multilang_formatter.php (.../multilang_formatter.php) (revision 7635) +++ trunk/core/kernel/utility/formatters/multilang_formatter.php (.../multilang_formatter.php) (revision 7702) @@ -59,6 +59,12 @@ if ( getArrayValue($grid, 'Fields', $field_name) ) { array_rename_key($grids[$name]['Fields'], $field_name, $lang_field_name); } + // update sort fields - used for sorting and filtering in SQLs + foreach ($grid['Fields'] as $grid_fld_name => $fld_options) { + if (isset($fld_options['sort_field']) && $fld_options['sort_field'] == $field_name) { + $grids[$name]['Fields'][$grid_fld_name]['sort_field'] = $lang_field_name; + } + } } $this->Application->setUnitOption($object->Prefix, 'Grids', $grids); Index: trunk/system/user_files/icons/pdf.gif =================================================================== diff -u -N Binary files differ Index: trunk/system/user_files/icons/ppt.gif =================================================================== diff -u -N Binary files differ Index: trunk/system/user_files/icons/excel.gif =================================================================== diff -u -N Binary files differ Index: trunk/core/units/groups/groups_config.php =================================================================== diff -u -N -r7635 -r7702 --- trunk/core/units/groups/groups_config.php (.../groups_config.php) (revision 7635) +++ trunk/core/units/groups/groups_config.php (.../groups_config.php) (revision 7702) @@ -26,7 +26,7 @@ 'TitlePresets' => Array( 'default' => Array( 'new_status_labels' => Array('g' => '!la_title_Adding_Group!'), 'edit_status_labels' => Array('g' => '!la_title_Editing_Group!'), - 'new_titlefield' => Array('g' => '!la_title_New_Group!'), + 'new_titlefield' => Array('g' => ''), ), 'groups_list' => Array('prefixes' => Array('g.total_List'), 'format' => "!la_title_Groups! (#g.total_recordcount#)"), @@ -102,7 +102,7 @@ 'Name' => Array('title' => 'la_col_GroupName'), ), ), - + 'Radio' => Array ( 'Icons' => Array(1 => 'icon16_group.gif', 0 => 'icon16_group_disabled.gif'), 'Fields' => Array( @@ -111,7 +111,7 @@ 'Description' => Array('title' => 'la_col_Description'), ), ), - + 'GroupSelector' => Array ( 'Icons' => Array(1 => 'icon16_group.gif', 0 => 'icon16_group_disabled.gif'), 'Fields' => Array( @@ -121,8 +121,8 @@ ), ), ), - + ); ?> \ No newline at end of file Index: trunk/core/units/categories/categories_config.php =================================================================== diff -u -N -r7635 -r7702 --- trunk/core/units/categories/categories_config.php (.../categories_config.php) (revision 7635) +++ trunk/core/units/categories/categories_config.php (.../categories_config.php) (revision 7702) @@ -54,7 +54,7 @@ 'TitlePresets' => Array( 'default' => Array( 'new_status_labels' => Array('c' => '!la_title_Adding_Category!'), 'edit_status_labels' => Array('c' => '!la_title_Editing_Category!'), - 'new_titlefield' => Array('c' => '!la_title_New_Category!'), + 'new_titlefield' => Array('c' => ''), ), 'category_list' => Array('prefixes' => Array('c_List'), 'format' => "!la_title_Categories! (#c_recordcount#)"), @@ -74,7 +74,7 @@ 'images_edit' => Array( 'prefixes' => Array('c', 'c-img'), 'new_status_labels' => Array('c-img'=>'!la_title_Adding_Image!'), 'edit_status_labels' => Array('c-img'=>'!la_title_Editing_Image!'), - 'new_titlefield' => Array('c-img'=>'!la_title_New_Image!'), + 'new_titlefield' => Array('c-img'=>''), 'format' => "#c_status# '#c_titlefield#' - #c-img_status# '#c-img_titlefield#'", ), Index: trunk/core/units/translator/translator_config.php =================================================================== diff -u -N -r4785 -r7702 --- trunk/core/units/translator/translator_config.php (.../translator_config.php) (revision 4785) +++ trunk/core/units/translator/translator_config.php (.../translator_config.php) (revision 7702) @@ -24,7 +24,7 @@ 'default' => Array( 'new_status_labels' => Array('trans'=>'!la_title_Adding_Order!'), 'edit_status_labels' => Array('trans'=>'!la_title_Editing_Order!'), - 'new_titlefield' => Array('trans'=>'!la_title_New_Order!'), + 'new_titlefield' => Array('trans'=>''), ), 'trans_edit' => Array('prefixes' => Array('trans'), 'format' => '!la_title_EditingTranslation!'), Index: trunk/system/user_files/icons/doc.gif =================================================================== diff -u -N Binary files differ Index: trunk/system/user_files/icons/video.gif =================================================================== diff -u -N Binary files differ Index: trunk/core/units/languages/languages_config.php =================================================================== diff -u -N -r7635 -r7702 --- trunk/core/units/languages/languages_config.php (.../languages_config.php) (revision 7635) +++ trunk/core/units/languages/languages_config.php (.../languages_config.php) (revision 7702) @@ -72,7 +72,7 @@ '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!'), + 'new_titlefield' => Array('lang'=>''), ), 'languages_list' => Array( 'prefixes' => Array('lang_List'), 'format' => "!la_title_Configuration! - !la_title_LanguagePacks! (#lang_recordcount#)"), @@ -96,7 +96,7 @@ 'format' => '#emailevents_status# - #emailevents_titlefield#'), 'email_messages_edit' => Array( 'prefixes' => Array('lang','emailmessages'), - 'new_titlefield' => Array('emailmessages' => '!la_NoSubject!'), + 'new_titlefield' => Array('emailmessages' => ''), 'format' => "#lang_status# '#lang_titlefield#' - !la_title_EditingEmailEvent! '#emailmessages_titlefield#'"), ), Index: trunk/core/kernel/db/dblist.php =================================================================== diff -u -N -r7635 -r7702 --- trunk/core/kernel/db/dblist.php (.../dblist.php) (revision 7635) +++ trunk/core/kernel/db/dblist.php (.../dblist.php) (revision 7702) @@ -280,6 +280,22 @@ } } + function GetNoFilterCount() + { + if (!$this->Counted) { + $this->CountRecs(); + } + return $this->NoFilterCount; + } + + function GetRecordsCount() + { + if (!$this->Counted) { + $this->CountRecs(); + } + return $this->RecordsCount; + } + function getCountSQL($sql) { if ( preg_match("/DISTINCT(.*?)FROM(?!_)/is",$sql,$regs ) ) @@ -604,7 +620,7 @@ $name = $field[0]; $ret .= isset($this->Fields[$name]) && !isset($this->VirtualFields[$name]) ? '`'.$this->TableName.'`.' : ''; - + if ($field[0] == 'RAND()' || $field[2]) { $ret .= $field[0].' '.$field[1].','; } Index: trunk/core/admin_templates/regional/phrases_edit.tpl =================================================================== diff -u -N -r7635 -r7702 --- trunk/core/admin_templates/regional/phrases_edit.tpl (.../phrases_edit.tpl) (revision 7635) +++ trunk/core/admin_templates/regional/phrases_edit.tpl (.../phrases_edit.tpl) (revision 7702) @@ -34,7 +34,8 @@ - +
+
"> @@ -56,5 +57,6 @@
+ Index: trunk/core/units/phrases/phrases_config.php =================================================================== diff -u -N -r7391 -r7702 --- trunk/core/units/phrases/phrases_config.php (.../phrases_config.php) (revision 7391) +++ trunk/core/units/phrases/phrases_config.php (.../phrases_config.php) (revision 7702) @@ -53,10 +53,10 @@ 'TitlePresets' => Array( 'default' => Array( 'new_status_labels' => Array('phrases'=>'!la_title_Adding_Phrase!'), 'edit_status_labels' => Array('phrases'=>'!la_title_Editing_Phrase!'), - 'new_titlefield' => Array('phrases'=>'!la_title_New_Phrase!'), + 'new_titlefield' => Array('phrases'=>''), ), - 'phrase_edit' => Array('prefixes' => Array('phrases'), 'format' => '#phrases_status# - #phrases_titlefield#'), + 'phrase_edit' => Array('prefixes' => Array('phrases'), 'format' => '#phrases_status# #phrases_titlefield#'), ), Index: trunk/core/units/email_events/email_events_event_handler.php =================================================================== diff -u -N -r7391 -r7702 --- trunk/core/units/email_events/email_events_event_handler.php (.../email_events_event_handler.php) (revision 7391) +++ trunk/core/units/email_events/email_events_event_handler.php (.../email_events_event_handler.php) (revision 7702) @@ -82,9 +82,9 @@ $items_info = $this->Application->GetVar('u'); if ($items_info) { $user_id = array_shift( array_keys($items_info) ); - + $selected_ids = $this->getSelectedIDs($event, true); - + $ids = $this->Application->RecallVar($event->getPrefixSpecial().'_selected_ids'); $id_field = $this->Application->getUnitOption($event->Prefix, 'IDField'); $table_name = $this->Application->getUnitOption($event->Prefix, 'TableName'); @@ -199,6 +199,7 @@ $direct_send_params['message_text'] = $message_body_additional; $this->Application->Parser->Params = array_merge_recursive2($this->Application->Parser->Params, $direct_send_params); $message_template = str_replace('Application->Parser->Parse($message_template, 'email_template', 0); Index: trunk/core/admin_templates/js/script.js =================================================================== diff -u -N -r7635 -r7702 --- trunk/core/admin_templates/js/script.js (.../script.js) (revision 7635) +++ trunk/core/admin_templates/js/script.js (.../script.js) (revision 7702) @@ -1318,3 +1318,41 @@ } return x1 + x2; } + +var last_shown_error = false; +var errors = new Object(); +var first_error = new Object(); +var fields = new Object(); +var textareas100 = new Array(); +function show_form_error(prefix, field, sticky) +{ + if (isset(errors[prefix]) && isset(errors[prefix][field])) { + span = document.getElementById('error_msg_'+prefix); + span.innerHTML = fields[prefix][field] + ' - ' + errors[prefix][field]; + if (sticky) last_shown_error = field; + } +} +function hide_form_error(prefix) +{ + span = document.getElementById('error_msg_'+prefix); + if (!span) return; + span.innerHTML = '
'; + if (typeof(last_shown_error) != 'undefined' && last_shown_error) { + show_form_error(prefix, last_shown_error); + } +} +function add_form_error(prefix, field, element, error_msg) { + if (error_msg != '') { + if (typeof(errors[prefix]) == 'undefined') { + errors[prefix] = new Object(); + } + errors[prefix][field] = error_msg; + document.getElementById(element).onfocus = function() { + show_form_error(prefix, field, true) + }; + document.getElementById(element).onblur = function() {last_shown_error = false}; + if (typeof(first_error[prefix]) == 'undefined' || first_error[prefix] == false) { + first_error[prefix] = [field, element]; + } + } +} \ No newline at end of file Index: trunk/core/kernel/db/db_tag_processor.php =================================================================== diff -u -N -r7635 -r7702 --- trunk/core/kernel/db/db_tag_processor.php (.../db_tag_processor.php) (revision 7635) +++ trunk/core/kernel/db/db_tag_processor.php (.../db_tag_processor.php) (revision 7702) @@ -708,6 +708,7 @@ $params['field'] = 'any'; } if ($this->HasError($params)) { + $params['prefix'] = $this->getPrefixSpecial(); return $this->Application->ParseBlock($params); } } @@ -1318,8 +1319,11 @@ // b. setting object's titlefield value (in titlebar ONLY) to default in case if object beeing created with no titlefield filled in if( $object_status[ $prefix_data['prefix_special'] ] == 'new' ) { + $title = str_replace('\'#'.$prefix_data['prefix_special'].'_titlefield#\'', '#'.$prefix_data['prefix_special'].'_titlefield#', $title); $new_value = $this->getInfo( $objects[ $prefix_data['prefix_special'] ], 'titlefield' ); - if(!$new_value && getArrayValue($title_info['new_titlefield'],$prefix_data['prefix_special']) ) $new_value = $this->Application->Phrase($title_info['new_titlefield'][ $prefix_data['prefix_special'] ]); + if(!$new_value && getArrayValue($title_info['new_titlefield'],$prefix_data['prefix_special']) ) { + $new_value = $this->Application->Phrase($title_info['new_titlefield'][ $prefix_data['prefix_special'] ]); + } // old format had single quotes in the format $title = str_replace('\'#'.$prefix_data['prefix_special'].'_titlefield#\'', "'$new_value'", $title); // new format has no quotes and $new_value should be empty when creating items @@ -1385,15 +1389,15 @@ switch ($params['type']) { case 'filtered': - return $object->RecordsCount; + return $object->GetRecordsCount(); case 'total': - return $object->NoFilterCount; + return $object->GetNoFilterCount(); case 'from': return $object->RecordsCount ? $object->Offset+1 : 0; //0-based case 'to': return min($object->Offset + $object->PerPage, $object->RecordsCount); case 'total_pages': - return ceil($object->RecordsCount / $object->PerPage); + return $object->GetTotalPages(); case 'needs_pagination': return $object->RecordsCount > $object->PerPage; } Index: trunk/system/user_files/icons/audio.gif =================================================================== diff -u -N Binary files differ Index: trunk/core/units/users/users_event_handler.php =================================================================== diff -u -N -r7635 -r7702 --- trunk/core/units/users/users_event_handler.php (.../users_event_handler.php) (revision 7635) +++ trunk/core/units/users/users_event_handler.php (.../users_event_handler.php) (revision 7702) @@ -497,6 +497,7 @@ $cs_helper->CheckStateField($event, 'State', 'Country'); $object =& $event->getObject( Array('skip_autoload' => true) ); + /* @var $object kDBItem */ if ($this->Application->ConfigValue('User_Password_Auto')) { $pass = makepassword4(rand(5,8)); $object->SetField('Password', $pass); @@ -505,7 +506,6 @@ } parent::OnCreate($event); - $this->Application->SetVar('u.current_id', $object->getID() ); // for affil:OnRegisterAffiliate after hook $this->setNextTemplate($event); @@ -1121,6 +1121,55 @@ } } } + + /** + * Apply some special processing to + * object beeing recalled before using + * it in other events that call prepareObject + * + * @param Object $object + * @param kEvent $event + * @access protected + */ + function prepareObject(&$object, &$event) + { + parent::prepareObject($object, $event); + + if (!$this->Application->IsAdmin()) { + if ($this->Application->RecallVar('register_captcha_code')) return ; + $captcha_helper =& $this->Application->recallObject('CaptchaHelper'); + /* @var $captcha_helper kCaptchaHelper */ + $this->Application->StoreVar('register_captcha_code', $captcha_helper->GenerateCaptchaCode()); + } + } + + /** + * Apply custom processing to item + * + * @param kEvent $event + */ + function customProcessing(&$event, $type) + { + if ($event->Name == 'OnCreate' && $type == 'before') { + $object =& $event->getObject(); + /* @var $object kDBItem */ + + // if auto password has not been set already - store real one - to be used in email events + if (!$this->Application->GetVar('user_password')) { + $this->Application->SetVar('user_password', $object->GetDirtyField('Password')); + $object->SetDBField('Password_plain', $object->GetDirtyField('Password')); + } + + // Validate captcha image if it's requried + if ($this->Application->ConfigValue('RegistrationCaptcha') && $object->GetDBField('Captcha') != $this->Application->RecallVar('register_captcha_code')) { + $object->SetError('Captcha', 'captcha_error', 'lu_captcha_error'); + $captcha_helper =& $this->Application->recallObject('CaptchaHelper'); + /* @var $captcha_helper kCaptchaHelper */ + $this->Application->StoreVar('register_captcha_code', $captcha_helper->GenerateCaptchaCode()); + } + + } + } } ?> \ No newline at end of file Index: trunk/core/admin_templates/incs/footer.tpl =================================================================== diff -u -N -r7635 -r7702 --- trunk/core/admin_templates/incs/footer.tpl (.../footer.tpl) (revision 7635) +++ trunk/core/admin_templates/incs/footer.tpl (.../footer.tpl) (revision 7702) @@ -17,14 +17,44 @@ function MakeHeight100(id) { if (!id) id = 'scroll_container'; + AdjustTextAreas(true); // reseting textareas to minimal size var el = document.getElementById(id); var h = (document.all ? window.document.body.offsetHeight : window.innerHeight) - el.offsetTop + 'px'; var w = (document.all ? window.document.body.offsetWidth : window.innerWidth) - el.offsetLeft + 'px'; // alert('h: '+h) el.style.height = h; // el.style.width=w; + AdjustTextAreas(); // adjusting textarea height } + function AdjustTextAreas(reset) + { + var tmp; + var sizes = new Array(); + if (isset(textareas100)) { + // we need separate cycle to get heights, because if we set the height in the same cycle + // it will recursively affect heights of other textareas + for (var i in textareas100) { + tmp = document.getElementById(textareas100[i]); + sizes[tmp.name] = tmp.parentNode.offsetHeight; + } + for (var i in textareas100) { + tmp = document.getElementById(textareas100[i]); + tmp.style.height = reset ? '70px' : (sizes[tmp.name] - 18) + 'px'; + } + } + } + + if (isset(first_error)) { + for (var i in first_error) { + if (first_error[i] != false) { +// show_form_error(i, first_error[i][0]); + document.getElementById(first_error[i][1]).focus(); +// alert('focused on '+first_error[i][1]) + } + } + } + Index: trunk/system/user_files/icons/xml.gif =================================================================== diff -u -N Binary files differ Index: trunk/core/units/email_messages/email_messages_config.php =================================================================== diff -u -N -r7391 -r7702 --- trunk/core/units/email_messages/email_messages_config.php (.../email_messages_config.php) (revision 7391) +++ trunk/core/units/email_messages/email_messages_config.php (.../email_messages_config.php) (revision 7702) @@ -74,8 +74,8 @@ 'Default' => Array( 'Icons' => Array('default'=>'icon16_custom.gif'), 'Fields' => Array( - 'Description' => Array( 'title'=>'la_col_Description', 'data_block' => 'label_grid_checkbox_td'), 'Subject' => Array( 'title'=>'la_col_Subject'), + 'Description' => Array( 'title'=>'la_col_Description', 'data_block' => 'label_grid_checkbox_td'), 'Type' => Array( 'title'=>'la_col_Type'), ), Index: trunk/system/user_files/icons/image.gif =================================================================== diff -u -N Binary files differ Index: trunk/core/install/install_data.sql =================================================================== diff -u -N -r7635 -r7702 --- trunk/core/install/install_data.sql (.../install_data.sql) (revision 7635) +++ trunk/core/install/install_data.sql (.../install_data.sql) (revision 7702) @@ -46,6 +46,7 @@ INSERT INTO ConfigurationAdmin VALUES ('Min_UserName', 'la_Text_General', 'la_text_min_username', 'text', '', '', 10.03, 0, 0); INSERT INTO ConfigurationAdmin VALUES ('Min_Password', 'la_Text_General', 'la_text_min_password', 'text', '', '', 10.04, 0, 0); INSERT INTO ConfigurationAdmin VALUES ('Email_As_Login', 'la_Text_General', 'la_use_emails_as_login', 'checkbox', NULL, NULL, 10.02, 0, 0); +INSERT INTO ConfigurationAdmin VALUES ('RegistrationCaptcha', 'la_Text_General', 'la_registration_captcha', 'checkbox', NULL, NULL, 10.025, 0, 0); INSERT INTO ConfigurationAdmin VALUES ('User_LoggedInGroup', 'la_Text_General', 'la_users_assign_all_to', 'select', NULL, '0=lu_none,SELECT GroupId as OptionValue, Name as OptionName FROM PortalGroup WHERE Enabled=1 AND Personal=0', 10.09, 0, 1); INSERT INTO ConfigurationAdmin VALUES ('FirstDayOfWeek', 'la_Text_Date_Time_Settings', 'la_config_first_day_of_week', 'select', '', '0=la_sunday,1=la_monday', 20.03, 0, 1); INSERT INTO ConfigurationAdmin VALUES ('SSL_URL', 'la_Text_Website', 'la_config_ssl_url', 'text', '', '', 10.09, 0, 1); @@ -179,6 +180,7 @@ INSERT INTO ConfigurationValues VALUES (NULL, 'Search_MinKeyword_Length', '3', 'In-Portal', ''); INSERT INTO ConfigurationValues VALUES (NULL, 'Users_AllowReset', '180', 'In-Portal:Users', 'in-portal:configure_users'); INSERT INTO ConfigurationValues VALUES (NULL, 'Email_As_Login', '0', 'In-Portal:Users', 'in-portal:configure_users'); +INSERT INTO ConfigurationValues VALUES (NULL, 'RegistrationCaptcha', '0', 'In-Portal:Users', 'in-portal:configure_users'); INSERT INTO ConfigurationValues VALUES (NULL, 'User_LoggedInGroup', '15', 'In-Portal:Users', 'in-portal:configure_users'); INSERT INTO ConfigurationValues VALUES (NULL, 'User_MembershipExpirationReminder', '10', 'In-Portal:Users', 'in-portal:configure_users'); INSERT INTO ConfigurationValues VALUES (NULL, 'FirstDayOfWeek', '1', 'In-Portal', 'in-portal:configure_general'); Index: trunk/core/kernel/utility/debugger/debugger.js =================================================================== diff -u -N -r7635 -r7702 --- trunk/core/kernel/utility/debugger/debugger.js (.../debugger.js) (revision 7635) +++ trunk/core/kernel/utility/debugger/debugger.js (.../debugger.js) (revision 7702) @@ -99,6 +99,7 @@ Debugger.prototype.AddToolbar = function($var_name) { var $span = document.createElement('SPAN'); $span.style.position = 'absolute'; + document.body.style.textAlign = 'left'; var $toolbar_content = 'Reload Frame'; Index: trunk/core/units/general/helpers/search_helper.php =================================================================== diff -u -N -r7391 -r7702 --- trunk/core/units/general/helpers/search_helper.php (.../search_helper.php) (revision 7391) +++ trunk/core/units/general/helpers/search_helper.php (.../search_helper.php) (revision 7702) @@ -1,8 +1,8 @@ $kw) $final[$kw] = $res[1][$index]; $keyword = preg_replace($quotes_re, '', $keyword); $not_quoted_kw = preg_match_all($no_quotes_re, $keyword, $res); foreach ($res[2] as $index => $kw) $final[$kw] = $res[1][$index]; - + return $final; } - + function getPositiveKeywords($keyword) { $keywords = $this->splitKeyword($keyword); - + $ret = Array(); foreach ($keywords as $keyword => $sign) { if ($sign == '+' || $sign == '') { @@ -35,54 +35,54 @@ } return $ret; } - + function buildWhereClause($keyword, $fields) { $keywords = $this->splitKeyword($keyword); - + $normal_conditions = Array(); $plus_conditions = Array(); $minus_conditions = Array(); - + foreach ($keywords as $keyword => $sign) { switch ($sign) { case '+': $plus_conditions[] = implode(' LIKE "%'.$keyword.'%" OR ', $fields).' LIKE "%'.$keyword.'%"'; break; - + case '-': foreach ($fields as $field) { $condition[] = $field.' NOT LIKE "%'.$keyword.'%" OR '.$field.' IS NULL'; } $minus_conditions[] = '('.implode(') AND (', $condition).')'; break; - + case '': $keyword = str_replace('"', '\"', $keyword); $normal_conditions[] = implode(' LIKE "%'.$keyword.'%" OR ', $fields).' LIKE "%'.$keyword.'%"'; break; } } - + // building where clause if ($normal_conditions) { $where_clause = '('.implode(') OR (', $normal_conditions).')'; } else { $where_clause = '1'; } - + if ($plus_conditions) { $where_clause = '('.$where_clause.') AND ('.implode(') AND (', $plus_conditions).')'; } - + if ($minus_conditions) { $where_clause = '('.$where_clause.') AND ('.implode(') AND (', $minus_conditions).')'; } - + return $where_clause; } - + /** * Returns additional information about search field * @@ -104,16 +104,16 @@ } $table_name = ($sql_filter_type == 'where') ? $table_name : ''; - + // replace wid inside table name to WID_MARK constant value $is_temp_table = preg_match('/(.*)'.TABLE_PREFIX.'ses_'.$this->Application->GetSID().'(_[\d]+){0,1}_edit_(.*)/', $table_name, $regs); if ($is_temp_table) { $table_name = $regs[1].TABLE_PREFIX.'ses_'.EDIT_MARK.'_edit_'.$regs[3]; // edit_mark will be replaced with sid[_main_wid] in AddFilters } - + return Array ('field_name' => $field_name, 'field_type' => $field_type, 'table_name' => $table_name, 'sql_filter_type' => $sql_filter_type); } - + /** * Enter description here... * @@ -129,32 +129,32 @@ $search_keyword = str_replace('*', '%', $search_keyword); $custom_filter = $this->processCustomFilters($event); - + if(!$search_keyword && $custom_filter === false) { $this->resetSearch($event); return true; } - + if ($search_keyword) { $this->processAutomaticFilters($event, $search_keyword, $custom_filter); } } - - + + function processAutomaticFilters(&$event, $search_keyword, $custom_filter) { $grid_name = $this->Application->GetVar('grid_name'); $grids = $this->Application->getUnitOption($event->Prefix, 'Grids'); $search_fields = array_keys($grids[$grid_name]['Fields']); - + $search_filter = Array(); $object =& $event->getObject(); - + foreach ($search_fields as $search_field) { $custom_search = isset($custom_filter[$search_field]); - + $filter_data = $this->getSearchClause($object, $search_field, $search_keyword, $custom_search); - + if ($filter_data) { $search_filter[$search_field] = $filter_data; } @@ -164,7 +164,7 @@ } $this->Application->StoreVar($event->getPrefixSpecial().'_search_filter', serialize($search_filter) ); } - + /** * Returns search clause for any particular field * @@ -177,17 +177,17 @@ function getSearchClause(&$object, $field_name, $search_keyword, $custom_search) { $search_keywords = $this->splitKeyword($search_keyword); - + extract( $this->getFieldInformation($object, $field_name) ); // see getFieldInformation for more details - + $filter_value = ''; - + // get field clause by formatter name and/or parameters $formatter = getArrayValue($object->Fields[$field_name], 'formatter'); switch ($formatter) { case 'kOptionsFormatter': $search_keys = Array(); - + if ($custom_search === false) { // if keywords passed through simple search filter (on each grid) $use_phrases = getArrayValue($object->Fields[$field_name], 'use_phrases'); @@ -271,14 +271,14 @@ break; } } - + if ($filter_value) { return Array('type' => $sql_filter_type, 'value' => $filter_value); } - + return false; } - + /** * Processes custom filters from submit * @@ -288,7 +288,7 @@ function processCustomFilters(&$event) { $grid_name = $this->Application->GetVar('grid_name'); - + // update "custom filter" with values from submit: begin $view_name = $this->Application->RecallVar($event->getPrefixSpecial().'_current_view'); $custom_filters = $this->Application->RecallPersistentVar($event->getPrefixSpecial().'_custom_filter.'.$view_name); @@ -312,7 +312,7 @@ if (isset($custom_filter[$field_name])) { // use isset, because non-existing key will cause "php notice"! unset($custom_filter[$field_name][$filter_type]); // remove filter - + if (!$custom_filter[$field_name]) { // if no filters left for field, then delete record at all unset($custom_filter[$field_name]); @@ -325,21 +325,21 @@ } } } - + if ($custom_filter) { $custom_filters[$grid_name] = $custom_filter; } else { unset($custom_filters[$grid_name]); } // update "custom filter" with values from submit: end - + if (!$custom_filter) { // in case when no filters specified, there are nothing to process $this->Application->StorePersistentVar($event->getPrefixSpecial().'_custom_filter.'.$view_name, serialize($custom_filters) ); return false; } - + $object =& $event->getObject(); // don't recall it each time in getCustomFilterSearchClause $grid_info = $this->Application->getUnitOption($event->Prefix.'.'.$grid_name, 'Grids'); foreach ($custom_filter as $field_name => $field_options) { @@ -351,12 +351,12 @@ $custom_filter[$field_name][$filter_type] = $field_options; } } - + $custom_filters[$grid_name] = $custom_filter; $this->Application->StorePersistentVar($event->getPrefixSpecial().'_custom_filter.'.$view_name, serialize($custom_filters) ); return $custom_filter; } - + /** * Return numeric range filter value + checking that it's number * @@ -367,23 +367,22 @@ { return strlen($value) && is_numeric($value) ? $this->Conn->qstr($value) : false; } - + function getCustomFilterSearchClause(&$object, $field_name, $filter_type, $field_options) { - if ($filter_type == 'date_range') { - // use timestamp field, not formatted one + // this is usually used for mutlilingual fields and date fields + if (isset($field_options['grid_options']['sort_field'])) { $field_name = $field_options['grid_options']['sort_field']; } - extract( $this->getFieldInformation($object, $field_name) ); // see getFieldInformation for more details - + $filter_value = ''; - + switch ($filter_type) { case 'range': $from = $this->getRangeValue($field_options['submit_value']['from']); $to = $this->getRangeValue($field_options['submit_value']['to']); - + if ($from !== false && $to !== false) { // add range filter $filter_value = $table_name.'`'.$field_name.'` >= '.$from.' AND '.$table_name.'`'.$field_name.'` <= '.$to; @@ -397,12 +396,12 @@ $filter_value = $table_name.'`'.$field_name.'` = '.$to; } break; - + case 'float_range': // MySQL can't compare values in "float" type columns using "=" operator $from = $this->getRangeValue($field_options['submit_value']['from']); $to = $this->getRangeValue($field_options['submit_value']['to']); - + if ($from !== false && $to !== false) { // add range filter $filter_value = $table_name.'`'.$field_name.'` >= '.$from.' AND '.$table_name.'`'.$field_name.'` <= '.$to; @@ -416,11 +415,11 @@ $filter_value = 'ABS('.$table_name.'`'.$field_name.'` - '.$to.') <= 0.0001'; } break; - + case 'date_range': $from = $this->processRangeField($object, $field_name, $field_options['submit_value'], 'from'); $to = $this->processRangeField($object, $field_name, $field_options['submit_value'], 'to'); - + $day_seconds = 23 * 60 * 60 + 59 * 60 + 59; if ($from !== false && $to === false) { $from = strtotime(date('Y-m-d', $from).' 00:00:00', $from); // reset to morning @@ -430,34 +429,34 @@ $to = strtotime(date('Y-m-d', $to).' 23:59:59', $to); // reset to evening $from = $to - $day_seconds; } - + if ($from !== false && $to !== false) { $filter_value = $table_name.'`'.$field_name.'` >= '.$from.' AND '.$table_name.'`'.$field_name.'` <= '.$to; } break; - + case 'equals': - case 'options': + case 'options': $field_value = strlen($field_options['submit_value']) ? $this->Conn->qstr($field_options['submit_value']) : false; if ($field_value) { $filter_value = $table_name.'`'.$field_name.'` = '.$field_value; } break; - + case 'like': $filter_value = $this->buildWhereClause($field_options['submit_value'], Array($table_name.'`'.$field_name.'`')); - break; - + break; + default: break; } - + $field_options['sql_filter_type'] = $sql_filter_type; $field_options['value'] = $filter_value; - + return $field_options; } - + /** * Enter description here... * @@ -471,11 +470,11 @@ if (!strlen($value[$type])) { return false; } - + $lang_current =& $this->Application->recallObject('lang.current'); $options = $object->GetFieldOptions($search_field); $dt_separator = isset($options['date_time_separator']) ? $options['date_time_separator'] : ' '; - + $tmp_value = explode($dt_separator, $value[$type], 2); if (count($tmp_value) == 1) { // time is missing, then guess it and add to date @@ -495,7 +494,7 @@ } return $value_ts; } - + /** * Resets current search * @@ -509,10 +508,10 @@ $view_name = $this->Application->RecallVar($event->getPrefixSpecial().'_current_view'); $this->Application->RemovePersistentVar($event->getPrefixSpecial().'_custom_filter.'.$view_name); } - - - - + + + + } ?> \ No newline at end of file Index: trunk/core/units/users/users_config.php =================================================================== diff -u -N -r7635 -r7702 --- trunk/core/units/users/users_config.php (.../users_config.php) (revision 7635) +++ trunk/core/units/users/users_config.php (.../users_config.php) (revision 7702) @@ -69,14 +69,14 @@ 'default' => Array( 'new_status_labels' => Array('u'=>'!la_title_Adding_User!'), 'edit_status_labels' => Array('u'=>'!la_title_Editing_User!'), - 'new_titlefield' => Array('u'=>'!la_title_New_User!'), + 'new_titlefield' => Array('u'=>''), ), 'users_list' => Array('prefixes' => Array('u_List'), 'format' => "!la_title_Users! (#u_recordcount#)"), 'users_edit' => Array('prefixes' => Array('u'), 'format' => "#u_status# '#u_titlefield#' - !la_title_General!"), 'users_custom' => Array('prefixes' => Array('u'), 'format' => "#u_status# '#u_titlefield#' - !la_title_Custom!"), - + 'users_select' => Array('prefixes' => Array('u_List'), 'format' => "!la_title_Users! (#u_recordcount#) - !la_title_SelectUser!"), 'user_groups_list' => Array('prefixes' => Array('u', 'u-ug_List'), 'format' => "#u_status# '#u_titlefield#' - !la_title_Groups! (#u-ug_recordcount#)"), @@ -176,6 +176,7 @@ 'ValidateLogin' => Array('type'=>'string','default'=>''), 'SubscribeEmail' => Array('type'=>'string','default'=>''), 'PrimaryGroup' => Array('type' => 'string', 'default' => ''), + 'Captcha' => Array('type' => 'string', 'default' => ''), 'RootPassword' => Array('type' => 'string', 'formatter' => 'kPasswordFormatter', 'encryption_method' => 'md5', 'verify_field' => 'VerifyRootPassword', 'skip_empty' => 1, 'default' => md5('') ), ), Index: trunk/core/units/custom_fields/custom_fields_config.php =================================================================== diff -u -N -r6583 -r7702 --- trunk/core/units/custom_fields/custom_fields_config.php (.../custom_fields_config.php) (revision 6583) +++ trunk/core/units/custom_fields/custom_fields_config.php (.../custom_fields_config.php) (revision 7702) @@ -1,5 +1,5 @@ 'cf', 'ItemClass' => Array('class'=>'kDBItem','file'=>'','build_event'=>'OnItemBuild'), @@ -15,7 +15,7 @@ 4 => 'type', 5 => 'mode', ), - + 'Hooks' => Array( Array( 'Mode' => hAFTER, @@ -28,50 +28,50 @@ 'DoEvent' => 'OnSaveCustomField', ), ), - + 'IDField' => 'CustomFieldId', - + 'TitleField' => 'FieldName', // field, used in bluebar when editing existing item - + 'TitlePhrase' => 'la_title_CustomFields', - + 'TitlePresets' => Array( 'default' => Array( 'new_status_labels' => Array('cf'=>'!la_title_addingCustom!'), 'edit_status_labels' => Array('cf'=>'!la_title_Editing_CustomField!'), - 'new_titlefield' => Array('cf'=>'!la_title_NewCustomField!'), + 'new_titlefield' => Array('cf'=>''), ), - + 'custom_fields_list'=>Array( 'prefixes' => Array('cf_List'), 'format' => "!la_tab_ConfigCustom! (#cf_recordcount#)", ), - + 'custom_fields_edit'=>Array( 'prefixes' => Array('cf'), - 'new_titlefield' => Array('cf'=>'!la_title_NewCustomField!'), + 'new_titlefield' => Array('cf'=>''), 'format' => "#cf_status# '#cf_titlefield#'", ), ), - + 'TableName' => TABLE_PREFIX.'CustomField', - + 'ListSQLs' => Array( ''=>'SELECT * FROM %s', ), // key - special, value - list select sql - - 'ListSortings' => Array( + + 'ListSortings' => Array( '' => Array( 'ForcedSorting' => Array('DisplayOrder' => 'asc'), 'Sorting' => Array('FieldName' => 'asc'), ), - + 'general' => Array( 'Sorting' => Array('DisplayOrder' => 'asc') ), - + ), - + 'ItemSQLs' => Array( ''=>'SELECT * FROM %s', ), 'SubItems' => Array('confs-cf'), - + 'Fields' => Array( 'CustomFieldId' => Array('type' => 'int','not_null' => '1','default' => ''), 'Type' => Array('type' => 'int','not_null' => '1','default' => '0'), @@ -89,9 +89,9 @@ 'Value' => Array('type' => 'string', 'default' => ''), 'OriginalValue' => Array('type' => 'string', 'default' => ''), 'Error' => Array('type' => 'string', 'default' => ''), - + ), - + 'Grids' => Array( 'Default' => Array( 'Icons' => Array('default'=>'icon16_custom.gif'), @@ -102,7 +102,7 @@ 'DisplayOrder' => Array('title' => 'la_prompt_DisplayOrder'), ), ), - + 'SeparateTab' => Array( 'Icons' => Array('default'=>'icon16_custom.gif'), 'Fields' => Array( @@ -112,7 +112,7 @@ 'Error' => Array( 'title'=>'la_col_Error', 'data_block' => 'custom_error_td'), ), ), - + 'SeparateTabOriginal' => Array( 'Icons' => Array('default'=>'icon16_custom.gif'), 'Fields' => Array( @@ -122,12 +122,12 @@ 'OriginalValue' => Array( 'title'=>'la_col_OriginalValue', 'data_block' => 'grid_original_td'), ), ), - + ), ); if (constOn('DEBUG_MODE')) { $config['Grids']['Default']['Fields']['IsSystem'] = Array('title' => 'la_col_IsSystem'); } - + ?> \ No newline at end of file Index: trunk/core/install.php =================================================================== diff -u -N -r6707 -r7702 --- trunk/core/install.php (.../install.php) (revision 6707) +++ trunk/core/install.php (.../install.php) (revision 7702) @@ -3,9 +3,22 @@ error_reporting(E_ALL); define('IS_INSTALL', 1); + define('ADMIN', 1); define('FULL_PATH', realpath(dirname(__FILE__).'/..') ); define('REL_PATH', '/core'); + /** + * Upgrade sqls are located using this mask + * + */ + define('UPGRADES_FILE', FULL_PATH.'/%sinstall/upgrades.sql'); + + /** + * Format of version identificator in upgrade files + * + */ + define('VERSION_MARK', '# ===== v ([\d]+\.[\d]+\.[\d]+) ====='); + // print_pre($_POST); $install_engine = new kInstallator(); @@ -72,26 +85,32 @@ 'fresh_install' => Array ('check_paths', 'db_config', 'root_password', 'choose_modules', 'finish'), 'already_installed' => Array ('install_setup'), - 'upgrade' => Array ('install_setup',/* ..., */ 'finish'), + 'upgrade' => Array ('install_setup', 'upgrade_modules', /* ..., */ 'finish'), 'db_reconfig' => Array ('install_setup',/* ..., */ 'finish'), 'fix_paths' => Array ('install_setup',/* ..., */ 'finish'), ); /** + * Steps, that doesn't required admin to be logged-in to proceed + * + * @var Array + */ + var $skipLoginSteps = Array ('root_password', 'choose_modules', 'finish', -1); + + /** * Steps, on which kApplication should not be initialized, because of missing correct db table structure * * @var Array */ + var $skipApplicationSteps = Array ('check_paths', 'db_config'/*, 'install_setup'*/); // remove install_setup when application will work separately from install - var $skipApplicationSteps = Array ('check_paths', 'db_config', 'install_setup'); // remove install_setup when application will work separately from install - /** * Folders that should be writeable to continue installation * * @var Array */ - var $writeableFolders = Array ('/', '/system'); + var $writeableFolders = Array ('/system'); /** * Contains last error message text @@ -121,46 +140,59 @@ // if config.php found, then check his write permission too $this->writeableFolders[] = '/config.php'; } + else { + $this->writeableFolders[] = '/'; + } $this->systemConfig = $this->ParseConfig(true); $this->systemConfig['Misc']['WriteablePath'] = '/system'; // for development purposes $this->currentStep = $this->GetVar('step'); + // can't check login on steps where no application present anyways :) + $this->skipLoginSteps = array_unique(array_merge($this->skipLoginSteps, $this->skipApplicationSteps)); + $this->SelectPreset(); if (!$this->currentStep) { - // first step of current preset - reset($this->steps[$this->stepsPreset]); - $this->currentStep = current($this->steps[$this->stepsPreset]); + $this->SetFirstStep(); // sets first step of current preset } $this->InitStep(); } + function SetFirstStep() + { + reset($this->steps[$this->stepsPreset]); + $this->currentStep = current($this->steps[$this->stepsPreset]); + } + /** * Selects preset to proceed based on various criteria * */ function SelectPreset() { $preset = $this->GetVar('preset'); - - if ($preset === false) { - $preset = 'fresh_install'; // default preset - - if (file_exists($this->INIFile)) { - // only at installation first step - $status = $this->CheckDatabase(false); - if ($status && $this->AlreadyInstalled()) { + if (file_exists($this->INIFile) && $this->systemConfig) { + // only at installation first step + $status = $this->CheckDatabase(false); + if ($status && $this->AlreadyInstalled()) { + // if already installed, then all future actions need login to work + $this->skipLoginSteps = Array (-1); + if (!$preset) { $preset = 'already_installed'; + $this->currentStep = ''; } } } + if ($preset === false) { + $preset = 'fresh_install'; // default preset + } $this->stepsPreset = $preset; } - + function GetVar($name) { return isset($_REQUEST[$name]) ? $_REQUEST[$name] : false; @@ -172,8 +204,17 @@ */ function InitStep() { - $this->InitApplication(); + $require_login = !in_array($this->currentStep, $this->skipLoginSteps); + $this->InitApplication($require_login); + if ($require_login) { + // step require login to proceed + if (!$this->Application->LoggedIn()) { + $this->stepsPreset = 'already_installed'; + $this->SetFirstStep(); + } + } + switch ($this->currentStep) { case 'check_paths': foreach ($this->writeableFolders as $folder_path) { @@ -214,30 +255,43 @@ } break; - case 'install_setup': - if ($this->stepsPreset == 'already_installed') { - // if preset was not choosen, then raise error - $this->errorMessage = 'Please select action to perform'; + case 'upgrade_modules': + // get installed modules from db and compare their versions to upgrade script + $modules = $this->GetUpgradableModules(); + if (!$modules) { + $this->currentStep = $this->GetNextStep(); } - else { - // if preset was choosen, then check root password entered - $user_name = $this->GetVar('user_name'); - $user_password = $this->GetVar('user_password'); - - if ($user_name == 'root') { - $sql = 'SELECT VariableValue - FROM '.$this->systemConfig['Database']['TablePrefix'].' - WHERE VariableName = "RootPass"'; - $root_password = $this->Conn->GetOne($sql); - $user_password = md5( md5($user_password) . 'b38'); - if ($user_password != $root_password) { - $this->errorMessage = 'Invalid User Name or Password. If you don\'t know your username or password, contact Intechnic Support'; + break; + + case 'install_setup': + $next_preset = $this->Application->GetVar('next_preset'); + if ($next_preset !== false && $this->Application->GetVar('login') == 'root') { + // option was choosen, then verify password & login user + $login_event = new kEvent('u.current:OnLogin'); + $this->Application->HandleEvent($login_event); + + if ($login_event->status == erSUCCESS) { + // login succeeded + + if (!isset($this->steps[$next_preset])) { + $this->errorMessage = 'Preset "'.$next_preset.'" not yet implemented'; } + else { + $this->stepsPreset = $next_preset; + } } else { - $this->errorMessage = 'By now only login using "root" username is supported'; + // login failed + $user =& $this->Application->recallObject('u.current'); + /* @var $user UsersItem */ + + $this->errorMessage = $user->GetErrorMsg('ValidateLogin').'. If you don\'t know your username or password, contact Intechnic Support'; } } + else { + // if preset was not choosen, then raise error + $this->errorMessage = 'Please select action to perform'; + } break; } @@ -314,29 +368,100 @@ // import base data into database $this->RunSQL('/core/install/install_schema.sql'); $this->RunSQL('/core/install/install_data.sql'); + + // set module "Core" version after install (based on upgrade scripts) + $this->SetModuleVersion('Core'); break; case 'root_password': // update root password in database $password = md5( md5($this->Application->GetVar('root_password')) . 'b38'); - $sql = 'UPDATE '.TABLE_PREFIX.'ConfigurationValues - SET VariableValue = '.$this->Conn->qstr($password).' - WHERE VariableName = "RootPass"'; - $this->Conn->Query($sql); + $this->SetConfigValue('RootPass', $password); + // set Site_Path (for SSL & old in-portal code) + $this->SetConfigValue('Site_Path', BASE_PATH.'/'); + // import base language for core (english) $this->ImportLanguage('/core/install/english'); + + // set imported language as primary + $lang =& $this->Application->recallObject('lang.-item', null, Array('skip_autoload' => true)); + /* @var $lang LanguagesItem */ + + $lang->Load(1); // fresh install => ID=1 + $lang->setPrimary(); break; case 'choose_modules': + // run module install scripts $modules = $this->Application->GetVar('modules'); - foreach ($modules as $module) { - $install_file = MODULES_PATH.'/'.$module.'/install.php'; - if (file_exists($install_file)) { - include_once($install_file); + if ($modules) { + foreach ($modules as $module) { + $install_file = MODULES_PATH.'/'.$module.'/install.php'; + if (file_exists($install_file)) { + include_once($install_file); + + // set module version after install (based on upgrade scripts) + $this->SetModuleVersion($module); + } } } + // scan themes + $themes_helper =& $this->Application->recallObject('ThemesHelper'); + /* @var $themes_helper kThemesHelper */ + + $themes_helper->refreshThemes(); + + $this->Conn->Query('UPDATE '.TABLE_PREFIX.'Theme SET Enabled=1, PrimaryTheme =1 LIMIT 1'); + + // update categories cache + $updater =& $this->Application->recallObject('kPermCacheUpdater'); + /* @var $updater kPermCacheUpdater */ + + $updater->OneStepRun(); break; + + case 'upgrade_modules': + // get installed modules from db and compare their versions to upgrade script + $modules = $this->Application->GetVar('modules'); + if ($modules) { + $upgrade_data = $this->GetUpgradableModules(); + + foreach ($modules as $module_name) { + $module_info = $upgrade_data[$module_name]; + $upgrades_file = sprintf(UPGRADES_FILE, $module_info['Path']); + + $sqls = file_get_contents($upgrades_file); + $version_mark = preg_replace('/(\(.*?\))/', $module_info['FromVersion'], VERSION_MARK); + + $start_pos = strpos($sqls, $version_mark); + $sqls = substr($sqls, $start_pos); + $this->RunSQLText($sqls); + + // after upgrade sqls are executed update version + $this->SetModuleVersion($module_name, $module_info['ToVersion']); + } + } + else { + $this->errorMessage = 'Please select module(-s) to upgrade'; + } + break; + + case 'finish': + // delete cache + $sql = 'DELETE FROM '.TABLE_PREFIX.'Cache + WHERE VarName IN ("config_files","configs_parsed","sections_parsed")'; + $this->Conn->Query($sql); + + // set installation finished mark + if ($this->Application->ConfigValue('InstallFinished') === false) { + $fields_hash = Array ( + 'VariableName' => 'InstallFinished', + 'VariableValue' => 1, + ); + $this->Conn->doInsert($fields_hash, TABLE_PREFIX.'ConfigurationValues'); + } + break; } if ($this->errorMessage) { @@ -351,15 +476,55 @@ if ($this->currentStep == -1) { // step after last step -> redirect to admin - $this->Application->Redirect('index', null, '', 'admin/index.php'); + $this->Application->Redirect('index', null, '', 'index.php'); } } - function InitApplication() + /** + * Sets module version to passed + * + * @param string $module_name + * @param string $version + */ + function SetModuleVersion($module_name, $version = false) { - if (!in_array($this->currentStep, $this->skipApplicationSteps) && !isset($this->Application)) { + if ($version === false) { + $version = $this->GetMaxModuleVersion($module_name); + } + + $table_prefix = $this->systemConfig['Database']['TablePrefix']; + + $sql = 'UPDATE '.$table_prefix.'Modules + SET Version = "'.$version.'" + WHERE Name = "'.$module_name.'"'; + $this->Conn->Query($sql); + } + + + /** + * Sets new configuration variable value + * + * @param string $name + * @param mixed $value + */ + function SetConfigValue($name, $value) + { + $sql = 'UPDATE '.TABLE_PREFIX.'ConfigurationValues + SET VariableValue = '.$this->Conn->qstr($value).' + WHERE VariableName = '.$this->Conn->qstr($name); + $this->Conn->Query($sql); + } + + /** + * Initialize kApplication + * + * @param bool $force initialize in any case + */ + function InitApplication($force = false) + { + if (($force || !in_array($this->currentStep, $this->skipApplicationSteps)) && !isset($this->Application)) { // step is allowed for application usage & it was not initialized in previous step - global $debugger; + global $start, $debugger, $dbg_options; include_once(FULL_PATH.'/core/kernel/startup.php'); $this->Application =& kApplication::Instance(); @@ -383,21 +548,42 @@ if (isset($this->Application)) { $this->Application->Done(); - echo 'SID: ['.$this->Application->GetSID().']
'; +// echo 'SID: ['.$this->Application->GetSID().']
'; } exit; } - function GetModuleVersion($module_name) + function GetMaxModuleVersion($module_name) { - return '0.1.1'; + $upgrades_file = sprintf(UPGRADES_FILE, strtolower($module_name).'/'); + if (!file_exists($upgrades_file)) { + // no upgrade file + return '4.0.1'; + } + + $sqls = file_get_contents($upgrades_file); + $versions_found = preg_match_all('/'.VERSION_MARK.'/s', $sqls, $regs); + if (!$versions_found) { + // upgrades file doesn't contain version definitions + return '4.0.1'; + } + + return end($regs[1]); } function ConnectToDatabase() { include_once FULL_PATH.'/core/kernel/db/db_connection.php'; + if (!isset($this->systemConfig['Database']['DBType']) || + !isset($this->systemConfig['Database']['DBUser']) || + !isset($this->systemConfig['Database']['DBName']) + ) { + return false; + } + + $this->Conn = new kDBConnection($this->systemConfig['Database']['DBType'], Array(&$this, 'DBErrorHandler')); $this->Conn->Connect($this->systemConfig['Database']['DBHost'], $this->systemConfig['Database']['DBUser'], $this->systemConfig['Database']['DBUserPassword'], $this->systemConfig['Database']['DBName']); return $this->Conn->errorCode == 0; @@ -410,7 +596,8 @@ */ function AlreadyInstalled() { - return $this->TableExists('ConfigurationAdmin'); //,Category,Permissions'); + $table_prefix = $this->systemConfig['Database']['TablePrefix']; + return $this->TableExists('ConfigurationValues') && $this->Conn->GetOne('SELECT VariableValue FROM '.$table_prefix.'ConfigurationValues WHERE VariableName = \'InstallFinished\''); } function CheckDatabase($check_installed = true) @@ -463,6 +650,7 @@ } else { // was error while connecting + if (!$this->Conn) return false; $this->errorMessage = 'Connection Error: ('.$this->Conn->getErrorCode().') '.$this->Conn->getErrorMsg(); return false; } @@ -493,14 +681,32 @@ return $all_found; } + /** + * Runs SQLs from file + * + * @param string $filename + * @param mixed $replace_from + * @param mixed $replace_to + */ function RunSQL($filename, $replace_from = null, $replace_to = null) { if (!file_exists(FULL_PATH.$filename)) { return ; } $sqls = file_get_contents(FULL_PATH.$filename); + $this->RunSQLText($sqls, $replace_from, $replace_to); + } + /** + * Runs SQLs from string + * + * @param string $sqls + * @param mixed $replace_from + * @param mixed $replace_to + */ + function RunSQLText(&$sqls, $replace_from = null, $replace_to = null) + { $table_prefix = $this->systemConfig['Database']['TablePrefix']; // add prefix to all tables @@ -516,13 +722,15 @@ // replace something additionally, e.g. module root category $sqls = str_replace($replace_from, $replace_to, $sqls); } - + + $sqls = str_replace("\r\n", "\n", $sqls); // convert to linux line endings + $sqls = preg_replace("/#(.*?)\n/", '', $sqls); // remove all comments $sqls = explode(";\n", $sqls); foreach ($sqls as $sql) { $sql = trim($sql); - if (!$sql || substr($sql, 0, 1) == '#') { - continue; // usually last line || comment + if (!$sql) { + continue; // usually last line } $this->Conn->Query($sql); if ($this->Conn->getErrorCode() != 0) { @@ -532,7 +740,7 @@ } } } - + function ImportLanguage($lang_file) { $lang_file = FULL_PATH.$lang_file.'.lang'; @@ -575,6 +783,69 @@ } /** + * Converts module version in format X.Y.Z to signle integer + * + * @param string $version + * @return int + */ + function ConvertModuleVersion($version) + { + $parts = explode('.', $version); + + $bin = ''; + foreach ($parts as $part) { + $bin .= str_pad(decbin($part), 8, '0', STR_PAD_LEFT); + } + + return bindec($bin); + } + + /** + * Returns list of modules, that can be upgraded + * + */ + function GetUpgradableModules() + { + $ret = Array (); + + foreach ($this->Application->ModuleInfo as $module_name => $module_info) { + $upgrades_file = sprintf(UPGRADES_FILE, $module_info['Path']); + if (!file_exists($upgrades_file)) { + // no upgrade file + continue; + } + + $sqls = file_get_contents($upgrades_file); + $versions_found = preg_match_all('/'.VERSION_MARK.'/s', $sqls, $regs); + if (!$versions_found) { + // upgrades file doesn't contain version definitions + continue; + } + + $to_version = end($regs[1]); + $this_version = $this->ConvertModuleVersion($module_info['Version']); + if ($this->ConvertModuleVersion($to_version) > $this_version) { + // destination version is greather then current + foreach ($regs[1] as $version) { + if ($this->ConvertModuleVersion($version) > $this_version) { + $from_version = $version; + break; + } + } + + $version_info = Array ( + 'FromVersion' => $from_version, + 'ToVersion' => $to_version, + ); + + $ret[$module_name] = array_merge_recursive2($module_info, $version_info); + } + } + + return $ret; + } + + /** * Returns content to show for current step * * @return string Index: trunk/core/kernel/processors/main_processor.php =================================================================== diff -u -N -r7391 -r7702 --- trunk/core/kernel/processors/main_processor.php (.../main_processor.php) (revision 7391) +++ trunk/core/kernel/processors/main_processor.php (.../main_processor.php) (revision 7702) @@ -951,6 +951,7 @@ function CaptchaImage($params){ $captcha_helper =& $this->Application->recallObject('CaptchaHelper'); + /* @var $captcha_helper kCaptchaHelper */ $captcha_helper->GenerateCaptchaImage( $this->Application->RecallVar($this->Application->GetVar('var')), $this->Application->GetVar('w'),