diff options
Diffstat (limited to 'phpBB/includes')
53 files changed, 1089 insertions, 468 deletions
| diff --git a/phpBB/includes/acp/acp_attachments.php b/phpBB/includes/acp/acp_attachments.php index abe304c282..eccc935a6e 100644 --- a/phpBB/includes/acp/acp_attachments.php +++ b/phpBB/includes/acp/acp_attachments.php @@ -98,7 +98,7 @@ class acp_attachments  				}  				$db->sql_freeresult($result); -				$l_legend_cat_images = $user->lang['SETTINGS_CAT_IMAGES'] . ' [' . $user->lang['ASSIGNED_GROUP'] . ': ' . ((!empty($s_assigned_groups[ATTACHMENT_CATEGORY_IMAGE])) ? implode(', ', $s_assigned_groups[ATTACHMENT_CATEGORY_IMAGE]) : $user->lang['NO_EXT_GROUP']) . ']'; +				$l_legend_cat_images = $user->lang['SETTINGS_CAT_IMAGES'] . ' [' . $user->lang['ASSIGNED_GROUP'] . ': ' . ((!empty($s_assigned_groups[ATTACHMENT_CATEGORY_IMAGE])) ? implode($user->lang['COMMA_SEPARATOR'], $s_assigned_groups[ATTACHMENT_CATEGORY_IMAGE]) : $user->lang['NO_EXT_GROUP']) . ']';  				$display_vars = array(  					'title'	=> 'ACP_ATTACHMENT_SETTINGS', @@ -917,7 +917,7 @@ class acp_attachments  						$db->sql_query($sql);  						add_log('admin', 'LOG_ATTACH_ORPHAN_DEL', implode(', ', $delete_files)); -						$notify[] = sprintf($user->lang['LOG_ATTACH_ORPHAN_DEL'], implode(', ', $delete_files)); +						$notify[] = sprintf($user->lang['LOG_ATTACH_ORPHAN_DEL'], implode($user->lang['COMMA_SEPARATOR'], $delete_files));  					}  					$upload_list = array(); @@ -1074,7 +1074,7 @@ class acp_attachments  								$error[] = $user->lang['FILES_GONE'];  							}  							add_log('admin', 'LOG_ATTACHMENTS_DELETED', implode(', ', $deleted_filenames)); -							$notify[] = sprintf($user->lang['LOG_ATTACHMENTS_DELETED'], implode(', ', $deleted_filenames)); +							$notify[] = sprintf($user->lang['LOG_ATTACHMENTS_DELETED'], implode($user->lang['COMMA_SEPARATOR'], $deleted_filenames));  						}  						else  						{ @@ -1222,12 +1222,14 @@ class acp_attachments  				}  				$db->sql_freeresult($result); +				$base_url = $this->u_action . "&$u_sort_param"; +				phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $num_files, $attachments_per_page, $start); +				  				$template->assign_vars(array(  					'TOTAL_FILES'		=> $num_files,  					'TOTAL_SIZE'		=> get_formatted_filesize($total_size), -					'PAGINATION'		=> generate_pagination($this->u_action . "&$u_sort_param", $num_files, $attachments_per_page, $start, true), -					'S_ON_PAGE'			=> on_page($num_files, $attachments_per_page, $start), +					'S_ON_PAGE'			=> phpbb_on_page($template, $user, $base_url, $num_files, $attachments_per_page, $start),  					'S_LIMIT_DAYS'		=> $s_limit_days,  					'S_SORT_KEY'		=> $s_sort_key,  					'S_SORT_DIR'		=> $s_sort_dir) diff --git a/phpBB/includes/acp/acp_board.php b/phpBB/includes/acp/acp_board.php index d537885ef1..575d05933f 100644 --- a/phpBB/includes/acp/acp_board.php +++ b/phpBB/includes/acp/acp_board.php @@ -57,8 +57,7 @@ class acp_board  						'board_disable_msg'		=> false,  						'default_lang'			=> array('lang' => 'DEFAULT_LANGUAGE',		'validate' => 'lang',	'type' => 'select', 'function' => 'language_select', 'params' => array('{CONFIG_VALUE}'), 'explain' => false),  						'default_dateformat'	=> array('lang' => 'DEFAULT_DATE_FORMAT',	'validate' => 'string',	'type' => 'custom', 'method' => 'dateformat_select', 'explain' => true), -						'board_timezone'		=> array('lang' => 'SYSTEM_TIMEZONE',		'validate' => 'string',	'type' => 'select', 'function' => 'tz_select', 'params' => array('{CONFIG_VALUE}', 1), 'explain' => true), -						'board_dst'				=> array('lang' => 'SYSTEM_DST',			'validate' => 'bool',	'type' => 'radio:yes_no', 'explain' => false), +						'board_timezone'		=> array('lang' => 'SYSTEM_TIMEZONE',		'validate' => 'timezone',	'type' => 'custom', 'method' => 'timezone_select', 'explain' => true),  						'default_style'			=> array('lang' => 'DEFAULT_STYLE',			'validate' => 'int',	'type' => 'select', 'function' => 'style_select', 'params' => array('{CONFIG_VALUE}', false), 'explain' => false),  						'override_user_style'	=> array('lang' => 'OVERRIDE_STYLE',		'validate' => 'bool',	'type' => 'radio:yes_no', 'explain' => true), @@ -897,6 +896,18 @@ class acp_board  			'<br /><br /><input class="button2" type="submit" id="' . $key . '_enable" name="' . $key . '_enable" value="' . $user->lang['ALLOW_QUICK_REPLY_BUTTON'] . '" />';  	} +	/** +	* Select guest timezone +	*/ +	function timezone_select($value, $key) +	{ +		global $user; + +		$timezone_select = phpbb_timezone_select($user, $value, true); +		$timezone_select['tz_select']; + +		return '<select name="config[' . $key . ']" id="' . $key . '">' . $timezone_select['tz_select'] . '</select>'; +	}  	/**  	* Select default dateformat @@ -907,10 +918,14 @@ class acp_board  		// Let the format_date function operate with the acp values  		$old_tz = $user->timezone; -		$old_dst = $user->dst; - -		$user->timezone = $config['board_timezone'] * 3600; -		$user->dst = $config['board_dst'] * 3600; +		try +		{ +			$user->timezone = new DateTimeZone($config['board_timezone']); +		} +		catch (Exception $e) +		{ +			// If the board timezone is invalid, we just use the users timezone. +		}  		$dateformat_options = ''; @@ -930,7 +945,6 @@ class acp_board  		// Reset users date options  		$user->timezone = $old_tz; -		$user->dst = $old_dst;  		return "<select name=\"dateoptions\" id=\"dateoptions\" onchange=\"if (this.value == 'custom') { document.getElementById('" . addslashes($key) . "').value = '" . addslashes($value) . "'; } else { document.getElementById('" . addslashes($key) . "').value = this.value; }\">$dateformat_options</select>  		<input type=\"text\" name=\"config[$key]\" id=\"$key\" value=\"$value\" maxlength=\"30\" />"; diff --git a/phpBB/includes/acp/acp_groups.php b/phpBB/includes/acp/acp_groups.php index 607254adb5..f88fa76df1 100644 --- a/phpBB/includes/acp/acp_groups.php +++ b/phpBB/includes/acp/acp_groups.php @@ -682,13 +682,15 @@ class acp_groups  					$s_action_options .= '<option value="' . $option . '">' . $user->lang['GROUP_' . $lang] . '</option>';  				} +				$base_url = $this->u_action . "&action=$action&g=$group_id"; +				phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $total_members, $config['topics_per_page'], $start);				 +				  				$template->assign_vars(array(  					'S_LIST'			=> true,  					'S_GROUP_SPECIAL'	=> ($group_row['group_type'] == GROUP_SPECIAL) ? true : false,  					'S_ACTION_OPTIONS'	=> $s_action_options, -					'S_ON_PAGE'		=> on_page($total_members, $config['topics_per_page'], $start), -					'PAGINATION'	=> generate_pagination($this->u_action . "&action=$action&g=$group_id", $total_members, $config['topics_per_page'], $start, true), +					'S_ON_PAGE'		=> phpbb_on_page($template, $user, $base_url, $total_members, $config['topics_per_page'], $start),  					'GROUP_NAME'	=> ($group_row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $group_row['group_name']] : $group_row['group_name'],  					'U_ACTION'			=> $this->u_action . "&g=$group_id", diff --git a/phpBB/includes/acp/acp_icons.php b/phpBB/includes/acp/acp_icons.php index bfe17c5007..b7be92d477 100644 --- a/phpBB/includes/acp/acp_icons.php +++ b/phpBB/includes/acp/acp_icons.php @@ -927,10 +927,8 @@ class acp_icons  			}  		}  		$db->sql_freeresult($result); - -		$template->assign_var('PAGINATION', -			generate_pagination($this->u_action, $item_count, $config['smilies_per_page'], $pagination_start, true) -		); +		 +		phpbb_generate_template_pagination($template, $this->u_action, 'pagination', 'start', $item_count, $config['smilies_per_page'], $pagination_start);		  	}  	/** diff --git a/phpBB/includes/acp/acp_inactive.php b/phpBB/includes/acp/acp_inactive.php index 78d6a0b2f3..1e23c2e6cf 100644 --- a/phpBB/includes/acp/acp_inactive.php +++ b/phpBB/includes/acp/acp_inactive.php @@ -136,6 +136,8 @@ class acp_inactive  								add_log('admin', 'LOG_USER_ACTIVE', $row['username']);  								add_log('user', $row['user_id'], 'LOG_USER_ACTIVE_USER');  							} + +							trigger_error(sprintf($user->lang['LOG_INACTIVE_ACTIVATE'], implode($user->lang['COMMA_SEPARATOR'], $user_affected) . ' ' . adm_back_link($this->u_action)));  						}  						// For activate we really need to redirect, else a refresh can result in users being deactivated again @@ -159,6 +161,8 @@ class acp_inactive  							}  							add_log('admin', 'LOG_INACTIVE_' . strtoupper($action), implode(', ', $user_affected)); + +							trigger_error(sprintf($user->lang['LOG_INACTIVE_DELETE'], implode($user->lang['COMMA_SEPARATOR'], $user_affected) . ' ' . adm_back_link($this->u_action)));  						}  						else  						{ @@ -230,7 +234,8 @@ class acp_inactive  						$db->sql_query($sql);  						add_log('admin', 'LOG_INACTIVE_REMIND', implode(', ', $usernames)); -						unset($usernames); + +						trigger_error(sprintf($user->lang['LOG_INACTIVE_REMIND'], implode($user->lang['COMMA_SEPARATOR'], $usernames) . ' ' . adm_back_link($this->u_action)));  					}  					$db->sql_freeresult($result); @@ -283,6 +288,9 @@ class acp_inactive  			$option_ary += array('remind' => 'REMIND');  		} +		$base_url = $this->u_action . "&$u_sort_param&users_per_page=$per_page"; +		phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $inactive_count, $per_page, $start);		 +		  		$template->assign_vars(array(  			'S_INACTIVE_USERS'		=> true,  			'S_INACTIVE_OPTIONS'	=> build_select($option_ary), @@ -290,8 +298,8 @@ class acp_inactive  			'S_LIMIT_DAYS'	=> $s_limit_days,  			'S_SORT_KEY'	=> $s_sort_key,  			'S_SORT_DIR'	=> $s_sort_dir, -			'S_ON_PAGE'		=> on_page($inactive_count, $per_page, $start), -			'PAGINATION'	=> generate_pagination($this->u_action . "&$u_sort_param&users_per_page=$per_page", $inactive_count, $per_page, $start, true), +			'S_ON_PAGE'		=> phpbb_on_page($template, $user, $base_url, $inactive_count, $per_page, $start), +			  			'USERS_PER_PAGE'	=> $per_page,  			'U_ACTION'		=> $this->u_action . "&$u_sort_param&users_per_page=$per_page&start=$start", diff --git a/phpBB/includes/acp/acp_logs.php b/phpBB/includes/acp/acp_logs.php index 6b67175220..4538633d6c 100644 --- a/phpBB/includes/acp/acp_logs.php +++ b/phpBB/includes/acp/acp_logs.php @@ -129,13 +129,15 @@ class acp_logs  		$log_count = 0;  		$start = view_log($mode, $log_data, $log_count, $config['topics_per_page'], $start, $forum_id, 0, 0, $sql_where, $sql_sort, $keywords); +		$base_url = $this->u_action . "&$u_sort_param$keywords_param"; +		phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $log_count, $config['topics_per_page'], $start); +		  		$template->assign_vars(array(  			'L_TITLE'		=> $l_title,  			'L_EXPLAIN'		=> $l_title_explain,  			'U_ACTION'		=> $this->u_action . "&$u_sort_param$keywords_param&start=$start", -			'S_ON_PAGE'		=> on_page($log_count, $config['topics_per_page'], $start), -			'PAGINATION'	=> generate_pagination($this->u_action . "&$u_sort_param$keywords_param", $log_count, $config['topics_per_page'], $start, true), +			'S_ON_PAGE'		=> phpbb_on_page($template, $user, $base_url, $log_count, $config['topics_per_page'], $start),  			'S_LIMIT_DAYS'	=> $s_limit_days,  			'S_SORT_KEY'	=> $s_sort_key, diff --git a/phpBB/includes/acp/acp_permissions.php b/phpBB/includes/acp/acp_permissions.php index d728744c04..dd071074de 100644 --- a/phpBB/includes/acp/acp_permissions.php +++ b/phpBB/includes/acp/acp_permissions.php @@ -497,7 +497,7 @@ class acp_permissions  				$template->assign_vars(array(  					'S_FORUM_NAMES'		=> (sizeof($forum_names)) ? true : false, -					'FORUM_NAMES'		=> implode(', ', $forum_names)) +					'FORUM_NAMES'		=> implode($user->lang['COMMA_SEPARATOR'], $forum_names))  				);  			} diff --git a/phpBB/includes/acp/acp_profile.php b/phpBB/includes/acp/acp_profile.php index 3ffffd3047..849160f1fa 100644 --- a/phpBB/includes/acp/acp_profile.php +++ b/phpBB/includes/acp/acp_profile.php @@ -383,6 +383,7 @@ class acp_profile  					$field_row = array_merge($default_values[$field_type], array(  						'field_ident'		=> str_replace(' ', '_', utf8_clean_string(request_var('field_ident', '', true))),  						'field_required'	=> 0, +						'field_show_novalue'=> 0,  						'field_hide'		=> 0,  						'field_show_profile'=> 0,  						'field_no_view'		=> 0, @@ -399,7 +400,7 @@ class acp_profile  				// $exclude contains the data we gather in each step  				$exclude = array( -					1	=> array('field_ident', 'lang_name', 'lang_explain', 'field_option_none', 'field_show_on_reg', 'field_show_on_pm', 'field_show_on_vt', 'field_required', 'field_hide', 'field_show_profile', 'field_no_view'), +					1	=> array('field_ident', 'lang_name', 'lang_explain', 'field_option_none', 'field_show_on_reg', 'field_show_on_pm', 'field_show_on_vt', 'field_required', 'field_show_novalue', 'field_hide', 'field_show_profile', 'field_no_view'),  					2	=> array('field_length', 'field_maxlen', 'field_minlen', 'field_validation', 'field_novalue', 'field_default_value'),  					3	=> array('l_lang_name', 'l_lang_explain', 'l_lang_default_value', 'l_lang_options')  				); @@ -424,6 +425,7 @@ class acp_profile  				// Visibility Options...  				$visibility_ary = array(  					'field_required', +					'field_show_novalue',  					'field_show_on_reg',  					'field_show_on_pm',  					'field_show_on_vt', @@ -779,6 +781,7 @@ class acp_profile  						$template->assign_vars(array(  							'S_STEP_ONE'		=> true,  							'S_FIELD_REQUIRED'	=> ($cp->vars['field_required']) ? true : false, +							'S_FIELD_SHOW_NOVALUE'=> ($cp->vars['field_show_novalue']) ? true : false,  							'S_SHOW_ON_REG'		=> ($cp->vars['field_show_on_reg']) ? true : false,  							'S_SHOW_ON_PM'		=> ($cp->vars['field_show_on_pm']) ? true : false,  							'S_SHOW_ON_VT'		=> ($cp->vars['field_show_on_vt']) ? true : false, @@ -1096,6 +1099,7 @@ class acp_profile  			'field_default_value'	=> $cp->vars['field_default_value'],  			'field_validation'		=> $cp->vars['field_validation'],  			'field_required'		=> $cp->vars['field_required'], +			'field_show_novalue'	=> $cp->vars['field_show_novalue'],  			'field_show_on_reg'		=> $cp->vars['field_show_on_reg'],  			'field_show_on_pm'		=> $cp->vars['field_show_on_pm'],  			'field_show_on_vt'		=> $cp->vars['field_show_on_vt'], diff --git a/phpBB/includes/acp/acp_reasons.php b/phpBB/includes/acp/acp_reasons.php index 479fcfba81..71e9108c2c 100644 --- a/phpBB/includes/acp/acp_reasons.php +++ b/phpBB/includes/acp/acp_reasons.php @@ -113,7 +113,7 @@ class acp_reasons  							$result = $db->sql_query($sql);  							$max_order = (int) $db->sql_fetchfield('max_reason_order');  							$db->sql_freeresult($result); -							 +  							$sql_ary = array(  								'reason_title'			=> (string) $reason_row['reason_title'],  								'reason_description'	=> (string) $reason_row['reason_description'], @@ -171,14 +171,14 @@ class acp_reasons  					'U_ACTION'		=> $this->u_action . "&id=$reason_id&action=$action",  					'U_BACK'		=> $this->u_action,  					'ERROR_MSG'		=> (sizeof($error)) ? implode('<br />', $error) : '', -					 +  					'REASON_TITLE'			=> $reason_row['reason_title'],  					'REASON_DESCRIPTION'	=> $reason_row['reason_description'],  					'TRANSLATED_TITLE'		=> ($translated) ? $user->lang['report_reasons']['TITLE'][strtoupper($reason_row['reason_title'])] : '',  					'TRANSLATED_DESCRIPTION'=> ($translated) ? $user->lang['report_reasons']['DESCRIPTION'][strtoupper($reason_row['reason_title'])] : '', -					'S_AVAILABLE_TITLES'	=> implode(', ', array_map('htmlspecialchars', array_keys($user->lang['report_reasons']['TITLE']))), +					'S_AVAILABLE_TITLES'	=> implode($user->lang['COMMA_SEPARATOR'], array_map('htmlspecialchars', array_keys($user->lang['report_reasons']['TITLE']))),  					'S_EDIT_REASON'			=> true,  					'S_TRANSLATED'			=> $translated,  					'S_ERROR'				=> (sizeof($error)) ? true : false, @@ -303,7 +303,7 @@ class acp_reasons  			do  			{  				++$order; -				 +  				if ($row['reason_order'] != $order)  				{  					$sql = 'UPDATE ' . REPORTS_REASONS_TABLE . " diff --git a/phpBB/includes/acp/acp_styles.php b/phpBB/includes/acp/acp_styles.php index 943bfe6a6f..d41ef571dd 100644 --- a/phpBB/includes/acp/acp_styles.php +++ b/phpBB/includes/acp/acp_styles.php @@ -36,11 +36,11 @@ class acp_styles  	protected $cache;  	protected $auth;  	protected $phpbb_root_path; -	protected $phpEx; +	protected $php_ext;  	public function main($id, $mode)  	{ -		global $db, $user, $phpbb_admin_path, $phpbb_root_path, $phpEx, $template, $request, $cache, $auth, $config; +		global $db, $user, $phpbb_admin_path, $phpbb_root_path, $php_ext, $template, $request, $cache, $auth, $config;  		$this->db = $db;  		$this->user = $user; @@ -50,12 +50,12 @@ class acp_styles  		$this->auth = $auth;  		$this->config = $config;  		$this->phpbb_root_path = $phpbb_root_path; -		$this->phpEx = $phpEx; +		$this->php_ext = $php_ext;  		$this->default_style = $config['default_style'];  		$this->styles_path = $this->phpbb_root_path . $this->styles_path_absolute . '/'; -		$this->u_base_action = append_sid("{$phpbb_admin_path}index.$phpEx", "i={$id}"); +		$this->u_base_action = append_sid("{$phpbb_admin_path}index.$php_ext", "i={$id}");  		$this->s_hidden_fields = array(  			'mode'		=> $mode,  		); @@ -939,7 +939,7 @@ class acp_styles  			// Preview  			$actions[] = array( -				'U_ACTION'	=> append_sid($this->phpbb_root_path . 'index.' . $this->phpEx, 'style=' . $style['style_id']), +				'U_ACTION'	=> append_sid($this->phpbb_root_path . 'index.' . $this->php_ext, 'style=' . $style['style_id']),  				'L_ACTION'	=> $this->user->lang['PREVIEW']  			);  		} diff --git a/phpBB/includes/acp/acp_users.php b/phpBB/includes/acp/acp_users.php index 17687b05c7..62968a17b7 100644 --- a/phpBB/includes/acp/acp_users.php +++ b/phpBB/includes/acp/acp_users.php @@ -1120,10 +1120,12 @@ class acp_users  				$log_count = 0;  				$start = view_log('user', $log_data, $log_count, $config['topics_per_page'], $start, 0, 0, $user_id, $sql_where, $sql_sort); +				$base_url = $this->u_action . "&u=$user_id&$u_sort_param"; +				phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $log_count, $config['topics_per_page'], $start); +				  				$template->assign_vars(array(  					'S_FEEDBACK'	=> true, -					'S_ON_PAGE'		=> on_page($log_count, $config['topics_per_page'], $start), -					'PAGINATION'	=> generate_pagination($this->u_action . "&u=$user_id&$u_sort_param", $log_count, $config['topics_per_page'], $start, true), +					'S_ON_PAGE'		=> phpbb_on_page($template, $user, $base_url, $log_count, $config['topics_per_page'], $start),  					'S_LIMIT_DAYS'	=> $s_limit_days,  					'S_SORT_KEY'	=> $s_sort_key, @@ -1458,9 +1460,8 @@ class acp_users  				$data = array(  					'dateformat'		=> utf8_normalize_nfc(request_var('dateformat', $user_row['user_dateformat'], true)),  					'lang'				=> basename(request_var('lang', $user_row['user_lang'])), -					'tz'				=> request_var('tz', (float) $user_row['user_timezone']), +					'tz'				=> request_var('tz', $user_row['user_timezone']),  					'style'				=> request_var('style', $user_row['user_style']), -					'dst'				=> request_var('dst', $user_row['user_dst']),  					'viewemail'			=> request_var('viewemail', $user_row['user_allow_viewemail']),  					'massemail'			=> request_var('massemail', $user_row['user_allow_massemail']),  					'hideonline'		=> request_var('hideonline', !$user_row['user_allow_viewonline']), @@ -1495,7 +1496,7 @@ class acp_users  					$error = validate_data($data, array(  						'dateformat'	=> array('string', false, 1, 30),  						'lang'			=> array('match', false, '#^[a-z_\-]{2,}$#i'), -						'tz'			=> array('num', false, -14, 14), +						'tz'			=> array('timezone'),  						'topic_sk'		=> array('string', false, 1, 1),  						'topic_sd'		=> array('string', false, 1, 1), @@ -1531,7 +1532,6 @@ class acp_users  							'user_notify_type'		=> $data['notifymethod'],  							'user_notify_pm'		=> $data['notifypm'], -							'user_dst'				=> $data['dst'],  							'user_dateformat'		=> $data['dateformat'],  							'user_lang'				=> $data['lang'],  							'user_timezone'			=> $data['tz'], @@ -1641,6 +1641,7 @@ class acp_users  					${'s_sort_' . $sort_option . '_dir'} .= '</select>';  				} +				$timezone_selects = phpbb_timezone_select($user, $data['tz'], true);  				$template->assign_vars(array(  					'S_PREFS'			=> true,  					'S_JABBER_DISABLED'	=> ($config['jab_enable'] && $user_row['user_jabber'] && @extension_loaded('xml')) ? false : true, @@ -1654,7 +1655,6 @@ class acp_users  					'NOTIFY_BOTH'		=> ($data['notifymethod'] == NOTIFY_BOTH) ? true : false,  					'NOTIFY_PM'			=> $data['notifypm'],  					'POPUP_PM'			=> $data['popuppm'], -					'DST'				=> $data['dst'],  					'BBCODE'			=> $data['bbcode'],  					'SMILIES'			=> $data['smilies'],  					'ATTACH_SIG'		=> $data['sig'], @@ -1681,7 +1681,8 @@ class acp_users  					'S_LANG_OPTIONS'	=> language_select($data['lang']),  					'S_STYLE_OPTIONS'	=> style_select($data['style']), -					'S_TZ_OPTIONS'		=> tz_select($data['tz'], true), +					'S_TZ_OPTIONS'			=> $timezone_selects['tz_select'], +					'S_TZ_DATE_OPTIONS'		=> $timezone_selects['tz_dates'],  					)  				); @@ -1942,7 +1943,7 @@ class acp_users  						$message = (sizeof($log_attachments) == 1) ? $user->lang['ATTACHMENT_DELETED'] : $user->lang['ATTACHMENTS_DELETED']; -						add_log('admin', 'LOG_ATTACHMENTS_DELETED', implode(', ', $log_attachments)); +						add_log('admin', 'LOG_ATTACHMENTS_DELETED', implode($user->lang['COMMA_SEPARATOR'], $log_attachments));  						trigger_error($message . adm_back_link($this->u_action . '&u=' . $user_id));  					}  					else @@ -2035,14 +2036,15 @@ class acp_users  				}  				$db->sql_freeresult($result); +				$base_url = $this->u_action . "&u=$user_id&sk=$sort_key&sd=$sort_dir"; +				phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $num_attachments, $config['topics_per_page'], $start); +				  				$template->assign_vars(array(  					'S_ATTACHMENTS'		=> true, -					'S_ON_PAGE'			=> on_page($num_attachments, $config['topics_per_page'], $start), +					'S_ON_PAGE'			=> phpbb_on_page($template, $user, $base_url, $num_attachments, $config['topics_per_page'], $start),  					'S_SORT_KEY'		=> $s_sort_key,  					'S_SORT_DIR'		=> $s_sort_dir, - -					'PAGINATION'		=> generate_pagination($this->u_action . "&u=$user_id&sk=$sort_key&sd=$sort_dir", $num_attachments, $config['topics_per_page'], $start, true)) -				); +				));  			break; diff --git a/phpBB/includes/acp/auth.php b/phpBB/includes/acp/auth.php index 7d9fd267ff..6b1da46a12 100644 --- a/phpBB/includes/acp/auth.php +++ b/phpBB/includes/acp/auth.php @@ -529,8 +529,8 @@ class auth_admin extends phpbb_auth  					'NAME'			=> $ug_name,  					'CATEGORIES'	=> implode('</th><th>', $categories), -					'USER_GROUPS_DEFAULT'	=> ($user_mode == 'user' && isset($user_groups_default[$ug_id]) && sizeof($user_groups_default[$ug_id])) ? implode(', ', $user_groups_default[$ug_id]) : '', -					'USER_GROUPS_CUSTOM'	=> ($user_mode == 'user' && isset($user_groups_custom[$ug_id]) && sizeof($user_groups_custom[$ug_id])) ? implode(', ', $user_groups_custom[$ug_id]) : '', +					'USER_GROUPS_DEFAULT'	=> ($user_mode == 'user' && isset($user_groups_default[$ug_id]) && sizeof($user_groups_default[$ug_id])) ? implode($user->lang['COMMA_SEPARATOR'], $user_groups_default[$ug_id]) : '', +					'USER_GROUPS_CUSTOM'	=> ($user_mode == 'user' && isset($user_groups_custom[$ug_id]) && sizeof($user_groups_custom[$ug_id])) ? implode($user->lang['COMMA_SEPARATOR'], $user_groups_custom[$ug_id]) : '',  					'L_ACL_TYPE'			=> $l_acl_type,  					'S_LOCAL'		=> ($local) ? true : false, diff --git a/phpBB/includes/datetime.php b/phpBB/includes/datetime.php new file mode 100644 index 0000000000..b3462ddf67 --- /dev/null +++ b/phpBB/includes/datetime.php @@ -0,0 +1,158 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2012 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +*/ + +/** +* phpBB custom extensions to the PHP DateTime class +* This handles the relative formats phpBB employs +*/ +class phpbb_datetime extends DateTime +{ +	/** +	* String used to wrap the date segment which should be replaced by today/tomorrow/yesterday +	*/ +	const RELATIVE_WRAPPER = '|'; + +	/** +	* @var user User who is the context for this DateTime instance +	*/ +	protected $user; + +	/** +	* @var array Date formats are preprocessed by phpBB, to save constant recalculation they are cached. +	*/ +	static protected $format_cache = array(); + +	/** +	* Constructs a new instance of phpbb_datetime, expanded to include an argument to inject +	* the user context and modify the timezone to the users selected timezone if one is not set. +	* +	* @param string $time String in a format accepted by strtotime(). +	* @param DateTimeZone $timezone Time zone of the time. +	* @param user User object for context. +	*/ +	public function __construct($user, $time = 'now', DateTimeZone $timezone = null) +	{ +		$this->user	= $user; +		$timezone	= $timezone ?: $this->user->timezone; + +		parent::__construct($time, $timezone); +	} + +	/** +	* Formats the current date time into the specified format +	* +	* @param string $format Optional format to use for output, defaults to users chosen format +	* @param boolean $force_absolute Force output of a non relative date +	* @return string Formatted date time +	*/ +	public function format($format = '', $force_absolute = false) +	{ +		$format		= $format ? $format : $this->user->date_format; +		$format		= self::format_cache($format, $this->user); +		$relative	= ($format['is_short'] && !$force_absolute); +		$now		= new self($this->user, 'now', $this->user->timezone); + +		$timestamp	= $this->getTimestamp(); +		$now_ts		= $now->getTimeStamp(); + +		$delta		= $now_ts - $timestamp; + +		if ($relative) +		{ +			/* +			* Check the delta is less than or equal to 1 hour +			* and the delta not more than a minute in the past +			* and the delta is either greater than -5 seconds or timestamp +			* and current time are of the same minute (they must be in the same hour already) +			* finally check that relative dates are supported by the language pack +			*/ +			if ($delta <= 3600 && $delta > -60 && +			  ($delta >= -5 || (($now_ts / 60) % 60) == (($timestamp / 60) % 60)) +			  && isset($this->user->lang['datetime']['AGO'])) +			{ +				return $this->user->lang(array('datetime', 'AGO'), max(0, (int) floor($delta / 60))); +			} +			else +			{ +				$midnight = clone $now; +				$midnight->setTime(0, 0, 0); + +				$midnight	= $midnight->getTimestamp(); + +				$day = false; + +				if ($timestamp > $midnight + 86400) +				{ +					$day = 'TOMORROW'; +				} +				else if ($timestamp > $midnight) +				{ +					$day = 'TODAY'; +				} +				else if ($timestamp > $midnight - 86400) +				{ +					$day = 'YESTERDAY'; +				} + +				if ($day !== false) +				{ +					// Format using the short formatting and finally swap out the relative token placeholder with the correct value +					return str_replace(self::RELATIVE_WRAPPER . self::RELATIVE_WRAPPER, $this->user->lang['datetime'][$day], strtr(parent::format($format['format_short']), $format['lang'])); +				} +			} +		} + +		return strtr(parent::format($format['format_long']), $format['lang']); +	} + +	/** +	* Magic method to convert DateTime object to string +	* +	* @return Formatted date time, according to the users default settings. +	*/ +	public function __toString() +	{ +		return $this->format(); +	} + +	/** +	* Pre-processes the specified date format +	* +	* @param string $format Output format +	* @param user $user User object to use for localisation +	* @return array Processed date format +	*/ +	static protected function format_cache($format, $user) +	{ +		$lang = $user->lang_name; + +		if (!isset(self::$format_cache[$lang])) +		{ +			self::$format_cache[$lang] = array(); +		} + +		if (!isset(self::$format_cache[$lang][$format])) +		{ +			// Is the user requesting a friendly date format (i.e. 'Today 12:42')? +			self::$format_cache[$lang][$format] = array( +				'is_short'		=> strpos($format, self::RELATIVE_WRAPPER) !== false, +				'format_short'	=> substr($format, 0, strpos($format, self::RELATIVE_WRAPPER)) . self::RELATIVE_WRAPPER . self::RELATIVE_WRAPPER . substr(strrchr($format, self::RELATIVE_WRAPPER), 1), +				'format_long'	=> str_replace(self::RELATIVE_WRAPPER, '', $format), +				'lang'			=> $user->lang['datetime'], +			); + +			// Short representation of month in format? Some languages use different terms for the long and short format of May +			if ((strpos($format, '\M') === false && strpos($format, 'M') !== false) || (strpos($format, '\r') === false && strpos($format, 'r') !== false)) +			{ +				self::$format_cache[$lang][$format]['lang']['May'] = $user->lang['datetime']['May_short']; +			} +		} + +		return self::$format_cache[$lang][$format]; +	} +} diff --git a/phpBB/includes/db/dbal.php b/phpBB/includes/db/dbal.php index cf54d455f7..159703d3be 100644 --- a/phpBB/includes/db/dbal.php +++ b/phpBB/includes/db/dbal.php @@ -284,6 +284,37 @@ class dbal  	}  	/** +	* Build a case expression +	* +	* Note: The two statements action_true and action_false must have the same data type (int, vchar, ...) in the database! +	* +	* @param	string	$condition		The condition which must be true, to use action_true rather then action_else +	* @param	string	$action_true	SQL expression that is used, if the condition is true +	* @param	string	$action_else	SQL expression that is used, if the condition is false, optional +	* @return	string			CASE expression including the condition and statements +	*/ +	public function sql_case($condition, $action_true, $action_false = false) +	{ +		$sql_case = 'CASE WHEN ' . $condition; +		$sql_case .= ' THEN ' . $action_true; +		$sql_case .= ($action_false !== false) ? ' ELSE ' . $action_false : ''; +		$sql_case .= ' END'; +		return $sql_case; +	} + +	/** +	* Build a concatenated expression +	* +	* @param	string	$expr1		Base SQL expression where we append the second one +	* @param	string	$expr2		SQL expression that is appended to the first expression +	* @return	string		Concatenated string +	*/ +	public function sql_concatenate($expr1, $expr2) +	{ +		return $expr1 . ' || ' . $expr2; +	} + +	/**  	* Returns whether results of a query need to be buffered to run a transaction while iterating over them.  	*  	* @return bool Whether buffering is required. diff --git a/phpBB/includes/db/mssql.php b/phpBB/includes/db/mssql.php index abeabc389f..fb044b492f 100644 --- a/phpBB/includes/db/mssql.php +++ b/phpBB/includes/db/mssql.php @@ -92,6 +92,14 @@ class dbal_mssql extends dbal  	}  	/** +	* {@inheritDoc} +	*/ +	public function sql_concatenate($expr1, $expr2) +	{ +		return $expr1 . ' + ' . $expr2; +	} + +	/**  	* SQL Transaction  	* @access private  	*/ diff --git a/phpBB/includes/db/mssql_odbc.php b/phpBB/includes/db/mssql_odbc.php index 6e24f4e9e8..64fa9634d1 100644 --- a/phpBB/includes/db/mssql_odbc.php +++ b/phpBB/includes/db/mssql_odbc.php @@ -110,6 +110,14 @@ class dbal_mssql_odbc extends dbal  	}  	/** +	* {@inheritDoc} +	*/ +	public function sql_concatenate($expr1, $expr2) +	{ +		return $expr1 . ' + ' . $expr2; +	} + +	/**  	* SQL Transaction  	* @access private  	*/ diff --git a/phpBB/includes/db/mssqlnative.php b/phpBB/includes/db/mssqlnative.php index 8a4503f111..1f37d54ecb 100644 --- a/phpBB/includes/db/mssqlnative.php +++ b/phpBB/includes/db/mssqlnative.php @@ -260,6 +260,14 @@ class dbal_mssqlnative extends dbal  	/**  	* {@inheritDoc}  	*/ +	public function sql_concatenate($expr1, $expr2) +	{ +		return $expr1 . ' + ' . $expr2; +	} + +	/** +	* {@inheritDoc} +	*/  	function sql_buffer_nested_transactions()  	{  		return true; @@ -435,7 +443,7 @@ class dbal_mssqlnative extends dbal  				unset($row['line2'], $row['line3']);  			}  		} -		return $row; +		return (sizeof($row)) ? $row : false;  	}  	/** diff --git a/phpBB/includes/db/mysql.php b/phpBB/includes/db/mysql.php index eb38e3e913..8d1f805870 100644 --- a/phpBB/includes/db/mysql.php +++ b/phpBB/includes/db/mysql.php @@ -120,6 +120,14 @@ class dbal_mysql extends dbal  	}  	/** +	* {@inheritDoc} +	*/ +	public function sql_concatenate($expr1, $expr2) +	{ +		return 'CONCAT(' . $expr1 . ', ' . $expr2 . ')'; +	} + +	/**  	* SQL Transaction  	* @access private  	*/ diff --git a/phpBB/includes/db/mysqli.php b/phpBB/includes/db/mysqli.php index 4210a58002..e07cd35e24 100644 --- a/phpBB/includes/db/mysqli.php +++ b/phpBB/includes/db/mysqli.php @@ -123,6 +123,14 @@ class dbal_mysqli extends dbal  	}  	/** +	* {@inheritDoc} +	*/ +	public function sql_concatenate($expr1, $expr2) +	{ +		return 'CONCAT(' . $expr1 . ', ' . $expr2 . ')'; +	} + +	/**  	* SQL Transaction  	* @access private  	*/ diff --git a/phpBB/includes/extension/controller.php b/phpBB/includes/extension/controller.php index c7fd439a19..ec051c756f 100644 --- a/phpBB/includes/extension/controller.php +++ b/phpBB/includes/extension/controller.php @@ -50,7 +50,7 @@ abstract class phpbb_extension_controller implements phpbb_extension_controller_  	/**  	* @var string PHP Extension  	*/ -	protected $phpEx; +	protected $php_ext;  	/**  	* @var string Relative path to board root @@ -64,14 +64,14 @@ abstract class phpbb_extension_controller implements phpbb_extension_controller_  	public function __construct()  	{  		global $request, $db, $user, $template, $config; -		global $phpEx, $phpbb_root_path; +		global $php_ext, $phpbb_root_path;  		$this->request = $request;  		$this->db = $db;  		$this->user = $user;  		$this->template = $template;  		$this->config = $config; -		$this->phpEx = $phpEx; +		$this->php_ext = $php_ext;  		$this->phpbb_root_path = $phpbb_root_path;  	}  } diff --git a/phpBB/includes/extension/finder.php b/phpBB/includes/extension/finder.php index 87ca40917d..fb19b98429 100644 --- a/phpBB/includes/extension/finder.php +++ b/phpBB/includes/extension/finder.php @@ -25,7 +25,7 @@ class phpbb_extension_finder  	protected $extension_manager;  	protected $phpbb_root_path;  	protected $cache; -	protected $phpEx; +	protected $php_ext;  	/**  	* The cache variable name used to store $this->cached_queries in $this->cache. @@ -56,16 +56,16 @@ class phpbb_extension_finder  	*            extensions and their locations  	* @param string $phpbb_root_path Path to the phpbb root directory  	* @param phpbb_cache_driver_interface $cache A cache instance or null -	* @param string $phpEx php file extension +	* @param string $php_ext php file extension  	* @param string $cache_name The name of the cache variable, defaults to  	*                           _ext_finder  	*/ -	public function __construct(phpbb_extension_manager $extension_manager, $phpbb_root_path = '', phpbb_cache_driver_interface $cache = null, $phpEx = '.php', $cache_name = '_ext_finder') +	public function __construct(phpbb_extension_manager $extension_manager, $phpbb_root_path = '', phpbb_cache_driver_interface $cache = null, $php_ext = '.php', $cache_name = '_ext_finder')  	{  		$this->extension_manager = $extension_manager;  		$this->phpbb_root_path = $phpbb_root_path;  		$this->cache = $cache; -		$this->phpEx = $phpEx; +		$this->php_ext = $php_ext;  		$this->cache_name = $cache_name;  		$this->query = array( @@ -251,8 +251,8 @@ class phpbb_extension_finder  	*/  	public function get_classes($cache = true)  	{ -		$this->query['extension_suffix'] .= $this->phpEx; -		$this->query['core_suffix'] .= $this->phpEx; +		$this->query['extension_suffix'] .= $this->php_ext; +		$this->query['core_suffix'] .= $this->php_ext;  		$files = $this->find($cache, false); @@ -261,7 +261,7 @@ class phpbb_extension_finder  		{  			$file = preg_replace('#^includes/#', '', $file); -			$classes[] = 'phpbb_' . str_replace('/', '_', substr($file, 0, -strlen($this->phpEx))); +			$classes[] = 'phpbb_' . str_replace('/', '_', substr($file, 0, -strlen($this->php_ext)));  		}  		return $classes;  	} diff --git a/phpBB/includes/extension/manager.php b/phpBB/includes/extension/manager.php index 537c19aff8..86d8fab64b 100644 --- a/phpBB/includes/extension/manager.php +++ b/phpBB/includes/extension/manager.php @@ -23,7 +23,7 @@ if (!defined('IN_PHPBB'))  class phpbb_extension_manager  {  	protected $cache; -	protected $phpEx; +	protected $php_ext;  	protected $extensions;  	protected $extension_table;  	protected $phpbb_root_path; @@ -35,16 +35,16 @@ class phpbb_extension_manager  	* @param dbal $db A database connection  	* @param string $extension_table The name of the table holding extensions  	* @param string $phpbb_root_path Path to the phpbb includes directory. -	* @param string $phpEx php file extension +	* @param string $php_ext php file extension  	* @param phpbb_cache_driver_interface $cache A cache instance or null  	* @param string $cache_name The name of the cache variable, defaults to _ext  	*/ -	public function __construct(dbal $db, $extension_table, $phpbb_root_path, $phpEx = '.php', phpbb_cache_driver_interface $cache = null, $cache_name = '_ext') +	public function __construct(dbal $db, $extension_table, $phpbb_root_path, $php_ext = '.php', phpbb_cache_driver_interface $cache = null, $cache_name = '_ext')  	{  		$this->phpbb_root_path = $phpbb_root_path;  		$this->db = $db;  		$this->cache = $cache; -		$this->phpEx = $phpEx; +		$this->php_ext = $php_ext;  		$this->extension_table = $extension_table;  		$this->cache_name = $cache_name; @@ -362,7 +362,7 @@ class phpbb_extension_manager  			RecursiveIteratorIterator::SELF_FIRST);  		foreach ($iterator as $file_info)  		{ -			if ($file_info->isFile() && $file_info->getFilename() == 'ext' . $this->phpEx) +			if ($file_info->isFile() && $file_info->getFilename() == 'ext' . $this->php_ext)  			{  				$ext_name = $iterator->getInnerIterator()->getSubPath(); @@ -432,7 +432,7 @@ class phpbb_extension_manager  		}  		return $disabled;  	} -	 +  	/**  	* Check to see if a given extension is available on the filesystem  	* @@ -462,6 +462,6 @@ class phpbb_extension_manager  	*/  	public function get_finder()  	{ -		return new phpbb_extension_finder($this, $this->phpbb_root_path, $this->cache, $this->phpEx, $this->cache_name . '_finder'); +		return new phpbb_extension_finder($this, $this->phpbb_root_path, $this->cache, $this->php_ext, $this->cache_name . '_finder');  	}  } diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index e40df93194..e5b721b1f5 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -1069,32 +1069,209 @@ function style_select($default = '', $all = false)  }  /** +* Format the timezone offset with hours and minutes +* +* @param	int		$tz_offset	Timezone offset in seconds +* @return	string		Normalized offset string:	-7200 => -02:00 +*													16200 => +04:30 +*/ +function phpbb_format_timezone_offset($tz_offset) +{ +	$sign = ($tz_offset < 0) ? '-' : '+'; +	$time_offset = abs($tz_offset); + +	$offset_seconds	= $time_offset % 3600; +	$offset_minutes	= $offset_seconds / 60; +	$offset_hours	= ($time_offset - $offset_seconds) / 3600; + +	$offset_string	= sprintf("%s%02d:%02d", $sign, $offset_hours, $offset_minutes); +	return $offset_string; +} + +/** +* Compares two time zone labels. +* Arranges them in increasing order by timezone offset. +* Places UTC before other timezones in the same offset. +*/ +function phpbb_tz_select_compare($a, $b) +{ +	$a_sign = $a[3]; +	$b_sign = $b[3]; +	if ($a_sign != $b_sign) +	{ +		return $a_sign == '-' ? -1 : 1; +	} + +	$a_offset = substr($a, 4, 5); +	$b_offset = substr($b, 4, 5); +	if ($a_offset == $b_offset) +	{ +		$a_name = substr($a, 12); +		$b_name = substr($b, 12); +		if ($a_name == $b_name) +		{ +			return 0; +		} +		else if ($a_name == 'UTC') +		{ +			return -1; +		} +		else if ($b_name == 'UTC') +		{ +			return 1; +		} +		else +		{ +			return $a_name < $b_name ? -1 : 1; +		} +	} +	else +	{ +		if ($a_sign == '-') +		{ +			return $a_offset > $b_offset ? -1 : 1; +		} +		else +		{ +			return $a_offset < $b_offset ? -1 : 1; +		} +	} +} + +/** +* Return list of timezone identifiers +* We also add the selected timezone if we can create an object with it. +* DateTimeZone::listIdentifiers seems to not add all identifiers to the list, +* because some are only kept for backward compatible reasons. If the user has +* a deprecated value, we add it here, so it can still be kept. Once the user +* changed his value, there is no way back to deprecated values. +* +* @param	string		$selected_timezone		Additional timezone that shall +*												be added to the list of identiers +* @return		array		DateTimeZone::listIdentifiers and additional +*							selected_timezone if it is a valid timezone. +*/ +function phpbb_get_timezone_identifiers($selected_timezone) +{ +	$timezones = DateTimeZone::listIdentifiers(); + +	if (!in_array($selected_timezone, $timezones)) +	{ +		try +		{ +			// Add valid timezones that are currently selected but not returned +			// by DateTimeZone::listIdentifiers +			$validate_timezone = new DateTimeZone($selected_timezone); +			$timezones[] = $selected_timezone; +		} +		catch (Exception $e) +		{ +		} +	} + +	return $timezones; +} + +/**  * Pick a timezone +* +* @param	string		$default			A timezone to select +* @param	boolean		$truncate			Shall we truncate the options text +* +* @return		string		Returns the options for timezone selector only +* +* @deprecated  */  function tz_select($default = '', $truncate = false)  {  	global $user; -	$tz_select = ''; -	foreach ($user->lang['tz_zones'] as $offset => $zone) +	$timezone_select = phpbb_timezone_select($user, $default, $truncate); +	return $timezone_select['tz_select']; +} + +/** +* Options to pick a timezone and date/time +* +* @param	phpbb_user	$user				Object of the current user +* @param	string		$default			A timezone to select +* @param	boolean		$truncate			Shall we truncate the options text +* +* @return		array		Returns an array, also containing the options for the time selector. +*/ +function phpbb_timezone_select($user, $default = '', $truncate = false) +{ +	static $timezones; + +	$default_offset = ''; +	if (!isset($timezones))  	{ -		if ($truncate) +		$unsorted_timezones = phpbb_get_timezone_identifiers($default); + +		$timezones = array(); +		foreach ($unsorted_timezones as $timezone)  		{ -			$zone_trunc = truncate_string($zone, 50, 255, false, '...'); +			$tz = new DateTimeZone($timezone); +			$dt = new phpbb_datetime($user, 'now', $tz); +			$offset = $dt->getOffset(); +			$current_time = $dt->format($user->lang['DATETIME_FORMAT'], true); +			$offset_string = phpbb_format_timezone_offset($offset); +			$timezones['GMT' . $offset_string . ' - ' . $timezone] = array( +				'tz'		=> $timezone, +				'offest'	=> 'GMT' . $offset_string, +				'current'	=> $current_time, +			); +			if ($timezone === $default) +			{ +				$default_offset = 'GMT' . $offset_string; +			} +		} +		unset($unsorted_timezones); + +		uksort($timezones, 'phpbb_tz_select_compare'); +	} + +	$tz_select = $tz_dates = $opt_group = ''; + +	foreach ($timezones as $timezone) +	{ +		if ($opt_group != $timezone['offest']) +		{ +			$tz_select .= ($opt_group) ? '</optgroup>' : ''; +			$tz_select .= '<optgroup label="' . $timezone['offest'] . ' - ' . $timezone['current'] . '">'; +			$opt_group = $timezone['offest']; + +			$selected = ($default_offset == $timezone['offest']) ? ' selected="selected"' : ''; +			$tz_dates .= '<option value="' . $timezone['offest'] . ' - ' . $timezone['current'] . '"' . $selected . '>' . $timezone['offest'] . ' - ' . $timezone['current'] . '</option>'; +		} + +		if (isset($user->lang['timezones'][$timezone['tz']])) +		{ +			$title = $label = $user->lang['timezones'][$timezone['tz']];  		}  		else  		{ -			$zone_trunc = $zone; +			// No label, we'll figure one out +			$bits = explode('/', str_replace('_', ' ', $timezone['tz'])); + +			$label = implode(' - ', $bits); +			$title = $timezone['offest'] . ' - ' . $label;  		} -		if (is_numeric($offset)) +		if ($truncate)  		{ -			$selected = ($offset == $default) ? ' selected="selected"' : ''; -			$tz_select .= '<option title="' . $zone . '" value="' . $offset . '"' . $selected . '>' . $zone_trunc . '</option>'; +			$label = truncate_string($label, 50, 255, false, '...');  		} + +		$selected = ($timezone['tz'] === $default) ? ' selected="selected"' : ''; +		$tz_select .= '<option title="' . $title . '" value="' . $timezone['tz'] . '"' . $selected . '>' . $label . '</option>';  	} +	$tz_select .= '</optgroup>'; -	return $tz_select; +	return array( +		'tz_select'		=> $tz_select, +		'tz_dates'		=> $tz_dates, +	);  }  // Functions handling topic/post tracking/marking @@ -1881,105 +2058,152 @@ function tracking_unserialize($string, $max_depth = 3)  // Pagination functions  /** -* Pagination routine, generates page number sequence -* tpl_prefix is for using different pagination blocks at one page +* Generate template rendered pagination +* Allows full control of rendering of pagination with the template +* +* @param object $template the template object +* @param string $base_url is url prepended to all links generated within the function +* @param string $block_var_name is the name assigned to the pagination data block within the template (example: <!-- BEGIN pagination -->) +* @param string $start_name is the name of the parameter containing the first item of the given page (example: start=20) +* @param int $num_items the total number of items, posts, etc., used to determine the number of pages to produce +* @param int $per_page the number of items, posts, etc. to display per page, used to determine the number of pages to produce +* @param int $start_item the item which should be considered currently active, used to determine the page we're on +* @param bool $reverse_count determines whether we weight display of the list towards the start (false) or end (true) of the list +* @param bool $ignore_on_page decides whether we enable an active (unlinked) item, used primarily for embedded lists +* @return null  */ -function generate_pagination($base_url, $num_items, $per_page, $start_item, $add_prevnext_text = false, $tpl_prefix = '') +function phpbb_generate_template_pagination($template, $base_url, $block_var_name, $start_name, $num_items, $per_page, $start_item = 1, $reverse_count = false, $ignore_on_page = false)  { -	global $template, $user; -  	// Make sure $per_page is a valid value  	$per_page = ($per_page <= 0) ? 1 : $per_page; - -	$separator = '<span class="page-sep">' . $user->lang['COMMA_SEPARATOR'] . '</span>';  	$total_pages = ceil($num_items / $per_page);  	if ($total_pages == 1 || !$num_items)  	{ -		return false; +		return;  	}  	$on_page = floor($start_item / $per_page) + 1;  	$url_delim = (strpos($base_url, '?') === false) ? '?' : ((strpos($base_url, '?') === strlen($base_url) - 1) ? '' : '&'); - -	$page_string = ($on_page == 1) ? '<strong>1</strong>' : '<a href="' . $base_url . '">1</a>'; - -	if ($total_pages > 5) +	 +	if ($reverse_count)  	{ -		$start_cnt = min(max(1, $on_page - 4), $total_pages - 5); -		$end_cnt = max(min($total_pages, $on_page + 4), 6); - -		$page_string .= ($start_cnt > 1) ? '<span class="page-dots"> ... </span>' : $separator; - -		for ($i = $start_cnt + 1; $i < $end_cnt; $i++) -		{ -			$page_string .= ($i == $on_page) ? '<strong>' . $i . '</strong>' : '<a href="' . $base_url . "{$url_delim}start=" . (($i - 1) * $per_page) . '">' . $i . '</a>'; -			if ($i < $end_cnt - 1) -			{ -				$page_string .= $separator; -			} -		} - -		$page_string .= ($end_cnt < $total_pages) ? '<span class="page-dots"> ... </span>' : $separator; +		$start_page = ($total_pages > 5) ? $total_pages - 4 : 1; +		$end_page = $total_pages;  	}  	else  	{ -		$page_string .= $separator; +		// What we're doing here is calculating what the "start" and "end" pages should be. We +		// do this by assuming pagination is "centered" around the currently active page with  +		// the three previous and three next page links displayed. Anything more than that and  +		// we display the ellipsis, likewise anything less.  +		// +		// $start_page is the page at which we start creating the list. When we have five or less +		// pages we start at page 1 since there will be no ellipsis displayed. Anymore than that +		// and we calculate the start based on the active page. This is the min/max calculation. +		// First (max) would we end up starting on a page less than 1? Next (min) would we end +		// up starting so close to the end that we'd not display our minimum number of pages. +		// +		// $end_page is the last page in the list to display. Like $start_page we use a min/max to +		// determine this number. Again at most five pages? Then just display them all. More than +		// five and we first (min) determine whether we'd end up listing more pages than exist. +		// We then (max) ensure we're displaying the minimum number of pages. +		$start_page = ($total_pages > 5) ? min(max(1, $on_page - 3), $total_pages - 4) : 1; +		$end_page = ($total_pages > 5) ? max(min($total_pages, $on_page + 3), 5) : $total_pages; +	} + +	if ($on_page != $total_pages) +	{ +		$template->assign_block_vars($block_var_name, array( +			'PAGE_NUMBER'	=> '',  +			'PAGE_URL'		=> $base_url . $url_delim . $start_name . '=' . ($on_page * $per_page), +			'S_IS_CURRENT'	=> false,  +			'S_IS_PREV'		=> false,   +			'S_IS_NEXT'		=> true,  +			'S_IS_ELLIPSIS'	=> false,  +		)); +	}	 + +	// This do...while exists purely to negate the need for start and end assign_block_vars, i.e. +	// to display the first and last page in the list plus any ellipsis. We use this loop to jump  +	// around a little within the list depending on where we're starting (and ending).  +	$at_page = 1; +	do +	{ +		$page_url = $base_url . (($at_page == 1) ? '' : $url_delim . $start_name . '=' . (($at_page - 1) * $per_page)); + +		// We decide whether to display the ellipsis during the loop. The ellipsis is always +		// displayed as either the second or penultimate item in the list. So are we at either +		// of those points and of course do we even need to display it, i.e. is the list starting +		// on at least page 3 and ending three pages before the final item. +		$template->assign_block_vars($block_var_name, array( +			'PAGE_NUMBER'	=> $at_page,   +			'PAGE_URL'		=> $page_url, +			'S_IS_CURRENT'	=> (!$ignore_on_page && $at_page == $on_page),  +			'S_IS_NEXT'		=> false,  +			'S_IS_PREV'		=> false,  +			'S_IS_ELLIPSIS'	=> ($at_page == 2 && $start_page > 2) || ($at_page == $total_pages - 1 && $end_page < $total_pages - 1),  +		)); -		for ($i = 2; $i < $total_pages; $i++) +		// We may need to jump around in the list depending on whether we have or need to display  +		// the ellipsis. Are we on page 2 and are we more than one page away from the start +		// of the list? Yes? Then we jump to the start of the list. Likewise are we at the end of  +		// the list and are there more than two pages left in total? Yes? Then jump to the penultimate +		// page (so we can display the ellipsis next pass). Else, increment the counter and keep +		// going +		if ($at_page == 2 && $at_page < $start_page - 1)  		{ -			$page_string .= ($i == $on_page) ? '<strong>' . $i . '</strong>' : '<a href="' . $base_url . "{$url_delim}start=" . (($i - 1) * $per_page) . '">' . $i . '</a>'; -			if ($i < $total_pages) -			{ -				$page_string .= $separator; -			} +			$at_page = $start_page;  		} -	} - -	$page_string .= ($on_page == $total_pages) ? '<strong>' . $total_pages . '</strong>' : '<a href="' . $base_url . "{$url_delim}start=" . (($total_pages - 1) * $per_page) . '">' . $total_pages . '</a>'; - -	if ($add_prevnext_text) -	{ -		if ($on_page != 1) +		else if ($at_page == $end_page && $end_page < $total_pages - 1)  		{ -			$page_string = '<a href="' . $base_url . "{$url_delim}start=" . (($on_page - 2) * $per_page) . '">' . $user->lang['PREVIOUS'] . '</a>  ' . $page_string; +			$at_page = $total_pages - 1;  		} - -		if ($on_page != $total_pages) +		else  		{ -			$page_string .= '  <a href="' . $base_url . "{$url_delim}start=" . ($on_page * $per_page) . '">' . $user->lang['NEXT'] . '</a>'; +			$at_page++;  		}  	} +	while ($at_page <= $total_pages); -	$template->assign_vars(array( -		$tpl_prefix . 'BASE_URL'		=> $base_url, -		'A_' . $tpl_prefix . 'BASE_URL'	=> addslashes($base_url), -		$tpl_prefix . 'PER_PAGE'		=> $per_page, - -		$tpl_prefix . 'PREVIOUS_PAGE'	=> ($on_page == 1) ? '' : $base_url . "{$url_delim}start=" . (($on_page - 2) * $per_page), -		$tpl_prefix . 'NEXT_PAGE'		=> ($on_page == $total_pages) ? '' : $base_url . "{$url_delim}start=" . ($on_page * $per_page), -		$tpl_prefix . 'TOTAL_PAGES'		=> $total_pages, -		$tpl_prefix . 'CURRENT_PAGE'	=> $on_page, -	)); - -	return $page_string; +	if ($on_page != 1) +	{ +		$template->assign_block_vars($block_var_name, array( +			'PAGE_NUMBER'	=> '',  +			'PAGE_URL'		=> $base_url . $url_delim . $start_name . '=' . (($on_page - 2) * $per_page), +			'S_IS_CURRENT'	=> false,  +			'S_IS_PREV'		=> true,  +			'S_IS_NEXT'		=> false,  +			'S_IS_ELLIPSIS'	=> false,  +		)); +	}  }  /** -* Return current page (pagination) +* Return current page  +* This function also sets certain specific template variables +* +* @param object $template the template object +* @param object $user the user object +* @param string $base_url the base url used to call this page, used by Javascript for popup jump to page +* @param int $num_items the total number of items, posts, topics, etc. +* @param int $per_page the number of items, posts, etc. per page +* @param int $start the item which should be considered currently active, used to determine the page we're on +* @return null  */ -function on_page($num_items, $per_page, $start) +function phpbb_on_page($template, $user, $base_url, $num_items, $per_page, $start)  { -	global $template, $user; -  	// Make sure $per_page is a valid value  	$per_page = ($per_page <= 0) ? 1 : $per_page;  	$on_page = floor($start / $per_page) + 1;  	$template->assign_vars(array( -		'ON_PAGE'		=> $on_page) -	); +		'PER_PAGE'		=> $per_page, +		'ON_PAGE'		=> $on_page,  +		 +		'A_BASE_URL'	=> addslashes($base_url),  +	));  	return sprintf($user->lang['PAGE_OF'], $on_page, max(ceil($num_items / $per_page), 1));  } @@ -4654,9 +4878,6 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0  	$board_url = generate_board_url() . '/';  	$web_path = (defined('PHPBB_USE_BOARD_URL_PATH') && PHPBB_USE_BOARD_URL_PATH) ? $board_url : $phpbb_root_path; -	// Which timezone? -	$tz = ($user->data['user_id'] != ANONYMOUS) ? strval(doubleval($user->data['user_timezone'])) : strval(doubleval($config['board_timezone'])); -  	// Send a proper content-language to the output  	$user_lang = $user->lang['USER_LANG'];  	if (strpos($user_lang, '-x-') !== false) @@ -4679,6 +4900,14 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0  		}  	} +	$dt = new phpbb_datetime($user, 'now', $user->timezone); +	$timezone_offset = 'GMT' . phpbb_format_timezone_offset($dt->getOffset()); +	$timezone_name = $user->timezone->getName(); +	if (isset($user->lang['timezones'][$timezone_name])) +	{ +		$timezone_name = $user->lang['timezones'][$timezone_name]; +	} +  	// The following assigns all _common_ variables that may be used at any point in a template.  	$template->assign_vars(array(  		'SITENAME'						=> $config['sitename'], @@ -4746,7 +4975,7 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0  		'S_CONTENT_FLOW_BEGIN'	=> ($user->lang['DIRECTION'] == 'ltr') ? 'left' : 'right',  		'S_CONTENT_FLOW_END'	=> ($user->lang['DIRECTION'] == 'ltr') ? 'right' : 'left',  		'S_CONTENT_ENCODING'	=> 'UTF-8', -		'S_TIMEZONE'			=> ($user->data['user_dst'] || ($user->data['user_id'] == ANONYMOUS && $config['board_dst'])) ? sprintf($user->lang['ALL_TIMES'], $user->lang['tz'][$tz], $user->lang['tz']['dst']) : sprintf($user->lang['ALL_TIMES'], $user->lang['tz'][$tz], ''), +		'S_TIMEZONE'			=> sprintf($user->lang['ALL_TIMES'], $timezone_offset, $timezone_name),  		'S_DISPLAY_ONLINE_LIST'	=> ($l_online_time) ? 1 : 0,  		'S_DISPLAY_SEARCH'		=> (!$config['load_search']) ? 0 : (isset($auth) ? ($auth->acl_get('u_search') && $auth->acl_getf_global('f_search')) : 1),  		'S_DISPLAY_PM'			=> ($config['allow_privmsg'] && !empty($user->data['is_registered']) && ($auth->acl_get('u_readpm') || $auth->acl_get('u_sendpm'))) ? true : false, diff --git a/phpBB/includes/functions_admin.php b/phpBB/includes/functions_admin.php index 3ebd6682a9..5d19cd7adb 100644 --- a/phpBB/includes/functions_admin.php +++ b/phpBB/includes/functions_admin.php @@ -2292,21 +2292,6 @@ function auto_prune($forum_id, $prune_mode, $prune_flags, $prune_days, $prune_fr  }  /** -* remove_comments will strip the sql comment lines out of an uploaded sql file -* specifically for mssql and postgres type files in the install.... -* -* @deprecated		Use phpbb_remove_comments() instead. -*/ -function remove_comments(&$output) -{ -	// Remove /* */ comments (http://ostermiller.org/findcomment.html) -	$output = preg_replace('#/\*(.|[\r\n])*?\*/#', "\n", $output); - -	// Return by reference and value. -	return $output; -} - -/**  * Cache moderators, called whenever permissions are changed via admin_permissions. Changes of username  * and group names must be carried through for the moderators table  */ diff --git a/phpBB/includes/functions_convert.php b/phpBB/includes/functions_convert.php index e9ec153c50..ac791e0d9b 100644 --- a/phpBB/includes/functions_convert.php +++ b/phpBB/includes/functions_convert.php @@ -1884,7 +1884,7 @@ function add_bots()  			'user_email'			=> '',  			'user_lang'				=> $config['default_lang'],  			'user_style'			=> 1, -			'user_timezone'			=> 0, +			'user_timezone'			=> 'UTC',  			'user_allow_massemail'	=> 0,  		); diff --git a/phpBB/includes/functions_display.php b/phpBB/includes/functions_display.php index 545f75ad67..a1ff7a1f99 100644 --- a/phpBB/includes/functions_display.php +++ b/phpBB/includes/functions_display.php @@ -411,7 +411,7 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod  		if ($display_moderators && !empty($forum_moderators[$forum_id]))  		{  			$l_moderator = (sizeof($forum_moderators[$forum_id]) == 1) ? $user->lang['MODERATOR'] : $user->lang['MODERATORS']; -			$moderators_list = implode(', ', $forum_moderators[$forum_id]); +			$moderators_list = implode($user->lang['COMMA_SEPARATOR'], $forum_moderators[$forum_id]);  		}  		$l_post_click_count = ($row['forum_type'] == FORUM_LINK) ? 'CLICKS' : 'POSTS'; @@ -422,7 +422,7 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod  		{  			$s_subforums_list[] = '<a href="' . $subforum['link'] . '" class="subforum ' . (($subforum['unread']) ? 'unread' : 'read') . '" title="' . (($subforum['unread']) ? $user->lang['UNREAD_POSTS'] : $user->lang['NO_UNREAD_POSTS']) . '">' . $subforum['name'] . '</a>';  		} -		$s_subforums_list = (string) implode(', ', $s_subforums_list); +		$s_subforums_list = (string) implode($user->lang['COMMA_SEPARATOR'], $s_subforums_list);  		$catless = ($row['parent_id'] == $root_data['forum_id']) ? true : false;  		if ($row['forum_type'] != FORUM_LINK) @@ -640,48 +640,6 @@ function get_forum_parents(&$forum_data)  }  /** -* Generate topic pagination -*/ -function topic_generate_pagination($replies, $url) -{ -	global $config, $user; - -	// Make sure $per_page is a valid value -	$per_page = ($config['posts_per_page'] <= 0) ? 1 : $config['posts_per_page']; - -	if (($replies + 1) > $per_page) -	{ -		$total_pages = ceil(($replies + 1) / $per_page); -		$pagination = ''; - -		$times = 1; -		for ($j = 0; $j < $replies + 1; $j += $per_page) -		{ -			$pagination .= '<a href="' . $url . ($j == 0 ? '' : '&start=' . $j) . '">' . $times . '</a>'; -			if ($times == 1 && $total_pages > 5) -			{ -				$pagination .= '<span class="page-dots"> ... </span>'; - -				// Display the last three pages -				$times = $total_pages - 3; -				$j += ($total_pages - 4) * $per_page; -			} -			else if ($times < $total_pages) -			{ -				$pagination .= '<span class="page-sep">' . $user->lang['COMMA_SEPARATOR'] . '</span>'; -			} -			$times++; -		} -	} -	else -	{ -		$pagination = ''; -	} - -	return $pagination; -} - -/**  * Obtain list of moderators of each forum  */  function get_moderators(&$forum_moderators, $forum_id = false) diff --git a/phpBB/includes/functions_install.php b/phpBB/includes/functions_install.php index 80f2bf940d..46541acd44 100644 --- a/phpBB/includes/functions_install.php +++ b/phpBB/includes/functions_install.php @@ -49,7 +49,6 @@ function get_available_dbms($dbms = false, $return_unavailable = false, $only_20  			'SCHEMA'		=> 'firebird',  			'MODULE'		=> 'interbase',  			'DELIM'			=> ';;', -			'COMMENTS'		=> 'remove_remarks',  			'DRIVER'		=> 'firebird',  			'AVAILABLE'		=> true,  			'2.0.x'			=> false, @@ -59,7 +58,6 @@ function get_available_dbms($dbms = false, $return_unavailable = false, $only_20  			'SCHEMA'		=> 'mysql_41',  			'MODULE'		=> 'mysqli',  			'DELIM'			=> ';', -			'COMMENTS'		=> 'remove_remarks',  			'DRIVER'		=> 'mysqli',  			'AVAILABLE'		=> true,  			'2.0.x'			=> true, @@ -69,7 +67,6 @@ function get_available_dbms($dbms = false, $return_unavailable = false, $only_20  			'SCHEMA'		=> 'mysql',  			'MODULE'		=> 'mysql',  			'DELIM'			=> ';', -			'COMMENTS'		=> 'remove_remarks',  			'DRIVER'		=> 'mysql',  			'AVAILABLE'		=> true,  			'2.0.x'			=> true, @@ -79,7 +76,6 @@ function get_available_dbms($dbms = false, $return_unavailable = false, $only_20  			'SCHEMA'		=> 'mssql',  			'MODULE'		=> 'mssql',  			'DELIM'			=> 'GO', -			'COMMENTS'		=> 'remove_comments',  			'DRIVER'		=> 'mssql',  			'AVAILABLE'		=> true,  			'2.0.x'			=> true, @@ -89,7 +85,6 @@ function get_available_dbms($dbms = false, $return_unavailable = false, $only_20  			'SCHEMA'		=> 'mssql',  			'MODULE'		=> 'odbc',  			'DELIM'			=> 'GO', -			'COMMENTS'		=> 'remove_comments',  			'DRIVER'		=> 'mssql_odbc',  			'AVAILABLE'		=> true,  			'2.0.x'			=> true, @@ -99,7 +94,6 @@ function get_available_dbms($dbms = false, $return_unavailable = false, $only_20  			'SCHEMA'		=> 'mssql',  			'MODULE'		=> 'sqlsrv',  			'DELIM'			=> 'GO', -			'COMMENTS'		=> 'remove_comments',  			'DRIVER'		=> 'mssqlnative',  			'AVAILABLE'		=> true,  			'2.0.x'			=> false, @@ -109,7 +103,6 @@ function get_available_dbms($dbms = false, $return_unavailable = false, $only_20  			'SCHEMA'		=> 'oracle',  			'MODULE'		=> 'oci8',  			'DELIM'			=> '/', -			'COMMENTS'		=> 'remove_comments',  			'DRIVER'		=> 'oracle',  			'AVAILABLE'		=> true,  			'2.0.x'			=> false, @@ -119,7 +112,6 @@ function get_available_dbms($dbms = false, $return_unavailable = false, $only_20  			'SCHEMA'		=> 'postgres',  			'MODULE'		=> 'pgsql',  			'DELIM'			=> ';', -			'COMMENTS'		=> 'remove_comments',  			'DRIVER'		=> 'postgres',  			'AVAILABLE'		=> true,  			'2.0.x'			=> true, @@ -129,7 +121,6 @@ function get_available_dbms($dbms = false, $return_unavailable = false, $only_20  			'SCHEMA'		=> 'sqlite',  			'MODULE'		=> 'sqlite',  			'DELIM'			=> ';', -			'COMMENTS'		=> 'remove_remarks',  			'DRIVER'		=> 'sqlite',  			'AVAILABLE'		=> true,  			'2.0.x'			=> false, @@ -472,19 +463,6 @@ function connect_check_db($error_connect, &$error, $dbms_details, $table_prefix,  }  /** -* Removes comments from schema files -* -* @deprecated		Use phpbb_remove_comments() instead. -*/ -function remove_remarks(&$sql) -{ -	// Remove # style comments -	$sql = preg_replace('/\n{2,}/', "\n", preg_replace('/^#.*$/m', "\n", $sql)); - -	// Return by reference -} - -/**  * Removes "/* style" as well as "# style" comments from $input.  *  * @param string $input		Input string @@ -493,17 +471,11 @@ function remove_remarks(&$sql)  */  function phpbb_remove_comments($input)  { -	if (!function_exists('remove_comments')) -	{ -		global $phpbb_root_path, $phpEx; -		require($phpbb_root_path . 'includes/functions_admin.' . $phpEx); -	} - -	// Remove /* */ comments -	remove_comments($input); +	// Remove /* */ comments (http://ostermiller.org/findcomment.html) +	$input = preg_replace('#/\*(.|[\r\n])*?\*/#', "\n", $input);  	// Remove # style comments -	remove_remarks($input); +	$input = preg_replace('/\n{2,}/', "\n", preg_replace('/^#.*$/m', "\n", $input));  	return $input;  } diff --git a/phpBB/includes/functions_posting.php b/phpBB/includes/functions_posting.php index c549f99091..6c21b0f412 100644 --- a/phpBB/includes/functions_posting.php +++ b/phpBB/includes/functions_posting.php @@ -61,10 +61,7 @@ function generate_smilies($mode, $forum_id)  			'body' => 'posting_smilies.html')  		); -		$template->assign_var('PAGINATION', -			generate_pagination(append_sid("{$phpbb_root_path}posting.$phpEx", 'mode=smilies&f=' . $forum_id), -				$smiley_count, $config['smilies_per_page'], $start, true) -		); +		generate_pagination(append_sid("{$phpbb_root_path}posting.$phpEx", 'mode=smilies&f=' . $forum_id), $smiley_count, $config['smilies_per_page'], $start);	  	}  	$display_link = false; diff --git a/phpBB/includes/functions_privmsgs.php b/phpBB/includes/functions_privmsgs.php index 8542e3ab0a..9e055a319f 100644 --- a/phpBB/includes/functions_privmsgs.php +++ b/phpBB/includes/functions_privmsgs.php @@ -1147,127 +1147,166 @@ function phpbb_delete_user_pms($user_id)  	// Get PM Information for later deleting  	// The two queries where split, so we can use our indexes +	$undelivered_msg = $delete_ids = array(); +  	// Part 1: get PMs the user received -	$sql = 'SELECT msg_id, author_id, folder_id, pm_unread, pm_new +	$sql = 'SELECT msg_id  		FROM ' . PRIVMSGS_TO_TABLE . '  		WHERE user_id = ' . $user_id;  	$result = $db->sql_query($sql); -	$undelivered_msg = $undelivered_user = $delete_ids = array();  	while ($row = $db->sql_fetchrow($result))  	{ -		if ($row['author_id'] == $user_id && $row['folder_id'] == PRIVMSGS_NO_BOX) -		{ -			// Undelivered messages -			$undelivered_msg[] = $row['msg_id']; - -			if (isset($undelivered_user[$row['user_id']])) -			{ -				++$undelivered_user[$row['user_id']]; -			} -			else -			{ -				$undelivered_user[$row['user_id']] = 1; -			} -		} - -		$delete_ids[(int) $row['msg_id']] = (int) $row['msg_id']; +		$msg_id = (int) $row['msg_id']; +		$delete_ids[$msg_id] = $msg_id;  	}  	$db->sql_freeresult($result); -	// Part 2: get PMs the user sent -	$sql = 'SELECT msg_id, author_id, folder_id, pm_unread, pm_new +	// Part 2: get PMs the user sent, but have yet to be received +	// We cannot simply delete them. First we have to check, +	// whether another user already received and read the message. +	$sql = 'SELECT msg_id  		FROM ' . PRIVMSGS_TO_TABLE . '  		WHERE author_id = ' . $user_id . ' -				AND folder_id = ' . PRIVMSGS_NO_BOX; +			AND folder_id = ' . PRIVMSGS_NO_BOX;  	$result = $db->sql_query($sql);  	while ($row = $db->sql_fetchrow($result))  	{ -		if ($row['author_id'] == $user_id && $row['folder_id'] == PRIVMSGS_NO_BOX) -		{ -			// Undelivered messages -			$undelivered_msg[] = $row['msg_id']; - -			if (isset($undelivered_user[$row['user_id']])) -			{ -				++$undelivered_user[$row['user_id']]; -			} -			else -			{ -				$undelivered_user[$row['user_id']] = 1; -			} -		} - -		$delete_ids[(int) $row['msg_id']] = (int) $row['msg_id']; +		$msg_id = (int) $row['msg_id']; +		$undelivered_msg[$msg_id] = $msg_id;  	}  	$db->sql_freeresult($result); -	if (empty($delete_ids)) +	if (empty($delete_ids) && empty($undelivered_msg))  	{  		return false;  	}  	$db->sql_transaction('begin'); -	if (sizeof($undelivered_msg)) -	{ -		$sql = 'DELETE FROM ' . PRIVMSGS_TABLE . ' -			WHERE ' . $db->sql_in_set('msg_id', $undelivered_msg); -		$db->sql_query($sql); -	} +	if (!empty($undelivered_msg)) +	{ +		// A pm is delivered, if for any recipient the message was moved +		// from their NO_BOX to another folder. We do not delete such +		// messages, but only delete them for users, who have not yet +		// received them. +		$sql = 'SELECT msg_id +			FROM ' . PRIVMSGS_TO_TABLE . ' +			WHERE author_id = ' . $user_id . ' +				AND folder_id <> ' . PRIVMSGS_NO_BOX . ' +				AND folder_id <> ' . PRIVMSGS_OUTBOX . ' +				AND folder_id <> ' . PRIVMSGS_SENTBOX; +		$result = $db->sql_query($sql); -	// Reset the user´s pm count to 0 -	if (isset($undelivered_user[$user_id])) -	{ -		$sql = 'UPDATE ' . USERS_TABLE . ' -			SET user_new_privmsg = 0, -				user_unread_privmsg = 0 -			WHERE user_id = ' . $user_id; -		$db->sql_query($sql); -		unset($undelivered_user[$user_id]); -	} +		$delivered_msg = array(); +		while ($row = $db->sql_fetchrow($result)) +		{ +			$msg_id = (int) $row['msg_id']; +			$delivered_msg[$msg_id] = $msg_id; +			unset($undelivered_msg[$msg_id]); +		} +		$db->sql_freeresult($result); -	foreach ($undelivered_user as $_user_id => $count) -	{ -		$sql = 'UPDATE ' . USERS_TABLE . ' -			SET user_new_privmsg = user_new_privmsg - ' . $count . ', -				user_unread_privmsg = user_unread_privmsg - ' . $count . ' -			WHERE user_id = ' . $_user_id; -		$db->sql_query($sql); -	} +		$undelivered_user = array(); -	// Delete private message data -	$sql = 'DELETE FROM ' . PRIVMSGS_TO_TABLE . " -		WHERE user_id = $user_id -			AND " . $db->sql_in_set('msg_id', $delete_ids); -	$db->sql_query($sql); +		// Count the messages we delete, so we can correct the user pm data +		$sql = 'SELECT user_id, COUNT(msg_id) as num_undelivered_privmsgs +			FROM ' . PRIVMSGS_TO_TABLE . ' +			WHERE author_id = ' . $user_id . ' +				AND folder_id = ' . PRIVMSGS_NO_BOX . ' +					AND ' . $db->sql_in_set('msg_id', array_merge($undelivered_msg, $delivered_msg)) . ' +			GROUP BY user_id'; +		$result = $db->sql_query($sql); -	// Now we have to check which messages we can delete completely -	$sql = 'SELECT msg_id -		FROM ' . PRIVMSGS_TO_TABLE . ' -		WHERE ' . $db->sql_in_set('msg_id', $delete_ids); -	$result = $db->sql_query($sql); +		while ($row = $db->sql_fetchrow($result)) +		{ +			$num_pms = (int) $row['num_undelivered_privmsgs']; +			$undelivered_user[$num_pms][] = (int) $row['user_id']; -	while ($row = $db->sql_fetchrow($result)) -	{ -		unset($delete_ids[$row['msg_id']]); +			if (sizeof($undelivered_user[$num_pms]) > 50) +			{ +				// If there are too many users affected the query might get +				// too long, so we update the value for the first bunch here. +				$sql = 'UPDATE ' . USERS_TABLE . ' +					SET user_new_privmsg = user_new_privmsg - ' . $num_pms . ', +						user_unread_privmsg = user_unread_privmsg - ' . $num_pms . ' +					WHERE ' . $db->sql_in_set('user_id', $undelivered_user[$num_pms]); +				$db->sql_query($sql); +				unset($undelivered_user[$num_pms]); +			} +		} +		$db->sql_freeresult($result); + +		foreach ($undelivered_user as $num_pms => $undelivered_user_set) +		{ +			$sql = 'UPDATE ' . USERS_TABLE . ' +				SET user_new_privmsg = user_new_privmsg - ' . $num_pms . ', +					user_unread_privmsg = user_unread_privmsg - ' . $num_pms . ' +				WHERE ' . $db->sql_in_set('user_id', $undelivered_user_set); +			$db->sql_query($sql); +		} + +		if (!empty($delivered_msg)) +		{ +			$sql = 'DELETE FROM ' . PRIVMSGS_TO_TABLE . ' +				WHERE folder_id = ' . PRIVMSGS_NO_BOX . ' +					AND ' . $db->sql_in_set('msg_id', $delivered_msg); +			$db->sql_query($sql); +		} + +		if (!empty($undelivered_msg)) +		{ +			$sql = 'DELETE FROM ' . PRIVMSGS_TO_TABLE . ' +				WHERE ' . $db->sql_in_set('msg_id', $undelivered_msg); +			$db->sql_query($sql); + +			$sql = 'DELETE FROM ' . PRIVMSGS_TABLE . ' +				WHERE ' . $db->sql_in_set('msg_id', $undelivered_msg); +			$db->sql_query($sql); +		}  	} -	$db->sql_freeresult($result); + +	// Reset the user's pm count to 0 +	$sql = 'UPDATE ' . USERS_TABLE . ' +		SET user_new_privmsg = 0, +			user_unread_privmsg = 0 +		WHERE user_id = ' . $user_id; +	$db->sql_query($sql); + +	// Delete private message data of the user +	$sql = 'DELETE FROM ' . PRIVMSGS_TO_TABLE . ' +		WHERE user_id = ' . (int) $user_id; +	$db->sql_query($sql);  	if (!empty($delete_ids))  	{ -		// Check if there are any attachments we need to remove -		if (!function_exists('delete_attachments')) +		// Now we have to check which messages we can delete completely +		$sql = 'SELECT msg_id +			FROM ' . PRIVMSGS_TO_TABLE . ' +			WHERE ' . $db->sql_in_set('msg_id', $delete_ids); +		$result = $db->sql_query($sql); + +		while ($row = $db->sql_fetchrow($result))  		{ -			include($phpbb_root_path . 'includes/functions_admin.' . $phpEx); +			unset($delete_ids[$row['msg_id']]);  		} +		$db->sql_freeresult($result); -		delete_attachments('message', $delete_ids, false); +		if (!empty($delete_ids)) +		{ +			// Check if there are any attachments we need to remove +			if (!function_exists('delete_attachments')) +			{ +				include($phpbb_root_path . 'includes/functions_admin.' . $phpEx); +			} -		$sql = 'DELETE FROM ' . PRIVMSGS_TABLE . ' -			WHERE ' . $db->sql_in_set('msg_id', $delete_ids); -		$db->sql_query($sql); +			delete_attachments('message', $delete_ids, false); + +			$sql = 'DELETE FROM ' . PRIVMSGS_TABLE . ' +				WHERE ' . $db->sql_in_set('msg_id', $delete_ids); +			$db->sql_query($sql); +		}  	}  	// Set the remaining author id to anonymous @@ -2045,7 +2084,7 @@ function message_history($msg_id, $user_id, $message_row, $folder, $in_post_mode  			'SUBJECT'			=> $subject,  			'SENT_DATE'			=> $user->format_date($row['message_time']),  			'MESSAGE'			=> $message, -			'FOLDER'			=> implode(', ', $row['folder']), +			'FOLDER'			=> implode($user->lang['COMMA_SEPARATOR'], $row['folder']),  			'DECODED_MESSAGE'	=> $decoded_message,  			'S_CURRENT_MSG'		=> ($row['msg_id'] == $msg_id), diff --git a/phpBB/includes/functions_profile_fields.php b/phpBB/includes/functions_profile_fields.php index 3399334f94..10af997bff 100644 --- a/phpBB/includes/functions_profile_fields.php +++ b/phpBB/includes/functions_profile_fields.php @@ -121,7 +121,7 @@ class custom_profile  			case FIELD_BOOL:  				$field_value = (bool) $field_value; -			 +  				if (!$field_value && $field_data['field_required'])  				{  					return 'FIELD_REQUIRED'; @@ -133,7 +133,7 @@ class custom_profile  				{  					return false;  				} -				 +  				$field_value = (int) $field_value;  				if ($field_value < $field_data['field_minlen']) @@ -455,6 +455,8 @@ class custom_profile  			$user_fields = array(); +			$user_ids = $user_id; +  			// Go through the fields in correct order  			foreach (array_keys($this->profile_cache) as $used_ident)  			{ @@ -463,6 +465,15 @@ class custom_profile  					$user_fields[$user_id][$used_ident]['value'] = $row['pf_' . $used_ident];  					$user_fields[$user_id][$used_ident]['data'] = $this->profile_cache[$used_ident];  				} + +				foreach ($user_ids as $user_id) +				{ +					if (!isset($user_fields[$user_id][$used_ident]) && $this->profile_cache[$used_ident]['field_show_novalue']) +					{ +						$user_fields[$user_id][$used_ident]['value'] = ''; +						$user_fields[$user_id][$used_ident]['data'] = $this->profile_cache[$used_ident]; +					} +				}  			}  			return $user_fields; @@ -520,7 +531,7 @@ class custom_profile  		switch ($this->profile_types[$field_type])  		{  			case 'int': -				if ($value === '') +				if ($value === '' && !$ident_ary['data']['field_show_novalue'])  				{  					return NULL;  				} @@ -529,7 +540,7 @@ class custom_profile  			case 'string':  			case 'text': -				if (!$value) +				if (!$value && !$ident_ary['data']['field_show_novalue'])  				{  					return NULL;  				} @@ -547,16 +558,19 @@ class custom_profile  				$month = (isset($date[1])) ? (int) $date[1] : 0;  				$year = (isset($date[2])) ? (int) $date[2] : 0; -				if (!$day && !$month && !$year) +				if (!$day && !$month && !$year && !$ident_ary['data']['field_show_novalue'])  				{  					return NULL;  				}  				else if ($day && $month && $year)  				{  					global $user; -					// Date should display as the same date for every user regardless of timezone, so remove offset -					// to compensate for the offset added by phpbb_user::format_date() -					return $user->format_date(gmmktime(0, 0, 0, $month, $day, $year) - ($user->timezone + $user->dst), $user->lang['DATE_FORMAT'], true); +					// Date should display as the same date for every user regardless of timezone + +					return $user->create_datetime() +						->setDate($year, $month, $day) +						->setTime(0, 0, 0) +						->format($user->lang['DATE_FORMAT'], true);  				}  				return $value; @@ -570,12 +584,7 @@ class custom_profile  					$this->get_option_lang($field_id, $lang_id, FIELD_DROPDOWN, false);  				} -				// If a dropdown field is required, users -				// cannot choose the "no value" option. -				// They must choose one of the other options. -				// Therefore, here we treat a value equal to -				// the "no value" as a lack of value, i.e. NULL. -				if ($value == $ident_ary['data']['field_novalue'] && $ident_ary['data']['field_required']) +				if ($value == $ident_ary['data']['field_novalue'] && !$ident_ary['data']['field_show_novalue'])  				{  					return NULL;  				} @@ -585,7 +594,14 @@ class custom_profile  				// User not having a value assigned  				if (!isset($this->options_lang[$field_id][$lang_id][$value]))  				{ -					return NULL; +					if ($ident_ary['data']['field_show_novalue']) +					{ +						$value = $ident_ary['data']['field_novalue']; +					} +					else +					{ +						return NULL; +					}  				}  				return $this->options_lang[$field_id][$lang_id][$value]; @@ -599,6 +615,11 @@ class custom_profile  					$this->get_option_lang($field_id, $lang_id, FIELD_BOOL, false);  				} +				if (!$value && $ident_ary['data']['field_show_novalue']) +				{ +					$value = $ident_ary['data']['field_default_value']; +				} +  				if ($ident_ary['data']['field_length'] == 1)  				{  					return (isset($this->options_lang[$field_id][$lang_id][(int) $value])) ? $this->options_lang[$field_id][$lang_id][(int) $value] : NULL; diff --git a/phpBB/includes/functions_upload.php b/phpBB/includes/functions_upload.php index 33cb585b19..d4c6b42cf4 100644 --- a/phpBB/includes/functions_upload.php +++ b/phpBB/includes/functions_upload.php @@ -151,8 +151,7 @@ class filespec  	*/  	function is_image()  	{ -		$mimetype = $this->get_mimetype($this->filename); -		return (strpos($mimetype, 'image/') === 0); +		return (strpos($this->mimetype, 'image/') === 0);  	}  	/** @@ -201,12 +200,17 @@ class filespec  	}  	/** -	* Get mimetype. Utilises the finfo class. +	* Get mimetype. Utilize mime_content_type if the function exist. +	* Not used at the moment...  	*/  	function get_mimetype($filename)  	{ -		$finfo = new finfo(FILEINFO_MIME_TYPE); -		$mimetype = $finfo->file($filename); +		$mimetype = ''; + +		if (function_exists('mime_content_type')) +		{ +			$mimetype = mime_content_type($filename); +		}  		// Some browsers choke on a mimetype of application/octet-stream  		if (!$mimetype || $mimetype == 'application/octet-stream') @@ -338,7 +342,6 @@ class filespec  			// Remove temporary filename  			@unlink($this->filename); -			$this->filename = $this->destination_file;  			if (sizeof($this->error))  			{ diff --git a/phpBB/includes/functions_user.php b/phpBB/includes/functions_user.php index 9b102b7387..6e658b4ef4 100644 --- a/phpBB/includes/functions_user.php +++ b/phpBB/includes/functions_user.php @@ -197,7 +197,6 @@ function user_add($user_row, $cp_data = false)  		'user_lastpost_time'	=> 0,  		'user_lastpage'			=> '',  		'user_posts'			=> 0, -		'user_dst'				=> (int) $config['board_dst'],  		'user_colour'			=> '',  		'user_occ'				=> '',  		'user_interests'		=> '', @@ -677,8 +676,10 @@ function user_ban($mode, $ban, $ban_len, $ban_len_other, $ban_exclude, $ban_reas  			if (sizeof($ban_other) == 3 && ((int)$ban_other[0] < 9999) &&  				(strlen($ban_other[0]) == 4) && (strlen($ban_other[1]) == 2) && (strlen($ban_other[2]) == 2))  			{ -				$time_offset = (isset($user->timezone) && isset($user->dst)) ? (int) $user->timezone + (int) $user->dst : 0; -				$ban_end = max($current_time, gmmktime(0, 0, 0, (int)$ban_other[1], (int)$ban_other[2], (int)$ban_other[0]) - $time_offset); +				$ban_end = max($current_time, $user->create_datetime() +					->setDate((int) $ban_other[0], (int) $ban_other[1], (int) $ban_other[2]) +					->setTime(0, 0, 0) +					->getTimestamp() + $user->timezone->getOffset(new DateTime('UTC')));  			}  			else  			{ @@ -1247,10 +1248,21 @@ function validate_data($data, $val_ary)  			$function = array_shift($validate);  			array_unshift($validate, $data[$var]); -			if ($result = call_user_func_array('validate_' . $function, $validate)) +			if (function_exists('phpbb_validate_' . $function))  			{ -				// Since errors are checked later for their language file existence, we need to make sure custom errors are not adjusted. -				$error[] = (empty($user->lang[$result . '_' . strtoupper($var)])) ? $result : $result . '_' . strtoupper($var); +				if ($result = call_user_func_array('phpbb_validate_' . $function, $validate)) +				{ +					// Since errors are checked later for their language file existence, we need to make sure custom errors are not adjusted. +					$error[] = (empty($user->lang[$result . '_' . strtoupper($var)])) ? $result : $result . '_' . strtoupper($var); +				} +			} +			else +			{ +				if ($result = call_user_func_array('validate_' . $function, $validate)) +				{ +					// Since errors are checked later for their language file existence, we need to make sure custom errors are not adjusted. +					$error[] = (empty($user->lang[$result . '_' . strtoupper($var)])) ? $result : $result . '_' . strtoupper($var); +				}  			}  		}  	} @@ -1396,6 +1408,22 @@ function validate_language_iso_name($lang_iso)  }  /** +* Validate Timezone Name +* +* Tests whether a timezone name is valid +* +* @param string $timezone	The timezone string to test +* +* @return bool|string		Either false if validation succeeded or +*							a string which will be used as the error message +*							(with the variable name appended) +*/ +function phpbb_validate_timezone($timezone) +{ +	return (in_array($timezone, phpbb_get_timezone_identifiers($timezone))) ? false : 'TIMEZONE_INVALID'; +} + +/**  * Check to see if the username has been taken, or if it is disallowed.  * Also checks if it includes the " character, which we don't allow in usernames.  * Used for registering, changing names, and posting anonymously with a username diff --git a/phpBB/includes/mcp/mcp_forum.php b/phpBB/includes/mcp/mcp_forum.php index fec1edc872..4518e7b7cf 100644 --- a/phpBB/includes/mcp/mcp_forum.php +++ b/phpBB/includes/mcp/mcp_forum.php @@ -101,6 +101,9 @@ function mcp_forum_view($id, $mode, $action, $forum_info)  	$forum_topics = ($total == -1) ? $forum_info['forum_topics'] : $total;  	$limit_time_sql = ($sort_days) ? 'AND t.topic_last_post_time >= ' . (time() - ($sort_days * 86400)) : ''; +	$base_url = $url . "&i=$id&action=$action&mode=$mode&sd=$sort_dir&sk=$sort_key&st=$sort_days" . (($merge_select) ? $selected_ids : ''); +	phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $forum_topics, $topics_per_page, $start); +	  	$template->assign_vars(array(  		'ACTION'				=> $action,  		'FORUM_NAME'			=> $forum_info['forum_name'], @@ -129,8 +132,7 @@ function mcp_forum_view($id, $mode, $action, $forum_info)  		'S_MCP_ACTION'			=> $url . "&i=$id&forum_action=$action&mode=$mode&start=$start" . (($merge_select) ? $selected_ids : ''), -		'PAGINATION'			=> generate_pagination($url . "&i=$id&action=$action&mode=$mode&sd=$sort_dir&sk=$sort_key&st=$sort_days" . (($merge_select) ? $selected_ids : ''), $forum_topics, $topics_per_page, $start), -		'PAGE_NUMBER'			=> on_page($forum_topics, $topics_per_page, $start), +		'PAGE_NUMBER'			=> phpbb_on_page($template, $user, $base_url, $forum_topics, $topics_per_page, $start),  		'TOTAL_TOPICS'			=> $user->lang('VIEW_FORUM_TOPICS', (int) $forum_topics),  	)); diff --git a/phpBB/includes/mcp/mcp_logs.php b/phpBB/includes/mcp/mcp_logs.php index 848bad40a3..c1724b20d9 100644 --- a/phpBB/includes/mcp/mcp_logs.php +++ b/phpBB/includes/mcp/mcp_logs.php @@ -171,10 +171,12 @@ class mcp_logs  		$log_count = 0;  		$start = view_log('mod', $log_data, $log_count, $config['topics_per_page'], $start, $forum_list, $topic_id, 0, $sql_where, $sql_sort, $keywords); +		$base_url = $this->u_action . "&$u_sort_param$keywords_param"; +		phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $log_count, $config['topics_per_page'], $start);		 +		  		$template->assign_vars(array( -			'PAGE_NUMBER'		=> on_page($log_count, $config['topics_per_page'], $start), +			'PAGE_NUMBER'		=> phpbb_on_page($template, $user, $base_url, $log_count, $config['topics_per_page'], $start),  			'TOTAL'				=> $user->lang('TOTAL_LOGS', (int) $log_count), -			'PAGINATION'		=> generate_pagination($this->u_action . "&$u_sort_param$keywords_param", $log_count, $config['topics_per_page'], $start),  			'L_TITLE'			=> $user->lang['MCP_LOGS'], diff --git a/phpBB/includes/mcp/mcp_notes.php b/phpBB/includes/mcp/mcp_notes.php index 99dbb8d86d..bbf618ebef 100644 --- a/phpBB/includes/mcp/mcp_notes.php +++ b/phpBB/includes/mcp/mcp_notes.php @@ -215,6 +215,9 @@ class mcp_notes  			}  		} +		$base_url = $this->u_action . "&$u_sort_param$keywords_param"; +		phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $log_count, $config['topics_per_page'], $start); +		  		$template->assign_vars(array(  			'U_POST_ACTION'			=> $this->u_action,  			'S_CLEAR_ALLOWED'		=> ($auth->acl_get('a_clearlogs')) ? true : false, @@ -225,8 +228,7 @@ class mcp_notes  			'L_TITLE'			=> $user->lang['MCP_NOTES_USER'], -			'PAGE_NUMBER'		=> on_page($log_count, $config['topics_per_page'], $start), -			'PAGINATION'		=> generate_pagination($this->u_action . "&$u_sort_param$keywords_param", $log_count, $config['topics_per_page'], $start), +			'PAGE_NUMBER'		=> phpbb_on_page($template, $user, $base_url, $log_count, $config['topics_per_page'], $start),  			'TOTAL_REPORTS'		=> $user->lang('LIST_REPORTS', (int) $log_count),  			'RANK_TITLE'		=> $rank_title, diff --git a/phpBB/includes/mcp/mcp_pm_reports.php b/phpBB/includes/mcp/mcp_pm_reports.php index d242929a80..24e531517c 100644 --- a/phpBB/includes/mcp/mcp_pm_reports.php +++ b/phpBB/includes/mcp/mcp_pm_reports.php @@ -291,13 +291,16 @@ class mcp_pm_reports  								'REPORT_ID'				=> $row['report_id'],  								'REPORT_TIME'			=> $user->format_date($row['report_time']), -								'RECIPIENTS'			=> implode(', ', $address_list[$row['msg_id']]), +								'RECIPIENTS'			=> implode($user->lang['COMMA_SEPARATOR'], $address_list[$row['msg_id']]),  								'ATTACH_ICON_IMG'		=> ($auth->acl_get('u_download') && $row['message_attachment']) ? $user->img('icon_topic_attach', $user->lang['TOTAL_ATTACHMENTS']) : '',  							));  						}  					}  				} - +				 +				$base_url = $this->u_action . "&st=$sort_days&sk=$sort_key&sd=$sort_dir"; +				phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $total, $config['topics_per_page'], $start); +				  				// Now display the page  				$template->assign_vars(array(  					'L_EXPLAIN'				=> ($mode == 'pm_reports') ? $user->lang['MCP_PM_REPORTS_OPEN_EXPLAIN'] : $user->lang['MCP_PM_REPORTS_CLOSED_EXPLAIN'], @@ -307,8 +310,7 @@ class mcp_pm_reports  					'S_MCP_ACTION'			=> $this->u_action,  					'S_CLOSED'				=> ($mode == 'pm_reports_closed') ? true : false, -					'PAGINATION'			=> generate_pagination($this->u_action . "&st=$sort_days&sk=$sort_key&sd=$sort_dir", $total, $config['topics_per_page'], $start), -					'PAGE_NUMBER'			=> on_page($total, $config['topics_per_page'], $start), +					'PAGE_NUMBER'			=> phpbb_on_page($template, $user, $base_url, $total, $config['topics_per_page'], $start),  					'TOTAL'					=> $total,  					'TOTAL_REPORTS'			=> $user->lang('LIST_REPORTS', (int) $total),  					) diff --git a/phpBB/includes/mcp/mcp_queue.php b/phpBB/includes/mcp/mcp_queue.php index 4d720a435c..b44685b8a3 100644 --- a/phpBB/includes/mcp/mcp_queue.php +++ b/phpBB/includes/mcp/mcp_queue.php @@ -419,6 +419,9 @@ class mcp_queue  				}  				unset($rowset, $forum_names); +				$base_url = $this->u_action . "&f=$forum_id&st=$sort_days&sk=$sort_key&sd=$sort_dir"; +				phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $total, $config['topics_per_page'], $start); +				  				// Now display the page  				$template->assign_vars(array(  					'L_DISPLAY_ITEMS'		=> ($mode == 'unapproved_posts') ? $user->lang['DISPLAY_POSTS'] : $user->lang['DISPLAY_TOPICS'], @@ -430,8 +433,7 @@ class mcp_queue  					'S_MCP_ACTION'			=> build_url(array('t', 'f', 'sd', 'st', 'sk')),  					'S_TOPICS'				=> ($mode == 'unapproved_posts') ? false : true, -					'PAGINATION'			=> generate_pagination($this->u_action . "&f=$forum_id&st=$sort_days&sk=$sort_key&sd=$sort_dir", $total, $config['topics_per_page'], $start), -					'PAGE_NUMBER'			=> on_page($total, $config['topics_per_page'], $start), +					'PAGE_NUMBER'			=> phpbb_on_page($template, $user, $base_url, $total, $config['topics_per_page'], $start),  					'TOPIC_ID'				=> $topic_id,  					'TOTAL'					=> $user->lang((($mode == 'unapproved_posts') ? 'VIEW_TOPIC_POSTS' : 'VIEW_FORUM_TOPICS'), (int) $total),  				)); diff --git a/phpBB/includes/mcp/mcp_reports.php b/phpBB/includes/mcp/mcp_reports.php index 69c6a4cfff..2890cd56e2 100644 --- a/phpBB/includes/mcp/mcp_reports.php +++ b/phpBB/includes/mcp/mcp_reports.php @@ -411,6 +411,9 @@ class mcp_reports  					unset($report_ids, $row);  				} +				$base_url = $this->u_action . "&f=$forum_id&t=$topic_id&st=$sort_days&sk=$sort_key&sd=$sort_dir"; +				phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $total, $config['topics_per_page'], $start); +				  				// Now display the page  				$template->assign_vars(array(  					'L_EXPLAIN'				=> ($mode == 'reports') ? $user->lang['MCP_REPORTS_OPEN_EXPLAIN'] : $user->lang['MCP_REPORTS_CLOSED_EXPLAIN'], @@ -421,8 +424,7 @@ class mcp_reports  					'S_FORUM_OPTIONS'		=> $forum_options,  					'S_CLOSED'				=> ($mode == 'reports_closed') ? true : false, -					'PAGINATION'			=> generate_pagination($this->u_action . "&f=$forum_id&t=$topic_id&st=$sort_days&sk=$sort_key&sd=$sort_dir", $total, $config['topics_per_page'], $start), -					'PAGE_NUMBER'			=> on_page($total, $config['topics_per_page'], $start), +					'PAGE_NUMBER'			=> phpbb_on_page($template, $user, $base_url, $total, $config['topics_per_page'], $start),  					'TOPIC_ID'				=> $topic_id,  					'TOTAL'					=> $total,  					'TOTAL_REPORTS'			=> $user->lang('LIST_REPORTS', (int) $total), diff --git a/phpBB/includes/mcp/mcp_topic.php b/phpBB/includes/mcp/mcp_topic.php index d4ba89b04c..e39e553ab6 100644 --- a/phpBB/includes/mcp/mcp_topic.php +++ b/phpBB/includes/mcp/mcp_topic.php @@ -306,6 +306,12 @@ function mcp_topic_view($id, $mode, $action)  		'post_ids'	=> $post_id_list,  	)); +	$base_url = append_sid("{$phpbb_root_path}mcp.$phpEx", "i=$id&t={$topic_info['topic_id']}&mode=$mode&action=$action&to_topic_id=$to_topic_id&posts_per_page=$posts_per_page&st=$sort_days&sk=$sort_key&sd=$sort_dir"); +	if ($posts_per_page) +	{ +		phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $total, $posts_per_page, $start); +	} +	  	$template->assign_vars(array(  		'TOPIC_TITLE'		=> $topic_info['topic_title'],  		'U_VIEW_TOPIC'		=> append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'f=' . $topic_info['forum_id'] . '&t=' . $topic_info['topic_id']), @@ -344,8 +350,7 @@ function mcp_topic_view($id, $mode, $action)  		'RETURN_TOPIC'		=> sprintf($user->lang['RETURN_TOPIC'], '<a href="' . append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f={$topic_info['forum_id']}&t={$topic_info['topic_id']}&start=$start") . '">', '</a>'),  		'RETURN_FORUM'		=> sprintf($user->lang['RETURN_FORUM'], '<a href="' . append_sid("{$phpbb_root_path}viewforum.$phpEx", "f={$topic_info['forum_id']}&start=$start") . '">', '</a>'), -		'PAGE_NUMBER'		=> on_page($total, $posts_per_page, $start), -		'PAGINATION'		=> (!$posts_per_page) ? '' : generate_pagination(append_sid("{$phpbb_root_path}mcp.$phpEx", "i=$id&t={$topic_info['topic_id']}&mode=$mode&action=$action&to_topic_id=$to_topic_id&posts_per_page=$posts_per_page&st=$sort_days&sk=$sort_key&sd=$sort_dir"), $total, $posts_per_page, $start), +		'PAGE_NUMBER'		=> phpbb_on_page($template, $user, $base_url, $total, $posts_per_page, $start),  		'TOTAL_POSTS'		=> $user->lang('VIEW_TOPIC_POSTS', (int) $total),  	));  } diff --git a/phpBB/includes/mcp/mcp_warn.php b/phpBB/includes/mcp/mcp_warn.php index c614beea3b..aefddb7c01 100644 --- a/phpBB/includes/mcp/mcp_warn.php +++ b/phpBB/includes/mcp/mcp_warn.php @@ -175,6 +175,9 @@ class mcp_warn  			));  		} +		$base_url = append_sid("{$phpbb_root_path}mcp.$phpEx", "i=warn&mode=list&st=$st&sk=$sk&sd=$sd"); +		phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $user_count, $config['topics_per_page'], $start); +		  		$template->assign_vars(array(  			'U_POST_ACTION'			=> $this->u_action,  			'S_CLEAR_ALLOWED'		=> ($auth->acl_get('a_clearlogs')) ? true : false, @@ -182,8 +185,7 @@ class mcp_warn  			'S_SELECT_SORT_KEY'		=> $s_sort_key,  			'S_SELECT_SORT_DAYS'	=> $s_limit_days, -			'PAGE_NUMBER'		=> on_page($user_count, $config['topics_per_page'], $start), -			'PAGINATION'		=> generate_pagination(append_sid("{$phpbb_root_path}mcp.$phpEx", "i=warn&mode=list&st=$st&sk=$sk&sd=$sd"), $user_count, $config['topics_per_page'], $start), +			'PAGE_NUMBER'		=> phpbb_on_page($template, $user, $base_url, $user_count, $config['topics_per_page'], $start),  			'TOTAL_USERS'		=> $user->lang('LIST_USERS', (int) $user_count),  		));  	} diff --git a/phpBB/includes/questionnaire/questionnaire.php b/phpBB/includes/questionnaire/questionnaire.php index 46a743d7e9..5cb441d536 100644 --- a/phpBB/includes/questionnaire/questionnaire.php +++ b/phpBB/includes/questionnaire/questionnaire.php @@ -304,7 +304,6 @@ class phpbb_questionnaire_phpbb_data_provider  			'avatar_max_width' => true,  			'avatar_min_height' => true,  			'avatar_min_width' => true, -			'board_dst' => true,  			'board_email_form' => true,  			'board_hide_emails' => true,  			'board_timezone' => true, diff --git a/phpBB/includes/search/fulltext_native.php b/phpBB/includes/search/fulltext_native.php index 3e029c86d0..1e2074b1b1 100644 --- a/phpBB/includes/search/fulltext_native.php +++ b/phpBB/includes/search/fulltext_native.php @@ -334,7 +334,7 @@ class phpbb_search_fulltext_native extends phpbb_search_base  				// throw an error if we shall not ignore unexistant words  				else if (!$ignore_no_id && sizeof($non_common_words))  				{ -					trigger_error(sprintf($user->lang['WORDS_IN_NO_POST'], implode(', ', $non_common_words))); +					trigger_error(sprintf($user->lang['WORDS_IN_NO_POST'], implode($user->lang['COMMA_SEPARATOR'], $non_common_words)));  				}  				unset($non_common_words);  			} diff --git a/phpBB/includes/style/style.php b/phpBB/includes/style/style.php index 22e0f1d67a..6b7cd31cb3 100644 --- a/phpBB/includes/style/style.php +++ b/phpBB/includes/style/style.php @@ -38,7 +38,7 @@ class phpbb_style  	* PHP file extension  	* @var string  	*/ -	private $phpEx; +	private $php_ext;  	/**  	* phpBB config instance @@ -73,10 +73,10 @@ class phpbb_style  	* @param phpbb_style_path_provider $provider style path provider  	* @param phpbb_template $template template  	*/ -	public function __construct($phpbb_root_path, $phpEx, $config, $user, phpbb_style_resource_locator $locator, phpbb_style_path_provider_interface $provider, phpbb_template $template) +	public function __construct($phpbb_root_path, $php_ext, $config, $user, phpbb_style_resource_locator $locator, phpbb_style_path_provider_interface $provider, phpbb_template $template)  	{  		$this->phpbb_root_path = $phpbb_root_path; -		$this->phpEx = $phpEx; +		$this->php_ext = $php_ext;  		$this->config = $config;  		$this->user = $user;  		$this->locator = $locator; diff --git a/phpBB/includes/template/template.php b/phpBB/includes/template/template.php index 8ab3c44be3..13fa845659 100644 --- a/phpBB/includes/template/template.php +++ b/phpBB/includes/template/template.php @@ -54,7 +54,7 @@ class phpbb_template  	* PHP file extension  	* @var string  	*/ -	private $phpEx; +	private $php_ext;  	/**  	* phpBB config instance @@ -87,10 +87,10 @@ class phpbb_template  	* @param user $user current user  	* @param phpbb_template_locator $locator template locator  	*/ -	public function __construct($phpbb_root_path, $phpEx, $config, $user, phpbb_template_locator $locator) +	public function __construct($phpbb_root_path, $php_ext, $config, $user, phpbb_template_locator $locator)  	{  		$this->phpbb_root_path = $phpbb_root_path; -		$this->phpEx = $phpEx; +		$this->php_ext = $php_ext;  		$this->config = $config;  		$this->user = $user;  		$this->locator = $locator; @@ -313,7 +313,7 @@ class phpbb_template  	private function _compiled_file_for_handle($handle)  	{  		$source_file = $this->locator->get_filename_for_handle($handle); -		$compiled_file = $this->cachepath . str_replace('/', '.', $source_file) . '.' . $this->phpEx; +		$compiled_file = $this->cachepath . str_replace('/', '.', $source_file) . '.' . $this->php_ext;  		return $compiled_file;  	} diff --git a/phpBB/includes/ucp/ucp_attachments.php b/phpBB/includes/ucp/ucp_attachments.php index 836185f105..e4c351709b 100644 --- a/phpBB/includes/ucp/ucp_attachments.php +++ b/phpBB/includes/ucp/ucp_attachments.php @@ -170,9 +170,11 @@ class ucp_attachments  		}  		$db->sql_freeresult($result); +		$base_url = $this->u_action . "&sk=$sort_key&sd=$sort_dir"; +		phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $num_attachments, $config['topics_per_page'], $start);		 +		  		$template->assign_vars(array( -			'PAGE_NUMBER'			=> on_page($num_attachments, $config['topics_per_page'], $start), -			'PAGINATION'			=> generate_pagination($this->u_action . "&sk=$sort_key&sd=$sort_dir", $num_attachments, $config['topics_per_page'], $start), +			'PAGE_NUMBER'			=> phpbb_on_page($template, $user, $base_url, $num_attachments, $config['topics_per_page'], $start),  			'TOTAL_ATTACHMENTS'		=> $num_attachments,  			'L_TITLE'				=> $user->lang['UCP_ATTACHMENTS'], diff --git a/phpBB/includes/ucp/ucp_groups.php b/phpBB/includes/ucp/ucp_groups.php index a7c6479759..65ab92e78e 100644 --- a/phpBB/includes/ucp/ucp_groups.php +++ b/phpBB/includes/ucp/ucp_groups.php @@ -844,11 +844,13 @@ class ucp_groups  							$s_action_options .= '<option value="' . $option . '">' . $user->lang['GROUP_' . $lang] . '</option>';  						} +						$base_url = $this->u_action . "&action=$action&g=$group_id"; +						phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $total_members, $config['topics_per_page'], $start); +  						$template->assign_vars(array(  							'S_LIST'			=> true,  							'S_ACTION_OPTIONS'	=> $s_action_options, -							'S_ON_PAGE'			=> on_page($total_members, $config['topics_per_page'], $start), -							'PAGINATION'		=> generate_pagination($this->u_action . "&action=$action&g=$group_id", $total_members, $config['topics_per_page'], $start), +							'S_ON_PAGE'			=> phpbb_on_page($template, $user, $base_url, $total_members, $config['topics_per_page'], $start),  							'U_ACTION'			=> $this->u_action . "&g=$group_id",  							'S_UCP_ACTION'		=> $this->u_action . "&g=$group_id", @@ -1067,7 +1069,8 @@ class ucp_groups  								'mode'		=> $mode,  								'action'	=> $action  							); -							confirm_box(false, $user->lang('GROUP_CONFIRM_ADD_USERS', sizeof($name_ary), implode(', ', $name_ary)), build_hidden_fields($s_hidden_fields)); + +							confirm_box(false, $user->lang('GROUP_CONFIRM_ADD_USERS', sizeof($name_ary), implode($user->lang['COMMA_SEPARATOR'], $name_ary)), build_hidden_fields($s_hidden_fields));  						}  						trigger_error($user->lang['NO_USERS_ADDED'] . '<br /><br />' . sprintf($user->lang['RETURN_PAGE'], '<a href="' . $this->u_action . '&action=list&g=' . $group_id . '">', '</a>')); diff --git a/phpBB/includes/ucp/ucp_main.php b/phpBB/includes/ucp/ucp_main.php index 00b7b55f27..f21ea2471b 100644 --- a/phpBB/includes/ucp/ucp_main.php +++ b/phpBB/includes/ucp/ucp_main.php @@ -670,9 +670,10 @@ class ucp_main  		if ($topics_count)  		{ +			phpbb_generate_template_pagination($template, $this->u_action, 'pagination', 'start', $topics_count, $config['topics_per_page'], $start); +		  			$template->assign_vars(array( -				'PAGINATION'	=> generate_pagination($this->u_action, $topics_count, $config['topics_per_page'], $start), -				'PAGE_NUMBER'	=> on_page($topics_count, $config['topics_per_page'], $start), +				'PAGE_NUMBER'	=> phpbb_on_page($template, $user, $this->u_action, $topics_count, $config['topics_per_page'], $start),  				'TOTAL_TOPICS'	=> $user->lang('VIEW_FORUM_TOPICS', (int) $topics_count),  			));  		} @@ -813,7 +814,6 @@ class ucp_main  				'S_DELETED_TOPIC'	=> (!$row['topic_id']) ? true : false, -				'PAGINATION'		=> topic_generate_pagination($replies, append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'f=' . $row['forum_id'] . "&t=$topic_id")),  				'REPLIES'			=> $replies,  				'VIEWS'				=> $row['topic_views'],  				'TOPIC_TITLE'		=> censor_text($row['topic_title']), @@ -837,6 +837,8 @@ class ucp_main  				'U_VIEW_TOPIC'			=> $view_topic_url,  				'U_VIEW_FORUM'			=> append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $forum_id),  			)); +			 +			phpbb_generate_template_pagination($template, append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'f=' . $row['forum_id'] . "&t=$topic_id"), 'topicrow.pagination', 'start', $replies + 1, $config['posts_per_page'], 1, true, true);  		}  	}  } diff --git a/phpBB/includes/ucp/ucp_pm_compose.php b/phpBB/includes/ucp/ucp_pm_compose.php index 1b474457b3..d8bcd374fe 100644 --- a/phpBB/includes/ucp/ucp_pm_compose.php +++ b/phpBB/includes/ucp/ucp_pm_compose.php @@ -874,7 +874,7 @@ function compose_pm($id, $mode, $action, $user_folders = array())  		$forward_text[] = sprintf($user->lang['FWD_SUBJECT'], censor_text($message_subject));  		$forward_text[] = sprintf($user->lang['FWD_DATE'], $user->format_date($message_time, false, true));  		$forward_text[] = sprintf($user->lang['FWD_FROM'], $quote_username_text); -		$forward_text[] = sprintf($user->lang['FWD_TO'], implode(', ', $fwd_to_field['to'])); +		$forward_text[] = sprintf($user->lang['FWD_TO'], implode($user->lang['COMMA_SEPARATOR'], $fwd_to_field['to']));  		$message_parser->message = implode("\n", $forward_text) . "\n\n[quote="{$quote_username}"]\n" . censor_text(trim($message_parser->message)) . "\n[/quote]";  		$message_subject = ((!preg_match('/^Fwd:/', $message_subject)) ? 'Fwd: ' : '') . censor_text($message_subject); diff --git a/phpBB/includes/ucp/ucp_pm_viewfolder.php b/phpBB/includes/ucp/ucp_pm_viewfolder.php index 8b1cd419f4..1026f24699 100644 --- a/phpBB/includes/ucp/ucp_pm_viewfolder.php +++ b/phpBB/includes/ucp/ucp_pm_viewfolder.php @@ -176,7 +176,7 @@ function view_folder($id, $mode, $folder_id, $folder)  					'U_VIEW_PM'			=> ($row['pm_deleted']) ? '' : $view_message_url,  					'U_REMOVE_PM'		=> ($row['pm_deleted']) ? $remove_message_url : '',  					'U_MCP_REPORT'		=> (isset($row['report_id'])) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=pm_reports&mode=pm_report_details&r=' . $row['report_id']) : '', -					'RECIPIENTS'		=> ($folder_id == PRIVMSGS_OUTBOX || $folder_id == PRIVMSGS_SENTBOX) ? implode(', ', $address_list[$message_id]) : '') +					'RECIPIENTS'		=> ($folder_id == PRIVMSGS_OUTBOX || $folder_id == PRIVMSGS_SENTBOX) ? implode($user->lang['COMMA_SEPARATOR'], $address_list[$message_id]) : '')  				);  			}  			unset($folder_info['rowset']); @@ -266,9 +266,9 @@ function view_folder($id, $mode, $folder_id, $folder)  					}  				} -				// There is the chance that all recipients of the message got deleted. To avoid creating  +				// There is the chance that all recipients of the message got deleted. To avoid creating  				// exports without recipients, we add a bogus "undisclosed recipient". -				if (!(isset($address[$message_id]['g']) && sizeof($address[$message_id]['g'])) &&  +				if (!(isset($address[$message_id]['g']) && sizeof($address[$message_id]['g'])) &&  				    !(isset($address[$message_id]['u']) && sizeof($address[$message_id]['u'])))  				{  					$address[$message_id]['u'] = array(); @@ -277,7 +277,7 @@ function view_folder($id, $mode, $folder_id, $folder)  				}  				decode_message($message_row['message_text'], $message_row['bbcode_uid']); -				 +  				$data[] = array(  					'subject'	=> censor_text($row['message_subject']),  					'sender'	=> $row['username'], @@ -451,9 +451,11 @@ function get_pm_from($folder_id, $folder, $user_id)  		$sql_limit_time = '';  	} +	$base_url = append_sid("{$phpbb_root_path}ucp.$phpEx", "i=pm&mode=view&action=view_folder&f=$folder_id&$u_sort_param"); +	phpbb_generate_template_pagination($template, $base_url, 'pagination', 'start', $pm_count, $config['topics_per_page'], $start); +	  	$template->assign_vars(array( -		'PAGINATION'		=> generate_pagination(append_sid("{$phpbb_root_path}ucp.$phpEx", "i=pm&mode=view&action=view_folder&f=$folder_id&$u_sort_param"), $pm_count, $config['topics_per_page'], $start), -		'PAGE_NUMBER'		=> on_page($pm_count, $config['topics_per_page'], $start), +		'PAGE_NUMBER'		=> phpbb_on_page($template, $user, $base_url, $pm_count, $config['topics_per_page'], $start),  		'TOTAL_MESSAGES'	=> $user->lang('VIEW_PM_MESSAGES', (int) $pm_count),  		'POST_IMG'		=> (!$auth->acl_get('u_sendpm')) ? $user->img('button_topic_locked', 'POST_PM_LOCKED') : $user->img('button_pm_new', 'POST_NEW_PM'), diff --git a/phpBB/includes/ucp/ucp_prefs.php b/phpBB/includes/ucp/ucp_prefs.php index 0c9f20f266..2228bc7931 100644 --- a/phpBB/includes/ucp/ucp_prefs.php +++ b/phpBB/includes/ucp/ucp_prefs.php @@ -41,9 +41,8 @@ class ucp_prefs  					'dateformat'	=> request_var('dateformat', $user->data['user_dateformat'], true),  					'lang'			=> basename(request_var('lang', $user->data['user_lang'])),  					'style'			=> request_var('style', (int) $user->data['user_style']), -					'tz'			=> request_var('tz', (float) $user->data['user_timezone']), +					'tz'			=> request_var('tz', $user->data['user_timezone']), -					'dst'			=> request_var('dst', (bool) $user->data['user_dst']),  					'viewemail'		=> request_var('viewemail', (bool) $user->data['user_allow_viewemail']),  					'massemail'		=> request_var('massemail', (bool) $user->data['user_allow_massemail']),  					'hideonline'	=> request_var('hideonline', (bool) !$user->data['user_allow_viewonline']), @@ -72,7 +71,7 @@ class ucp_prefs  					$error = validate_data($data, array(  						'dateformat'	=> array('string', false, 1, 30),  						'lang'			=> array('language_iso_name'), -						'tz'			=> array('num', false, -14, 14), +						'tz'			=> array('timezone'),  					));  					if (!check_form_key('ucp_prefs_personal')) @@ -93,7 +92,6 @@ class ucp_prefs  							'user_notify_pm'		=> $data['notifypm'],  							'user_options'			=> $user->data['user_options'], -							'user_dst'				=> $data['dst'],  							'user_dateformat'		=> $data['dateformat'],  							'user_lang'				=> $data['lang'],  							'user_timezone'			=> $data['tz'], @@ -133,6 +131,7 @@ class ucp_prefs  				}  				$dateformat_options .= '>' . $user->lang['CUSTOM_DATEFORMAT'] . '</option>'; +				$timezone_selects = phpbb_timezone_select($user, $data['tz'], true);  				$template->assign_vars(array(  					'ERROR'				=> (sizeof($error)) ? implode('<br />', $error) : '', @@ -145,7 +144,6 @@ class ucp_prefs  					'S_HIDE_ONLINE'		=> $data['hideonline'],  					'S_NOTIFY_PM'		=> $data['notifypm'],  					'S_POPUP_PM'		=> $data['popuppm'], -					'S_DST'				=> $data['dst'],  					'DATE_FORMAT'			=> $data['dateformat'],  					'A_DATE_FORMAT'			=> addslashes($data['dateformat']), @@ -156,7 +154,8 @@ class ucp_prefs  					'S_LANG_OPTIONS'		=> language_select($data['lang']),  					'S_STYLE_OPTIONS'		=> ($config['override_user_style']) ? '' : style_select($data['style']), -					'S_TZ_OPTIONS'			=> tz_select($data['tz'], true), +					'S_TZ_OPTIONS'			=> $timezone_selects['tz_select'], +					'S_TZ_DATE_OPTIONS'		=> $timezone_selects['tz_dates'],  					'S_CAN_HIDE_ONLINE'		=> ($auth->acl_get('u_hideonline')) ? true : false,  					'S_SELECT_NOTIFY'		=> ($config['jab_enable'] && $user->data['user_jabber'] && @extension_loaded('xml')) ? true : false)  				); diff --git a/phpBB/includes/ucp/ucp_register.php b/phpBB/includes/ucp/ucp_register.php index 5d85029e62..6ce53a79ab 100644 --- a/phpBB/includes/ucp/ucp_register.php +++ b/phpBB/includes/ucp/ucp_register.php @@ -100,7 +100,7 @@ class ucp_register  					'username'			=> utf8_normalize_nfc(request_var('username', '', true)),  					'email'				=> strtolower(request_var('email', '')),  					'lang'				=> $user->lang_name, -					'tz'				=> request_var('tz', (float) $config['board_timezone']), +					'tz'				=> request_var('tz', $config['board_timezone']),  				));  			} @@ -120,7 +120,10 @@ class ucp_register  			if ($coppa === false && $config['coppa_enable'])  			{  				$now = getdate(); -				$coppa_birthday = $user->format_date(mktime($now['hours'] + $user->data['user_dst'], $now['minutes'], $now['seconds'], $now['mon'], $now['mday'] - 1, $now['year'] - 13), $user->lang['DATE_FORMAT']); +				$coppa_birthday = $user->create_datetime() +					->setDate($now['year'] - 13, $now['mon'], $now['mday'] - 1) +					->setTime(0, 0, 0) +					->format($user->lang['DATE_FORMAT'], true);  				unset($now);  				$template->assign_vars(array( @@ -163,7 +166,6 @@ class ucp_register  			$captcha->init(CONFIRM_REG);  		} -		$is_dst = $config['board_dst'];  		$timezone = $config['board_timezone'];  		$data = array( @@ -172,7 +174,7 @@ class ucp_register  			'password_confirm'	=> request_var('password_confirm', '', true),  			'email'				=> strtolower(request_var('email', '')),  			'lang'				=> basename(request_var('lang', $user->lang_name)), -			'tz'				=> request_var('tz', (float) $timezone), +			'tz'				=> request_var('tz', $timezone),  		);  		// Check and initialize some variables if needed @@ -189,7 +191,7 @@ class ucp_register  				'email'				=> array(  					array('string', false, 6, 60),  					array('email')), -				'tz'				=> array('num', false, -14, 14), +				'tz'				=> array('timezone'),  				'lang'				=> array('language_iso_name'),  			)); @@ -279,8 +281,7 @@ class ucp_register  					'user_password'			=> phpbb_hash($data['new_password']),  					'user_email'			=> $data['email'],  					'group_id'				=> (int) $group_id, -					'user_timezone'			=> (float) $data['tz'], -					'user_dst'				=> $is_dst, +					'user_timezone'			=> $data['tz'],  					'user_lang'				=> $data['lang'],  					'user_type'				=> $user_type,  					'user_actkey'			=> $user_actkey, @@ -441,6 +442,7 @@ class ucp_register  			break;  		} +		$timezone_selects = phpbb_timezone_select($user, $data['tz'], true);  		$template->assign_vars(array(  			'ERROR'				=> (sizeof($error)) ? implode('<br />', $error) : '',  			'USERNAME'			=> $data['username'], @@ -453,7 +455,8 @@ class ucp_register  			'L_PASSWORD_EXPLAIN'		=> $user->lang($config['pass_complex'] . '_EXPLAIN', $user->lang('CHARACTERS', (int) $config['min_pass_chars']), $user->lang('CHARACTERS', (int) $config['max_pass_chars'])),  			'S_LANG_OPTIONS'	=> language_select($data['lang']), -			'S_TZ_OPTIONS'		=> tz_select($data['tz']), +			'S_TZ_OPTIONS'			=> $timezone_selects['tz_select'], +			'S_TZ_DATE_OPTIONS'		=> $timezone_selects['tz_dates'],  			'S_CONFIRM_REFRESH'	=> ($config['enable_confirm'] && $config['confirm_refresh']) ? true : false,  			'S_REGISTRATION'	=> true,  			'S_COPPA'			=> $coppa, diff --git a/phpBB/includes/update_helpers.php b/phpBB/includes/update_helpers.php new file mode 100644 index 0000000000..69d678b2f8 --- /dev/null +++ b/phpBB/includes/update_helpers.php @@ -0,0 +1,112 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2012 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +*/ + +/** +* phpBB Update Helpers +*/ +class phpbb_update_helpers +{ +	/** +	* Determine the new timezone for a given phpBB 3.0 timezone and +	* "Daylight Saving Time" option +	* +	*	@param	$timezone	float	Users timezone in 3.0 +	*	@param	$dst		int		Users daylight saving time +	*	@return		string		Users new php Timezone which is used since 3.1 +	*/ +	function convert_phpbb30_timezone($timezone, $dst) +	{ +		$offset = $timezone + $dst; + +		switch ($timezone) +		{ +			case '-12': +				return 'Etc/GMT+' . abs($offset);	//'[UTC - 12] Baker Island Time' +			case '-11': +				return 'Etc/GMT+' . abs($offset);	//'[UTC - 11] Niue Time, Samoa Standard Time' +			case '-10': +				return 'Etc/GMT+' . abs($offset);	//'[UTC - 10] Hawaii-Aleutian Standard Time, Cook Island Time' +			case '-9.5': +				return 'Pacific/Marquesas';			//'[UTC - 9:30] Marquesas Islands Time' +			case '-9': +				return 'Etc/GMT+' . abs($offset);	//'[UTC - 9] Alaska Standard Time, Gambier Island Time' +			case '-8': +				return 'Etc/GMT+' . abs($offset);	//'[UTC - 8] Pacific Standard Time' +			case '-7': +				return 'Etc/GMT+' . abs($offset);	//'[UTC - 7] Mountain Standard Time' +			case '-6': +				return 'Etc/GMT+' . abs($offset);	//'[UTC - 6] Central Standard Time' +			case '-5': +				return 'Etc/GMT+' . abs($offset);	//'[UTC - 5] Eastern Standard Time' +			case '-4.5': +				return 'America/Caracas';			//'[UTC - 4:30] Venezuelan Standard Time' +			case '-4': +				return 'Etc/GMT+' . abs($offset);	//'[UTC - 4] Atlantic Standard Time' +			case '-3.5': +				return 'America/St_Johns';			//'[UTC - 3:30] Newfoundland Standard Time' +			case '-3': +				return 'Etc/GMT+' . abs($offset);	//'[UTC - 3] Amazon Standard Time, Central Greenland Time' +			case '-2': +				return 'Etc/GMT+' . abs($offset);	//'[UTC - 2] Fernando de Noronha Time, South Georgia & the South Sandwich Islands Time' +			case '-1': +				return 'Etc/GMT+' . abs($offset);	//'[UTC - 1] Azores Standard Time, Cape Verde Time, Eastern Greenland Time' +			case '0': +				return (!$dst) ? 'UTC' : 'Etc/GMT-1';	//'[UTC] Western European Time, Greenwich Mean Time' +			case '1': +				return 'Etc/GMT-' . $offset;		//'[UTC + 1] Central European Time, West African Time' +			case '2': +				return 'Etc/GMT-' . $offset;		//'[UTC + 2] Eastern European Time, Central African Time' +			case '3': +				return 'Etc/GMT-' . $offset;		//'[UTC + 3] Moscow Standard Time, Eastern African Time' +			case '3.5': +				return 'Asia/Tehran';				//'[UTC + 3:30] Iran Standard Time' +			case '4': +				return 'Etc/GMT-' . $offset;		//'[UTC + 4] Gulf Standard Time, Samara Standard Time' +			case '4.5': +				return 'Asia/Kabul';				//'[UTC + 4:30] Afghanistan Time' +			case '5': +				return 'Etc/GMT-' . $offset;		//'[UTC + 5] Pakistan Standard Time, Yekaterinburg Standard Time' +			case '5.5': +				return 'Asia/Kolkata';				//'[UTC + 5:30] Indian Standard Time, Sri Lanka Time' +			case '5.75': +				return 'Asia/Kathmandu';			//'[UTC + 5:45] Nepal Time' +			case '6': +				return 'Etc/GMT-' . $offset;		//'[UTC + 6] Bangladesh Time, Bhutan Time, Novosibirsk Standard Time' +			case '6.5': +				return 'Indian/Cocos';				//'[UTC + 6:30] Cocos Islands Time, Myanmar Time' +			case '7': +				return 'Etc/GMT-' . $offset;		//'[UTC + 7] Indochina Time, Krasnoyarsk Standard Time' +			case '8': +				return 'Etc/GMT-' . $offset;		//'[UTC + 8] Chinese Standard Time, Australian Western Standard Time, Irkutsk Standard Time' +			case '8.75': +				return 'Australia/Eucla';			//'[UTC + 8:45] Southeastern Western Australia Standard Time' +			case '9': +				return 'Etc/GMT-' . $offset;		//'[UTC + 9] Japan Standard Time, Korea Standard Time, Chita Standard Time' +			case '9.5': +				return 'Australia/ACT';				//'[UTC + 9:30] Australian Central Standard Time' +			case '10': +				return 'Etc/GMT-' . $offset;		//'[UTC + 10] Australian Eastern Standard Time, Vladivostok Standard Time' +			case '10.5': +				return 'Australia/Lord_Howe';		//'[UTC + 10:30] Lord Howe Standard Time' +			case '11': +				return 'Etc/GMT-' . $offset;		//'[UTC + 11] Solomon Island Time, Magadan Standard Time' +			case '11.5': +				return 'Pacific/Norfolk';			//'[UTC + 11:30] Norfolk Island Time' +			case '12': +				return 'Etc/GMT-12';				//'[UTC + 12] New Zealand Time, Fiji Time, Kamchatka Standard Time' +			case '12.75': +				return 'Pacific/Chatham';			//'[UTC + 12:45] Chatham Islands Time' +			case '13': +				return 'Pacific/Tongatapu';			//'[UTC + 13] Tonga Time, Phoenix Islands Time' +			case '14': +				return 'Pacific/Kiritimati';		//'[UTC + 14] Line Island Time' +			default: +				return 'UTC'; +		} +	} +} diff --git a/phpBB/includes/user.php b/phpBB/includes/user.php index cf9e6b9994..fcbfaaddfa 100644 --- a/phpBB/includes/user.php +++ b/phpBB/includes/user.php @@ -29,8 +29,11 @@ class phpbb_user extends phpbb_session  	var $help = array();  	var $style = array();  	var $date_format; -	var $timezone; -	var $dst; + +	/** +	* DateTimeZone object holding the timezone of the user +	*/ +	public $timezone;  	var $lang_name = false;  	var $lang_id = false; @@ -79,15 +82,13 @@ class phpbb_user extends phpbb_session  			$this->lang_name = (file_exists($this->lang_path . $this->data['user_lang'] . "/common.$phpEx")) ? $this->data['user_lang'] : basename($config['default_lang']);  			$this->date_format = $this->data['user_dateformat']; -			$this->timezone = $this->data['user_timezone'] * 3600; -			$this->dst = $this->data['user_dst'] * 3600; +			$user_timezone = $this->data['user_timezone'];  		}  		else  		{  			$this->lang_name = basename($config['default_lang']);  			$this->date_format = $config['default_dateformat']; -			$this->timezone = $config['board_timezone'] * 3600; -			$this->dst = $config['board_dst'] * 3600; +			$user_timezone = $config['board_timezone'];  			/**  			* If a guest user is surfing, we try to guess his/her language first by obtaining the browser language @@ -126,6 +127,16 @@ class phpbb_user extends phpbb_session  			*/  		} +		try +		{ +			$this->timezone = new DateTimeZone($user_timezone); +		} +		catch (Exception $e) +		{ +			// If the timezone the user has selected is invalid, we fall back to UTC. +			$this->timezone = new DateTimeZone('UTC'); +		} +  		// We include common language file here to not load it every time a custom language file is included  		$lang = &$this->lang; @@ -612,70 +623,46 @@ class phpbb_user extends phpbb_session  	*/  	function format_date($gmepoch, $format = false, $forcedate = false)  	{ -		static $midnight; -		static $date_cache; - -		$format = (!$format) ? $this->date_format : $format; -		$now = time(); -		$delta = $now - $gmepoch; - -		if (!isset($date_cache[$format])) -		{ -			// Is the user requesting a friendly date format (i.e. 'Today 12:42')? -			$date_cache[$format] = array( -				'is_short'      => strpos($format, '|'), -				'format_short'  => substr($format, 0, strpos($format, '|')) . '||' . substr(strrchr($format, '|'), 1), -				'format_long'   => str_replace('|', '', $format), -				'lang'          => $this->lang['datetime'], -			); - -			// Short representation of month in format? Some languages use different terms for the long and short format of May -			if ((strpos($format, '\M') === false && strpos($format, 'M') !== false) || (strpos($format, '\r') === false && strpos($format, 'r') !== false)) -			{ -				$date_cache[$format]['lang']['May'] = $this->lang['datetime']['May_short']; -			} -		} +		static $utc; -		// Zone offset -		$zone_offset = $this->timezone + $this->dst; - -		// Show date < 1 hour ago as 'xx min ago' but not greater than 60 seconds in the future -		// A small tolerence is given for times in the future but in the same minute are displayed as '< than a minute ago' -		if ($delta < 3600 && $delta > -60 && ($delta >= -5 || (($now / 60) % 60) == (($gmepoch / 60) % 60)) && $date_cache[$format]['is_short'] !== false && !$forcedate && isset($this->lang['datetime']['AGO'])) +		if (!isset($utc))  		{ -			return $this->lang(array('datetime', 'AGO'), max(0, (int) floor($delta / 60))); +			$utc = new DateTimeZone('UTC');  		} -		if (!$midnight) -		{ -			list($d, $m, $y) = explode(' ', gmdate('j n Y', time() + $zone_offset)); -			$midnight = gmmktime(0, 0, 0, $m, $d, $y) - $zone_offset; -		} - -		if ($date_cache[$format]['is_short'] !== false && !$forcedate && !($gmepoch < $midnight - 86400 || $gmepoch > $midnight + 172800)) -		{ -			$day = false; +		$time = new phpbb_datetime($this, "@$gmepoch", $utc); +		$time->setTimezone($this->timezone); -			if ($gmepoch > $midnight + 86400) -			{ -				$day = 'TOMORROW'; -			} -			else if ($gmepoch > $midnight) -			{ -				$day = 'TODAY'; -			} -			else if ($gmepoch > $midnight - 86400) -			{ -				$day = 'YESTERDAY'; -			} +		return $time->format($format, $forcedate); +	} -			if ($day !== false) -			{ -				return str_replace('||', $this->lang['datetime'][$day], strtr(@gmdate($date_cache[$format]['format_short'], $gmepoch + $zone_offset), $date_cache[$format]['lang'])); -			} -		} +	/** +	* Create a phpbb_datetime object in the context of the current user +	* +	* @since 3.1 +	* @param string $time String in a format accepted by strtotime(). +	* @param DateTimeZone $timezone Time zone of the time. +	* @return phpbb_datetime Date time object linked to the current users locale +	*/ +	public function create_datetime($time = 'now', DateTimeZone $timezone = null) +	{ +		$timezone = $timezone ?: $this->timezone; +		return new phpbb_datetime($this, $time, $timezone); +	} -		return strtr(@gmdate($date_cache[$format]['format_long'], $gmepoch + $zone_offset), $date_cache[$format]['lang']); +	/** +	* Get the UNIX timestamp for a datetime in the users timezone, so we can store it in the database. +	* +	* @param	string			$format		Format of the entered date/time +	* @param	string			$time		Date/time with the timezone applied +	* @param	DateTimeZone	$timezone	Timezone of the date/time, falls back to timezone of current user +	* @return	int			Returns the unix timestamp +	*/ +	public function get_timestamp_from_format($format, $time, DateTimeZone $timezone = null) +	{ +		$timezone = $timezone ?: $this->timezone; +		$date = DateTime::createFromFormat($format, $time, $timezone); +		return ($date !== false) ? $date->format('U') : false;  	}  	/** | 
