From 17f5c6bf71f560be2f4e2ecabae83ab2973bec47 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Sat, 18 Feb 2012 12:00:12 +0100 Subject: [PATCH 001/441] [ticket/10605] Check for orphan privmsgs when deleting a user Also moved the hole code into a new function. PHPBB3-10605 --- phpBB/includes/functions_privmsgs.php | 116 ++++++++++++++++++++++++++ phpBB/includes/functions_user.php | 58 +------------ 2 files changed, 120 insertions(+), 54 deletions(-) diff --git a/phpBB/includes/functions_privmsgs.php b/phpBB/includes/functions_privmsgs.php index c40ceb088f..30cff8ed72 100644 --- a/phpBB/includes/functions_privmsgs.php +++ b/phpBB/includes/functions_privmsgs.php @@ -1083,6 +1083,122 @@ function delete_pm($user_id, $msg_ids, $folder_id) return true; } +/** +* Delete all PM(s) for a given user and delete the ones without references +*/ +function delete_user_pms($user_id) +{ + global $db, $user, $phpbb_root_path, $phpEx; + + $user_id = (int) $user_id; + + if (!$user_id) + { + return false; + } + + // Get PM Information for later deleting + $sql = 'SELECT msg_id, author_id, folder_id, pm_unread, pm_new + FROM ' . PRIVMSGS_TO_TABLE . ' + WHERE user_id = ' . $user_id . ' + OR (author_id = ' . $user_id . ' + AND folder_id = ' . PRIVMSGS_NO_BOX . ')'; + $result = $db->sql_query($sql); + + $undelivered_msg = $undelivered_user = $delete_rows = array(); + $num_unread = $num_new = $num_deleted = 0; + 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']; + $undelivered_user[$row['user_id']][] = true; + } + + $delete_rows[$row['msg_id']] = 1; + } + $db->sql_freeresult($result); + + if (!sizeof($delete_rows)) + { + 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); + } + + foreach ($undelivered_user as $_user_id => $ary) + { + if ($_user_id == $user_id) + { + continue; + } + + $sql = 'UPDATE ' . USERS_TABLE . ' + SET user_new_privmsg = user_new_privmsg - ' . sizeof($ary) . ', + user_unread_privmsg = user_unread_privmsg - ' . sizeof($ary) . ' + WHERE user_id = ' . $_user_id; + $db->sql_query($sql); + } + + // Delete private message data + $sql = 'DELETE FROM ' . PRIVMSGS_TO_TABLE . " + WHERE user_id = $user_id + AND " . $db->sql_in_set('msg_id', array_keys($delete_rows)); + $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', array_keys($delete_rows)); + $result = $db->sql_query($sql); + + while ($row = $db->sql_fetchrow($result)) + { + unset($delete_rows[$row['msg_id']]); + } + $db->sql_freeresult($result); + + $delete_ids = array_keys($delete_rows); + + if (sizeof($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); + } + + 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 - this way users are still able to read messages from users being removed + $sql = 'UPDATE ' . PRIVMSGS_TO_TABLE . ' + SET author_id = ' . ANONYMOUS . ' + WHERE author_id = ' . $user_id; + $db->sql_query($sql); + + $sql = 'UPDATE ' . PRIVMSGS_TABLE . ' + SET author_id = ' . ANONYMOUS . ' + WHERE author_id = ' . $user_id; + $db->sql_query($sql); + + $db->sql_transaction('commit'); + + return true; +} + /** * Rebuild message header */ diff --git a/phpBB/includes/functions_user.php b/phpBB/includes/functions_user.php index 6b5cca8abb..20923ea495 100644 --- a/phpBB/includes/functions_user.php +++ b/phpBB/includes/functions_user.php @@ -528,62 +528,12 @@ function user_delete($mode, $user_id, $post_username = false) WHERE session_user_id = ' . $user_id; $db->sql_query($sql); - // Remove any undelivered mails... - $sql = 'SELECT msg_id, user_id - FROM ' . PRIVMSGS_TO_TABLE . ' - WHERE author_id = ' . $user_id . ' - AND folder_id = ' . PRIVMSGS_NO_BOX; - $result = $db->sql_query($sql); - - $undelivered_msg = $undelivered_user = array(); - while ($row = $db->sql_fetchrow($result)) + // Clean the private messages tables from the user + if (!function_exists('delete_user_pms')) { - $undelivered_msg[] = $row['msg_id']; - $undelivered_user[$row['user_id']][] = true; - } - $db->sql_freeresult($result); - - if (sizeof($undelivered_msg)) - { - $sql = 'DELETE FROM ' . PRIVMSGS_TABLE . ' - WHERE ' . $db->sql_in_set('msg_id', $undelivered_msg); - $db->sql_query($sql); - } - - $sql = 'DELETE FROM ' . PRIVMSGS_TO_TABLE . ' - WHERE author_id = ' . $user_id . ' - AND folder_id = ' . PRIVMSGS_NO_BOX; - $db->sql_query($sql); - - // Delete all to-information - $sql = 'DELETE FROM ' . PRIVMSGS_TO_TABLE . ' - WHERE user_id = ' . $user_id; - $db->sql_query($sql); - - // Set the remaining author id to anonymous - this way users are still able to read messages from users being removed - $sql = 'UPDATE ' . PRIVMSGS_TO_TABLE . ' - SET author_id = ' . ANONYMOUS . ' - WHERE author_id = ' . $user_id; - $db->sql_query($sql); - - $sql = 'UPDATE ' . PRIVMSGS_TABLE . ' - SET author_id = ' . ANONYMOUS . ' - WHERE author_id = ' . $user_id; - $db->sql_query($sql); - - foreach ($undelivered_user as $_user_id => $ary) - { - if ($_user_id == $user_id) - { - continue; - } - - $sql = 'UPDATE ' . USERS_TABLE . ' - SET user_new_privmsg = user_new_privmsg - ' . sizeof($ary) . ', - user_unread_privmsg = user_unread_privmsg - ' . sizeof($ary) . ' - WHERE user_id = ' . $_user_id; - $db->sql_query($sql); + include($phpbb_root_path . 'includes/functions_privmsgs.' . $phpEx); } + delete_user_pms($user_id); $db->sql_transaction('commit'); From cd5c01ac2da2ec316e997e8850e1b2d326191e56 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 21 Feb 2012 11:10:10 +0100 Subject: [PATCH 002/441] [ticket/9089] Add tabindex to PM recipient box, to allow tabbing to the subject I also added tabindex 1 to the buttons for adding the recipients. Also note, that duplicated tabindex are fine: http://www.w3.org/TR/html4/interact/forms.html#adef-tabindex PHPBB3-9089 --- phpBB/styles/prosilver/template/posting_editor.html | 6 +++--- phpBB/styles/subsilver2/template/ucp_header.html | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/phpBB/styles/prosilver/template/posting_editor.html b/phpBB/styles/prosilver/template/posting_editor.html index 5f7fb8408e..e7c1dc21eb 100644 --- a/phpBB/styles/prosilver/template/posting_editor.html +++ b/phpBB/styles/prosilver/template/posting_editor.html @@ -37,10 +37,10 @@
-
+
{L_FIND_USERNAME}
-
-
+
+
diff --git a/phpBB/styles/subsilver2/template/ucp_header.html b/phpBB/styles/subsilver2/template/ucp_header.html index ea64dcb299..1566a15929 100644 --- a/phpBB/styles/subsilver2/template/ucp_header.html +++ b/phpBB/styles/subsilver2/template/ucp_header.html @@ -26,7 +26,7 @@ {L_USERNAMES}: -
+
[ {L_FIND_USERNAME} ] @@ -41,7 +41,7 @@ -
  
  
+
  
  
From 45f39c6d1f2adc318d521bd9eb75d80f0750fdb8 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Sat, 18 Feb 2012 12:16:21 +0100 Subject: [PATCH 003/441] [ticket/10605] Delete orphan private messages on update PHPBB3-10605 --- phpBB/install/database_update.php | 42 +++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/phpBB/install/database_update.php b/phpBB/install/database_update.php index a1b7dcd47f..b6298ca651 100644 --- a/phpBB/install/database_update.php +++ b/phpBB/install/database_update.php @@ -2024,6 +2024,48 @@ function change_database_data(&$no_updates, $version) // No changes from 3.0.10-RC3 to 3.0.10 case '3.0.10-RC3': break; + + // Changes from 3.0.10 to 3.0.11-RC1 + case '3.0.10': + // Delete orphan private messages + $batch_size = 500; + + $sql_array = array( + 'SELECT' => 'p.msg_id', + 'FROM' => array( + PRIVMSGS_TABLE => 'p', + ), + 'LEFT_JOIN' => array( + array( + 'FROM' => array(PRIVMSGS_TO_TABLE, 't'), + 'ON' => 'p.msg_id = t.msg_id', + ), + ), + 'WHERE' => 't.user_id IS NULL'; + $sql = $db->sql_build_query('SELECT', $sql_array); + + do + { + $result = $db->sql_query_limit($sql, $batch_size); + + $delete_pms = array(); + while ($row = $db->sql_fetchrow($result)) + { + $delete_pms[] = (int) $row['msg_id']; + } + $db->sql_freeresult($result); + + if (!empty($delete_pms)) + { + $sql = 'DELETE FROM ' . PRIVMSGS_TABLE . ' + WHERE ' . $db->sql_in_set('msg_id', $delete_pms); + $db->sql_query($sql); + } + } + while (sizeof($delete_pms) == $batch_size); + + $no_updates = false; + break; } } From 17dc8c6c5c0e651a305961fae579c59d09abf88d Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Mon, 27 Feb 2012 17:16:42 +0100 Subject: [PATCH 004/441] [ticket/9089] Add tabindex to pm/topic/post icon-options aswell PHPBB3-9089 --- phpBB/styles/prosilver/template/posting_editor.html | 4 ++-- phpBB/styles/subsilver2/template/posting_body.html | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/phpBB/styles/prosilver/template/posting_editor.html b/phpBB/styles/prosilver/template/posting_editor.html index e7c1dc21eb..67ba74a690 100644 --- a/phpBB/styles/prosilver/template/posting_editor.html +++ b/phpBB/styles/prosilver/template/posting_editor.html @@ -87,8 +87,8 @@
- - + +
diff --git a/phpBB/styles/subsilver2/template/posting_body.html b/phpBB/styles/subsilver2/template/posting_body.html index fec6d7ff6c..dbdf6b230c 100644 --- a/phpBB/styles/subsilver2/template/posting_body.html +++ b/phpBB/styles/subsilver2/template/posting_body.html @@ -127,7 +127,7 @@ - +
{L_NO_TOPIC_ICON}{L_NO_PM_ICON} {L_NO_TOPIC_ICON}{L_NO_PM_ICON}
From ba6943a6a0ea50af772dc6e94f13b56292cd9f37 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Mon, 12 Mar 2012 10:11:52 +0100 Subject: [PATCH 005/441] [ticket/10605] Prefix function with phpbb_ and use true instead of 1 PHPBB3-10605 --- phpBB/includes/functions_privmsgs.php | 4 ++-- phpBB/includes/functions_user.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/phpBB/includes/functions_privmsgs.php b/phpBB/includes/functions_privmsgs.php index 30cff8ed72..34f16ea9da 100644 --- a/phpBB/includes/functions_privmsgs.php +++ b/phpBB/includes/functions_privmsgs.php @@ -1086,7 +1086,7 @@ function delete_pm($user_id, $msg_ids, $folder_id) /** * Delete all PM(s) for a given user and delete the ones without references */ -function delete_user_pms($user_id) +function phpbb_delete_user_pms($user_id) { global $db, $user, $phpbb_root_path, $phpEx; @@ -1116,7 +1116,7 @@ function delete_user_pms($user_id) $undelivered_user[$row['user_id']][] = true; } - $delete_rows[$row['msg_id']] = 1; + $delete_rows[$row['msg_id']] = true; } $db->sql_freeresult($result); diff --git a/phpBB/includes/functions_user.php b/phpBB/includes/functions_user.php index 20923ea495..92a7b8e0e9 100644 --- a/phpBB/includes/functions_user.php +++ b/phpBB/includes/functions_user.php @@ -529,11 +529,11 @@ function user_delete($mode, $user_id, $post_username = false) $db->sql_query($sql); // Clean the private messages tables from the user - if (!function_exists('delete_user_pms')) + if (!function_exists('phpbb_delete_user_pms')) { include($phpbb_root_path . 'includes/functions_privmsgs.' . $phpEx); } - delete_user_pms($user_id); + phpbb_delete_user_pms($user_id); $db->sql_transaction('commit'); From 6f7d095e3f4b09847c5963646b2f4a817d68ba39 Mon Sep 17 00:00:00 2001 From: Chris Smith Date: Sun, 18 Apr 2010 22:11:04 +0100 Subject: [PATCH 006/441] [feature/new-tz-handling] Wrapper around DateTime for new date time handling. Wrapped PHP's DateTime with some extensions for supporting phpBB's relative date formats and provided the DateTime::getTimestamp() method to PHP < 5.3. PHPBB3-9558 --- phpBB/includes/datetime.php | 160 ++++++++++++++++++++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100644 phpBB/includes/datetime.php diff --git a/phpBB/includes/datetime.php b/phpBB/includes/datetime.php new file mode 100644 index 0000000000..b1e95e58a3 --- /dev/null +++ b/phpBB/includes/datetime.php @@ -0,0 +1,160 @@ +_user = $user ? $user : $GLOBALS['user']; + + $timezone = (!$timezone && $this->_user->tz instanceof DateTimeZone) ? $this->_user->tz : $timezone; + + parent::__construct($time, $timezone); + } + + /** + * Returns a UNIX timestamp representation of the date time. + * + * @return int UNIX timestamp + */ + public function getTimestamp() + { + static $compat; + + if (!isset($compat)) + { + $compat = !method_exists('DateTime', 'getTimestamp'); + } + + return !$compat ? parent::getTimestamp() : (int) parent::format('U'); + } + + /** + * 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; + $relative = (strpos($format, self::RELATIVE_WRAPPER) !== false && !$force_absolute); + $now = new self('now', $this->_user->tz, $this->_user); + $delta = $now->getTimestamp() - $this->getTimestamp(); + + if ($relative) + { + if ($delta <= 3600 && ($delta >= -5 || (($now->getTimestamp() / 60) % 60) == (($this->getTimestamp() / 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(); + $gmepoch = $this->getTimestamp(); + + if (!($gmepoch < $midnight - 86400 || $gmepoch > $midnight + 172800)) + { + $day = false; + + if ($gmepoch > $midnight + 86400) + { + $day = 'TOMORROW'; + } + else if ($gmepoch > $midnight) + { + $day = 'TODAY'; + } + else if ($gmepoch > $midnight - 86400) + { + $day = 'YESTERDAY'; + } + + if ($day !== false) + { + $format = self::_format_cache($format, $this->_user); + + return str_replace(self::RELATIVE_WRAPPER . self::RELATIVE_WRAPPER, $this->_user->lang['datetime'][$day], strtr(parent::format($format['format_short']), $format['lang'])); + } + } + } + } + + $format = self::_format_cache($format, $this->_user); + + return strtr(parent::format($format['format_long']), $format['lang']); + } + + /** + * 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]; + } +} From e8b60fc3d8b483fda50c715e59b73861cd3ced9e Mon Sep 17 00:00:00 2001 From: Chris Smith Date: Sun, 18 Apr 2010 22:26:33 +0100 Subject: [PATCH 007/441] [feature/new-tz-handling] Use phpbb_datetime rather than phpbb_DateTime. PHPBB3-9558 --- phpBB/includes/datetime.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/phpBB/includes/datetime.php b/phpBB/includes/datetime.php index b1e95e58a3..d14693faa3 100644 --- a/phpBB/includes/datetime.php +++ b/phpBB/includes/datetime.php @@ -11,7 +11,7 @@ * phpBB custom extensions to the PHP DateTime class * This handles the relative formats phpBB employs */ -class phpbb_DateTime extends DateTime +class phpbb_datetime extends DateTime { /** * String used to wrap the date segment which should be replaced by today/tomorrow/yesterday @@ -29,7 +29,7 @@ class phpbb_DateTime extends DateTime static protected $format_cache = array(); /** - * Constructs a new instance of phpbb_DateTime, expanded to include an argument to inject + * 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(). From a5c3ff376911f2f25595f1a540c7a16395dac67d Mon Sep 17 00:00:00 2001 From: Chris Smith Date: Tue, 20 Apr 2010 19:30:05 +0100 Subject: [PATCH 008/441] [feature/new-tz-handling] Renamed old variables and removed extra conditional. PHPBB3-9558 --- phpBB/includes/datetime.php | 39 ++++++++++++++++--------------------- 1 file changed, 17 insertions(+), 22 deletions(-) diff --git a/phpBB/includes/datetime.php b/phpBB/includes/datetime.php index d14693faa3..92aef88599 100644 --- a/phpBB/includes/datetime.php +++ b/phpBB/includes/datetime.php @@ -87,32 +87,27 @@ class phpbb_datetime extends DateTime $midnight = clone $now; $midnight->setTime(0, 0, 0); - $midnight = $midnight->getTimestamp(); - $gmepoch = $this->getTimestamp(); + $midnight = $midnight->getTimestamp(); + $timestamp = $this->getTimestamp(); - if (!($gmepoch < $midnight - 86400 || $gmepoch > $midnight + 172800)) + if ($timestamp > $midnight + 86400) { - $day = false; + $day = 'TOMORROW'; + } + else if ($timestamp > $midnight) + { + $day = 'TODAY'; + } + else if ($timestamp > $midnight - 86400) + { + $day = 'YESTERDAY'; + } - if ($gmepoch > $midnight + 86400) - { - $day = 'TOMORROW'; - } - else if ($gmepoch > $midnight) - { - $day = 'TODAY'; - } - else if ($gmepoch > $midnight - 86400) - { - $day = 'YESTERDAY'; - } + if ($day !== false) + { + $format = self::_format_cache($format, $this->_user); - if ($day !== false) - { - $format = self::_format_cache($format, $this->_user); - - return str_replace(self::RELATIVE_WRAPPER . self::RELATIVE_WRAPPER, $this->_user->lang['datetime'][$day], strtr(parent::format($format['format_short']), $format['lang'])); - } + return str_replace(self::RELATIVE_WRAPPER . self::RELATIVE_WRAPPER, $this->_user->lang['datetime'][$day], strtr(parent::format($format['format_short']), $format['lang'])); } } } From 3559d2062480d5c3a0e94dae7388f9f1e5918ea7 Mon Sep 17 00:00:00 2001 From: Chris Smith Date: Tue, 20 Apr 2010 19:43:49 +0100 Subject: [PATCH 009/441] [feature/new-tz-handling] Update user methods to use new date processing class. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit user::setup() now stores a DateTimeZone object in user::$timezone representing the users timezone. For backwards compatibility a numeric value in user/board_timezone will be converted into one of the legacy Etc/GMT±X timezones. This will be used until the user updates his/her timezone in the UCP. user::format_date() is now basically a legacy wrapper that transforms a UTC UNIX timestamp into a formatted localised date using phpbb_datetime::format(). PHPBB3-9558 --- phpBB/includes/session.php | 87 +++++++++++--------------------------- 1 file changed, 24 insertions(+), 63 deletions(-) diff --git a/phpBB/includes/session.php b/phpBB/includes/session.php index 497aaf1141..ba9136b568 100644 --- a/phpBB/includes/session.php +++ b/phpBB/includes/session.php @@ -1574,20 +1574,26 @@ class user extends session { global $db, $template, $config, $auth, $phpEx, $phpbb_root_path, $cache; + // @todo Move this to a better location + if (!class_exists('phpbb_datetime')) + { + global $phpbb_root_path, $phpEx; + + require "{$phpbb_root_path}includes/datetime.$phpEx"; + } + if ($this->data['user_id'] != ANONYMOUS) { $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; + $this->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; + $this->timezone = $config['board_timezone']; /** * If a guest user is surfing, we try to guess his/her language first by obtaining the browser language @@ -1626,6 +1632,14 @@ class user extends session */ } + if (is_numeric($this->timezone)) + { + // Might still be numeric by chance + $this->timezone = sprintf('Etc/GMT%+d', ($this->timezone + ($this->data['user_id'] != ANONYMOUS ? $this->data['user_dst'] : $config['board_dst']))); + } + + $this->timezone = new DateTimeZone($this->timezone); + // We include common language file here to not load it every time a custom language file is included $lang = &$this->lang; @@ -2072,70 +2086,17 @@ class user extends session */ function format_date($gmepoch, $format = false, $forcedate = false) { - static $midnight; - static $date_cache; + static $utc; - $format = (!$format) ? $this->date_format : $format; - $now = time(); - $delta = $now - $gmepoch; - - if (!isset($date_cache[$format])) + if (!isset($utc)) { - // 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']; - } + $utc = new DateTimeZone('UTC'); } - // Zone offset - $zone_offset = $this->timezone + $this->dst; + $time = new phpbb_DateTime("@$gmepoch", $utc, $this); + $time->setTimezone($this->tz); - // 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'])) - { - return $this->lang(array('datetime', 'AGO'), max(0, (int) floor($delta / 60))); - } - - 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; - - if ($gmepoch > $midnight + 86400) - { - $day = 'TOMORROW'; - } - else if ($gmepoch > $midnight) - { - $day = 'TODAY'; - } - else if ($gmepoch > $midnight - 86400) - { - $day = 'YESTERDAY'; - } - - if ($day !== false) - { - return str_replace('||', $this->lang['datetime'][$day], strtr(@gmdate($date_cache[$format]['format_short'], $gmepoch + $zone_offset), $date_cache[$format]['lang'])); - } - } - - return strtr(@gmdate($date_cache[$format]['format_long'], $gmepoch + $zone_offset), $date_cache[$format]['lang']); + return $time->format($format, $forcedate); } /** From b2a812e36bc90d01f21da469823f4e759294b770 Mon Sep 17 00:00:00 2001 From: Chris Smith Date: Tue, 20 Apr 2010 21:01:20 +0100 Subject: [PATCH 010/441] [feature/new-tz-handling] Correct capitalisation of phpbb_datetime. PHPBB3-9558 --- phpBB/includes/session.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/includes/session.php b/phpBB/includes/session.php index ba9136b568..d8204e41f6 100644 --- a/phpBB/includes/session.php +++ b/phpBB/includes/session.php @@ -2093,7 +2093,7 @@ class user extends session $utc = new DateTimeZone('UTC'); } - $time = new phpbb_DateTime("@$gmepoch", $utc, $this); + $time = new phpbb_datetime("@$gmepoch", $utc, $this); $time->setTimezone($this->tz); return $time->format($format, $forcedate); From 9e1812a0ca728aee69df9ec5b86ea21756d3b1cc Mon Sep 17 00:00:00 2001 From: Chris Smith Date: Wed, 7 Jul 2010 21:31:41 +0100 Subject: [PATCH 011/441] [feature/new-tz-handling] Remove old user::$dst property PHPBB3-9558 --- phpBB/includes/session.php | 1 - 1 file changed, 1 deletion(-) diff --git a/phpBB/includes/session.php b/phpBB/includes/session.php index d8204e41f6..fe690a1a9a 100644 --- a/phpBB/includes/session.php +++ b/phpBB/includes/session.php @@ -1529,7 +1529,6 @@ class user extends session var $theme = array(); var $date_format; var $timezone; - var $dst; var $lang_name = false; var $lang_id = false; From 6a783b843b596c46738d76f2db5d539d8f68a815 Mon Sep 17 00:00:00 2001 From: Chris Smith Date: Wed, 7 Jul 2010 22:17:40 +0100 Subject: [PATCH 012/441] [feature/new-tz-handling] Replace user::$timezone with user::$tz. user::$tz will store the new DateTimeZone object representing the users timezone instead of the existing user::$timezone and user::$dst combination. PHPBB3-9558 --- phpBB/includes/session.php | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/phpBB/includes/session.php b/phpBB/includes/session.php index fe690a1a9a..2352e6394a 100644 --- a/phpBB/includes/session.php +++ b/phpBB/includes/session.php @@ -1528,7 +1528,14 @@ class user extends session var $help = array(); var $theme = array(); var $date_format; - var $timezone; + + /** + * Users current timezone + * + * @var DateTimeZone Timezone of the user + * @since 3.1 + */ + public $tz; var $lang_name = false; var $lang_id = false; @@ -1586,13 +1593,13 @@ class user extends 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']; + $this->tz = $this->data['user_timezone']; } else { $this->lang_name = basename($config['default_lang']); $this->date_format = $config['default_dateformat']; - $this->timezone = $config['board_timezone']; + $this->tz = $config['board_timezone']; /** * If a guest user is surfing, we try to guess his/her language first by obtaining the browser language @@ -1631,13 +1638,13 @@ class user extends session */ } - if (is_numeric($this->timezone)) + if (is_numeric($this->tz)) { // Might still be numeric by chance - $this->timezone = sprintf('Etc/GMT%+d', ($this->timezone + ($this->data['user_id'] != ANONYMOUS ? $this->data['user_dst'] : $config['board_dst']))); + $this->tz = sprintf('Etc/GMT%+d', ($this->tz + ($this->data['user_id'] != ANONYMOUS ? $this->data['user_dst'] : $config['board_dst']))); } - $this->timezone = new DateTimeZone($this->timezone); + $this->tz = new DateTimeZone($this->tz); // We include common language file here to not load it every time a custom language file is included $lang = &$this->lang; From 74be23a098ec222cf3f3d14d6b6df236c58e8c01 Mon Sep 17 00:00:00 2001 From: Chris Smith Date: Wed, 7 Jul 2010 22:20:08 +0100 Subject: [PATCH 013/441] [feature/new-tz-handling] Added a user::create_datetime() method. New method which handles instantiating new phpbb_datetime objects in the context of the current user. PHPBB3-9558 --- phpBB/includes/session.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/phpBB/includes/session.php b/phpBB/includes/session.php index 2352e6394a..e91606878a 100644 --- a/phpBB/includes/session.php +++ b/phpBB/includes/session.php @@ -2105,6 +2105,21 @@ class user extends session return $time->format($format, $forcedate); } + /** + * 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, DateTimeZone $timezone = null) + { + $timezone = $timezone ? $timezone : $this->tz; + + return new phpbb_datetime($time, $timezone, $this); + } + /** * Get language id currently used by the user */ From 2e7d9ec805a8f2088ceebf22dbc97b89a72f76d0 Mon Sep 17 00:00:00 2001 From: Chris Smith Date: Wed, 7 Jul 2010 23:46:20 +0100 Subject: [PATCH 014/441] [feature/new-tz-handling] Fixed bug with signature of user::create_datetime(). First argument to user::create_datetime() should be optional. PHPBB3-9558 --- phpBB/includes/session.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/includes/session.php b/phpBB/includes/session.php index e91606878a..cf2efd2960 100644 --- a/phpBB/includes/session.php +++ b/phpBB/includes/session.php @@ -2113,7 +2113,7 @@ class user extends session * @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, DateTimeZone $timezone = null) + public function create_datetime($time = 'now', DateTimeZone $timezone = null) { $timezone = $timezone ? $timezone : $this->tz; From 522f65d079c61e9ea7f718b67e37a9e58968b0f0 Mon Sep 17 00:00:00 2001 From: Chris Smith Date: Wed, 7 Jul 2010 22:21:40 +0100 Subject: [PATCH 015/441] [feature/new-tz-handling] Correct typo in member comment. PHPBB3-9558 --- phpBB/includes/datetime.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/includes/datetime.php b/phpBB/includes/datetime.php index 92aef88599..3a7fc04105 100644 --- a/phpBB/includes/datetime.php +++ b/phpBB/includes/datetime.php @@ -24,7 +24,7 @@ class phpbb_datetime extends DateTime protected $_user; /** - * @var array Date formats are preprocessed by phpBB, to save constact recalculation they are cached. + * @var array Date formats are preprocessed by phpBB, to save constant recalculation they are cached. */ static protected $format_cache = array(); From c521ef1591022e69fe952ec23e6614ae36dee2e2 Mon Sep 17 00:00:00 2001 From: Chris Smith Date: Wed, 7 Jul 2010 22:22:38 +0100 Subject: [PATCH 016/441] [feature/new-tz-handling] Comment and optimise phpbb_datetime::format(). - Added comments explaining the complex time computations for rendering relative date times. - Replaced some repeated method invokations with variables. PHPBB3-9558 --- phpBB/includes/datetime.php | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/phpBB/includes/datetime.php b/phpBB/includes/datetime.php index 3a7fc04105..577081e40b 100644 --- a/phpBB/includes/datetime.php +++ b/phpBB/includes/datetime.php @@ -74,11 +74,18 @@ class phpbb_datetime extends DateTime $format = $format ? $format : $this->_user->date_format; $relative = (strpos($format, self::RELATIVE_WRAPPER) !== false && !$force_absolute); $now = new self('now', $this->_user->tz, $this->_user); - $delta = $now->getTimestamp() - $this->getTimestamp(); + + $timestamp = $this->getTimestamp(); + $now_ts = $now->getTimeStamp(); + + $delta = $now_ts - $timestamp; if ($relative) { - if ($delta <= 3600 && ($delta >= -5 || (($now->getTimestamp() / 60) % 60) == (($this->getTimestamp() / 60) % 60)) && isset($this->_user->lang['datetime']['AGO'])) + // Check the delta is less than or equal to 1 hour + // 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 >= -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))); } @@ -88,7 +95,6 @@ class phpbb_datetime extends DateTime $midnight->setTime(0, 0, 0); $midnight = $midnight->getTimestamp(); - $timestamp = $this->getTimestamp(); if ($timestamp > $midnight + 86400) { @@ -107,6 +113,7 @@ class phpbb_datetime extends DateTime { $format = self::_format_cache($format, $this->_user); + // 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'])); } } From dba89a534120d48d0ba901aedd69f962536bf36d Mon Sep 17 00:00:00 2001 From: Chris Smith Date: Wed, 7 Jul 2010 22:24:43 +0100 Subject: [PATCH 017/441] [feature/new-tz-handling] Added phpbb_datetime::__toString(). New phpbb_datetime::__toString() magic method that formats the datetime according to the users default settings. PHPBB3-9558 --- phpBB/includes/datetime.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/phpBB/includes/datetime.php b/phpBB/includes/datetime.php index 577081e40b..8763697c78 100644 --- a/phpBB/includes/datetime.php +++ b/phpBB/includes/datetime.php @@ -124,6 +124,16 @@ class phpbb_datetime extends DateTime 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 * From f085735ef812a57790699a6d789cbab22f882328 Mon Sep 17 00:00:00 2001 From: Chris Smith Date: Wed, 7 Jul 2010 22:25:52 +0100 Subject: [PATCH 018/441] [feature/new-tz-handling] Explained name of phpbb_datetime::getTimestamp() phpbb_datetime::getTimestamp() exists purely to support PHP 5.2 which does not implement the method. PHPBB3-9558 --- phpBB/includes/datetime.php | 1 + 1 file changed, 1 insertion(+) diff --git a/phpBB/includes/datetime.php b/phpBB/includes/datetime.php index 8763697c78..12d04d5ca6 100644 --- a/phpBB/includes/datetime.php +++ b/phpBB/includes/datetime.php @@ -48,6 +48,7 @@ class phpbb_datetime extends DateTime /** * Returns a UNIX timestamp representation of the date time. * + * @internal This method is for backwards compatibility with 5.2, hence why it doesn't use our method naming standards. * @return int UNIX timestamp */ public function getTimestamp() From 8fe46175aff1d9275b7337a8ced8060ff850d153 Mon Sep 17 00:00:00 2001 From: Chris Smith Date: Wed, 7 Jul 2010 22:29:36 +0100 Subject: [PATCH 019/441] [feature/new-tz-handling] Fix undefined variable. PHPBB3-9558 --- phpBB/includes/datetime.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/phpBB/includes/datetime.php b/phpBB/includes/datetime.php index 12d04d5ca6..25da6401d7 100644 --- a/phpBB/includes/datetime.php +++ b/phpBB/includes/datetime.php @@ -97,6 +97,8 @@ class phpbb_datetime extends DateTime $midnight = $midnight->getTimestamp(); + $day = false; + if ($timestamp > $midnight + 86400) { $day = 'TOMORROW'; From 5dd7916c496b76ab2e1e28b804069dde63f7dbf0 Mon Sep 17 00:00:00 2001 From: Chris Smith Date: Wed, 7 Jul 2010 22:47:34 +0100 Subject: [PATCH 020/441] [feature/new-tz-handling] Check the is_short flag stored inside the format array. Reuse the existing check store in the format array to determine if the date time format supports relative formatting. PHPBB3-9558 --- phpBB/includes/datetime.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/phpBB/includes/datetime.php b/phpBB/includes/datetime.php index 25da6401d7..ecb3dfcf17 100644 --- a/phpBB/includes/datetime.php +++ b/phpBB/includes/datetime.php @@ -73,7 +73,8 @@ class phpbb_datetime extends DateTime public function format($format = '', $force_absolute = false) { $format = $format ? $format : $this->_user->date_format; - $relative = (strpos($format, self::RELATIVE_WRAPPER) !== false && !$force_absolute); + $format = self::_format_cache($format, $this->_user); + $relative = ($format['is_short'] && !$force_absolute); $now = new self('now', $this->_user->tz, $this->_user); $timestamp = $this->getTimestamp(); @@ -114,8 +115,6 @@ class phpbb_datetime extends DateTime if ($day !== false) { - $format = self::_format_cache($format, $this->_user); - // 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'])); } From e9fe9ea5185679e9950e330c949cc2577bfea21d Mon Sep 17 00:00:00 2001 From: Chris Smith Date: Wed, 7 Jul 2010 22:52:04 +0100 Subject: [PATCH 021/441] [feature/new-tz-handling] Fix bug from 3.0 formatting future dates. Future dates can get formatted as 'less than a minute ago' if they occur in the future on the same minute as the current minute. PHPBB3-9558 PHPBB3-9712 --- phpBB/includes/datetime.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/phpBB/includes/datetime.php b/phpBB/includes/datetime.php index ecb3dfcf17..2276d36413 100644 --- a/phpBB/includes/datetime.php +++ b/phpBB/includes/datetime.php @@ -85,9 +85,10 @@ class phpbb_datetime extends DateTime 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 >= -5 || (($now_ts / 60) % 60) == (($timestamp / 60) % 60)) && isset($this->_user->lang['datetime']['AGO'])) + 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))); } From 6e1278655ff3f250b4f1e09aa8674bae8d86287a Mon Sep 17 00:00:00 2001 From: Chris Smith Date: Wed, 7 Jul 2010 22:57:43 +0100 Subject: [PATCH 022/441] [feature/new-tz-handling] Removed line that was missed in cc312d8. PHPBB3-9558 --- phpBB/includes/datetime.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/phpBB/includes/datetime.php b/phpBB/includes/datetime.php index 2276d36413..22b7f871fd 100644 --- a/phpBB/includes/datetime.php +++ b/phpBB/includes/datetime.php @@ -122,8 +122,6 @@ class phpbb_datetime extends DateTime } } - $format = self::_format_cache($format, $this->_user); - return strtr(parent::format($format['format_long']), $format['lang']); } From af789040b8880f908df0a26d5239d07d77c34124 Mon Sep 17 00:00:00 2001 From: Chris Smith Date: Wed, 7 Jul 2010 23:23:11 +0100 Subject: [PATCH 023/441] [feature/new-tz-handling] Modify database schemas. - Dropped the user_dst column which is no longer required. - Modified the user_timezone column to take a string, max length 100. PHPBB3-9558 --- phpBB/develop/create_schema_files.php | 3 +-- phpBB/install/schemas/firebird_schema.sql | 3 +-- phpBB/install/schemas/mssql_schema.sql | 3 +-- phpBB/install/schemas/mysql_40_schema.sql | 3 +-- phpBB/install/schemas/mysql_41_schema.sql | 3 +-- phpBB/install/schemas/oracle_schema.sql | 3 +-- phpBB/install/schemas/postgres_schema.sql | 3 +-- phpBB/install/schemas/sqlite_schema.sql | 3 +-- 8 files changed, 8 insertions(+), 16 deletions(-) diff --git a/phpBB/develop/create_schema_files.php b/phpBB/develop/create_schema_files.php index 1735bffef5..f16675385b 100644 --- a/phpBB/develop/create_schema_files.php +++ b/phpBB/develop/create_schema_files.php @@ -1823,8 +1823,7 @@ function get_schema_struct() 'user_inactive_time' => array('TIMESTAMP', 0), 'user_posts' => array('UINT', 0), 'user_lang' => array('VCHAR:30', ''), - 'user_timezone' => array('DECIMAL', 0), - 'user_dst' => array('BOOL', 0), + 'user_timezone' => array('VCHAR:100', 'UTC'), 'user_dateformat' => array('VCHAR_UNI:30', 'd M Y H:i'), 'user_style' => array('UINT', 0), 'user_rank' => array('UINT', 0), diff --git a/phpBB/install/schemas/firebird_schema.sql b/phpBB/install/schemas/firebird_schema.sql index daeba45864..f4b1c624d7 100644 --- a/phpBB/install/schemas/firebird_schema.sql +++ b/phpBB/install/schemas/firebird_schema.sql @@ -1290,8 +1290,7 @@ CREATE TABLE phpbb_users ( user_inactive_time INTEGER DEFAULT 0 NOT NULL, user_posts INTEGER DEFAULT 0 NOT NULL, user_lang VARCHAR(30) CHARACTER SET NONE DEFAULT '' NOT NULL, - user_timezone DOUBLE PRECISION DEFAULT 0 NOT NULL, - user_dst INTEGER DEFAULT 0 NOT NULL, + user_timezone VARCHAR(100) CHARACTER SET NONE DEFAULT 'UTC' NOT NULL, user_dateformat VARCHAR(30) CHARACTER SET UTF8 DEFAULT 'd M Y H:i' NOT NULL COLLATE UNICODE, user_style INTEGER DEFAULT 0 NOT NULL, user_rank INTEGER DEFAULT 0 NOT NULL, diff --git a/phpBB/install/schemas/mssql_schema.sql b/phpBB/install/schemas/mssql_schema.sql index 736917fdcb..fc1afcbbff 100644 --- a/phpBB/install/schemas/mssql_schema.sql +++ b/phpBB/install/schemas/mssql_schema.sql @@ -1576,8 +1576,7 @@ CREATE TABLE [phpbb_users] ( [user_inactive_time] [int] DEFAULT (0) NOT NULL , [user_posts] [int] DEFAULT (0) NOT NULL , [user_lang] [varchar] (30) DEFAULT ('') NOT NULL , - [user_timezone] [float] DEFAULT (0) NOT NULL , - [user_dst] [int] DEFAULT (0) NOT NULL , + [user_timezone] [varchar] (100) DEFAULT ('UTC') NOT NULL , [user_dateformat] [varchar] (30) DEFAULT ('d M Y H:i') NOT NULL , [user_style] [int] DEFAULT (0) NOT NULL , [user_rank] [int] DEFAULT (0) NOT NULL , diff --git a/phpBB/install/schemas/mysql_40_schema.sql b/phpBB/install/schemas/mysql_40_schema.sql index 97c378621b..76b9294987 100644 --- a/phpBB/install/schemas/mysql_40_schema.sql +++ b/phpBB/install/schemas/mysql_40_schema.sql @@ -914,8 +914,7 @@ CREATE TABLE phpbb_users ( user_inactive_time int(11) UNSIGNED DEFAULT '0' NOT NULL, user_posts mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, user_lang varbinary(30) DEFAULT '' NOT NULL, - user_timezone decimal(5,2) DEFAULT '0' NOT NULL, - user_dst tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, + user_timezone varbinary(100) DEFAULT 'UTC' NOT NULL, user_dateformat varbinary(90) DEFAULT 'd M Y H:i' NOT NULL, user_style mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, user_rank mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, diff --git a/phpBB/install/schemas/mysql_41_schema.sql b/phpBB/install/schemas/mysql_41_schema.sql index 9615905625..30fb7a8623 100644 --- a/phpBB/install/schemas/mysql_41_schema.sql +++ b/phpBB/install/schemas/mysql_41_schema.sql @@ -914,8 +914,7 @@ CREATE TABLE phpbb_users ( user_inactive_time int(11) UNSIGNED DEFAULT '0' NOT NULL, user_posts mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, user_lang varchar(30) DEFAULT '' NOT NULL, - user_timezone decimal(5,2) DEFAULT '0' NOT NULL, - user_dst tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, + user_timezone varchar(100) DEFAULT 'UTC' NOT NULL, user_dateformat varchar(30) DEFAULT 'd M Y H:i' NOT NULL, user_style mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, user_rank mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, diff --git a/phpBB/install/schemas/oracle_schema.sql b/phpBB/install/schemas/oracle_schema.sql index 5d60d2a19e..a4b8686948 100644 --- a/phpBB/install/schemas/oracle_schema.sql +++ b/phpBB/install/schemas/oracle_schema.sql @@ -1702,8 +1702,7 @@ CREATE TABLE phpbb_users ( user_inactive_time number(11) DEFAULT '0' NOT NULL, user_posts number(8) DEFAULT '0' NOT NULL, user_lang varchar2(30) DEFAULT '' , - user_timezone number(5, 2) DEFAULT '0' NOT NULL, - user_dst number(1) DEFAULT '0' NOT NULL, + user_timezone varchar2(100) DEFAULT 'UTC' NOT NULL, user_dateformat varchar2(90) DEFAULT 'd M Y H:i' NOT NULL, user_style number(8) DEFAULT '0' NOT NULL, user_rank number(8) DEFAULT '0' NOT NULL, diff --git a/phpBB/install/schemas/postgres_schema.sql b/phpBB/install/schemas/postgres_schema.sql index d7377ac2e6..7138c818ff 100644 --- a/phpBB/install/schemas/postgres_schema.sql +++ b/phpBB/install/schemas/postgres_schema.sql @@ -1172,8 +1172,7 @@ CREATE TABLE phpbb_users ( user_inactive_time INT4 DEFAULT '0' NOT NULL CHECK (user_inactive_time >= 0), user_posts INT4 DEFAULT '0' NOT NULL CHECK (user_posts >= 0), user_lang varchar(30) DEFAULT '' NOT NULL, - user_timezone decimal(5,2) DEFAULT '0' NOT NULL, - user_dst INT2 DEFAULT '0' NOT NULL CHECK (user_dst >= 0), + user_timezone varchar(100) DEFAULT 'UTC' NOT NULL, user_dateformat varchar(30) DEFAULT 'd M Y H:i' NOT NULL, user_style INT4 DEFAULT '0' NOT NULL CHECK (user_style >= 0), user_rank INT4 DEFAULT '0' NOT NULL CHECK (user_rank >= 0), diff --git a/phpBB/install/schemas/sqlite_schema.sql b/phpBB/install/schemas/sqlite_schema.sql index 257937275c..5066ac97df 100644 --- a/phpBB/install/schemas/sqlite_schema.sql +++ b/phpBB/install/schemas/sqlite_schema.sql @@ -886,8 +886,7 @@ CREATE TABLE phpbb_users ( user_inactive_time INTEGER UNSIGNED NOT NULL DEFAULT '0', user_posts INTEGER UNSIGNED NOT NULL DEFAULT '0', user_lang varchar(30) NOT NULL DEFAULT '', - user_timezone decimal(5,2) NOT NULL DEFAULT '0', - user_dst INTEGER UNSIGNED NOT NULL DEFAULT '0', + user_timezone varchar(100) NOT NULL DEFAULT 'UTC', user_dateformat varchar(30) NOT NULL DEFAULT 'd M Y H:i', user_style INTEGER UNSIGNED NOT NULL DEFAULT '0', user_rank INTEGER UNSIGNED NOT NULL DEFAULT '0', From 1665434853fb09e70337d23955e1c9a5f3f0d19d Mon Sep 17 00:00:00 2001 From: Chris Smith Date: Wed, 7 Jul 2010 23:42:54 +0100 Subject: [PATCH 024/441] [feature/new-tz-handling] Remove code using legacy timezone properties. Code accessing the legacy user::$timezone and user::$dst properties has been removed and replaced with code utilising user::create_datetime(). Changed by Oleg: in viewtopic, memberlist and index use getTimestamp() + getOffset(). We show members that have birthdays on the specified date. getTimestamp() returns the current date in UTC. We add getOffset() to obtain the current local time in the viewing user's timezone. Then we find members having birthday on this date. Changed by Oleg again: Take leap year status out of the datetime object we have, this seems like it should work as one would expect. PHPBB3-9558 --- phpBB/feed.php | 2 +- phpBB/includes/functions_profile_fields.php | 9 ++++++--- phpBB/index.php | 5 +++-- phpBB/memberlist.php | 3 ++- phpBB/viewtopic.php | 3 ++- 5 files changed, 14 insertions(+), 8 deletions(-) diff --git a/phpBB/feed.php b/phpBB/feed.php index b8c0c370f9..d7092d6758 100644 --- a/phpBB/feed.php +++ b/phpBB/feed.php @@ -255,7 +255,7 @@ function feed_format_date($time) { global $user; - $zone_offset = (int) $user->timezone + (int) $user->dst; + $zone_offset = $user->create_datetime()->getOffset(); $sign = ($zone_offset < 0) ? '-' : '+'; $time_offset = abs($zone_offset); diff --git a/phpBB/includes/functions_profile_fields.php b/phpBB/includes/functions_profile_fields.php index ec29a1732d..aacfa82c54 100644 --- a/phpBB/includes/functions_profile_fields.php +++ b/phpBB/includes/functions_profile_fields.php @@ -555,9 +555,12 @@ class custom_profile 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 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; diff --git a/phpBB/index.php b/phpBB/index.php index 182efbc7e0..ccefd9833c 100644 --- a/phpBB/index.php +++ b/phpBB/index.php @@ -84,11 +84,12 @@ $legend = implode(', ', $legend); $birthday_list = array(); if ($config['load_birthdays'] && $config['allow_birthdays'] && $auth->acl_gets('u_viewprofile', 'a_user', 'a_useradd', 'a_userdel')) { - $now = phpbb_gmgetdate(time() + $user->timezone + $user->dst); + $time = $user->create_datetime(); + $now = phpbb_gmgetdate($time->getTimestamp() + $time->getOffset()); // Display birthdays of 29th february on 28th february in non-leap-years $leap_year_birthdays = ''; - if ($now['mday'] == 28 && $now['mon'] == 2 && !$user->format_date(time(), 'L')) + if ($now['mday'] == 28 && $now['mon'] == 2 && !$time->format('L')) { $leap_year_birthdays = " OR user_birthday LIKE '" . $db->sql_escape(sprintf('%2d-%2d-', 29, 2)) . "%'"; } diff --git a/phpBB/memberlist.php b/phpBB/memberlist.php index 556db2fa5d..ea8a6fc44b 100644 --- a/phpBB/memberlist.php +++ b/phpBB/memberlist.php @@ -1684,7 +1684,8 @@ function show_profile($data, $user_notes_enabled = false, $warn_user_enabled = f if ($bday_year) { - $now = phpbb_gmgetdate(time() + $user->timezone + $user->dst); + $now = $user->create_datetime(); + $now = phpbb_gmgetdate($now->getTimestamp() + $now->getOffset()); $diff = $now['mon'] - $bday_month; if ($diff == 0) diff --git a/phpBB/viewtopic.php b/phpBB/viewtopic.php index e78ba73cd7..782f02fd4b 100644 --- a/phpBB/viewtopic.php +++ b/phpBB/viewtopic.php @@ -965,7 +965,8 @@ $sql_ary = array( $sql = $db->sql_build_query('SELECT', $sql_ary); $result = $db->sql_query($sql); -$now = phpbb_gmgetdate(time() + $user->timezone + $user->dst); +$now = $user->create_datetime(); +$now = phpbb_gmgetdate($now->getTimestamp() + $now->getOffset()); // Posts are stored in the $rowset array while $attach_list, $user_cache // and the global bbcode_bitfield are built From 0f320a6c48d63154bba45c2937adeee79165816c Mon Sep 17 00:00:00 2001 From: Chris Smith Date: Thu, 8 Jul 2010 21:56:51 +0100 Subject: [PATCH 025/441] [feature/new-tz-handling] Update tz_select() to use the PHP timezone database. tz_select() now uses the PHP timezone database to generate the timezone selection box, it tries to use a translated language string otherwise falls back to a label produced from the timezone identifier. I've done this so new timezones are available immediately without a new language pack. PHPBB3-9558 --- phpBB/includes/functions.php | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index 9e2e57dd5e..fb8ea93e32 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -1071,28 +1071,45 @@ function style_select($default = '', $all = false) /** * Pick a timezone +* @todo Possible HTML escaping */ function tz_select($default = '', $truncate = false) { global $user; - $tz_select = ''; - foreach ($user->lang['tz_zones'] as $offset => $zone) + static $timezones; + + if (!isset($timezones)) { - if ($truncate) + $timezones = DateTimeZone::listIdentifiers(); + + sort($timezones); + } + + $tz_select = ''; + + foreach ($timezones as $timezone) + { + if (isset($user->lang['timezones'][$timezone])) { - $zone_trunc = truncate_string($zone, 50, 255, false, '...'); + $title = $label = $user->lang['timezones'][$timezone]; } else { - $zone_trunc = $zone; + // No label, we'll figure one out + // @todo rtl languages? + $bits = explode('/', strtolower(str_replace('_', ' ', $timezone))); + + $title = $label = ucwords(implode(' - ', $bits)); } - if (is_numeric($offset)) + if ($truncate) { - $selected = ($offset == $default) ? ' selected="selected"' : ''; - $tz_select .= ''; + $label = truncate_string($label, 50, 255, false, '...'); } + + $selected = ($timezone === $default) ? ' selected="selected"' : ''; + $tz_select .= ''; } return $tz_select; From 190b019fa28f59c018554916e33446d93efb7311 Mon Sep 17 00:00:00 2001 From: Chris Smith Date: Thu, 8 Jul 2010 22:09:24 +0100 Subject: [PATCH 026/441] [feature/new-tz-handling] Remove case mangling, the identifiers are correct. PHPBB3-9558 --- phpBB/includes/functions.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index fb8ea93e32..69bfe3e090 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -1098,9 +1098,9 @@ function tz_select($default = '', $truncate = false) { // No label, we'll figure one out // @todo rtl languages? - $bits = explode('/', strtolower(str_replace('_', ' ', $timezone))); + $bits = explode('/', str_replace('_', ' ', $timezone)); - $title = $label = ucwords(implode(' - ', $bits)); + $title = $label = implode(' - ', $bits); } if ($truncate) From f17664a00c9fa3b80a887bde2cdb2424a5d5567a Mon Sep 17 00:00:00 2001 From: Chris Smith Date: Fri, 9 Jul 2010 20:39:30 +0100 Subject: [PATCH 027/441] [feature/new-tz-handling] Correct a bug preventing multiple formats working. PHPBB3-9558 --- phpBB/includes/datetime.php | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/phpBB/includes/datetime.php b/phpBB/includes/datetime.php index 22b7f871fd..15e3c8b0b7 100644 --- a/phpBB/includes/datetime.php +++ b/phpBB/includes/datetime.php @@ -149,22 +149,22 @@ class phpbb_datetime extends DateTime if (!isset(self::$format_cache[$lang])) { self::$format_cache[$lang] = array(); + } - if (!isset(self::$format_cache[$lang][$format])) + 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)) { - // 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']; - } + self::$format_cache[$lang][$format]['lang']['May'] = $user->lang['datetime']['May_short']; } } From bb461c8daa97358e8bcce923a21eba0abd6ea3dc Mon Sep 17 00:00:00 2001 From: Oleg Pudeyev Date: Thu, 10 Mar 2011 19:14:53 -0500 Subject: [PATCH 028/441] [feature/new-tz-handling] Sort timezones in selector by offset. Since the list of timezones is very long, and users are likely to know their current offset but not necessarily which city that is nearby is in the timezone database, sort the list of timezones by offset. UTC is specially handled to show up before other GMT+0 timezones. PHPBB3-9558 --- phpBB/feed.php | 10 +---- phpBB/includes/functions.php | 71 +++++++++++++++++++++++++++++++++++- 2 files changed, 71 insertions(+), 10 deletions(-) diff --git a/phpBB/feed.php b/phpBB/feed.php index d7092d6758..025904e682 100644 --- a/phpBB/feed.php +++ b/phpBB/feed.php @@ -256,15 +256,7 @@ function feed_format_date($time) global $user; $zone_offset = $user->create_datetime()->getOffset(); - - $sign = ($zone_offset < 0) ? '-' : '+'; - $time_offset = abs($zone_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); + $offset_string = phpbb_format_timezone_offset($zone_offset); } return gmdate("Y-m-d\TH:i:s", $time + $zone_offset) . $offset_string; diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index 69bfe3e090..31a191b513 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -1069,6 +1069,65 @@ function style_select($default = '', $all = false) return $style_options; } +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 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; + } + } +} + /** * Pick a timezone * @todo Possible HTML escaping @@ -1083,7 +1142,17 @@ function tz_select($default = '', $truncate = false) { $timezones = DateTimeZone::listIdentifiers(); - sort($timezones); + foreach ($timezones as &$timezone) + { + $tz = new DateTimeZone($timezone); + $dt = new phpbb_datetime('now', $tz); + $offset = $dt->getOffset(); + $offset_string = phpbb_format_timezone_offset($offset); + $timezone = 'GMT' . $offset_string . ' - ' . $timezone; + } + unset($timezone); + + usort($timezones, 'tz_select_compare'); } $tz_select = ''; From da8009603d05acdccaff15cd610353d85c365220 Mon Sep 17 00:00:00 2001 From: Oleg Pudeyev Date: Tue, 15 Mar 2011 07:45:43 -0400 Subject: [PATCH 029/441] [feature/new-tz-handling] Preselect a timezone in registration. Use Javascript to obtain client's timezone offset and select the first timezone in our list with that offset. Changes for prosilver only. The javascript file should be shared between styles. PHPBB3-9558 --- phpBB/language/en/ucp.php | 1 + phpBB/styles/prosilver/template/timezone.js | 54 +++++++++++++++++++ .../template/ucp_prefs_personal.html | 10 +++- .../prosilver/template/ucp_register.html | 10 +++- 4 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 phpBB/styles/prosilver/template/timezone.js diff --git a/phpBB/language/en/ucp.php b/phpBB/language/en/ucp.php index c8ffbf31c0..9cbca4b740 100644 --- a/phpBB/language/en/ucp.php +++ b/phpBB/language/en/ucp.php @@ -399,6 +399,7 @@ $lang = array_merge($lang, array( 'SIGNATURE_EXPLAIN' => 'This is a block of text that can be added to posts you make. There is a %d character limit.', 'SIGNATURE_PREVIEW' => 'Your signature will appear like this in posts', 'SIGNATURE_TOO_LONG' => 'Your signature is too long.', + 'SELECT_TIMEZONE' => 'Select timezone', 'SORT' => 'Sort', 'SORT_COMMENT' => 'File comment', 'SORT_DOWNLOADS' => 'Downloads', diff --git a/phpBB/styles/prosilver/template/timezone.js b/phpBB/styles/prosilver/template/timezone.js new file mode 100644 index 0000000000..5d07b1d3ad --- /dev/null +++ b/phpBB/styles/prosilver/template/timezone.js @@ -0,0 +1,54 @@ +function phpbb_preselect_tz_select() +{ + var selector = document.getElementsByClassName('tz_select')[0]; + if (selector.value) + { + return; + } + // The offset returned here is in minutes and negated. + // http://www.w3schools.com/jsref/jsref_getTimezoneOffset.asp + var offset = (new Date()).getTimezoneOffset(); + if (offset < 0) + { + var sign = '+'; + offset = -offset; + } + else + { + var sign = '-'; + } + var minutes = offset % 60; + var hours = (offset - minutes) / 60; + if (hours < 10) + { + hours = '0' + hours.toString(); + } + else + { + hours = hours.toString(); + } + if (minutes < 10) + { + minutes = '0' + minutes.toString(); + } + else + { + minutes = minutes.toString(); + } + var prefix = 'GMT' + sign + hours + ':' + minutes; + var prefix_length = prefix.length; + for (var i = 0; i < selector.options.length; ++i) + { + var option = selector.options[i]; + if (option.value.substring(0, prefix_length) == prefix) + { + // Firefox scrolls the selector only to put the option into view; + // for negative-offset timezones, this means the first timezone + // of a particular offset will be the bottom one, and selected, + // with all other timezones not visible. Not much can be done + // about that here unfortunately. + option.selected = true; + break; + } + } +} diff --git a/phpBB/styles/prosilver/template/ucp_prefs_personal.html b/phpBB/styles/prosilver/template/ucp_prefs_personal.html index 635f321469..eae37b8021 100644 --- a/phpBB/styles/prosilver/template/ucp_prefs_personal.html +++ b/phpBB/styles/prosilver/template/ucp_prefs_personal.html @@ -75,7 +75,12 @@
-
+
+ +
@@ -141,4 +146,7 @@ // ]]> + + + diff --git a/phpBB/styles/prosilver/template/ucp_register.html b/phpBB/styles/prosilver/template/ucp_register.html index dd0e5ad02a..542a860f23 100644 --- a/phpBB/styles/prosilver/template/ucp_register.html +++ b/phpBB/styles/prosilver/template/ucp_register.html @@ -59,7 +59,12 @@
-
+
+ +
@@ -110,4 +115,7 @@ + + + From 56a7038aa57a1ec473196e01f68b7c8a1d0a89b6 Mon Sep 17 00:00:00 2001 From: Oleg Pudeyev Date: Tue, 15 Mar 2011 07:56:21 -0400 Subject: [PATCH 030/441] [feature/new-tz-handling] Removed DST options from templates. PHPBB3-9558 --- phpBB/adm/style/acp_users_prefs.html | 5 ----- phpBB/styles/prosilver/template/ucp_prefs_personal.html | 7 ------- phpBB/styles/subsilver2/template/ucp_prefs_personal.html | 4 ---- 3 files changed, 16 deletions(-) diff --git a/phpBB/adm/style/acp_users_prefs.html b/phpBB/adm/style/acp_users_prefs.html index a519447b2f..90db62984e 100644 --- a/phpBB/adm/style/acp_users_prefs.html +++ b/phpBB/adm/style/acp_users_prefs.html @@ -56,11 +56,6 @@
-
-
-
-
-

{L_BOARD_DATE_FORMAT_EXPLAIN}
diff --git a/phpBB/styles/prosilver/template/ucp_prefs_personal.html b/phpBB/styles/prosilver/template/ucp_prefs_personal.html index eae37b8021..267a3b8c2f 100644 --- a/phpBB/styles/prosilver/template/ucp_prefs_personal.html +++ b/phpBB/styles/prosilver/template/ucp_prefs_personal.html @@ -82,13 +82,6 @@
-
-
-
- - -
-

{L_BOARD_DATE_FORMAT_EXPLAIN}
diff --git a/phpBB/styles/subsilver2/template/ucp_prefs_personal.html b/phpBB/styles/subsilver2/template/ucp_prefs_personal.html index 8e4b04fc10..357e1fe100 100644 --- a/phpBB/styles/subsilver2/template/ucp_prefs_personal.html +++ b/phpBB/styles/subsilver2/template/ucp_prefs_personal.html @@ -77,10 +77,6 @@ - - {L_BOARD_DST}: - checked="checked" /> {L_YES}   checked="checked" /> {L_NO} - {L_BOARD_DATE_FORMAT}:
{L_BOARD_DATE_FORMAT_EXPLAIN} From e8e5d2b2c000e8a91897b4044c6a3005f60b86ab Mon Sep 17 00:00:00 2001 From: Oleg Pudeyev Date: Tue, 15 Mar 2011 17:37:15 -0400 Subject: [PATCH 031/441] [feature/new-tz-handling] Removed DST and numeric timezone-related language. PHPBB3-9558 --- phpBB/language/en/acp/board.php | 1 - phpBB/language/en/common.php | 87 --------------------------------- phpBB/language/en/help_faq.php | 2 +- phpBB/language/en/ucp.php | 1 - 4 files changed, 1 insertion(+), 90 deletions(-) diff --git a/phpBB/language/en/acp/board.php b/phpBB/language/en/acp/board.php index ff516a8146..0be4c0df6d 100644 --- a/phpBB/language/en/acp/board.php +++ b/phpBB/language/en/acp/board.php @@ -49,7 +49,6 @@ $lang = array_merge($lang, array( 'OVERRIDE_STYLE_EXPLAIN' => 'Replaces user’s style with the default.', 'SITE_DESC' => 'Site description', 'SITE_NAME' => 'Site name', - 'SYSTEM_DST' => 'Enable Summer Time/DST', 'SYSTEM_TIMEZONE' => 'Guest timezone', 'SYSTEM_TIMEZONE_EXPLAIN' => 'Timezone to use for displaying times to users who are not logged in (guests, bots). Logged in users set their timezone during registration and can change it in their user control panel.', 'WARNINGS_EXPIRE' => 'Warning duration', diff --git a/phpBB/language/en/common.php b/phpBB/language/en/common.php index 44a63a6acb..bcb08a8b73 100644 --- a/phpBB/language/en/common.php +++ b/phpBB/language/en/common.php @@ -786,93 +786,6 @@ $lang = array_merge($lang, array( 'Dec' => 'Dec', ), - 'tz' => array( - '-12' => 'UTC - 12 hours', - '-11' => 'UTC - 11 hours', - '-10' => 'UTC - 10 hours', - '-9.5' => 'UTC - 9:30 hours', - '-9' => 'UTC - 9 hours', - '-8' => 'UTC - 8 hours', - '-7' => 'UTC - 7 hours', - '-6' => 'UTC - 6 hours', - '-5' => 'UTC - 5 hours', - '-4.5' => 'UTC - 4:30 hours', - '-4' => 'UTC - 4 hours', - '-3.5' => 'UTC - 3:30 hours', - '-3' => 'UTC - 3 hours', - '-2' => 'UTC - 2 hours', - '-1' => 'UTC - 1 hour', - '0' => 'UTC', - '1' => 'UTC + 1 hour', - '2' => 'UTC + 2 hours', - '3' => 'UTC + 3 hours', - '3.5' => 'UTC + 3:30 hours', - '4' => 'UTC + 4 hours', - '4.5' => 'UTC + 4:30 hours', - '5' => 'UTC + 5 hours', - '5.5' => 'UTC + 5:30 hours', - '5.75' => 'UTC + 5:45 hours', - '6' => 'UTC + 6 hours', - '6.5' => 'UTC + 6:30 hours', - '7' => 'UTC + 7 hours', - '8' => 'UTC + 8 hours', - '8.75' => 'UTC + 8:45 hours', - '9' => 'UTC + 9 hours', - '9.5' => 'UTC + 9:30 hours', - '10' => 'UTC + 10 hours', - '10.5' => 'UTC + 10:30 hours', - '11' => 'UTC + 11 hours', - '11.5' => 'UTC + 11:30 hours', - '12' => 'UTC + 12 hours', - '12.75' => 'UTC + 12:45 hours', - '13' => 'UTC + 13 hours', - '14' => 'UTC + 14 hours', - 'dst' => '[ DST ]', - ), - - 'tz_zones' => array( - '-12' => '[UTC - 12] Baker Island Time', - '-11' => '[UTC - 11] Niue Time, Samoa Standard Time', - '-10' => '[UTC - 10] Hawaii-Aleutian Standard Time, Cook Island Time', - '-9.5' => '[UTC - 9:30] Marquesas Islands Time', - '-9' => '[UTC - 9] Alaska Standard Time, Gambier Island Time', - '-8' => '[UTC - 8] Pacific Standard Time', - '-7' => '[UTC - 7] Mountain Standard Time', - '-6' => '[UTC - 6] Central Standard Time', - '-5' => '[UTC - 5] Eastern Standard Time', - '-4.5' => '[UTC - 4:30] Venezuelan Standard Time', - '-4' => '[UTC - 4] Atlantic Standard Time', - '-3.5' => '[UTC - 3:30] Newfoundland Standard Time', - '-3' => '[UTC - 3] Amazon Standard Time, Central Greenland Time', - '-2' => '[UTC - 2] Fernando de Noronha Time, South Georgia & the South Sandwich Islands Time', - '-1' => '[UTC - 1] Azores Standard Time, Cape Verde Time, Eastern Greenland Time', - '0' => '[UTC] Western European Time, Greenwich Mean Time', - '1' => '[UTC + 1] Central European Time, West African Time', - '2' => '[UTC + 2] Eastern European Time, Central African Time', - '3' => '[UTC + 3] Moscow Standard Time, Eastern African Time', - '3.5' => '[UTC + 3:30] Iran Standard Time', - '4' => '[UTC + 4] Gulf Standard Time, Samara Standard Time', - '4.5' => '[UTC + 4:30] Afghanistan Time', - '5' => '[UTC + 5] Pakistan Standard Time, Yekaterinburg Standard Time', - '5.5' => '[UTC + 5:30] Indian Standard Time, Sri Lanka Time', - '5.75' => '[UTC + 5:45] Nepal Time', - '6' => '[UTC + 6] Bangladesh Time, Bhutan Time, Novosibirsk Standard Time', - '6.5' => '[UTC + 6:30] Cocos Islands Time, Myanmar Time', - '7' => '[UTC + 7] Indochina Time, Krasnoyarsk Standard Time', - '8' => '[UTC + 8] Chinese Standard Time, Australian Western Standard Time, Irkutsk Standard Time', - '8.75' => '[UTC + 8:45] Southeastern Western Australia Standard Time', - '9' => '[UTC + 9] Japan Standard Time, Korea Standard Time, Chita Standard Time', - '9.5' => '[UTC + 9:30] Australian Central Standard Time', - '10' => '[UTC + 10] Australian Eastern Standard Time, Vladivostok Standard Time', - '10.5' => '[UTC + 10:30] Lord Howe Standard Time', - '11' => '[UTC + 11] Solomon Island Time, Magadan Standard Time', - '11.5' => '[UTC + 11:30] Norfolk Island Time', - '12' => '[UTC + 12] New Zealand Time, Fiji Time, Kamchatka Standard Time', - '12.75' => '[UTC + 12:45] Chatham Islands Time', - '13' => '[UTC + 13] Tonga Time, Phoenix Islands Time', - '14' => '[UTC + 14] Line Island Time', - ), - // The value is only an example and will get replaced by the current time on view 'dateformats' => array( 'd M Y, H:i' => '01 Jan 2007, 13:37', diff --git a/phpBB/language/en/help_faq.php b/phpBB/language/en/help_faq.php index 6ca9589913..5f9af2d721 100644 --- a/phpBB/language/en/help_faq.php +++ b/phpBB/language/en/help_faq.php @@ -88,7 +88,7 @@ $help = array( ), array( 0 => 'I changed the timezone and the time is still wrong!', - 1 => 'If you are sure you have set the timezone and Summer Time/DST correctly and the time is still incorrect, then the time stored on the server clock is incorrect. Please notify an administrator to correct the problem.' + 1 => 'If you are sure you have set the timezone correctly and the time is still incorrect, then the time stored on the server clock is incorrect. Please notify an administrator to correct the problem.' ), array( 0 => 'My language is not in the list!', diff --git a/phpBB/language/en/ucp.php b/phpBB/language/en/ucp.php index 9cbca4b740..3925005968 100644 --- a/phpBB/language/en/ucp.php +++ b/phpBB/language/en/ucp.php @@ -103,7 +103,6 @@ $lang = array_merge($lang, array( 'BIRTHDAY_EXPLAIN' => 'Setting a year will list your age when it is your birthday.', 'BOARD_DATE_FORMAT' => 'My date format', 'BOARD_DATE_FORMAT_EXPLAIN' => 'The syntax used is identical to the PHP date() function.', - 'BOARD_DST' => 'Summer Time/DST is in effect', 'BOARD_LANGUAGE' => 'My language', 'BOARD_STYLE' => 'My board style', 'BOARD_TIMEZONE' => 'My timezone', From b672fc7ae113c0e01f1d7ce4ffae3eb26e57b586 Mon Sep 17 00:00:00 2001 From: Oleg Pudeyev Date: Tue, 26 Apr 2011 22:11:45 -0400 Subject: [PATCH 032/441] [feature/new-tz-handling] Started on database updater changes. The changes are tricky since we need to drop user_dst column from users table, but we need it during the data migration process to properly calculate effective timezones for all users. The change here converts user_timezone to vchar and computes timezone identifiers from the offsets. It uses database-specific functions for building SQL conditionals and concatenations which need to be implemented, probably in a separate ticket. As a result the current code is not functional. PHPBB3-9558 --- phpBB/install/database_update.php | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/phpBB/install/database_update.php b/phpBB/install/database_update.php index fa0fba9dc7..9d550cf938 100644 --- a/phpBB/install/database_update.php +++ b/phpBB/install/database_update.php @@ -1090,6 +1090,9 @@ function database_update_info() GROUPS_TABLE => array( 'group_legend' => array('UINT', 0), ), + USERS_TABLE => array( + 'user_timezone' => array('VCHAR:100', ''), + ), ), 'drop_columns' => array( STYLES_TABLE => array( @@ -2352,6 +2355,25 @@ function change_database_data(&$no_updates, $version) set_config('teampage_memberships', '1'); } + // Update timezones + // user_dst is 0 if not in dst and 1 if in dst; + // this happens to be exactly the correction that should be added to the timezone offset + // to obtain dst offset. + // Parenthesize here because we operate on this value later. + $active_offset = '(user_timezone + user_dst)'; + // Now we have a tricky problem of forcing the plus sign into the expression. + // Build it via a conditional since there cannot be a portable printf equivalent in databases. + // Note that active offset is not an absolute value here - it is an expression that will + // be evaluated by the database during query execution. + // We don't print - here because it will come from active offset. + $sign = $db->conditional_sql("$active_offset < 0", '', '+'); + // Use database-specific escaping because strings are quoted differently by different databases. + $new_value = $db->concatenate_sql($db->sql_escape('GMT'), $sign, $active_offset); + $sql = 'UPDATE ' . USERS_TABLE . ' + SET user_timezone = ' . $new_value; + _sql($sql, $errored, $error_ary); + // After we have calculated the timezones we can delete user_dst column from user table. + $no_updates = false; break; } From e8830f605f73a0c8fa5c3ea579ee18f295b81600 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Tue, 27 Mar 2012 01:18:02 +0200 Subject: [PATCH 033/441] [ticket/10605] Use unset() instead of checking user_id over and over again. PHPBB3-10605 --- phpBB/includes/functions_privmsgs.php | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/phpBB/includes/functions_privmsgs.php b/phpBB/includes/functions_privmsgs.php index 34f16ea9da..59dea50094 100644 --- a/phpBB/includes/functions_privmsgs.php +++ b/phpBB/includes/functions_privmsgs.php @@ -1134,13 +1134,9 @@ function phpbb_delete_user_pms($user_id) $db->sql_query($sql); } + unset($undelivered_user[$user_id]); foreach ($undelivered_user as $_user_id => $ary) { - if ($_user_id == $user_id) - { - continue; - } - $sql = 'UPDATE ' . USERS_TABLE . ' SET user_new_privmsg = user_new_privmsg - ' . sizeof($ary) . ', user_unread_privmsg = user_unread_privmsg - ' . sizeof($ary) . ' From 2203bc204e55c33e2e9b212eeb0c7bf2e3060851 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Tue, 27 Mar 2012 01:29:29 +0200 Subject: [PATCH 034/441] [ticket/10605] Turn $undelivered_user into a real array of counters. PHPBB3-10605 --- phpBB/includes/functions_privmsgs.php | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/phpBB/includes/functions_privmsgs.php b/phpBB/includes/functions_privmsgs.php index 59dea50094..352bd4d15d 100644 --- a/phpBB/includes/functions_privmsgs.php +++ b/phpBB/includes/functions_privmsgs.php @@ -1113,7 +1113,15 @@ function phpbb_delete_user_pms($user_id) { // Undelivered messages $undelivered_msg[] = $row['msg_id']; - $undelivered_user[$row['user_id']][] = true; + + if (isset($undelivered_user[$row['user_id']])) + { + ++$undelivered_user[$row['user_id']]; + } + else + { + $undelivered_user[$row['user_id']] = 1; + } } $delete_rows[$row['msg_id']] = true; @@ -1135,11 +1143,11 @@ function phpbb_delete_user_pms($user_id) } unset($undelivered_user[$user_id]); - foreach ($undelivered_user as $_user_id => $ary) + foreach ($undelivered_user as $_user_id => $count) { $sql = 'UPDATE ' . USERS_TABLE . ' - SET user_new_privmsg = user_new_privmsg - ' . sizeof($ary) . ', - user_unread_privmsg = user_unread_privmsg - ' . sizeof($ary) . ' + SET user_new_privmsg = user_new_privmsg - ' . $count . ', + user_unread_privmsg = user_unread_privmsg - ' . $count . ' WHERE user_id = ' . $_user_id; $db->sql_query($sql); } From dbc7a69ad2bf6b062a4d7a40d62be29a410b5c18 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Tue, 27 Mar 2012 01:30:52 +0200 Subject: [PATCH 035/441] [ticket/10605] Remove unused variable declarations. PHPBB3-10605 --- phpBB/includes/functions_privmsgs.php | 1 - 1 file changed, 1 deletion(-) diff --git a/phpBB/includes/functions_privmsgs.php b/phpBB/includes/functions_privmsgs.php index 352bd4d15d..4ff0c53420 100644 --- a/phpBB/includes/functions_privmsgs.php +++ b/phpBB/includes/functions_privmsgs.php @@ -1106,7 +1106,6 @@ function phpbb_delete_user_pms($user_id) $result = $db->sql_query($sql); $undelivered_msg = $undelivered_user = $delete_rows = array(); - $num_unread = $num_new = $num_deleted = 0; while ($row = $db->sql_fetchrow($result)) { if ($row['author_id'] == $user_id && $row['folder_id'] == PRIVMSGS_NO_BOX) From 9040f18d7cf9de137acbac6072dc2ffd3cede1b5 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Tue, 27 Mar 2012 01:35:01 +0200 Subject: [PATCH 036/441] [ticket/10605] Remove unnecessary array_keys calls on $delete_rows. PHPBB3-10605 --- phpBB/includes/functions_privmsgs.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/phpBB/includes/functions_privmsgs.php b/phpBB/includes/functions_privmsgs.php index 4ff0c53420..00029a1986 100644 --- a/phpBB/includes/functions_privmsgs.php +++ b/phpBB/includes/functions_privmsgs.php @@ -1123,7 +1123,7 @@ function phpbb_delete_user_pms($user_id) } } - $delete_rows[$row['msg_id']] = true; + $delete_rows[(int) $row['msg_id']] = (int) $row['msg_id']; } $db->sql_freeresult($result); @@ -1154,13 +1154,13 @@ function phpbb_delete_user_pms($user_id) // Delete private message data $sql = 'DELETE FROM ' . PRIVMSGS_TO_TABLE . " WHERE user_id = $user_id - AND " . $db->sql_in_set('msg_id', array_keys($delete_rows)); + AND " . $db->sql_in_set('msg_id', $delete_rows); $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', array_keys($delete_rows)); + WHERE ' . $db->sql_in_set('msg_id', $delete_rows); $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) From dd53d0576d8256e37074cc23dd5b9769acc12d1a Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Tue, 27 Mar 2012 01:39:49 +0200 Subject: [PATCH 037/441] [ticket/10605] Remove unnecessary $delete_ids array. PHPBB3-10605 --- phpBB/includes/functions_privmsgs.php | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/phpBB/includes/functions_privmsgs.php b/phpBB/includes/functions_privmsgs.php index 00029a1986..23f582641b 100644 --- a/phpBB/includes/functions_privmsgs.php +++ b/phpBB/includes/functions_privmsgs.php @@ -1169,9 +1169,7 @@ function phpbb_delete_user_pms($user_id) } $db->sql_freeresult($result); - $delete_ids = array_keys($delete_rows); - - if (sizeof($delete_ids)) + if (!empty($delete_rows)) { // Check if there are any attachments we need to remove if (!function_exists('delete_attachments')) @@ -1179,10 +1177,10 @@ function phpbb_delete_user_pms($user_id) include($phpbb_root_path . 'includes/functions_admin.' . $phpEx); } - delete_attachments('message', $delete_ids, false); + delete_attachments('message', $delete_rows, false); $sql = 'DELETE FROM ' . PRIVMSGS_TABLE . ' - WHERE ' . $db->sql_in_set('msg_id', $delete_ids); + WHERE ' . $db->sql_in_set('msg_id', $delete_rows); $db->sql_query($sql); } From ad073d22b9e543d5842af7b8ef94fe7e6b443504 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Tue, 27 Mar 2012 01:43:09 +0200 Subject: [PATCH 038/441] [ticket/10605] Break long comment into multiple lines 80 chars short. PHPBB3-10605 --- phpBB/includes/functions_privmsgs.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/phpBB/includes/functions_privmsgs.php b/phpBB/includes/functions_privmsgs.php index 23f582641b..e7beae3fab 100644 --- a/phpBB/includes/functions_privmsgs.php +++ b/phpBB/includes/functions_privmsgs.php @@ -1184,7 +1184,8 @@ function phpbb_delete_user_pms($user_id) $db->sql_query($sql); } - // Set the remaining author id to anonymous - this way users are still able to read messages from users being removed + // Set the remaining author id to anonymous + // This way users are still able to read messages from users being removed $sql = 'UPDATE ' . PRIVMSGS_TO_TABLE . ' SET author_id = ' . ANONYMOUS . ' WHERE author_id = ' . $user_id; From 9c8aab4d32a001ae66fe005b7124737fc5ad7dd6 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Tue, 27 Mar 2012 02:02:17 +0200 Subject: [PATCH 039/441] [ticket/10605] Rename $delete_rows to $delete_ids. PHPBB3-10605 --- phpBB/includes/functions_privmsgs.php | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/phpBB/includes/functions_privmsgs.php b/phpBB/includes/functions_privmsgs.php index e7beae3fab..576da4d439 100644 --- a/phpBB/includes/functions_privmsgs.php +++ b/phpBB/includes/functions_privmsgs.php @@ -1105,7 +1105,7 @@ function phpbb_delete_user_pms($user_id) AND folder_id = ' . PRIVMSGS_NO_BOX . ')'; $result = $db->sql_query($sql); - $undelivered_msg = $undelivered_user = $delete_rows = array(); + $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) @@ -1123,11 +1123,11 @@ function phpbb_delete_user_pms($user_id) } } - $delete_rows[(int) $row['msg_id']] = (int) $row['msg_id']; + $delete_ids[(int) $row['msg_id']] = (int) $row['msg_id']; } $db->sql_freeresult($result); - if (!sizeof($delete_rows)) + if (empty($delete_ids)) { return false; } @@ -1154,22 +1154,22 @@ function phpbb_delete_user_pms($user_id) // Delete private message data $sql = 'DELETE FROM ' . PRIVMSGS_TO_TABLE . " WHERE user_id = $user_id - AND " . $db->sql_in_set('msg_id', $delete_rows); + AND " . $db->sql_in_set('msg_id', $delete_ids); $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_rows); + WHERE ' . $db->sql_in_set('msg_id', $delete_ids); $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) { - unset($delete_rows[$row['msg_id']]); + unset($delete_ids[$row['msg_id']]); } $db->sql_freeresult($result); - if (!empty($delete_rows)) + if (!empty($delete_ids)) { // Check if there are any attachments we need to remove if (!function_exists('delete_attachments')) @@ -1177,10 +1177,10 @@ function phpbb_delete_user_pms($user_id) include($phpbb_root_path . 'includes/functions_admin.' . $phpEx); } - delete_attachments('message', $delete_rows, false); + delete_attachments('message', $delete_ids, false); $sql = 'DELETE FROM ' . PRIVMSGS_TABLE . ' - WHERE ' . $db->sql_in_set('msg_id', $delete_rows); + WHERE ' . $db->sql_in_set('msg_id', $delete_ids); $db->sql_query($sql); } From 0397b462174887bda3fea4bcebf9a26f6b591a3e Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 27 Mar 2012 17:29:03 +0200 Subject: [PATCH 040/441] [ticket/10605] Split query to be able to use indexes PHPBB3-10605 --- phpBB/includes/functions_privmsgs.php | 34 ++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/phpBB/includes/functions_privmsgs.php b/phpBB/includes/functions_privmsgs.php index 576da4d439..dd81e8f92d 100644 --- a/phpBB/includes/functions_privmsgs.php +++ b/phpBB/includes/functions_privmsgs.php @@ -1098,11 +1098,11 @@ function phpbb_delete_user_pms($user_id) } // Get PM Information for later deleting + // The two queries where split, so we can use our indexes + // Part 1: get PMs the user received $sql = 'SELECT msg_id, author_id, folder_id, pm_unread, pm_new FROM ' . PRIVMSGS_TO_TABLE . ' - WHERE user_id = ' . $user_id . ' - OR (author_id = ' . $user_id . ' - AND folder_id = ' . PRIVMSGS_NO_BOX . ')'; + WHERE user_id = ' . $user_id; $result = $db->sql_query($sql); $undelivered_msg = $undelivered_user = $delete_ids = array(); @@ -1127,6 +1127,34 @@ function phpbb_delete_user_pms($user_id) } $db->sql_freeresult($result); + // Part 2: get PMs the user sent + $sql = 'SELECT msg_id, author_id, folder_id, pm_unread, pm_new + FROM ' . PRIVMSGS_TO_TABLE . ' + WHERE author_id = ' . $user_id . ' + 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']; + } + $db->sql_freeresult($result); + if (empty($delete_ids)) { return false; From b9324577aca6f7f7632b609e975e510e25d8ec86 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 27 Mar 2012 17:32:55 +0200 Subject: [PATCH 041/441] =?UTF-8?q?[ticket/10605]=20Reset=20user=C2=B4s=20?= =?UTF-8?q?pm=20count=20to=200=20when=20deleting=20his=20PMs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PHPBB3-10605 --- phpBB/includes/functions_privmsgs.php | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/phpBB/includes/functions_privmsgs.php b/phpBB/includes/functions_privmsgs.php index dd81e8f92d..14a6d83b2a 100644 --- a/phpBB/includes/functions_privmsgs.php +++ b/phpBB/includes/functions_privmsgs.php @@ -1169,7 +1169,17 @@ function phpbb_delete_user_pms($user_id) $db->sql_query($sql); } - unset($undelivered_user[$user_id]); + // 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]); + } + foreach ($undelivered_user as $_user_id => $count) { $sql = 'UPDATE ' . USERS_TABLE . ' From 31ea2da5ac5dbec6a7a6f1a2575960af582df2f3 Mon Sep 17 00:00:00 2001 From: Shibu Lijack Date: Sat, 31 Mar 2012 18:02:49 +0530 Subject: [PATCH 042/441] [ticket/10734] CSS tweaks Modified colours.css Removed the corner images. Added border radius. PHPBB3-10734 --- phpBB/styles/prosilver/theme/colours.css | 33 +++++++++++++++++++++--- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/phpBB/styles/prosilver/theme/colours.css b/phpBB/styles/prosilver/theme/colours.css index 855febf4aa..11fa6932db 100644 --- a/phpBB/styles/prosilver/theme/colours.css +++ b/phpBB/styles/prosilver/theme/colours.css @@ -47,25 +47,50 @@ hr { background-color: #12A3EB; background-image: url("./images/bg_header.gif"); color: #FFFFFF; + border-radius: 7px; + -webkit-border-radius: 7px; + -moz-border-radius: 7px; } .navbar { background-color: #cadceb; + border-radius: 7px; + -webkit-border-radius: 7px; + -moz-border-radius: 7px; + } .forabg { background-color: #0076b1; background-image: url("./images/bg_list.gif"); + border-radius: 7px; + -webkit-border-radius: 7px; + -moz-border-radius: 7px; + } .forumbg { background-color: #12A3EB; background-image: url("./images/bg_header.gif"); + border-radius: 7px; + -webkit-border-radius: 7px; + -moz-border-radius: 7px; + } .panel { background-color: #ECF1F3; color: #28313F; + border-radius: 7px; + -webkit-border-radius: 7px; + -moz-border-radius: 7px; +} + +.post { + border-radius: 7px; + -webkit-border-radius: 7px; + -moz-border-radius: 7px; + } .post:target .content { @@ -89,19 +114,19 @@ hr { } span.corners-top { - background-image: url("./images/corners_left.png"); + } span.corners-top span { - background-image: url("./images/corners_right.png"); + } span.corners-bottom { - background-image: url("./images/corners_left.png"); + } span.corners-bottom span { - background-image: url("./images/corners_right.png"); + } /* Horizontal lists From 609e8e3b1123c6144712cf7c94aa6de5ad49bce7 Mon Sep 17 00:00:00 2001 From: Shibu Lijack Date: Sat, 31 Mar 2012 18:32:05 +0530 Subject: [PATCH 043/441] [ticket/10734] Fixed template files Removed unnecessary span from overall_header, overall_footer, forumlist_body, viewforum_body. PHPBB3-10734 --- .../prosilver/template/forumlist_body.html | 10 ++++----- .../prosilver/template/overall_footer.html | 6 ++--- .../prosilver/template/overall_header.html | 10 ++++----- .../prosilver/template/viewforum_body.html | 22 +++++++++---------- 4 files changed, 24 insertions(+), 24 deletions(-) diff --git a/phpBB/styles/prosilver/template/forumlist_body.html b/phpBB/styles/prosilver/template/forumlist_body.html index d6596203e5..cb6d14e47e 100644 --- a/phpBB/styles/prosilver/template/forumlist_body.html +++ b/phpBB/styles/prosilver/template/forumlist_body.html @@ -3,13 +3,13 @@ - +
-
+
  • @@ -55,14 +55,14 @@
-
+
-
+
{L_NO_FORUMS} -
+
diff --git a/phpBB/styles/prosilver/template/overall_footer.html b/phpBB/styles/prosilver/template/overall_footer.html index 1561bae26a..81736cc917 100644 --- a/phpBB/styles/prosilver/template/overall_footer.html +++ b/phpBB/styles/prosilver/template/overall_footer.html @@ -3,8 +3,8 @@ +
-
+
  • @@ -156,16 +156,16 @@
-
+
-
+
{L_NO_TOPICS} -
+
From 259b86199be326e75080630f28407114aab7a56a Mon Sep 17 00:00:00 2001 From: Shibu Lijack Date: Sat, 31 Mar 2012 18:57:49 +0530 Subject: [PATCH 044/441] [ticket/10734] Fixed template files Removed unnecessary span from several other template files PHPBB3-10734 --- phpBB/styles/prosilver/template/faq_body.html | 4 ++-- phpBB/styles/prosilver/template/login_body.html | 8 ++++---- phpBB/styles/prosilver/template/login_forum.html | 4 ++-- .../prosilver/template/memberlist_body.html | 12 ++++++------ .../prosilver/template/memberlist_email.html | 8 ++++---- .../prosilver/template/memberlist_search.html | 4 ++-- .../prosilver/template/memberlist_view.html | 12 ++++++------ .../styles/prosilver/template/message_body.html | 4 ++-- .../prosilver/template/search_results.html | 16 ++++++++-------- 9 files changed, 36 insertions(+), 36 deletions(-) diff --git a/phpBB/styles/prosilver/template/faq_body.html b/phpBB/styles/prosilver/template/faq_body.html index 36d677a505..7aa32b66b9 100644 --- a/phpBB/styles/prosilver/template/faq_body.html +++ b/phpBB/styles/prosilver/template/faq_body.html @@ -4,7 +4,7 @@
- + diff --git a/phpBB/styles/prosilver/template/login_body.html b/phpBB/styles/prosilver/template/login_body.html index 03615398c1..a3a70e3333 100644 --- a/phpBB/styles/prosilver/template/login_body.html +++ b/phpBB/styles/prosilver/template/login_body.html @@ -8,7 +8,7 @@
-
+

{LOGIN_EXPLAIN}{L_LOGIN}

@@ -45,13 +45,13 @@
-
+
-
+

{L_REGISTER}

@@ -61,7 +61,7 @@

{L_REGISTER}

-
+
diff --git a/phpBB/styles/prosilver/template/login_forum.html b/phpBB/styles/prosilver/template/login_forum.html index 569638411c..e66e531fcd 100644 --- a/phpBB/styles/prosilver/template/login_forum.html +++ b/phpBB/styles/prosilver/template/login_forum.html @@ -5,7 +5,7 @@ {S_FORM_TOKEN}
-
+

{L_LOGIN_FORUM}

@@ -27,7 +27,7 @@ {S_LOGIN_REDIRECT} -
+
diff --git a/phpBB/styles/prosilver/template/memberlist_body.html b/phpBB/styles/prosilver/template/memberlist_body.html index 504d1b80ef..f6f7bdc485 100644 --- a/phpBB/styles/prosilver/template/memberlist_body.html +++ b/phpBB/styles/prosilver/template/memberlist_body.html @@ -28,7 +28,7 @@

{PAGE_TITLE}: {SEARCH_WORDS}

-
+
-
+
-
+
@@ -77,11 +77,11 @@
-
+
-
+
@@ -121,7 +121,7 @@
-
+
diff --git a/phpBB/styles/prosilver/template/memberlist_email.html b/phpBB/styles/prosilver/template/memberlist_email.html index 9759abb859..062d266252 100644 --- a/phpBB/styles/prosilver/template/memberlist_email.html +++ b/phpBB/styles/prosilver/template/memberlist_email.html @@ -5,7 +5,7 @@
-
+

{ERROR_MESSAGE}

@@ -46,17 +46,17 @@
-
+
-
+
-
+
{S_FORM_TOKEN}
diff --git a/phpBB/styles/prosilver/template/memberlist_search.html b/phpBB/styles/prosilver/template/memberlist_search.html index 9df648f644..8d2ccf044c 100644 --- a/phpBB/styles/prosilver/template/memberlist_search.html +++ b/phpBB/styles/prosilver/template/memberlist_search.html @@ -44,7 +44,7 @@ function insert_single(user)
-
+

{L_FIND_USERNAME_EXPLAIN}

@@ -118,7 +118,7 @@ function insert_single(user) {S_FORM_TOKEN} -
+
diff --git a/phpBB/styles/prosilver/template/memberlist_view.html b/phpBB/styles/prosilver/template/memberlist_view.html index d8bb92a731..b50e3a84ad 100644 --- a/phpBB/styles/prosilver/template/memberlist_view.html +++ b/phpBB/styles/prosilver/template/memberlist_view.html @@ -4,7 +4,7 @@
-
+
@@ -49,11 +49,11 @@
-
+
-
+

{L_CONTACT_USER} {USERNAME}

@@ -94,18 +94,18 @@
-
+
-
+

{L_SIGNATURE}

{SIGNATURE}
-
+
diff --git a/phpBB/styles/prosilver/template/message_body.html b/phpBB/styles/prosilver/template/message_body.html index 3a970769b7..645807cd89 100644 --- a/phpBB/styles/prosilver/template/message_body.html +++ b/phpBB/styles/prosilver/template/message_body.html @@ -5,11 +5,11 @@
-
+

{MESSAGE_TITLE}

{MESSAGE_TEXT}

{L_RETURN_TO_SEARCH_ADV}

-
+
diff --git a/phpBB/styles/prosilver/template/search_results.html b/phpBB/styles/prosilver/template/search_results.html index 942d154d44..dbda076086 100644 --- a/phpBB/styles/prosilver/template/search_results.html +++ b/phpBB/styles/prosilver/template/search_results.html @@ -36,7 +36,7 @@
-
+
  • @@ -71,13 +71,13 @@
-
+
-
+
{L_NO_SEARCH_RESULTS} -
+
@@ -85,7 +85,7 @@
-
+
@@ -114,13 +114,13 @@ -
+
-
+
{L_NO_SEARCH_RESULTS} -
+
From d0e0f3e72b6d37b63c1e2eac7e1fb5a789a4dc43 Mon Sep 17 00:00:00 2001 From: Shibu Lijack Date: Sat, 31 Mar 2012 19:54:40 +0530 Subject: [PATCH 045/441] [ticket/10734] Fixed common.css Fixed padding. PHPBB3-10734 --- phpBB/styles/prosilver/theme/common.css | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/phpBB/styles/prosilver/theme/common.css b/phpBB/styles/prosilver/theme/common.css index 31015b28f9..6fd410029d 100644 --- a/phpBB/styles/prosilver/theme/common.css +++ b/phpBB/styles/prosilver/theme/common.css @@ -251,30 +251,35 @@ a#logo:hover { .headerbar { background: transparent none repeat-x 0 0; margin-bottom: 4px; - padding: 0 5px; + padding: 5px; } .navbar { padding: 0 10px; + background-color: #ebebeb; + padding: 5px 10px 5px 10px; } .forabg { background: transparent none repeat-x 0 0; margin-bottom: 4px; - padding: 0 5px; + padding: 5px; clear: both; } .forumbg { background: transparent none repeat-x 0 0; margin-bottom: 4px; - padding: 0 5px; + padding: 5px; clear: both; } .panel { margin-bottom: 4px; padding: 0 10px; + padding: 5px 10px; + background-color: #f3f3f3; + color: #3f3f3f; } .post { @@ -319,6 +324,11 @@ span.corners-bottom span { background-position: 100% 100%; } +span.clear { + background-image: none; + clear: both; +} + .headbg span.corners-bottom { margin-bottom: -1px; } From 05cbecb5581b0191ce9ba82b7966858595f81f85 Mon Sep 17 00:00:00 2001 From: Shibu Lijack Date: Sat, 31 Mar 2012 20:40:01 +0530 Subject: [PATCH 046/441] [ticket/10734] Removed unnecessary images Deleted the corner_left and corner_right images. PHPBB-10734 --- phpBB/styles/prosilver/theme/images/.DS_Store | Bin 0 -> 6148 bytes .../prosilver/theme/images/corners_left.gif | Bin 55 -> 0 bytes .../prosilver/theme/images/corners_left.png | Bin 195 -> 0 bytes .../prosilver/theme/images/corners_right.gif | Bin 56 -> 0 bytes .../prosilver/theme/images/corners_right.png | Bin 201 -> 0 bytes 5 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 phpBB/styles/prosilver/theme/images/.DS_Store delete mode 100644 phpBB/styles/prosilver/theme/images/corners_left.gif delete mode 100644 phpBB/styles/prosilver/theme/images/corners_left.png delete mode 100644 phpBB/styles/prosilver/theme/images/corners_right.gif delete mode 100644 phpBB/styles/prosilver/theme/images/corners_right.png diff --git a/phpBB/styles/prosilver/theme/images/.DS_Store b/phpBB/styles/prosilver/theme/images/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..5008ddfcf53c02e82d7eee2e57c38e5672ef89f6 GIT binary patch literal 6148 zcmeH~Jr2S!425mzP>H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T04$o>ne4iAh3&L2`^WYRA5oO4L^V4Js-_;eQwGtO9r vb18?EcF5l3lUA6=a3sAULP~`}Ac4V8+^F^0SN$nKYZyFT{an^LB{Ts5ju$_5 From 33a10f57f96d365bac2cd23764d23c76325d2c1b Mon Sep 17 00:00:00 2001 From: Shibu Lijack Date: Sat, 31 Mar 2012 22:21:18 +0530 Subject: [PATCH 047/441] [ticket/10734] Removed unwanted CSS hacks Removed -webkit and -moz as suggested by cyberalien. Removed unused style elements. PHPBB-10734 --- phpBB/styles/prosilver/theme/colours.css | 32 ------------------------ 1 file changed, 32 deletions(-) diff --git a/phpBB/styles/prosilver/theme/colours.css b/phpBB/styles/prosilver/theme/colours.css index 11fa6932db..4f7bc12818 100644 --- a/phpBB/styles/prosilver/theme/colours.css +++ b/phpBB/styles/prosilver/theme/colours.css @@ -48,49 +48,33 @@ hr { background-image: url("./images/bg_header.gif"); color: #FFFFFF; border-radius: 7px; - -webkit-border-radius: 7px; - -moz-border-radius: 7px; } .navbar { background-color: #cadceb; border-radius: 7px; - -webkit-border-radius: 7px; - -moz-border-radius: 7px; - } .forabg { background-color: #0076b1; background-image: url("./images/bg_list.gif"); border-radius: 7px; - -webkit-border-radius: 7px; - -moz-border-radius: 7px; - } .forumbg { background-color: #12A3EB; background-image: url("./images/bg_header.gif"); border-radius: 7px; - -webkit-border-radius: 7px; - -moz-border-radius: 7px; - } .panel { background-color: #ECF1F3; color: #28313F; border-radius: 7px; - -webkit-border-radius: 7px; - -moz-border-radius: 7px; } .post { border-radius: 7px; - -webkit-border-radius: 7px; - -moz-border-radius: 7px; - } .post:target .content { @@ -113,22 +97,6 @@ hr { background-color: #E7E8EA; } -span.corners-top { - -} - -span.corners-top span { - -} - -span.corners-bottom { - -} - -span.corners-bottom span { - -} - /* Horizontal lists ----------------------------------------*/ From a728b08e9056473f19906f93f38339b9eb8f2ffc Mon Sep 17 00:00:00 2001 From: Shibu Lijack Date: Mon, 2 Apr 2012 00:05:37 +0530 Subject: [PATCH 048/441] [ticket/10734] Used pseudo class for clearing Instead of using a separate class for clearing, pseudo :after class is added. PHPBB3-10734 --- phpBB/styles/prosilver/theme/common.css | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/phpBB/styles/prosilver/theme/common.css b/phpBB/styles/prosilver/theme/common.css index 6fd410029d..790b9c154a 100644 --- a/phpBB/styles/prosilver/theme/common.css +++ b/phpBB/styles/prosilver/theme/common.css @@ -289,6 +289,12 @@ a#logo:hover { background-position: 100% 0; } +.inner:after { + content: ''; + clear: both; + display: block; +} + .rowbg { margin: 5px 5px 2px 5px; } From 03f5fde7476797ff06b9bdabcb5d56730180c628 Mon Sep 17 00:00:00 2001 From: Shibu Lijack Date: Mon, 2 Apr 2012 00:42:11 +0530 Subject: [PATCH 049/441] [ticket/10734] Removed unwanted span classes Removed the corner and clear span classes PHPBB-10734 --- .../styles/prosilver/template/confirm_body.html | 4 ++-- phpBB/styles/prosilver/template/drafts.html | 8 ++++---- phpBB/styles/prosilver/template/faq_body.html | 6 +++--- .../prosilver/template/forumlist_body.html | 6 +++--- phpBB/styles/prosilver/template/login_body.html | 4 ++-- phpBB/styles/prosilver/template/login_forum.html | 2 +- .../prosilver/template/memberlist_body.html | 6 +++--- .../prosilver/template/memberlist_email.html | 4 ++-- .../styles/prosilver/template/memberlist_im.html | 4 ++-- .../prosilver/template/memberlist_leaders.html | 4 ++-- .../prosilver/template/memberlist_search.html | 2 +- .../styles/prosilver/template/message_body.html | 2 +- .../prosilver/template/overall_footer.html | 2 +- .../prosilver/template/overall_header.html | 8 ++++---- .../prosilver/template/posting_attach_body.html | 4 ++-- .../prosilver/template/posting_editor.html | 12 ++++++------ .../prosilver/template/posting_layout.html | 16 ++++++++-------- .../prosilver/template/posting_pm_layout.html | 8 ++++---- .../prosilver/template/posting_poll_body.html | 4 ++-- .../prosilver/template/posting_preview.html | 8 ++++---- .../prosilver/template/posting_review.html | 6 +++--- .../prosilver/template/posting_smilies.html | 4 ++-- .../prosilver/template/posting_topic_review.html | 6 +++--- .../prosilver/template/quickreply_editor.html | 4 ++-- phpBB/styles/prosilver/template/report_body.html | 8 ++++---- phpBB/styles/prosilver/template/search_body.html | 16 ++++++++-------- .../prosilver/template/search_results.html | 8 ++++---- .../prosilver/template/viewforum_body.html | 12 ++++++------ .../prosilver/template/viewonline_body.html | 4 ++-- .../prosilver/template/viewonline_whois.html | 4 ++-- .../prosilver/template/viewtopic_body.html | 12 ++++++------ 31 files changed, 99 insertions(+), 99 deletions(-) diff --git a/phpBB/styles/prosilver/template/confirm_body.html b/phpBB/styles/prosilver/template/confirm_body.html index 5b783915a4..cddbdee391 100644 --- a/phpBB/styles/prosilver/template/confirm_body.html +++ b/phpBB/styles/prosilver/template/confirm_body.html @@ -2,7 +2,7 @@
-
+

{MESSAGE_TITLE}

{MESSAGE_TEXT}

@@ -13,7 +13,7 @@ -
+
diff --git a/phpBB/styles/prosilver/template/drafts.html b/phpBB/styles/prosilver/template/drafts.html index dea3bb414e..c3c54876e3 100644 --- a/phpBB/styles/prosilver/template/drafts.html +++ b/phpBB/styles/prosilver/template/drafts.html @@ -2,16 +2,16 @@
-
+

{L_LOAD_DRAFT}

{L_LOAD_DRAFT_EXPLAIN}

-
+
-
+
  • @@ -39,6 +39,6 @@
-
+
diff --git a/phpBB/styles/prosilver/template/faq_body.html b/phpBB/styles/prosilver/template/faq_body.html index 7aa32b66b9..46f738aa3a 100644 --- a/phpBB/styles/prosilver/template/faq_body.html +++ b/phpBB/styles/prosilver/template/faq_body.html @@ -21,7 +21,7 @@
- + @@ -30,7 +30,7 @@
-
+

{faq_block.BLOCK_TITLE}

@@ -44,7 +44,7 @@
-
+
diff --git a/phpBB/styles/prosilver/template/forumlist_body.html b/phpBB/styles/prosilver/template/forumlist_body.html index cb6d14e47e..ed08aa791a 100644 --- a/phpBB/styles/prosilver/template/forumlist_body.html +++ b/phpBB/styles/prosilver/template/forumlist_body.html @@ -3,7 +3,7 @@ - + @@ -55,7 +55,7 @@ - + @@ -63,6 +63,6 @@
{L_NO_FORUMS} -
+
diff --git a/phpBB/styles/prosilver/template/login_body.html b/phpBB/styles/prosilver/template/login_body.html index a3a70e3333..d8b9b01779 100644 --- a/phpBB/styles/prosilver/template/login_body.html +++ b/phpBB/styles/prosilver/template/login_body.html @@ -45,7 +45,7 @@ - + @@ -61,7 +61,7 @@

{L_REGISTER}

- + diff --git a/phpBB/styles/prosilver/template/login_forum.html b/phpBB/styles/prosilver/template/login_forum.html index e66e531fcd..13669a78bb 100644 --- a/phpBB/styles/prosilver/template/login_forum.html +++ b/phpBB/styles/prosilver/template/login_forum.html @@ -27,7 +27,7 @@ {S_LOGIN_REDIRECT} - + diff --git a/phpBB/styles/prosilver/template/memberlist_body.html b/phpBB/styles/prosilver/template/memberlist_body.html index f6f7bdc485..d5154761e9 100644 --- a/phpBB/styles/prosilver/template/memberlist_body.html +++ b/phpBB/styles/prosilver/template/memberlist_body.html @@ -46,7 +46,7 @@ - + @@ -77,7 +77,7 @@ - +
@@ -121,7 +121,7 @@ -
+ diff --git a/phpBB/styles/prosilver/template/memberlist_email.html b/phpBB/styles/prosilver/template/memberlist_email.html index 062d266252..97bea144e8 100644 --- a/phpBB/styles/prosilver/template/memberlist_email.html +++ b/phpBB/styles/prosilver/template/memberlist_email.html @@ -46,7 +46,7 @@ - +
@@ -56,7 +56,7 @@
- + {S_FORM_TOKEN} diff --git a/phpBB/styles/prosilver/template/memberlist_im.html b/phpBB/styles/prosilver/template/memberlist_im.html index 88c57eb8c5..ccef778ebb 100644 --- a/phpBB/styles/prosilver/template/memberlist_im.html +++ b/phpBB/styles/prosilver/template/memberlist_im.html @@ -6,7 +6,7 @@
-
+

{L_SEND_IM_EXPLAIN}

@@ -79,7 +79,7 @@ {S_FORM_TOKEN} -
+
diff --git a/phpBB/styles/prosilver/template/memberlist_leaders.html b/phpBB/styles/prosilver/template/memberlist_leaders.html index bce1a69619..d0daa564c1 100644 --- a/phpBB/styles/prosilver/template/memberlist_leaders.html +++ b/phpBB/styles/prosilver/template/memberlist_leaders.html @@ -6,7 +6,7 @@
-
+
@@ -37,7 +37,7 @@
-
+
diff --git a/phpBB/styles/prosilver/template/memberlist_search.html b/phpBB/styles/prosilver/template/memberlist_search.html index 8d2ccf044c..2ea32fc774 100644 --- a/phpBB/styles/prosilver/template/memberlist_search.html +++ b/phpBB/styles/prosilver/template/memberlist_search.html @@ -118,7 +118,7 @@ function insert_single(user) {S_FORM_TOKEN} - + diff --git a/phpBB/styles/prosilver/template/message_body.html b/phpBB/styles/prosilver/template/message_body.html index 645807cd89..fb6dfce35f 100644 --- a/phpBB/styles/prosilver/template/message_body.html +++ b/phpBB/styles/prosilver/template/message_body.html @@ -9,7 +9,7 @@

{MESSAGE_TITLE}

{MESSAGE_TEXT}

{L_RETURN_TO_SEARCH_ADV}

- + diff --git a/phpBB/styles/prosilver/template/overall_footer.html b/phpBB/styles/prosilver/template/overall_footer.html index 81736cc917..3973ffe73f 100644 --- a/phpBB/styles/prosilver/template/overall_footer.html +++ b/phpBB/styles/prosilver/template/overall_footer.html @@ -16,7 +16,7 @@
  • {L_THE_TEAM}{L_DELETE_COOKIES}{S_TIMEZONE}
  • - + - + + @@ -165,8 +165,8 @@
    -
    +
    {L_INFORMATION}: {L_BOARD_DISABLED} -
    +
    diff --git a/phpBB/styles/prosilver/template/posting_attach_body.html b/phpBB/styles/prosilver/template/posting_attach_body.html index d39405487d..162b0b5d4e 100644 --- a/phpBB/styles/prosilver/template/posting_attach_body.html +++ b/phpBB/styles/prosilver/template/posting_attach_body.html @@ -1,5 +1,5 @@
    -
    +

    {L_ADD_ATTACHMENT_EXPLAIN}

    @@ -17,5 +17,5 @@ -
    +
    diff --git a/phpBB/styles/prosilver/template/posting_editor.html b/phpBB/styles/prosilver/template/posting_editor.html index efd2c054d5..a5b41b6da4 100644 --- a/phpBB/styles/prosilver/template/posting_editor.html +++ b/phpBB/styles/prosilver/template/posting_editor.html @@ -149,13 +149,13 @@ -
    +
    -
    +

    {L_POSTED_ATTACHMENTS}

    @@ -177,13 +177,13 @@
    -
    +
    -
    +
    {S_HIDDEN_ADDRESS_FIELD} {S_HIDDEN_FIELDS} @@ -194,7 +194,7 @@
    -
    +
    @@ -210,7 +210,7 @@
    -
    +
    diff --git a/phpBB/styles/prosilver/template/posting_layout.html b/phpBB/styles/prosilver/template/posting_layout.html index b81c8162d7..a5cb3fc154 100644 --- a/phpBB/styles/prosilver/template/posting_layout.html +++ b/phpBB/styles/prosilver/template/posting_layout.html @@ -8,7 +8,7 @@
    -
    +
    {L_FORUM_RULES} @@ -17,7 +17,7 @@ {FORUM_RULES} -
    +
    @@ -25,12 +25,12 @@
    -
    +

    {L_INFORMATION}

    {L_DRAFT_LOADED}

    -
    +
    @@ -40,7 +40,7 @@
    -
    +

    {L_SELECT_DESTINATION_FORUM}

    {L_UNGLOBALISE_EXPLAIN}

    @@ -55,21 +55,21 @@
    -
    +
    -
    +

    {L_POST_A}

    {S_FORM_TOKEN} -
    +
    diff --git a/phpBB/styles/prosilver/template/posting_pm_layout.html b/phpBB/styles/prosilver/template/posting_pm_layout.html index ebeb90b6d3..5421cc2cbd 100644 --- a/phpBB/styles/prosilver/template/posting_pm_layout.html +++ b/phpBB/styles/prosilver/template/posting_pm_layout.html @@ -2,12 +2,12 @@
    -
    +

    {L_INFORMATION}

    {L_DRAFT_LOADED_PM}

    -
    +
    @@ -18,12 +18,12 @@

    {L_TITLE}

    -
    +
    -
    +
    diff --git a/phpBB/styles/prosilver/template/posting_poll_body.html b/phpBB/styles/prosilver/template/posting_poll_body.html index ba0014ce57..3f64c5d5b5 100644 --- a/phpBB/styles/prosilver/template/posting_poll_body.html +++ b/phpBB/styles/prosilver/template/posting_poll_body.html @@ -1,5 +1,5 @@
    -
    +

    {L_ADD_POLL_EXPLAIN}

    @@ -52,5 +52,5 @@
    -
    +
    diff --git a/phpBB/styles/prosilver/template/posting_preview.html b/phpBB/styles/prosilver/template/posting_preview.html index 82227c23b0..16fc4ba233 100644 --- a/phpBB/styles/prosilver/template/posting_preview.html +++ b/phpBB/styles/prosilver/template/posting_preview.html @@ -1,5 +1,5 @@
    -
    +
    @@ -16,11 +16,11 @@
    -
    +
    -
    +
    @@ -41,7 +41,7 @@
    {PREVIEW_SIGNATURE}
    -
    +

    diff --git a/phpBB/styles/prosilver/template/posting_review.html b/phpBB/styles/prosilver/template/posting_review.html index 540f116de4..2771c9829a 100644 --- a/phpBB/styles/prosilver/template/posting_review.html +++ b/phpBB/styles/prosilver/template/posting_review.html @@ -5,11 +5,11 @@
    -
    +
    {post_review_row.L_IGNORE_POST}
    -
    +
    @@ -28,7 +28,7 @@
    -
    +
    diff --git a/phpBB/styles/prosilver/template/posting_smilies.html b/phpBB/styles/prosilver/template/posting_smilies.html index 9f7e25406e..84191588e2 100644 --- a/phpBB/styles/prosilver/template/posting_smilies.html +++ b/phpBB/styles/prosilver/template/posting_smilies.html @@ -10,12 +10,12 @@

    {L_SMILIES}

    -
    +
    {smiley.SMILEY_CODE} -
    +
    {PAGINATION}
    {L_CLOSE_WINDOW} diff --git a/phpBB/styles/prosilver/template/posting_topic_review.html b/phpBB/styles/prosilver/template/posting_topic_review.html index 1c4b67044d..5e7b36c526 100644 --- a/phpBB/styles/prosilver/template/posting_topic_review.html +++ b/phpBB/styles/prosilver/template/posting_topic_review.html @@ -14,11 +14,11 @@
    -
    +
    {topic_review_row.L_IGNORE_POST}
    -
    +
    @@ -45,7 +45,7 @@
    -
    +
    diff --git a/phpBB/styles/prosilver/template/quickreply_editor.html b/phpBB/styles/prosilver/template/quickreply_editor.html index 4cd5eedd3e..f2c1eeb139 100644 --- a/phpBB/styles/prosilver/template/quickreply_editor.html +++ b/phpBB/styles/prosilver/template/quickreply_editor.html @@ -1,6 +1,6 @@
    -
    +

    {L_QUICKREPLY}

    @@ -17,6 +17,6 @@    
    -
    +
    diff --git a/phpBB/styles/prosilver/template/report_body.html b/phpBB/styles/prosilver/template/report_body.html index ec1a1e5820..3e876afe85 100644 --- a/phpBB/styles/prosilver/template/report_body.html +++ b/phpBB/styles/prosilver/template/report_body.html @@ -4,7 +4,7 @@
    -
    +

    {L_REPORT_POST_EXPLAIN}{L_REPORT_MESSAGE_EXPLAIN}

    @@ -30,11 +30,11 @@
    -
    +
    -
    +
    @@ -44,7 +44,7 @@
    -
    +
    diff --git a/phpBB/styles/prosilver/template/search_body.html b/phpBB/styles/prosilver/template/search_body.html index 4b1d30d77d..a8baafa5f1 100644 --- a/phpBB/styles/prosilver/template/search_body.html +++ b/phpBB/styles/prosilver/template/search_body.html @@ -11,7 +11,7 @@
    -
    +

    {L_SEARCH_QUERY}

    @@ -27,11 +27,11 @@
    -
    +
    -
    +

    {L_SEARCH_OPTIONS}

    @@ -81,25 +81,25 @@ -
    +
    -
    +
    {S_HIDDEN_FIELDS} 
    -
    +
    -
    +
    @@ -121,7 +121,7 @@
    -
    +
    diff --git a/phpBB/styles/prosilver/template/search_results.html b/phpBB/styles/prosilver/template/search_results.html index dbda076086..5d75bd3d56 100644 --- a/phpBB/styles/prosilver/template/search_results.html +++ b/phpBB/styles/prosilver/template/search_results.html @@ -71,13 +71,13 @@ -
    +
    {L_NO_SEARCH_RESULTS} -
    +
    @@ -114,13 +114,13 @@ -
    +
    {L_NO_SEARCH_RESULTS} -
    +
    diff --git a/phpBB/styles/prosilver/template/viewforum_body.html b/phpBB/styles/prosilver/template/viewforum_body.html index f62815ede1..f5ff1d3f98 100644 --- a/phpBB/styles/prosilver/template/viewforum_body.html +++ b/phpBB/styles/prosilver/template/viewforum_body.html @@ -21,7 +21,7 @@ {FORUM_RULES} - + @@ -72,7 +72,7 @@
    {L_NO_READ_ACCESS} -
    +
    @@ -104,7 +104,7 @@ - + @@ -117,7 +117,7 @@ - + @@ -156,7 +156,7 @@ - + @@ -165,7 +165,7 @@
    {L_NO_TOPICS} -
    +
    diff --git a/phpBB/styles/prosilver/template/viewonline_body.html b/phpBB/styles/prosilver/template/viewonline_body.html index 3f1f0e64bf..9da8202783 100644 --- a/phpBB/styles/prosilver/template/viewonline_body.html +++ b/phpBB/styles/prosilver/template/viewonline_body.html @@ -8,7 +8,7 @@
    -
    +
    @@ -38,7 +38,7 @@
    -
    +
    diff --git a/phpBB/styles/prosilver/template/viewonline_whois.html b/phpBB/styles/prosilver/template/viewonline_whois.html index 88a41a1a3f..8abd933efa 100644 --- a/phpBB/styles/prosilver/template/viewonline_whois.html +++ b/phpBB/styles/prosilver/template/viewonline_whois.html @@ -3,13 +3,13 @@

    {L_WHOIS}

    -
    +
    {WHOIS}
    -
    +
    {L_CLOSE_WINDOW} diff --git a/phpBB/styles/prosilver/template/viewtopic_body.html b/phpBB/styles/prosilver/template/viewtopic_body.html index 3c551b3d52..9110cea4e9 100644 --- a/phpBB/styles/prosilver/template/viewtopic_body.html +++ b/phpBB/styles/prosilver/template/viewtopic_body.html @@ -12,7 +12,7 @@
    -
    +
    {L_FORUM_RULES} @@ -21,7 +21,7 @@ {FORUM_RULES} -
    +
    @@ -59,7 +59,7 @@
    -
    +

    {POLL_QUESTION}

    @@ -98,7 +98,7 @@
    -
    +
    {S_FORM_TOKEN} {S_HIDDEN_FIELDS}
    @@ -111,7 +111,7 @@
    -
    +
    @@ -221,7 +221,7 @@ -
    +

    From 57ba42d8df363a51cb2443ae8a502d58ae63f26d Mon Sep 17 00:00:00 2001 From: Shibu Lijack Date: Mon, 2 Apr 2012 00:49:31 +0530 Subject: [PATCH 050/441] [ticket/10734] Removed unwanted css elements Removed all the corner css elements PHPBB-10734 --- phpBB/styles/prosilver/theme/colours.css | 33 -------------------- phpBB/styles/prosilver/theme/common.css | 38 +----------------------- 2 files changed, 1 insertion(+), 70 deletions(-) diff --git a/phpBB/styles/prosilver/theme/colours.css b/phpBB/styles/prosilver/theme/colours.css index 4f7bc12818..b6d1f310c6 100644 --- a/phpBB/styles/prosilver/theme/colours.css +++ b/phpBB/styles/prosilver/theme/colours.css @@ -877,39 +877,6 @@ ul.cplist { background-color: #FFFFFF; } -#cp-main span.corners-top, #cp-menu span.corners-top { - background-image: url("./images/corners_left2.gif"); -} - -#cp-main span.corners-top span, #cp-menu span.corners-top span { - background-image: url("./images/corners_right2.gif"); -} - -#cp-main span.corners-bottom, #cp-menu span.corners-bottom { - background-image: url("./images/corners_left2.gif"); -} - -#cp-main span.corners-bottom span, #cp-menu span.corners-bottom span { - background-image: url("./images/corners_right2.gif"); -} - -/* Topicreview */ -#cp-main .panel #topicreview span.corners-top, #cp-menu .panel #topicreview span.corners-top { - background-image: url("./images/corners_left.gif"); -} - -#cp-main .panel #topicreview span.corners-top span, #cp-menu .panel #topicreview span.corners-top span { - background-image: url("./images/corners_right.gif"); -} - -#cp-main .panel #topicreview span.corners-bottom, #cp-menu .panel #topicreview span.corners-bottom { - background-image: url("./images/corners_left.gif"); -} - -#cp-main .panel #topicreview span.corners-bottom span, #cp-menu .panel #topicreview span.corners-bottom span { - background-image: url("./images/corners_right.gif"); -} - /* Friends list */ .cp-mini { background-color: #eef5f9; diff --git a/phpBB/styles/prosilver/theme/common.css b/phpBB/styles/prosilver/theme/common.css index 790b9c154a..249e3a3822 100644 --- a/phpBB/styles/prosilver/theme/common.css +++ b/phpBB/styles/prosilver/theme/common.css @@ -283,7 +283,7 @@ a#logo:hover { } .post { - padding: 0 10px; + padding: 10px; margin-bottom: 4px; background-repeat: no-repeat; background-position: 100% 0; @@ -299,42 +299,6 @@ a#logo:hover { margin: 5px 5px 2px 5px; } -span.corners-top, span.corners-bottom, span.corners-top span, span.corners-bottom span { - font-size: 1px; - line-height: 1px; - display: block; - height: 5px; - background-repeat: no-repeat; -} - -span.corners-top { - background-image: none; - background-position: 0 0; - margin: 0 -5px; -} - -span.corners-top span { - background-image: none; - background-position: 100% 0; -} - -span.corners-bottom { - background-image: none; - background-position: 0 100%; - margin: 0 -5px; - clear: both; -} - -span.corners-bottom span { - background-image: none; - background-position: 100% 100%; -} - -span.clear { - background-image: none; - clear: both; -} - .headbg span.corners-bottom { margin-bottom: -1px; } From 6498f2d33a16fa493f18c0d84bcce2dca1478179 Mon Sep 17 00:00:00 2001 From: Shibu Lijack Date: Mon, 2 Apr 2012 01:47:08 +0530 Subject: [PATCH 051/441] [ticket/10734] Fixed IE7 clear float bug Modified tweaks.css to fix IE bug PHPBB-10734 --- phpBB/styles/prosilver/theme/tweaks.css | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/phpBB/styles/prosilver/theme/tweaks.css b/phpBB/styles/prosilver/theme/tweaks.css index 416c4a5510..cdef01965e 100644 --- a/phpBB/styles/prosilver/theme/tweaks.css +++ b/phpBB/styles/prosilver/theme/tweaks.css @@ -28,4 +28,9 @@ dl.details dd { /* Headerbar height fix for IE7 */ #site-description p { *margin-bottom: 1.0em; +} + +/* Clear float fix for IE7 */ +.inner { + zoom: 1; } \ No newline at end of file From 97ff7ee9d80ed04210242c5c902f05c583467513 Mon Sep 17 00:00:00 2001 From: Shibu Lijack Date: Mon, 2 Apr 2012 02:04:11 +0530 Subject: [PATCH 052/441] [ticket/10734] Fixed padding issues Fixed padding for post and panel. PHPBB-10734 --- phpBB/styles/prosilver/theme/common.css | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/phpBB/styles/prosilver/theme/common.css b/phpBB/styles/prosilver/theme/common.css index 249e3a3822..592b6a2ff9 100644 --- a/phpBB/styles/prosilver/theme/common.css +++ b/phpBB/styles/prosilver/theme/common.css @@ -277,13 +277,12 @@ a#logo:hover { .panel { margin-bottom: 4px; padding: 0 10px; - padding: 5px 10px; background-color: #f3f3f3; color: #3f3f3f; } .post { - padding: 10px; + padding: 5px 10px; margin-bottom: 4px; background-repeat: no-repeat; background-position: 100% 0; From 3ced1d2bfcee5ee4c0c62cae752d84c9cd4c9ea0 Mon Sep 17 00:00:00 2001 From: Shibu Lijack Date: Mon, 2 Apr 2012 16:15:55 +0530 Subject: [PATCH 053/441] [ticket/10734] Removed all the unnecessary corner classes Removed the corner span classes from all the template and theme files. PHPBB-10734 --- .../prosilver/template/captcha_default.html | 4 +- .../styles/prosilver/template/captcha_qa.html | 4 +- .../prosilver/template/captcha_recaptcha.html | 4 +- .../prosilver/template/mcp_approve.html | 4 +- phpBB/styles/prosilver/template/mcp_ban.html | 10 ++--- .../styles/prosilver/template/mcp_forum.html | 4 +- .../styles/prosilver/template/mcp_front.html | 16 ++++---- .../styles/prosilver/template/mcp_header.html | 2 +- phpBB/styles/prosilver/template/mcp_logs.html | 6 +-- phpBB/styles/prosilver/template/mcp_move.html | 4 +- .../prosilver/template/mcp_notes_front.html | 4 +- .../prosilver/template/mcp_notes_user.html | 12 +++--- phpBB/styles/prosilver/template/mcp_post.html | 28 +++++++------- .../styles/prosilver/template/mcp_queue.html | 4 +- .../prosilver/template/mcp_reports.html | 4 +- .../styles/prosilver/template/mcp_topic.html | 18 ++++----- .../prosilver/template/mcp_warn_front.html | 12 +++--- .../prosilver/template/mcp_warn_list.html | 4 +- .../prosilver/template/mcp_warn_post.html | 12 +++--- .../prosilver/template/mcp_warn_user.html | 8 ++-- .../styles/prosilver/template/mcp_whois.html | 4 +- .../prosilver/template/ucp_agreement.html | 12 +++--- .../prosilver/template/ucp_attachments.html | 4 +- .../template/ucp_avatar_options.html | 8 ++-- .../prosilver/template/ucp_groups_manage.html | 16 ++++---- .../template/ucp_groups_membership.html | 12 +++--- .../styles/prosilver/template/ucp_header.html | 10 ++--- .../template/ucp_main_bookmarks.html | 4 +- .../prosilver/template/ucp_main_drafts.html | 6 +-- .../prosilver/template/ucp_main_front.html | 4 +- .../template/ucp_main_subscribed.html | 4 +- .../prosilver/template/ucp_pm_history.html | 4 +- .../template/ucp_pm_message_header.html | 2 +- .../prosilver/template/ucp_pm_options.html | 4 +- .../prosilver/template/ucp_pm_popup.html | 4 +- .../prosilver/template/ucp_pm_viewfolder.html | 6 +-- .../template/ucp_pm_viewmessage.html | 6 +-- .../template/ucp_prefs_personal.html | 4 +- .../prosilver/template/ucp_prefs_post.html | 4 +- .../prosilver/template/ucp_prefs_view.html | 4 +- .../template/ucp_profile_profile_info.html | 4 +- .../template/ucp_profile_reg_details.html | 8 ++-- .../template/ucp_profile_signature.html | 8 ++-- .../prosilver/template/ucp_register.html | 12 +++--- .../styles/prosilver/template/ucp_remind.html | 4 +- .../styles/prosilver/template/ucp_resend.html | 4 +- .../prosilver/template/ucp_zebra_foes.html | 4 +- .../prosilver/template/ucp_zebra_friends.html | 4 +- phpBB/styles/prosilver/theme/common.css | 24 ------------ phpBB/styles/prosilver/theme/cp.css | 37 ------------------- 50 files changed, 167 insertions(+), 228 deletions(-) diff --git a/phpBB/styles/prosilver/template/captcha_default.html b/phpBB/styles/prosilver/template/captcha_default.html index bccf231251..007cff644f 100644 --- a/phpBB/styles/prosilver/template/captcha_default.html +++ b/phpBB/styles/prosilver/template/captcha_default.html @@ -1,6 +1,6 @@
    -
    +

    {L_CONFIRMATION}

    {L_CONFIRM_EXPLAIN}

    @@ -19,6 +19,6 @@ -
    +
    diff --git a/phpBB/styles/prosilver/template/captcha_qa.html b/phpBB/styles/prosilver/template/captcha_qa.html index 0b18ada3bb..7986b1faa2 100644 --- a/phpBB/styles/prosilver/template/captcha_qa.html +++ b/phpBB/styles/prosilver/template/captcha_qa.html @@ -1,6 +1,6 @@
    -
    +

    {L_CONFIRMATION}

    @@ -16,6 +16,6 @@
    -
    +
    diff --git a/phpBB/styles/prosilver/template/captcha_recaptcha.html b/phpBB/styles/prosilver/template/captcha_recaptcha.html index 51a1615bd5..087a5b9405 100644 --- a/phpBB/styles/prosilver/template/captcha_recaptcha.html +++ b/phpBB/styles/prosilver/template/captcha_recaptcha.html @@ -1,6 +1,6 @@
    -
    +

    {L_CONFIRMATION}

    {L_CONFIRM_EXPLAIN}

    @@ -45,6 +45,6 @@ -
    +
    diff --git a/phpBB/styles/prosilver/template/mcp_approve.html b/phpBB/styles/prosilver/template/mcp_approve.html index 1010ac6e6f..8b7f7c8c6d 100644 --- a/phpBB/styles/prosilver/template/mcp_approve.html +++ b/phpBB/styles/prosilver/template/mcp_approve.html @@ -3,7 +3,7 @@
    {S_FORM_TOKEN} -
    +
    @@ -45,7 +45,7 @@
    -
    +
    diff --git a/phpBB/styles/prosilver/template/mcp_ban.html b/phpBB/styles/prosilver/template/mcp_ban.html index f8cdc1a687..adcd86d057 100644 --- a/phpBB/styles/prosilver/template/mcp_ban.html +++ b/phpBB/styles/prosilver/template/mcp_ban.html @@ -36,7 +36,7 @@

    {L_TITLE}

    -
    +

    {L_TITLE}

    {L_EXPLAIN}

    @@ -72,7 +72,7 @@ -
    +
    @@ -82,7 +82,7 @@
    -
    +

    {L_UNBAN_TITLE}

    {L_UNBAN_EXPLAIN}

    @@ -107,7 +107,7 @@ -
    +
    @@ -119,7 +119,7 @@

    {L_NO_BAN_CELL}

    -
    + diff --git a/phpBB/styles/prosilver/template/mcp_forum.html b/phpBB/styles/prosilver/template/mcp_forum.html index 49d4601dfa..afd4f2308a 100644 --- a/phpBB/styles/prosilver/template/mcp_forum.html +++ b/phpBB/styles/prosilver/template/mcp_forum.html @@ -8,7 +8,7 @@
    -
    +
    -
    +
    diff --git a/phpBB/styles/prosilver/template/mcp_front.html b/phpBB/styles/prosilver/template/mcp_front.html index e9635e528c..69e0b02a4e 100644 --- a/phpBB/styles/prosilver/template/mcp_front.html +++ b/phpBB/styles/prosilver/template/mcp_front.html @@ -7,7 +7,7 @@
    -
    +

    {L_LATEST_UNAPPROVED}

    {L_UNAPPROVED_TOTAL}

    @@ -42,7 +42,7 @@ -
    +
    {S_FORM_TOKEN}
    @@ -59,7 +59,7 @@
    -
    +

    {L_LATEST_REPORTED}

    {L_REPORTS_TOTAL}

    @@ -92,13 +92,13 @@ -
    +
    -
    +

    {L_LATEST_REPORTED_PMS}

    {L_PM_REPORTS_TOTAL}

    @@ -131,13 +131,13 @@ -
    +
    -
    +

    {L_LATEST_LOGS}

    @@ -170,7 +170,7 @@ -
    +
    diff --git a/phpBB/styles/prosilver/template/mcp_header.html b/phpBB/styles/prosilver/template/mcp_header.html index 13cc7e12cf..7b9e4c13cb 100644 --- a/phpBB/styles/prosilver/template/mcp_header.html +++ b/phpBB/styles/prosilver/template/mcp_header.html @@ -19,7 +19,7 @@
    -
    +
    diff --git a/phpBB/styles/prosilver/template/mcp_logs.html b/phpBB/styles/prosilver/template/mcp_logs.html index 713ab7d9da..b5561687b2 100644 --- a/phpBB/styles/prosilver/template/mcp_logs.html +++ b/phpBB/styles/prosilver/template/mcp_logs.html @@ -5,7 +5,7 @@
    -
    +
    {S_FORM_TOKEN} -
    +
    @@ -80,7 +80,7 @@ {S_FORM_TOKEN} -
    +
    diff --git a/phpBB/styles/prosilver/template/mcp_move.html b/phpBB/styles/prosilver/template/mcp_move.html index 03a5c475db..4611412a9e 100644 --- a/phpBB/styles/prosilver/template/mcp_move.html +++ b/phpBB/styles/prosilver/template/mcp_move.html @@ -3,7 +3,7 @@
    -
    +

    {MESSAGE_TITLE}

    @@ -30,7 +30,7 @@
    -
    +
    diff --git a/phpBB/styles/prosilver/template/mcp_notes_front.html b/phpBB/styles/prosilver/template/mcp_notes_front.html index 38970198e7..3da66ccb2e 100644 --- a/phpBB/styles/prosilver/template/mcp_notes_front.html +++ b/phpBB/styles/prosilver/template/mcp_notes_front.html @@ -5,7 +5,7 @@

    {L_TITLE}

    -
    +
    @@ -15,7 +15,7 @@
    -
    +
    diff --git a/phpBB/styles/prosilver/template/mcp_notes_user.html b/phpBB/styles/prosilver/template/mcp_notes_user.html index 129f2ca839..afe904dab3 100644 --- a/phpBB/styles/prosilver/template/mcp_notes_user.html +++ b/phpBB/styles/prosilver/template/mcp_notes_user.html @@ -5,7 +5,7 @@

    {L_TITLE}

    -
    +

    {USERNAME_FULL}

    @@ -25,11 +25,11 @@
    -
    +
    -
    +

    {L_ADD_FEEDBACK}

    {L_ADD_FEEDBACK_EXPLAIN}

    @@ -38,7 +38,7 @@
    - +
    @@ -48,7 +48,7 @@
    -
    +
    -
    +
    diff --git a/phpBB/styles/prosilver/template/mcp_post.html b/phpBB/styles/prosilver/template/mcp_post.html index 496d9ffd0f..752fbdd078 100644 --- a/phpBB/styles/prosilver/template/mcp_post.html +++ b/phpBB/styles/prosilver/template/mcp_post.html @@ -8,7 +8,7 @@
    -
    +

    {L_REPORT_REASON}: {REPORT_REASON_TITLE}

    @@ -25,7 +25,7 @@
    -
    +
    @@ -45,7 +45,7 @@
    -
    +
    @@ -115,12 +115,12 @@
    -
    +
    -
    +

    {L_MOD_OPTIONS}

    @@ -159,18 +159,18 @@ -
    +
    -
    +

    {RETURN_QUEUE} | {RETURN_TOPIC_SIMPLE} | {RETURN_POST}{RETURN_REPORTS} | {L_VIEW_POST} | {L_VIEW_TOPIC} | {L_VIEW_FORUM}{RETURN_TOPIC}

    -
    +
    @@ -179,7 +179,7 @@
    -
    +
    @@ -216,13 +216,13 @@
    -
    +
    -
    +

    {L_MCP_POST_REPORTS}

    @@ -231,13 +231,13 @@

    {reports.REASON_TITLE}: {reports.REASON_DESC}
    {reports.REPORT_TEXT}

    -
    +
    -
    +

    {L_THIS_POST_IP}: {POST_IPADDR}{POST_IP} ({POST_IP}{L_LOOKUP_IP}) @@ -289,7 +289,7 @@

    {L_LOOKUP_ALL}

    -
    +
    diff --git a/phpBB/styles/prosilver/template/mcp_queue.html b/phpBB/styles/prosilver/template/mcp_queue.html index f86678ebe4..e9a477a24c 100644 --- a/phpBB/styles/prosilver/template/mcp_queue.html +++ b/phpBB/styles/prosilver/template/mcp_queue.html @@ -11,7 +11,7 @@

    {L_TITLE}

    -
    +

    {L_EXPLAIN}

    @@ -81,7 +81,7 @@

    {L_NO_TOPICS_QUEUE}{L_NO_POSTS_QUEUE}

    -
    +
    diff --git a/phpBB/styles/prosilver/template/mcp_reports.html b/phpBB/styles/prosilver/template/mcp_reports.html index 5f06fc091e..95e7d9e021 100644 --- a/phpBB/styles/prosilver/template/mcp_reports.html +++ b/phpBB/styles/prosilver/template/mcp_reports.html @@ -13,7 +13,7 @@

    {L_TITLE}

    -
    +

    {L_EXPLAIN}

    @@ -83,7 +83,7 @@

    {L_NO_REPORTS}

    -
    +
    diff --git a/phpBB/styles/prosilver/template/mcp_topic.html b/phpBB/styles/prosilver/template/mcp_topic.html index ab0c83a56f..1da1b1b3d4 100644 --- a/phpBB/styles/prosilver/template/mcp_topic.html +++ b/phpBB/styles/prosilver/template/mcp_topic.html @@ -22,15 +22,15 @@ onload_functions.push('subPanels()');
    @@ -39,7 +39,7 @@ onload_functions.push('subPanels()');
    -
    +
    @@ -89,11 +89,11 @@ onload_functions.push('subPanels()');
    -
    +
    -
    +

    {L_EXPAND_VIEW} @@ -103,7 +103,7 @@ onload_functions.push('subPanels()');
    -
    +
    @@ -131,7 +131,7 @@ onload_functions.push('subPanels()');
    -
    +
    @@ -147,7 +147,7 @@ onload_functions.push('subPanels()'); -

    +
    diff --git a/phpBB/styles/prosilver/template/mcp_warn_front.html b/phpBB/styles/prosilver/template/mcp_warn_front.html index 8f42e28cc0..f631cfb00d 100644 --- a/phpBB/styles/prosilver/template/mcp_warn_front.html +++ b/phpBB/styles/prosilver/template/mcp_warn_front.html @@ -5,7 +5,7 @@

    {L_WARN_USER}

    -
    +

    {L_SELECT_USER}

    @@ -17,7 +17,7 @@
    -
    +
    @@ -28,7 +28,7 @@
    -
    +

    {L_MOST_WARNINGS}

    @@ -58,11 +58,11 @@

    {L_WARNINGS_ZERO_TOTAL}

    -
    +
    -
    +

    {L_LATEST_WARNINGS}

    @@ -91,7 +91,7 @@

    {L_WARNINGS_ZERO_TOTAL}

    -
    +
    diff --git a/phpBB/styles/prosilver/template/mcp_warn_list.html b/phpBB/styles/prosilver/template/mcp_warn_list.html index d9c0bce088..b17b1dd589 100644 --- a/phpBB/styles/prosilver/template/mcp_warn_list.html +++ b/phpBB/styles/prosilver/template/mcp_warn_list.html @@ -5,7 +5,7 @@

    {L_WARNED_USERS}

    -
    +

    {L_WARNED_USERS_EXPLAIN}

    @@ -56,7 +56,7 @@

    {L_WARNINGS_ZERO_TOTAL}

    -
    +
    {S_FORM_TOKEN}
    diff --git a/phpBB/styles/prosilver/template/mcp_warn_post.html b/phpBB/styles/prosilver/template/mcp_warn_post.html index fd8c60d25a..540abb9473 100644 --- a/phpBB/styles/prosilver/template/mcp_warn_post.html +++ b/phpBB/styles/prosilver/template/mcp_warn_post.html @@ -5,7 +5,7 @@

    {L_MCP_WARN_POST}

    -
    +

    {USERNAME}{USERNAME}

    @@ -25,11 +25,11 @@
    -
    +
    -
    +

    {L_POST_DETAILS}

    @@ -41,11 +41,11 @@
    -
    +
    -
    +

    {L_ADD_WARNING}

    {L_ADD_WARNING_EXPLAIN}

    @@ -61,7 +61,7 @@
    - +
    diff --git a/phpBB/styles/prosilver/template/mcp_warn_user.html b/phpBB/styles/prosilver/template/mcp_warn_user.html index 6c326c8bc6..5e99c8d7e1 100644 --- a/phpBB/styles/prosilver/template/mcp_warn_user.html +++ b/phpBB/styles/prosilver/template/mcp_warn_user.html @@ -5,7 +5,7 @@

    {L_WARN_USER}

    -
    +

    {USERNAME_FULL}

    @@ -25,11 +25,11 @@
    -
    +
    -
    +

    {L_ADD_WARNING}

    {L_ADD_WARNING_EXPLAIN}

    @@ -45,7 +45,7 @@
    - +
    diff --git a/phpBB/styles/prosilver/template/mcp_whois.html b/phpBB/styles/prosilver/template/mcp_whois.html index 0da9b6187e..88d3269a71 100644 --- a/phpBB/styles/prosilver/template/mcp_whois.html +++ b/phpBB/styles/prosilver/template/mcp_whois.html @@ -2,7 +2,7 @@

    {L_WHOIS}

    -
    +

    {L_RETURN_POST}

    @@ -10,7 +10,7 @@

    {L_RETURN_POST}

    -
    +
    diff --git a/phpBB/styles/prosilver/template/ucp_agreement.html b/phpBB/styles/prosilver/template/ucp_agreement.html index 3825abc08f..4109b6ef34 100644 --- a/phpBB/styles/prosilver/template/ucp_agreement.html +++ b/phpBB/styles/prosilver/template/ucp_agreement.html @@ -31,16 +31,16 @@
    -
    +

    {SITENAME} - {L_REGISTRATION}

    {L_COPPA_BIRTHDAY}{L_TERMS_OF_USE}

    -
    +
    -
    +
    {L_COPPA_NO}  {L_COPPA_YES} @@ -51,21 +51,21 @@ {S_HIDDEN_FIELDS} {S_FORM_TOKEN}
    -
    +
    -
    +

    {SITENAME} - {AGREEMENT_TITLE}

    {AGREEMENT_TEXT}


    {L_BACK}

    -
    +
    diff --git a/phpBB/styles/prosilver/template/ucp_attachments.html b/phpBB/styles/prosilver/template/ucp_attachments.html index 5a15339b8a..84e4c2e875 100644 --- a/phpBB/styles/prosilver/template/ucp_attachments.html +++ b/phpBB/styles/prosilver/template/ucp_attachments.html @@ -5,7 +5,7 @@

    {L_TITLE}

    -
    +

    {L_ATTACHMENTS_EXPLAIN}

    @@ -63,7 +63,7 @@

    {L_UCP_NO_ATTACHMENTS}

    -
    +
    diff --git a/phpBB/styles/prosilver/template/ucp_avatar_options.html b/phpBB/styles/prosilver/template/ucp_avatar_options.html index 7012c42f3b..9801e065a5 100644 --- a/phpBB/styles/prosilver/template/ucp_avatar_options.html +++ b/phpBB/styles/prosilver/template/ucp_avatar_options.html @@ -1,6 +1,6 @@
    -
    +

    {L_AVATAR_FEATURES_DISABLED}

    @@ -43,11 +43,11 @@
    - +
    -
    +

    {L_AVATAR_GALLERY}

    @@ -66,5 +66,5 @@ -
    +
    diff --git a/phpBB/styles/prosilver/template/ucp_groups_manage.html b/phpBB/styles/prosilver/template/ucp_groups_manage.html index a6f8e1d793..a13c043e48 100644 --- a/phpBB/styles/prosilver/template/ucp_groups_manage.html +++ b/phpBB/styles/prosilver/template/ucp_groups_manage.html @@ -5,7 +5,7 @@
    -
    +

    {L_GROUPS_EXPLAIN}

    @@ -45,11 +45,11 @@ -
    +
    -
    +

    {L_GROUP_SETTINGS_SAVE}

    @@ -63,7 +63,7 @@
    -
    +
    @@ -163,7 +163,7 @@ - +
    @@ -173,7 +173,7 @@
    -
    +

    {L_ADD_USERS}

    @@ -194,7 +194,7 @@ -
    +
    @@ -230,7 +230,7 @@

    {L_NO_LEADERS}

    - + diff --git a/phpBB/styles/prosilver/template/ucp_groups_membership.html b/phpBB/styles/prosilver/template/ucp_groups_membership.html index 26ee6d8a52..a312911ae4 100644 --- a/phpBB/styles/prosilver/template/ucp_groups_membership.html +++ b/phpBB/styles/prosilver/template/ucp_groups_membership.html @@ -5,7 +5,7 @@
    -
    +

    {L_GROUPS_EXPLAIN}

    @@ -66,12 +66,12 @@ -
    +
    -
    +
    • @@ -98,12 +98,12 @@
    -
    +
    -
    +
    • @@ -130,7 +130,7 @@
    -
    +
    diff --git a/phpBB/styles/prosilver/template/ucp_header.html b/phpBB/styles/prosilver/template/ucp_header.html index 4d008564c4..c5d58b8eaa 100644 --- a/phpBB/styles/prosilver/template/ucp_header.html +++ b/phpBB/styles/prosilver/template/ucp_header.html @@ -15,7 +15,7 @@
    -
    +
    @@ -63,7 +63,7 @@
    -
    +
    {L_FRIENDS}
    @@ -77,13 +77,13 @@
    -
    +
    -
    +
    {L_MESSAGE_COLOURS}
    @@ -92,7 +92,7 @@
    -
    +
    diff --git a/phpBB/styles/prosilver/template/ucp_main_bookmarks.html b/phpBB/styles/prosilver/template/ucp_main_bookmarks.html index 50310f3b79..89502bbc3d 100644 --- a/phpBB/styles/prosilver/template/ucp_main_bookmarks.html +++ b/phpBB/styles/prosilver/template/ucp_main_bookmarks.html @@ -5,7 +5,7 @@

    {L_TITLE}

    -
    +

    {L_BOOKMARKS_EXPLAIN}

    @@ -60,7 +60,7 @@ -
    +
    diff --git a/phpBB/styles/prosilver/template/ucp_main_drafts.html b/phpBB/styles/prosilver/template/ucp_main_drafts.html index 2fc9e3e1fc..2155abeda3 100644 --- a/phpBB/styles/prosilver/template/ucp_main_drafts.html +++ b/phpBB/styles/prosilver/template/ucp_main_drafts.html @@ -5,14 +5,14 @@

    {L_TITLE}

    -
    +

    {L_DRAFTS_EXPLAIN}

    -
    +
    @@ -55,7 +55,7 @@

    {L_NO_SAVED_DRAFTS}

    -
    +
    diff --git a/phpBB/styles/prosilver/template/ucp_main_front.html b/phpBB/styles/prosilver/template/ucp_main_front.html index 20afd119cc..b7a0619227 100644 --- a/phpBB/styles/prosilver/template/ucp_main_front.html +++ b/phpBB/styles/prosilver/template/ucp_main_front.html @@ -3,7 +3,7 @@

    {L_TITLE}

    -
    +

    {L_UCP_WELCOME}

    @@ -39,7 +39,7 @@
    {L_YOUR_WARNINGS}:
    {WARNING_IMG} [{WARNINGS}]
    -
    +
    diff --git a/phpBB/styles/prosilver/template/ucp_main_subscribed.html b/phpBB/styles/prosilver/template/ucp_main_subscribed.html index 2711c9486f..ab65d9b3ae 100644 --- a/phpBB/styles/prosilver/template/ucp_main_subscribed.html +++ b/phpBB/styles/prosilver/template/ucp_main_subscribed.html @@ -4,7 +4,7 @@

    {L_TITLE}

    -
    +

    {L_WATCHED_EXPLAIN}

    @@ -77,7 +77,7 @@

    {L_NO_WATCHED_TOPICS}

    -
    +
    diff --git a/phpBB/styles/prosilver/template/ucp_pm_history.html b/phpBB/styles/prosilver/template/ucp_pm_history.html index 9051eb2ee0..d7fcbb9e54 100644 --- a/phpBB/styles/prosilver/template/ucp_pm_history.html +++ b/phpBB/styles/prosilver/template/ucp_pm_history.html @@ -12,7 +12,7 @@
    -
    +
    @@ -28,7 +28,7 @@
    -
    +
    diff --git a/phpBB/styles/prosilver/template/ucp_pm_message_header.html b/phpBB/styles/prosilver/template/ucp_pm_message_header.html index ae66dd0a36..d6659fad0f 100644 --- a/phpBB/styles/prosilver/template/ucp_pm_message_header.html +++ b/phpBB/styles/prosilver/template/ucp_pm_message_header.html @@ -3,7 +3,7 @@
    -
    +

    {FOLDER_STATUS}

    diff --git a/phpBB/styles/prosilver/template/ucp_pm_options.html b/phpBB/styles/prosilver/template/ucp_pm_options.html index c2a2e58c97..dde8ee639b 100644 --- a/phpBB/styles/prosilver/template/ucp_pm_options.html +++ b/phpBB/styles/prosilver/template/ucp_pm_options.html @@ -5,7 +5,7 @@
    -
    +

    {ERROR_MESSAGE}

    {NOTIFICATION_MESSAGE}

    @@ -123,7 +123,7 @@
    - + {S_FORM_TOKEN}
    diff --git a/phpBB/styles/prosilver/template/ucp_pm_popup.html b/phpBB/styles/prosilver/template/ucp_pm_popup.html index 1a9a4d015e..4cc39ee450 100644 --- a/phpBB/styles/prosilver/template/ucp_pm_popup.html +++ b/phpBB/styles/prosilver/template/ucp_pm_popup.html @@ -14,12 +14,12 @@ function jump_to_inbox(url)
    -
    +

    {L_LOGIN_CHECK_PM}{MESSAGE}

    {CLICK_TO_VIEW}

    {L_CLOSE_WINDOW}

    -
    +
    diff --git a/phpBB/styles/prosilver/template/ucp_pm_viewfolder.html b/phpBB/styles/prosilver/template/ucp_pm_viewfolder.html index dac03c3505..20394b254e 100644 --- a/phpBB/styles/prosilver/template/ucp_pm_viewfolder.html +++ b/phpBB/styles/prosilver/template/ucp_pm_viewfolder.html @@ -8,7 +8,7 @@

    {L_EXPORT_AS_CSV}

    -
    +

    {L_OPTIONS}

    @@ -20,7 +20,7 @@
    -
    +
    @@ -110,7 +110,7 @@ - + diff --git a/phpBB/styles/prosilver/template/ucp_pm_viewmessage.html b/phpBB/styles/prosilver/template/ucp_pm_viewmessage.html index 5411fda572..2e7a7c4ac9 100644 --- a/phpBB/styles/prosilver/template/ucp_pm_viewmessage.html +++ b/phpBB/styles/prosilver/template/ucp_pm_viewmessage.html @@ -2,7 +2,7 @@ - + @@ -15,7 +15,7 @@
    -
    +
    @@ -96,7 +96,7 @@ -
    +
    diff --git a/phpBB/styles/prosilver/template/ucp_prefs_personal.html b/phpBB/styles/prosilver/template/ucp_prefs_personal.html index 635f321469..1c829899fd 100644 --- a/phpBB/styles/prosilver/template/ucp_prefs_personal.html +++ b/phpBB/styles/prosilver/template/ucp_prefs_personal.html @@ -5,7 +5,7 @@

    {L_TITLE}

    -
    +

    {ERROR}

    @@ -95,7 +95,7 @@
    -
    +
    diff --git a/phpBB/styles/prosilver/template/ucp_prefs_post.html b/phpBB/styles/prosilver/template/ucp_prefs_post.html index ee3ae3f34e..0ca51ed7d6 100644 --- a/phpBB/styles/prosilver/template/ucp_prefs_post.html +++ b/phpBB/styles/prosilver/template/ucp_prefs_post.html @@ -4,7 +4,7 @@

    {L_TITLE}

    -
    +

    {ERROR}

    @@ -38,7 +38,7 @@
    -
    +
    diff --git a/phpBB/styles/prosilver/template/ucp_prefs_view.html b/phpBB/styles/prosilver/template/ucp_prefs_view.html index 125a62e12a..2e47c2e054 100644 --- a/phpBB/styles/prosilver/template/ucp_prefs_view.html +++ b/phpBB/styles/prosilver/template/ucp_prefs_view.html @@ -5,7 +5,7 @@

    {L_TITLE}

    -
    +

    {ERROR}

    @@ -81,7 +81,7 @@
    -
    +
    diff --git a/phpBB/styles/prosilver/template/ucp_profile_profile_info.html b/phpBB/styles/prosilver/template/ucp_profile_profile_info.html index 0f53c82e76..b6f6a8988d 100644 --- a/phpBB/styles/prosilver/template/ucp_profile_profile_info.html +++ b/phpBB/styles/prosilver/template/ucp_profile_profile_info.html @@ -5,7 +5,7 @@

    {L_TITLE}

    -
    +

    {L_PROFILE_INFO_NOTICE}

    @@ -66,7 +66,7 @@
    -
    +
    diff --git a/phpBB/styles/prosilver/template/ucp_profile_reg_details.html b/phpBB/styles/prosilver/template/ucp_profile_reg_details.html index 9d4a9e3463..4f74c7193b 100644 --- a/phpBB/styles/prosilver/template/ucp_profile_reg_details.html +++ b/phpBB/styles/prosilver/template/ucp_profile_reg_details.html @@ -4,7 +4,7 @@

    {L_TITLE}

    -
    +

    {L_FORCE_PASSWORD_EXPLAIN}

    @@ -31,11 +31,11 @@
    -
    +
    -
    +
    @@ -44,7 +44,7 @@
    -
    +
    diff --git a/phpBB/styles/prosilver/template/ucp_profile_signature.html b/phpBB/styles/prosilver/template/ucp_profile_signature.html index cf5a6c3229..574f61ed9f 100644 --- a/phpBB/styles/prosilver/template/ucp_profile_signature.html +++ b/phpBB/styles/prosilver/template/ucp_profile_signature.html @@ -6,17 +6,17 @@
    -
    +

    {L_SIGNATURE_PREVIEW}

    {SIGNATURE_PREVIEW}
    -
    +
    -
    +

    {L_SIGNATURE_EXPLAIN}

    @@ -36,7 +36,7 @@
    - +
    diff --git a/phpBB/styles/prosilver/template/ucp_register.html b/phpBB/styles/prosilver/template/ucp_register.html index 30ed37eecc..47253af37c 100644 --- a/phpBB/styles/prosilver/template/ucp_register.html +++ b/phpBB/styles/prosilver/template/ucp_register.html @@ -21,7 +21,7 @@
    -
    +

    {SITENAME} - {L_REGISTRATION}

    @@ -72,7 +72,7 @@
    - + @@ -83,17 +83,17 @@
    -
    +

    {L_COPPA_COMPLIANCE}

    {L_COPPA_EXPLAIN}

    -
    +
    -
    +
    {S_HIDDEN_FIELDS} @@ -102,7 +102,7 @@ {S_FORM_TOKEN}
    -
    +
    diff --git a/phpBB/styles/prosilver/template/ucp_remind.html b/phpBB/styles/prosilver/template/ucp_remind.html index afc23b3f21..d480258209 100644 --- a/phpBB/styles/prosilver/template/ucp_remind.html +++ b/phpBB/styles/prosilver/template/ucp_remind.html @@ -3,7 +3,7 @@
    -
    +

    {L_SEND_PASSWORD}

    @@ -25,7 +25,7 @@
    - + diff --git a/phpBB/styles/prosilver/template/ucp_resend.html b/phpBB/styles/prosilver/template/ucp_resend.html index 0481c2a601..36e112863c 100644 --- a/phpBB/styles/prosilver/template/ucp_resend.html +++ b/phpBB/styles/prosilver/template/ucp_resend.html @@ -4,7 +4,7 @@
    -
    +

    {L_UCP_RESEND}

    @@ -25,7 +25,7 @@
    -
    +
    diff --git a/phpBB/styles/prosilver/template/ucp_zebra_foes.html b/phpBB/styles/prosilver/template/ucp_zebra_foes.html index 8a2c9cbff5..7aceac74c3 100644 --- a/phpBB/styles/prosilver/template/ucp_zebra_foes.html +++ b/phpBB/styles/prosilver/template/ucp_zebra_foes.html @@ -5,7 +5,7 @@

    {L_TITLE}

    -
    +

    {L_FOES_EXPLAIN}

    @@ -28,7 +28,7 @@ -
    +
    diff --git a/phpBB/styles/prosilver/template/ucp_zebra_friends.html b/phpBB/styles/prosilver/template/ucp_zebra_friends.html index 928ec1a881..8908e4ba69 100644 --- a/phpBB/styles/prosilver/template/ucp_zebra_friends.html +++ b/phpBB/styles/prosilver/template/ucp_zebra_friends.html @@ -5,7 +5,7 @@

    {L_TITLE}

    -
    +

    {L_FRIENDS_EXPLAIN}

    @@ -28,7 +28,7 @@
    - +
    diff --git a/phpBB/styles/prosilver/theme/common.css b/phpBB/styles/prosilver/theme/common.css index 592b6a2ff9..fd67c48111 100644 --- a/phpBB/styles/prosilver/theme/common.css +++ b/phpBB/styles/prosilver/theme/common.css @@ -298,22 +298,6 @@ a#logo:hover { margin: 5px 5px 2px 5px; } -.headbg span.corners-bottom { - margin-bottom: -1px; -} - -.post span.corners-top, .post span.corners-bottom, .panel span.corners-top, .panel span.corners-bottom, .navbar span.corners-top, .navbar span.corners-bottom { - margin: 0 -10px; -} - -.rules span.corners-top { - margin: 0 -10px 5px -10px; -} - -.rules span.corners-bottom { - margin: 5px -10px 0 -10px; -} - /* Horizontal lists ----------------------------------------*/ ul.linklist { @@ -437,14 +421,6 @@ table.info tbody th { margin: 0 -1px; } -.forumbg-table > .inner > span.corners-top { - margin: 0 -4px -1px -4px; -} - -.forumbg-table > .inner > span.corners-bottom { - margin: -1px -4px 0 -4px; -} - /* Misc layout styles ---------------------------------------- */ /* column[1-2] styles are containers for two column layouts diff --git a/phpBB/styles/prosilver/theme/cp.css b/phpBB/styles/prosilver/theme/cp.css index 74f11e47a6..d073b2b9d1 100644 --- a/phpBB/styles/prosilver/theme/cp.css +++ b/phpBB/styles/prosilver/theme/cp.css @@ -240,49 +240,12 @@ ul.cplist { margin-left: 10px; } -#cp-main span.corners-top, #cp-menu span.corners-top { - background-image: none; -} - -#cp-main span.corners-top span, #cp-menu span.corners-top span { - background-image: none; -} - -#cp-main span.corners-bottom, #cp-menu span.corners-bottom { - background-image: none; -} - -#cp-main span.corners-bottom span, #cp-menu span.corners-bottom span { - background-image: none; -} - -/* Topicreview */ -#cp-main .panel #topicreview span.corners-top, #cp-menu .panel #topicreview span.corners-top { - background-image: none; -} - -#cp-main .panel #topicreview span.corners-top span, #cp-menu .panel #topicreview span.corners-top span { - background-image: none; -} - -#cp-main .panel #topicreview span.corners-bottom, #cp-menu .panel #topicreview span.corners-bottom { - background-image: none; -} - -#cp-main .panel #topicreview span.corners-bottom span, #cp-menu .panel #topicreview span.corners-bottom span { - background-image: none; -} - /* Friends list */ .cp-mini { padding: 0 5px; margin: 10px 15px 10px 5px; } -.cp-mini span.corners-top, .cp-mini span.corners-bottom { - margin: 0 -5px; -} - dl.mini dt { font-weight: bold; } From d8c67937d6e9bb07f4ab103e66c96efaf0bb51d1 Mon Sep 17 00:00:00 2001 From: Shibu Lijack Date: Mon, 2 Apr 2012 16:53:09 +0530 Subject: [PATCH 054/441] [ticket/10734] Fixed cp css Fixed border radius and padding of the ucp and mcp. PHPBB-10734 --- phpBB/styles/prosilver/theme/colours.css | 1 + phpBB/styles/prosilver/theme/common.css | 2 +- phpBB/styles/prosilver/theme/cp.css | 4 +++- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/phpBB/styles/prosilver/theme/colours.css b/phpBB/styles/prosilver/theme/colours.css index b6d1f310c6..53fa2dd653 100644 --- a/phpBB/styles/prosilver/theme/colours.css +++ b/phpBB/styles/prosilver/theme/colours.css @@ -871,6 +871,7 @@ ul.cplist { #cp-main .panel { background-color: #F9F9F9; + padding: 5px 10px; } #cp-main .pm { diff --git a/phpBB/styles/prosilver/theme/common.css b/phpBB/styles/prosilver/theme/common.css index fd67c48111..57696d71ee 100644 --- a/phpBB/styles/prosilver/theme/common.css +++ b/phpBB/styles/prosilver/theme/common.css @@ -276,7 +276,7 @@ a#logo:hover { .panel { margin-bottom: 4px; - padding: 0 10px; + padding: 5px 10px; background-color: #f3f3f3; color: #3f3f3f; } diff --git a/phpBB/styles/prosilver/theme/cp.css b/phpBB/styles/prosilver/theme/cp.css index d073b2b9d1..899b02faf1 100644 --- a/phpBB/styles/prosilver/theme/cp.css +++ b/phpBB/styles/prosilver/theme/cp.css @@ -179,7 +179,9 @@ ul.cplist { #minitabs li { display: block; float: right; - padding: 0 10px 4px 10px; + border-top-left-radius: 5px; + border-top-right-radius: 5px; + padding: 5px 10px 4px 10px; font-size: 1em; font-weight: bold; margin-left: 2px; From 57065095d570f0ff5976470ce81a4b216fe5f98e Mon Sep 17 00:00:00 2001 From: Vjacheslav Trushkin Date: Tue, 3 Apr 2012 00:41:56 +0300 Subject: [PATCH 055/441] [ticket/10754] Changing $style to $phpbb_style Renaming global variable $style to $phpbb_style PHPBB3-10754 --- phpBB/adm/index.php | 4 ++-- phpBB/common.php | 2 +- phpBB/includes/functions_messenger.php | 4 ++-- phpBB/includes/user.php | 4 ++-- phpBB/install/index.php | 6 +++--- phpBB/install/install_update.php | 2 +- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/phpBB/adm/index.php b/phpBB/adm/index.php index 91894e5aec..e20bbe4bec 100644 --- a/phpBB/adm/index.php +++ b/phpBB/adm/index.php @@ -51,8 +51,8 @@ $module_id = request_var('i', ''); $mode = request_var('mode', ''); // Set custom style for admin area -$style->set_ext_dir_prefix('adm/'); -$style->set_custom_style('admin', $phpbb_admin_path . 'style', ''); +$phpbb_style->set_ext_dir_prefix('adm/'); +$phpbb_style->set_custom_style('admin', $phpbb_admin_path . 'style', ''); $template->assign_var('T_ASSETS_PATH', $phpbb_root_path . 'assets'); $template->assign_var('T_TEMPLATE_PATH', $phpbb_admin_path . 'style'); diff --git a/phpBB/common.php b/phpBB/common.php index b3b8d7e4f7..a00e3e82a8 100644 --- a/phpBB/common.php +++ b/phpBB/common.php @@ -125,7 +125,7 @@ $phpbb_extension_manager = new phpbb_extension_manager($db, EXT_TABLE, $phpbb_ro $phpbb_style_resource_locator = new phpbb_style_resource_locator(); $phpbb_style_path_provider = new phpbb_style_extension_path_provider($phpbb_extension_manager, new phpbb_style_path_provider()); $template = new phpbb_style_template($phpbb_root_path, $phpEx, $config, $user, $phpbb_style_resource_locator, $phpbb_style_path_provider); -$style = new phpbb_style($phpbb_root_path, $phpEx, $config, $user, $phpbb_style_resource_locator, $phpbb_style_path_provider, $template); +$phpbb_style = new phpbb_style($phpbb_root_path, $phpEx, $config, $user, $phpbb_style_resource_locator, $phpbb_style_path_provider, $template); $phpbb_subscriber_loader = new phpbb_event_extension_subscriber_loader($phpbb_dispatcher, $phpbb_extension_manager); $phpbb_subscriber_loader->load(); diff --git a/phpBB/includes/functions_messenger.php b/phpBB/includes/functions_messenger.php index aae200df55..f608c95fe4 100644 --- a/phpBB/includes/functions_messenger.php +++ b/phpBB/includes/functions_messenger.php @@ -211,7 +211,7 @@ class messenger $style_resource_locator = new phpbb_style_resource_locator(); $style_path_provider = new phpbb_style_extension_path_provider($phpbb_extension_manager, new phpbb_style_path_provider()); $tpl = new phpbb_style_template($phpbb_root_path, $phpEx, $config, $user, $style_resource_locator, $style_path_provider); - $stl = new phpbb_style($phpbb_root_path, $phpEx, $config, $user, $style_resource_locator, $style_path_provider, $tpl); + $style = new phpbb_style($phpbb_root_path, $phpEx, $config, $user, $style_resource_locator, $style_path_provider, $tpl); $this->tpl_msg[$template_lang . $template_file] = $tpl; $fallback_template_path = false; @@ -230,7 +230,7 @@ class messenger } } - $stl->set_custom_style($template_lang . '_email', array($template_path, $fallback_template_path), ''); + $style->set_custom_style($template_lang . '_email', array($template_path, $fallback_template_path), ''); $tpl->set_filenames(array( 'body' => $template_file . '.txt', diff --git a/phpBB/includes/user.php b/phpBB/includes/user.php index 1676f82ccb..ce9c804f23 100644 --- a/phpBB/includes/user.php +++ b/phpBB/includes/user.php @@ -72,7 +72,7 @@ class phpbb_user extends phpbb_session */ function setup($lang_set = false, $style_id = false) { - global $db, $style, $template, $config, $auth, $phpEx, $phpbb_root_path, $cache; + global $db, $phpbb_style, $template, $config, $auth, $phpEx, $phpbb_root_path, $cache; if ($this->data['user_id'] != ANONYMOUS) { @@ -206,7 +206,7 @@ class phpbb_user extends phpbb_session } } - $style->set_style(); + $phpbb_style->set_style(); $this->img_lang = $this->lang_name; diff --git a/phpBB/install/index.php b/phpBB/install/index.php index 13ab30a9fa..bb10521bba 100644 --- a/phpBB/install/index.php +++ b/phpBB/install/index.php @@ -203,9 +203,9 @@ $config = new phpbb_config(array( $phpbb_style_resource_locator = new phpbb_style_resource_locator(); $phpbb_style_path_provider = new phpbb_style_path_provider(); $template = new phpbb_style_template($phpbb_root_path, $phpEx, $config, $user, $phpbb_style_resource_locator, $phpbb_style_path_provider); -$style = new phpbb_style($phpbb_root_path, $phpEx, $config, $user, $phpbb_style_resource_locator, $phpbb_style_path_provider, $template); -$style->set_ext_dir_prefix('adm/'); -$style->set_custom_style('admin', '../adm/style', ''); +$phpbb_style = new phpbb_style($phpbb_root_path, $phpEx, $config, $user, $phpbb_style_resource_locator, $phpbb_style_path_provider, $template); +$phpbb_style->set_ext_dir_prefix('adm/'); +$phpbb_style->set_custom_style('admin', '../adm/style', ''); $template->assign_var('T_ASSETS_PATH', '../assets'); $template->assign_var('T_TEMPLATE_PATH', '../adm/style'); diff --git a/phpBB/install/install_update.php b/phpBB/install/install_update.php index dcf01e5cc8..c2feaa086a 100644 --- a/phpBB/install/install_update.php +++ b/phpBB/install/install_update.php @@ -131,7 +131,7 @@ class install_update extends module } // Set custom template again. ;) - $style->set_custom_style('admin', '../adm/style', ''); + $phpbb_style->set_custom_style('admin', '../adm/style', ''); $template->assign_vars(array( 'S_USER_LANG' => $user->lang['USER_LANG'], From e769e0f723224b24cd9363530eb101be4818dc21 Mon Sep 17 00:00:00 2001 From: Vjacheslav Trushkin Date: Wed, 4 Apr 2012 13:07:24 +0300 Subject: [PATCH 056/441] [ticket/10762] Changing version format in style.cfg Splitting version into style_version and phpbb_version in style.cfg PHPBB3-10762 --- phpBB/styles/prosilver/style.cfg | 3 ++- phpBB/styles/subsilver2/style.cfg | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/phpBB/styles/prosilver/style.cfg b/phpBB/styles/prosilver/style.cfg index a80f1ed537..633079e4a6 100644 --- a/phpBB/styles/prosilver/style.cfg +++ b/phpBB/styles/prosilver/style.cfg @@ -18,7 +18,8 @@ # General Information about this style name = prosilver copyright = © phpBB Group, 2007 -version = 3.1.0-dev +style_version = 3.1.0-dev +phpbb_version = 3.1.0-dev # Defining a different template bitfield # template_bitfield = lNg= diff --git a/phpBB/styles/subsilver2/style.cfg b/phpBB/styles/subsilver2/style.cfg index 1a71e7254d..ca81337d17 100644 --- a/phpBB/styles/subsilver2/style.cfg +++ b/phpBB/styles/subsilver2/style.cfg @@ -18,7 +18,8 @@ # General Information about this style name = subsilver2 copyright = © 2005 phpBB Group -version = 3.1.0-dev +style_version = 3.1.0-dev +phpbb_version = 3.1.0-dev # Defining a different template bitfield # template_bitfield = lNg= From bb628044071f40130cdfc632d7f5636a11711ae0 Mon Sep 17 00:00:00 2001 From: Vjacheslav Trushkin Date: Wed, 4 Apr 2012 13:13:12 +0300 Subject: [PATCH 057/441] [ticket/10762] Check for phpbb_version when installing style Check if phpbb_version exists when installing style. Do not warn users about installing outdated styles yet, that part of acp_styles will be changed in different branch. PHPBB3-10762 --- phpBB/includes/acp/acp_styles.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/includes/acp/acp_styles.php b/phpBB/includes/acp/acp_styles.php index d33be274b4..de1f678e38 100644 --- a/phpBB/includes/acp/acp_styles.php +++ b/phpBB/includes/acp/acp_styles.php @@ -1056,7 +1056,7 @@ class acp_styles */ protected function read_style_cfg($dir) { - static $required = array('name', 'version', 'copyright'); + static $required = array('name', 'phpbb_version', 'copyright'); $cfg = parse_cfg_file($this->styles_path . $dir . '/style.cfg'); // Check if it is a valid file From 03e382f99c61c12655998ac8bd798fca7a34c099 Mon Sep 17 00:00:00 2001 From: Oleg Pudeyev Date: Thu, 5 Apr 2012 17:34:37 -0400 Subject: [PATCH 058/441] [ticket/10605] Fix syntax error in database updater. PHPBB3-10605 --- phpBB/install/database_update.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/install/database_update.php b/phpBB/install/database_update.php index b6298ca651..6088a58fc4 100644 --- a/phpBB/install/database_update.php +++ b/phpBB/install/database_update.php @@ -2041,7 +2041,7 @@ function change_database_data(&$no_updates, $version) 'ON' => 'p.msg_id = t.msg_id', ), ), - 'WHERE' => 't.user_id IS NULL'; + 'WHERE' => 't.user_id IS NULL'); $sql = $db->sql_build_query('SELECT', $sql_array); do From de1e343c5b408da09448b3150cfec2de75afd04a Mon Sep 17 00:00:00 2001 From: Oleg Pudeyev Date: Thu, 5 Apr 2012 17:34:54 -0400 Subject: [PATCH 059/441] [ticket/10605] Add a section for updating from 3.0.10 to schema updates. Without it data updates do not appear to be run. PHPBB3-10605 --- phpBB/install/database_update.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/phpBB/install/database_update.php b/phpBB/install/database_update.php index 6088a58fc4..116e6ea9a6 100644 --- a/phpBB/install/database_update.php +++ b/phpBB/install/database_update.php @@ -993,6 +993,8 @@ function database_update_info() '3.0.10-RC2' => array(), // No changes from 3.0.10-RC3 to 3.0.10 '3.0.10-RC3' => array(), + // No changes from 3.0.10 to 3.0.11-RC1 + '3.0.10' => array(), /** @todo DROP LOGIN_ATTEMPT_TABLE.attempt_id in 3.0.11-RC1 */ ); From 2b2286a46c56b8a9e5444fd06eff263f880e0c78 Mon Sep 17 00:00:00 2001 From: Oleg Pudeyev Date: Thu, 5 Apr 2012 17:35:27 -0400 Subject: [PATCH 060/441] [ticket/10605] Fix left join usage. Previously this produced broken SQL: SELECT p.msg_id FROM phpbb_privmsgs p LEFT JOIN 0 phpbb_privmsgs_to ON (p.msg_id = t.msg_id) WHERE t.user_id IS NULL LIMIT 500 OFFSET 0 PHPBB3-10605 --- phpBB/install/database_update.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/install/database_update.php b/phpBB/install/database_update.php index 116e6ea9a6..0737061887 100644 --- a/phpBB/install/database_update.php +++ b/phpBB/install/database_update.php @@ -2039,7 +2039,7 @@ function change_database_data(&$no_updates, $version) ), 'LEFT_JOIN' => array( array( - 'FROM' => array(PRIVMSGS_TO_TABLE, 't'), + 'FROM' => array(PRIVMSGS_TO_TABLE => 't'), 'ON' => 'p.msg_id = t.msg_id', ), ), From 9b30bd639201ffbbf1d1b3ae32fda7e75d3253dd Mon Sep 17 00:00:00 2001 From: Rahul Date: Sat, 24 Mar 2012 12:57:28 +0530 Subject: [PATCH 061/441] [ticket/10650] Displaying last topic on forum list The most recent topic title of the forum can now be displayed on the board index. An option is provided in the ACP under the 'General Forum Setting' which allows the admin to enable or disable this feature. PHPBB3-10650 --- phpBB/adm/style/acp_forums.html | 5 +++++ phpBB/develop/create_schema_files.php | 1 + phpBB/includes/acp/acp_forums.php | 4 ++++ phpBB/includes/functions_display.php | 1 + phpBB/install/database_update.php | 3 +++ phpBB/language/en/acp/forums.php | 2 ++ phpBB/styles/prosilver/template/forumlist_body.html | 5 ++++- 7 files changed, 20 insertions(+), 1 deletion(-) diff --git a/phpBB/adm/style/acp_forums.html b/phpBB/adm/style/acp_forums.html index 048a24a328..ec82947f92 100644 --- a/phpBB/adm/style/acp_forums.html +++ b/phpBB/adm/style/acp_forums.html @@ -237,6 +237,11 @@
    +
    +

    {L_DISPLAY_LAST_SUBJECT_EXPLAIN}
    +
    +
    +

    {L_FORUM_TOPICS_PAGE_EXPLAIN}
    diff --git a/phpBB/develop/create_schema_files.php b/phpBB/develop/create_schema_files.php index 4088657743..067ad198e3 100644 --- a/phpBB/develop/create_schema_files.php +++ b/phpBB/develop/create_schema_files.php @@ -1109,6 +1109,7 @@ function get_schema_struct() 'forum_options' => array('UINT:20', 0), 'display_subforum_list' => array('BOOL', 1), 'display_on_index' => array('BOOL', 1), + 'display_last_subject' => array('BOOL', 1), 'enable_indexing' => array('BOOL', 1), 'enable_icons' => array('BOOL', 1), 'enable_prune' => array('BOOL', 0), diff --git a/phpBB/includes/acp/acp_forums.php b/phpBB/includes/acp/acp_forums.php index 3a3b2021eb..29eabba0c7 100644 --- a/phpBB/includes/acp/acp_forums.php +++ b/phpBB/includes/acp/acp_forums.php @@ -133,6 +133,7 @@ class acp_forums 'forum_style' => request_var('forum_style', 0), 'display_subforum_list' => request_var('display_subforum_list', false), 'display_on_index' => request_var('display_on_index', false), + 'display_last_subject' => request_var('display_last_subject',true), 'forum_topics_per_page' => request_var('topics_per_page', 0), 'enable_indexing' => request_var('enable_indexing', true), 'enable_icons' => request_var('enable_icons', false), @@ -444,6 +445,7 @@ class acp_forums 'enable_prune' => false, 'prune_days' => 7, 'prune_viewed' => 7, + 'display_last_subject' => 0, 'prune_freq' => 1, 'forum_flags' => FORUM_FLAG_POST_REVIEW + FORUM_FLAG_ACTIVE_TOPICS, 'forum_options' => 0, @@ -636,6 +638,7 @@ class acp_forums 'S_ENABLE_INDEXING' => ($forum_data['enable_indexing']) ? true : false, 'S_TOPIC_ICONS' => ($forum_data['enable_icons']) ? true : false, 'S_DISPLAY_SUBFORUM_LIST' => ($forum_data['display_subforum_list']) ? true : false, + 'S_DISPLAY_SUBJECT' => ($forum_data['display_last_subject']) ? true : false, 'S_DISPLAY_ON_INDEX' => ($forum_data['display_on_index']) ? true : false, 'S_PRUNE_ENABLE' => ($forum_data['enable_prune']) ? true : false, 'S_FORUM_LINK_TRACK' => ($forum_data['forum_flags'] & FORUM_FLAG_LINK_TRACK) ? true : false, @@ -804,6 +807,7 @@ class acp_forums 'FORUM_TOPICS' => $row['forum_topics'], 'FORUM_POSTS' => $row['forum_posts'], + 'S_DISPLAY_SUBJECT' => ($row['display_last_subject']) ? true : false, 'S_FORUM_LINK' => ($forum_type == FORUM_LINK) ? true : false, 'S_FORUM_POST' => ($forum_type == FORUM_POST) ? true : false, diff --git a/phpBB/includes/functions_display.php b/phpBB/includes/functions_display.php index 18db64cc68..9b80763ee4 100644 --- a/phpBB/includes/functions_display.php +++ b/phpBB/includes/functions_display.php @@ -451,6 +451,7 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod 'S_LOCKED_FORUM' => ($row['forum_status'] == ITEM_LOCKED) ? true : false, 'S_LIST_SUBFORUMS' => ($row['display_subforum_list']) ? true : false, 'S_SUBFORUMS' => (sizeof($subforums_list)) ? true : false, + 'S_DISPLAY_SUBJECT' => ($row['display_last_subject']) ? true : false, 'S_FEED_ENABLED' => ($config['feed_forum'] && !phpbb_optionget(FORUM_OPTION_FEED_EXCLUDE, $row['forum_options']) && $row['forum_type'] == FORUM_POST) ? true : false, 'FORUM_ID' => $row['forum_id'], diff --git a/phpBB/install/database_update.php b/phpBB/install/database_update.php index a84136388c..509e991c81 100644 --- a/phpBB/install/database_update.php +++ b/phpBB/install/database_update.php @@ -1084,6 +1084,9 @@ function database_update_info() GROUPS_TABLE => array( 'group_teampage' => array('UINT', 0, 'after' => 'group_legend'), ), + FORUMS_TABLE => array( + 'display_last_subject' => array('BOOL', 1), + ), PROFILE_FIELDS_TABLE => array( 'field_show_on_pm' => array('BOOL', 0), ), diff --git a/phpBB/language/en/acp/forums.php b/phpBB/language/en/acp/forums.php index 756cb7ae0f..d456e8693d 100644 --- a/phpBB/language/en/acp/forums.php +++ b/phpBB/language/en/acp/forums.php @@ -57,6 +57,8 @@ $lang = array_merge($lang, array( 'DELETE_ALL_POSTS' => 'Delete posts', 'DELETE_SUBFORUMS' => 'Delete subforums and posts', 'DISPLAY_ACTIVE_TOPICS' => 'Enable active topics', + 'DISPLAY_LAST_SUBJECT' => 'Display last added post title on forum list', + 'DISPLAY_LAST_SUBJECT_EXPLAIN' => 'If set to yes the title of the last added post will be displayed in the forum list with a hyperlink to the post.', 'DISPLAY_ACTIVE_TOPICS_EXPLAIN' => 'If set to yes active topics in selected subforums will be displayed under this category.', 'EDIT_FORUM' => 'Edit forum', diff --git a/phpBB/styles/prosilver/template/forumlist_body.html b/phpBB/styles/prosilver/template/forumlist_body.html index d6596203e5..e1070ca23d 100644 --- a/phpBB/styles/prosilver/template/forumlist_body.html +++ b/phpBB/styles/prosilver/template/forumlist_body.html @@ -44,7 +44,10 @@
    {forumrow.POSTS} {L_POSTS}
    {UNAPPROVED_IMG} - {L_LAST_POST} {L_POST_BY_AUTHOR} {forumrow.LAST_POSTER_FULL} + {L_LAST_POST} + + {forumrow.LAST_POST_SUBJECT} + {L_POST_BY_AUTHOR} {forumrow.LAST_POSTER_FULL} {LAST_POST_IMG}
    {forumrow.LAST_POST_TIME}{L_NO_POSTS}
     
    From 668e47721c3566667c07c6892dcd2d55012e43b3 Mon Sep 17 00:00:00 2001 From: Rahul Date: Sun, 25 Mar 2012 01:39:34 +0530 Subject: [PATCH 062/441] [ticket/10650] Added static sql files Ran create_schema_files.php and added the generated static sql files to the commit. PHPBB3-10650 --- phpBB/install/schemas/firebird_schema.sql | 1 + phpBB/install/schemas/mssql_schema.sql | 1 + phpBB/install/schemas/mysql_40_schema.sql | 1 + phpBB/install/schemas/mysql_41_schema.sql | 1 + phpBB/install/schemas/oracle_schema.sql | 1 + phpBB/install/schemas/postgres_schema.sql | 1 + phpBB/install/schemas/sqlite_schema.sql | 1 + 7 files changed, 7 insertions(+) diff --git a/phpBB/install/schemas/firebird_schema.sql b/phpBB/install/schemas/firebird_schema.sql index 51565ef2d4..950362e746 100644 --- a/phpBB/install/schemas/firebird_schema.sql +++ b/phpBB/install/schemas/firebird_schema.sql @@ -376,6 +376,7 @@ CREATE TABLE phpbb_forums ( forum_options INTEGER DEFAULT 0 NOT NULL, display_subforum_list INTEGER DEFAULT 1 NOT NULL, display_on_index INTEGER DEFAULT 1 NOT NULL, + display_last_subject INTEGER DEFAULT 1 NOT NULL, enable_indexing INTEGER DEFAULT 1 NOT NULL, enable_icons INTEGER DEFAULT 1 NOT NULL, enable_prune INTEGER DEFAULT 0 NOT NULL, diff --git a/phpBB/install/schemas/mssql_schema.sql b/phpBB/install/schemas/mssql_schema.sql index 2c78dd009f..90a9563760 100644 --- a/phpBB/install/schemas/mssql_schema.sql +++ b/phpBB/install/schemas/mssql_schema.sql @@ -455,6 +455,7 @@ CREATE TABLE [phpbb_forums] ( [forum_options] [int] DEFAULT (0) NOT NULL , [display_subforum_list] [int] DEFAULT (1) NOT NULL , [display_on_index] [int] DEFAULT (1) NOT NULL , + [display_last_subject] [int] DEFAULT (1) NOT NULL , [enable_indexing] [int] DEFAULT (1) NOT NULL , [enable_icons] [int] DEFAULT (1) NOT NULL , [enable_prune] [int] DEFAULT (0) NOT NULL , diff --git a/phpBB/install/schemas/mysql_40_schema.sql b/phpBB/install/schemas/mysql_40_schema.sql index d19f1930d0..7f7225463d 100644 --- a/phpBB/install/schemas/mysql_40_schema.sql +++ b/phpBB/install/schemas/mysql_40_schema.sql @@ -262,6 +262,7 @@ CREATE TABLE phpbb_forums ( forum_options int(20) UNSIGNED DEFAULT '0' NOT NULL, display_subforum_list tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, display_on_index tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, + display_last_subject tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, enable_indexing tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, enable_icons tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, enable_prune tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, diff --git a/phpBB/install/schemas/mysql_41_schema.sql b/phpBB/install/schemas/mysql_41_schema.sql index 3fd8d4f1d1..cd23c6ec86 100644 --- a/phpBB/install/schemas/mysql_41_schema.sql +++ b/phpBB/install/schemas/mysql_41_schema.sql @@ -262,6 +262,7 @@ CREATE TABLE phpbb_forums ( forum_options int(20) UNSIGNED DEFAULT '0' NOT NULL, display_subforum_list tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, display_on_index tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, + display_last_subject tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, enable_indexing tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, enable_icons tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, enable_prune tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, diff --git a/phpBB/install/schemas/oracle_schema.sql b/phpBB/install/schemas/oracle_schema.sql index 8a0f3e56b1..0fe1eb9acb 100644 --- a/phpBB/install/schemas/oracle_schema.sql +++ b/phpBB/install/schemas/oracle_schema.sql @@ -522,6 +522,7 @@ CREATE TABLE phpbb_forums ( forum_options number(20) DEFAULT '0' NOT NULL, display_subforum_list number(1) DEFAULT '1' NOT NULL, display_on_index number(1) DEFAULT '1' NOT NULL, + display_last_subject number(1) DEFAULT '1' NOT NULL, enable_indexing number(1) DEFAULT '1' NOT NULL, enable_icons number(1) DEFAULT '1' NOT NULL, enable_prune number(1) DEFAULT '0' NOT NULL, diff --git a/phpBB/install/schemas/postgres_schema.sql b/phpBB/install/schemas/postgres_schema.sql index c624024362..91e5629791 100644 --- a/phpBB/install/schemas/postgres_schema.sql +++ b/phpBB/install/schemas/postgres_schema.sql @@ -398,6 +398,7 @@ CREATE TABLE phpbb_forums ( forum_options INT4 DEFAULT '0' NOT NULL CHECK (forum_options >= 0), display_subforum_list INT2 DEFAULT '1' NOT NULL CHECK (display_subforum_list >= 0), display_on_index INT2 DEFAULT '1' NOT NULL CHECK (display_on_index >= 0), + display_last_subject INT2 DEFAULT '1' NOT NULL CHECK (display_last_subject >= 0), enable_indexing INT2 DEFAULT '1' NOT NULL CHECK (enable_indexing >= 0), enable_icons INT2 DEFAULT '1' NOT NULL CHECK (enable_icons >= 0), enable_prune INT2 DEFAULT '0' NOT NULL CHECK (enable_prune >= 0), diff --git a/phpBB/install/schemas/sqlite_schema.sql b/phpBB/install/schemas/sqlite_schema.sql index bd002c93ed..090ae0911b 100644 --- a/phpBB/install/schemas/sqlite_schema.sql +++ b/phpBB/install/schemas/sqlite_schema.sql @@ -255,6 +255,7 @@ CREATE TABLE phpbb_forums ( forum_options INTEGER UNSIGNED NOT NULL DEFAULT '0', display_subforum_list INTEGER UNSIGNED NOT NULL DEFAULT '1', display_on_index INTEGER UNSIGNED NOT NULL DEFAULT '1', + display_last_subject INTEGER UNSIGNED NOT NULL DEFAULT '1', enable_indexing INTEGER UNSIGNED NOT NULL DEFAULT '1', enable_icons INTEGER UNSIGNED NOT NULL DEFAULT '1', enable_prune INTEGER UNSIGNED NOT NULL DEFAULT '0', From 492c27a6935aa1fe3165ee3cd89897496fa153d1 Mon Sep 17 00:00:00 2001 From: Rahul Date: Sat, 31 Mar 2012 22:41:41 +0530 Subject: [PATCH 063/441] [ticket/10650] Changed language files and forumlist The entry in languages have been changed from title to subject. Also the IF condition in forumlist_body.html has been properly intented. PHPBB3-10650 --- phpBB/language/en/acp/forums.php | 4 ++-- phpBB/styles/prosilver/template/forumlist_body.html | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/phpBB/language/en/acp/forums.php b/phpBB/language/en/acp/forums.php index d456e8693d..9141abc8eb 100644 --- a/phpBB/language/en/acp/forums.php +++ b/phpBB/language/en/acp/forums.php @@ -57,8 +57,8 @@ $lang = array_merge($lang, array( 'DELETE_ALL_POSTS' => 'Delete posts', 'DELETE_SUBFORUMS' => 'Delete subforums and posts', 'DISPLAY_ACTIVE_TOPICS' => 'Enable active topics', - 'DISPLAY_LAST_SUBJECT' => 'Display last added post title on forum list', - 'DISPLAY_LAST_SUBJECT_EXPLAIN' => 'If set to yes the title of the last added post will be displayed in the forum list with a hyperlink to the post.', + 'DISPLAY_LAST_SUBJECT' => 'Display subject of last added post on forum list', + 'DISPLAY_LAST_SUBJECT_EXPLAIN' => 'If set to yes the subject of the last added post will be displayed in the forum list with a hyperlink to the post.', 'DISPLAY_ACTIVE_TOPICS_EXPLAIN' => 'If set to yes active topics in selected subforums will be displayed under this category.', 'EDIT_FORUM' => 'Edit forum', diff --git a/phpBB/styles/prosilver/template/forumlist_body.html b/phpBB/styles/prosilver/template/forumlist_body.html index e1070ca23d..17454ed330 100644 --- a/phpBB/styles/prosilver/template/forumlist_body.html +++ b/phpBB/styles/prosilver/template/forumlist_body.html @@ -46,7 +46,8 @@ {UNAPPROVED_IMG} {L_LAST_POST} - {forumrow.LAST_POST_SUBJECT} + {forumrow.LAST_POST_SUBJECT} + {L_POST_BY_AUTHOR} {forumrow.LAST_POSTER_FULL} {LAST_POST_IMG}
    {forumrow.LAST_POST_TIME}{L_NO_POSTS}
      From bc21dec9c07a9566d60d775b2c25d8065b503764 Mon Sep 17 00:00:00 2001 From: Rahul Date: Sat, 31 Mar 2012 23:25:13 +0530 Subject: [PATCH 064/441] [ticket/10650] Corrected space before true Inserted a space before 'true' as per coding guidelines. PHPBB3-10650 --- phpBB/includes/acp/acp_forums.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/includes/acp/acp_forums.php b/phpBB/includes/acp/acp_forums.php index 29eabba0c7..5323a0e4e6 100644 --- a/phpBB/includes/acp/acp_forums.php +++ b/phpBB/includes/acp/acp_forums.php @@ -133,7 +133,7 @@ class acp_forums 'forum_style' => request_var('forum_style', 0), 'display_subforum_list' => request_var('display_subforum_list', false), 'display_on_index' => request_var('display_on_index', false), - 'display_last_subject' => request_var('display_last_subject',true), + 'display_last_subject' => request_var('display_last_subject', true), 'forum_topics_per_page' => request_var('topics_per_page', 0), 'enable_indexing' => request_var('enable_indexing', true), 'enable_icons' => request_var('enable_icons', false), From 720fc46807f92364321bcb26291eafea1688c5ca Mon Sep 17 00:00:00 2001 From: Rahul R Date: Tue, 3 Apr 2012 21:36:26 +0530 Subject: [PATCH 065/441] [ticket/10650] Cropped subject and inserted newline The subject being displayed in the forum list have been shortened to 30 characters. Also it is now being shown in a separate line. PHPBB3-10650 --- phpBB/includes/functions_display.php | 5 +++++ phpBB/styles/prosilver/template/forumlist_body.html | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/phpBB/includes/functions_display.php b/phpBB/includes/functions_display.php index 9b80763ee4..b331ed7d71 100644 --- a/phpBB/includes/functions_display.php +++ b/phpBB/includes/functions_display.php @@ -397,6 +397,11 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod if ($row['forum_last_post_id']) { $last_post_subject = $row['forum_last_post_subject']; + if (strlen($last_post_subject) > 30) + { + $last_post_subject = substr($last_post_subject, 0, 30); + $last_post_subject .= '...'; + } $last_post_time = $user->format_date($row['forum_last_post_time']); $last_post_url = append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'f=' . $row['forum_id_last_post'] . '&p=' . $row['forum_last_post_id']) . '#p' . $row['forum_last_post_id']; } diff --git a/phpBB/styles/prosilver/template/forumlist_body.html b/phpBB/styles/prosilver/template/forumlist_body.html index 17454ed330..68df81932a 100644 --- a/phpBB/styles/prosilver/template/forumlist_body.html +++ b/phpBB/styles/prosilver/template/forumlist_body.html @@ -46,7 +46,7 @@ {UNAPPROVED_IMG} {L_LAST_POST} - {forumrow.LAST_POST_SUBJECT} + {forumrow.LAST_POST_SUBJECT}
    {L_POST_BY_AUTHOR} {forumrow.LAST_POSTER_FULL} {LAST_POST_IMG}
    {forumrow.LAST_POST_TIME}{L_NO_POSTS}
      From 4bb20d7ceaf4d8f2cf19fa7f79ba239156326045 Mon Sep 17 00:00:00 2001 From: Rahul R Date: Thu, 5 Apr 2012 00:39:52 +0530 Subject: [PATCH 066/441] [ticket/10650]Added permission checking and utf8 functions Passworded forums and ones in which user doesn't have read access will be excluded. Also uft8 based string functions and html encode/decode functions have been used to sanitise subject. PHPBB3-10650 --- phpBB/includes/functions_display.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/phpBB/includes/functions_display.php b/phpBB/includes/functions_display.php index b331ed7d71..8e0005eadf 100644 --- a/phpBB/includes/functions_display.php +++ b/phpBB/includes/functions_display.php @@ -397,9 +397,9 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod if ($row['forum_last_post_id']) { $last_post_subject = $row['forum_last_post_subject']; - if (strlen($last_post_subject) > 30) - { - $last_post_subject = substr($last_post_subject, 0, 30); + if (utf8_strlen(htmlspecialchars_decode($last_post_subject)) > 30) + { + $last_post_subject = htmlspecialchars(utf8_substr(htmlspecialchars_decode($last_post_subject, 0, 30))); $last_post_subject .= '...'; } $last_post_time = $user->format_date($row['forum_last_post_time']); @@ -456,7 +456,7 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod 'S_LOCKED_FORUM' => ($row['forum_status'] == ITEM_LOCKED) ? true : false, 'S_LIST_SUBFORUMS' => ($row['display_subforum_list']) ? true : false, 'S_SUBFORUMS' => (sizeof($subforums_list)) ? true : false, - 'S_DISPLAY_SUBJECT' => ($row['display_last_subject']) ? true : false, + 'S_DISPLAY_SUBJECT' => ($row['display_last_subject'] && !$row['forum_password'] && $auth->acl_get('f_read', $row['forum_id'])) ? true : false, 'S_FEED_ENABLED' => ($config['feed_forum'] && !phpbb_optionget(FORUM_OPTION_FEED_EXCLUDE, $row['forum_options']) && $row['forum_type'] == FORUM_POST) ? true : false, 'FORUM_ID' => $row['forum_id'], From 630c0397b9a1735fc60ef3704be41d05e4929ceb Mon Sep 17 00:00:00 2001 From: Rahul R Date: Thu, 5 Apr 2012 01:19:46 +0530 Subject: [PATCH 067/441] [ticket/10650] Corrected intendation Corrected the intendation of if condition. PHPBB3-10650 --- phpBB/includes/functions_display.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/phpBB/includes/functions_display.php b/phpBB/includes/functions_display.php index 8e0005eadf..a28f546be0 100644 --- a/phpBB/includes/functions_display.php +++ b/phpBB/includes/functions_display.php @@ -398,10 +398,10 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod { $last_post_subject = $row['forum_last_post_subject']; if (utf8_strlen(htmlspecialchars_decode($last_post_subject)) > 30) - { - $last_post_subject = htmlspecialchars(utf8_substr(htmlspecialchars_decode($last_post_subject, 0, 30))); - $last_post_subject .= '...'; - } + { + $last_post_subject = htmlspecialchars(utf8_substr(htmlspecialchars_decode($last_post_subject, 0, 30))); + $last_post_subject .= '...'; + } $last_post_time = $user->format_date($row['forum_last_post_time']); $last_post_url = append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'f=' . $row['forum_id_last_post'] . '&p=' . $row['forum_last_post_id']) . '#p' . $row['forum_last_post_id']; } From 2a8481d68188480061e9769711195091f05f7134 Mon Sep 17 00:00:00 2001 From: Rahul R Date: Thu, 5 Apr 2012 02:02:02 +0530 Subject: [PATCH 068/441] [ticket/10650] Added checking for empty subjects Now empty subjects will not be displayed in a new line on the forum list. PHPBB3-10650 --- phpBB/includes/functions_display.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/includes/functions_display.php b/phpBB/includes/functions_display.php index a28f546be0..4e70a4911c 100644 --- a/phpBB/includes/functions_display.php +++ b/phpBB/includes/functions_display.php @@ -456,7 +456,7 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod 'S_LOCKED_FORUM' => ($row['forum_status'] == ITEM_LOCKED) ? true : false, 'S_LIST_SUBFORUMS' => ($row['display_subforum_list']) ? true : false, 'S_SUBFORUMS' => (sizeof($subforums_list)) ? true : false, - 'S_DISPLAY_SUBJECT' => ($row['display_last_subject'] && !$row['forum_password'] && $auth->acl_get('f_read', $row['forum_id'])) ? true : false, + 'S_DISPLAY_SUBJECT' => ($last_post_subject && $row['display_last_subject'] && !$row['forum_password'] && $auth->acl_get('f_read', $row['forum_id'])) ? true : false, 'S_FEED_ENABLED' => ($config['feed_forum'] && !phpbb_optionget(FORUM_OPTION_FEED_EXCLUDE, $row['forum_options']) && $row['forum_type'] == FORUM_POST) ? true : false, 'FORUM_ID' => $row['forum_id'], From c524236ef6d84f6ef78f684aeb7bb469ca844db4 Mon Sep 17 00:00:00 2001 From: Rahul R Date: Fri, 6 Apr 2012 01:07:23 +0530 Subject: [PATCH 069/441] [ticket/10650] Changed acp option from per forum to global Changed the display last subject acp toggle option from per forum to global. Modified associated database entries. New option is available in ACP General->Board Features. Also corrected
    in forumlist_body.html. PHPBB3-10650 --- phpBB/adm/style/acp_forums.html | 5 ----- phpBB/develop/create_schema_files.php | 1 - phpBB/includes/acp/acp_board.php | 1 + phpBB/includes/functions_display.php | 2 +- phpBB/install/database_update.php | 10 +++++++--- phpBB/install/schemas/firebird_schema.sql | 1 - phpBB/install/schemas/mssql_schema.sql | 1 - phpBB/install/schemas/mysql_40_schema.sql | 1 - phpBB/install/schemas/mysql_41_schema.sql | 1 - phpBB/install/schemas/oracle_schema.sql | 1 - phpBB/install/schemas/postgres_schema.sql | 1 - phpBB/install/schemas/sqlite_schema.sql | 1 - phpBB/language/en/acp/board.php | 2 ++ phpBB/language/en/acp/forums.php | 2 -- phpBB/styles/prosilver/template/forumlist_body.html | 2 +- 15 files changed, 12 insertions(+), 20 deletions(-) diff --git a/phpBB/adm/style/acp_forums.html b/phpBB/adm/style/acp_forums.html index ec82947f92..048a24a328 100644 --- a/phpBB/adm/style/acp_forums.html +++ b/phpBB/adm/style/acp_forums.html @@ -237,11 +237,6 @@
    -
    -

    {L_DISPLAY_LAST_SUBJECT_EXPLAIN}
    -
    -
    -

    {L_FORUM_TOPICS_PAGE_EXPLAIN}
    diff --git a/phpBB/develop/create_schema_files.php b/phpBB/develop/create_schema_files.php index 067ad198e3..4088657743 100644 --- a/phpBB/develop/create_schema_files.php +++ b/phpBB/develop/create_schema_files.php @@ -1109,7 +1109,6 @@ function get_schema_struct() 'forum_options' => array('UINT:20', 0), 'display_subforum_list' => array('BOOL', 1), 'display_on_index' => array('BOOL', 1), - 'display_last_subject' => array('BOOL', 1), 'enable_indexing' => array('BOOL', 1), 'enable_icons' => array('BOOL', 1), 'enable_prune' => array('BOOL', 0), diff --git a/phpBB/includes/acp/acp_board.php b/phpBB/includes/acp/acp_board.php index 58b55eeddb..7bd51b5e0d 100644 --- a/phpBB/includes/acp/acp_board.php +++ b/phpBB/includes/acp/acp_board.php @@ -88,6 +88,7 @@ class acp_board 'allow_nocensors' => array('lang' => 'ALLOW_NO_CENSORS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'allow_bookmarks' => array('lang' => 'ALLOW_BOOKMARKS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'allow_birthdays' => array('lang' => 'ALLOW_BIRTHDAYS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), + 'display_last_subject' => array('lang' => 'DISPLAY_LAST_SUBJECT', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'allow_quick_reply' => array('lang' => 'ALLOW_QUICK_REPLY', 'validate' => 'bool', 'type' => 'custom', 'method' => 'quick_reply', 'explain' => true), 'legend2' => 'ACP_LOAD_SETTINGS', diff --git a/phpBB/includes/functions_display.php b/phpBB/includes/functions_display.php index 4e70a4911c..99adf6f6a7 100644 --- a/phpBB/includes/functions_display.php +++ b/phpBB/includes/functions_display.php @@ -456,7 +456,7 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod 'S_LOCKED_FORUM' => ($row['forum_status'] == ITEM_LOCKED) ? true : false, 'S_LIST_SUBFORUMS' => ($row['display_subforum_list']) ? true : false, 'S_SUBFORUMS' => (sizeof($subforums_list)) ? true : false, - 'S_DISPLAY_SUBJECT' => ($last_post_subject && $row['display_last_subject'] && !$row['forum_password'] && $auth->acl_get('f_read', $row['forum_id'])) ? true : false, + 'S_DISPLAY_SUBJECT' => ($last_post_subject && $config['display_last_subject'] && !$row['forum_password'] && $auth->acl_get('f_read', $row['forum_id'])) ? true : false, 'S_FEED_ENABLED' => ($config['feed_forum'] && !phpbb_optionget(FORUM_OPTION_FEED_EXCLUDE, $row['forum_options']) && $row['forum_type'] == FORUM_POST) ? true : false, 'FORUM_ID' => $row['forum_id'], diff --git a/phpBB/install/database_update.php b/phpBB/install/database_update.php index 509e991c81..89b252e3fa 100644 --- a/phpBB/install/database_update.php +++ b/phpBB/install/database_update.php @@ -1084,9 +1084,6 @@ function database_update_info() GROUPS_TABLE => array( 'group_teampage' => array('UINT', 0, 'after' => 'group_legend'), ), - FORUMS_TABLE => array( - 'display_last_subject' => array('BOOL', 1), - ), PROFILE_FIELDS_TABLE => array( 'field_show_on_pm' => array('BOOL', 0), ), @@ -2397,8 +2394,15 @@ function change_database_data(&$no_updates, $version) $sql = 'INSERT INTO ' . STYLES_TABLE . " (style_name, style_copyright, style_active, style_path, bbcode_bitfield, style_parent_id, style_parent_tree) VALUES ('prosilver', '© phpBB Group', 1, 'prosilver', 'kNg=', 0, '')"; _sql($sql, $errored, $error_ary); + //Create config value for displaying last subject on forum list + if(!isset($config['display_last_subject'])) + { + $config->set("display_last_subject", '1'); + } + $no_updates = false; break; } } + diff --git a/phpBB/install/schemas/firebird_schema.sql b/phpBB/install/schemas/firebird_schema.sql index 950362e746..51565ef2d4 100644 --- a/phpBB/install/schemas/firebird_schema.sql +++ b/phpBB/install/schemas/firebird_schema.sql @@ -376,7 +376,6 @@ CREATE TABLE phpbb_forums ( forum_options INTEGER DEFAULT 0 NOT NULL, display_subforum_list INTEGER DEFAULT 1 NOT NULL, display_on_index INTEGER DEFAULT 1 NOT NULL, - display_last_subject INTEGER DEFAULT 1 NOT NULL, enable_indexing INTEGER DEFAULT 1 NOT NULL, enable_icons INTEGER DEFAULT 1 NOT NULL, enable_prune INTEGER DEFAULT 0 NOT NULL, diff --git a/phpBB/install/schemas/mssql_schema.sql b/phpBB/install/schemas/mssql_schema.sql index 90a9563760..2c78dd009f 100644 --- a/phpBB/install/schemas/mssql_schema.sql +++ b/phpBB/install/schemas/mssql_schema.sql @@ -455,7 +455,6 @@ CREATE TABLE [phpbb_forums] ( [forum_options] [int] DEFAULT (0) NOT NULL , [display_subforum_list] [int] DEFAULT (1) NOT NULL , [display_on_index] [int] DEFAULT (1) NOT NULL , - [display_last_subject] [int] DEFAULT (1) NOT NULL , [enable_indexing] [int] DEFAULT (1) NOT NULL , [enable_icons] [int] DEFAULT (1) NOT NULL , [enable_prune] [int] DEFAULT (0) NOT NULL , diff --git a/phpBB/install/schemas/mysql_40_schema.sql b/phpBB/install/schemas/mysql_40_schema.sql index 7f7225463d..d19f1930d0 100644 --- a/phpBB/install/schemas/mysql_40_schema.sql +++ b/phpBB/install/schemas/mysql_40_schema.sql @@ -262,7 +262,6 @@ CREATE TABLE phpbb_forums ( forum_options int(20) UNSIGNED DEFAULT '0' NOT NULL, display_subforum_list tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, display_on_index tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - display_last_subject tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, enable_indexing tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, enable_icons tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, enable_prune tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, diff --git a/phpBB/install/schemas/mysql_41_schema.sql b/phpBB/install/schemas/mysql_41_schema.sql index cd23c6ec86..3fd8d4f1d1 100644 --- a/phpBB/install/schemas/mysql_41_schema.sql +++ b/phpBB/install/schemas/mysql_41_schema.sql @@ -262,7 +262,6 @@ CREATE TABLE phpbb_forums ( forum_options int(20) UNSIGNED DEFAULT '0' NOT NULL, display_subforum_list tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, display_on_index tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - display_last_subject tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, enable_indexing tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, enable_icons tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, enable_prune tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, diff --git a/phpBB/install/schemas/oracle_schema.sql b/phpBB/install/schemas/oracle_schema.sql index 0fe1eb9acb..8a0f3e56b1 100644 --- a/phpBB/install/schemas/oracle_schema.sql +++ b/phpBB/install/schemas/oracle_schema.sql @@ -522,7 +522,6 @@ CREATE TABLE phpbb_forums ( forum_options number(20) DEFAULT '0' NOT NULL, display_subforum_list number(1) DEFAULT '1' NOT NULL, display_on_index number(1) DEFAULT '1' NOT NULL, - display_last_subject number(1) DEFAULT '1' NOT NULL, enable_indexing number(1) DEFAULT '1' NOT NULL, enable_icons number(1) DEFAULT '1' NOT NULL, enable_prune number(1) DEFAULT '0' NOT NULL, diff --git a/phpBB/install/schemas/postgres_schema.sql b/phpBB/install/schemas/postgres_schema.sql index 91e5629791..c624024362 100644 --- a/phpBB/install/schemas/postgres_schema.sql +++ b/phpBB/install/schemas/postgres_schema.sql @@ -398,7 +398,6 @@ CREATE TABLE phpbb_forums ( forum_options INT4 DEFAULT '0' NOT NULL CHECK (forum_options >= 0), display_subforum_list INT2 DEFAULT '1' NOT NULL CHECK (display_subforum_list >= 0), display_on_index INT2 DEFAULT '1' NOT NULL CHECK (display_on_index >= 0), - display_last_subject INT2 DEFAULT '1' NOT NULL CHECK (display_last_subject >= 0), enable_indexing INT2 DEFAULT '1' NOT NULL CHECK (enable_indexing >= 0), enable_icons INT2 DEFAULT '1' NOT NULL CHECK (enable_icons >= 0), enable_prune INT2 DEFAULT '0' NOT NULL CHECK (enable_prune >= 0), diff --git a/phpBB/install/schemas/sqlite_schema.sql b/phpBB/install/schemas/sqlite_schema.sql index 090ae0911b..bd002c93ed 100644 --- a/phpBB/install/schemas/sqlite_schema.sql +++ b/phpBB/install/schemas/sqlite_schema.sql @@ -255,7 +255,6 @@ CREATE TABLE phpbb_forums ( forum_options INTEGER UNSIGNED NOT NULL DEFAULT '0', display_subforum_list INTEGER UNSIGNED NOT NULL DEFAULT '1', display_on_index INTEGER UNSIGNED NOT NULL DEFAULT '1', - display_last_subject INTEGER UNSIGNED NOT NULL DEFAULT '1', enable_indexing INTEGER UNSIGNED NOT NULL DEFAULT '1', enable_icons INTEGER UNSIGNED NOT NULL DEFAULT '1', enable_prune INTEGER UNSIGNED NOT NULL DEFAULT '0', diff --git a/phpBB/language/en/acp/board.php b/phpBB/language/en/acp/board.php index 0bb99b5449..187d823fd0 100644 --- a/phpBB/language/en/acp/board.php +++ b/phpBB/language/en/acp/board.php @@ -44,6 +44,8 @@ $lang = array_merge($lang, array( 'DEFAULT_STYLE' => 'Default style', 'DISABLE_BOARD' => 'Disable board', 'DISABLE_BOARD_EXPLAIN' => 'This will make the board unavailable to users. You can also enter a short (255 character) message to display if you wish.', + 'DISPLAY_LAST_SUBJECT' => 'Display subject of last added post on forum list', + 'DISPLAY_LAST_SUBJECT_EXPLAIN' => 'The subject of the last added post will be displayed in the forum list with a hyperlink to the post. Subjects from password protected forums and ones in which user doesnt have read access are not shown.', 'OVERRIDE_STYLE' => 'Override user style', 'OVERRIDE_STYLE_EXPLAIN' => 'Replaces user’s style with the default.', 'SITE_DESC' => 'Site description', diff --git a/phpBB/language/en/acp/forums.php b/phpBB/language/en/acp/forums.php index 9141abc8eb..756cb7ae0f 100644 --- a/phpBB/language/en/acp/forums.php +++ b/phpBB/language/en/acp/forums.php @@ -57,8 +57,6 @@ $lang = array_merge($lang, array( 'DELETE_ALL_POSTS' => 'Delete posts', 'DELETE_SUBFORUMS' => 'Delete subforums and posts', 'DISPLAY_ACTIVE_TOPICS' => 'Enable active topics', - 'DISPLAY_LAST_SUBJECT' => 'Display subject of last added post on forum list', - 'DISPLAY_LAST_SUBJECT_EXPLAIN' => 'If set to yes the subject of the last added post will be displayed in the forum list with a hyperlink to the post.', 'DISPLAY_ACTIVE_TOPICS_EXPLAIN' => 'If set to yes active topics in selected subforums will be displayed under this category.', 'EDIT_FORUM' => 'Edit forum', diff --git a/phpBB/styles/prosilver/template/forumlist_body.html b/phpBB/styles/prosilver/template/forumlist_body.html index 68df81932a..ca38d3b5c0 100644 --- a/phpBB/styles/prosilver/template/forumlist_body.html +++ b/phpBB/styles/prosilver/template/forumlist_body.html @@ -46,7 +46,7 @@ {UNAPPROVED_IMG} {L_LAST_POST} - {forumrow.LAST_POST_SUBJECT}
    + {forumrow.LAST_POST_SUBJECT}
    {L_POST_BY_AUTHOR} {forumrow.LAST_POSTER_FULL} {LAST_POST_IMG}
    {forumrow.LAST_POST_TIME}{L_NO_POSTS}
      From b6957aa5252544fe0b52af94e35bc93b47e3518e Mon Sep 17 00:00:00 2001 From: Rahul R Date: Fri, 6 Apr 2012 01:15:12 +0530 Subject: [PATCH 070/441] [ticket/10650]Removed incorrect newline Deleted additional line in the end of database_update.php PHPBB3-10650 --- phpBB/install/database_update.php | 1 - 1 file changed, 1 deletion(-) diff --git a/phpBB/install/database_update.php b/phpBB/install/database_update.php index 89b252e3fa..4f5fe142c9 100644 --- a/phpBB/install/database_update.php +++ b/phpBB/install/database_update.php @@ -2405,4 +2405,3 @@ function change_database_data(&$no_updates, $version) break; } } - From b0f5db152f2c24fe6fe821f91d05d7e327a587c0 Mon Sep 17 00:00:00 2001 From: Rahul R Date: Sun, 8 Apr 2012 11:12:29 +0530 Subject: [PATCH 071/441] [ticket/10650] Removed changes from acp_forums.php Removed unneccesary changes from acp_forums.php PHPBB3-10650 --- phpBB/includes/acp/acp_forums.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/phpBB/includes/acp/acp_forums.php b/phpBB/includes/acp/acp_forums.php index 5323a0e4e6..3a3b2021eb 100644 --- a/phpBB/includes/acp/acp_forums.php +++ b/phpBB/includes/acp/acp_forums.php @@ -133,7 +133,6 @@ class acp_forums 'forum_style' => request_var('forum_style', 0), 'display_subforum_list' => request_var('display_subforum_list', false), 'display_on_index' => request_var('display_on_index', false), - 'display_last_subject' => request_var('display_last_subject', true), 'forum_topics_per_page' => request_var('topics_per_page', 0), 'enable_indexing' => request_var('enable_indexing', true), 'enable_icons' => request_var('enable_icons', false), @@ -445,7 +444,6 @@ class acp_forums 'enable_prune' => false, 'prune_days' => 7, 'prune_viewed' => 7, - 'display_last_subject' => 0, 'prune_freq' => 1, 'forum_flags' => FORUM_FLAG_POST_REVIEW + FORUM_FLAG_ACTIVE_TOPICS, 'forum_options' => 0, @@ -638,7 +636,6 @@ class acp_forums 'S_ENABLE_INDEXING' => ($forum_data['enable_indexing']) ? true : false, 'S_TOPIC_ICONS' => ($forum_data['enable_icons']) ? true : false, 'S_DISPLAY_SUBFORUM_LIST' => ($forum_data['display_subforum_list']) ? true : false, - 'S_DISPLAY_SUBJECT' => ($forum_data['display_last_subject']) ? true : false, 'S_DISPLAY_ON_INDEX' => ($forum_data['display_on_index']) ? true : false, 'S_PRUNE_ENABLE' => ($forum_data['enable_prune']) ? true : false, 'S_FORUM_LINK_TRACK' => ($forum_data['forum_flags'] & FORUM_FLAG_LINK_TRACK) ? true : false, @@ -807,7 +804,6 @@ class acp_forums 'FORUM_TOPICS' => $row['forum_topics'], 'FORUM_POSTS' => $row['forum_posts'], - 'S_DISPLAY_SUBJECT' => ($row['display_last_subject']) ? true : false, 'S_FORUM_LINK' => ($forum_type == FORUM_LINK) ? true : false, 'S_FORUM_POST' => ($forum_type == FORUM_POST) ? true : false, From 094dbe7ccc22119aa50963ae4714a00e76aef9a5 Mon Sep 17 00:00:00 2001 From: Rahul R Date: Sun, 8 Apr 2012 12:25:25 +0530 Subject: [PATCH 072/441] [ticket/10650] Made use of truncate_string() function Removed manual cropping and used truncate_string function. Also made a new variable so that is preserved. PHPBB3-10650 --- phpBB/includes/functions_display.php | 7 ++----- phpBB/styles/prosilver/template/forumlist_body.html | 2 +- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/phpBB/includes/functions_display.php b/phpBB/includes/functions_display.php index 99adf6f6a7..fbb6d65b92 100644 --- a/phpBB/includes/functions_display.php +++ b/phpBB/includes/functions_display.php @@ -397,11 +397,7 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod if ($row['forum_last_post_id']) { $last_post_subject = $row['forum_last_post_subject']; - if (utf8_strlen(htmlspecialchars_decode($last_post_subject)) > 30) - { - $last_post_subject = htmlspecialchars(utf8_substr(htmlspecialchars_decode($last_post_subject, 0, 30))); - $last_post_subject .= '...'; - } + $last_post_subject_truncated = truncate_string($last_post_subject, 30, 255 ,false, '…'); $last_post_time = $user->format_date($row['forum_last_post_time']); $last_post_url = append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'f=' . $row['forum_id_last_post'] . '&p=' . $row['forum_last_post_id']) . '#p' . $row['forum_last_post_id']; } @@ -470,6 +466,7 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod 'FORUM_IMAGE' => ($row['forum_image']) ? '' . $user->lang[$folder_alt] . '' : '', 'FORUM_IMAGE_SRC' => ($row['forum_image']) ? $phpbb_root_path . $row['forum_image'] : '', 'LAST_POST_SUBJECT' => censor_text($last_post_subject), + 'LAST_POST_SUBJECT_TRUNCATED' => censor_text($last_post_subject_truncated), 'LAST_POST_TIME' => $last_post_time, 'LAST_POSTER' => get_username_string('username', $row['forum_last_poster_id'], $row['forum_last_poster_name'], $row['forum_last_poster_colour']), 'LAST_POSTER_COLOUR' => get_username_string('colour', $row['forum_last_poster_id'], $row['forum_last_poster_name'], $row['forum_last_poster_colour']), diff --git a/phpBB/styles/prosilver/template/forumlist_body.html b/phpBB/styles/prosilver/template/forumlist_body.html index ca38d3b5c0..55f8e6df30 100644 --- a/phpBB/styles/prosilver/template/forumlist_body.html +++ b/phpBB/styles/prosilver/template/forumlist_body.html @@ -46,7 +46,7 @@ {UNAPPROVED_IMG} {L_LAST_POST} - {forumrow.LAST_POST_SUBJECT}
    + {forumrow.LAST_POST_SUBJECT_TRUNCATED}
    {L_POST_BY_AUTHOR} {forumrow.LAST_POSTER_FULL} {LAST_POST_IMG}
    {forumrow.LAST_POST_TIME}{L_NO_POSTS}
      From dd3b8e74b33da4dabb60001c2bffa5d8b2cec236 Mon Sep 17 00:00:00 2001 From: Rahul R Date: Sun, 8 Apr 2012 12:45:51 +0530 Subject: [PATCH 073/441] [ticket/10650] Added href title to subject link Added title attribute to anchor tag which displays last_post_subject so that the full subject can be seen by hovering over the truncated subject displayed in forumlist. PHPBB3-10650 --- phpBB/styles/prosilver/template/forumlist_body.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/styles/prosilver/template/forumlist_body.html b/phpBB/styles/prosilver/template/forumlist_body.html index 55f8e6df30..be12f1e89a 100644 --- a/phpBB/styles/prosilver/template/forumlist_body.html +++ b/phpBB/styles/prosilver/template/forumlist_body.html @@ -46,7 +46,7 @@ {UNAPPROVED_IMG} {L_LAST_POST} - {forumrow.LAST_POST_SUBJECT_TRUNCATED}
    + {forumrow.LAST_POST_SUBJECT_TRUNCATED}
    {L_POST_BY_AUTHOR} {forumrow.LAST_POSTER_FULL} {LAST_POST_IMG}
    {forumrow.LAST_POST_TIME}{L_NO_POSTS}
      From 2dec700aabcb8b5bebf707b41378ede61512e745 Mon Sep 17 00:00:00 2001 From: Rahul R Date: Sun, 8 Apr 2012 22:52:49 +0530 Subject: [PATCH 074/441] [ticket/10650] Added ellipsis to language file Added ELLIPSIS to language file common.php and also corrected language explanation of ACP option. PHPBB3-10650 --- phpBB/includes/functions_display.php | 2 +- phpBB/language/en/acp/board.php | 2 +- phpBB/language/en/common.php | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/phpBB/includes/functions_display.php b/phpBB/includes/functions_display.php index fbb6d65b92..138749d2db 100644 --- a/phpBB/includes/functions_display.php +++ b/phpBB/includes/functions_display.php @@ -397,7 +397,7 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod if ($row['forum_last_post_id']) { $last_post_subject = $row['forum_last_post_subject']; - $last_post_subject_truncated = truncate_string($last_post_subject, 30, 255 ,false, '…'); + $last_post_subject_truncated = truncate_string($last_post_subject, 30, 255 ,false, $user->lang['ELLIPSIS']); $last_post_time = $user->format_date($row['forum_last_post_time']); $last_post_url = append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'f=' . $row['forum_id_last_post'] . '&p=' . $row['forum_last_post_id']) . '#p' . $row['forum_last_post_id']; } diff --git a/phpBB/language/en/acp/board.php b/phpBB/language/en/acp/board.php index 187d823fd0..7329f8dcaf 100644 --- a/phpBB/language/en/acp/board.php +++ b/phpBB/language/en/acp/board.php @@ -45,7 +45,7 @@ $lang = array_merge($lang, array( 'DISABLE_BOARD' => 'Disable board', 'DISABLE_BOARD_EXPLAIN' => 'This will make the board unavailable to users. You can also enter a short (255 character) message to display if you wish.', 'DISPLAY_LAST_SUBJECT' => 'Display subject of last added post on forum list', - 'DISPLAY_LAST_SUBJECT_EXPLAIN' => 'The subject of the last added post will be displayed in the forum list with a hyperlink to the post. Subjects from password protected forums and ones in which user doesnt have read access are not shown.', + 'DISPLAY_LAST_SUBJECT_EXPLAIN' => 'The subject of the last added post will be displayed in the forum list with a hyperlink to the post. Subjects from password protected forums and forums in which user doesnt have read access are not shown.', 'OVERRIDE_STYLE' => 'Override user style', 'OVERRIDE_STYLE_EXPLAIN' => 'Replaces user’s style with the default.', 'SITE_DESC' => 'Site description', diff --git a/phpBB/language/en/common.php b/phpBB/language/en/common.php index 12f8edad9e..f46e5df4db 100644 --- a/phpBB/language/en/common.php +++ b/phpBB/language/en/common.php @@ -169,6 +169,7 @@ $lang = array_merge($lang, array( ), 'EDIT_POST' => 'Edit post', + 'ELLIPSIS' => ' …', // ... 'EMAIL' => 'E-mail', // Short form for EMAIL_ADDRESS 'EMAIL_ADDRESS' => 'E-mail address', 'EMAIL_SMTP_ERROR_RESPONSE' => 'Ran into problems sending e-mail at Line %1$s. Response: %2$s.', From 303748b02db2aa76391f60770c292edf45cee360 Mon Sep 17 00:00:00 2001 From: Rahul R Date: Mon, 9 Apr 2012 01:43:44 +0530 Subject: [PATCH 075/441] [ticket/10650] Added space after if and comment Added space in proper places in database_update.php. Also corrected language entry of ELLIPSIS to utf8 PHPBB3-10650 --- phpBB/install/database_update.php | 6 +++--- phpBB/language/en/common.php | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/phpBB/install/database_update.php b/phpBB/install/database_update.php index 4f5fe142c9..5c70a07f1e 100644 --- a/phpBB/install/database_update.php +++ b/phpBB/install/database_update.php @@ -2394,10 +2394,10 @@ function change_database_data(&$no_updates, $version) $sql = 'INSERT INTO ' . STYLES_TABLE . " (style_name, style_copyright, style_active, style_path, bbcode_bitfield, style_parent_id, style_parent_tree) VALUES ('prosilver', '© phpBB Group', 1, 'prosilver', 'kNg=', 0, '')"; _sql($sql, $errored, $error_ary); - //Create config value for displaying last subject on forum list - if(!isset($config['display_last_subject'])) + // Create config value for displaying last subject on forum list + if (!isset($config['display_last_subject'])) { - $config->set("display_last_subject", '1'); + $config->set('display_last_subject', '1'); } $no_updates = false; diff --git a/phpBB/language/en/common.php b/phpBB/language/en/common.php index f46e5df4db..bf44ba0796 100644 --- a/phpBB/language/en/common.php +++ b/phpBB/language/en/common.php @@ -169,7 +169,7 @@ $lang = array_merge($lang, array( ), 'EDIT_POST' => 'Edit post', - 'ELLIPSIS' => ' …', // ... + 'ELLIPSIS' => ' ...', 'EMAIL' => 'E-mail', // Short form for EMAIL_ADDRESS 'EMAIL_ADDRESS' => 'E-mail address', 'EMAIL_SMTP_ERROR_RESPONSE' => 'Ran into problems sending e-mail at Line %1$s. Response: %2$s.', From db275d0a907f60fc437710b099b21061ef3b0daf Mon Sep 17 00:00:00 2001 From: Rahul R Date: Mon, 9 Apr 2012 02:51:18 +0530 Subject: [PATCH 076/441] [ticket/10650] Inserted correct utf ELLIPSIS character Inserted the correct utf-8 ellipsis to the language file. PHPBB3-10650 --- phpBB/language/en/common.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/language/en/common.php b/phpBB/language/en/common.php index bf44ba0796..91c37e82bd 100644 --- a/phpBB/language/en/common.php +++ b/phpBB/language/en/common.php @@ -169,7 +169,7 @@ $lang = array_merge($lang, array( ), 'EDIT_POST' => 'Edit post', - 'ELLIPSIS' => ' ...', + 'ELLIPSIS' => '…', 'EMAIL' => 'E-mail', // Short form for EMAIL_ADDRESS 'EMAIL_ADDRESS' => 'E-mail address', 'EMAIL_SMTP_ERROR_RESPONSE' => 'Ran into problems sending e-mail at Line %1$s. Response: %2$s.', From 6661c92dd3ce4dc9b414bb39706298725057b7c0 Mon Sep 17 00:00:00 2001 From: Rahul R Date: Mon, 9 Apr 2012 03:22:35 +0530 Subject: [PATCH 077/441] [ticket/10650] Added apostrophe in explanation in language file A missing apostrophe was added to the language file entry of DISPLAY_LAST_SUBJECT_EXPLAIN PHPBB3-10650 --- phpBB/language/en/acp/board.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/language/en/acp/board.php b/phpBB/language/en/acp/board.php index 7329f8dcaf..a448c0ee7d 100644 --- a/phpBB/language/en/acp/board.php +++ b/phpBB/language/en/acp/board.php @@ -45,7 +45,7 @@ $lang = array_merge($lang, array( 'DISABLE_BOARD' => 'Disable board', 'DISABLE_BOARD_EXPLAIN' => 'This will make the board unavailable to users. You can also enter a short (255 character) message to display if you wish.', 'DISPLAY_LAST_SUBJECT' => 'Display subject of last added post on forum list', - 'DISPLAY_LAST_SUBJECT_EXPLAIN' => 'The subject of the last added post will be displayed in the forum list with a hyperlink to the post. Subjects from password protected forums and forums in which user doesnt have read access are not shown.', + 'DISPLAY_LAST_SUBJECT_EXPLAIN' => 'The subject of the last added post will be displayed in the forum list with a hyperlink to the post. Subjects from password protected forums and forums in which user doesn\'t have read access are not shown.', 'OVERRIDE_STYLE' => 'Override user style', 'OVERRIDE_STYLE_EXPLAIN' => 'Replaces user’s style with the default.', 'SITE_DESC' => 'Site description', From fa04c3712b611425e41f5f5ac661eb0cddcba3ec Mon Sep 17 00:00:00 2001 From: Shibu Lijack Date: Mon, 9 Apr 2012 18:43:54 +0530 Subject: [PATCH 078/441] [ticket/10734] Moved style elements and fixed minor bugs Moved color related style elements to colours.css and other elements to common.css Also added an empty display for corners span. Removed unwanted space in mcp_topic Removed DS_Store PHPBB-10734 --- phpBB/styles/prosilver/template/mcp_topic.html | 3 +-- phpBB/styles/prosilver/theme/colours.css | 11 +---------- phpBB/styles/prosilver/theme/common.css | 10 ++++++++++ phpBB/styles/prosilver/theme/content.css | 4 ++++ phpBB/styles/prosilver/theme/images/.DS_Store | Bin 6148 -> 0 bytes 5 files changed, 16 insertions(+), 12 deletions(-) delete mode 100644 phpBB/styles/prosilver/theme/images/.DS_Store diff --git a/phpBB/styles/prosilver/template/mcp_topic.html b/phpBB/styles/prosilver/template/mcp_topic.html index 1da1b1b3d4..527d21771e 100644 --- a/phpBB/styles/prosilver/template/mcp_topic.html +++ b/phpBB/styles/prosilver/template/mcp_topic.html @@ -21,8 +21,7 @@ onload_functions.push('subPanels()');
      -
    • class="activetab"> - +
    • class="activetab" {L_DISPLAY_OPTIONS}
    • diff --git a/phpBB/styles/prosilver/theme/colours.css b/phpBB/styles/prosilver/theme/colours.css index 53fa2dd653..66b60ea7bf 100644 --- a/phpBB/styles/prosilver/theme/colours.css +++ b/phpBB/styles/prosilver/theme/colours.css @@ -47,34 +47,26 @@ hr { background-color: #12A3EB; background-image: url("./images/bg_header.gif"); color: #FFFFFF; - border-radius: 7px; } .navbar { background-color: #cadceb; - border-radius: 7px; } .forabg { background-color: #0076b1; background-image: url("./images/bg_list.gif"); - border-radius: 7px; } .forumbg { background-color: #12A3EB; background-image: url("./images/bg_header.gif"); - border-radius: 7px; } .panel { background-color: #ECF1F3; color: #28313F; - border-radius: 7px; -} - -.post { - border-radius: 7px; + } .post:target .content { @@ -871,7 +863,6 @@ ul.cplist { #cp-main .panel { background-color: #F9F9F9; - padding: 5px 10px; } #cp-main .pm { diff --git a/phpBB/styles/prosilver/theme/common.css b/phpBB/styles/prosilver/theme/common.css index 57696d71ee..300125b4f1 100644 --- a/phpBB/styles/prosilver/theme/common.css +++ b/phpBB/styles/prosilver/theme/common.css @@ -252,12 +252,14 @@ a#logo:hover { background: transparent none repeat-x 0 0; margin-bottom: 4px; padding: 5px; + border-radius: 7px; } .navbar { padding: 0 10px; background-color: #ebebeb; padding: 5px 10px 5px 10px; + border-radius: 7px; } .forabg { @@ -265,6 +267,7 @@ a#logo:hover { margin-bottom: 4px; padding: 5px; clear: both; + border-radius: 7px; } .forumbg { @@ -272,6 +275,7 @@ a#logo:hover { margin-bottom: 4px; padding: 5px; clear: both; + border-radius: 7px; } .panel { @@ -279,6 +283,7 @@ a#logo:hover { padding: 5px 10px; background-color: #f3f3f3; color: #3f3f3f; + border-radius: 7px; } .post { @@ -286,6 +291,7 @@ a#logo:hover { margin-bottom: 4px; background-repeat: no-repeat; background-position: 100% 0; + border-radius: 7px; } .inner:after { @@ -307,6 +313,10 @@ ul.linklist { overflow: hidden; } +#cp-main .panel { + padding: 5px 10px; +} + ul.linklist li { display: block; list-style-type: none; diff --git a/phpBB/styles/prosilver/theme/content.css b/phpBB/styles/prosilver/theme/content.css index b0872f78aa..60903911dd 100644 --- a/phpBB/styles/prosilver/theme/content.css +++ b/phpBB/styles/prosilver/theme/content.css @@ -336,6 +336,10 @@ div[class].topic-actions { line-height: 1.4em; } +span.corners-top, span.corners-bottom { + display: none; +} + dl.faq { font-family: "Lucida Grande", Verdana, Helvetica, Arial, sans-serif; font-size: 1.1em; diff --git a/phpBB/styles/prosilver/theme/images/.DS_Store b/phpBB/styles/prosilver/theme/images/.DS_Store deleted file mode 100644 index 5008ddfcf53c02e82d7eee2e57c38e5672ef89f6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeH~Jr2S!425mzP>H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T0 Date: Tue, 10 Apr 2012 00:46:24 +0200 Subject: [PATCH 079/441] [ticket/10774] Add unit tests for UNIQUE index existence and creation. PHPBB3-10774 --- tests/dbal/db_tools_test.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/dbal/db_tools_test.php b/tests/dbal/db_tools_test.php index fbde636b58..c7ddb88ce8 100644 --- a/tests/dbal/db_tools_test.php +++ b/tests/dbal/db_tools_test.php @@ -354,9 +354,20 @@ class phpbb_dbal_db_tools_test extends phpbb_database_test_case $this->assertTrue($this->tools->sql_index_exists('prefix_table_name', 'i_simple')); } + public function test_unique_index_exists() + { + $this->assertTrue($this->tools->sql_unique_index_exists('prefix_table_name', 'i_uniq')); + } + public function test_create_index_against_index_exists() { $this->tools->sql_create_index('prefix_table_name', 'fookey', array('c_timestamp', 'c_decimal')); $this->assertTrue($this->tools->sql_index_exists('prefix_table_name', 'fookey')); } + + public function test_create_unique_index_against_unique_index_exists() + { + $this->tools->sql_create_unique_index('prefix_table_name', 'i_uniq_ts_id', array('c_timestamp', 'c_id')); + $this->assertTrue($this->tools->sql_unique_index_exists('prefix_table_name', 'i_uniq_ts_id')); + } } From ef8160e8a2a1dbb51cd2603eefcd9309d2daece8 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Tue, 10 Apr 2012 00:53:27 +0200 Subject: [PATCH 080/441] [ticket/10774] Correctly specify index name when creating unique index on MySQL. PHPBB3-10774 --- phpBB/includes/db/db_tools.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/includes/db/db_tools.php b/phpBB/includes/db/db_tools.php index 2cba11133a..c6dd23e6bd 100644 --- a/phpBB/includes/db/db_tools.php +++ b/phpBB/includes/db/db_tools.php @@ -2115,7 +2115,7 @@ class phpbb_db_tools case 'mysql_40': case 'mysql_41': - $statements[] = 'ALTER TABLE ' . $table_name . ' ADD UNIQUE INDEX (' . implode(', ', $column) . ')'; + $statements[] = 'ALTER TABLE ' . $table_name . ' ADD UNIQUE INDEX ' . $index_name . '(' . implode(', ', $column) . ')'; break; case 'mssql': From 1e4710b1949155543a729d36b5da89c9c965f6c0 Mon Sep 17 00:00:00 2001 From: Rahul R Date: Tue, 10 Apr 2012 08:22:52 +0530 Subject: [PATCH 081/441] [ticket/10650] Moving censoring to before truncation The censor_text function is now being applied to the last_post_subject before being truncated. PHPBB3-10650 --- phpBB/includes/functions_display.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/phpBB/includes/functions_display.php b/phpBB/includes/functions_display.php index 138749d2db..950c1f0cd8 100644 --- a/phpBB/includes/functions_display.php +++ b/phpBB/includes/functions_display.php @@ -397,7 +397,7 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod if ($row['forum_last_post_id']) { $last_post_subject = $row['forum_last_post_subject']; - $last_post_subject_truncated = truncate_string($last_post_subject, 30, 255 ,false, $user->lang['ELLIPSIS']); + $last_post_subject_truncated = truncate_string(censor_text($last_post_subject), 30, 255, false, $user->lang['ELLIPSIS']); $last_post_time = $user->format_date($row['forum_last_post_time']); $last_post_url = append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'f=' . $row['forum_id_last_post'] . '&p=' . $row['forum_last_post_id']) . '#p' . $row['forum_last_post_id']; } @@ -466,7 +466,7 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod 'FORUM_IMAGE' => ($row['forum_image']) ? '' . $user->lang[$folder_alt] . '' : '', 'FORUM_IMAGE_SRC' => ($row['forum_image']) ? $phpbb_root_path . $row['forum_image'] : '', 'LAST_POST_SUBJECT' => censor_text($last_post_subject), - 'LAST_POST_SUBJECT_TRUNCATED' => censor_text($last_post_subject_truncated), + 'LAST_POST_SUBJECT_TRUNCATED' => $last_post_subject_truncated, 'LAST_POST_TIME' => $last_post_time, 'LAST_POSTER' => get_username_string('username', $row['forum_last_poster_id'], $row['forum_last_poster_name'], $row['forum_last_poster_colour']), 'LAST_POSTER_COLOUR' => get_username_string('colour', $row['forum_last_poster_id'], $row['forum_last_poster_name'], $row['forum_last_poster_colour']), From c1c71c26b4679a0a094bfc5a4723268e53b9ae18 Mon Sep 17 00:00:00 2001 From: Shibu Lijack Date: Tue, 10 Apr 2012 19:48:00 +0530 Subject: [PATCH 082/441] [ticket/10734] Removed unwanted color elements Deleted all the color elements from the common.css PHPBB-10734 --- phpBB/styles/prosilver/theme/common.css | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/phpBB/styles/prosilver/theme/common.css b/phpBB/styles/prosilver/theme/common.css index 300125b4f1..01187cc684 100644 --- a/phpBB/styles/prosilver/theme/common.css +++ b/phpBB/styles/prosilver/theme/common.css @@ -257,7 +257,6 @@ a#logo:hover { .navbar { padding: 0 10px; - background-color: #ebebeb; padding: 5px 10px 5px 10px; border-radius: 7px; } @@ -281,8 +280,6 @@ a#logo:hover { .panel { margin-bottom: 4px; padding: 5px 10px; - background-color: #f3f3f3; - color: #3f3f3f; border-radius: 7px; } @@ -545,14 +542,6 @@ li.pagination { background: none 0 50% no-repeat; } -.row .pagination span a, li.pagination span a { - background-color: #FFFFFF; -} - -.row .pagination span a:hover, li.pagination span a:hover { - background-color: #d2d2d2; -} - /* jQuery popups ---------------------------------------- */ .phpbb_alert { From daee25340381d4b97119be298a9fc2671e681bb3 Mon Sep 17 00:00:00 2001 From: Shibu Lijack Date: Tue, 10 Apr 2012 20:51:24 +0530 Subject: [PATCH 083/441] [ticket/10734] Fixed minor bug Removed an extra empty line in colors.css PHPBB-10734 --- phpBB/styles/prosilver/theme/colours.css | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/phpBB/styles/prosilver/theme/colours.css b/phpBB/styles/prosilver/theme/colours.css index 66b60ea7bf..fe6a7a7fda 100644 --- a/phpBB/styles/prosilver/theme/colours.css +++ b/phpBB/styles/prosilver/theme/colours.css @@ -65,8 +65,7 @@ hr { .panel { background-color: #ECF1F3; - color: #28313F; - + color: #28313F; } .post:target .content { From 779b16041cf270f1fd0873e6490ce5f5cc11d5e4 Mon Sep 17 00:00:00 2001 From: Rahul R Date: Tue, 10 Apr 2012 21:27:09 +0530 Subject: [PATCH 084/441] [ticket/10777] Corrected typo in comment savely was corrected to safely PHPBB3-10777 --- phpBB/viewtopic.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/viewtopic.php b/phpBB/viewtopic.php index a43edee5da..df6ccc5905 100644 --- a/phpBB/viewtopic.php +++ b/phpBB/viewtopic.php @@ -1629,7 +1629,7 @@ else $all_marked_read = true; } -// If there are absolutely no more unread posts in this forum and unread posts shown, we can savely show the #unread link +// If there are absolutely no more unread posts in this forum and unread posts shown, we can safely show the #unread link if ($all_marked_read) { if ($post_unread) From 4176ee1c9555950480e9c4872107917abc32a209 Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Tue, 10 Apr 2012 15:19:26 -0700 Subject: [PATCH 085/441] [ticket/10779] Move jQuery CDN option to Load Settings http://tracker.phpbb.com/browse/PHPBB3-10779 PHPBB3-10779 --- phpBB/includes/acp/acp_board.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/phpBB/includes/acp/acp_board.php b/phpBB/includes/acp/acp_board.php index 58b55eeddb..951166f086 100644 --- a/phpBB/includes/acp/acp_board.php +++ b/phpBB/includes/acp/acp_board.php @@ -98,7 +98,6 @@ class acp_board 'load_cpf_pm' => array('lang' => 'LOAD_CPF_PM', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'load_cpf_viewprofile' => array('lang' => 'LOAD_CPF_VIEWPROFILE', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'load_cpf_viewtopic' => array('lang' => 'LOAD_CPF_VIEWTOPIC', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), - 'load_jquery_cdn' => array('lang' => 'LOAD_JQUERY_CDN', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'legend3' => 'ACP_SUBMIT_CHANGES', ) @@ -324,7 +323,8 @@ class acp_board 'load_moderators' => array('lang' => 'YES_MODERATORS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'load_jumpbox' => array('lang' => 'YES_JUMPBOX', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'load_user_activity' => array('lang' => 'LOAD_USER_ACTIVITY', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), - 'load_tplcompile' => array('lang' => 'RECOMPILE_STYLES', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), + 'load_tplcompile' => array('lang' => 'RECOMPILE_STYLES', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), + 'load_jquery_cdn' => array('lang' => 'LOAD_JQUERY_CDN', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'legend3' => 'CUSTOM_PROFILE_FIELDS', 'load_cpf_memberlist' => array('lang' => 'LOAD_CPF_MEMBERLIST', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), From bab32bd56afefb97634f7c9ac336c7ac2fe3f7c1 Mon Sep 17 00:00:00 2001 From: Rahul R Date: Wed, 11 Apr 2012 06:23:56 +0530 Subject: [PATCH 086/441] [ticket/10650] Changed apostrophe to utf8 single quote The apostrophe in language entry DISPLAY_LAST_SUBJECT_EXPLAIN was changed to utf8 single quote character. PHPBB3-10650 --- phpBB/language/en/acp/board.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/language/en/acp/board.php b/phpBB/language/en/acp/board.php index a448c0ee7d..19c380e0a6 100644 --- a/phpBB/language/en/acp/board.php +++ b/phpBB/language/en/acp/board.php @@ -45,7 +45,7 @@ $lang = array_merge($lang, array( 'DISABLE_BOARD' => 'Disable board', 'DISABLE_BOARD_EXPLAIN' => 'This will make the board unavailable to users. You can also enter a short (255 character) message to display if you wish.', 'DISPLAY_LAST_SUBJECT' => 'Display subject of last added post on forum list', - 'DISPLAY_LAST_SUBJECT_EXPLAIN' => 'The subject of the last added post will be displayed in the forum list with a hyperlink to the post. Subjects from password protected forums and forums in which user doesn\'t have read access are not shown.', + 'DISPLAY_LAST_SUBJECT_EXPLAIN' => 'The subject of the last added post will be displayed in the forum list with a hyperlink to the post. Subjects from password protected forums and forums in which user doesn’t have read access are not shown.', 'OVERRIDE_STYLE' => 'Override user style', 'OVERRIDE_STYLE_EXPLAIN' => 'Replaces user’s style with the default.', 'SITE_DESC' => 'Site description', From e0df7d17f9a4d6afc1033b5ab181001eaa5afce0 Mon Sep 17 00:00:00 2001 From: Callum Macrae Date: Wed, 11 Apr 2012 13:00:02 +0100 Subject: [PATCH 087/441] [ticket/10785] Fixed illegal use of $_REQUEST in develop/fill.php. PHPBB3-10785 --- phpBB/develop/fill.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/phpBB/develop/fill.php b/phpBB/develop/fill.php index a4cd90bfca..5c3552265d 100644 --- a/phpBB/develop/fill.php +++ b/phpBB/develop/fill.php @@ -39,8 +39,8 @@ $posts_per_topic = 500; // general vars -$mode = (isset($_REQUEST['mode'])) ? $_REQUEST['mode'] : 'generate'; -$start = (isset($_REQUEST['start'])) ? intval($_REQUEST['start']) : 0; +$mode = request_var('mode', 'generate'); +$start = request_var('start', 0); switch ($mode) { From 3da5166703a63988e75d0f4e4d7c9ea99897a648 Mon Sep 17 00:00:00 2001 From: Shibu Lijack Date: Wed, 11 Apr 2012 17:46:47 +0530 Subject: [PATCH 088/441] [ticket/10688] Changed 3.0 to 3.1 in docs Replaced all the occurrences of phpBB 3.0 with phpBB 3.1 in all the doc files PHPBB-10688 --- phpBB/docs/CHANGELOG.html | 6 +++--- phpBB/docs/FAQ.html | 6 +++--- phpBB/docs/INSTALL.html | 14 +++++++------- phpBB/docs/README.html | 6 +++--- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/phpBB/docs/CHANGELOG.html b/phpBB/docs/CHANGELOG.html index ba56d02759..7655aaa71f 100644 --- a/phpBB/docs/CHANGELOG.html +++ b/phpBB/docs/CHANGELOG.html @@ -3,7 +3,7 @@ - + phpBB3 • Changelog @@ -20,7 +20,7 @@
      -

      phpBB 3.0.x Changelog

      +

      phpBB 3.1.x Changelog

      Skip

      @@ -34,7 +34,7 @@ -

      This is a non-exhaustive (but still near complete) changelog for phpBB 3.0.x including release candidate versions. Our thanks to all those people who've contributed bug reports and code fixes.

      +

      This is a non-exhaustive (but still near complete) changelog for phpBB 3.1.x including release candidate versions. Our thanks to all those people who've contributed bug reports and code fixes.

      Changelog

      diff --git a/phpBB/docs/FAQ.html b/phpBB/docs/FAQ.html index 5e83f27142..ebc5d06189 100644 --- a/phpBB/docs/FAQ.html +++ b/phpBB/docs/FAQ.html @@ -3,7 +3,7 @@ - + phpBB3 • FAQ @@ -20,8 +20,8 @@
      -

      phpBB 3.0.x FAQ

      -

      phpBB 3.0.x frequently asked questions

      +

      phpBB 3.1.x FAQ

      +

      phpBB 3.1.x frequently asked questions

      Skip

      diff --git a/phpBB/docs/INSTALL.html b/phpBB/docs/INSTALL.html index 9b27ac06bc..9628e4c337 100644 --- a/phpBB/docs/INSTALL.html +++ b/phpBB/docs/INSTALL.html @@ -3,7 +3,7 @@ - + phpBB3 • Install @@ -20,8 +20,8 @@
      -

      phpBB 3.0.x Install

      -

      phpBB 3.0.x Installation, updating and conversion informations

      +

      phpBB 3.1.x Install

      +

      phpBB 3.1.x Installation, updating and conversion informations

      Skip

      @@ -52,7 +52,7 @@
    • Quick install
    • Requirements
    • New installation
    • -
    • Updating from stable releases of phpBB 3.0.x +
    • Updating from stable releases of phpBB 3.1.x
      1. Full package
      2. Changed files only
      3. @@ -61,7 +61,7 @@
      4. All package types
    • -
    • Conversion from phpBB 2.0.x to phpBB 3.0.x +
    • Conversion from phpBB 2.0.x to phpBB 3.1.x
      1. Requirements before converting
      2. Converting
      3. @@ -242,7 +242,7 @@
        -

        4. Updating from stable releases of phpBB 3.0.x

        +

        4. Updating from stable releases of phpBB 3.1.x

        @@ -316,7 +316,7 @@
        -

        5. Conversion from phpBB 2.0.x to phpBB 3.0.x

        +

        5. Conversion from phpBB 2.0.x to phpBB 3.1.x

        diff --git a/phpBB/docs/README.html b/phpBB/docs/README.html index 592d2be76e..7cd727c60e 100644 --- a/phpBB/docs/README.html +++ b/phpBB/docs/README.html @@ -3,7 +3,7 @@ - + phpBB3 • Readme @@ -20,7 +20,7 @@
        -

        phpBB 3.0.x Readme

        +

        phpBB 3.1.x Readme

        Skip

        @@ -215,7 +215,7 @@

        http://area51.phpbb.com/phpBB/

        -

        Please note that this forum should NOT be used to obtain support for or ask questions about phpBB 2.0.x or phpBB 3.0.x, the main community forums are the place for this. Any such posts will be locked and go unanswered.

        +

        Please note that this forum should NOT be used to obtain support for or ask questions about phpBB 2.0.x or phpBB 3.1.x, the main community forums are the place for this. Any such posts will be locked and go unanswered.

        From 394a95b5c5c048e9c606f5fc05e512ddc40e5ded Mon Sep 17 00:00:00 2001 From: Shibu Lijack Date: Wed, 11 Apr 2012 17:54:50 +0530 Subject: [PATCH 089/441] [ticket/10688] Updated version to 3.1 Replace phpBB 3.0.x to phpBB 3.1.x PHPBB-10688 --- phpBB/includes/functions.php | 2 +- phpBB/includes/functions_install.php | 2 +- phpBB/install/convertors/functions_phpbb20.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index 9913a80a70..438e095071 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -343,7 +343,7 @@ function still_on_time($extra_time = 15) /** * -* @version Version 0.1 / slightly modified for phpBB 3.0.x (using $H$ as hash type identifier) +* @version Version 0.1 / slightly modified for phpBB 3.1.x (using $H$ as hash type identifier) * * Portable PHP password hashing framework. * diff --git a/phpBB/includes/functions_install.php b/phpBB/includes/functions_install.php index a49e19f09a..c1250bac27 100644 --- a/phpBB/includes/functions_install.php +++ b/phpBB/includes/functions_install.php @@ -516,7 +516,7 @@ function phpbb_create_config_file_data($data, $dbms, $load_extensions, $debug = $load_extensions = implode(',', $load_extensions); $config_data = " $dbms, diff --git a/phpBB/install/convertors/functions_phpbb20.php b/phpBB/install/convertors/functions_phpbb20.php index aea6074637..0b6daeef47 100644 --- a/phpBB/install/convertors/functions_phpbb20.php +++ b/phpBB/install/convertors/functions_phpbb20.php @@ -13,7 +13,7 @@ if (!defined('IN_PHPBB')) } /** -* Helper functions for phpBB 2.0.x to phpBB 3.0.x conversion +* Helper functions for phpBB 2.0.x to phpBB 3.1.x conversion */ /** From 7fa2be51ce1a9c3f196c85a450da8f200b95bf84 Mon Sep 17 00:00:00 2001 From: Shibu Lijack Date: Wed, 11 Apr 2012 18:01:58 +0530 Subject: [PATCH 090/441] [ticket/10688] Changed version 3.0 to 3.1 Replaced phpBB 3.0 to 3.1 in the stylesheets PHPBB-10688 --- phpBB/adm/style/admin.css | 2 +- phpBB/styles/prosilver/theme/stylesheet.css | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/phpBB/adm/style/admin.css b/phpBB/adm/style/admin.css index ceda824e5a..7ae4339b49 100644 --- a/phpBB/adm/style/admin.css +++ b/phpBB/adm/style/admin.css @@ -1,4 +1,4 @@ -/* phpBB 3.0 Admin Style Sheet +/* phpBB 3.1 Admin Style Sheet ------------------------------------------------------------------------ Original author: subBlue ( http://www.subblue.com/ ) Copyright 2007 phpBB Group ( http://www.phpbb.com/ ) diff --git a/phpBB/styles/prosilver/theme/stylesheet.css b/phpBB/styles/prosilver/theme/stylesheet.css index 3cf60ea494..b597ee43e6 100644 --- a/phpBB/styles/prosilver/theme/stylesheet.css +++ b/phpBB/styles/prosilver/theme/stylesheet.css @@ -1,6 +1,6 @@ /* phpBB3 Style Sheet -------------------------------------------------------------- - Style name: prosilver (the default phpBB 3.0.x style) + Style name: prosilver (the default phpBB 3.1.x style) Based on style: Original author: Tom Beddard ( http://www.subblue.com/ ) Modified by: phpBB Group ( http://www.phpbb.com/ ) From 5665e82616fd12fbec36e7a1d42713a75ed85e22 Mon Sep 17 00:00:00 2001 From: Callum Macrae Date: Wed, 11 Apr 2012 14:28:12 +0100 Subject: [PATCH 091/441] [ticket/10783] Added ?assets_version to assets. PHPBB3-10783 --- phpBB/includes/functions.php | 7 ++++--- phpBB/includes/style/template_filter.php | 4 +++- phpBB/install/database_update.php | 11 +++++++++++ phpBB/styles/prosilver/template/overall_footer.html | 4 ++-- phpBB/styles/prosilver/template/overall_header.html | 8 ++++---- 5 files changed, 24 insertions(+), 10 deletions(-) diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index 9a6af29d69..a13605f688 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -4767,6 +4767,7 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0 'S_SEARCH_HIDDEN_FIELDS' => build_hidden_fields($s_search_hidden_fields), + 'T_ASSETS_VERSION' => $config['assets_version'], 'T_ASSETS_PATH' => "{$web_path}assets", 'T_THEME_PATH' => "{$web_path}styles/" . rawurlencode($user->theme['style_path']) . '/theme', 'T_TEMPLATE_PATH' => "{$web_path}styles/" . rawurlencode($user->theme['style_path']) . '/template', @@ -4778,10 +4779,10 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0 'T_ICONS_PATH' => "{$web_path}{$config['icons_path']}/", 'T_RANKS_PATH' => "{$web_path}{$config['ranks_path']}/", 'T_UPLOAD_PATH' => "{$web_path}{$config['upload_path']}/", - 'T_STYLESHEET_LINK' => "{$web_path}styles/" . rawurlencode($user->theme['style_path']) . '/theme/stylesheet.css', - 'T_STYLESHEET_LANG_LINK' => "{$web_path}styles/" . rawurlencode($user->theme['style_path']) . '/theme/' . $user->lang_name . '/stylesheet.css', + 'T_STYLESHEET_LINK' => "{$web_path}styles/" . rawurlencode($user->theme['style_path']) . '/theme/stylesheet.css?assets_version=' . $config['assets_version'], + 'T_STYLESHEET_LANG_LINK' => "{$web_path}styles/" . rawurlencode($user->theme['style_path']) . '/theme/' . $user->lang_name . '/stylesheet.css?assets_version=' . $config['assets_version'], 'T_STYLESHEET_NAME' => $user->theme['style_name'], - 'T_JQUERY_LINK' => ($config['load_jquery_cdn'] && !empty($config['load_jquery_url'])) ? $config['load_jquery_url'] : "{$web_path}assets/javascript/jquery.js", + 'T_JQUERY_LINK' => ($config['load_jquery_cdn'] && !empty($config['load_jquery_url'])) ? $config['load_jquery_url'] : "{$web_path}assets/javascript/jquery.js?assets_version=" . $config['assets_version'], 'S_JQUERY_FALLBACK' => ($config['load_jquery_cdn']) ? true : false, 'T_THEME_NAME' => rawurlencode($user->theme['style_path']), diff --git a/phpBB/includes/style/template_filter.php b/phpBB/includes/style/template_filter.php index d62ad0ba1e..f9bbcce4b2 100644 --- a/phpBB/includes/style/template_filter.php +++ b/phpBB/includes/style/template_filter.php @@ -882,6 +882,8 @@ class phpbb_style_template_filter extends php_user_filter */ private function compile_tag_include_js($tag_args) { + global $config; + // Process dynamic includes if ($tag_args[0] == '{') { @@ -894,7 +896,7 @@ class phpbb_style_template_filter extends php_user_filter } // Locate file - $filename = $this->locator->get_first_file_location(array($tag_args), false, true); + $filename = $this->locator->get_first_file_location(array($tag_args), false, true) . '?assets_version=' . $config['assets_version']; if ($filename === false) { diff --git a/phpBB/install/database_update.php b/phpBB/install/database_update.php index be39b12d12..5368ec06bb 100644 --- a/phpBB/install/database_update.php +++ b/phpBB/install/database_update.php @@ -189,6 +189,12 @@ $config = new phpbb_config_db($db, $cache->get_driver(), CONFIG_TABLE); set_config(null, null, null, $config); set_config_count(null, null, null, $config); +// Update asset_version +if (isset($config['assets_version'])) +{ + set_config('assets_version', $config['assets_version'] + 1); +} + // phpbb_db_tools will be taken from new files (under install/update/new) // if possible, falling back to the board's copy. $db_tools = new phpbb_db_tools($db, true); @@ -2424,6 +2430,11 @@ function change_database_data(&$no_updates, $version) $no_updates = false; + if (!isset($config['assets_version'])) + { + $config->set('assets_version', '1'); + } + break; } } diff --git a/phpBB/styles/prosilver/template/overall_footer.html b/phpBB/styles/prosilver/template/overall_footer.html index c84b327b71..621f7ab0af 100644 --- a/phpBB/styles/prosilver/template/overall_footer.html +++ b/phpBB/styles/prosilver/template/overall_footer.html @@ -50,8 +50,8 @@
        - - + + - + - + - + From 4771af08339d456174cbe3ebb1563e0f756733dd Mon Sep 17 00:00:00 2001 From: Callum Macrae Date: Wed, 11 Apr 2012 14:33:09 +0100 Subject: [PATCH 092/441] [ticket/10783] Added assets_version to subsilver2. PHPBB3-10783 --- phpBB/styles/subsilver2/template/overall_footer.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/styles/subsilver2/template/overall_footer.html b/phpBB/styles/subsilver2/template/overall_footer.html index 4f686cf5e4..24c6f8105c 100644 --- a/phpBB/styles/subsilver2/template/overall_footer.html +++ b/phpBB/styles/subsilver2/template/overall_footer.html @@ -9,7 +9,7 @@
        - + {SCRIPTS} From 6ad58c7e046c9f257ad5441b7a583cddb213ad3f Mon Sep 17 00:00:00 2001 From: Callum Macrae Date: Wed, 11 Apr 2012 14:37:15 +0100 Subject: [PATCH 093/441] [ticket/10783] Added assets_version to ACP and simple_*.html. PHPBB3-10783 --- phpBB/adm/style/overall_footer.html | 4 ++-- phpBB/adm/style/overall_header.html | 2 +- phpBB/adm/style/simple_footer.html | 2 +- phpBB/adm/style/simple_header.html | 2 +- phpBB/styles/prosilver/template/simple_footer.html | 2 +- phpBB/styles/prosilver/template/simple_header.html | 8 ++++---- phpBB/styles/subsilver2/template/simple_footer.html | 2 +- 7 files changed, 11 insertions(+), 11 deletions(-) diff --git a/phpBB/adm/style/overall_footer.html b/phpBB/adm/style/overall_footer.html index 0d88c8bcc5..2bc9ee52d7 100644 --- a/phpBB/adm/style/overall_footer.html +++ b/phpBB/adm/style/overall_footer.html @@ -37,8 +37,8 @@
        - - + + {SCRIPTS} diff --git a/phpBB/adm/style/overall_header.html b/phpBB/adm/style/overall_header.html index be5ac29131..f79c0318b5 100644 --- a/phpBB/adm/style/overall_header.html +++ b/phpBB/adm/style/overall_header.html @@ -5,7 +5,7 @@ {META} {PAGE_TITLE} - + - + diff --git a/phpBB/adm/style/simple_header.html b/phpBB/adm/style/simple_header.html index 84ff665acc..d4cbcb6cbe 100644 --- a/phpBB/adm/style/simple_header.html +++ b/phpBB/adm/style/simple_header.html @@ -5,7 +5,7 @@ {META} {PAGE_TITLE} - + - + {SCRIPTS} diff --git a/phpBB/styles/prosilver/template/simple_header.html b/phpBB/styles/prosilver/template/simple_header.html index f0dcbed5a4..5440d66520 100644 --- a/phpBB/styles/prosilver/template/simple_header.html +++ b/phpBB/styles/prosilver/template/simple_header.html @@ -40,18 +40,18 @@ // ]]> - + - + - + diff --git a/phpBB/styles/subsilver2/template/simple_footer.html b/phpBB/styles/subsilver2/template/simple_footer.html index 771765ee12..6082b71891 100644 --- a/phpBB/styles/subsilver2/template/simple_footer.html +++ b/phpBB/styles/subsilver2/template/simple_footer.html @@ -6,7 +6,7 @@
    - + {SCRIPTS} From 534d96695744e2ddeebf33a971edef40d443e585 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Wed, 11 Apr 2012 21:39:27 +0200 Subject: [PATCH 094/441] [ticket/10788] Add imkingdavid to the list of developers in docs/AUTHORS. PHPBB3-10788 --- phpBB/docs/AUTHORS | 1 + 1 file changed, 1 insertion(+) diff --git a/phpBB/docs/AUTHORS b/phpBB/docs/AUTHORS index de599193d2..234f8c273b 100644 --- a/phpBB/docs/AUTHORS +++ b/phpBB/docs/AUTHORS @@ -25,6 +25,7 @@ phpBB Lead Developer: naderman (Nils Adermann) phpBB Developers: Acyd Burn (Meik Sievertsen) [Lead 09/2005 - 01/2010] bantu (Andreas Fischer) ckwalsh (Cullen Walsh) + imkingdavid (David King) igorw (Igor Wiedler) kellanved (Henry Sudhof) nickvergessen (Joas Schilling) From f394fd250e5cf35a38579ecc403a78e223f37da8 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Wed, 11 Apr 2012 22:08:36 +0200 Subject: [PATCH 095/441] [ticket/10788] Move ckwalsh and kellanved to the Former Contributors section. PHPBB3-10788 --- phpBB/docs/AUTHORS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/phpBB/docs/AUTHORS b/phpBB/docs/AUTHORS index 234f8c273b..57adec6a67 100644 --- a/phpBB/docs/AUTHORS +++ b/phpBB/docs/AUTHORS @@ -24,10 +24,8 @@ phpBB Lead Developer: naderman (Nils Adermann) phpBB Developers: Acyd Burn (Meik Sievertsen) [Lead 09/2005 - 01/2010] bantu (Andreas Fischer) - ckwalsh (Cullen Walsh) imkingdavid (David King) igorw (Igor Wiedler) - kellanved (Henry Sudhof) nickvergessen (Joas Schilling) Oleg (Oleg Pudeyev) rxu (Ruslan Uzdenov) @@ -49,9 +47,11 @@ phpBB Developers: A_Jelly_Doughnut (Josh Woody) [01/2010 - 11/2010] APTX (Marek A. Ruszczyński) [12/2007 - 04/2011] Ashe (Ludovic Arnaud) [10/2002 - 11/2003, 06/2006 - 10/2006] BartVB (Bart van Bragt) [11/2000 - 03/2006] + ckwalsh (Cullen Walsh) [01/2010 - 07/2011] DavidMJ (David M.) [12/2005 - 08/2009] dhn (Dominik Dröscher) [05/2007 - 01/2011] GrahamJE (Graham Eames) [09/2005 - 11/2006] + kellanved (Henry Sudhof) [04/2007 - 03/2011] TerraFrost (Jim Wigginton) [04/2009 - 01/2011] Vic D'Elfant (Vic D'Elfant) [04/2007 - 04/2009] From 8382e449423fd1dfecb416389613e847b02f63c6 Mon Sep 17 00:00:00 2001 From: Oleg Pudeyev Date: Wed, 11 Apr 2012 23:57:36 -0400 Subject: [PATCH 096/441] [ticket/10688] Update readme for 3.1 and current practices. PHPBB3-10688 --- phpBB/docs/README.html | 55 ++++++++++++++++++++++++------------------ 1 file changed, 31 insertions(+), 24 deletions(-) diff --git a/phpBB/docs/README.html b/phpBB/docs/README.html index 7cd727c60e..6adc1ee7cb 100644 --- a/phpBB/docs/README.html +++ b/phpBB/docs/README.html @@ -84,23 +84,26 @@
    -

    Installation, update and conversion instructions can be found in the INSTALL document contained in this distribution. If you are intending to convert from a previous phpBB 2.0.x installation we highly recommend you backup any existing data before proceeding!

    +

    Installation, update and conversion instructions can be found in the INSTALL document contained in this distribution. If you are intending to convert from a previous phpBB 2.0.x or 3.0.x installation we highly recommend you backup any existing data before proceeding!

    -

    Users of phpBB3 Beta versions cannot directly update.

    +

    Users of phpBB 3.0 and 3.1 Beta versions cannot directly update.

    Please note that we won't support the following installation types:

      -
    • Updates from phpBB3 Beta versions to phpBB3 RC1 and higher
    • -
    • Conversions from phpBB 2.0.x to phpBB3 Beta versions
    • -
    • phpBB3 Beta installations
    • +
    • Updates from phpBB 3.0 Beta versions to phpBB 3.0 RC1 and higher
    • +
    • Updates from phpBB 3.1 Beta versions to phpBB 3.1 RC1 and higher
    • +
    • Conversions from phpBB 2.0.x to phpBB 3.0 or 3.1 Beta versions
    • +
    • phpBB 3.0 or 3.1 Beta installations

    We give support for the following installation types:

      -
    • Updates from phpBB3 RC1 to the latest version
    • +
    • Updates from phpBB 3.0 RC1 and 3.1 RC1 to the latest version
    • +
    • Note: if using the Automatic Update Package, updates are supported from phpBB 3.0.2 onward. To update a pre-3.0.2 installation, first update to 3.0.2 and then update to the current version.
    • Conversions from phpBB 2.0.x to the latest version
    • -
    • New installations of phpBB3 - always only the latest released version
    • +
    • New installations of phpBB 3.0.x - always only the latest released version
    • +
    • New installations of phpBB 3.1.x - always only the latest released version
    @@ -129,13 +132,13 @@

    This is the official location for all supported language sets. If you download a package from a 3rd party site you do so with the understanding that we cannot offer support. So please, do not ask for help in these cases!

    -

    Installation of these packages is straightforward, simply download the required language pack and unarchive it into the languages/ folder. Please ensure you retain the directory structure when doing this! Once uploaded go to the Admin->System->Language Packs and install the now appeared new language pack. To install the style imageset you should download the imageset for your language and unarchive the file/s into the relevant imageset directory (styles/prosilver/imageset or styles/subsilver2/imageset), again you must retain the directory structure. Once installed the imageset will become immediately available.

    +

    Installation of these packages is straightforward, simply download the required language pack and unarchive it into the languages/ folder. Please ensure you retain the directory structure when doing this! Once uploaded go to the Admin->System->Language Packs and install the now appearing new language pack. To install the style imageset you should download the imageset for your language and unarchive the file/s into the relevant imageset directory (styles/prosilver/imageset or styles/subsilver2/imageset), again you must retain the directory structure. Once installed the imageset will become immediately available.

    If your language is not available please visit our forums where you will find a topic listing translations currently available or in preparation. This topic also gives you information should you wish to volunteer to translate a language not currently listed.

    2.ii. Styles

    -

    Although phpBB Group are rather proud of the included styles we realise that it may not be to everyones tastes. Therefore phpBB3 allows styles to be switched with relative ease. Firstly you need to locate and download a style you like. We maintain such a site at

    +

    Although phpBB Group are rather proud of the included styles we realise that they may not be to everyone's tastes. Therefore phpBB3 allows styles to be switched with relative ease. Firstly you need to locate and download a style you like. We maintain such a site at

    http://www.phpbb.com/styles/

    @@ -185,7 +188,7 @@

    phpBB Group maintains a thriving community where a number of people have generously decided to donate their time to help support users. This site can be found at:

    -

    http://www.phpbb.com/

    +

    http://www.phpbb.com/community/

    If you do seek help via our forums please be sure to do a Search before posting. This may well save both you and us time and allow the developer, moderator and support groups to spend more time responding to people with unknown issues and problems. Please also remember that phpBB is an entirely volunteer effort, no one receives any compensation for the time they give, this includes moderators as well as developers. So please be respectful and mindful when awaiting responses.

    @@ -193,6 +196,8 @@

    Another place you may find help is our IRC channel. This operates on the Freenode IRC network, irc.freenode.net and the channel is #phpbb and can be accessed by any good IRC client such as mIRC, XChat, etc. Again, please do not abuse this service and be respectful of other users.

    +

    There are other IRC channels available, please see http://www.phpbb.com/support/irc/ for the complete list.

    + @@ -209,13 +214,13 @@
    -

    This is the third stable release of phpBB. The 3.0.x line is essentially feature frozen, with only point releases seeing fixes for bugs and security issues, though feature alterations and minor feature additions may be done if deemed absolutely required. Our next major release will be phpBB 3.2 and the planning phase has begun (the unstable development version is 3.1). Please do not post questions asking when 3.2 will be available, no release date has been set.

    +

    This is a stable release of phpBB. The 3.1.x line is feature frozen, with point releases principally including fixes for bugs and security issues. Feature alterations and minor feature additions may be done if deemed absolutely required. The next major release will be phpBB 3.2 which is currently under development. Please do not post questions asking when 3.2 will be available, no release date has been set.

    -

    For those interested in the development of phpBB should keep an eye on the community forums to see how things are progressing:

    +

    Those interested in the development of phpBB should keep an eye on the development forums to see how things are progressing:

    http://area51.phpbb.com/phpBB/

    -

    Please note that this forum should NOT be used to obtain support for or ask questions about phpBB 2.0.x or phpBB 3.1.x, the main community forums are the place for this. Any such posts will be locked and go unanswered.

    +

    Please note that this forum should NOT be used to obtain support for phpBB, the main community forums are the place for this.

    @@ -233,31 +238,33 @@
    -

    The phpBB Group uses a bug tracking system to store, list and manage all reported bugs, it can be found at the location listed below. Please DO NOT post bug reports to our forums, they will be locked. In addition please DO NOT use the bug tracker for support requests. Posting such a request will only see you directed to the support forums (while taking time away from working on real bugs).

    +

    The phpBB Group uses a bug tracking system to store, list and manage all reported bugs, it can be found at the location listed below. Please DO NOT post bug reports to our forums. In addition please DO NOT use the bug tracker for support requests. Posting such a request will only see you directed to the support forums (while taking time away from working on real bugs).

    -

    http://tracker.phpbb.com/

    +

    http://tracker.phpbb.com/browse/PHPBB3

    While we very much appreciate receiving bug reports (the more reports the more stable phpBB will be) we ask you carry out a few steps before adding new entries:

      -
    • Firstly determine if your bug is reproduceable, how to determine this depends on the bug in question. Only if the bug is reproduceable it is likely to be a problem with phpBB3 (or in some way connected). If something cannot be reproduced it may turn out to have been your hosting provider working on something, a user doing something silly, etc. Bug reports for non-reproduceable events can slow down our attempts to fix real, reproduceable issues

    • +
    • Firstly determine if your bug is reproduceable, how to determine this depends on the bug in question. Only if the bug is reproduceable it is likely to be a problem with phpBB3 (or in some way connected). If something cannot be reproduced it may turn out to have been your hosting provider working on something, a user doing something silly, etc. Bug reports for non-reproduceable events can slow down our attempts to fix real, reproduceable issues.

    • Next please read or search through the existing bug reports to see if your bug (or one very similar to it) is already listed. If it is please add to that existing bug rather than creating a new duplicate entry (all this does is slow us down).

    • -
    • Check the forums (use search!) to see if people have discussed anything that sounds similar to what you are seeing. However, as noted above please DO NOT post your particular bug to the forum unless it's non-reproduceable or you are sure it's related to something you have done rather phpBB3

    • -
    • If no existing bug exists then please feel free to add it
    • +
    • Check the forums (use search!) to see if people have discussed anything that sounds similar to what you are seeing. However, as noted above please DO NOT post your particular bug to the forum unless it's non-reproduceable or you are sure it's related to something you have done rather phpBB3.

    • +
    • If no existing bug exists then please feel free to add it.

    If you do post a new bug (i.e. one that isn't already listed in the bug tracker) firstly make sure you have logged in (your username and password are the same as for the community forums) then please include the following details:

      -
    • Your server type/version, e.g. Apache 1.3.28, IIS 4, Sambar, etc.
    • -
    • PHP version and mode of operation, e.g. PHP 5.1.1 as a module, PHP 4.4.4 running as CGI, etc.
    • -
    • DB type/version, e.g. MySQL 4.0.1, PostgreSQL 7.3.2, MSSQL Server 2000 SP1, etc.
    • +
    • Your server type/version, e.g. Apache 2.2.3, IIS 7, Sambar, etc.
    • +
    • PHP version and mode of operation, e.g. PHP 5.3.2 as a module, PHP 5.4.0 running as CGI, etc.
    • +
    • DB type/version, e.g. MySQL 5.0.77, PostgreSQL 9.0.6, MSSQL Server 2000 SP1, etc.
    -

    The relevant database type/version is listed within the administration control panel

    +

    The relevant database type/version is listed within the administration control panel.

    Please also be as detailed as you can in your report, if possible list the steps required to duplicate the problem. If you have a patch that fixes the issue, please attach it to the ticket or submit a pull request on GitHub.

    +

    If you create a patch, it is very much appreciated (but not required) if you follow the phpBB coding guidelines. Please note that the coding guidelines are somewhat different between different versions of phpBB. For phpBB 3.1.x the coding guidelines may be found here: http://area51.phpbb.com/docs/31x/coding-guidelines.html

    +

    Once a bug has been submitted you will be emailed any follow up comments added to it. Please if you are requested to supply additional information, do so! It is frustrating for us to receive bug reports, ask for additional information but get nothing. In these cases we have a policy of closing the bug, which may leave a very real problem in place. Obviously we would rather not have this situation arise.

    5.i. Security related bugs

    @@ -306,11 +313,11 @@
    -

    phpBB is no longer supported on PHP4 due to several compatibility issues and we recommend that you upgrade to the latest stable release of PHP5 to run phpBB. The minimum version required is PHP 5.2.0.

    +

    phpBB 3.1.x takes advantage of new features added in PHP 5.3. We recommend that you upgrade to the latest stable release of PHP5 to run phpBB. The minimum version required is PHP 5.3.2.

    Please remember that running any application on a developmental version of PHP can lead to strange/unexpected results which may appear to be bugs in the application (which may not be true). Therefore we recommend you upgrade to the newest stable version of PHP before running phpBB3. If you are running a developmental version of PHP please check any bugs you find on a system running a stable release before submitting.

    -

    This board has been developed and tested under Linux and Windows (amongst others) running Apache using MySQL 3.23, 4.x, 5.x, MSSQL Server 2000, PostgreSQL 7.x, Oracle 8, SQLite and Firebird. Versions of PHP used range from 5.2.0 to 5.3.x without problem.

    +

    This board has been developed and tested under Linux and Windows (amongst others) running Apache using MySQL 3.23, 4.x, 5.x, MSSQL Server 2000, PostgreSQL 8.x, Oracle 8, SQLite and Firebird. Versions of PHP used range from 5.3.x to 5.4.x without problem.

    7.i. Notice on PHP security issues

    From 8bb083eed91f049600ff0db4d8528e7a6c7e5093 Mon Sep 17 00:00:00 2001 From: Oleg Pudeyev Date: Thu, 12 Apr 2012 00:24:09 -0400 Subject: [PATCH 097/441] [ticket/10688] Update install.html for 3.1 and current practices. PHPBB3-10688 --- phpBB/docs/INSTALL.html | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/phpBB/docs/INSTALL.html b/phpBB/docs/INSTALL.html index 9628e4c337..47cf546ee8 100644 --- a/phpBB/docs/INSTALL.html +++ b/phpBB/docs/INSTALL.html @@ -124,7 +124,7 @@
    -

    phpBB3 has a few requirements which must be met before you are able to install and use it.

    +

    phpBB 3.1.x has a few requirements which must be met before you are able to install and use it.

    • A webserver or web hosting account running on any major Operating System with support for PHP
    • @@ -134,13 +134,17 @@
    • PostgreSQL 7.3+
    • SQLite 2.8.2+
    • Firebird 2.1+
    • -
    • MS SQL Server 2000 or above (directly or via ODBC)
    • +
    • MS SQL Server 2000 or above (directly or via ODBC or the native adapter)
    • Oracle
    -
  • PHP 5.2.0+ with support for the database you intend to use.
  • +
  • PHP 5.3.2+ with support for the database you intend to use.
  • +
  • The following PHP modules are required:
  • +
      +
    • json
    • +
  • getimagesize() function need to be enabled.
  • -
  • These optional presence of the following modules within PHP will provide access to additional features, but they are not required. +
  • Presence of the following modules within PHP will provide access to additional features, but they are not required:
    • zlib Compression support
    • Remote FTP support
    • @@ -151,7 +155,7 @@
    -

    If your server or hosting account does not meet the requirements above we are afraid phpBB3 is not for you.

    +

    If your server or hosting account does not meet the requirements above we are afraid phpBB 3.1.x is not for you.

  • @@ -175,7 +179,7 @@

    All .php, .inc, .sql, .cfg, .html and .txt files should be uploaded in ASCII mode, while all graphics should be uploaded in BINARY mode. If you are unfamiliar with what this means please refer to your FTP client documentation. In most cases this is all handled transparantly by your ftp client but if you encounter problems later you should be sure the files where uploaded correctly as described here.

    -

    phpBB3 comes supplied with english as its standard language. However a number of separate packs for different languages are available. If you are not a native english speaker you may wish to install one or more of these packages before continuing. The installation process below will allow you to select a default language from those available (you can of course change this default at a later stage). For more details of language packs, where to obtain them and how to install them please see the README.

    +

    phpBB3 comes supplied with British English as its standard language. However a number of separate packs for different languages are available. If you are not a native English speaker you may wish to install one or more of these packages before continuing. The installation process below will allow you to select a default language from those available (you can of course change this default at a later stage). For more details of language packs, where to obtain them and how to install them please see the README.

    Once all the files have been uploaded to your site you should point your browser at this location with the addition of install/. For example if your domain name is www.mydomain.tld and you placed phpBB3 in a directory /phpBB3 off your web root you would enter http://www.mydomain.tld/phpBB3/install/ or (alternatively) http://www.mydomain.tld/phpBB3/install/index.php into your browser. When you have done this you should see the phpBB3 Installation screen appear.

    @@ -267,7 +271,7 @@

    This package is meant for those wanting to only replace changed files from a previous version to the latest version. This package normally contains the changed files from up to five previous versions.

    -

    This package contains a number of archives, each contains the files changed from a given release to the latest version. You should select the appropriate archive for your current version, e.g. if you currently have 3.0.9 you should select the phpBB-3.0.9_to_3.0.10.zip/tar.gz file.

    +

    This package contains a number of archives, each contains the files changed from a given release to the latest version. You should select the appropriate archive for your current version, e.g. if you currently have 3.1.0 you should select the phpBB-3.1.0_to_3.1.1.zip/tar.gz file.

    The directory structure has been preserved enabling you (if you wish) to simply upload the contents of the archive to the appropriate location on your server, i.e. simply overwrite the existing files with the new versions. Do not forget that if you have installed any MODs these files will overwrite the originals possibly destroying them in the process. You will need to re-add MODs to any affected file before uploading.

    @@ -279,7 +283,7 @@

    The patch file is one solution for those with many Modifications (MODs) or other changes who do not want to re-add them back to all the changed files if they use the method explained above. To use this you will need command line access to a standard UNIX type patch application. If you do not have access to such an application but still want to use this update approach, we strongly recommend the Automatic update package explained below. It is also the recommended update method.

    -

    A number of patch files are provided to allow you to update from previous stable releases. Select the correct patch, e.g. if your current version is 3.0.9 you need the phpBB-3.0.9_to_3.0.10.patch file. Place the correct patch in the parent directory containing the phpBB3 core files (i.e. index.php, viewforum.php, etc.). With this done you should run the following command: patch -cl -d [PHPBB DIRECTORY] -p1 < [PATCH NAME] (where PHPBB DIRECTORY is the directory name your phpBB Installation resides in, for example phpBB3, and where PATCH NAME is the relevant filename of the selected patch file). This should complete quickly, hopefully without any HUNK FAILED comments.

    +

    A number of patch files are provided to allow you to update from previous stable releases. Select the correct patch, e.g. if your current version is 3.1.0 you need the phpBB-3.1.0_to_3.1.1.patch file. Place the correct patch in the parent directory containing the phpBB3 core files (i.e. index.php, viewforum.php, etc.). With this done you should run the following command: patch -cl -d [PHPBB DIRECTORY] -p1 < [PATCH NAME] (where PHPBB DIRECTORY is the directory name your phpBB Installation resides in, for example phpBB3, and where PATCH NAME is the relevant filename of the selected patch file). This should complete quickly, hopefully without any HUNK FAILED comments.

    If you do get failures you should look at using the Changed files only package to replace the files which failed to patch, please note that you will need to manually re-add any Modifications (MODs) to these particular files. Alternatively if you know how you can examine the .rej files to determine what failed where and make manual adjustments to the relevant source.

    From 7a9d9f97ef83b61ce155a09c1e75c90f4c533f3f Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Wed, 11 Apr 2012 23:29:47 +0200 Subject: [PATCH 098/441] [ticket/10784] Do not show ajax overlay unless needed PHPBB3-10784 --- phpBB/adm/style/ajax.js | 12 ++++++++---- phpBB/assets/javascript/core.js | 6 +++++- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/phpBB/adm/style/ajax.js b/phpBB/adm/style/ajax.js index fd2f7a2122..12541cb057 100644 --- a/phpBB/adm/style/ajax.js +++ b/phpBB/adm/style/ajax.js @@ -28,7 +28,8 @@ phpbb.add_ajax_callback('forum_down', function() { phpbb.ajaxify({ selector: el.parents('span').siblings('.up').children('a'), - callback: 'forum_up' + callback: 'forum_up', + overlay: false }); } @@ -43,7 +44,8 @@ phpbb.add_ajax_callback('forum_down', function() { phpbb.ajaxify({ selector: tr.prev().find('.down').children('a'), - callback: 'forum_down' + callback: 'forum_down', + overlay: false }); } }); @@ -61,7 +63,8 @@ phpbb.add_ajax_callback('forum_up', function() { phpbb.ajaxify({ selector: el.parents('span').siblings('.down').children('a'), - callback: 'forum_down' + callback: 'forum_down', + overlay: false }); } @@ -76,7 +79,8 @@ phpbb.add_ajax_callback('forum_up', function() { phpbb.ajaxify({ selector: tr.next().find('.up').children('a'), - callback: 'forum_up' + callback: 'forum_up', + overlay: false }); } }); diff --git a/phpBB/assets/javascript/core.js b/phpBB/assets/javascript/core.js index c41edfa145..958b6c9ff6 100644 --- a/phpBB/assets/javascript/core.js +++ b/phpBB/assets/javascript/core.js @@ -245,6 +245,7 @@ phpbb.ajaxify = function(options) { var elements = $(options.selector), refresh = options.refresh, callback = options.callback, + overlay = (typeof options.overlay !== 'undefined') ? options.overlay : true, is_form = elements.is('form'), event_name = is_form ? 'submit' : 'click'; @@ -382,7 +383,10 @@ phpbb.ajaxify = function(options) { return; } - phpbb.loading_alert(); + if (overlay) + { + phpbb.loading_alert(); + } $.ajax({ url: action, From 8a1d084d6d00500b3ea17a7fd3168ec4f321b31b Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Fri, 13 Apr 2012 04:03:07 +0200 Subject: [PATCH 099/441] [ticket/10783] Correctly add assets_version config var to includejs urls PHPBB3-10783 --- phpBB/includes/style/template.php | 3 +++ phpBB/includes/style/template_filter.php | 10 ++++------ tests/template/template_includejs_test.php | 8 ++++---- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/phpBB/includes/style/template.php b/phpBB/includes/style/template.php index 3f15355f7a..9d476e74b9 100644 --- a/phpBB/includes/style/template.php +++ b/phpBB/includes/style/template.php @@ -507,6 +507,9 @@ class phpbb_style_template $file = $this->locator->get_first_file_location(array($file), true, true); } + $file .= (strpos($file, '?') === false) ? '?' : '&'; + $file .= 'assets_version=' . $this->config['assets_version']; + // Add HTML code $code = ''; $this->context->append_var('SCRIPTS', $code); diff --git a/phpBB/includes/style/template_filter.php b/phpBB/includes/style/template_filter.php index f9bbcce4b2..6ef9d80a3d 100644 --- a/phpBB/includes/style/template_filter.php +++ b/phpBB/includes/style/template_filter.php @@ -138,7 +138,7 @@ class phpbb_style_template_filter extends php_user_filter /** * Initializer, called on creation. * - * Get the allow_php option, root directory and locator from params, + * Get the allow_php option, root directory and locator from params, * which are passed to stream_filter_append. */ public function onCreate() @@ -882,8 +882,6 @@ class phpbb_style_template_filter extends php_user_filter */ private function compile_tag_include_js($tag_args) { - global $config; - // Process dynamic includes if ($tag_args[0] == '{') { @@ -896,14 +894,14 @@ class phpbb_style_template_filter extends php_user_filter } // Locate file - $filename = $this->locator->get_first_file_location(array($tag_args), false, true) . '?assets_version=' . $config['assets_version']; - + $filename = $this->locator->get_first_file_location(array($tag_args), false, true); + if ($filename === false) { // File does not exist, find it during run time return ' $_template->_js_include(\'' . addslashes($tag_args) . '\', true); '; } - + if (substr($filename, 0, strlen($this->phpbb_root_path)) != $this->phpbb_root_path) { // Absolute path, include as is diff --git a/tests/template/template_includejs_test.php b/tests/template/template_includejs_test.php index fa23837553..632fde61d1 100644 --- a/tests/template/template_includejs_test.php +++ b/tests/template/template_includejs_test.php @@ -14,14 +14,14 @@ class phpbb_template_template_includejs_test extends phpbb_template_template_tes public function test_includejs_compilation() { // Reset the engine state - $this->setup_engine(); + $this->setup_engine(array('assets_version' => 1)); // Prepare correct result $dir = dirname(__FILE__); $scripts = array( - '', - '', - '' + '', + '', + '' ); // Run test From 875958573cfbda4ea5ae42000bbd40ec9dfa3241 Mon Sep 17 00:00:00 2001 From: Callum Macrae Date: Fri, 13 Apr 2012 12:10:49 +0100 Subject: [PATCH 100/441] [ticket/10783] Fixed an HTML error with assets_version. PHPBB3-10783 --- phpBB/styles/prosilver/template/overall_footer.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/styles/prosilver/template/overall_footer.html b/phpBB/styles/prosilver/template/overall_footer.html index 621f7ab0af..5d61f5b580 100644 --- a/phpBB/styles/prosilver/template/overall_footer.html +++ b/phpBB/styles/prosilver/template/overall_footer.html @@ -51,7 +51,7 @@ - {SCRIPTS} From f8a5a16d0b8ed23653e1ce261c569fafe0bd6365 Mon Sep 17 00:00:00 2001 From: Rahul R Date: Wed, 11 Apr 2012 06:10:45 +0530 Subject: [PATCH 101/441] [ticket/10777] Split the comment into 2 lines Split the comment into 2 lines each having less than 79 characters. PHPBB3-10777 --- phpBB/viewtopic.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/phpBB/viewtopic.php b/phpBB/viewtopic.php index df6ccc5905..1f167ed722 100644 --- a/phpBB/viewtopic.php +++ b/phpBB/viewtopic.php @@ -1629,7 +1629,8 @@ else $all_marked_read = true; } -// If there are absolutely no more unread posts in this forum and unread posts shown, we can safely show the #unread link +// If there are absolutely no more unread posts in this forum +// and unread posts shown, we can safely show the #unread link if ($all_marked_read) { if ($post_unread) From 4b6b41a1e5cb3d4ba7c896dfa4d72082aa2f069e Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 13 Apr 2012 16:26:41 +0200 Subject: [PATCH 102/441] [ticket/10605] Add parameter documentation to phpbb_delete_user_pms PHPBB3-10605 --- phpBB/includes/functions_privmsgs.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/phpBB/includes/functions_privmsgs.php b/phpBB/includes/functions_privmsgs.php index 14a6d83b2a..00bec11569 100644 --- a/phpBB/includes/functions_privmsgs.php +++ b/phpBB/includes/functions_privmsgs.php @@ -1085,6 +1085,10 @@ function delete_pm($user_id, $msg_ids, $folder_id) /** * Delete all PM(s) for a given user and delete the ones without references +* +* @param int $user_id ID of the user whose private messages we want to delete +* +* @return boolean False if there were no pms found, true otherwise. */ function phpbb_delete_user_pms($user_id) { From 7a4b4c7599f3203664350158e36e666a59ca9de2 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Fri, 13 Apr 2012 16:31:49 +0200 Subject: [PATCH 103/441] [ticket/10094] Purge acm_file cache before phpBB installation. PHPBB3-10094 --- phpBB/install/install_install.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/phpBB/install/install_install.php b/phpBB/install/install_install.php index 026fc0d404..08d072c522 100644 --- a/phpBB/install/install_install.php +++ b/phpBB/install/install_install.php @@ -53,11 +53,13 @@ class install_install extends module function main($mode, $sub) { - global $lang, $template, $language, $phpbb_root_path; + global $lang, $template, $language, $phpbb_root_path, $cache; switch ($sub) { case 'intro': + $cache->purge(); + $this->page_title = $lang['SUB_INTRO']; $template->assign_vars(array( From 3741e99aab94fc903db82c1c4d3d6b1f7b1e2a1a Mon Sep 17 00:00:00 2001 From: Senky Date: Sun, 15 Apr 2012 20:10:51 +0200 Subject: [PATCH 104/441] [ticket/10161] all "e-mail" strings in language files changed to "email" according to Oleg's comment: email is preferred by RFCs and probably the way of the future PHPBB3-10161 --- phpBB/language/en/acp/ban.php | 14 ++--- phpBB/language/en/acp/board.php | 58 +++++++++---------- phpBB/language/en/acp/common.php | 32 +++++----- phpBB/language/en/acp/email.php | 6 +- phpBB/language/en/acp/language.php | 2 +- phpBB/language/en/acp/permissions.php | 2 +- phpBB/language/en/acp/permissions_phpbb.php | 10 ++-- phpBB/language/en/acp/posting.php | 2 +- phpBB/language/en/acp/styles.php | 4 +- phpBB/language/en/acp/users.php | 6 +- phpBB/language/en/common.php | 28 ++++----- phpBB/language/en/email/admin_send_email.txt | 4 +- .../en/email/admin_welcome_inactive.txt | 2 +- .../en/email/coppa_resend_inactive.txt | 2 +- .../en/email/coppa_welcome_inactive.txt | 2 +- phpBB/language/en/email/email_notify.txt | 6 +- phpBB/language/en/email/installed.txt | 2 +- .../language/en/email/profile_send_email.txt | 4 +- .../en/email/user_reactivate_account.txt | 2 +- .../en/email/user_resend_inactive.txt | 2 +- phpBB/language/en/email/user_welcome.txt | 2 +- .../en/email/user_welcome_inactive.txt | 2 +- phpBB/language/en/help_bbcode.php | 2 +- phpBB/language/en/help_faq.php | 12 ++-- phpBB/language/en/install.php | 4 +- phpBB/language/en/mcp.php | 2 +- phpBB/language/en/memberlist.php | 20 +++---- phpBB/language/en/ucp.php | 46 +++++++-------- phpBB/language/en/viewtopic.php | 4 +- 29 files changed, 142 insertions(+), 142 deletions(-) diff --git a/phpBB/language/en/acp/ban.php b/phpBB/language/en/acp/ban.php index 77e8a93f3c..2dc0489030 100644 --- a/phpBB/language/en/acp/ban.php +++ b/phpBB/language/en/acp/ban.php @@ -40,7 +40,7 @@ $lang = array_merge($lang, array( '30_MINS' => '30 minutes', '6_HOURS' => '6 hours', - 'ACP_BAN_EXPLAIN' => 'Here you can control the banning of users by name, IP or e-mail address. These methods prevent a user reaching any part of the board. You can give a short (maximum 3000 characters) reason for the ban if you wish. This will be displayed in the admin log. The duration of a ban can also be specified. If you want the ban to end on a specific date rather than after a set time period select Until -> for the ban length and enter a date in YYYY-MM-DD format.', + 'ACP_BAN_EXPLAIN' => 'Here you can control the banning of users by name, IP or email address. These methods prevent a user reaching any part of the board. You can give a short (maximum 3000 characters) reason for the ban if you wish. This will be displayed in the admin log. The duration of a ban can also be specified. If you want the ban to end on a specific date rather than after a set time period select Until -> for the ban length and enter a date in YYYY-MM-DD format.', 'BAN_EXCLUDE' => 'Exclude from banning', 'BAN_LENGTH' => 'Length of ban', @@ -50,12 +50,12 @@ $lang = array_merge($lang, array( 'BANNED_UNTIL_DATE' => 'until %s', // Example: "until Mon 13.Jul.2009, 14:44" 'BANNED_UNTIL_DURATION' => '%1$s (until %2$s)', // Example: "7 days (until Tue 14.Jul.2009, 14:44)" - 'EMAIL_BAN' => 'Ban one or more e-mail addresses', - 'EMAIL_BAN_EXCLUDE_EXPLAIN' => 'Enable this to exclude the entered e-mail address from all current bans.', - 'EMAIL_BAN_EXPLAIN' => 'To specify more than one e-mail address enter each on a new line. To match partial addresses use * as the wildcard, e.g. *@hotmail.com, *@*.domain.tld, etc.', - 'EMAIL_NO_BANNED' => 'No banned e-mail addresses', - 'EMAIL_UNBAN' => 'Un-ban or un-exclude e-mails', - 'EMAIL_UNBAN_EXPLAIN' => 'You can unban (or un-exclude) multiple e-mail addresses in one go using the appropriate combination of mouse and keyboard for your computer and browser. Excluded e-mail addresses are emphasised.', + 'EMAIL_BAN' => 'Ban one or more email addresses', + 'EMAIL_BAN_EXCLUDE_EXPLAIN' => 'Enable this to exclude the entered email address from all current bans.', + 'EMAIL_BAN_EXPLAIN' => 'To specify more than one email address enter each on a new line. To match partial addresses use * as the wildcard, e.g. *@hotmail.com, *@*.domain.tld, etc.', + 'EMAIL_NO_BANNED' => 'No banned email addresses', + 'EMAIL_UNBAN' => 'Un-ban or un-exclude emails', + 'EMAIL_UNBAN_EXPLAIN' => 'You can unban (or un-exclude) multiple email addresses in one go using the appropriate combination of mouse and keyboard for your computer and browser. Excluded email addresses are emphasised.', 'IP_BAN' => 'Ban one or more IPs', 'IP_BAN_EXCLUDE_EXPLAIN' => 'Enable this to exclude the entered IP from all current bans.', diff --git a/phpBB/language/en/acp/board.php b/phpBB/language/en/acp/board.php index 0bb99b5449..758ef8ed82 100644 --- a/phpBB/language/en/acp/board.php +++ b/phpBB/language/en/acp/board.php @@ -207,7 +207,7 @@ $lang = array_merge($lang, array( 'ACP_REGISTER_SETTINGS_EXPLAIN' => 'Here you are able to define registration and profile related settings.', 'ACC_ACTIVATION' => 'Account activation', - 'ACC_ACTIVATION_EXPLAIN' => 'This determines whether users have immediate access to the board or if confirmation is required. You can also completely disable new registrations. “Board-wide e-mail” must be enabled in order to use user or admin activation.', + 'ACC_ACTIVATION_EXPLAIN' => 'This determines whether users have immediate access to the board or if confirmation is required. You can also completely disable new registrations. “Board-wide email” must be enabled in order to use user or admin activation.', 'NEW_MEMBER_POST_LIMIT' => 'New member post limit', 'NEW_MEMBER_POST_LIMIT_EXPLAIN' => 'New members are within the Newly Registered Users group until they reach this number of posts. You can use this group to keep them from using the PM system or to review their posts. A value of 0 disables this feature.', 'NEW_MEMBER_GROUP_DEFAULT' => 'Set Newly Registered Users group to default', @@ -216,10 +216,10 @@ $lang = array_merge($lang, array( 'ACC_ADMIN' => 'By admin', 'ACC_DISABLE' => 'Disable registration', 'ACC_NONE' => 'No activation (immediate access)', - 'ACC_USER' => 'By user (e-mail verification)', + 'ACC_USER' => 'By user (email verification)', // 'ACC_USER_ADMIN' => 'User + Admin', - 'ALLOW_EMAIL_REUSE' => 'Allow e-mail address re-use', - 'ALLOW_EMAIL_REUSE_EXPLAIN' => 'Different users can register with the same e-mail address.', + 'ALLOW_EMAIL_REUSE' => 'Allow email address re-use', + 'ALLOW_EMAIL_REUSE_EXPLAIN' => 'Different users can register with the same email address.', 'COPPA' => 'COPPA', 'COPPA_FAX' => 'COPPA fax number', 'COPPA_MAIL' => 'COPPA mailing address', @@ -390,10 +390,10 @@ $lang = array_merge($lang, array( 'LDAP_DN' => 'LDAP base dn', 'LDAP_DN_EXPLAIN' => 'This is the Distinguished Name, locating the user information, e.g. o=My Company,c=US.', - 'LDAP_EMAIL' => 'LDAP e-mail attribute', - 'LDAP_EMAIL_EXPLAIN' => 'Set this to the name of your user entry e-mail attribute (if one exists) in order to automatically set the e-mail address for new users. Leaving this empty results in empty e-mail address for users who log in for the first time.', + 'LDAP_EMAIL' => 'LDAP email attribute', + 'LDAP_EMAIL_EXPLAIN' => 'Set this to the name of your user entry email attribute (if one exists) in order to automatically set the email address for new users. Leaving this empty results in empty email address for users who log in for the first time.', 'LDAP_INCORRECT_USER_PASSWORD' => 'Binding to LDAP server failed with specified user/password.', - 'LDAP_NO_EMAIL' => 'The specified e-mail attribute does not exist.', + 'LDAP_NO_EMAIL' => 'The specified email attribute does not exist.', 'LDAP_NO_IDENTITY' => 'Could not find a login identity for %s.', 'LDAP_PASSWORD' => 'LDAP password', 'LDAP_PASSWORD_EXPLAIN' => 'Leave blank to use anonymous binding, otherwise fill in the password for the above user. Required for Active Directory Servers.
    Warning: This password will be stored as plain text in the database, visible to everybody who can access your database or who can view this configuration page.', @@ -411,7 +411,7 @@ $lang = array_merge($lang, array( // Server Settings $lang = array_merge($lang, array( - 'ACP_SERVER_SETTINGS_EXPLAIN' => 'Here you define server and domain dependant settings. Please ensure the data you enter is accurate, errors will result in e-mails containing incorrect information. When entering the domain name remember it does include http:// or other protocol term. Only alter the port number if you know your server uses a different value, port 80 is correct in most cases.', + 'ACP_SERVER_SETTINGS_EXPLAIN' => 'Here you define server and domain dependant settings. Please ensure the data you enter is accurate, errors will result in emails containing incorrect information. When entering the domain name remember it does include http:// or other protocol term. Only alter the port number if you know your server uses a different value, port 80 is correct in most cases.', 'ENABLE_GZIP' => 'Enable GZip compression', 'ENABLE_GZIP_EXPLAIN' => 'Generated content will be compressed prior to sending it to the user. This can reduce network traffic but will also increase CPU usage on both server and client side. Requires zlib PHP extension to be loaded.', @@ -454,8 +454,8 @@ $lang = array_merge($lang, array( 'CHECK_DNSBL_EXPLAIN' => 'If enabled the user’s IP address is checked against the following DNSBL services on registration and posting: spamcop.net and www.spamhaus.org. This lookup may take a while, depending on the server’s configuration. If slowdowns are experienced or too many false positives reported it is recommended to disable this check.', 'CLASS_B' => 'A.B', 'CLASS_C' => 'A.B.C', - 'EMAIL_CHECK_MX' => 'Check e-mail domain for valid MX record', - 'EMAIL_CHECK_MX_EXPLAIN' => 'If enabled, the e-mail domain provided on registration and profile changes is checked for a valid MX record.', + 'EMAIL_CHECK_MX' => 'Check email domain for valid MX record', + 'EMAIL_CHECK_MX_EXPLAIN' => 'If enabled, the email domain provided on registration and profile changes is checked for a valid MX record.', 'FORCE_PASS_CHANGE' => 'Force password change', 'FORCE_PASS_CHANGE_EXPLAIN' => 'Require user to change their password after a set number of days. Setting this value to 0 disables this behaviour.', 'FORM_TIME_MAX' => 'Maximum time to submit forms', @@ -492,24 +492,24 @@ $lang = array_merge($lang, array( // Email Settings $lang = array_merge($lang, array( - 'ACP_EMAIL_SETTINGS_EXPLAIN' => 'This information is used when the board sends e-mails to your users. Please ensure the e-mail address you specify is valid, any bounced or undeliverable messages will likely be sent to that address. If your host does not provide a native (PHP based) e-mail service you can instead send messages directly using SMTP. This requires the address of an appropriate server (ask your provider if necessary). If the server requires authentication (and only if it does) enter the necessary username, password and authentication method.', + 'ACP_EMAIL_SETTINGS_EXPLAIN' => 'This information is used when the board sends emails to your users. Please ensure the email address you specify is valid, any bounced or undeliverable messages will likely be sent to that address. If your host does not provide a native (PHP based) email service you can instead send messages directly using SMTP. This requires the address of an appropriate server (ask your provider if necessary). If the server requires authentication (and only if it does) enter the necessary username, password and authentication method.', - 'ADMIN_EMAIL' => 'Return e-mail address', - 'ADMIN_EMAIL_EXPLAIN' => 'This will be used as the return address on all e-mails, the technical contact e-mail address. It will always be used as the Return-Path and Sender address in e-mails.', - 'BOARD_EMAIL_FORM' => 'Users send e-mail via board', - 'BOARD_EMAIL_FORM_EXPLAIN' => 'Instead of showing the users e-mail address users are able to send e-mails via the board.', - 'BOARD_HIDE_EMAILS' => 'Hide e-mail addresses', - 'BOARD_HIDE_EMAILS_EXPLAIN' => 'This function keeps e-mail addresses completely private.', - 'CONTACT_EMAIL' => 'Contact e-mail address', - 'CONTACT_EMAIL_EXPLAIN' => 'This address will be used whenever a specific contact point is needed, e.g. spam, error output, etc. It will always be used as the From and Reply-To address in e-mails.', - 'EMAIL_FUNCTION_NAME' => 'E-mail function name', - 'EMAIL_FUNCTION_NAME_EXPLAIN' => 'The e-mail function used to send mails through PHP.', - 'EMAIL_PACKAGE_SIZE' => 'E-mail package size', - 'EMAIL_PACKAGE_SIZE_EXPLAIN' => 'This is the number of maximum e-mails sent out in one package. This setting is applied to the internal message queue; set this value to 0 if you have problems with non-delivered notification e-mails.', - 'EMAIL_SIG' => 'E-mail signature', - 'EMAIL_SIG_EXPLAIN' => 'This text will be attached to all e-mails the board sends.', - 'ENABLE_EMAIL' => 'Enable board-wide e-mails', - 'ENABLE_EMAIL_EXPLAIN' => 'If this is set to disabled no e-mails will be sent by the board at all. Note the user and admin account activation settings require this setting to be enabled. If currently using “user” or “admin” activation in the activation settings, disabling this setting will require no activation of new accounts.', + 'ADMIN_EMAIL' => 'Return email address', + 'ADMIN_EMAIL_EXPLAIN' => 'This will be used as the return address on all emails, the technical contact email address. It will always be used as the Return-Path and Sender address in emails.', + 'BOARD_EMAIL_FORM' => 'Users send email via board', + 'BOARD_EMAIL_FORM_EXPLAIN' => 'Instead of showing the users email address users are able to send emails via the board.', + 'BOARD_HIDE_EMAILS' => 'Hide email addresses', + 'BOARD_HIDE_EMAILS_EXPLAIN' => 'This function keeps email addresses completely private.', + 'CONTACT_EMAIL' => 'Contact email address', + 'CONTACT_EMAIL_EXPLAIN' => 'This address will be used whenever a specific contact point is needed, e.g. spam, error output, etc. It will always be used as the From and Reply-To address in emails.', + 'EMAIL_FUNCTION_NAME' => 'Email function name', + 'EMAIL_FUNCTION_NAME_EXPLAIN' => 'The email function used to send mails through PHP.', + 'EMAIL_PACKAGE_SIZE' => 'Email package size', + 'EMAIL_PACKAGE_SIZE_EXPLAIN' => 'This is the number of maximum emails sent out in one package. This setting is applied to the internal message queue; set this value to 0 if you have problems with non-delivered notification emails.', + 'EMAIL_SIG' => 'Email signature', + 'EMAIL_SIG_EXPLAIN' => 'This text will be attached to all emails the board sends.', + 'ENABLE_EMAIL' => 'Enable board-wide emails', + 'ENABLE_EMAIL_EXPLAIN' => 'If this is set to disabled no emails will be sent by the board at all. Note the user and admin account activation settings require this setting to be enabled. If currently using “user” or “admin” activation in the activation settings, disabling this setting will require no activation of new accounts.', 'SMTP_AUTH_METHOD' => 'Authentication method for SMTP', 'SMTP_AUTH_METHOD_EXPLAIN' => 'Only used if a username/password is set, ask your provider if you are unsure which method to use.', 'SMTP_CRAM_MD5' => 'CRAM-MD5', @@ -525,8 +525,8 @@ $lang = array_merge($lang, array( 'SMTP_SETTINGS' => 'SMTP settings', 'SMTP_USERNAME' => 'SMTP username', 'SMTP_USERNAME_EXPLAIN' => 'Only enter a username if your SMTP server requires it.', - 'USE_SMTP' => 'Use SMTP server for e-mail', - 'USE_SMTP_EXPLAIN' => 'Select “Yes” if you want or have to send e-mail via a named server instead of the local mail function.', + 'USE_SMTP' => 'Use SMTP server for email', + 'USE_SMTP_EXPLAIN' => 'Select “Yes” if you want or have to send email via a named server instead of the local mail function.', )); // Jabber settings diff --git a/phpBB/language/en/acp/common.php b/phpBB/language/en/acp/common.php index 6012c59483..dc35969955 100644 --- a/phpBB/language/en/acp/common.php +++ b/phpBB/language/en/acp/common.php @@ -47,7 +47,7 @@ $lang = array_merge($lang, array( 'ACP_BACKUP' => 'Backup', 'ACP_BAN' => 'Banning', - 'ACP_BAN_EMAILS' => 'Ban e-mails', + 'ACP_BAN_EMAILS' => 'Ban emails', 'ACP_BAN_IPS' => 'Ban IPs', 'ACP_BAN_USERNAMES' => 'Ban usernames', 'ACP_BBCODES' => 'BBCodes', @@ -79,7 +79,7 @@ $lang = array_merge($lang, array( 'ACP_DISALLOW' => 'Disallow', 'ACP_DISALLOW_USERNAMES' => 'Disallow usernames', - 'ACP_EMAIL_SETTINGS' => 'E-mail settings', + 'ACP_EMAIL_SETTINGS' => 'Email settings', 'ACP_EXTENSION_GROUPS' => 'Manage extension groups', 'ACP_FORUM_BASED_PERMISSIONS' => 'Forum based permissions', @@ -123,7 +123,7 @@ $lang = array_merge($lang, array( 'ACP_MANAGE_RANKS' => 'Manage ranks', 'ACP_MANAGE_REASONS' => 'Manage report/denial reasons', 'ACP_MANAGE_USERS' => 'Manage users', - 'ACP_MASS_EMAIL' => 'Mass e-mail', + 'ACP_MASS_EMAIL' => 'Mass email', 'ACP_MESSAGES' => 'Messages', 'ACP_MESSAGE_SETTINGS' => 'Private message settings', 'ACP_MODULE_MANAGEMENT' => 'Module management', @@ -265,7 +265,7 @@ $lang = array_merge($lang, array( 'NOTIFY' => 'Notification', 'NO_ADMIN' => 'You are not authorised to administer this board.', - 'NO_EMAILS_DEFINED' => 'No valid e-mail addresses found.', + 'NO_EMAILS_DEFINED' => 'No valid email addresses found.', 'NO_FILES_TO_DELETE' => 'Attachments you selected for deletion do not exist.', 'NO_PASSWORD_SUPPLIED' => 'You need to enter your password to access the Administration Control Panel.', @@ -314,7 +314,7 @@ $lang = array_merge($lang, array( // Logs $lang = array_merge($lang, array( 'ACP_ADMIN_LOGS_EXPLAIN' => 'This lists all the actions carried out by board administrators. You can sort by username, date, IP or action. If you have appropriate permissions you can also clear individual operations or the log as a whole.', - 'ACP_CRITICAL_LOGS_EXPLAIN' => 'This lists the actions carried out by the board itself. This log provides you with information you are able to use for solving specific problems, for example non-delivery of e-mails. You can sort by username, date, IP or action. If you have appropriate permissions you can also clear individual operations or the log as a whole.', + 'ACP_CRITICAL_LOGS_EXPLAIN' => 'This lists the actions carried out by the board itself. This log provides you with information you are able to use for solving specific problems, for example non-delivery of emails. You can sort by username, date, IP or action. If you have appropriate permissions you can also clear individual operations or the log as a whole.', 'ACP_MOD_LOGS_EXPLAIN' => 'This lists all actions done on forums, topics and posts as well as actions carried out on users by moderators, including banning. You can sort by username, date, IP or action. If you have appropriate permissions you can also clear individual operations or the log as a whole.', 'ACP_USERS_LOGS_EXPLAIN' => 'This lists all actions carried out by users or on users (reports, warnings and user notes).', 'ALL_ENTRIES' => 'All entries', @@ -426,8 +426,8 @@ $lang = array_merge($lang, array( 'INACTIVE_REASON_REMIND' => 'Forced user account reactivation', 'INACTIVE_REASON_UNKNOWN' => 'Unknown', 'INACTIVE_USERS' => 'Inactive users', - 'INACTIVE_USERS_EXPLAIN' => 'This is a list of users who have registered but whose accounts are inactive. You can activate, delete or remind (by sending an e-mail) these users if you wish.', - 'INACTIVE_USERS_EXPLAIN_INDEX' => 'This is a list of the last 10 registered users who have inactive accounts. Accounts are inactive either because account activation was enabled in user registration settings and these users’ accounts have not yet been activated, or because these accounts have been deactivated. A full list is available by following the link below from where you can activate, delete or remind (by sending an e-mail) these users if you wish.', + 'INACTIVE_USERS_EXPLAIN' => 'This is a list of users who have registered but whose accounts are inactive. You can activate, delete or remind (by sending an email) these users if you wish.', + 'INACTIVE_USERS_EXPLAIN_INDEX' => 'This is a list of the last 10 registered users who have inactive accounts. Accounts are inactive either because account activation was enabled in user registration settings and these users’ accounts have not yet been activated, or because these accounts have been deactivated. A full list is available by following the link below from where you can activate, delete or remind (by sending an email) these users if you wish.', 'NO_INACTIVE_USERS' => 'No inactive users', @@ -497,13 +497,13 @@ $lang = array_merge($lang, array( 'LOG_BAN_EXCLUDE_USER' => 'Excluded user from ban for reason “%1$s”
    » %2$s', 'LOG_BAN_EXCLUDE_IP' => 'Excluded IP from ban for reason “%1$s”
    » %2$s', - 'LOG_BAN_EXCLUDE_EMAIL' => 'Excluded e-mail from ban for reason “%1$s”
    » %2$s', + 'LOG_BAN_EXCLUDE_EMAIL' => 'Excluded email from ban for reason “%1$s”
    » %2$s', 'LOG_BAN_USER' => 'Banned user for reason “%1$s”
    » %2$s', 'LOG_BAN_IP' => 'Banned IP for reason “%1$s”
    » %2$s', - 'LOG_BAN_EMAIL' => 'Banned e-mail for reason “%1$s”
    » %2$s', + 'LOG_BAN_EMAIL' => 'Banned email for reason “%1$s”
    » %2$s', 'LOG_UNBAN_USER' => 'Unbanned user
    » %s', 'LOG_UNBAN_IP' => 'Unbanned IP
    » %s', - 'LOG_UNBAN_EMAIL' => 'Unbanned e-mail
    » %s', + 'LOG_UNBAN_EMAIL' => 'Unbanned email
    » %s', 'LOG_BBCODE_ADD' => 'Added new BBCode
    » %s', 'LOG_BBCODE_EDIT' => 'Edited BBCode
    » %s', @@ -523,7 +523,7 @@ $lang = array_merge($lang, array( 'LOG_CONFIG_AUTH' => 'Altered authentication settings', 'LOG_CONFIG_AVATAR' => 'Altered avatar settings', 'LOG_CONFIG_COOKIE' => 'Altered cookie settings', - 'LOG_CONFIG_EMAIL' => 'Altered e-mail settings', + 'LOG_CONFIG_EMAIL' => 'Altered email settings', 'LOG_CONFIG_FEATURES' => 'Altered board features', 'LOG_CONFIG_LOAD' => 'Altered load settings', 'LOG_CONFIG_MESSAGE' => 'Altered private message settings', @@ -576,7 +576,7 @@ $lang = array_merge($lang, array( 'LOG_DOWNLOAD_REMOVE_IP' => 'Removed IP/hostname from download list
    » %s', 'LOG_ERROR_JABBER' => 'Jabber error
    » %s', - 'LOG_ERROR_EMAIL' => 'E-mail error
    » %s', + 'LOG_ERROR_EMAIL' => 'Email error
    » %s', 'LOG_FORUM_ADD' => 'Created new forum
    » %s', 'LOG_FORUM_COPIED_PERMISSIONS' => 'Copied forum permissions from %1$s
    » %2$s', @@ -612,7 +612,7 @@ $lang = array_merge($lang, array( 'LOG_INACTIVE_ACTIVATE' => 'Activated inactive users
    » %s', 'LOG_INACTIVE_DELETE' => 'Deleted inactive users
    » %s', - 'LOG_INACTIVE_REMIND' => 'Sent reminder e-mails to inactive users
    » %s', + 'LOG_INACTIVE_REMIND' => 'Sent reminder emails to inactive users
    » %s', 'LOG_INSTALL_CONVERTED' => 'Converted from %1$s to phpBB %2$s', 'LOG_INSTALL_INSTALLED' => 'Installed phpBB %s', @@ -629,7 +629,7 @@ $lang = array_merge($lang, array( 'LOG_LANGUAGE_FILE_REPLACED' => 'Replaced language file
    » %s', 'LOG_LANGUAGE_FILE_SUBMITTED' => 'Submitted language file and placed in store folder
    » %s', - 'LOG_MASS_EMAIL' => 'Sent mass e-mail
    » %s', + 'LOG_MASS_EMAIL' => 'Sent mass email
    » %s', 'LOG_MCP_CHANGE_POSTER' => 'Changed poster in topic “%1$s”
    » from %2$s to %3$s', @@ -723,7 +723,7 @@ $lang = array_merge($lang, array( 'LOG_USER_ACTIVE' => 'User activated
    » %s', 'LOG_USER_BAN_USER' => 'Banned User via user management for reason “%1$s”
    » %2$s', 'LOG_USER_BAN_IP' => 'Banned IP via user management for reason “%1$s”
    » %2$s', - 'LOG_USER_BAN_EMAIL' => 'Banned e-mail via user management for reason “%1$s”
    » %2$s', + 'LOG_USER_BAN_EMAIL' => 'Banned email via user management for reason “%1$s”
    » %2$s', 'LOG_USER_DELETED' => 'Deleted user
    » %s', 'LOG_USER_DEL_ATTACH' => 'Removed all attachments made by the user
    » %s', 'LOG_USER_DEL_AVATAR' => 'Removed user avatar
    » %s', @@ -736,7 +736,7 @@ $lang = array_merge($lang, array( 'LOG_USER_REACTIVATE' => 'Forced user account reactivation
    » %s', 'LOG_USER_REMOVED_NR' => 'Removed newly registered flag from user
    » %s', - 'LOG_USER_UPDATE_EMAIL' => 'User “%1$s” changed e-mail
    » from “%2$s” to “%3$s”', + 'LOG_USER_UPDATE_EMAIL' => 'User “%1$s” changed email
    » from “%2$s” to “%3$s”', 'LOG_USER_UPDATE_NAME' => 'Changed username
    » from “%1$s” to “%2$s”', 'LOG_USER_USER_UPDATE' => 'Updated user details
    » %s', diff --git a/phpBB/language/en/acp/email.php b/phpBB/language/en/acp/email.php index c39b8743e7..aacb35b9bb 100644 --- a/phpBB/language/en/acp/email.php +++ b/phpBB/language/en/acp/email.php @@ -36,12 +36,12 @@ if (empty($lang) || !is_array($lang)) // Email settings $lang = array_merge($lang, array( - 'ACP_MASS_EMAIL_EXPLAIN' => 'Here you can e-mail a message to either all of your users or all users of a specific group having the option to receive mass e-mails enabled. To achieve this an e-mail will be sent out to the administrative e-mail address supplied, with a blind carbon copy sent to all recipients. The default setting is to only include 50 recipients in such an e-mail, for more recipients more e-mails will be sent. If you are emailing a large group of people please be patient after submitting and do not stop the page halfway through. It is normal for a mass emailing to take a long time, you will be notified when the script has completed.', + 'ACP_MASS_EMAIL_EXPLAIN' => 'Here you can email a message to either all of your users or all users of a specific group having the option to receive mass emails enabled. To achieve this an email will be sent out to the administrative email address supplied, with a blind carbon copy sent to all recipients. The default setting is to only include 50 recipients in such an email, for more recipients more emails will be sent. If you are emailing a large group of people please be patient after submitting and do not stop the page halfway through. It is normal for a mass emailing to take a long time, you will be notified when the script has completed.', 'ALL_USERS' => 'All users', 'COMPOSE' => 'Compose', - 'EMAIL_SEND_ERROR' => 'There were one or more errors while sending the e-mail. Please check the %sError log%s for detailed error messages.', + 'EMAIL_SEND_ERROR' => 'There were one or more errors while sending the email. Please check the %sError log%s for detailed error messages.', 'EMAIL_SENT' => 'This message has been sent.', 'EMAIL_SENT_QUEUE' => 'This message has been queued for sending.', @@ -53,7 +53,7 @@ $lang = array_merge($lang, array( 'SEND_TO_USERS_EXPLAIN' => 'Entering names here will override any group selected above. Enter each username on a new line.', 'MAIL_BANNED' => 'Mail banned users', - 'MAIL_BANNED_EXPLAIN' => 'When sending a mass e-mail to a group you can select here whether banned users will also receive the e-mail.', + 'MAIL_BANNED_EXPLAIN' => 'When sending a mass email to a group you can select here whether banned users will also receive the email.', 'MAIL_HIGH_PRIORITY' => 'High', 'MAIL_LOW_PRIORITY' => 'Low', 'MAIL_NORMAL_PRIORITY' => 'Normal', diff --git a/phpBB/language/en/acp/language.php b/phpBB/language/en/acp/language.php index 6bac0a815b..154551bd6e 100644 --- a/phpBB/language/en/acp/language.php +++ b/phpBB/language/en/acp/language.php @@ -38,7 +38,7 @@ $lang = array_merge($lang, array( 'ACP_FILES' => 'Admin language files', 'ACP_LANGUAGE_PACKS_EXPLAIN' => 'Here you are able to install/remove language packs. The default language pack is marked with an asterisk (*).', - 'EMAIL_FILES' => 'E-mail templates', + 'EMAIL_FILES' => 'Email templates', 'FILE_CONTENTS' => 'File contents', 'FILE_FROM_STORAGE' => 'File from storage folder', diff --git a/phpBB/language/en/acp/permissions.php b/phpBB/language/en/acp/permissions.php index 2a8d857197..cf5ad33bab 100644 --- a/phpBB/language/en/acp/permissions.php +++ b/phpBB/language/en/acp/permissions.php @@ -202,7 +202,7 @@ $lang = array_merge($lang, array( 'ROLE_DESCRIPTION_MOD_SIMPLE' => 'Can only use basic topic actions. Cannot send warnings or use moderation queue.', 'ROLE_DESCRIPTION_MOD_STANDARD' => 'Can use most moderating tools, but cannot ban users or change the post author.', 'ROLE_DESCRIPTION_USER_FULL' => 'Can use all available forum features for users, including changing the user name or ignoring the flood limit.
    Not recommended.', - 'ROLE_DESCRIPTION_USER_LIMITED' => 'Can access some of the user features. Attachments, e-mails, or instant messages are not allowed.', + 'ROLE_DESCRIPTION_USER_LIMITED' => 'Can access some of the user features. Attachments, emails, or instant messages are not allowed.', 'ROLE_DESCRIPTION_USER_NOAVATAR' => 'Has a limited feature set and is not allowed to use the Avatar feature.', 'ROLE_DESCRIPTION_USER_NOPM' => 'Has a limited feature set, and is not allowed to use Private Messages.', 'ROLE_DESCRIPTION_USER_STANDARD' => 'Can access most but not all user features. Cannot change user name or ignore the flood limit, for instance.', diff --git a/phpBB/language/en/acp/permissions_phpbb.php b/phpBB/language/en/acp/permissions_phpbb.php index f8cb35ed6a..17649693fa 100644 --- a/phpBB/language/en/acp/permissions_phpbb.php +++ b/phpBB/language/en/acp/permissions_phpbb.php @@ -99,7 +99,7 @@ $lang = array_merge($lang, array( 'acl_u_viewprofile' => array('lang' => 'Can view profiles, memberlist and online list', 'cat' => 'profile'), 'acl_u_chgname' => array('lang' => 'Can change username', 'cat' => 'profile'), 'acl_u_chgpasswd' => array('lang' => 'Can change password', 'cat' => 'profile'), - 'acl_u_chgemail' => array('lang' => 'Can change e-mail address', 'cat' => 'profile'), + 'acl_u_chgemail' => array('lang' => 'Can change email address', 'cat' => 'profile'), 'acl_u_chgavatar' => array('lang' => 'Can change avatar', 'cat' => 'profile'), 'acl_u_chggrp' => array('lang' => 'Can change default usergroup', 'cat' => 'profile'), @@ -116,7 +116,7 @@ $lang = array_merge($lang, array( 'acl_u_pm_edit' => array('lang' => 'Can edit own private messages', 'cat' => 'pm'), 'acl_u_pm_delete' => array('lang' => 'Can remove private messages from own folder', 'cat' => 'pm'), 'acl_u_pm_forward' => array('lang' => 'Can forward private messages', 'cat' => 'pm'), - 'acl_u_pm_emailpm' => array('lang' => 'Can e-mail private messages', 'cat' => 'pm'), + 'acl_u_pm_emailpm' => array('lang' => 'Can email private messages', 'cat' => 'pm'), 'acl_u_pm_printpm' => array('lang' => 'Can print private messages', 'cat' => 'pm'), 'acl_u_pm_attach' => array('lang' => 'Can attach files in private messages', 'cat' => 'pm'), 'acl_u_pm_download' => array('lang' => 'Can download files in private messages', 'cat' => 'pm'), @@ -125,7 +125,7 @@ $lang = array_merge($lang, array( 'acl_u_pm_img' => array('lang' => 'Can use [img] BBCode tag in private messages', 'cat' => 'pm'), 'acl_u_pm_flash' => array('lang' => 'Can use [flash] BBCode tag in private messages', 'cat' => 'pm'), - 'acl_u_sendemail' => array('lang' => 'Can send e-mails', 'cat' => 'misc'), + 'acl_u_sendemail' => array('lang' => 'Can send emails', 'cat' => 'misc'), 'acl_u_sendim' => array('lang' => 'Can send instant messages', 'cat' => 'misc'), 'acl_u_ignoreflood' => array('lang' => 'Can ignore flood limit', 'cat' => 'misc'), 'acl_u_hideonline' => array('lang' => 'Can hide online status', 'cat' => 'misc'), @@ -162,7 +162,7 @@ $lang = array_merge($lang, array( 'acl_f_report' => array('lang' => 'Can report posts', 'cat' => 'actions'), 'acl_f_subscribe' => array('lang' => 'Can subscribe forum', 'cat' => 'actions'), 'acl_f_print' => array('lang' => 'Can print topics', 'cat' => 'actions'), - 'acl_f_email' => array('lang' => 'Can e-mail topics', 'cat' => 'actions'), + 'acl_f_email' => array('lang' => 'Can email topics', 'cat' => 'actions'), 'acl_f_search' => array('lang' => 'Can search the forum', 'cat' => 'misc'), 'acl_f_ignoreflood' => array('lang' => 'Can ignore flood limit', 'cat' => 'misc'), @@ -230,7 +230,7 @@ $lang = array_merge($lang, array( 'acl_a_clearlogs' => array('lang' => 'Can clear logs', 'cat' => 'misc'), 'acl_a_modules' => array('lang' => 'Can manage modules', 'cat' => 'misc'), 'acl_a_language' => array('lang' => 'Can manage language packs', 'cat' => 'misc'), - 'acl_a_email' => array('lang' => 'Can send mass e-mail', 'cat' => 'misc'), + 'acl_a_email' => array('lang' => 'Can send mass email', 'cat' => 'misc'), 'acl_a_bots' => array('lang' => 'Can manage bots', 'cat' => 'misc'), 'acl_a_reasons' => array('lang' => 'Can manage report/denial reasons', 'cat' => 'misc'), 'acl_a_backup' => array('lang' => 'Can backup/restore database', 'cat' => 'misc'), diff --git a/phpBB/language/en/acp/posting.php b/phpBB/language/en/acp/posting.php index 76d4869990..89e171744f 100644 --- a/phpBB/language/en/acp/posting.php +++ b/phpBB/language/en/acp/posting.php @@ -81,7 +81,7 @@ $lang = array_merge($lang, array( 'INTTEXT' => 'Unicode letter characters, numbers, spaces, commas, dots, minus, plus, hyphen, underscore and whitespaces.', 'IDENTIFIER' => 'Characters from the latin alphabet (A-Z), numbers, hyphen and underscore', 'NUMBER' => 'Any series of digits', - 'EMAIL' => 'A valid e-mail address', + 'EMAIL' => 'A valid email address', 'URL' => 'A valid URL using any protocol (http, ftp, etc… cannot be used for javascript exploits). If none is given, “http://” is prefixed to the string.', 'LOCAL_URL' => 'A local URL. The URL must be relative to the topic page and cannot contain a server name or protocol.', 'COLOR' => 'A HTML colour, can be either in the numeric form #FF1234 or a CSS colour keyword such as fuchsia or InactiveBorder' diff --git a/phpBB/language/en/acp/styles.php b/phpBB/language/en/acp/styles.php index f5bab1d76f..e7954ff148 100644 --- a/phpBB/language/en/acp/styles.php +++ b/phpBB/language/en/acp/styles.php @@ -183,7 +183,7 @@ $lang = array_merge($lang, array( 'IMG_ICON_BACK_TOP' => 'Top', 'IMG_ICON_CONTACT_AIM' => 'AIM', - 'IMG_ICON_CONTACT_EMAIL' => 'Send e-mail', + 'IMG_ICON_CONTACT_EMAIL' => 'Send email', 'IMG_ICON_CONTACT_ICQ' => 'ICQ', 'IMG_ICON_CONTACT_JABBER' => 'Jabber', 'IMG_ICON_CONTACT_MSNM' => 'WLM', @@ -255,7 +255,7 @@ $lang = array_merge($lang, array( 'NO_UNIT' => 'None', 'ONLY_STYLE' => 'This is the only remaining style, you cannot delete it.', - + 'PARENT_STYLE_NOT_FOUND' => 'Parent style was not found. This style may not work correctly. Please uninstall it.', 'PURGED_CACHE' => 'Cache was purged.', diff --git a/phpBB/language/en/acp/users.php b/phpBB/language/en/acp/users.php index 852f68bcd7..4496fdba7c 100644 --- a/phpBB/language/en/acp/users.php +++ b/phpBB/language/en/acp/users.php @@ -54,7 +54,7 @@ $lang = array_merge($lang, array( 'CANNOT_REMOVE_YOURSELF' => 'You are not allowed to remove your own user account.', 'CANNOT_SET_FOUNDER_IGNORED' => 'You are not able to promote ignored users to be founders.', 'CANNOT_SET_FOUNDER_INACTIVE' => 'You need to activate users before you promote them to founders, only activated users are able to be promoted.', - 'CONFIRM_EMAIL_EXPLAIN' => 'You only need to specify this if you are changing the users e-mail address.', + 'CONFIRM_EMAIL_EXPLAIN' => 'You only need to specify this if you are changing the users email address.', 'DELETE_POSTS' => 'Delete posts', 'DELETE_USER' => 'Delete user', @@ -93,8 +93,8 @@ $lang = array_merge($lang, array( 'USER_ADMIN_ACTIVATE' => 'Activate account', 'USER_ADMIN_ACTIVATED' => 'User activated successfully.', 'USER_ADMIN_AVATAR_REMOVED' => 'Successfully removed avatar from user account.', - 'USER_ADMIN_BAN_EMAIL' => 'Ban by e-mail', - 'USER_ADMIN_BAN_EMAIL_REASON' => 'E-mail address banned via user management', + 'USER_ADMIN_BAN_EMAIL' => 'Ban by email', + 'USER_ADMIN_BAN_EMAIL_REASON' => 'Email address banned via user management', 'USER_ADMIN_BAN_IP' => 'Ban by IP', 'USER_ADMIN_BAN_IP_REASON' => 'IP banned via user management', 'USER_ADMIN_BAN_NAME_REASON' => 'Username banned via user management', diff --git a/phpBB/language/en/common.php b/phpBB/language/en/common.php index 12f8edad9e..75717e1807 100644 --- a/phpBB/language/en/common.php +++ b/phpBB/language/en/common.php @@ -101,7 +101,7 @@ $lang = array_merge($lang, array( 'BACK_TO_TOP' => 'Top', 'BACK_TO_PREV' => 'Back to previous page', - 'BAN_TRIGGERED_BY_EMAIL'=> 'A ban has been issued on your e-mail address.', + 'BAN_TRIGGERED_BY_EMAIL'=> 'A ban has been issued on your email address.', 'BAN_TRIGGERED_BY_IP' => 'A ban has been issued on your IP address.', 'BAN_TRIGGERED_BY_USER' => 'A ban has been issued on your username.', 'BBCODE_GUIDE' => 'BBCode guide', @@ -169,9 +169,9 @@ $lang = array_merge($lang, array( ), 'EDIT_POST' => 'Edit post', - 'EMAIL' => 'E-mail', // Short form for EMAIL_ADDRESS - 'EMAIL_ADDRESS' => 'E-mail address', - 'EMAIL_SMTP_ERROR_RESPONSE' => 'Ran into problems sending e-mail at Line %1$s. Response: %2$s.', + 'EMAIL' => 'Email', // Short form for EMAIL_ADDRESS + 'EMAIL_ADDRESS' => 'Email address', + 'EMAIL_SMTP_ERROR_RESPONSE' => 'Ran into problems sending email at Line %1$s. Response: %2$s.', 'EMPTY_SUBJECT' => 'You must specify a subject when posting a new topic.', 'EMPTY_MESSAGE_SUBJECT' => 'You must specify a subject when composing a new message.', 'ENABLED' => 'Enabled', @@ -296,7 +296,7 @@ $lang = array_merge($lang, array( 'INFORMATION' => 'Information', 'INTERESTS' => 'Interests', 'INVALID_DIGEST_CHALLENGE' => 'Invalid digest challenge.', - 'INVALID_EMAIL_LOG' => '%s possibly an invalid e-mail address?', + 'INVALID_EMAIL_LOG' => '%s possibly an invalid email address?', 'INVALID_PLURAL_RULE' => 'The chosen plural rule is invalid. Valid values are integers between 0 and 15.', 'IP' => 'IP', 'IP_BLACKLISTED' => 'Your IP %1$s has been blocked because it is blacklisted. For details please see %2$s.', @@ -391,9 +391,9 @@ $lang = array_merge($lang, array( 'NO_AUTH_OPERATION' => 'You do not have the necessary permissions to complete this operation.', 'NO_CONNECT_TO_SMTP_HOST' => 'Could not connect to smtp host : %1$s : %2$s', 'NO_BIRTHDAYS' => 'No birthdays today', - 'NO_EMAIL_MESSAGE' => 'E-mail message was blank.', + 'NO_EMAIL_MESSAGE' => 'Email message was blank.', 'NO_EMAIL_RESPONSE_CODE' => 'Could not get mail server response codes.', - 'NO_EMAIL_SUBJECT' => 'No e-mail subject specified.', + 'NO_EMAIL_SUBJECT' => 'No email subject specified.', 'NO_FORUM' => 'The forum you selected does not exist.', 'NO_FORUMS' => 'This board has no forums.', 'NO_GROUP' => 'The requested usergroup does not exist.', @@ -521,7 +521,7 @@ $lang = array_merge($lang, array( 'REPORT_BY' => 'Report by', 'REPORT_POST' => 'Report this post', 'REPORTING_POST' => 'Reporting post', - 'RESEND_ACTIVATION' => 'Resend activation e-mail', + 'RESEND_ACTIVATION' => 'Resend activation email', 'RESET' => 'Reset', 'RESTORE_PERMISSIONS' => 'Restore permissions', 'RETURN_INDEX' => '%sReturn to the index page%s', @@ -571,8 +571,8 @@ $lang = array_merge($lang, array( 'SELECT_ALL_CODE' => 'Select all', 'SELECT_DESTINATION_FORUM' => 'Please select a destination forum', 'SELECT_FORUM' => 'Select a forum', - 'SEND_EMAIL' => 'E-mail', // Used for submit buttons - 'SEND_EMAIL_USER' => 'E-mail', // Used as: {L_SEND_EMAIL_USER} {USERNAME} -> E-mail UserX + 'SEND_EMAIL' => 'Email', // Used for submit buttons + 'SEND_EMAIL_USER' => 'Email', // Used as: {L_SEND_EMAIL_USER} {USERNAME} -> Email UserX 'SEND_PRIVATE_MESSAGE' => 'Send private message', 'SETTINGS' => 'Settings', 'SIGNATURE' => 'Signature', @@ -604,7 +604,7 @@ $lang = array_merge($lang, array( 'THE_TEAM' => 'The team', 'TIME' => 'Time', 'TIMEOUT_PROCESSING_REQ' => 'Request timed out.', - + 'TOO_LARGE' => 'The value you entered is too large.', 'TOO_LARGE_MAX_RECIPIENTS' => 'The value of Maximum number of allowed recipients per private message setting you entered is too large.', @@ -623,7 +623,7 @@ $lang = array_merge($lang, array( 'TOO_LONG_PASSWORD_CONFIRM' => 'The password confirmation you entered is too long.', 'TOO_LONG_USER_PASSWORD' => 'The password you entered is too long.', 'TOO_LONG_USERNAME' => 'The username you entered is too long.', - 'TOO_LONG_EMAIL' => 'The e-mail address you entered is too long.', + 'TOO_LONG_EMAIL' => 'The email address you entered is too long.', 'TOO_LONG_WEBSITE' => 'The website address you entered is too long.', 'TOO_LONG_YIM' => 'The Yahoo! Messenger name you entered is too long.', @@ -644,10 +644,10 @@ $lang = array_merge($lang, array( 'TOO_SHORT_PASSWORD_CONFIRM' => 'The password confirmation you entered is too short.', 'TOO_SHORT_USER_PASSWORD' => 'The password you entered is too short.', 'TOO_SHORT_USERNAME' => 'The username you entered is too short.', - 'TOO_SHORT_EMAIL' => 'The e-mail address you entered is too short.', + 'TOO_SHORT_EMAIL' => 'The email address you entered is too short.', 'TOO_SHORT_WEBSITE' => 'The website address you entered is too short.', 'TOO_SHORT_YIM' => 'The Yahoo! Messenger name you entered is too short.', - + 'TOO_SMALL' => 'The value you entered is too small.', 'TOO_SMALL_MAX_RECIPIENTS' => 'The value of Maximum number of allowed recipients per private message setting you entered is too small.', diff --git a/phpBB/language/en/email/admin_send_email.txt b/phpBB/language/en/email/admin_send_email.txt index 6687404527..b778496258 100644 --- a/phpBB/language/en/email/admin_send_email.txt +++ b/phpBB/language/en/email/admin_send_email.txt @@ -1,9 +1,9 @@ -The following is an e-mail sent to you by an administrator of "{SITENAME}". If this message is spam, contains abusive or other comments you find offensive please contact the webmaster of the board at the following address: +The following is an email sent to you by an administrator of "{SITENAME}". If this message is spam, contains abusive or other comments you find offensive please contact the webmaster of the board at the following address: {CONTACT_EMAIL} -Include this full e-mail (particularly the headers). +Include this full email (particularly the headers). Message sent to you follows: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/phpBB/language/en/email/admin_welcome_inactive.txt b/phpBB/language/en/email/admin_welcome_inactive.txt index 30b3aae852..8605956318 100644 --- a/phpBB/language/en/email/admin_welcome_inactive.txt +++ b/phpBB/language/en/email/admin_welcome_inactive.txt @@ -2,7 +2,7 @@ Subject: Welcome to "{SITENAME}" {WELCOME_MSG} -Please keep this e-mail for your records. Your account information is as follows: +Please keep this email for your records. Your account information is as follows: ---------------------------- Username: {USERNAME} diff --git a/phpBB/language/en/email/coppa_resend_inactive.txt b/phpBB/language/en/email/coppa_resend_inactive.txt index c3e4af576d..915534a13e 100644 --- a/phpBB/language/en/email/coppa_resend_inactive.txt +++ b/phpBB/language/en/email/coppa_resend_inactive.txt @@ -16,7 +16,7 @@ OR mail it to: Permission to participate at "{SITENAME}" - {U_BOARD} Username: {USERNAME} -E-mail: {EMAIL_ADDRESS} +Email: {EMAIL_ADDRESS} I HAVE REVIEWED THE INFORMATION PROVIDED BY MY CHILD AND HEREBY GRANT PERMISSION TO "{SITENAME}" TO STORE THIS INFORMATION. I UNDERSTAND THIS INFORMATION CAN BE CHANGED AT ANY TIME BY ENTERING A PASSWORD. diff --git a/phpBB/language/en/email/coppa_welcome_inactive.txt b/phpBB/language/en/email/coppa_welcome_inactive.txt index c3e4af576d..915534a13e 100644 --- a/phpBB/language/en/email/coppa_welcome_inactive.txt +++ b/phpBB/language/en/email/coppa_welcome_inactive.txt @@ -16,7 +16,7 @@ OR mail it to: Permission to participate at "{SITENAME}" - {U_BOARD} Username: {USERNAME} -E-mail: {EMAIL_ADDRESS} +Email: {EMAIL_ADDRESS} I HAVE REVIEWED THE INFORMATION PROVIDED BY MY CHILD AND HEREBY GRANT PERMISSION TO "{SITENAME}" TO STORE THIS INFORMATION. I UNDERSTAND THIS INFORMATION CAN BE CHANGED AT ANY TIME BY ENTERING A PASSWORD. diff --git a/phpBB/language/en/email/email_notify.txt b/phpBB/language/en/email/email_notify.txt index 0d0ac7fc28..725b52f0cc 100644 --- a/phpBB/language/en/email/email_notify.txt +++ b/phpBB/language/en/email/email_notify.txt @@ -1,8 +1,8 @@ -Subject: "{SITENAME}" - E-mail a friend +Subject: "{SITENAME}" - Email a friend Hello {TO_USERNAME}, -This e-mail was sent from "{SITENAME}" by {FROM_USERNAME} who thought you may be interested in the following topic: +This email was sent from "{SITENAME}" by {FROM_USERNAME} who thought you may be interested in the following topic: {TOPIC_NAME} @@ -10,7 +10,7 @@ You can find it at: {U_TOPIC} -A message from {FROM_USERNAME} may also be included below. Please note that this message has not been seen or approved by the board administrators. If you wish to complain about having received this e-mail please contact the board administrator at {BOARD_CONTACT}. Please quote the message headers when contacting this address. +A message from {FROM_USERNAME} may also be included below. Please note that this message has not been seen or approved by the board administrators. If you wish to complain about having received this email please contact the board administrator at {BOARD_CONTACT}. Please quote the message headers when contacting this address. ---------- diff --git a/phpBB/language/en/email/installed.txt b/phpBB/language/en/email/installed.txt index 2aa03a7f33..9ec93484e1 100644 --- a/phpBB/language/en/email/installed.txt +++ b/phpBB/language/en/email/installed.txt @@ -4,7 +4,7 @@ Congratulations, You have successfully installed phpBB on your server. -This e-mail contains important information regarding your installation and should be kept for reference. Your password has been securely stored in our database and cannot be retrieved. In the event that it is forgotten, you will be able to reset it using the email address associated with your account. +This email contains important information regarding your installation and should be kept for reference. Your password has been securely stored in our database and cannot be retrieved. In the event that it is forgotten, you will be able to reset it using the email address associated with your account. ---------------------------- Username: {USERNAME} diff --git a/phpBB/language/en/email/profile_send_email.txt b/phpBB/language/en/email/profile_send_email.txt index 9fb19e7eb1..3e63777c9f 100644 --- a/phpBB/language/en/email/profile_send_email.txt +++ b/phpBB/language/en/email/profile_send_email.txt @@ -1,11 +1,11 @@ Hello {TO_USERNAME}, -The following is an e-mail sent to you by {FROM_USERNAME} via your account on "{SITENAME}". If this message is spam, contains abusive or other comments you find offensive please contact the webmaster of the board at the following address: +The following is an email sent to you by {FROM_USERNAME} via your account on "{SITENAME}". If this message is spam, contains abusive or other comments you find offensive please contact the webmaster of the board at the following address: {BOARD_CONTACT} -Include this full e-mail (particularly the headers). Please note that the reply address to this e-mail has been set to that of {FROM_USERNAME}. +Include this full email (particularly the headers). Please note that the reply address to this email has been set to that of {FROM_USERNAME}. Message sent to you follows ~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/phpBB/language/en/email/user_reactivate_account.txt b/phpBB/language/en/email/user_reactivate_account.txt index 4ef7dd899a..7e25018f4d 100644 --- a/phpBB/language/en/email/user_reactivate_account.txt +++ b/phpBB/language/en/email/user_reactivate_account.txt @@ -3,7 +3,7 @@ Subject: Reactivate your account on "{SITENAME}" A board administrator requested that your account be reactivated. Your account is currently inactive. Please follow the steps listed here to reactivate your account. -Please keep this e-mail for your records. Your account information is as follows: +Please keep this email for your records. Your account information is as follows: ---------------------------- Username: {USERNAME} diff --git a/phpBB/language/en/email/user_resend_inactive.txt b/phpBB/language/en/email/user_resend_inactive.txt index 4638d6df63..7879b914b9 100644 --- a/phpBB/language/en/email/user_resend_inactive.txt +++ b/phpBB/language/en/email/user_resend_inactive.txt @@ -2,7 +2,7 @@ Subject: Welcome to "{SITENAME}" {WELCOME_MSG} -Please keep this e-mail for your records. Your account information is as follows: +Please keep this email for your records. Your account information is as follows: ---------------------------- Username: {USERNAME} diff --git a/phpBB/language/en/email/user_welcome.txt b/phpBB/language/en/email/user_welcome.txt index 2648769dfd..aaead86afc 100644 --- a/phpBB/language/en/email/user_welcome.txt +++ b/phpBB/language/en/email/user_welcome.txt @@ -2,7 +2,7 @@ Subject: Welcome to "{SITENAME}" {WELCOME_MSG} -Please keep this e-mail for your records. Your account information is as follows: +Please keep this email for your records. Your account information is as follows: ---------------------------- Username: {USERNAME} diff --git a/phpBB/language/en/email/user_welcome_inactive.txt b/phpBB/language/en/email/user_welcome_inactive.txt index 1b72b1c5a8..5cbb3af3de 100644 --- a/phpBB/language/en/email/user_welcome_inactive.txt +++ b/phpBB/language/en/email/user_welcome_inactive.txt @@ -2,7 +2,7 @@ Subject: Welcome to "{SITENAME}" {WELCOME_MSG} -Please keep this e-mail for your records. Your account information is as follows: +Please keep this email for your records. Your account information is as follows: ---------------------------- Username: {USERNAME} diff --git a/phpBB/language/en/help_bbcode.php b/phpBB/language/en/help_bbcode.php index 7b2672ad94..e0cda9df04 100644 --- a/phpBB/language/en/help_bbcode.php +++ b/phpBB/language/en/help_bbcode.php @@ -88,7 +88,7 @@ $help = array( ), array( 0 => 'Linking to another site', - 1 => 'phpBB BBCode supports a number of ways of creating URIs (Uniform Resource Indicators) better known as URLs.
    • The first of these uses the [url=][/url] tag, whatever you type after the = sign will cause the contents of that tag to act as a URL. For example to link to phpBB.com you could use:

      [url=http://www.phpbb.com/]Visit phpBB![/url]

      This would generate the following link, Visit phpBB! Please notice that the link opens in the same window or a new window depending on the users browser preferences.
    • If you want the URL itself displayed as the link you can do this by simply using:

      [url]http://www.phpbb.com/[/url]

      This would generate the following link, http://www.phpbb.com/
    • Additionally, phpBB features something called Magic Links, this will turn any syntactically correct URL into a link without you needing to specify any tags or even the leading http://. For example typing www.phpbb.com into your message will automatically lead to www.phpbb.com being output when you view the message.
    • The same thing applies equally to e-mail addresses, you can either specify an address explicitly for example:

      [email]no.one@domain.adr[/email]

      which will output no.one@domain.adr or you can just type no.one@domain.adr into your message and it will be automatically converted when you view.
    As with all the BBCode tags you can wrap URLs around any of the other tags such as [img][/img] (see next entry), [b][/b], etc. As with the formatting tags it is up to you to ensure the correct open and close order is following, for example:

    [url=http://www.google.com/][img]http://www.google.com/intl/en_ALL/images/logo.gif[/url][/img]

    is not correct which may lead to your post being deleted so take care.' + 1 => 'phpBB BBCode supports a number of ways of creating URIs (Uniform Resource Indicators) better known as URLs.
    • The first of these uses the [url=][/url] tag, whatever you type after the = sign will cause the contents of that tag to act as a URL. For example to link to phpBB.com you could use:

      [url=http://www.phpbb.com/]Visit phpBB![/url]

      This would generate the following link, Visit phpBB! Please notice that the link opens in the same window or a new window depending on the users browser preferences.
    • If you want the URL itself displayed as the link you can do this by simply using:

      [url]http://www.phpbb.com/[/url]

      This would generate the following link, http://www.phpbb.com/
    • Additionally, phpBB features something called Magic Links, this will turn any syntactically correct URL into a link without you needing to specify any tags or even the leading http://. For example typing www.phpbb.com into your message will automatically lead to www.phpbb.com being output when you view the message.
    • The same thing applies equally to email addresses, you can either specify an address explicitly for example:

      [email]no.one@domain.adr[/email]

      which will output no.one@domain.adr or you can just type no.one@domain.adr into your message and it will be automatically converted when you view.
    As with all the BBCode tags you can wrap URLs around any of the other tags such as [img][/img] (see next entry), [b][/b], etc. As with the formatting tags it is up to you to ensure the correct open and close order is following, for example:

    [url=http://www.google.com/][img]http://www.google.com/intl/en_ALL/images/logo.gif[/url][/img]

    is not correct which may lead to your post being deleted so take care.' ), array( 0 => '--', diff --git a/phpBB/language/en/help_faq.php b/phpBB/language/en/help_faq.php index b14f155f3a..f21a8d866e 100644 --- a/phpBB/language/en/help_faq.php +++ b/phpBB/language/en/help_faq.php @@ -55,7 +55,7 @@ $help = array( ), array( 0 => 'I registered but cannot login!', - 1 => 'First, check your username and password. If they are correct, then one of two things may have happened. If COPPA support is enabled and you specified being under 13 years old during registration, you will have to follow the instructions you received. Some boards will also require new registrations to be activated, either by yourself or by an administrator before you can logon; this information was present during registration. If you were sent an e-mail, follow the instructions. If you did not receive an e-mail, you may have provided an incorrect e-mail address or the e-mail may have been picked up by a spam filer. If you are sure the e-mail address you provided is correct, try contacting an administrator.' + 1 => 'First, check your username and password. If they are correct, then one of two things may have happened. If COPPA support is enabled and you specified being under 13 years old during registration, you will have to follow the instructions you received. Some boards will also require new registrations to be activated, either by yourself or by an administrator before you can logon; this information was present during registration. If you were sent an email, follow the instructions. If you did not receive an email, you may have provided an incorrect email address or the email may have been picked up by a spam filer. If you are sure the email address you provided is correct, try contacting an administrator.' ), array( 0 => 'I registered in the past but cannot login any more?!', @@ -102,8 +102,8 @@ $help = array( 1 => 'Ranks, which appear below your username, indicate the number of posts you have made or identify certain users, e.g. moderators and administrators. In general, you cannot directly change the wording of any board ranks as they are set by the board administrator. Please do not abuse the board by posting unnecessarily just to increase your rank. Most boards will not tolerate this and the moderator or administrator will simply lower your post count.' ), array( - 0 => 'When I click the e-mail link for a user it asks me to login?', - 1 => 'Only registered users can send e-mail to other users via the built-in e-mail form, and only if the administrator has enabled this feature. This is to prevent malicious use of the e-mail system by anonymous users.' + 0 => 'When I click the email link for a user it asks me to login?', + 1 => 'Only registered users can send email to other users via the built-in email form, and only if the administrator has enabled this feature. This is to prevent malicious use of the email system by anonymous users.' ), array( 0 => '--', @@ -255,8 +255,8 @@ $help = array( 1 => 'You can block a user from sending you private messages by using message rules within your User Control Panel. If you are receiving abusive private messages from a particular user, inform a board administrator; they have the power to prevent a user from sending private messages.' ), array( - 0 => 'I have received a spamming or abusive e-mail from someone on this board!', - 1 => 'We are sorry to hear that. The e-mail form feature of this board includes safeguards to try and track users who send such posts, so e-mail the board administrator with a full copy of the e-mail you received. It is very important that this includes the headers that contain the details of the user that sent the e-mail. The board administrator can then take action.' + 0 => 'I have received a spamming or abusive email from someone on this board!', + 1 => 'We are sorry to hear that. The email form feature of this board includes safeguards to try and track users who send such posts, so email the board administrator with a full copy of the email you received. It is very important that this includes the headers that contain the details of the user that sent the email. The board administrator can then take action.' ), array( 0 => '--', @@ -336,6 +336,6 @@ $help = array( ), array( 0 => 'Who do I contact about abusive and/or legal matters related to this board?', - 1 => 'Any of the administrators listed on the “The team” page should be an appropriate point of contact for your complaints. If this still gets no response then you should contact the owner of the domain (do a whois lookup) or, if this is running on a free service (e.g. Yahoo!, free.fr, f2s.com, etc.), the management or abuse department of that service. Please note that the phpBB Group has absolutely no jurisdiction and cannot in any way be held liable over how, where or by whom this board is used. Do not contact the phpBB Group in relation to any legal (cease and desist, liable, defamatory comment, etc.) matter not directly related to the phpBB.com website or the discrete software of phpBB itself. If you do e-mail phpBB Group about any third party use of this software then you should expect a terse response or no response at all.' + 1 => 'Any of the administrators listed on the “The team” page should be an appropriate point of contact for your complaints. If this still gets no response then you should contact the owner of the domain (do a whois lookup) or, if this is running on a free service (e.g. Yahoo!, free.fr, f2s.com, etc.), the management or abuse department of that service. Please note that the phpBB Group has absolutely no jurisdiction and cannot in any way be held liable over how, where or by whom this board is used. Do not contact the phpBB Group in relation to any legal (cease and desist, liable, defamatory comment, etc.) matter not directly related to the phpBB.com website or the discrete software of phpBB itself. If you do email phpBB Group about any third party use of this software then you should expect a terse response or no response at all.' ) ); diff --git a/phpBB/language/en/install.php b/phpBB/language/en/install.php index ca6045a921..03f2e964ec 100644 --- a/phpBB/language/en/install.php +++ b/phpBB/language/en/install.php @@ -240,8 +240,8 @@ $lang = array_merge($lang, array( 'INST_ERR_DB_NO_FIREBIRD_PS'=> 'The database you selected for Firebird has a page size less than 8192, it must be at least 8192.', 'INST_ERR_DB_NO_POSTGRES' => 'The database you have selected was not created in UNICODE or UTF8 encoding. Try installing with a database in UNICODE or UTF8 encoding.', 'INST_ERR_DB_NO_NAME' => 'No database name specified.', - 'INST_ERR_EMAIL_INVALID' => 'The e-mail address you entered is invalid.', - 'INST_ERR_EMAIL_MISMATCH' => 'The e-mails you entered did not match.', + 'INST_ERR_EMAIL_INVALID' => 'The email address you entered is invalid.', + 'INST_ERR_EMAIL_MISMATCH' => 'The emails you entered did not match.', 'INST_ERR_FATAL' => 'Fatal installation error', 'INST_ERR_FATAL_DB' => 'A fatal and unrecoverable database error has occurred. This may be because the specified user does not have appropriate permissions to CREATE TABLES or INSERT data, etc. Further information may be given below. Please contact your hosting provider in the first instance or the support forums of phpBB for further assistance.', 'INST_ERR_FTP_PATH' => 'Could not change to the given directory, please check the path.', diff --git a/phpBB/language/en/mcp.php b/phpBB/language/en/mcp.php index 3ee619ea16..eaa2d7e3a5 100644 --- a/phpBB/language/en/mcp.php +++ b/phpBB/language/en/mcp.php @@ -144,7 +144,7 @@ $lang = array_merge($lang, array( 'MCP_ADD' => 'Add a warning', 'MCP_BAN' => 'Banning', - 'MCP_BAN_EMAILS' => 'Ban e-mails', + 'MCP_BAN_EMAILS' => 'Ban emails', 'MCP_BAN_IPS' => 'Ban IPs', 'MCP_BAN_USERNAMES' => 'Ban Usernames', diff --git a/phpBB/language/en/memberlist.php b/phpBB/language/en/memberlist.php index c3ab27871e..cdbedebefc 100644 --- a/phpBB/language/en/memberlist.php +++ b/phpBB/language/en/memberlist.php @@ -46,25 +46,25 @@ $lang = array_merge($lang, array( 'BEFORE' => 'Before', - 'CC_EMAIL' => 'Send a copy of this e-mail to yourself.', + 'CC_EMAIL' => 'Send a copy of this email to yourself.', 'CONTACT_USER' => 'Contact', 'DEST_LANG' => 'Language', 'DEST_LANG_EXPLAIN' => 'Select an appropriate language (if available) for the recipient of this message.', - 'EMAIL_BODY_EXPLAIN' => 'This message will be sent as plain text, do not include any HTML or BBCode. The return address for this message will be set to your e-mail address.', - 'EMAIL_DISABLED' => 'Sorry but all e-mail related functions have been disabled.', - 'EMAIL_SENT' => 'The e-mail has been sent.', - 'EMAIL_TOPIC_EXPLAIN' => 'This message will be sent as plain text, do not include any HTML or BBCode. Please note that the topic information is already included in the message. The return address for this message will be set to your e-mail address.', - 'EMPTY_ADDRESS_EMAIL' => 'You must provide a valid e-mail address for the recipient.', + 'EMAIL_BODY_EXPLAIN' => 'This message will be sent as plain text, do not include any HTML or BBCode. The return address for this message will be set to your email address.', + 'EMAIL_DISABLED' => 'Sorry but all email related functions have been disabled.', + 'EMAIL_SENT' => 'The email has been sent.', + 'EMAIL_TOPIC_EXPLAIN' => 'This message will be sent as plain text, do not include any HTML or BBCode. Please note that the topic information is already included in the message. The return address for this message will be set to your email address.', + 'EMPTY_ADDRESS_EMAIL' => 'You must provide a valid email address for the recipient.', 'EMPTY_MESSAGE_EMAIL' => 'You must enter a message to be emailed.', 'EMPTY_MESSAGE_IM' => 'You must enter a message to be send.', 'EMPTY_NAME_EMAIL' => 'You must enter the real name of the recipient.', - 'EMPTY_SUBJECT_EMAIL' => 'You must specify a subject for the e-mail.', + 'EMPTY_SUBJECT_EMAIL' => 'You must specify a subject for the email.', 'EQUAL_TO' => 'Equal to', 'FIND_USERNAME_EXPLAIN' => 'Use this form to search for specific members. You do not need to fill out all fields. To match partial data use * as a wildcard. When entering dates use the format YYYY-MM-DD, e.g. 2004-02-29. Use the mark checkboxes to select one or more usernames (several usernames may be accepted depending on the form itself) and click the Select Marked button to return to the previous form.', - 'FLOOD_EMAIL_LIMIT' => 'You cannot send another e-mail at this time. Please try again later.', + 'FLOOD_EMAIL_LIMIT' => 'You cannot send another email at this time. Please try again later.', 'GROUP_LEADER' => 'Group leader', @@ -103,7 +103,7 @@ $lang = array_merge($lang, array( 'MORE_THAN' => 'More than', - 'NO_EMAIL' => 'You are not permitted to send e-mail to this user.', + 'NO_EMAIL' => 'You are not permitted to send email to this user.', 'NO_VIEW_USERS' => 'You are not authorised to view the member list or profiles.', 'ORDER' => 'Order', @@ -126,7 +126,7 @@ $lang = array_merge($lang, array( 'SEND_MESSAGE' => 'Message', 'SEND_MSNM_MESSAGE' => 'Send WLM message', 'SEND_YIM_MESSAGE' => 'Send YIM message', - 'SORT_EMAIL' => 'E-mail', + 'SORT_EMAIL' => 'Email', 'SORT_LAST_ACTIVE' => 'Last active', 'SORT_POST_COUNT' => 'Post count', diff --git a/phpBB/language/en/ucp.php b/phpBB/language/en/ucp.php index aa1e9c27ce..2212e44628 100644 --- a/phpBB/language/en/ucp.php +++ b/phpBB/language/en/ucp.php @@ -49,9 +49,9 @@ $lang = array_merge($lang, array(
    We may also create cookies external to the phpBB software whilst browsing “%1$s”, though these are outside the scope of this document which is intended to only cover the pages created by the phpBB software. The second way in which we collect your information is by what you submit to us. This can be, and is not limited to: posting as an anonymous user (hereinafter “anonymous posts”), registering on “%1$s” (hereinafter “your account”) and posts submitted by you after registration and whilst logged in (hereinafter “your posts”).

    - Your account will at a bare minimum contain a uniquely identifiable name (hereinafter “your user name”), a personal password used for logging into your account (hereinafter “your password”) and a personal, valid e-mail address (hereinafter “your e-mail”). Your information for your account at “%1$s” is protected by data-protection laws applicable in the country that hosts us. Any information beyond your user name, your password, and your e-mail address required by “%1$s” during the registration process is either mandatory or optional, at the discretion of “%1$s”. In all cases, you have the option of what information in your account is publicly displayed. Furthermore, within your account, you have the option to opt-in or opt-out of automatically generated e-mails from the phpBB software.
    + Your account will at a bare minimum contain a uniquely identifiable name (hereinafter “your user name”), a personal password used for logging into your account (hereinafter “your password”) and a personal, valid email address (hereinafter “your email”). Your information for your account at “%1$s” is protected by data-protection laws applicable in the country that hosts us. Any information beyond your user name, your password, and your email address required by “%1$s” during the registration process is either mandatory or optional, at the discretion of “%1$s”. In all cases, you have the option of what information in your account is publicly displayed. Furthermore, within your account, you have the option to opt-in or opt-out of automatically generated emails from the phpBB software.

    - Your password is ciphered (a one-way hash) so that it is secure. However, it is recommended that you do not reuse the same password across a number of different websites. Your password is the means of accessing your account at “%1$s”, so please guard it carefully and under no circumstance will anyone affiliated with “%1$s”, phpBB or another 3rd party, legitimately ask you for your password. Should you forget your password for your account, you can use the “I forgot my password” feature provided by the phpBB software. This process will ask you to submit your user name and your e-mail, then the phpBB software will generate a new password to reclaim your account.
    + Your password is ciphered (a one-way hash) so that it is secure. However, it is recommended that you do not reuse the same password across a number of different websites. Your password is the means of accessing your account at “%1$s”, so please guard it carefully and under no circumstance will anyone affiliated with “%1$s”, phpBB or another 3rd party, legitimately ask you for your password. Should you forget your password for your account, you can use the “I forgot my password” feature provided by the phpBB software. This process will ask you to submit your user name and your email, then the phpBB software will generate a new password to reclaim your account.
    ', )); @@ -61,13 +61,13 @@ $lang = array_merge($lang, array( 'ACCOUNT_ACTIVE_ADMIN' => 'The account has now been activated.', 'ACCOUNT_ACTIVE_PROFILE' => 'Your account has now been successfully reactivated.', 'ACCOUNT_ADDED' => 'Thank you for registering, your account has been created. You may now login with your username and password.', - 'ACCOUNT_COPPA' => 'Your account has been created but has to be approved, please check your e-mail for details.', - 'ACCOUNT_EMAIL_CHANGED' => 'Your account has been updated. However, this board requires account reactivation on e-mail changes. An activation key has been sent to the new e-mail address you provided. Please check your e-mail for further information.', - 'ACCOUNT_EMAIL_CHANGED_ADMIN' => 'Your account has been updated. However, this board requires account reactivation by the administrators on e-mail changes. An e-mail has been sent to them and you will be informed when your account has been reactivated.', - 'ACCOUNT_INACTIVE' => 'Your account has been created. However, this board requires account activation, an activation key has been sent to the e-mail address you provided. Please check your e-mail for further information.', - 'ACCOUNT_INACTIVE_ADMIN' => 'Your account has been created. However, this board requires account activation by the administrator group. An e-mail has been sent to them and you will be informed when your account has been activated.', - 'ACTIVATION_EMAIL_SENT' => 'The activation e-mail has been sent to your e-mail address.', - 'ACTIVATION_EMAIL_SENT_ADMIN' => 'The activation e-mail has been sent to the administrators e-mail addresses.', + 'ACCOUNT_COPPA' => 'Your account has been created but has to be approved, please check your email for details.', + 'ACCOUNT_EMAIL_CHANGED' => 'Your account has been updated. However, this board requires account reactivation on email changes. An activation key has been sent to the new email address you provided. Please check your email for further information.', + 'ACCOUNT_EMAIL_CHANGED_ADMIN' => 'Your account has been updated. However, this board requires account reactivation by the administrators on email changes. An email has been sent to them and you will be informed when your account has been reactivated.', + 'ACCOUNT_INACTIVE' => 'Your account has been created. However, this board requires account activation, an activation key has been sent to the email address you provided. Please check your email for further information.', + 'ACCOUNT_INACTIVE_ADMIN' => 'Your account has been created. However, this board requires account activation by the administrator group. An email has been sent to them and you will be informed when your account has been activated.', + 'ACTIVATION_EMAIL_SENT' => 'The activation email has been sent to your email address.', + 'ACTIVATION_EMAIL_SENT_ADMIN' => 'The activation email has been sent to the administrators email addresses.', 'ADD' => 'Add', 'ADD_BCC' => 'Add [BCC]', 'ADD_FOES' => 'Add new foes', @@ -79,7 +79,7 @@ $lang = array_merge($lang, array( 'ADD_RULE' => 'Add rule', 'ADD_TO' => 'Add [To]', 'ADD_USERS_UCP_EXPLAIN' => 'Here you can add new users to the group. You may select whether this group becomes the new default for the selected users. Please enter each username on a separate line.', - 'ADMIN_EMAIL' => 'Administrators can e-mail me information', + 'ADMIN_EMAIL' => 'Administrators can email me information', 'AGREE' => 'I agree to these terms', 'ALLOW_PM' => 'Allow users to send you private messages', 'ALLOW_PM_EXPLAIN' => 'Note that administrators and moderators will always be able to send you messages.', @@ -134,7 +134,7 @@ $lang = array_merge($lang, array( 'CREATE_FOLDER' => 'Add folder…', 'CURRENT_IMAGE' => 'Current image', 'CURRENT_PASSWORD' => 'Current password', - 'CURRENT_PASSWORD_EXPLAIN' => 'You must confirm your current password if you wish to change it, alter your e-mail address or username.', + 'CURRENT_PASSWORD_EXPLAIN' => 'You must confirm your current password if you wish to change it, alter your email address or username.', 'CUR_PASSWORD_EMPTY' => 'You did not enter your current password.', 'CUR_PASSWORD_ERROR' => 'The current password you entered is incorrect.', 'CUSTOM_DATEFORMAT' => 'Custom…', @@ -164,17 +164,17 @@ $lang = array_merge($lang, array( 'DEMOTE_SELECTED' => 'Demote selected', 'DISABLE_CENSORS' => 'Enable word censoring', 'DISPLAY_GALLERY' => 'Display gallery', - 'DOMAIN_NO_MX_RECORD_EMAIL' => 'The entered e-mail domain has no valid MX record.', + 'DOMAIN_NO_MX_RECORD_EMAIL' => 'The entered email domain has no valid MX record.', 'DOWNLOADS' => 'Downloads', 'DRAFTS_DELETED' => 'All selected drafts were successfully deleted.', 'DRAFTS_EXPLAIN' => 'Here you can view, edit and delete your saved drafts.', 'DRAFT_UPDATED' => 'Draft successfully updated.', 'EDIT_DRAFT_EXPLAIN' => 'Here you are able to edit your draft. Drafts do not contain attachment and poll information.', - 'EMAIL_BANNED_EMAIL' => 'The e-mail address you entered is not allowed to be used.', - 'EMAIL_INVALID_EMAIL' => 'The e-mail address you entered is invalid.', - 'EMAIL_REMIND' => 'This must be the e-mail address associated with your account. If you have not changed this via your user control panel then it is the e-mail address you registered your account with.', - 'EMAIL_TAKEN_EMAIL' => 'The entered e-mail address is already in use.', + 'EMAIL_BANNED_EMAIL' => 'The email address you entered is not allowed to be used.', + 'EMAIL_INVALID_EMAIL' => 'The email address you entered is invalid.', + 'EMAIL_REMIND' => 'This must be the email address associated with your account. If you have not changed this via your user control panel then it is the email address you registered your account with.', + 'EMAIL_TAKEN_EMAIL' => 'The entered email address is already in use.', 'EMPTY_DRAFT' => 'You must enter a message to submit your changes.', 'EMPTY_DRAFT_TITLE' => 'You must enter a draft title.', 'EXPORT_AS_XML' => 'Export as XML', @@ -286,7 +286,7 @@ $lang = array_merge($lang, array( 'NEW_PASSWORD_ERROR' => 'The passwords you entered do not match.', 'NOTIFY_METHOD' => 'Notification method', 'NOTIFY_METHOD_BOTH' => 'Both', - 'NOTIFY_METHOD_EMAIL' => 'E-mail only', + 'NOTIFY_METHOD_EMAIL' => 'Email only', 'NOTIFY_METHOD_EXPLAIN' => 'Method for sending messages sent via this board.', 'NOTIFY_METHOD_IM' => 'Jabber only', 'NOTIFY_ON_PM' => 'Notify me on new private messages', @@ -324,7 +324,7 @@ $lang = array_merge($lang, array( 'NO_BOOKMARKS' => 'You have no bookmarks.', 'NO_BOOKMARKS_SELECTED' => 'You have selected no bookmarks.', 'NO_EDIT_READ_MESSAGE' => 'Private message cannot be edited because it has already been read.', - 'NO_EMAIL_USER' => 'The e-mail/username information submitted could not be found.', + 'NO_EMAIL_USER' => 'The email/username information submitted could not be found.', 'NO_FOES' => 'No foes currently defined', 'NO_FRIENDS' => 'No friends currently defined', 'NO_FRIENDS_OFFLINE' => 'No friends offline', @@ -350,7 +350,7 @@ $lang = array_merge($lang, array( 'PASS_TYPE_SYMBOL_EXPLAIN' => 'Password must be between %1$s and %2$s long, must contain letters in mixed case, must contain numbers and must contain symbols.', 'PASSWORD' => 'Password', 'PASSWORD_ACTIVATED' => 'Your new password has been activated.', - 'PASSWORD_UPDATED' => 'A new password was sent to your registered e-mail address.', + 'PASSWORD_UPDATED' => 'A new password was sent to your registered email address.', 'PERMISSIONS_RESTORED' => 'Successfully restored original permissions.', 'PERMISSIONS_TRANSFERRED' => 'Successfully transferred permissions from %s, you are now able to browse the board with this user’s permissions.
    Please note that admin permissions were not transferred. You are able to revert to your permission set at any time.', 'PM_DISABLED' => 'Private messaging has been disabled on this board.', @@ -408,7 +408,7 @@ $lang = array_merge($lang, array( 'SEARCH_YOUR_POSTS' => 'Show your posts', 'SEND_PASSWORD' => 'Send password', 'SENT_AT' => 'Sent', // Used before dates in private messages - 'SHOW_EMAIL' => 'Users can contact me by e-mail', + 'SHOW_EMAIL' => 'Users can contact me by email', 'SIGNATURE_EXPLAIN' => 'This is a block of text that can be added to posts you make. There is a %d character limit.', 'SIGNATURE_PREVIEW' => 'Your signature will appear like this in posts', 'SIGNATURE_TOO_LONG' => 'Your signature is too long.', @@ -427,12 +427,12 @@ $lang = array_merge($lang, array( 'UCP' => 'User Control Panel', 'UCP_ACTIVATE' => 'Activate account', - 'UCP_ADMIN_ACTIVATE' => 'Please note that you will need to enter a valid e-mail address before your account is activated. The administrator will review your account and if approved you will receive an e-mail at the address you specified.', + 'UCP_ADMIN_ACTIVATE' => 'Please note that you will need to enter a valid email address before your account is activated. The administrator will review your account and if approved you will receive an email at the address you specified.', 'UCP_AIM' => 'AOL Instant Messenger', 'UCP_ATTACHMENTS' => 'Attachments', 'UCP_COPPA_BEFORE' => 'Before %s', 'UCP_COPPA_ON_AFTER' => 'On or after %s', - 'UCP_EMAIL_ACTIVATE' => 'Please note that you will need to enter a valid e-mail address before your account is activated. You will receive an e-mail at the address you provide that contains an account activation link.', + 'UCP_EMAIL_ACTIVATE' => 'Please note that you will need to enter a valid email address before your account is activated. You will receive an email at the address you provide that contains an account activation link.', 'UCP_ICQ' => 'ICQ number', 'UCP_JABBER' => 'Jabber address', @@ -472,7 +472,7 @@ $lang = array_merge($lang, array( 'UCP_REGISTER_DISABLE' => 'Creating a new account is currently not possible.', 'UCP_REMIND' => 'Send password', - 'UCP_RESEND' => 'Send activation e-mail', + 'UCP_RESEND' => 'Send activation email', 'UCP_WELCOME' => 'Welcome to the User Control Panel. From here you can monitor, view and update your profile, preferences, subscribed forums and topics. You can also send messages to other users (if permitted). Please ensure you read any announcements before continuing.', 'UCP_YIM' => 'Yahoo Messenger', 'UCP_ZEBRA' => 'Friends & Foes', diff --git a/phpBB/language/en/viewtopic.php b/phpBB/language/en/viewtopic.php index 184f88ed3c..278c064fe7 100644 --- a/phpBB/language/en/viewtopic.php +++ b/phpBB/language/en/viewtopic.php @@ -57,13 +57,13 @@ $lang = array_merge($lang, array( 1 => 'Last edited by %2$s on %3$s, edited %1$d time in total.', 2 => 'Last edited by %2$s on %3$s, edited %1$d times in total.', ), - 'EMAIL_TOPIC' => 'E-mail friend', + 'EMAIL_TOPIC' => 'Email friend', 'ERROR_NO_ATTACHMENT' => 'The selected attachment does not exist anymore.', 'FILE_NOT_FOUND_404' => 'The file %s does not exist.', 'FORK_TOPIC' => 'Copy topic', 'FULL_EDITOR' => 'Full Editor & Preview', - + 'LINKAGE_FORBIDDEN' => 'You are not authorised to view, download or link from/to this site.', 'LOGIN_NOTIFY_TOPIC' => 'You have been notified about this topic, please login to view it.', 'LOGIN_VIEWTOPIC' => 'The board requires you to be registered and logged in to view this topic.', From 249d8ede1261f6736a1d245ad204bc2bca544945 Mon Sep 17 00:00:00 2001 From: Dhruv Goel Date: Mon, 16 Apr 2012 01:24:10 +0530 Subject: [PATCH 105/441] [ticket/10797] user rank is displayed in mcp_warn.php When warning a user in MCP, the user's rank title and image are displayed. language key user rank also added. PHPBB3-10797 --- phpBB/includes/mcp/mcp_warn.php | 4 ++-- phpBB/language/en/mcp.php | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/phpBB/includes/mcp/mcp_warn.php b/phpBB/includes/mcp/mcp_warn.php index 63e5b19155..1016204ff8 100644 --- a/phpBB/includes/mcp/mcp_warn.php +++ b/phpBB/includes/mcp/mcp_warn.php @@ -308,7 +308,7 @@ class mcp_warn include($phpbb_root_path . 'includes/functions_display.' . $phpEx); } - $rank_title = $rank_img = ''; + get_user_rank($user_row['user_rank'], $user_row['user_posts'], $rank_title, $rank_img, $rank_img_src); $avatar_img = get_user_avatar($user_row['user_avatar'], $user_row['user_avatar_type'], $user_row['user_avatar_width'], $user_row['user_avatar_height']); $template->assign_vars(array( @@ -413,7 +413,7 @@ class mcp_warn include($phpbb_root_path . 'includes/functions_display.' . $phpEx); } - $rank_title = $rank_img = ''; + get_user_rank($user_row['user_rank'], $user_row['user_posts'], $rank_title, $rank_img, $rank_img_src); $avatar_img = get_user_avatar($user_row['user_avatar'], $user_row['user_avatar_type'], $user_row['user_avatar_width'], $user_row['user_avatar_height']); // OK, they didn't submit a warning so lets build the page for them to do so diff --git a/phpBB/language/en/mcp.php b/phpBB/language/en/mcp.php index d0bcec0d9c..16b55b3612 100644 --- a/phpBB/language/en/mcp.php +++ b/phpBB/language/en/mcp.php @@ -274,6 +274,7 @@ $lang = array_merge($lang, array( 'POST_REPORTED_SUCCESS' => 'This post has been successfully reported.', 'POST_UNLOCKED_SUCCESS' => 'Post unlocked successfully.', + 'RANK' => 'User rank', 'READ_USERNOTES' => 'User notes', 'READ_WARNINGS' => 'User warnings', 'REPORTER' => 'Reporter', From 7a6d3ec61bff708fa1ebc60765c91af0a5648fc9 Mon Sep 17 00:00:00 2001 From: Patrick Webster Date: Sun, 15 Apr 2012 23:33:34 -0500 Subject: [PATCH 106/441] [ticket/10819] Improve side-by-side diff styling Used transparent background for unchanged lines Shortened the table headers and make the background grey Added a border between the columns Increased the font size on pre blocks Added Consolas as the first pre font, for Windows users Added wordwrapping for pre blocks PHPBB3-10819 --- phpBB/adm/style/install_update_diff.html | 27 ++++++++++++------------ 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/phpBB/adm/style/install_update_diff.html b/phpBB/adm/style/install_update_diff.html index b65a014312..96bf2532b1 100644 --- a/phpBB/adm/style/install_update_diff.html +++ b/phpBB/adm/style/install_update_diff.html @@ -119,6 +119,7 @@ table.hrdiff { overflow: hidden; border-bottom: 1px solid #999; table-layout: fixed; + background: transparent; } table.hrdiff th { @@ -128,7 +129,8 @@ table.hrdiff th { font-family: Verdana,Helvetica,sans-serif; font-size: 11px; border-bottom: 1px solid #999; - background: transparent; + border-right: 1px solid #999; + background: #D9D9D9; } table.hrdiff thead th { @@ -142,29 +144,28 @@ table.hrdiff tr:first-child th { } table.hrdiff tbody th { - padding: 2em 1px 1px 1px; font-size: 80%; border-top: 1px solid #999; } -table.hrdiff tbody td.old { - border-left: 1px solid #999; - border-right: 1px solid #999; -} -table.hrdiff tbody td.new { +table.hrdiff tbody td { border-right: 1px solid #999; } +/* Variant of http://www.longren.org/wrapping-text-inside-pre-tags/ */ table.hrdiff td pre { - overflow: auto; - display: block; - width: 100%; - overflow: auto; - display: block; + font-family: "Consolas", monospace; + font-size: 1.1em; + overflow-x: auto; /* Use horizontal scroller if needed; for Firefox 2, not needed in Firefox 3 */ + white-space: pre-wrap; /* css-3 */ + white-space: -moz-pre-wrap !important; /* Mozilla, since 1999 */ + white-space: -pre-wrap; /* Opera 4-6 */ + white-space: -o-pre-wrap; /* Opera 7 */ + word-wrap: break-word; /* Internet Explorer 5.5+ */ } table.hrdiff .unmodified { - background: #fff; + background: transparent; } table.hrdiff .added { From 09621342a54525e9dfcd3419b91d39e13ee7a326 Mon Sep 17 00:00:00 2001 From: Patrick Webster Date: Sun, 15 Apr 2012 23:38:12 -0500 Subject: [PATCH 107/441] [ticket/10819] Forgot this causes vertical scrollbars on IE PHPBB3-10819 --- phpBB/adm/style/install_update_diff.html | 1 - 1 file changed, 1 deletion(-) diff --git a/phpBB/adm/style/install_update_diff.html b/phpBB/adm/style/install_update_diff.html index 96bf2532b1..e57d19161d 100644 --- a/phpBB/adm/style/install_update_diff.html +++ b/phpBB/adm/style/install_update_diff.html @@ -156,7 +156,6 @@ table.hrdiff tbody td { table.hrdiff td pre { font-family: "Consolas", monospace; font-size: 1.1em; - overflow-x: auto; /* Use horizontal scroller if needed; for Firefox 2, not needed in Firefox 3 */ white-space: pre-wrap; /* css-3 */ white-space: -moz-pre-wrap !important; /* Mozilla, since 1999 */ white-space: -pre-wrap; /* Opera 4-6 */ From bdf21e45caadd74c7f4c41d6e1bf4737d9300cf4 Mon Sep 17 00:00:00 2001 From: Oleg Pudeyev Date: Mon, 16 Apr 2012 03:04:29 -0400 Subject: [PATCH 108/441] [ticket/10767] Revert unconditional unfatality in commit-msg hook. Revert "[ticket/10093] Make commit-msg always not fatal by nuking all fatal logic." This reverts commit 88cad5523e7cdac6826dd8581e27e22a65afda26. PHPBB3-10093 PHPBB3-10767 --- git-tools/hooks/commit-msg | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/git-tools/hooks/commit-msg b/git-tools/hooks/commit-msg index 52969670ca..3c42411602 100755 --- a/git-tools/hooks/commit-msg +++ b/git-tools/hooks/commit-msg @@ -12,6 +12,11 @@ # ln -s ../../git-tools/hooks/commit-msg \\ # .git/hooks/commit-msg # +# You can configure whether invalid commit messages abort commits: +# +# git config phpbb.hooks.commit-msg.fatal true (abort, this is the default) +# git config phpbb.hooks.commit-msg.fatal false (warn only, do not abort) +# # Warning/error messages use color by default if the output is a terminal # ("output" here is normally standard error when you run git commit). # To force or disable the use of color: @@ -21,6 +26,13 @@ config_ns="phpbb.hooks.commit-msg"; +if [ "$(git config --bool $config_ns.fatal)" = "false" ] +then + fatal=0; +else + fatal=1; +fi + debug_level=$(git config --int $config_ns.debug || echo 0); # Error codes @@ -47,9 +59,12 @@ debug() quit() { - # Now we always exit with success, since git will trash - # entered commit message if commit-msg hook exits with a failure. - exit 0 + if [ $1 -gt 0 ] && [ $1 -ne $ERR_UNKNOWN ] && [ $fatal -eq 0 ] + then + exit 0; + else + exit $1; + fi } use_color() From 1ce8a1d7ee1f361278358f5b2b3e15b449d2a8aa Mon Sep 17 00:00:00 2001 From: Oleg Pudeyev Date: Tue, 17 Apr 2012 05:49:59 -0400 Subject: [PATCH 109/441] [ticket/10767] Default to non-fatal behavior. PHPBB3-10767 --- git-tools/hooks/commit-msg | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/git-tools/hooks/commit-msg b/git-tools/hooks/commit-msg index 3c42411602..4c9e56f555 100755 --- a/git-tools/hooks/commit-msg +++ b/git-tools/hooks/commit-msg @@ -14,9 +14,11 @@ # # You can configure whether invalid commit messages abort commits: # -# git config phpbb.hooks.commit-msg.fatal true (abort, this is the default) +# git config phpbb.hooks.commit-msg.fatal true (abort) # git config phpbb.hooks.commit-msg.fatal false (warn only, do not abort) # +# The default is to warn only. +# # Warning/error messages use color by default if the output is a terminal # ("output" here is normally standard error when you run git commit). # To force or disable the use of color: @@ -26,11 +28,11 @@ config_ns="phpbb.hooks.commit-msg"; -if [ "$(git config --bool $config_ns.fatal)" = "false" ] +if [ "$(git config --bool $config_ns.fatal)" = "true" ] then - fatal=0; -else fatal=1; +else + fatal=0; fi debug_level=$(git config --int $config_ns.debug || echo 0); From 45b910f9b445dc50cf65e456d8fe6f3aae2cbc11 Mon Sep 17 00:00:00 2001 From: Oleg Pudeyev Date: Tue, 17 Apr 2012 05:56:09 -0400 Subject: [PATCH 110/441] [ticket/10767] Use warning/error language as appropriate. When commit-msg hook is fatal, label the message as an error. When it is not fatal, label the message as a warning. "Syntax error" is still always an error, not sure if this should be changed. PHPBB3-10767 --- git-tools/hooks/commit-msg | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/git-tools/hooks/commit-msg b/git-tools/hooks/commit-msg index 4c9e56f555..fbeda805b7 100755 --- a/git-tools/hooks/commit-msg +++ b/git-tools/hooks/commit-msg @@ -31,8 +31,10 @@ config_ns="phpbb.hooks.commit-msg"; if [ "$(git config --bool $config_ns.fatal)" = "true" ] then fatal=1; + severity=Error; else fatal=0; + severity=Warning; fi debug_level=$(git config --int $config_ns.debug || echo 0); @@ -187,7 +189,7 @@ do # Don't be too strict. # Commits may be temporary, intended to be squashed later. # Just issue a warning here. - complain "Warning: heading should be a sentence beginning with a capital letter." 1>&2 + complain "$severity: heading should be a sentence beginning with a capital letter." 1>&2 complain "You entered:" 1>&2 complain "$line" 1>&2 fi From aceca2566b80753d79c1dc77f5470618b0a2078d Mon Sep 17 00:00:00 2001 From: Oleg Pudeyev Date: Tue, 17 Apr 2012 05:59:35 -0400 Subject: [PATCH 111/441] [ticket/10767] Clarify what happens at the end of the hook. If there are problems and fatal is true, print that the commit is aborted. If there are problems and fatal is false, print instructions for fixing the commit. PHPBB3-10767 --- git-tools/hooks/commit-msg | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/git-tools/hooks/commit-msg b/git-tools/hooks/commit-msg index fbeda805b7..b156d276df 100755 --- a/git-tools/hooks/commit-msg +++ b/git-tools/hooks/commit-msg @@ -63,10 +63,17 @@ debug() quit() { - if [ $1 -gt 0 ] && [ $1 -ne $ERR_UNKNOWN ] && [ $fatal -eq 0 ] + if [ $1 -eq 0 ] || [ $1 -eq $ERR_UNKNOWN ] then + # success + exit 0; + elif [ $fatal -eq 0 ] + then + # problems found but fatal is false + complain 'Please run `git commit --amend` and fix the problems mentioned.' 1>&2 exit 0; else + complain "Aborting commit." 1>&2 exit $1; fi } From 00c54f8a7cad92eff14fe62530766666c2c796a7 Mon Sep 17 00:00:00 2001 From: Patrick Webster Date: Tue, 17 Apr 2012 22:59:10 -0500 Subject: [PATCH 112/441] [ticket/10819] Remove support for older browsers PHPBB3-10819 --- phpBB/adm/style/install_update_diff.html | 4 ---- 1 file changed, 4 deletions(-) diff --git a/phpBB/adm/style/install_update_diff.html b/phpBB/adm/style/install_update_diff.html index e57d19161d..4d8bcfd1fc 100644 --- a/phpBB/adm/style/install_update_diff.html +++ b/phpBB/adm/style/install_update_diff.html @@ -152,14 +152,10 @@ table.hrdiff tbody td { border-right: 1px solid #999; } -/* Variant of http://www.longren.org/wrapping-text-inside-pre-tags/ */ table.hrdiff td pre { font-family: "Consolas", monospace; font-size: 1.1em; white-space: pre-wrap; /* css-3 */ - white-space: -moz-pre-wrap !important; /* Mozilla, since 1999 */ - white-space: -pre-wrap; /* Opera 4-6 */ - white-space: -o-pre-wrap; /* Opera 7 */ word-wrap: break-word; /* Internet Explorer 5.5+ */ } From b3e42635ca201eea2fa82fb057f021768daf6786 Mon Sep 17 00:00:00 2001 From: Vjacheslav Trushkin Date: Tue, 10 Apr 2012 22:41:59 +0300 Subject: [PATCH 113/441] [ticket/10759] Fixing style in database updater Fixing error in database updater caused by style components merge PHPBB3-10759 --- phpBB/install/database_update.php | 155 ++++++++++++++++++++++++------ 1 file changed, 127 insertions(+), 28 deletions(-) diff --git a/phpBB/install/database_update.php b/phpBB/install/database_update.php index 5368ec06bb..0b33168496 100644 --- a/phpBB/install/database_update.php +++ b/phpBB/install/database_update.php @@ -1110,20 +1110,6 @@ function database_update_info() 'group_legend' => array('UINT', 0), ), ), - 'drop_columns' => array( - STYLES_TABLE => array( - 'imageset_id', - 'template_id', - 'theme_id', - ), - ), - 'drop_tables' => array( - STYLES_IMAGESET_TABLE, - STYLES_IMAGESET_DATA_TABLE, - STYLES_TEMPLATE_TABLE, - STYLES_TEMPLATE_DATA_TABLE, - STYLES_THEME_TABLE, - ), ), ); } @@ -1135,7 +1121,7 @@ function database_update_info() *****************************************************************************/ function change_database_data(&$no_updates, $version) { - global $db, $errored, $error_ary, $config, $phpbb_root_path, $phpEx; + global $db, $errored, $error_ary, $config, $phpbb_root_path, $phpEx, $db_tools; switch ($version) { @@ -2312,13 +2298,6 @@ function change_database_data(&$no_updates, $version) 'auth' => 'acl_a_styles', 'cat' => 'ACP_STYLE_MANAGEMENT', ), - 'edit' => array( - 'base' => 'acp_styles', - 'class' => 'acp', - 'title' => 'ACP_STYLES_EDIT', - 'auth' => 'acl_a_styles', - 'cat' => 'ACP_STYLE_MANAGEMENT', - ), 'cache' => array( 'base' => 'acp_styles', 'class' => 'acp', @@ -2421,13 +2400,133 @@ function change_database_data(&$no_updates, $version) { set_config('teampage_memberships', '1'); } - - // Clear styles table and add prosilver entry - _sql('DELETE FROM ' . STYLES_TABLE, $errored, $error_ary); - $sql = 'INSERT INTO ' . STYLES_TABLE . " (style_name, style_copyright, style_active, style_path, bbcode_bitfield, style_parent_id, style_parent_tree) VALUES ('prosilver', '© phpBB Group', 1, 'prosilver', 'kNg=', 0, '')"; - _sql($sql, $errored, $error_ary); - + // Check if styles table was already updated + if ($db_tools->sql_table_exists(STYLES_THEME_TABLE)) + { + // Get list of valid installed styles + $available_styles = array('prosilver'); + + $iterator = new DirectoryIterator($phpbb_root_path . 'styles'); + $skip_dirs = array('.', '..', 'prosilver'); + foreach ($iterator as $fileinfo) + { + if ($fileinfo->isDir() && !in_array($fileinfo->getFilename(), $skip_dirs) && file_exists($fileinfo->getPathname() . '/style.cfg')) + { + $style_cfg = parse_cfg_file($fileinfo->getPathname() . '/style.cfg'); + if (isset($style_cfg['phpbb_version']) && version_compare($style_cfg['phpbb_version'], '3.1.0-dev', '>=')) + { + // 3.1 style + $available_styles[] = $fileinfo->getFilename(); + } + } + } + + // Get all installed styles + if ($db_tools->sql_table_exists(STYLES_IMAGESET_TABLE)) + { + $sql = 'SELECT s.style_id, t.template_path, t.template_id, t.bbcode_bitfield, t.template_inherits_id, t.template_inherit_path, c.theme_path, c.theme_id, i.imageset_path, i.imageset_id + FROM ' . STYLES_TABLE . ' s, ' . STYLES_TEMPLATE_TABLE . ' t, ' . STYLES_THEME_TABLE . ' c, ' . STYLES_IMAGESET_TABLE . " i + WHERE t.template_id = s.template_id + AND c.theme_id = s.theme_id + AND i.imageset_id = s.imageset_id"; + } + else + { + $sql = 'SELECT s.style_id, t.template_path, t.template_id, t.bbcode_bitfield, t.template_inherits_id, t.template_inherit_path, c.theme_path, c.theme_id + FROM ' . STYLES_TABLE . ' s, ' . STYLES_TEMPLATE_TABLE . ' t, ' . STYLES_THEME_TABLE . " c + WHERE t.template_id = s.template_id + AND c.theme_id = s.theme_id"; + } + $result = $db->sql_query($sql); + + $styles = array(); + while ($row = $db->sql_fetchrow($result)) + { + $styles[] = $row; + } + $db->sql_freeresult($result); + + // Check each style + $valid_styles = array(); + foreach ($styles as $style_row) + { + if ( + // Ignore styles with parent style + $style_row['template_inherits_id'] == 0 && + // Check if components match + $style_row['template_path'] == $style_row['theme_path'] && (!isset($style_row['imageset_path']) || $style_row['template_path'] == $style_row['imageset_path']) && + // Check if components are valid + in_array($style_row['template_path'], $available_styles) + ) + { + // Valid style. Keep it + $sql_ary = array( + 'style_path' => $style_row['template_path'], + 'bbcode_bitfield' => $style_row['bbcode_bitfield'], + 'style_parent_id' => 0, + 'style_parent_tree' => '', + ); + _sql('UPDATE ' . STYLES_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . ' WHERE style_id = ' . $style_row['style_id'], $errored, $error_ary); + $valid_styles[] = $style_row['style_id']; + } + } + + // Remove old styles tables + $changes = array( + 'drop_columns' => array( + STYLES_TABLE => array( + 'imageset_id', + 'template_id', + 'theme_id', + ), + ), + + 'drop_tables' => array( + STYLES_IMAGESET_TABLE, + STYLES_IMAGESET_DATA_TABLE, + STYLES_TEMPLATE_TABLE, + STYLES_TEMPLATE_DATA_TABLE, + STYLES_THEME_TABLE, + ) + ); + $statements = $db_tools->perform_schema_changes($changes); + + foreach ($statements as $sql) + { + _sql($sql, $errored, $error_ary); + } + + // Remove old entries from styles table + if (!sizeof($valid_styles)) + { + // No valid styles: remove everything and add prosilver + _sql('DELETE FROM ' . STYLES_TABLE, $errored, $error_ary); + + $sql = 'INSERT INTO ' . STYLES_TABLE . " (style_id, style_name, style_copyright, style_active, style_path, bbcode_bitfield, style_parent_id, style_parent_tree) VALUES (1, 'prosilver', '© phpBB Group', 1, 'prosilver', 'kNg=', 0, '')"; + _sql($sql, $errored, $error_ary); + + set_config('default_style', '1'); + + $sql = 'UPDATE ' . USERS_TABLE . ' SET user_style = 0'; + _sql($sql, $errored, $error_ary); + } + else + { + // There are valid styles in styles table. Remove styles that are outdated + _sql('DELETE FROM ' . STYLES_TABLE . ' WHERE ' . $db->sql_in_set('style_id', $valid_styles, true), $errored, $error_ary); + + // Change default style + if (!in_array($config['default_style'], $valid_styles)) + { + set_config('default_style', $valid_styles[0]); + } + + // Reset styles for users + _sql('UPDATE ' . USERS_TABLE . ' SET user_style = 0 WHERE ' . $db->sql_in_set('user_style', $valid_styles, true), $errored, $error_ary); + } + } + $no_updates = false; if (!isset($config['assets_version'])) From ea8f83de6f87af8fc9413e1be557953cabe8811e Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Thu, 19 Apr 2012 03:06:40 +0200 Subject: [PATCH 114/441] [ticket/10759] Fix whitespace in database_update.php PHPBB3-10759 --- phpBB/install/database_update.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/phpBB/install/database_update.php b/phpBB/install/database_update.php index 0b33168496..cddc1c4164 100644 --- a/phpBB/install/database_update.php +++ b/phpBB/install/database_update.php @@ -2310,7 +2310,7 @@ function change_database_data(&$no_updates, $version) _add_modules($modules_to_install); $sql = 'DELETE FROM ' . MODULES_TABLE . " - WHERE (module_basename = 'styles' OR module_basename = 'acp_styles') AND (module_mode = 'imageset' OR module_mode = 'theme' OR module_mode = 'template')"; + WHERE (module_basename = 'styles' OR module_basename = 'acp_styles') AND (module_mode = 'imageset' OR module_mode = 'theme' OR module_mode = 'template')"; _sql($sql, $errored, $error_ary); // Localise Global Announcements @@ -2474,15 +2474,15 @@ function change_database_data(&$no_updates, $version) // Remove old styles tables $changes = array( - 'drop_columns' => array( - STYLES_TABLE => array( + 'drop_columns' => array( + STYLES_TABLE => array( 'imageset_id', 'template_id', 'theme_id', ), ), - 'drop_tables' => array( + 'drop_tables' => array( STYLES_IMAGESET_TABLE, STYLES_IMAGESET_DATA_TABLE, STYLES_TEMPLATE_TABLE, From c43373068636a4f361423f2fe41231ac2e32f70f Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Thu, 19 Apr 2012 03:18:20 +0200 Subject: [PATCH 115/441] [ticket/10759] Retrieve style_id after INSERT since we cannot set it PHPBB3-10759 --- phpBB/install/database_update.php | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/phpBB/install/database_update.php b/phpBB/install/database_update.php index cddc1c4164..d71226a29c 100644 --- a/phpBB/install/database_update.php +++ b/phpBB/install/database_update.php @@ -2503,10 +2503,17 @@ function change_database_data(&$no_updates, $version) // No valid styles: remove everything and add prosilver _sql('DELETE FROM ' . STYLES_TABLE, $errored, $error_ary); - $sql = 'INSERT INTO ' . STYLES_TABLE . " (style_id, style_name, style_copyright, style_active, style_path, bbcode_bitfield, style_parent_id, style_parent_tree) VALUES (1, 'prosilver', '© phpBB Group', 1, 'prosilver', 'kNg=', 0, '')"; + $sql = 'INSERT INTO ' . STYLES_TABLE . " (style_name, style_copyright, style_active, style_path, bbcode_bitfield, style_parent_id, style_parent_tree) VALUES ('prosilver', '© phpBB Group', 1, 'prosilver', 'kNg=', 0, '')"; _sql($sql, $errored, $error_ary); - set_config('default_style', '1'); + $sql = 'SELECT style_id + FROM ' . $table . " + WHERE style_name = 'prosilver'"; + $result = _sql($sql, $errored, $error_ary); + $default_style = $db->sql_fetchfield($result); + $db->sql_freeresult($result); + + set_config('default_style', $default_style); $sql = 'UPDATE ' . USERS_TABLE . ' SET user_style = 0'; _sql($sql, $errored, $error_ary); From 0b7a0fa2d11c4f30d31e36f2c11c574491432d4a Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Thu, 19 Apr 2012 03:27:42 +0200 Subject: [PATCH 116/441] [ticket/10759] Clarify comments a bit PHPBB3-10759 --- phpBB/install/database_update.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/phpBB/install/database_update.php b/phpBB/install/database_update.php index d71226a29c..c30508dcee 100644 --- a/phpBB/install/database_update.php +++ b/phpBB/install/database_update.php @@ -2404,7 +2404,7 @@ function change_database_data(&$no_updates, $version) // Check if styles table was already updated if ($db_tools->sql_table_exists(STYLES_THEME_TABLE)) { - // Get list of valid installed styles + // Get list of valid 3.1 styles $available_styles = array('prosilver'); $iterator = new DirectoryIterator($phpbb_root_path . 'styles'); @@ -2447,12 +2447,12 @@ function change_database_data(&$no_updates, $version) } $db->sql_freeresult($result); - // Check each style + // Decide which styles to keep, all others will be deleted $valid_styles = array(); foreach ($styles as $style_row) { if ( - // Ignore styles with parent style + // Delete styles with parent style (not supported yet) $style_row['template_inherits_id'] == 0 && // Check if components match $style_row['template_path'] == $style_row['theme_path'] && (!isset($style_row['imageset_path']) || $style_row['template_path'] == $style_row['imageset_path']) && From 18704215216cf31e8d96058d2df7ef7cf20a3f7b Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Thu, 19 Apr 2012 03:38:01 +0200 Subject: [PATCH 117/441] [ticket/10759] Don't select imageset_id, it's not needed PHPBB3-10759 --- phpBB/install/database_update.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/install/database_update.php b/phpBB/install/database_update.php index c30508dcee..88ebb8209e 100644 --- a/phpBB/install/database_update.php +++ b/phpBB/install/database_update.php @@ -2425,7 +2425,7 @@ function change_database_data(&$no_updates, $version) // Get all installed styles if ($db_tools->sql_table_exists(STYLES_IMAGESET_TABLE)) { - $sql = 'SELECT s.style_id, t.template_path, t.template_id, t.bbcode_bitfield, t.template_inherits_id, t.template_inherit_path, c.theme_path, c.theme_id, i.imageset_path, i.imageset_id + $sql = 'SELECT s.style_id, t.template_path, t.template_id, t.bbcode_bitfield, t.template_inherits_id, t.template_inherit_path, c.theme_path, c.theme_id, i.imageset_path FROM ' . STYLES_TABLE . ' s, ' . STYLES_TEMPLATE_TABLE . ' t, ' . STYLES_THEME_TABLE . ' c, ' . STYLES_IMAGESET_TABLE . " i WHERE t.template_id = s.template_id AND c.theme_id = s.theme_id From 439ade4ee2f2fcd301ad3690624a821a779c95ee Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Thu, 19 Apr 2012 03:51:17 +0200 Subject: [PATCH 118/441] [ticket/10759] Make sure style ids are integers PHPBB3-10759 --- phpBB/install/database_update.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/install/database_update.php b/phpBB/install/database_update.php index 88ebb8209e..a0892005d2 100644 --- a/phpBB/install/database_update.php +++ b/phpBB/install/database_update.php @@ -2468,7 +2468,7 @@ function change_database_data(&$no_updates, $version) 'style_parent_tree' => '', ); _sql('UPDATE ' . STYLES_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . ' WHERE style_id = ' . $style_row['style_id'], $errored, $error_ary); - $valid_styles[] = $style_row['style_id']; + $valid_styles[] = (int) $style_row['style_id']; } } From 733018f99a7d8c6200921f31c683606c6f01fe76 Mon Sep 17 00:00:00 2001 From: Vjacheslav Trushkin Date: Tue, 3 Apr 2012 11:23:09 +0300 Subject: [PATCH 119/441] [ticket/10756] Moving template classes Moving template class files from includes/style/ to includes/template/ and removing template_ file prefix PHPBB3-10756 --- .../includes/{style/template_compile.php => template/compile.php} | 0 .../includes/{style/template_context.php => template/context.php} | 0 phpBB/includes/{style/template_filter.php => template/filter.php} | 0 .../{style/template_renderer.php => template/renderer.php} | 0 .../template_renderer_eval.php => template/renderer_eval.php} | 0 .../renderer_include.php} | 0 6 files changed, 0 insertions(+), 0 deletions(-) rename phpBB/includes/{style/template_compile.php => template/compile.php} (100%) rename phpBB/includes/{style/template_context.php => template/context.php} (100%) rename phpBB/includes/{style/template_filter.php => template/filter.php} (100%) rename phpBB/includes/{style/template_renderer.php => template/renderer.php} (100%) rename phpBB/includes/{style/template_renderer_eval.php => template/renderer_eval.php} (100%) rename phpBB/includes/{style/template_renderer_include.php => template/renderer_include.php} (100%) diff --git a/phpBB/includes/style/template_compile.php b/phpBB/includes/template/compile.php similarity index 100% rename from phpBB/includes/style/template_compile.php rename to phpBB/includes/template/compile.php diff --git a/phpBB/includes/style/template_context.php b/phpBB/includes/template/context.php similarity index 100% rename from phpBB/includes/style/template_context.php rename to phpBB/includes/template/context.php diff --git a/phpBB/includes/style/template_filter.php b/phpBB/includes/template/filter.php similarity index 100% rename from phpBB/includes/style/template_filter.php rename to phpBB/includes/template/filter.php diff --git a/phpBB/includes/style/template_renderer.php b/phpBB/includes/template/renderer.php similarity index 100% rename from phpBB/includes/style/template_renderer.php rename to phpBB/includes/template/renderer.php diff --git a/phpBB/includes/style/template_renderer_eval.php b/phpBB/includes/template/renderer_eval.php similarity index 100% rename from phpBB/includes/style/template_renderer_eval.php rename to phpBB/includes/template/renderer_eval.php diff --git a/phpBB/includes/style/template_renderer_include.php b/phpBB/includes/template/renderer_include.php similarity index 100% rename from phpBB/includes/style/template_renderer_include.php rename to phpBB/includes/template/renderer_include.php From ef295a28606789874b524445f9fa690408c8eafc Mon Sep 17 00:00:00 2001 From: Vjacheslav Trushkin Date: Tue, 3 Apr 2012 11:27:15 +0300 Subject: [PATCH 120/441] [ticket/10756] Renaming template classes Renaming template classes from phpbb_style_template_ to phpbb_template_ PHPBB3-10756 --- phpBB/includes/style/style.php | 2 +- phpBB/includes/style/template.php | 20 ++++++++++---------- phpBB/includes/template/compile.php | 4 ++-- phpBB/includes/template/context.php | 2 +- phpBB/includes/template/filter.php | 2 +- phpBB/includes/template/renderer.php | 4 ++-- phpBB/includes/template/renderer_eval.php | 4 ++-- phpBB/includes/template/renderer_include.php | 4 ++-- tests/template/renderer_eval_test.php | 4 ++-- tests/template/template_compile_test.php | 2 +- 10 files changed, 24 insertions(+), 24 deletions(-) diff --git a/phpBB/includes/style/style.php b/phpBB/includes/style/style.php index 5ac61c9f10..4bfb9eaa07 100644 --- a/phpBB/includes/style/style.php +++ b/phpBB/includes/style/style.php @@ -119,7 +119,7 @@ class phpbb_style $this->template->cachepath = $this->phpbb_root_path . 'cache/tpl_' . str_replace('_', '-', $name) . '_'; - $this->template->context = new phpbb_style_template_context(); + $this->template->context = new phpbb_template_context(); if ($template_path !== false) { diff --git a/phpBB/includes/style/template.php b/phpBB/includes/style/template.php index 9d476e74b9..ad4c452268 100644 --- a/phpBB/includes/style/template.php +++ b/phpBB/includes/style/template.php @@ -32,7 +32,7 @@ if (!defined('IN_PHPBB')) class phpbb_style_template { /** - * @var phpbb_style_template_context Template context. + * @var phpbb_template_context Template context. * Stores template data used during template rendering. */ public $context; @@ -253,15 +253,15 @@ class phpbb_style_template * configuration setting may be used to force templates to be always * recompiled. * - * Returns an object implementing phpbb_style_template_renderer, or null + * Returns an object implementing phpbb_template_renderer, or null * if template loading or compilation failed. Call render() on the * renderer to display the template. This will result in template * contents sent to the output stream (unless, of course, output * buffering is in effect). * * @param string $handle Handle of the template to load - * @return phpbb_style_template_renderer Template renderer object, or null on failure - * @uses phpbb_style_template_compile is used to compile template source + * @return phpbb_template_renderer Template renderer object, or null on failure + * @uses phpbb_template_compile is used to compile template source */ private function _tpl_load($handle) { @@ -285,18 +285,18 @@ class phpbb_style_template // Recompile page if the original template is newer, otherwise load the compiled version if (!$recompile) { - return new phpbb_style_template_renderer_include($output_file, $this); + return new phpbb_template_renderer_include($output_file, $this); } - $compile = new phpbb_style_template_compile($this->config['tpl_allow_php'], $this->locator, $this->phpbb_root_path); + $compile = new phpbb_template_compile($this->config['tpl_allow_php'], $this->locator, $this->phpbb_root_path); if ($compile->compile_file_to_file($source_file, $output_file) !== false) { - $renderer = new phpbb_style_template_renderer_include($output_file, $this); + $renderer = new phpbb_template_renderer_include($output_file, $this); } else if (($code = $compile->compile_file($source_file)) !== false) { - $renderer = new phpbb_style_template_renderer_eval($code, $this); + $renderer = new phpbb_template_renderer_eval($code, $this); } else { @@ -358,7 +358,7 @@ class phpbb_style_template $this->context->append_var($varname, $varval); } - // Docstring is copied from phpbb_style_template_context method with the same name. + // Docstring is copied from phpbb_template_context method with the same name. /** * Assign key variable pairs from an array to a specified block * @param string $blockname Name of block to assign $vararray to @@ -369,7 +369,7 @@ class phpbb_style_template return $this->context->assign_block_vars($blockname, $vararray); } - // Docstring is copied from phpbb_style_template_context method with the same name. + // Docstring is copied from phpbb_template_context method with the same name. /** * Change already assigned key variable pair (one-dimensional - single loop entry) * diff --git a/phpBB/includes/template/compile.php b/phpBB/includes/template/compile.php index fa0928f424..82b301c1a2 100644 --- a/phpBB/includes/template/compile.php +++ b/phpBB/includes/template/compile.php @@ -15,7 +15,7 @@ if (!defined('IN_PHPBB')) exit; } -stream_filter_register('phpbb_template', 'phpbb_style_template_filter'); +stream_filter_register('phpbb_template', 'phpbb_template_filter'); /** * Extension of template class - Functions needed for compiling templates only. @@ -23,7 +23,7 @@ stream_filter_register('phpbb_template', 'phpbb_style_template_filter'); * @package phpBB3 * @uses template_filter As a PHP stream filter to perform compilation of templates */ -class phpbb_style_template_compile +class phpbb_template_compile { /** * Array of parameters to forward to template filter diff --git a/phpBB/includes/template/context.php b/phpBB/includes/template/context.php index b22f77da2e..5e0b1d4a7e 100644 --- a/phpBB/includes/template/context.php +++ b/phpBB/includes/template/context.php @@ -20,7 +20,7 @@ if (!defined('IN_PHPBB')) * * @package phpBB3 */ -class phpbb_style_template_context +class phpbb_template_context { /** * variable that holds all the data we'll be substituting into diff --git a/phpBB/includes/template/filter.php b/phpBB/includes/template/filter.php index 6ef9d80a3d..4a2593b757 100644 --- a/phpBB/includes/template/filter.php +++ b/phpBB/includes/template/filter.php @@ -35,7 +35,7 @@ if (!defined('IN_PHPBB')) * @see template_compile * @package phpBB3 */ -class phpbb_style_template_filter extends php_user_filter +class phpbb_template_filter extends php_user_filter { const REGEX_NS = '[a-z_][a-z_0-9]+'; diff --git a/phpBB/includes/template/renderer.php b/phpBB/includes/template/renderer.php index bd2a786e86..30e234a733 100644 --- a/phpBB/includes/template/renderer.php +++ b/phpBB/includes/template/renderer.php @@ -23,12 +23,12 @@ if (!defined('IN_PHPBB')) * * @package phpBB3 */ -interface phpbb_style_template_renderer +interface phpbb_template_renderer { /** * Displays the template managed by this renderer. * - * @param phpbb_style_template_context $context Template context to use + * @param phpbb_template_context $context Template context to use * @param array $lang Language entries to use */ public function render($context, $lang); diff --git a/phpBB/includes/template/renderer_eval.php b/phpBB/includes/template/renderer_eval.php index 3e08b06e69..62dfbc3708 100644 --- a/phpBB/includes/template/renderer_eval.php +++ b/phpBB/includes/template/renderer_eval.php @@ -21,7 +21,7 @@ if (!defined('IN_PHPBB')) * * @package phpBB3 */ -class phpbb_style_template_renderer_eval implements phpbb_style_template_renderer +class phpbb_template_renderer_eval implements phpbb_template_renderer { /** * Template code to be eval'ed. @@ -45,7 +45,7 @@ class phpbb_style_template_renderer_eval implements phpbb_style_template_rendere * Displays the template managed by this renderer by eval'ing php code * of the template. * - * @param phpbb_style_template_context $context Template context to use + * @param phpbb_template_context $context Template context to use * @param array $lang Language entries to use */ public function render($context, $lang) diff --git a/phpBB/includes/template/renderer_include.php b/phpBB/includes/template/renderer_include.php index 91c1a1bb65..f5c9026abf 100644 --- a/phpBB/includes/template/renderer_include.php +++ b/phpBB/includes/template/renderer_include.php @@ -22,7 +22,7 @@ if (!defined('IN_PHPBB')) * * @package phpBB3 */ -class phpbb_style_template_renderer_include implements phpbb_style_template_renderer +class phpbb_template_renderer_include implements phpbb_template_renderer { /** * Template path to be included. @@ -45,7 +45,7 @@ class phpbb_style_template_renderer_include implements phpbb_style_template_rend * Displays the template managed by this renderer by including * the php file containing the template. * - * @param phpbb_style_template_context $context Template context to use + * @param phpbb_template_context $context Template context to use * @param array $lang Language entries to use */ public function render($context, $lang) diff --git a/tests/template/renderer_eval_test.php b/tests/template/renderer_eval_test.php index 9b4f74c824..7ebb8b9bda 100644 --- a/tests/template/renderer_eval_test.php +++ b/tests/template/renderer_eval_test.php @@ -13,8 +13,8 @@ class phpbb_template_renderer_eval_test extends phpbb_test_case { $compiled_code = ''; $valid_code = ''; - $context = new phpbb_style_template_context(); - $template = new phpbb_style_template_renderer_eval($compiled_code, NULL); + $context = new phpbb_template_context(); + $template = new phpbb_template_renderer_eval($compiled_code, NULL); ob_start(); try { diff --git a/tests/template/template_compile_test.php b/tests/template/template_compile_test.php index e2264fb1b7..0cfcd6ceb5 100644 --- a/tests/template/template_compile_test.php +++ b/tests/template/template_compile_test.php @@ -16,7 +16,7 @@ class phpbb_template_template_compile_test extends phpbb_test_case protected function setUp() { - $this->template_compile = new phpbb_style_template_compile(false, null, ''); + $this->template_compile = new phpbb_template_compile(false, null, ''); $this->template_path = dirname(__FILE__) . '/templates'; } From ea3a2ef2234095e9db2d79f8c1d17bf1dfda1a23 Mon Sep 17 00:00:00 2001 From: Vjacheslav Trushkin Date: Tue, 3 Apr 2012 13:19:03 +0300 Subject: [PATCH 121/441] [ticket/10756] Creating locator interface Creating locator interface to be used in template class PHPBB3-10756 --- phpBB/includes/style/resource_locator.php | 2 +- phpBB/includes/style/template.php | 8 +- phpBB/includes/template/locator.php | 133 ++++++++++++++++++++++ 3 files changed, 138 insertions(+), 5 deletions(-) create mode 100644 phpBB/includes/template/locator.php diff --git a/phpBB/includes/style/resource_locator.php b/phpBB/includes/style/resource_locator.php index 3e6dd5d6aa..fafa11c352 100644 --- a/phpBB/includes/style/resource_locator.php +++ b/phpBB/includes/style/resource_locator.php @@ -30,7 +30,7 @@ if (!defined('IN_PHPBB')) * * @package phpBB3 */ -class phpbb_style_resource_locator +class phpbb_style_resource_locator implements phpbb_template_locator { /** * Paths to style directories. diff --git a/phpBB/includes/style/template.php b/phpBB/includes/style/template.php index ad4c452268..1967ec7d96 100644 --- a/phpBB/includes/style/template.php +++ b/phpBB/includes/style/template.php @@ -63,8 +63,8 @@ class phpbb_style_template private $user; /** - * Style resource locator - * @var phpbb_style_resource_locator + * Template locator + * @var phpbb_template_locator */ private $locator; @@ -85,10 +85,10 @@ class phpbb_style_template * * @param string $phpbb_root_path phpBB root path * @param user $user current user - * @param phpbb_style_resource_locator $locator style resource locator + * @param phpbb_template_locator $locator template locator * @param phpbb_style_path_provider $provider style path provider */ - public function __construct($phpbb_root_path, $phpEx, $config, $user, phpbb_style_resource_locator $locator, phpbb_style_path_provider_interface $provider) + public function __construct($phpbb_root_path, $phpEx, $config, $user, phpbb_template_locator $locator, phpbb_style_path_provider_interface $provider) { $this->phpbb_root_path = $phpbb_root_path; $this->phpEx = $phpEx; diff --git a/phpBB/includes/template/locator.php b/phpBB/includes/template/locator.php new file mode 100644 index 0000000000..836046e92b --- /dev/null +++ b/phpBB/includes/template/locator.php @@ -0,0 +1,133 @@ + filename pairs. + * + * @param array $filname_array Should be a hash of handle => filename pairs. + */ + public function set_filenames(array $filename_array); + + /** + * Determines the filename for a template handle. + * + * The filename comes from array used in a set_filenames call, + * which should have been performed prior to invoking this function. + * Return value is a file basename (without path). + * + * @param $handle string Template handle + * @return string Filename corresponding to the template handle + */ + public function get_filename_for_handle($handle); + + /** + * Determines the source file path for a template handle without + * regard for styles tree. + * + * This function returns the path in "primary" style directory + * corresponding to the given template handle. That path may or + * may not actually exist on the filesystem. Because this function + * does not perform stat calls to determine whether the path it + * returns actually exists, it is faster than get_source_file_for_handle. + * + * Use get_source_file_for_handle to obtain the actual path that is + * guaranteed to exist (which might come from the parent style + * directory if primary style has parent styles). + * + * This function will trigger an error if the handle was never + * associated with a template file via set_filenames. + * + * @param $handle string Template handle + * @return string Path to source file path in primary style directory + */ + public function get_virtual_source_file_for_handle($handle); + + /** + * Determines the source file path for a template handle, accounting + * for styles tree and verifying that the path exists. + * + * This function returns the actual path that may be compiled for + * the specified template handle. It will trigger an error if + * the template handle was never associated with a template path + * via set_filenames or if the template file does not exist on the + * filesystem. + * + * Use get_virtual_source_file_for_handle to just resolve a template + * handle to a path without any filesystem or styles tree checks. + * + * @param string $handle Template handle (i.e. "friendly" template name) + * @param bool $find_all If true, each root path will be checked and function + * will return array of files instead of string and will not + * trigger a error if template does not exist + * @return string Source file path + */ + public function get_source_file_for_handle($handle, $find_all = false); + + /** + * Locates source file path, accounting for styles tree and verifying that + * the path exists. + * + * Unlike previous functions, this function works without template handle + * and it can search for more than one file. If more than one file name is + * specified, it will return location of file that it finds first. + * + * @param array $files List of files to locate. + * @param bool $return_default Determines what to return if file does not + * exist. If true, function will return location where file is + * supposed to be. If false, function will return false. + * @param bool $return_full_path If true, function will return full path + * to file. If false, function will return file name. This + * parameter can be used to check which one of set of files + * is available. + * @return string or boolean Source file path if file exists or $return_default is + * true. False if file does not exist and $return_default is false + */ + public function get_first_file_location($files, $return_default = false, $return_full_path = true); +} From 6cecc91326135fbb36eb9d73aa25fc40cfdfb54b Mon Sep 17 00:00:00 2001 From: Vjacheslav Trushkin Date: Tue, 3 Apr 2012 13:23:08 +0300 Subject: [PATCH 122/441] [ticket/10756] Removing path provider from template class Removing path provider from template class because it is not used by template class PHPBB3-10756 --- phpBB/common.php | 3 ++- phpBB/includes/bbcode.php | 2 +- phpBB/includes/functions_messenger.php | 4 +++- phpBB/includes/style/template.php | 10 +--------- phpBB/install/index.php | 2 +- tests/template/template_test_case.php | 2 +- tests/template/template_test_case_with_tree.php | 2 +- 7 files changed, 10 insertions(+), 15 deletions(-) diff --git a/phpBB/common.php b/phpBB/common.php index a00e3e82a8..7694620b36 100644 --- a/phpBB/common.php +++ b/phpBB/common.php @@ -124,7 +124,8 @@ $phpbb_extension_manager = new phpbb_extension_manager($db, EXT_TABLE, $phpbb_ro // Initialize style $phpbb_style_resource_locator = new phpbb_style_resource_locator(); $phpbb_style_path_provider = new phpbb_style_extension_path_provider($phpbb_extension_manager, new phpbb_style_path_provider()); -$template = new phpbb_style_template($phpbb_root_path, $phpEx, $config, $user, $phpbb_style_resource_locator, $phpbb_style_path_provider); + +$template = new phpbb_style_template($phpbb_root_path, $phpEx, $config, $user, $phpbb_style_resource_locator); $phpbb_style = new phpbb_style($phpbb_root_path, $phpEx, $config, $user, $phpbb_style_resource_locator, $phpbb_style_path_provider, $template); $phpbb_subscriber_loader = new phpbb_event_extension_subscriber_loader($phpbb_dispatcher, $phpbb_extension_manager); diff --git a/phpBB/includes/bbcode.php b/phpBB/includes/bbcode.php index 612ced8ad6..3adf9582d6 100644 --- a/phpBB/includes/bbcode.php +++ b/phpBB/includes/bbcode.php @@ -134,7 +134,7 @@ class bbcode $style_resource_locator = new phpbb_style_resource_locator(); $style_path_provider = new phpbb_style_extension_path_provider($phpbb_extension_manager, new phpbb_style_path_provider()); - $template = new phpbb_style_template($phpbb_root_path, $phpEx, $config, $user, $style_resource_locator, $style_path_provider); + $template = new phpbb_style_template($phpbb_root_path, $phpEx, $config, $user, $style_resource_locator); $style = new phpbb_style($phpbb_root_path, $phpEx, $config, $user, $style_resource_locator, $style_path_provider, $template); $style->set_style(); $template->set_filenames(array('bbcode.html' => 'bbcode.html')); diff --git a/phpBB/includes/functions_messenger.php b/phpBB/includes/functions_messenger.php index f608c95fe4..de14703817 100644 --- a/phpBB/includes/functions_messenger.php +++ b/phpBB/includes/functions_messenger.php @@ -210,8 +210,10 @@ class messenger { $style_resource_locator = new phpbb_style_resource_locator(); $style_path_provider = new phpbb_style_extension_path_provider($phpbb_extension_manager, new phpbb_style_path_provider()); - $tpl = new phpbb_style_template($phpbb_root_path, $phpEx, $config, $user, $style_resource_locator, $style_path_provider); + + $tpl = new phpbb_style_template($phpbb_root_path, $phpEx, $config, $user, $style_resource_locator); $style = new phpbb_style($phpbb_root_path, $phpEx, $config, $user, $style_resource_locator, $style_path_provider, $tpl); + $this->tpl_msg[$template_lang . $template_file] = $tpl; $fallback_template_path = false; diff --git a/phpBB/includes/style/template.php b/phpBB/includes/style/template.php index 1967ec7d96..6dd588c17b 100644 --- a/phpBB/includes/style/template.php +++ b/phpBB/includes/style/template.php @@ -68,12 +68,6 @@ class phpbb_style_template */ private $locator; - /** - * Template path provider - * @var phpbb_style_path_provider - */ - private $provider; - /** * Location of templates directory within style directories * @var string @@ -86,9 +80,8 @@ class phpbb_style_template * @param string $phpbb_root_path phpBB root path * @param user $user current user * @param phpbb_template_locator $locator template locator - * @param phpbb_style_path_provider $provider style path provider */ - public function __construct($phpbb_root_path, $phpEx, $config, $user, phpbb_template_locator $locator, phpbb_style_path_provider_interface $provider) + public function __construct($phpbb_root_path, $phpEx, $config, $user, phpbb_template_locator $locator) { $this->phpbb_root_path = $phpbb_root_path; $this->phpEx = $phpEx; @@ -96,7 +89,6 @@ class phpbb_style_template $this->user = $user; $this->locator = $locator; $this->template_path = $this->locator->template_path; - $this->provider = $provider; } /** diff --git a/phpBB/install/index.php b/phpBB/install/index.php index bb10521bba..be5ebc53b5 100644 --- a/phpBB/install/index.php +++ b/phpBB/install/index.php @@ -202,7 +202,7 @@ $config = new phpbb_config(array( $phpbb_style_resource_locator = new phpbb_style_resource_locator(); $phpbb_style_path_provider = new phpbb_style_path_provider(); -$template = new phpbb_style_template($phpbb_root_path, $phpEx, $config, $user, $phpbb_style_resource_locator, $phpbb_style_path_provider); +$template = new phpbb_style_template($phpbb_root_path, $phpEx, $config, $user, $phpbb_style_resource_locator); $phpbb_style = new phpbb_style($phpbb_root_path, $phpEx, $config, $user, $phpbb_style_resource_locator, $phpbb_style_path_provider, $template); $phpbb_style->set_ext_dir_prefix('adm/'); $phpbb_style->set_custom_style('admin', '../adm/style', ''); diff --git a/tests/template/template_test_case.php b/tests/template/template_test_case.php index a87e531a07..4170fdf278 100644 --- a/tests/template/template_test_case.php +++ b/tests/template/template_test_case.php @@ -66,7 +66,7 @@ class phpbb_template_template_test_case extends phpbb_test_case $this->template_path = dirname(__FILE__) . '/templates'; $this->style_resource_locator = new phpbb_style_resource_locator(); $this->style_provider = new phpbb_style_path_provider(); - $this->template = new phpbb_style_template($phpbb_root_path, $phpEx, $config, $user, $this->style_resource_locator, $this->style_provider); + $this->template = new phpbb_style_template($phpbb_root_path, $phpEx, $config, $user, $this->style_resource_locator); $this->style = new phpbb_style($phpbb_root_path, $phpEx, $config, $user, $this->style_resource_locator, $this->style_provider, $this->template); $this->style->set_custom_style('tests', $this->template_path, ''); } diff --git a/tests/template/template_test_case_with_tree.php b/tests/template/template_test_case_with_tree.php index e76d9436cf..536ac394a8 100644 --- a/tests/template/template_test_case_with_tree.php +++ b/tests/template/template_test_case_with_tree.php @@ -22,7 +22,7 @@ class phpbb_template_template_test_case_with_tree extends phpbb_template_templat $this->parent_template_path = dirname(__FILE__) . '/parent_templates'; $this->style_resource_locator = new phpbb_style_resource_locator(); $this->style_provider = new phpbb_style_path_provider(); - $this->template = new phpbb_style_template($phpbb_root_path, $phpEx, $config, $user, $this->style_resource_locator, $this->style_provider); + $this->template = new phpbb_style_template($phpbb_root_path, $phpEx, $config, $user, $this->style_resource_locator); $this->style = new phpbb_style($phpbb_root_path, $phpEx, $config, $user, $this->style_resource_locator, $this->style_provider, $this->template); $this->style->set_custom_style('tests', array($this->template_path, $this->parent_template_path), ''); } From d91abbb146d3a808764bf19b9e6adc6e14db1751 Mon Sep 17 00:00:00 2001 From: Vjacheslav Trushkin Date: Tue, 3 Apr 2012 13:57:12 +0300 Subject: [PATCH 123/441] [ticket/10756] Renaming phpbb_style_template to phpbb_template Renaming phpbb_style_template to phpbb_template PHPBB3-10756 --- phpBB/common.php | 3 +-- phpBB/includes/bbcode.php | 2 +- phpBB/includes/functions_messenger.php | 3 +-- phpBB/includes/style/style.php | 6 +++--- phpBB/includes/template/context.php | 2 +- phpBB/includes/template/renderer_eval.php | 2 +- phpBB/includes/{style => template}/template.php | 2 +- phpBB/install/index.php | 2 +- tests/template/template_test_case.php | 2 +- tests/template/template_test_case_with_tree.php | 2 +- 10 files changed, 12 insertions(+), 14 deletions(-) rename phpBB/includes/{style => template}/template.php (99%) diff --git a/phpBB/common.php b/phpBB/common.php index 7694620b36..81fe275008 100644 --- a/phpBB/common.php +++ b/phpBB/common.php @@ -124,8 +124,7 @@ $phpbb_extension_manager = new phpbb_extension_manager($db, EXT_TABLE, $phpbb_ro // Initialize style $phpbb_style_resource_locator = new phpbb_style_resource_locator(); $phpbb_style_path_provider = new phpbb_style_extension_path_provider($phpbb_extension_manager, new phpbb_style_path_provider()); - -$template = new phpbb_style_template($phpbb_root_path, $phpEx, $config, $user, $phpbb_style_resource_locator); +$template = new phpbb_template($phpbb_root_path, $phpEx, $config, $user, $phpbb_style_resource_locator); $phpbb_style = new phpbb_style($phpbb_root_path, $phpEx, $config, $user, $phpbb_style_resource_locator, $phpbb_style_path_provider, $template); $phpbb_subscriber_loader = new phpbb_event_extension_subscriber_loader($phpbb_dispatcher, $phpbb_extension_manager); diff --git a/phpBB/includes/bbcode.php b/phpBB/includes/bbcode.php index 3adf9582d6..fde917e5b1 100644 --- a/phpBB/includes/bbcode.php +++ b/phpBB/includes/bbcode.php @@ -134,7 +134,7 @@ class bbcode $style_resource_locator = new phpbb_style_resource_locator(); $style_path_provider = new phpbb_style_extension_path_provider($phpbb_extension_manager, new phpbb_style_path_provider()); - $template = new phpbb_style_template($phpbb_root_path, $phpEx, $config, $user, $style_resource_locator); + $template = new phpbb_template($phpbb_root_path, $phpEx, $config, $user, $style_resource_locator); $style = new phpbb_style($phpbb_root_path, $phpEx, $config, $user, $style_resource_locator, $style_path_provider, $template); $style->set_style(); $template->set_filenames(array('bbcode.html' => 'bbcode.html')); diff --git a/phpBB/includes/functions_messenger.php b/phpBB/includes/functions_messenger.php index de14703817..e9073553d0 100644 --- a/phpBB/includes/functions_messenger.php +++ b/phpBB/includes/functions_messenger.php @@ -210,8 +210,7 @@ class messenger { $style_resource_locator = new phpbb_style_resource_locator(); $style_path_provider = new phpbb_style_extension_path_provider($phpbb_extension_manager, new phpbb_style_path_provider()); - - $tpl = new phpbb_style_template($phpbb_root_path, $phpEx, $config, $user, $style_resource_locator); + $tpl = new phpbb_template($phpbb_root_path, $phpEx, $config, $user, $style_resource_locator); $style = new phpbb_style($phpbb_root_path, $phpEx, $config, $user, $style_resource_locator, $style_path_provider, $tpl); $this->tpl_msg[$template_lang . $template_file] = $tpl; diff --git a/phpBB/includes/style/style.php b/phpBB/includes/style/style.php index 4bfb9eaa07..2be4cb8855 100644 --- a/phpBB/includes/style/style.php +++ b/phpBB/includes/style/style.php @@ -22,7 +22,7 @@ if (!defined('IN_PHPBB')) class phpbb_style { /** - * @var phpbb_style_template Template class. + * @var phpbb_template Template class. * Handles everything related to templates. */ private $template; @@ -66,9 +66,9 @@ class phpbb_style * @param user $user current user * @param phpbb_style_resource_locator $locator style resource locator * @param phpbb_style_path_provider $provider style path provider - * @param phpbb_style_template $template template + * @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_style_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) { $this->phpbb_root_path = $phpbb_root_path; $this->phpEx = $phpEx; diff --git a/phpBB/includes/template/context.php b/phpBB/includes/template/context.php index 5e0b1d4a7e..ec09da1cf3 100644 --- a/phpBB/includes/template/context.php +++ b/phpBB/includes/template/context.php @@ -86,7 +86,7 @@ class phpbb_template_context * Returns a reference to template data array. * * This function is public so that template renderer may invoke it. - * Users should alter template variables via functions in phpbb_style_template. + * Users should alter template variables via functions in phpbb_template. * * Note: modifying returned array will affect data stored in the context. * diff --git a/phpBB/includes/template/renderer_eval.php b/phpBB/includes/template/renderer_eval.php index 62dfbc3708..f8e4cb7b10 100644 --- a/phpBB/includes/template/renderer_eval.php +++ b/phpBB/includes/template/renderer_eval.php @@ -33,7 +33,7 @@ class phpbb_template_renderer_eval implements phpbb_template_renderer * Template includes are delegated to template object $template. * * @param string $code php code of the template - * @param phpbb_style_template $template template object + * @param phpbb_template $template template object */ public function __construct($code, $template) { diff --git a/phpBB/includes/style/template.php b/phpBB/includes/template/template.php similarity index 99% rename from phpBB/includes/style/template.php rename to phpBB/includes/template/template.php index 6dd588c17b..0a3e992b03 100644 --- a/phpBB/includes/style/template.php +++ b/phpBB/includes/template/template.php @@ -29,7 +29,7 @@ if (!defined('IN_PHPBB')) * Base Template class. * @package phpBB3 */ -class phpbb_style_template +class phpbb_template { /** * @var phpbb_template_context Template context. diff --git a/phpBB/install/index.php b/phpBB/install/index.php index be5ebc53b5..f992b67bb7 100644 --- a/phpBB/install/index.php +++ b/phpBB/install/index.php @@ -202,7 +202,7 @@ $config = new phpbb_config(array( $phpbb_style_resource_locator = new phpbb_style_resource_locator(); $phpbb_style_path_provider = new phpbb_style_path_provider(); -$template = new phpbb_style_template($phpbb_root_path, $phpEx, $config, $user, $phpbb_style_resource_locator); +$template = new phpbb_template($phpbb_root_path, $phpEx, $config, $user, $phpbb_style_resource_locator); $phpbb_style = new phpbb_style($phpbb_root_path, $phpEx, $config, $user, $phpbb_style_resource_locator, $phpbb_style_path_provider, $template); $phpbb_style->set_ext_dir_prefix('adm/'); $phpbb_style->set_custom_style('admin', '../adm/style', ''); diff --git a/tests/template/template_test_case.php b/tests/template/template_test_case.php index 4170fdf278..d660aa3f56 100644 --- a/tests/template/template_test_case.php +++ b/tests/template/template_test_case.php @@ -66,7 +66,7 @@ class phpbb_template_template_test_case extends phpbb_test_case $this->template_path = dirname(__FILE__) . '/templates'; $this->style_resource_locator = new phpbb_style_resource_locator(); $this->style_provider = new phpbb_style_path_provider(); - $this->template = new phpbb_style_template($phpbb_root_path, $phpEx, $config, $user, $this->style_resource_locator); + $this->template = new phpbb_template($phpbb_root_path, $phpEx, $config, $user, $this->style_resource_locator); $this->style = new phpbb_style($phpbb_root_path, $phpEx, $config, $user, $this->style_resource_locator, $this->style_provider, $this->template); $this->style->set_custom_style('tests', $this->template_path, ''); } diff --git a/tests/template/template_test_case_with_tree.php b/tests/template/template_test_case_with_tree.php index 536ac394a8..9522c97330 100644 --- a/tests/template/template_test_case_with_tree.php +++ b/tests/template/template_test_case_with_tree.php @@ -22,7 +22,7 @@ class phpbb_template_template_test_case_with_tree extends phpbb_template_templat $this->parent_template_path = dirname(__FILE__) . '/parent_templates'; $this->style_resource_locator = new phpbb_style_resource_locator(); $this->style_provider = new phpbb_style_path_provider(); - $this->template = new phpbb_style_template($phpbb_root_path, $phpEx, $config, $user, $this->style_resource_locator); + $this->template = new phpbb_template($phpbb_root_path, $phpEx, $config, $user, $this->style_resource_locator); $this->style = new phpbb_style($phpbb_root_path, $phpEx, $config, $user, $this->style_resource_locator, $this->style_provider, $this->template); $this->style->set_custom_style('tests', array($this->template_path, $this->parent_template_path), ''); } From ed9a58a6ccea5b9b2685488ff0cfc45f0ccdbeb5 Mon Sep 17 00:00:00 2001 From: Vjacheslav Trushkin Date: Tue, 3 Apr 2012 14:32:49 +0300 Subject: [PATCH 124/441] [ticket/10756] Fixing variable declarations in style and template classes Fixing variable declaration, removing function from template locator that does not belong there PHPBB3-10756 --- phpBB/includes/style/style.php | 15 ++++++++++----- phpBB/includes/template/locator.php | 12 ------------ phpBB/includes/template/template.php | 18 ++++++++++++------ 3 files changed, 22 insertions(+), 23 deletions(-) diff --git a/phpBB/includes/style/style.php b/phpBB/includes/style/style.php index 2be4cb8855..3f470015f6 100644 --- a/phpBB/includes/style/style.php +++ b/phpBB/includes/style/style.php @@ -22,28 +22,33 @@ if (!defined('IN_PHPBB')) class phpbb_style { /** - * @var phpbb_template Template class. + * Template class. * Handles everything related to templates. + * @var phpbb_template */ private $template; /** - * @var string phpBB root path + * phpBB root path + * @var string */ private $phpbb_root_path; /** - * @var phpEx PHP file extension + * PHP file extension + * @var string */ private $phpEx; /** - * @var phpbb_config phpBB config instance + * phpBB config instance + * @var phpbb_config */ private $config; /** - * @var user current user + * Current user + * @var phpbb_user */ private $user; diff --git a/phpBB/includes/template/locator.php b/phpBB/includes/template/locator.php index 836046e92b..01c79eec4e 100644 --- a/phpBB/includes/template/locator.php +++ b/phpBB/includes/template/locator.php @@ -35,18 +35,6 @@ if (!defined('IN_PHPBB')) */ interface phpbb_template_locator { - /** - * Sets the list of style paths - * - * These paths will be searched for style files in the provided order. - * Paths may be outside of phpBB, but templates loaded from these paths - * will still be cached. - * - * @param array $style_paths An array of paths to style directories - * @return null - */ - public function set_paths($style_paths); - /** * Sets the template filenames for handles. $filename_array * should be a hash of handle => filename pairs. diff --git a/phpBB/includes/template/template.php b/phpBB/includes/template/template.php index 0a3e992b03..e6512c8417 100644 --- a/phpBB/includes/template/template.php +++ b/phpBB/includes/template/template.php @@ -32,33 +32,39 @@ if (!defined('IN_PHPBB')) class phpbb_template { /** - * @var phpbb_template_context Template context. + * Template context. * Stores template data used during template rendering. + * @var phpbb_template_context */ public $context; /** - * @var string Path of the cache directory for the template + * Path of the cache directory for the template + * @var string */ public $cachepath = ''; /** - * @var string phpBB root path + * phpBB root path + * @var string */ private $phpbb_root_path; /** - * @var phpEx PHP file extension + * PHP file extension + * @var string */ private $phpEx; /** - * @var phpbb_config phpBB config instance + * phpBB config instance + * @var phpbb_config */ private $config; /** - * @var user current user + * Current user + * @var phpbb_user */ private $user; From 286aebd93bd49eac2ff80c3a6930f7f692a4c3ef Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Wed, 18 Apr 2012 17:01:40 +0200 Subject: [PATCH 125/441] [ticket/10811] Fix AJAX callback alt_text so it can be repeated. PHPBB3-10811 --- phpBB/assets/javascript/core.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/phpBB/assets/javascript/core.js b/phpBB/assets/javascript/core.js index 958b6c9ff6..74c71fca79 100644 --- a/phpBB/assets/javascript/core.js +++ b/phpBB/assets/javascript/core.js @@ -436,11 +436,12 @@ phpbb.add_ajax_callback = function(id, callback) * the alt-text data attribute, and replaces the text in the attribute with the * current text so that the process can be repeated. */ -phpbb.add_ajax_callback('alt_text', function(data) { +phpbb.add_ajax_callback('alt_text', function() { var el = $(this), alt_text; alt_text = el.attr('data-alt-text'); + el.attr('data-alt-text', el.text()); el.attr('title', alt_text); el.text(alt_text); }); From 00172afa532c99329f4683ecaefb0ba851e46b94 Mon Sep 17 00:00:00 2001 From: riadhchtara Date: Sun, 15 Apr 2012 12:36:42 +0100 Subject: [PATCH 126/441] [ticket/10813] Installer now checks json extension Installer now checks json extension and cannot continue without it. Changes are made in phpBB/install/install_install.php where the checking for json is added and to phpBB/language/en/install.php where 2 new keys for the messages that would be displayed are also added. PHPBB3-10813 --- phpBB/install/install_install.php | 22 +++++++++++++++++++++- phpBB/language/en/install.php | 2 ++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/phpBB/install/install_install.php b/phpBB/install/install_install.php index 7558fde944..ad84155585 100644 --- a/phpBB/install/install_install.php +++ b/phpBB/install/install_install.php @@ -128,7 +128,7 @@ class install_install extends module 'BODY' => $lang['REQUIREMENTS_EXPLAIN'], )); - $passed = array('php' => false, 'db' => false, 'files' => false, 'pcre' => false, 'imagesize' => false,); + $passed = array('php' => false, 'db' => false, 'files' => false, 'pcre' => false, 'imagesize' => false, 'json' => false,); // Test for basic PHP settings $template->assign_block_vars('checks', array( @@ -244,6 +244,26 @@ class install_install extends module 'S_EXPLAIN' => true, 'S_LEGEND' => false, )); + + // Check for php json support + if (@extension_loaded('json')) + { + $passed['json'] = true; + $result = '' . $lang['YES'] . ''; + } + else + { + $result = '' . $lang['NO'] . ''; + } + + $template->assign_block_vars('checks', array( + 'TITLE' => $lang['PHP_JSON_SUPPORT'], + 'TITLE_EXPLAIN' => $lang['PHP_JSON_SUPPORT_EXPLAIN'], + 'RESULT' => $result, + + 'S_EXPLAIN' => true, + 'S_LEGEND' => false, + )); /** * Better not enabling and adding to the loaded extensions due to the specific requirements needed diff --git a/phpBB/language/en/install.php b/phpBB/language/en/install.php index ca6045a921..29664ae5f0 100644 --- a/phpBB/language/en/install.php +++ b/phpBB/language/en/install.php @@ -292,6 +292,8 @@ $lang = array_merge($lang, array( 'PCRE_UTF_SUPPORT_EXPLAIN' => 'phpBB will not run if your PHP installation is not compiled with UTF-8 support in the PCRE extension.', 'PHP_GETIMAGESIZE_SUPPORT' => 'PHP function getimagesize() is available', 'PHP_GETIMAGESIZE_SUPPORT_EXPLAIN' => 'Required - In order for phpBB to function correctly, the getimagesize function needs to be available.', + 'PHP_JSON_SUPPORT' => 'PHP JSON support', + 'PHP_JSON_SUPPORT_EXPLAIN' => 'Required - In order for phpBB to function correctly, the PHP JSON extension needs to be available.', 'PHP_OPTIONAL_MODULE' => 'Optional modules', 'PHP_OPTIONAL_MODULE_EXPLAIN' => 'Optional - These modules or applications are optional. However, if they are available they will enable extra features.', 'PHP_SUPPORTED_DB' => 'Supported databases', From 90fc8fe59f5f6e53071a8ccb85d085d62491c466 Mon Sep 17 00:00:00 2001 From: Dhruv Goel Date: Fri, 20 Apr 2012 04:30:42 +0530 Subject: [PATCH 127/441] [ticket/10797] language key rank moved to common Language key RANK moved from memberlist to common. Removed from mcp language. PHPBB3-10797 --- phpBB/language/en/common.php | 1 + phpBB/language/en/mcp.php | 1 - phpBB/language/en/memberlist.php | 1 - 3 files changed, 1 insertion(+), 2 deletions(-) diff --git a/phpBB/language/en/common.php b/phpBB/language/en/common.php index 005640b7dd..dc6bab3ce2 100644 --- a/phpBB/language/en/common.php +++ b/phpBB/language/en/common.php @@ -459,6 +459,7 @@ $lang = array_merge($lang, array( 'PRIVATE_MESSAGING' => 'Private messaging', 'PROFILE' => 'User Control Panel', + 'RANK' => 'Rank', 'READING_FORUM' => 'Viewing topics in %s', 'READING_GLOBAL_ANNOUNCE' => 'Reading global announcement', 'READING_LINK' => 'Following forum link %s', diff --git a/phpBB/language/en/mcp.php b/phpBB/language/en/mcp.php index 16b55b3612..d0bcec0d9c 100644 --- a/phpBB/language/en/mcp.php +++ b/phpBB/language/en/mcp.php @@ -274,7 +274,6 @@ $lang = array_merge($lang, array( 'POST_REPORTED_SUCCESS' => 'This post has been successfully reported.', 'POST_UNLOCKED_SUCCESS' => 'Post unlocked successfully.', - 'RANK' => 'User rank', 'READ_USERNOTES' => 'User notes', 'READ_WARNINGS' => 'User warnings', 'REPORTER' => 'Reporter', diff --git a/phpBB/language/en/memberlist.php b/phpBB/language/en/memberlist.php index e71f9d6565..7dc5e6b74a 100644 --- a/phpBB/language/en/memberlist.php +++ b/phpBB/language/en/memberlist.php @@ -110,7 +110,6 @@ $lang = array_merge($lang, array( 'POST_IP' => 'Posted from IP/domain', - 'RANK' => 'Rank', 'REAL_NAME' => 'Recipient name', 'RECIPIENT' => 'Recipient', 'REMOVE_FOE' => 'Remove foe', From edf60bcd550334a521f35700d52d800b1851d693 Mon Sep 17 00:00:00 2001 From: galaxyAbstractor Date: Sat, 14 Apr 2012 18:57:21 +0200 Subject: [PATCH 128/441] [ticket/10812] Disabled register_globals check in PHP 5.4 Disabled the check for register_globals if PHP version is 5.4+ PHPBB3-10812 --- phpBB/install/install_install.php | 37 +++++++++++++++++-------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/phpBB/install/install_install.php b/phpBB/install/install_install.php index 026fc0d404..454c8b4df0 100644 --- a/phpBB/install/install_install.php +++ b/phpBB/install/install_install.php @@ -166,25 +166,28 @@ class install_install extends module 'S_LEGEND' => false, )); - // Check for register_globals being enabled - if (@ini_get('register_globals') == '1' || strtolower(@ini_get('register_globals')) == 'on') + // Don't check for register_globals on 5.4+ + if (version_compare($php_version, '5.4.0-dev') < 0) { - $result = '' . $lang['NO'] . ''; + // Check for register_globals being enabled + if (@ini_get('register_globals') == '1' || strtolower(@ini_get('register_globals')) == 'on') + { + $result = '' . $lang['NO'] . ''; + } + else + { + $result = '' . $lang['YES'] . ''; + } + + $template->assign_block_vars('checks', array( + 'TITLE' => $lang['PHP_REGISTER_GLOBALS'], + 'TITLE_EXPLAIN' => $lang['PHP_REGISTER_GLOBALS_EXPLAIN'], + 'RESULT' => $result, + + 'S_EXPLAIN' => true, + 'S_LEGEND' => false, + )); } - else - { - $result = '' . $lang['YES'] . ''; - } - - $template->assign_block_vars('checks', array( - 'TITLE' => $lang['PHP_REGISTER_GLOBALS'], - 'TITLE_EXPLAIN' => $lang['PHP_REGISTER_GLOBALS_EXPLAIN'], - 'RESULT' => $result, - - 'S_EXPLAIN' => true, - 'S_LEGEND' => false, - )); - // Check for url_fopen if (@ini_get('allow_url_fopen') == '1' || strtolower(@ini_get('allow_url_fopen')) == 'on') From 4788705a9a885df4bc9af834d6911a8c9919ce0b Mon Sep 17 00:00:00 2001 From: Dhruv Goel Date: Sun, 15 Apr 2012 15:01:32 +0530 Subject: [PATCH 129/441] [ticket/10815] enables feed feature by default for a fresh install PHPBB3-10815 --- phpBB/install/schemas/schema_data.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/install/schemas/schema_data.sql b/phpBB/install/schemas/schema_data.sql index fcc372ae93..efc81e37c0 100644 --- a/phpBB/install/schemas/schema_data.sql +++ b/phpBB/install/schemas/schema_data.sql @@ -99,7 +99,7 @@ INSERT INTO phpbb_config (config_name, config_value) VALUES ('email_package_size INSERT INTO phpbb_config (config_name, config_value) VALUES ('enable_confirm', '1'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('enable_pm_icons', '1'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('enable_post_confirm', '1'); -INSERT INTO phpbb_config (config_name, config_value) VALUES ('feed_enable', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('feed_enable', '1'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('feed_http_auth', '0'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('feed_limit_post', '15'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('feed_limit_topic', '10'); From de70b17b1dc19e19faa0d56395a1aba8868c9624 Mon Sep 17 00:00:00 2001 From: Patrick Webster Date: Fri, 20 Apr 2012 23:50:49 -0500 Subject: [PATCH 130/441] [ticket/10492] Separate config generation from the installer PHPBB3-10492 --- phpBB/includes/functions_install.php | 52 +++++++++++++++++++ phpBB/install/install_install.php | 28 +--------- .../phpbb_database_test_case.php | 40 ++------------ .../phpbb_test_case_helpers.php | 45 ++++++++++++++++ 4 files changed, 102 insertions(+), 63 deletions(-) diff --git a/phpBB/includes/functions_install.php b/phpBB/includes/functions_install.php index 6caa5c943f..633b2755f0 100644 --- a/phpBB/includes/functions_install.php +++ b/phpBB/includes/functions_install.php @@ -512,4 +512,56 @@ function adjust_language_keys_callback($matches) } } +/** +* Creates the output to be stored in a phpBB config.php file +* +* @param array $data Array containing the database connection information +* @param string $dbms The name of the DBAL class to use +* @param array $load_extensions Array of additional extensions that should be loaded +* @param bool $debug If the debug constants should be enabled by default or not +* +* @return string The output to write to the file +*/ +function phpbb_create_config_file_data($data, $dbms, $load_extensions, $debug = false) +{ + $load_extensions = implode(',', $load_extensions); + + $config_data = " $dbms, + 'dbhost' => $data['dbhost'], + 'dbport' => $data['dbport'], + 'dbname' => $data['dbname'], + 'dbuser' => $data['dbuser'], + 'dbpasswd' => htmlspecialchars_decode($data['dbpasswd']), + 'table_prefix' => $data['table_prefix'], + 'acm_type' => 'file', + 'load_extensions' => $load_extensions, + ); + + foreach ($config_data_array as $key => $value) + { + $config_data .= "\${$key} = '" . str_replace("'", "\\'", str_replace('\\', '\\\\', $value)) . "';\n"; + } + + $config_data .= "\n@define('PHPBB_INSTALLED', true);\n"; + + if ($debug) + { + $config_data .= "@define('DEBUG', true);\n"; + $config_data .= "@define('DEBUG_EXTRA', true);\n"; + } + else + { + $config_data .= "// @define('DEBUG', true);\n"; + $config_data .= "// @define('DEBUG_EXTRA', true);\n"; + } + + $config_data .= '?' . '>'; // Done this to prevent highlighting editors getting confused! + + return $config_data; +} + ?> \ No newline at end of file diff --git a/phpBB/install/install_install.php b/phpBB/install/install_install.php index 454c8b4df0..81dac9ecde 100644 --- a/phpBB/install/install_install.php +++ b/phpBB/install/install_install.php @@ -884,34 +884,8 @@ class install_install extends module @chmod($phpbb_root_path . 'cache/install_lock', 0777); - $load_extensions = implode(',', $load_extensions); - // Time to convert the data provided into a config file - $config_data = " $available_dbms[$data['dbms']]['DRIVER'], - 'dbhost' => $data['dbhost'], - 'dbport' => $data['dbport'], - 'dbname' => $data['dbname'], - 'dbuser' => $data['dbuser'], - 'dbpasswd' => htmlspecialchars_decode($data['dbpasswd']), - 'table_prefix' => $data['table_prefix'], - 'acm_type' => 'file', - 'load_extensions' => $load_extensions, - ); - - foreach ($config_data_array as $key => $value) - { - $config_data .= "\${$key} = '" . str_replace("'", "\\'", str_replace('\\', '\\\\', $value)) . "';\n"; - } - unset($config_data_array); - - $config_data .= "\n@define('PHPBB_INSTALLED', true);\n"; - $config_data .= "// @define('DEBUG', true);\n"; - $config_data .= "// @define('DEBUG_EXTRA', true);\n"; - $config_data .= '?' . '>'; // Done this to prevent highlighting editors getting confused! + $config_data = phpbb_create_config_file_data($data, $available_dbms[$data['dbms']]['DRIVER'], $load_extensions); // Attempt to write out the config file directly. If it works, this is the easiest way to do it ... if ((file_exists($phpbb_root_path . 'config.' . $phpEx) && phpbb_is_writable($phpbb_root_path . 'config.' . $phpEx)) || phpbb_is_writable($phpbb_root_path)) diff --git a/tests/test_framework/phpbb_database_test_case.php b/tests/test_framework/phpbb_database_test_case.php index fdb662b284..e742b543b0 100644 --- a/tests/test_framework/phpbb_database_test_case.php +++ b/tests/test_framework/phpbb_database_test_case.php @@ -40,46 +40,14 @@ abstract class phpbb_database_test_case extends PHPUnit_Extensions_Database_Test public function get_database_config() { - if (isset($_SERVER['PHPBB_TEST_DBMS'])) - { - return array( - 'dbms' => isset($_SERVER['PHPBB_TEST_DBMS']) ? $_SERVER['PHPBB_TEST_DBMS'] : '', - 'dbhost' => isset($_SERVER['PHPBB_TEST_DBHOST']) ? $_SERVER['PHPBB_TEST_DBHOST'] : '', - 'dbport' => isset($_SERVER['PHPBB_TEST_DBPORT']) ? $_SERVER['PHPBB_TEST_DBPORT'] : '', - 'dbname' => isset($_SERVER['PHPBB_TEST_DBNAME']) ? $_SERVER['PHPBB_TEST_DBNAME'] : '', - 'dbuser' => isset($_SERVER['PHPBB_TEST_DBUSER']) ? $_SERVER['PHPBB_TEST_DBUSER'] : '', - 'dbpasswd' => isset($_SERVER['PHPBB_TEST_DBPASSWD']) ? $_SERVER['PHPBB_TEST_DBPASSWD'] : '', - ); - } - else if (file_exists(dirname(__FILE__) . '/../test_config.php')) - { - include(dirname(__FILE__) . '/../test_config.php'); + $config = phpbb_test_case_helpers::get_test_config(); - return array( - 'dbms' => $dbms, - 'dbhost' => $dbhost, - 'dbport' => $dbport, - 'dbname' => $dbname, - 'dbuser' => $dbuser, - 'dbpasswd' => $dbpasswd, - ); - } - else if (extension_loaded('sqlite') && version_compare(PHPUnit_Runner_Version::id(), '3.4.15', '>=')) - { - // Silently use sqlite - return array( - 'dbms' => 'sqlite', - 'dbhost' => dirname(__FILE__) . '/../phpbb_unit_tests.sqlite2', // filename - 'dbport' => '', - 'dbname' => '', - 'dbuser' => '', - 'dbpasswd' => '', - ); - } - else + if (!isset($config['dbms'])) { $this->markTestSkipped('Missing test_config.php: See first error.'); } + + return $config; } public function getConnection() diff --git a/tests/test_framework/phpbb_test_case_helpers.php b/tests/test_framework/phpbb_test_case_helpers.php index 9a7ab2d237..9c60969d76 100644 --- a/tests/test_framework/phpbb_test_case_helpers.php +++ b/tests/test_framework/phpbb_test_case_helpers.php @@ -41,4 +41,49 @@ class phpbb_test_case_helpers $this->expectedTriggerError = true; $this->test_case->setExpectedException($exceptionName, (string) $message, $errno); } + + static public function get_test_config() + { + $config = array(); + + if (extension_loaded('sqlite') && version_compare(PHPUnit_Runner_Version::id(), '3.4.15', '>=')) + { + $config = array_merge($config, array( + 'dbms' => 'sqlite', + 'dbhost' => dirname(__FILE__) . '/../phpbb_unit_tests.sqlite2', // filename + 'dbport' => '', + 'dbname' => '', + 'dbuser' => '', + 'dbpasswd' => '', + )); + } + + if (file_exists(dirname(__FILE__) . '/../test_config.php')) + { + include(dirname(__FILE__) . '/../test_config.php'); + + $config = array_merge($config, array( + 'dbms' => $dbms, + 'dbhost' => $dbhost, + 'dbport' => $dbport, + 'dbname' => $dbname, + 'dbuser' => $dbuser, + 'dbpasswd' => $dbpasswd, + )); + } + + if (isset($_SERVER['PHPBB_TEST_DBMS'])) + { + $config = array_merge($config, array( + 'dbms' => isset($_SERVER['PHPBB_TEST_DBMS']) ? $_SERVER['PHPBB_TEST_DBMS'] : '', + 'dbhost' => isset($_SERVER['PHPBB_TEST_DBHOST']) ? $_SERVER['PHPBB_TEST_DBHOST'] : '', + 'dbport' => isset($_SERVER['PHPBB_TEST_DBPORT']) ? $_SERVER['PHPBB_TEST_DBPORT'] : '', + 'dbname' => isset($_SERVER['PHPBB_TEST_DBNAME']) ? $_SERVER['PHPBB_TEST_DBNAME'] : '', + 'dbuser' => isset($_SERVER['PHPBB_TEST_DBUSER']) ? $_SERVER['PHPBB_TEST_DBUSER'] : '', + 'dbpasswd' => isset($_SERVER['PHPBB_TEST_DBPASSWD']) ? $_SERVER['PHPBB_TEST_DBPASSWD'] : '' + )); + } + + return $config; + } } From 2aa994b5ad76941689e7993707509e48438c500b Mon Sep 17 00:00:00 2001 From: Patrick Webster Date: Sat, 21 Apr 2012 04:37:57 -0500 Subject: [PATCH 131/441] [ticket/10492] Backporting functional tests PHPBB3-10492 --- phpunit.xml.all | 4 + phpunit.xml.dist | 5 + phpunit.xml.functional | 35 ++++ tests/bootstrap.php | 5 + tests/functional/browse_test.php | 26 +++ .../phpbb_functional_test_case.php | 164 ++++++++++++++++++ .../phpbb_test_case_helpers.php | 12 ++ vendor/goutte.phar | Bin 0 -> 267414 bytes 8 files changed, 251 insertions(+) create mode 100644 phpunit.xml.functional create mode 100644 tests/functional/browse_test.php create mode 100644 tests/test_framework/phpbb_functional_test_case.php create mode 100644 vendor/goutte.phar diff --git a/phpunit.xml.all b/phpunit.xml.all index 1be2830729..9e220ff559 100644 --- a/phpunit.xml.all +++ b/phpunit.xml.all @@ -14,6 +14,10 @@ ./tests/ + ./tests/functional + + + ./tests/functional diff --git a/phpunit.xml.dist b/phpunit.xml.dist index de8134da8e..f8bf063d9a 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -14,11 +14,16 @@ ./tests/ + ./tests/functional + + + ./tests/functional + functional slow diff --git a/phpunit.xml.functional b/phpunit.xml.functional new file mode 100644 index 0000000000..376d52e6d8 --- /dev/null +++ b/phpunit.xml.functional @@ -0,0 +1,35 @@ + + + + + + ./tests/ + ./tests/functional + + + ./tests/functional + + + + + + functional + + + + + + ./tests/ + + + diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 2fb805043e..d6c5d25bc8 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -19,3 +19,8 @@ require_once 'test_framework/phpbb_test_case_helpers.php'; require_once 'test_framework/phpbb_test_case.php'; require_once 'test_framework/phpbb_database_test_case.php'; require_once 'test_framework/phpbb_database_test_connection_manager.php'; + +if (version_compare(PHP_VERSION, '5.3.0-dev', '>=')) +{ + require_once 'test_framework/phpbb_functional_test_case.php'; +} diff --git a/tests/functional/browse_test.php b/tests/functional/browse_test.php new file mode 100644 index 0000000000..d056003578 --- /dev/null +++ b/tests/functional/browse_test.php @@ -0,0 +1,26 @@ +request('GET', 'index.php'); + $this->assertGreaterThan(0, $crawler->filter('.topiclist')->count()); + } + + public function test_viewforum() + { + $crawler = $this->request('GET', 'viewforum.php?f=2'); + $this->assertGreaterThan(0, $crawler->filter('.topiclist')->count()); + } +} diff --git a/tests/test_framework/phpbb_functional_test_case.php b/tests/test_framework/phpbb_functional_test_case.php new file mode 100644 index 0000000000..b5e6f7e377 --- /dev/null +++ b/tests/test_framework/phpbb_functional_test_case.php @@ -0,0 +1,164 @@ +markTestSkipped('phpbb_functional_url was not set in test_config and wasn\'t set as PHPBB_FUNCTIONAL_URL environment variable either.'); + } + + $this->client = new Goutte\Client(); + $this->root_url = self::$config['phpbb_functional_url']; + } + + public function request($method, $path) + { + return $this->client->request($method, $this->root_url . $path); + } + + // bootstrap, called after board is set up + // once per test case class + // test cases can override this + protected function bootstrap() + { + } + + public function __construct($name = NULL, array $data = array(), $dataName = '') + { + parent::__construct($name, $data, $dataName); + + $this->backupStaticAttributesBlacklist += array( + 'phpbb_functional_test_case' => array('config', 'already_installed'), + ); + + if (!static::$already_installed) + { + $this->install_board(); + $this->bootstrap(); + static::$already_installed = true; + } + } + + protected function install_board() + { + global $phpbb_root_path, $phpEx; + + self::$config = phpbb_test_case_helpers::get_test_config(); + + if (!isset(self::$config['phpbb_functional_url'])) + { + return; + } + + self::$config['table_prefix'] = 'phpbb_'; + $this->recreate_database(self::$config); + + if (file_exists($phpbb_root_path . "config.$phpEx")) + { + if (!file_exists($phpbb_root_path . "config_dev.$phpEx")) + { + rename($phpbb_root_path . "config.$phpEx", $phpbb_root_path . "config_dev.$phpEx"); + } + else + { + unlink($phpbb_root_path . "config.$phpEx"); + } + } + + // begin data + $data = array(); + + $data = array_merge($data, self::$config); + + $data = array_merge($data, array( + 'default_lang' => 'en', + 'admin_name' => 'admin', + 'admin_pass1' => 'admin', + 'admin_pass2' => 'admin', + 'board_email' => 'nobody@example.com', + )); + + $parseURL = parse_url(self::$config['phpbb_functional_url']); + + $data = array_merge($data, array( + 'email_enable' => false, + 'smtp_delivery' => false, + 'smtp_host' => '', + 'smtp_auth' => '', + 'smtp_user' => '', + 'smtp_pass' => '', + 'cookie_secure' => false, + 'force_server_vars' => false, + 'server_protocol' => $parseURL['scheme'] . '://', + 'server_name' => 'localhost', + 'server_port' => isset($parseURL['port']) ? (int) $parseURL['port'] : 80, + 'script_path' => $parseURL['path'], + )); + // end data + + $content = $this->do_request('install'); + $this->assertContains('Welcome to Installation', $content); + + $this->do_request('create_table', $data); + + file_put_contents($phpbb_root_path . "config.$phpEx", phpbb_create_config_file_data($data, self::$config['dbms'], array(), true)); + + $this->do_request('config_file', $data); + + copy($phpbb_root_path . "config.$phpEx", $phpbb_root_path . "config_test.$phpEx"); + + $this->do_request('final', $data); + } + + private function do_request($sub, $post_data = null) + { + $context = null; + + if ($post_data) + { + $context = stream_context_create(array( + 'http' => array( + 'method' => 'POST', + 'header' => 'Content-Type: application/x-www-form-urlencoded', + 'content' => http_build_query($post_data), + 'ignore_errors' => true, + ), + )); + } + + return file_get_contents(self::$config['phpbb_functional_url'] . 'install/index.php?mode=install&sub=' . $sub, false, $context); + } + + private function recreate_database($config) + { + $db_conn_mgr = new phpbb_database_test_connection_manager($config); + $db_conn_mgr->recreate_db(); + } +} diff --git a/tests/test_framework/phpbb_test_case_helpers.php b/tests/test_framework/phpbb_test_case_helpers.php index 9c60969d76..b46c36efaa 100644 --- a/tests/test_framework/phpbb_test_case_helpers.php +++ b/tests/test_framework/phpbb_test_case_helpers.php @@ -70,6 +70,11 @@ class phpbb_test_case_helpers 'dbuser' => $dbuser, 'dbpasswd' => $dbpasswd, )); + + if (isset($phpbb_functional_url)) + { + $config['phpbb_functional_url'] = $phpbb_functional_url; + } } if (isset($_SERVER['PHPBB_TEST_DBMS'])) @@ -84,6 +89,13 @@ class phpbb_test_case_helpers )); } + if (isset($_SERVER['PHPBB_FUNCTIONAL_URL'])) + { + $config = array_merge($config, array( + 'phpbb_functional_url' => isset($_SERVER['PHPBB_FUNCTIONAL_URL']) ? $_SERVER['PHPBB_FUNCTIONAL_URL'] : '', + )); + } + return $config; } } diff --git a/vendor/goutte.phar b/vendor/goutte.phar new file mode 100644 index 0000000000000000000000000000000000000000..20b7166a6717aa5b904859fc1ffe3b32106d55a8 GIT binary patch literal 267414 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 L-+lYd^KbrtSl@Ba literal 0 HcmV?d00001 From 6293bbf09949335bb8101bcef8f043750d756dc9 Mon Sep 17 00:00:00 2001 From: Patrick Webster Date: Sat, 21 Apr 2012 05:24:57 -0500 Subject: [PATCH 132/441] [ticket/10492] Fix line endings PHPBB3-10492 --- tests/functional/browse_test.php | 52 ++++++++++++++++---------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/tests/functional/browse_test.php b/tests/functional/browse_test.php index d056003578..723cf93232 100644 --- a/tests/functional/browse_test.php +++ b/tests/functional/browse_test.php @@ -1,26 +1,26 @@ -request('GET', 'index.php'); - $this->assertGreaterThan(0, $crawler->filter('.topiclist')->count()); - } - - public function test_viewforum() - { - $crawler = $this->request('GET', 'viewforum.php?f=2'); - $this->assertGreaterThan(0, $crawler->filter('.topiclist')->count()); - } -} +request('GET', 'index.php'); + $this->assertGreaterThan(0, $crawler->filter('.topiclist')->count()); + } + + public function test_viewforum() + { + $crawler = $this->request('GET', 'viewforum.php?f=2'); + $this->assertGreaterThan(0, $crawler->filter('.topiclist')->count()); + } +} From a21b367b21d811a3673145572b0bdd123ccc4767 Mon Sep 17 00:00:00 2001 From: galaxyAbstractor Date: Sat, 21 Apr 2012 14:16:55 +0200 Subject: [PATCH 133/441] [ticket/10836] Enable avatars by default at install Enables avatars and local avatar upload by default. PHPBB3-10836 --- phpBB/install/schemas/schema_data.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/phpBB/install/schemas/schema_data.sql b/phpBB/install/schemas/schema_data.sql index efc81e37c0..ba2d18da00 100644 --- a/phpBB/install/schemas/schema_data.sql +++ b/phpBB/install/schemas/schema_data.sql @@ -8,10 +8,10 @@ INSERT INTO phpbb_config (config_name, config_value) VALUES ('active_sessions', '0'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_attachments', '1'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_autologin', '1'); -INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_avatar', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_avatar', '1'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_avatar_local', '0'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_avatar_remote', '0'); -INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_avatar_upload', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_avatar_upload', '1'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_avatar_remote_upload', '0'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_bbcode', '1'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_birthdays', '1'); From 8cf0b79a4746b416e66264cc3313f46d995b1783 Mon Sep 17 00:00:00 2001 From: David King Date: Mon, 23 Apr 2012 17:16:16 -0400 Subject: [PATCH 134/441] [task/functional] Increase code coverage for functional tests PHPBB3-10758 --- tests/functional/auth_test.php | 40 ++++++++++ tests/functional/browse_test.php | 6 ++ tests/functional/lang_test.php | 37 +++++++++ .../phpbb_functional_test_case.php | 77 ++++++++++++++++++- 4 files changed, 159 insertions(+), 1 deletion(-) create mode 100644 tests/functional/auth_test.php create mode 100644 tests/functional/lang_test.php diff --git a/tests/functional/auth_test.php b/tests/functional/auth_test.php new file mode 100644 index 0000000000..e955dcb4df --- /dev/null +++ b/tests/functional/auth_test.php @@ -0,0 +1,40 @@ +login(); + + // check for logout link + $crawler = $this->request('GET', 'index.php'); + $this->assertContains($this->lang('LOGOUT_USER', 'admin'), $crawler->filter('.navbar')->text()); + } + + /** + * @depends test_login + */ + public function test_logout() + { + $this->login(); + $this->add_lang('ucp'); + + // logout + $crawler = $this->request('GET', 'ucp.php?sid=' . $this->sid . '&mode=logout'); + $this->assertContains($this->lang('LOGOUT_REDIRECT'), $crawler->filter('#message')->text()); + + // look for a register link, which should be visible only when logged out + $crawler = $this->request('GET', 'index.php'); + $this->assertContains($this->lang('REGISTER'), $crawler->filter('.navbar')->text()); + } +} diff --git a/tests/functional/browse_test.php b/tests/functional/browse_test.php index 723cf93232..26c18c4c1f 100644 --- a/tests/functional/browse_test.php +++ b/tests/functional/browse_test.php @@ -23,4 +23,10 @@ class phpbb_functional_browse_test extends phpbb_functional_test_case $crawler = $this->request('GET', 'viewforum.php?f=2'); $this->assertGreaterThan(0, $crawler->filter('.topiclist')->count()); } + + public function test_viewtopic() + { + $crawler = $this->request('GET', 'viewtopic.php?t=1'); + $this->assertGreaterThan(0, $crawler->filter('.postbody')->count()); + } } diff --git a/tests/functional/lang_test.php b/tests/functional/lang_test.php new file mode 100644 index 0000000000..f77dd511a3 --- /dev/null +++ b/tests/functional/lang_test.php @@ -0,0 +1,37 @@ +assertEquals('Board index', $this->lang('FORUM_INDEX')); + } + + public function test_add_lang() + { + $this->add_lang('ucp'); + + // Test a language string present only in the UCP language file + $this->assertEquals('Your account has now been activated. Thank you for registering.', $this->lang('ACCOUNT_ACTIVE')); + } + + public function test_add_langs() + { + $this->add_lang(array('groups', 'memberlist')); + + // Test a language string from each UCP and memberlist + $this->assertEquals('The selected group is already your default group.', $this->lang('ALREADY_DEFAULT_GROUP')); + $this->assertEquals('Profile', $this->lang('ABOUT_USER')); + } +} diff --git a/tests/test_framework/phpbb_functional_test_case.php b/tests/test_framework/phpbb_functional_test_case.php index b5e6f7e377..f14e214a78 100644 --- a/tests/test_framework/phpbb_functional_test_case.php +++ b/tests/test_framework/phpbb_functional_test_case.php @@ -6,6 +6,7 @@ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ +use Symfony\Component\BrowserKit\CookieJar; require_once __DIR__ . '/../../phpBB/includes/functions_install.php'; @@ -13,6 +14,14 @@ class phpbb_functional_test_case extends phpbb_test_case { protected $client; protected $root_url; + /** + * @var string Session ID for current test's session (each test makes its own) + */ + protected $sid; + /** + * @var array Language array used by phpBB + */ + private $lang = array(); static protected $config = array(); static protected $already_installed = false; @@ -34,8 +43,13 @@ class phpbb_functional_test_case extends phpbb_test_case $this->markTestSkipped('phpbb_functional_url was not set in test_config and wasn\'t set as PHPBB_FUNCTIONAL_URL environment variable either.'); } - $this->client = new Goutte\Client(); + $this->cookieJar = new CookieJar; + $this->client = new Goutte\Client(array(), array(), null, $this->cookieJar); $this->root_url = self::$config['phpbb_functional_url']; + // Clear the language array so that things + // that were added in other tests are gone + $this->lang = array(); + $this->add_lang('common'); } public function request($method, $path) @@ -161,4 +175,65 @@ class phpbb_functional_test_case extends phpbb_test_case $db_conn_mgr = new phpbb_database_test_connection_manager($config); $db_conn_mgr->recreate_db(); } + + protected function login() + { + $this->add_lang('ucp'); + + $crawler = $this->request('GET', 'ucp.php'); + $this->assertContains($this->lang('LOGIN_EXPLAIN_UCP'), $crawler->filter('html')->text()); + + $form = $crawler->selectButton($this->lang('LOGIN'))->form(); + $login = $this->client->submit($form, array('username' => 'admin', 'password' => 'admin')); + + $cookies = $this->cookieJar->all(); + $sid = ''; + // get the SID from the cookie + foreach ($cookies as $key => $cookie); + { + if (substr($key, -4) == '_sid') + { + $this->sid = $cookie->getValue(); + } + } + } + + protected function add_lang($lang_file) + { + global $phpbb_root_path, $phpEx; + + if (is_array($lang_file)) + { + foreach ($lang_file as $file) + { + $this->add_lang($file); + } + } + + $lang_path = "{$phpbb_root_path}language/en/$lang_file.$phpEx"; + + $lang = array(); + + if (file_exists($lang_path)) + { + include($lang_path); + } + + $this->lang = array_merge($this->lang, $lang); + } + + protected function lang() + { + $args = func_get_args(); + $key = $args[0]; + + if (empty($this->lang[$key])) + { + throw new Exception('Language key "' . $key . '" could not be found.'); + } + + $args[0] = $this->lang[$key]; + + return call_user_func_array('sprintf', $args); + } } From b82c77b38f69aa2d8030ee848042a0169592878b Mon Sep 17 00:00:00 2001 From: David King Date: Tue, 24 Apr 2012 14:10:50 -0400 Subject: [PATCH 135/441] [task/functional] Make sure missing language values are handled properly PHPBB3-10758 --- tests/functional/lang_test.php | 8 ++++++++ tests/test_framework/phpbb_functional_test_case.php | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/tests/functional/lang_test.php b/tests/functional/lang_test.php index f77dd511a3..053806a431 100644 --- a/tests/functional/lang_test.php +++ b/tests/functional/lang_test.php @@ -18,6 +18,14 @@ class phpbb_functional_lang_test extends phpbb_functional_test_case $this->assertEquals('Board index', $this->lang('FORUM_INDEX')); } + /** + * @expectedException RuntimeException + */ + public function test_lang_missing() + { + $this->assertEquals('Your account has now been activated. Thank you for registering.', $this->lang('ACCOUNT_ACTIVE')); + } + public function test_add_lang() { $this->add_lang('ucp'); diff --git a/tests/test_framework/phpbb_functional_test_case.php b/tests/test_framework/phpbb_functional_test_case.php index f14e214a78..177f93cf3b 100644 --- a/tests/test_framework/phpbb_functional_test_case.php +++ b/tests/test_framework/phpbb_functional_test_case.php @@ -229,7 +229,7 @@ class phpbb_functional_test_case extends phpbb_test_case if (empty($this->lang[$key])) { - throw new Exception('Language key "' . $key . '" could not be found.'); + throw new RuntimeException('Language key "' . $key . '" could not be found.'); } $args[0] = $this->lang[$key]; From 1a8db76a200bd0de0bf17acd89e87e4875513d4c Mon Sep 17 00:00:00 2001 From: galaxyAbstractor Date: Sat, 21 Apr 2012 22:52:11 +0200 Subject: [PATCH 136/441] [ticket/10836] Check if avatar directory is writable after install Check if the avatar directory is writeable after the installation is complete. If it isn't, disable avatars and avatar uploading by default. PHPBB3-10836 --- phpBB/install/install_install.php | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/phpBB/install/install_install.php b/phpBB/install/install_install.php index 81dac9ecde..35fc0bb58e 100644 --- a/phpBB/install/install_install.php +++ b/phpBB/install/install_install.php @@ -105,6 +105,7 @@ class install_install extends module $this->add_language($mode, $sub); $this->add_bots($mode, $sub); $this->email_admin($mode, $sub); + $this->disable_avatars_if_unwritable(); // Remove the lock file @unlink($phpbb_root_path . 'cache/install_lock'); @@ -1941,6 +1942,21 @@ class install_install extends module )); } + /** + * Check if the avatar directory is writable and disable avatars + * if it isn't writable. + */ + function disable_avatars_if_unwritable() + { + global $phpbb_root_path; + + if (!phpbb_is_writable($phpbb_root_path . 'images/avatars/upload/')) + { + set_config('allow_avatar', 0); + set_config('allow_avatar_upload', 0); + } + } + /** * Generate a list of available mail server authentication methods */ From 02cc32b901d29df4b67c0d09c02370cbaf61170d Mon Sep 17 00:00:00 2001 From: Senky Date: Mon, 16 Apr 2012 15:19:10 +0200 Subject: [PATCH 137/441] [ticket/10161] coding-guidelines.html updated PHPBB3-10161 --- phpBB/docs/coding-guidelines.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/docs/coding-guidelines.html b/phpBB/docs/coding-guidelines.html index 6d428916c7..e60d20cd43 100644 --- a/phpBB/docs/coding-guidelines.html +++ b/phpBB/docs/coding-guidelines.html @@ -356,7 +356,7 @@ phpbb_dir_subdir_class_name - includes/dir/subdir/class_name.php

    The basic philosophy here is to not hurt code clarity for the sake of laziness. This has to be balanced by a little bit of common sense, though; print_login_status_for_a_given_user() goes too far, for example -- that function would be better named print_user_login_status(), or just print_login_status().

    Special Namings:

    -

    For all emoticons use the term smiley in singular and smilies in plural.

    +

    For all emoticons use the term smiley in singular and smilies in plural. For emails we use the term email (without dash between “e” and “m”)

    2.ii. Code Layout

    From 0858a8023be7b01e308959383bc1f955dbd4bf2d Mon Sep 17 00:00:00 2001 From: Senky Date: Mon, 16 Apr 2012 23:53:11 +0200 Subject: [PATCH 138/441] [ticket/10161] added fullstop to the end of sentence PHPBB3-10161 --- phpBB/docs/coding-guidelines.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/docs/coding-guidelines.html b/phpBB/docs/coding-guidelines.html index e60d20cd43..3f2c142ac6 100644 --- a/phpBB/docs/coding-guidelines.html +++ b/phpBB/docs/coding-guidelines.html @@ -356,7 +356,7 @@ phpbb_dir_subdir_class_name - includes/dir/subdir/class_name.php

    The basic philosophy here is to not hurt code clarity for the sake of laziness. This has to be balanced by a little bit of common sense, though; print_login_status_for_a_given_user() goes too far, for example -- that function would be better named print_user_login_status(), or just print_login_status().

    Special Namings:

    -

    For all emoticons use the term smiley in singular and smilies in plural. For emails we use the term email (without dash between “e” and “m”)

    +

    For all emoticons use the term smiley in singular and smilies in plural. For emails we use the term email (without dash between “e” and “m”).

    2.ii. Code Layout

    From 8d45901657801dcbf33ac2936559dbfe2ac373d8 Mon Sep 17 00:00:00 2001 From: galaxyAbstractor Date: Fri, 27 Apr 2012 22:19:41 +0200 Subject: [PATCH 139/441] [ticket/10849] Added missing helptext for listitem Added the missing helptext for list item in subsilver2. PHPBB3-10849 --- phpBB/styles/subsilver2/template/posting_buttons.html | 1 + 1 file changed, 1 insertion(+) diff --git a/phpBB/styles/subsilver2/template/posting_buttons.html b/phpBB/styles/subsilver2/template/posting_buttons.html index a9105b5eec..cfe69dee56 100644 --- a/phpBB/styles/subsilver2/template/posting_buttons.html +++ b/phpBB/styles/subsilver2/template/posting_buttons.html @@ -16,6 +16,7 @@ q: '{LA_BBCODE_Q_HELP}', c: '{LA_BBCODE_C_HELP}', l: '{LA_BBCODE_L_HELP}', + e: '{LA_BBCODE_LISTITEM_HELP}', o: '{LA_BBCODE_O_HELP}', p: '{LA_BBCODE_P_HELP}', w: '{LA_BBCODE_W_HELP}', From 51347ebc09d18a55fa93fe86ef50a215148c935f Mon Sep 17 00:00:00 2001 From: Vjacheslav Trushkin Date: Sun, 29 Apr 2012 00:30:08 +0300 Subject: [PATCH 140/441] [ticket/10800] Changing template paths in tests Changing template paths in tests from absolute to relative PHPBB3-10800 --- tests/template/template_includejs_test.php | 7 +++---- tests/template/template_locate_test.php | 6 +++--- tests/template/template_test.php | 2 +- tests/template/template_test_case.php | 4 +++- tests/template/template_test_case_with_tree.php | 4 ++-- 5 files changed, 12 insertions(+), 11 deletions(-) diff --git a/tests/template/template_includejs_test.php b/tests/template/template_includejs_test.php index 632fde61d1..d80254072b 100644 --- a/tests/template/template_includejs_test.php +++ b/tests/template/template_includejs_test.php @@ -17,11 +17,10 @@ class phpbb_template_template_includejs_test extends phpbb_template_template_tes $this->setup_engine(array('assets_version' => 1)); // Prepare correct result - $dir = dirname(__FILE__); $scripts = array( - '', - '', - '' + '', + '', + '' ); // Run test diff --git a/tests/template/template_locate_test.php b/tests/template/template_locate_test.php index d6e2e82a47..be9ae06809 100644 --- a/tests/template/template_locate_test.php +++ b/tests/template/template_locate_test.php @@ -17,21 +17,21 @@ class phpbb_template_template_locate_test extends phpbb_template_template_test_c // First element of the array is test name - keep them distinct array( 'simple inheritance - only parent template exists', - dirname(__FILE__) . '/parent_templates/parent_only.html', + $this->test_path . '/parent_templates/parent_only.html', 'parent_only.html', false, true, ), array( 'simple inheritance - only child template exists', - dirname(__FILE__) . '/templates/child_only.html', + $this->test_path . '/templates/child_only.html', 'child_only.html', false, true, ), array( 'simple inheritance - both parent and child templates exist', - dirname(__FILE__) . '/templates/parent_and_child.html', + $this->test_path . '/templates/parent_and_child.html', 'parent_and_child.html', false, true, diff --git a/tests/template/template_test.php b/tests/template/template_test.php index 739bbe9387..f8677ed913 100644 --- a/tests/template/template_test.php +++ b/tests/template/template_test.php @@ -277,7 +277,7 @@ class phpbb_template_template_test extends phpbb_template_template_test_case $this->template->set_filenames(array('test' => $filename)); $this->assertFileNotExists($this->template_path . '/' . $filename, 'Testing missing file, file cannot exist'); - $expecting = sprintf('style resource locator: File for handle test does not exist. Could not find: %s', realpath($this->template_path . '/../') . '/templates/' . $filename); + $expecting = sprintf('style resource locator: File for handle test does not exist. Could not find: %s', $this->test_path . '/templates/' . $filename); $this->setExpectedTriggerError(E_USER_ERROR, $expecting); $this->display('test'); diff --git a/tests/template/template_test_case.php b/tests/template/template_test_case.php index d660aa3f56..dd0acba6cd 100644 --- a/tests/template/template_test_case.php +++ b/tests/template/template_test_case.php @@ -18,6 +18,8 @@ class phpbb_template_template_test_case extends phpbb_test_case protected $style_resource_locator; protected $style_provider; + protected $test_path = 'tests/template'; + // Keep the contents of the cache for debugging? const PRESERVE_CACHE = true; @@ -63,7 +65,7 @@ class phpbb_template_template_test_case extends phpbb_test_case $defaults = $this->config_defaults(); $config = new phpbb_config(array_merge($defaults, $new_config)); - $this->template_path = dirname(__FILE__) . '/templates'; + $this->template_path = $this->test_path . '/templates'; $this->style_resource_locator = new phpbb_style_resource_locator(); $this->style_provider = new phpbb_style_path_provider(); $this->template = new phpbb_template($phpbb_root_path, $phpEx, $config, $user, $this->style_resource_locator); diff --git a/tests/template/template_test_case_with_tree.php b/tests/template/template_test_case_with_tree.php index 9522c97330..05ccb7ee55 100644 --- a/tests/template/template_test_case_with_tree.php +++ b/tests/template/template_test_case_with_tree.php @@ -18,8 +18,8 @@ class phpbb_template_template_test_case_with_tree extends phpbb_template_templat $defaults = $this->config_defaults(); $config = new phpbb_config(array_merge($defaults, $new_config)); - $this->template_path = dirname(__FILE__) . '/templates'; - $this->parent_template_path = dirname(__FILE__) . '/parent_templates'; + $this->template_path = $this->test_path . '/templates'; + $this->parent_template_path = $this->test_path . '/parent_templates'; $this->style_resource_locator = new phpbb_style_resource_locator(); $this->style_provider = new phpbb_style_path_provider(); $this->template = new phpbb_template($phpbb_root_path, $phpEx, $config, $user, $this->style_resource_locator); From 53a47fdcc323a5d7dc3696215cc47285a0c99042 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Wed, 18 Apr 2012 17:03:24 +0200 Subject: [PATCH 141/441] [ticket/10811] Make subscribe/unsubscribe repeatable with AJAX PHPBB3-10811 --- phpBB/assets/javascript/core.js | 25 +++++++++++++++++++ .../prosilver/template/overall_footer.html | 4 +-- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/phpBB/assets/javascript/core.js b/phpBB/assets/javascript/core.js index 74c71fca79..3c1e39fca6 100644 --- a/phpBB/assets/javascript/core.js +++ b/phpBB/assets/javascript/core.js @@ -446,5 +446,30 @@ phpbb.add_ajax_callback('alt_text', function() { el.text(alt_text); }); +/** + * This callback is based on the alt_text callback. + * + * It replaces the current text with the text in the alt-text data attribute, + * and replaces the text in the attribute with the current text so that the + * process can be repeated. + * Additionally it replaces the icon of the link and changes the link itself. + */ +phpbb.add_ajax_callback('toggle_subscribe', function() { + var el = $(this), + alt_text; + + phpbb.ajax_callbacks['alt_text'].call(this); + + if (el.attr('href').indexOf('unwatch') !== -1) + { + el.attr('href', el.attr('href').replace('unwatch', 'watch')); + el.parent().attr('class', 'icon-subscribe'); + } + else + { + el.attr('href', el.attr('href').replace('watch', 'unwatch')); + el.parent().attr('class', 'icon-unsubscribe'); + } +}); })(jQuery); // Avoid conflicts with other libraries diff --git a/phpBB/styles/prosilver/template/overall_footer.html b/phpBB/styles/prosilver/template/overall_footer.html index 2cb721073f..972d90305e 100644 --- a/phpBB/styles/prosilver/template/overall_footer.html +++ b/phpBB/styles/prosilver/template/overall_footer.html @@ -8,8 +8,8 @@

    Where to put the braces:

    -

    This one is a bit of a holy war, but we're going to use a style that can be summed up in one sentence: Braces always go on their own line. The closing brace should also always be at the same column as the corresponding opening brace, examples:

    +

    In PHP code, braces always go on their own line. The closing brace should also always be at the same column as the corresponding opening brace, examples:

     if (condition)
    @@ -427,6 +427,30 @@ function do_stuff()
     	...
     }
     	
    + +

    In JavaScript code, braces always go on the same line:

    + +
    +if (condition) {
    +	while (condition2) {
    +		...
    +	}
    +} else {
    +	...
    +}
    +
    +for (var i = 0; i < size; i++) {
    +	...
    +}
    +
    +while (condition) {
    +	...
    +}
    +
    +function do_stuff() {
    +	...
    +}
    +	

    Use spaces between tokens:

    This is another simple, easy step that helps keep code readable without much effort. Whenever you write an assignment, expression, etc.. Always leave one space between the tokens. Basically, write code as if it was English. Put spaces between variable names and operators. Don't put spaces just after an opening bracket or before a closing bracket. Don't put spaces just before a comma or a semicolon. This is best shown with a few examples, examples:

    From b83fa0349ad30eefed3e8064d29793a9b3dd17f7 Mon Sep 17 00:00:00 2001 From: Senky Date: Mon, 30 Apr 2012 21:55:24 +0200 Subject: [PATCH 143/441] [ticket/10847] fixing all misspelled "dependant" to "dependent" PHPBB3-10847 --- phpBB/develop/create_schema_files.php | 2 +- phpBB/develop/mysql_upgrader.php | 2 +- phpBB/includes/db/db_tools.php | 2 +- phpBB/includes/utf/utf_tools.php | 2 +- phpBB/language/en/acp/board.php | 2 +- phpBB/viewtopic.php | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/phpBB/develop/create_schema_files.php b/phpBB/develop/create_schema_files.php index 4088657743..7a9bda32a0 100644 --- a/phpBB/develop/create_schema_files.php +++ b/phpBB/develop/create_schema_files.php @@ -397,7 +397,7 @@ foreach ($supported_dbms as $dbms) } } - // Adjust default value if db-dependant specified + // Adjust default value if db-dependent specified if (is_array($column_data[1])) { $column_data[1] = (isset($column_data[1][$dbms])) ? $column_data[1][$dbms] : $column_data[1]['default']; diff --git a/phpBB/develop/mysql_upgrader.php b/phpBB/develop/mysql_upgrader.php index 88596e9461..e2d8c97e8b 100644 --- a/phpBB/develop/mysql_upgrader.php +++ b/phpBB/develop/mysql_upgrader.php @@ -176,7 +176,7 @@ foreach ($schema_data as $table_name => $table_data) $column_type = $dbms_type_map['mysql_41'][$column_data[0]]; } - // Adjust default value if db-dependant specified + // Adjust default value if db-dependent specified if (is_array($column_data[1])) { $column_data[1] = (isset($column_data[1][$dbms])) ? $column_data[1][$dbms] : $column_data[1]['default']; diff --git a/phpBB/includes/db/db_tools.php b/phpBB/includes/db/db_tools.php index efb8b3ebd7..73eae4e967 100644 --- a/phpBB/includes/db/db_tools.php +++ b/phpBB/includes/db/db_tools.php @@ -1503,7 +1503,7 @@ class phpbb_db_tools $column_type = $this->dbms_type_map[$this->sql_layer][$column_data[0]]; } - // Adjust default value if db-dependant specified + // Adjust default value if db-dependent specified if (is_array($column_data[1])) { $column_data[1] = (isset($column_data[1][$this->sql_layer])) ? $column_data[1][$this->sql_layer] : $column_data[1]['default']; diff --git a/phpBB/includes/utf/utf_tools.php b/phpBB/includes/utf/utf_tools.php index 9dc0634e5b..c402e15032 100644 --- a/phpBB/includes/utf/utf_tools.php +++ b/phpBB/includes/utf/utf_tools.php @@ -1933,7 +1933,7 @@ function utf8_wordwrap($string, $width = 75, $break = "\n", $cut = false) * UTF8-safe basename() function * * basename() has some limitations and is dependent on the locale setting -* according to the PHP manual. Therefore we provide our own locale independant +* according to the PHP manual. Therefore we provide our own locale independent * basename function. * * @param string $filename The filename basename() should be applied to diff --git a/phpBB/language/en/acp/board.php b/phpBB/language/en/acp/board.php index 758ef8ed82..7e3c227893 100644 --- a/phpBB/language/en/acp/board.php +++ b/phpBB/language/en/acp/board.php @@ -411,7 +411,7 @@ $lang = array_merge($lang, array( // Server Settings $lang = array_merge($lang, array( - 'ACP_SERVER_SETTINGS_EXPLAIN' => 'Here you define server and domain dependant settings. Please ensure the data you enter is accurate, errors will result in emails containing incorrect information. When entering the domain name remember it does include http:// or other protocol term. Only alter the port number if you know your server uses a different value, port 80 is correct in most cases.', + 'ACP_SERVER_SETTINGS_EXPLAIN' => 'Here you define server and domain dependent settings. Please ensure the data you enter is accurate, errors will result in emails containing incorrect information. When entering the domain name remember it does include http:// or other protocol term. Only alter the port number if you know your server uses a different value, port 80 is correct in most cases.', 'ENABLE_GZIP' => 'Enable GZip compression', 'ENABLE_GZIP_EXPLAIN' => 'Generated content will be compressed prior to sending it to the user. This can reduce network traffic but will also increase CPU usage on both server and client side. Requires zlib PHP extension to be loaded.', diff --git a/phpBB/viewtopic.php b/phpBB/viewtopic.php index 1f167ed722..b75f4aeccf 100644 --- a/phpBB/viewtopic.php +++ b/phpBB/viewtopic.php @@ -1099,7 +1099,7 @@ while ($row = $db->sql_fetchrow($result)) { $user_sig = ''; - // We add the signature to every posters entry because enable_sig is post dependant + // We add the signature to every posters entry because enable_sig is post dependent if ($row['user_sig'] && $config['allow_sig'] && $user->optionget('viewsigs')) { $user_sig = $row['user_sig']; From 665f38d42f8692f5eab76348568ddb46b372492d Mon Sep 17 00:00:00 2001 From: Senky Date: Mon, 30 Apr 2012 22:01:53 +0200 Subject: [PATCH 144/441] [ticket/10846] fixing SQL query bug in acp_main.php PHPBB3-10846 --- phpBB/includes/acp/acp_main.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/includes/acp/acp_main.php b/phpBB/includes/acp/acp_main.php index e529ae0e5a..cffe296651 100644 --- a/phpBB/includes/acp/acp_main.php +++ b/phpBB/includes/acp/acp_main.php @@ -201,7 +201,7 @@ class acp_main // No maximum post id? :o if (!$max_post_id) { - $sql = 'SELECT MAX(post_id) + $sql = 'SELECT MAX(post_id) as max_post_id FROM ' . POSTS_TABLE; $result = $db->sql_query($sql); $max_post_id = (int) $db->sql_fetchfield('max_post_id'); From 2dd71f65204c8e484c81147e4966e33fcb7d1f42 Mon Sep 17 00:00:00 2001 From: Senky Date: Tue, 1 May 2012 09:52:48 +0200 Subject: [PATCH 145/441] [ticket/10835] fixing misleading message in UCP PHPBB3-10835 --- phpBB/language/en/ucp.php | 3 ++- phpBB/styles/prosilver/template/ucp_profile_reg_details.html | 4 ++-- phpBB/styles/subsilver2/template/ucp_profile_reg_details.html | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/phpBB/language/en/ucp.php b/phpBB/language/en/ucp.php index 3ebc863447..fb417a5742 100644 --- a/phpBB/language/en/ucp.php +++ b/phpBB/language/en/ucp.php @@ -137,7 +137,8 @@ $lang = array_merge($lang, array( 'CREATE_FOLDER' => 'Add folder…', 'CURRENT_IMAGE' => 'Current image', 'CURRENT_PASSWORD' => 'Current password', - 'CURRENT_PASSWORD_EXPLAIN' => 'You must confirm your current password if you wish to change it, alter your e-mail address or username.', + 'CURRENT_PASSWORD_EXPLAIN' => 'You must enter your current password if you wish to alter your e-mail address or username.', + 'CURRENT_CHANGE_PASSWORD_EXPLAIN' => 'You must enter your current password if you wish to change it, alter your e-mail address or username.', 'CUR_PASSWORD_EMPTY' => 'You did not enter your current password.', 'CUR_PASSWORD_ERROR' => 'The current password you entered is incorrect.', 'CUSTOM_DATEFORMAT' => 'Custom…', diff --git a/phpBB/styles/prosilver/template/ucp_profile_reg_details.html b/phpBB/styles/prosilver/template/ucp_profile_reg_details.html index edd58d5e25..5eb55dc71c 100644 --- a/phpBB/styles/prosilver/template/ucp_profile_reg_details.html +++ b/phpBB/styles/prosilver/template/ucp_profile_reg_details.html @@ -45,7 +45,7 @@
    -

    {L_CURRENT_PASSWORD_EXPLAIN}
    +

    {L_CURRENT_CHANGE_PASSWORD_EXPLAIN}{L_CURRENT_PASSWORD_EXPLAIN}
    @@ -54,7 +54,7 @@
    - {S_HIDDEN_FIELDS}  + {S_HIDDEN_FIELDS}  {S_FORM_TOKEN}
    diff --git a/phpBB/styles/subsilver2/template/ucp_profile_reg_details.html b/phpBB/styles/subsilver2/template/ucp_profile_reg_details.html index 78fb5a9628..09f60ad5a7 100644 --- a/phpBB/styles/subsilver2/template/ucp_profile_reg_details.html +++ b/phpBB/styles/subsilver2/template/ucp_profile_reg_details.html @@ -42,7 +42,7 @@ {L_CONFIRM_CHANGES} - {L_CURRENT_PASSWORD}:
    {L_CURRENT_PASSWORD_EXPLAIN} + {L_CURRENT_PASSWORD}:
    {L_CURRENT_CHANGE_PASSWORD_EXPLAIN}{L_CURRENT_PASSWORD_EXPLAIN} From 5114edcafe440df04357d789c03b390d6da48db5 Mon Sep 17 00:00:00 2001 From: Vjacheslav Trushkin Date: Tue, 1 May 2012 17:41:46 +0300 Subject: [PATCH 146/441] [ticket/10800] Changing html to js for includejs tests Changing .html to .js files for includejs tests PHPBB3-10800 --- tests/template/parent_templates/parent_and_child.js | 1 + tests/template/parent_templates/parent_only.js | 1 + tests/template/template_includejs_test.php | 8 ++++---- tests/template/templates/child_only.js | 1 + tests/template/templates/includejs.html | 4 ++-- tests/template/templates/parent_and_child.js | 1 + 6 files changed, 10 insertions(+), 6 deletions(-) create mode 100644 tests/template/parent_templates/parent_and_child.js create mode 100644 tests/template/parent_templates/parent_only.js create mode 100644 tests/template/templates/child_only.js create mode 100644 tests/template/templates/parent_and_child.js diff --git a/tests/template/parent_templates/parent_and_child.js b/tests/template/parent_templates/parent_and_child.js new file mode 100644 index 0000000000..6d9bb163bf --- /dev/null +++ b/tests/template/parent_templates/parent_and_child.js @@ -0,0 +1 @@ +// JavaScript file in a parent style. diff --git a/tests/template/parent_templates/parent_only.js b/tests/template/parent_templates/parent_only.js new file mode 100644 index 0000000000..9c3007d83f --- /dev/null +++ b/tests/template/parent_templates/parent_only.js @@ -0,0 +1 @@ +// JavaScript file only in parent style. diff --git a/tests/template/template_includejs_test.php b/tests/template/template_includejs_test.php index d80254072b..a8f9a9037f 100644 --- a/tests/template/template_includejs_test.php +++ b/tests/template/template_includejs_test.php @@ -18,13 +18,13 @@ class phpbb_template_template_includejs_test extends phpbb_template_template_tes // Prepare correct result $scripts = array( - '', - '', - '' + '', + '', + '' ); // Run test $cache_file = $this->template->cachepath . 'includejs.html.php'; - $this->run_template('includejs.html', array('PARENT' => 'parent_only.html'), array(), array(), implode('', $scripts), $cache_file); + $this->run_template('includejs.html', array('PARENT' => 'parent_only.js'), array(), array(), implode('', $scripts), $cache_file); } } diff --git a/tests/template/templates/child_only.js b/tests/template/templates/child_only.js new file mode 100644 index 0000000000..542b26526c --- /dev/null +++ b/tests/template/templates/child_only.js @@ -0,0 +1 @@ +// JavaScript file only in a child style. diff --git a/tests/template/templates/includejs.html b/tests/template/templates/includejs.html index 186fc30b43..8a2587d76b 100644 --- a/tests/template/templates/includejs.html +++ b/tests/template/templates/includejs.html @@ -1,5 +1,5 @@ - + - + {SCRIPTS} \ No newline at end of file diff --git a/tests/template/templates/parent_and_child.js b/tests/template/templates/parent_and_child.js new file mode 100644 index 0000000000..d544d94d83 --- /dev/null +++ b/tests/template/templates/parent_and_child.js @@ -0,0 +1 @@ +// JavaScript file in a child style. From 63b41913a472a688b5b85bdbbd01e45366449781 Mon Sep 17 00:00:00 2001 From: Vjacheslav Trushkin Date: Tue, 1 May 2012 18:25:11 +0300 Subject: [PATCH 147/441] [ticket/10799] Removing global variable from includejs Removing global $phpbb_root_path from includejs implementation PHPBB3-10799 --- phpBB/includes/template/filter.php | 4 ++-- phpBB/includes/template/template.php | 7 ++++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/phpBB/includes/template/filter.php b/phpBB/includes/template/filter.php index 4a2593b757..ad2e35de6a 100644 --- a/phpBB/includes/template/filter.php +++ b/phpBB/includes/template/filter.php @@ -905,12 +905,12 @@ class phpbb_template_filter extends php_user_filter if (substr($filename, 0, strlen($this->phpbb_root_path)) != $this->phpbb_root_path) { // Absolute path, include as is - return ' $_template->_js_include(\'' . addslashes($filename) . '\', false); '; + return ' $_template->_js_include(\'' . addslashes($filename) . '\', false, false); '; } // Relative path, remove root path from it $filename = substr($filename, strlen($this->phpbb_root_path)); - return ' global $phpbb_root_path; $_template->_js_include($phpbb_root_path . \'' . addslashes($filename) . '\', false); '; + return ' $_template->_js_include(\'' . addslashes($filename) . '\', false, true); '; } /** diff --git a/phpBB/includes/template/template.php b/phpBB/includes/template/template.php index e6512c8417..8ab3c44be3 100644 --- a/phpBB/includes/template/template.php +++ b/phpBB/includes/template/template.php @@ -496,14 +496,19 @@ class phpbb_template * * @param string $file file name * @param bool $locate True if file needs to be located + * @param bool $relative True if path is relative to phpBB root directory. Ignored if $locate == true */ - public function _js_include($file, $locate = false) + public function _js_include($file, $locate = false, $relative = false) { // Locate file if ($locate) { $file = $this->locator->get_first_file_location(array($file), true, true); } + else if ($relative) + { + $file = $this->phpbb_root_path . $file; + } $file .= (strpos($file, '?') === false) ? '?' : '&'; $file .= 'assets_version=' . $this->config['assets_version']; From 7294c7143144b06dde799936e7631493b1df4e6c Mon Sep 17 00:00:00 2001 From: Vinny Date: Thu, 26 Apr 2012 21:19:08 -0300 Subject: [PATCH 148/441] [ticket/10778] Remove extra space from close link in prosilver smilies window PHPBB3-10778 --- phpBB/styles/prosilver/template/posting_smilies.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/styles/prosilver/template/posting_smilies.html b/phpBB/styles/prosilver/template/posting_smilies.html index 84191588e2..d3d6293586 100644 --- a/phpBB/styles/prosilver/template/posting_smilies.html +++ b/phpBB/styles/prosilver/template/posting_smilies.html @@ -18,6 +18,6 @@
    {PAGINATION}
    -{L_CLOSE_WINDOW} +{L_CLOSE_WINDOW} From ed67dcf3d83d40623471fe191fdc415289c59c21 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Wed, 2 May 2012 21:12:18 +0200 Subject: [PATCH 149/441] [ticket/10818] Global Announcements Update Dialog should call exit_handler() PHPBB3-10818 --- phpBB/install/database_update.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/install/database_update.php b/phpBB/install/database_update.php index a0892005d2..665db1f2f0 100644 --- a/phpBB/install/database_update.php +++ b/phpBB/install/database_update.php @@ -260,7 +260,7 @@ if ($has_global && !$ga_forum_id) Date: Thu, 3 May 2012 22:30:22 +0100 Subject: [PATCH 150/441] [ticket/10855] Added array trailing commas info in js to guidelines. PHPBB3-10855 --- phpBB/docs/coding-guidelines.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/docs/coding-guidelines.html b/phpBB/docs/coding-guidelines.html index fbec59a6ff..be78ad0b3b 100644 --- a/phpBB/docs/coding-guidelines.html +++ b/phpBB/docs/coding-guidelines.html @@ -526,7 +526,7 @@ $post_url = "{$phpbb_root_path}posting.$phpEx?mode=$mode&amp;start=$start";

    In SQL statements mixing single and double quotes is partly allowed (following the guidelines listed here about SQL formatting), else one should try to only use one method - mostly single quotes.

    Commas after every array element:

    -

    If an array is defined with each element on its own line, you still have to modify the previous line to add a comma when appending a new element. PHP allows for trailing (useless) commas in array definitions. These should always be used so each element including the comma can be appended with a single line

    +

    If an array is defined with each element on its own line, you still have to modify the previous line to add a comma when appending a new element. PHP allows for trailing (useless) commas in array definitions. These should always be used so each element including the comma can be appended with a single line. In JavaScript, you should not use the trailing comma, as IE doesn't like it.

    // wrong

    
    From 06efa6c0beac3cb4fed0e7412c3b60f91f4181bb Mon Sep 17 00:00:00 2001
    From: Callum Macrae 
    Date: Thu, 3 May 2012 22:34:35 +0100
    Subject: [PATCH 151/441] [ticket/10855] Added JS camelCaps info to guidelines.
    
    PHPBB3-10855
    ---
     phpBB/docs/coding-guidelines.html | 10 ++++++++--
     1 file changed, 8 insertions(+), 2 deletions(-)
    
    diff --git a/phpBB/docs/coding-guidelines.html b/phpBB/docs/coding-guidelines.html
    index be78ad0b3b..237bc18d20 100644
    --- a/phpBB/docs/coding-guidelines.html
    +++ b/phpBB/docs/coding-guidelines.html
    @@ -295,11 +295,17 @@ PHPBB_QA                   (Set board to QA-Mode, which means the updater also c
     	

    We will not be using any form of hungarian notation in our naming conventions. Many of us believe that hungarian naming is one of the primary code obfuscation techniques currently in use.

    Variable Names:

    -

    Variable names should be in all lowercase, with words separated by an underscore, example:

    +

    In PHP, variable names should be in all lowercase, with words separated by an underscore, example:

    $current_user is right, but $currentuser and $currentUser are not.

    + +

    In JavaScript, variable names should use camel caps:

    + +
    +

    currentUser is right, but currentuser and current_user are not.

    +

    Names should be descriptive, but concise. We don't want huge sentences as our variable names, but typing an extra couple of characters is always better than wondering what exactly a certain variable is for.

    @@ -317,7 +323,7 @@ for ($i = 0; $i < $outer_size; $i++)

    Function Names:

    -

    Functions should also be named descriptively. We're not programming in C here, we don't want to write functions called things like "stristr()". Again, all lower-case names with words separated by a single underscore character. Function names should preferably have a verb in them somewhere. Good function names are print_login_status(), get_user_data(), etc.

    +

    Functions should also be named descriptively. We're not programming in C here, we don't want to write functions called things like "stristr()". Again, all lower-case names with words separated by a single underscore character in PHP, and camel caps in JavaScript. Function names should preferably have a verb in them somewhere. Good function names are print_login_status(), get_user_data(), etc. Constructor functions in JavaScript should begin with a capital letter.

    Function Arguments:

    Arguments are subject to the same guidelines as variable names. We don't want a bunch of functions like: do_stuff($a, $b, $c). In most cases, we'd like to be able to tell how to use a function by just looking at its declaration.

    From 0e906f2575892d25a359f3ad8020e8f66b91054d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20Fr=C3=A8rejean?= Date: Fri, 4 May 2012 00:13:27 +0200 Subject: [PATCH 152/441] [task/10869] Remove PHP 5.2 check from .travis.yml The travis configuration file contains a statement that checks whether the test is ran against PHP 5.2 but as that version isn't tested at all the check can be removed. PHPBB3-10869 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 82f7d27e35..cc2383de57 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,7 +11,7 @@ before_script: - sh -c "if [ '$DB' = 'pgsql' ]; then psql -c 'DROP DATABASE IF EXISTS phpbb_tests;' -U postgres; fi" - sh -c "if [ '$DB' = 'pgsql' ]; then psql -c 'create database phpbb_tests;' -U postgres; fi" - sh -c "if [ '$DB' = 'mysql' ]; then mysql -e 'create database IF NOT EXISTS phpbb_tests;'; fi" - - sh -c "if [ '$TRAVIS_PHP_VERSION' = '5.2' ]; then pear install --force phpunit/DbUnit; else pyrus install --force phpunit/DbUnit; fi" + - pyrus install --force phpunit/DbUnit - phpenv rehash - cd phpBB - curl -s http://getcomposer.org/installer | php From fce0c5d436f7a2b3b8b39128b607e0e9d81018ea Mon Sep 17 00:00:00 2001 From: Bruno Ais Date: Fri, 4 May 2012 20:08:42 +0100 Subject: [PATCH 153/441] [ticket/10871] Delete the unwanted implode Deleted the implode that had no reason to be there PHPBB3-10871 --- phpBB/includes/mcp/mcp_queue.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/phpBB/includes/mcp/mcp_queue.php b/phpBB/includes/mcp/mcp_queue.php index 59fa8b7263..4d720a435c 100644 --- a/phpBB/includes/mcp/mcp_queue.php +++ b/phpBB/includes/mcp/mcp_queue.php @@ -268,8 +268,6 @@ class mcp_queue trigger_error('NOT_MODERATOR'); } - $forum_list = implode(', ', $forum_list); - $sql = 'SELECT SUM(forum_topics) as sum_forum_topics FROM ' . FORUMS_TABLE . ' WHERE ' . $db->sql_in_set('forum_id', $forum_list); From 58842b5ca8020b16a99f5420381a2b095bba89de Mon Sep 17 00:00:00 2001 From: Oleg Pudeyev Date: Sat, 5 May 2012 16:01:07 -0400 Subject: [PATCH 154/441] [ticket/10834] Backport general development language changes to 3.0. PHPBB3-10688 PHPBB3-10834 --- phpBB/docs/README.html | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/phpBB/docs/README.html b/phpBB/docs/README.html index aa60d7dd25..fb30ef5cba 100644 --- a/phpBB/docs/README.html +++ b/phpBB/docs/README.html @@ -106,6 +106,7 @@
    • Updates from phpBB3 RC1 to the latest version
    • +
    • Note: if using the Automatic Update Package, updates are supported from phpBB 3.0.2 onward. To update a pre-3.0.2 installation, first update to 3.0.2 and then update to the current version.
    • Conversions from phpBB 2.0.x to the latest version
    • New installations of phpBB3 - always only the latest released version
    @@ -136,13 +137,13 @@

    This is the official location for all supported language sets. If you download a package from a 3rd party site you do so with the understanding that we cannot offer support. So please, do not ask for help in these cases!

    -

    Installation of these packages is straightforward, simply download the required language pack and unarchive it into the languages/ folder. Please ensure you retain the directory structure when doing this! Once uploaded go to the Admin->System->Language Packs and install the now appeared new language pack. To install the style imageset you should download the imageset for your language and unarchive the file/s into the relevant imageset directory (styles/prosilver/imageset or styles/subsilver2/imageset), again you must retain the directory structure. Once installed the imageset will become immediately available.

    +

    Installation of these packages is straightforward, simply download the required language pack and unarchive it into the languages/ folder. Please ensure you retain the directory structure when doing this! Once uploaded go to the Admin->System->Language Packs and install the now appearing new language pack. To install the style imageset you should download the imageset for your language and unarchive the file/s into the relevant imageset directory (styles/prosilver/imageset or styles/subsilver2/imageset), again you must retain the directory structure. Once installed the imageset will become immediately available.

    If your language is not available please visit our forums where you will find a topic listing translations currently available or in preparation. This topic also gives you information should you wish to volunteer to translate a language not currently listed.

    2.ii. Styles

    -

    Although phpBB Group are rather proud of the included styles we realise that it may not be to everyones tastes. Therefore phpBB3 allows styles to be switched with relative ease. Firstly you need to locate and download a style you like. We maintain such a site at

    +

    Although phpBB Group are rather proud of the included styles we realise that they may not be to everyone's tastes. Therefore phpBB3 allows styles to be switched with relative ease. Firstly you need to locate and download a style you like. We maintain such a site at

    http://www.phpbb.com/styles/

    @@ -192,7 +193,7 @@

    phpBB Group maintains a thriving community where a number of people have generously decided to donate their time to help support users. This site can be found at:

    -

    http://www.phpbb.com/

    +

    http://www.phpbb.com/community/

    If you do seek help via our forums please be sure to do a Search before posting. This may well save both you and us time and allow the developer, moderator and support groups to spend more time responding to people with unknown issues and problems. Please also remember that phpBB is an entirely volunteer effort, no one receives any compensation for the time they give, this includes moderators as well as developers. So please be respectful and mindful when awaiting responses.

    @@ -200,6 +201,8 @@

    Another place you may find help is our IRC channel. This operates on the Freenode IRC network, irc.freenode.net and the channel is #phpbb and can be accessed by any good IRC client such as mIRC, XChat, etc. Again, please do not abuse this service and be respectful of other users.

    +

    There are other IRC channels available, please see http://www.phpbb.com/support/irc/ for the complete list.

    + @@ -216,9 +219,9 @@
    -

    This is the third stable release of phpBB. The 3.0.x line is essentially feature frozen, with only point releases seeing fixes for bugs and security issues, though feature alterations and minor feature additions may be done if deemed absolutely required. Our next major release will be phpBB 3.2 and the planning phase has begun (the unstable development version is 3.1). Please do not post questions asking when 3.2 will be available, no release date has been set.

    +

    This is the third stable release of phpBB. The 3.0.x line is essentially feature frozen, with only point releases seeing fixes for bugs and security issues, though feature alterations and minor feature additions may be done if deemed absolutely required. Our next major release will be phpBB 3.1. Please do not post questions asking when 3.1 will be available, no release date has been set.

    -

    For those interested in the development of phpBB should keep an eye on the community forums to see how things are progressing:

    +

    Those interested in the development of phpBB should keep an eye on the development forums to see how things are progressing:

    http://area51.phpbb.com/phpBB/

    @@ -240,17 +243,17 @@
    -

    The phpBB Group uses a bug tracking system to store, list and manage all reported bugs, it can be found at the location listed below. Please DO NOT post bug reports to our forums, they will be locked. In addition please DO NOT use the bug tracker for support requests. Posting such a request will only see you directed to the support forums (while taking time away from working on real bugs).

    +

    The phpBB Group uses a bug tracking system to store, list and manage all reported bugs, it can be found at the location listed below. Please DO NOT post bug reports to our forums. In addition please DO NOT use the bug tracker for support requests. Posting such a request will only see you directed to the support forums (while taking time away from working on real bugs).

    -

    http://tracker.phpbb.com/

    +

    http://tracker.phpbb.com/browse/PHPBB3

    While we very much appreciate receiving bug reports (the more reports the more stable phpBB will be) we ask you carry out a few steps before adding new entries:

      -
    • Firstly determine if your bug is reproduceable, how to determine this depends on the bug in question. Only if the bug is reproduceable it is likely to be a problem with phpBB3 (or in some way connected). If something cannot be reproduced it may turn out to have been your hosting provider working on something, a user doing something silly, etc. Bug reports for non-reproduceable events can slow down our attempts to fix real, reproduceable issues

    • +
    • Firstly determine if your bug is reproduceable, how to determine this depends on the bug in question. Only if the bug is reproduceable it is likely to be a problem with phpBB3 (or in some way connected). If something cannot be reproduced it may turn out to have been your hosting provider working on something, a user doing something silly, etc. Bug reports for non-reproduceable events can slow down our attempts to fix real, reproduceable issues.

    • Next please read or search through the existing bug reports to see if your bug (or one very similar to it) is already listed. If it is please add to that existing bug rather than creating a new duplicate entry (all this does is slow us down).

    • -
    • Check the forums (use search!) to see if people have discussed anything that sounds similar to what you are seeing. However, as noted above please DO NOT post your particular bug to the forum unless it's non-reproduceable or you are sure it's related to something you have done rather phpBB3

    • -
    • If no existing bug exists then please feel free to add it
    • +
    • Check the forums (use search!) to see if people have discussed anything that sounds similar to what you are seeing. However, as noted above please DO NOT post your particular bug to the forum unless it's non-reproduceable or you are sure it's related to something you have done rather phpBB3.

    • +
    • If no existing bug exists then please feel free to add it.

    If you do post a new bug (i.e. one that isn't already listed in the bug tracker) firstly make sure you have logged in (your username and password are the same as for the community forums) then please include the following details:

    @@ -261,10 +264,12 @@
  • DB type/version, e.g. MySQL 4.0.1, PostgreSQL 7.3.2, MSSQL Server 2000 SP1, etc.
  • -

    The relevant database type/version is listed within the administration control panel

    +

    The relevant database type/version is listed within the administration control panel.

    Please also be as detailed as you can in your report, if possible list the steps required to duplicate the problem. If you have a patch that fixes the issue, please attach it to the ticket or submit a pull request on GitHub.

    +

    If you create a patch, it is very much appreciated (but not required) if you follow the phpBB coding guidelines. Please note that the coding guidelines are somewhat different between different versions of phpBB. For phpBB 3.0.x the coding guidelines may be found here: http://area51.phpbb.com/docs/30x/coding-guidelines.html

    +

    Once a bug has been submitted you will be emailed any follow up comments added to it. Please if you are requested to supply additional information, do so! It is frustrating for us to receive bug reports, ask for additional information but get nothing. In these cases we have a policy of closing the bug, which may leave a very real problem in place. Obviously we would rather not have this situation arise.

    5.i. Security related bugs

    @@ -317,7 +322,7 @@

    Please remember that running any application on a developmental version of PHP can lead to strange/unexpected results which may appear to be bugs in the application (which may not be true). Therefore we recommend you upgrade to the newest stable version of PHP before running phpBB3. If you are running a developmental version of PHP please check any bugs you find on a system running a stable release before submitting.

    -

    This board has been developed and tested under Linux and Windows (amongst others) running Apache using MySQL 3.23, 4.x, 5.x, MSSQL Server 2000, PostgreSQL 7.x, Oracle 8, SQLite and Firebird. Versions of PHP used range from 4.3.3 to 6.0.0-dev without problem.

    +

    This board has been developed and tested under Linux and Windows (amongst others) running Apache using MySQL 3.23, 4.x, 5.x, MSSQL Server 2000, PostgreSQL 7.x, Oracle 8, SQLite and Firebird. Versions of PHP used range from 4.3.3 to 5.4.x without problem.

    7.i. Notice on PHP security issues

    From c34ee343ba1ff0c401f3a04216e9e7ffb9a1a859 Mon Sep 17 00:00:00 2001 From: Oleg Pudeyev Date: Sat, 5 May 2012 16:08:37 -0400 Subject: [PATCH 155/441] [ticket/10843] Backport changes to install language. PHPBB3-10688 PHPBB3-10843 --- phpBB/docs/INSTALL.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/phpBB/docs/INSTALL.html b/phpBB/docs/INSTALL.html index c54e408be2..6ab118e3ee 100644 --- a/phpBB/docs/INSTALL.html +++ b/phpBB/docs/INSTALL.html @@ -141,13 +141,13 @@
  • PostgreSQL 7.3+
  • SQLite 2.8.2+
  • Firebird 2.1+
  • -
  • MS SQL Server 2000 or above (directly or via ODBC)
  • +
  • MS SQL Server 2000 or above (directly or via ODBC or the native adapter)
  • Oracle
  • -
  • PHP 4.3.3+ (>=4.3.3, >4.4.x, >5.x.x, >6.0-dev (compatible)) with support for the database you intend to use.
  • +
  • PHP 4.3.3+ (>=4.3.3, >=4.4.x, >=5.x.x, >=5.4.x) with support for the database you intend to use.
  • getimagesize() function need to be enabled.
  • -
  • These optional presence of the following modules within PHP will provide access to additional features, but they are not required. +
  • Presence of the following modules within PHP will provide access to additional features, but they are not required:
    • zlib Compression support
    • Remote FTP support
    • @@ -182,7 +182,7 @@

      All .php, .inc, .sql, .cfg, .html and .txt files should be uploaded in ASCII mode, while all graphics should be uploaded in BINARY mode. If you are unfamiliar with what this means please refer to your FTP client documentation. In most cases this is all handled transparantly by your ftp client but if you encounter problems later you should be sure the files where uploaded correctly as described here.

      -

      phpBB3 comes supplied with english as its standard language. However a number of separate packs for different languages are available. If you are not a native english speaker you may wish to install one or more of these packages before continuing. The installation process below will allow you to select a default language from those available (you can of course change this default at a later stage). For more details of language packs, where to obtain them and how to install them please see the README.

      +

      phpBB3 comes supplied with British English as its standard language. However a number of separate packs for different languages are available. If you are not a native English speaker you may wish to install one or more of these packages before continuing. The installation process below will allow you to select a default language from those available (you can of course change this default at a later stage). For more details of language packs, where to obtain them and how to install them please see the README.

      Once all the files have been uploaded to your site you should point your browser at this location with the addition of install/. For example if your domain name is www.mydomain.tld and you placed phpBB3 in a directory /phpBB3 off your web root you would enter http://www.mydomain.tld/phpBB3/install/ or (alternatively) http://www.mydomain.tld/phpBB3/install/index.php into your browser. When you have done this you should see the phpBB3 Installation screen appear.

      From a960bd6790a60bd1023e632230848e9e786c8921 Mon Sep 17 00:00:00 2001 From: Vjacheslav Trushkin Date: Sun, 6 May 2012 19:37:49 +0300 Subject: [PATCH 156/441] [ticket/10860] Fixing js error in updater Fixing javascript error in side-by-side diff styling in updater: resizing inner block instead of outer block and increasing height by inner/outer block difference. PHPBB3-10860 --- phpBB/adm/style/install_update_diff.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/phpBB/adm/style/install_update_diff.html b/phpBB/adm/style/install_update_diff.html index b65a014312..15ea00141d 100644 --- a/phpBB/adm/style/install_update_diff.html +++ b/phpBB/adm/style/install_update_diff.html @@ -15,12 +15,12 @@ // Date: Mon, 7 May 2012 08:18:50 +0200 Subject: [PATCH 157/441] [ticket/10835] changing CURRENT_CHANGE_PASSWORD_EXPLAIN language entry PHPBB3-10835 --- phpBB/language/en/ucp.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/language/en/ucp.php b/phpBB/language/en/ucp.php index fb417a5742..6f6b319d48 100644 --- a/phpBB/language/en/ucp.php +++ b/phpBB/language/en/ucp.php @@ -138,7 +138,7 @@ $lang = array_merge($lang, array( 'CURRENT_IMAGE' => 'Current image', 'CURRENT_PASSWORD' => 'Current password', 'CURRENT_PASSWORD_EXPLAIN' => 'You must enter your current password if you wish to alter your e-mail address or username.', - 'CURRENT_CHANGE_PASSWORD_EXPLAIN' => 'You must enter your current password if you wish to change it, alter your e-mail address or username.', + 'CURRENT_CHANGE_PASSWORD_EXPLAIN' => 'To change your password, your email address, or your username, you must enter your current password.', 'CUR_PASSWORD_EMPTY' => 'You did not enter your current password.', 'CUR_PASSWORD_ERROR' => 'The current password you entered is incorrect.', 'CUSTOM_DATEFORMAT' => 'Custom…', From 5b96b5fce7283ebd52f88ef6daa3c8233a7df1ec Mon Sep 17 00:00:00 2001 From: David King Date: Mon, 7 May 2012 10:39:49 -0400 Subject: [PATCH 158/441] [ticket/10837] Removed tearDownAfterClass() from extension_controller_test.php PHPBB3-10837 --- tests/functional/extension_controller_test.php | 9 --------- 1 file changed, 9 deletions(-) diff --git a/tests/functional/extension_controller_test.php b/tests/functional/extension_controller_test.php index 4ee0e68718..e9409d9d3f 100644 --- a/tests/functional/extension_controller_test.php +++ b/tests/functional/extension_controller_test.php @@ -65,15 +65,6 @@ class phpbb_functional_extension_controller_test extends phpbb_functional_test_c } } - public static function tearDownAfterClass() - { - $phpbb_root_path = self::$config['phpbb_functional_path']; - - // @todo delete the fixtures from the $phpbb_root_path board - // Note that it might be best to find a public domain function - // and port it into here instead of writing it from scratch - } - public function setUp() { parent::setUp(); From d578eff712b6376e3568965afec7054bff317127 Mon Sep 17 00:00:00 2001 From: Patrick Webster Date: Tue, 28 Feb 2012 06:18:24 -0600 Subject: [PATCH 159/441] [ticket/10678] Add better support for Firebird, Oracle, and MSSQL Allow ODBC connections for Firebird Capitalize fixture tables and columns for Firebird On database drop failure, drop all tables Provide cleanup utilities for databases that cannot be dropped PHPBB3-10678 --- tests/RUNNING_TESTS.txt | 19 ++++ .../phpbb_database_connection_helper.php | 24 ++++ .../phpbb_database_test_case.php | 27 +++++ ...phpbb_database_test_connection_manager.php | 106 +++++++++++++++++- 4 files changed, 171 insertions(+), 5 deletions(-) create mode 100644 tests/test_framework/phpbb_database_connection_helper.php diff --git a/tests/RUNNING_TESTS.txt b/tests/RUNNING_TESTS.txt index 59197acc0f..705fb28d07 100644 --- a/tests/RUNNING_TESTS.txt +++ b/tests/RUNNING_TESTS.txt @@ -43,6 +43,25 @@ will run phpunit with the same parameters as in the shown test_config.php file: PHPBB_TEST_DBNAME='database' PHPBB_TEST_DBUSER='user' \ PHPBB_TEST_DBPASSWD='password' phpunit +Special Database Cases +---------------------- +In order to run tests on some of the databases that we support, it will be +necessary to provide a custom DSN string in test_config.php. This is only needed for +MSSQL 2000+ (PHP module), MSSQL via ODBC, and Firebird when PDO_Firebird does not work +on your system (https://bugs.php.net/bug.php?id=61183). The variable must be named $custom_dsn. + +Examples: +Firebird using http://www.firebirdsql.org/en/odbc-driver/ +$custom_dsn = "Driver={Firebird/InterBase(r) driver};dbname=$dbhost:$dbname"; + +MSSQL +$custom_dsn = "Driver={SQL Server Native Client 10.0};Server=$dbhost;Database=$dbname"; + +The other fields in test_config.php should be filled out as you would normally to connect +to that database in phpBB. + +Additionally, you will need to be running the DbUnit fork from https://github.com/phpbb/dbunit/tree/phpbb. + Running ======= diff --git a/tests/test_framework/phpbb_database_connection_helper.php b/tests/test_framework/phpbb_database_connection_helper.php new file mode 100644 index 0000000000..e1c50655ed --- /dev/null +++ b/tests/test_framework/phpbb_database_connection_helper.php @@ -0,0 +1,24 @@ +driver = $dbms; + $this->version = (double)$version; + + parent::__construct($dsn, $user, $pass); + } +} \ No newline at end of file diff --git a/tests/test_framework/phpbb_database_test_case.php b/tests/test_framework/phpbb_database_test_case.php index e742b543b0..0e5518fef8 100644 --- a/tests/test_framework/phpbb_database_test_case.php +++ b/tests/test_framework/phpbb_database_test_case.php @@ -28,6 +28,28 @@ abstract class phpbb_database_test_case extends PHPUnit_Extensions_Database_Test ); } + public function createXMLDataSet($path) + { + $db_config = $this->get_database_config(); + + //Firebird requires table and column names to be uppercase + if($db_config['dbms'] == 'firebird') + { + $xml_data = file_get_contents($path); + $xml_data = preg_replace_callback('/(?:())/', 'phpbb_database_test_case::to_upper', $xml_data); + $xml_data = preg_replace_callback('/(?:())([a-z_]+)(?:(<\/column>))/', 'phpbb_database_test_case::to_upper', $xml_data); + + $temp = tmpfile(); + fwrite($temp, $xml_data); + fseek($temp, 0); + + $meta_data = stream_get_meta_data($temp); + $path = $meta_data['uri']; + } + + return parent::createXMLDataSet($path); + } + public function get_test_case_helpers() { if (!$this->test_case_helpers) @@ -106,4 +128,9 @@ abstract class phpbb_database_test_case extends PHPUnit_Extensions_Database_Test { return new phpbb_database_test_connection_manager($config); } + + public static function to_upper($matches) + { + return $matches[1] . strtoupper($matches[2]) . $matches[3]; + } } diff --git a/tests/test_framework/phpbb_database_test_connection_manager.php b/tests/test_framework/phpbb_database_test_connection_manager.php index c734c90a1a..328d90fca9 100644 --- a/tests/test_framework/phpbb_database_test_connection_manager.php +++ b/tests/test_framework/phpbb_database_test_connection_manager.php @@ -8,6 +8,7 @@ */ require_once dirname(__FILE__) . '/../../phpBB/includes/functions_install.php'; +require_once 'phpbb_database_connection_helper.php'; class phpbb_database_test_connection_manager { @@ -83,9 +84,37 @@ class phpbb_database_test_connection_manager break; } + //These require different connection strings on the phpBB side than they do in PDO + //so you must provide a DSN string for ODBC separately + if($this->config['dbms'] == 'mssql' || $this->config['dbms'] == 'firebird') + { + if(!empty($this->config['custom_dsn'])) + { + $dsn = 'odbc:' . $this->config['custom_dsn']; + } + } + try { - $this->pdo = new PDO($dsn, $this->config['dbuser'], $this->config['dbpasswd']); + switch($this->config['dbms']) + { + case 'mssql': + case 'mssql_odbc': + $this->pdo = new phpbb_database_connection_ODBC_PDO_wrapper('mssql', 0, $dsn, $this->config['dbuser'], $this->config['dbpasswd']); + break; + + case 'firebird': + if(!empty($this->config['custom_dsn'])) + { + $this->pdo = new phpbb_database_connection_ODBC_PDO_wrapper('firebird', 0, $dsn, $this->config['dbuser'], $this->config['dbpasswd']); + break; + } + //Fall through if they're using the firebird PDO driver and not the generic ODBC driver + + default: + $this->pdo = new PDO($dsn, $this->config['dbuser'], $this->config['dbpasswd']); + break; + } } catch (PDOException $e) { @@ -93,8 +122,7 @@ class phpbb_database_test_connection_manager throw new Exception("Unable do connect to $cleaned_dsn using PDO with error: {$e->getMessage()}"); } - // good for debug - // $this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + $this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } /** @@ -125,12 +153,41 @@ class phpbb_database_test_connection_manager } break; + case 'firebird': + $this->connect(); + // Drop all of the tables + foreach ($this->get_tables() as $table) + { + $this->pdo->exec('DROP TABLE ' . $table); + } + $this->purge_extras(); + break; + + case 'oracle': + $this->connect(); + // Drop all of the tables + foreach ($this->get_tables() as $table) + { + $this->pdo->exec('DROP TABLE ' . $table . ' CASCADE CONSTRAINTS'); + } + $this->purge_extras(); + break; + default: $this->connect(false); try { $this->pdo->exec('DROP DATABASE ' . $this->config['dbname']); + + try + { + $this->pdo->exec('CREATE DATABASE ' . $this->config['dbname']); + } + catch (PDOException $e) + { + throw new Exception("Unable to re-create database: {$e->getMessage()}"); + } } catch (PDOException $e) { @@ -139,9 +196,8 @@ class phpbb_database_test_connection_manager { $this->pdo->exec('DROP TABLE ' . $table); } + $this->purge_extras(); } - - $this->pdo->exec('CREATE DATABASE ' . $this->config['dbname']); break; } } @@ -317,4 +373,44 @@ class phpbb_database_test_connection_manager throw new Exception($message); } } + + /** + * Removes extra objects from a database. This is for cases where dropping the database fails. + */ + public function purge_extras() + { + $this->ensure_connected(__METHOD__); + $queries = array(); + + switch ($this->config['dbms']) + { + case 'firebird': + $sql = 'SELECT RDB$GENERATOR_NAME + FROM RDB$GENERATORS + WHERE RDB$SYSTEM_FLAG = 0'; + $result = $this->pdo->query($sql); + + while ($row = $result->fetch(PDO::FETCH_NUM)) + { + $queries[] = 'DROP GENERATOR ' . current($row); + } + break; + + case 'oracle': + $sql = 'SELECT sequence_name + FROM USER_SEQUENCES'; + $result = $this->pdo->query($sql); + + while ($row = $result->fetch(PDO::FETCH_NUM)) + { + $queries[] = 'DROP SEQUENCE ' . current($row); + } + break; + } + + foreach($queries as $query) + { + $this->pdo->exec($query); + } + } } From 5cbe919256a0046a896a88c47b96276b6d7c05d0 Mon Sep 17 00:00:00 2001 From: Patrick Webster Date: Tue, 28 Feb 2012 13:47:15 -0600 Subject: [PATCH 160/441] [ticket/10678] Fix formatting PHPBB3-10678 --- .../phpbb_database_connection_helper.php | 10 +++++++++- tests/test_framework/phpbb_database_test_case.php | 2 +- .../phpbb_database_test_connection_manager.php | 10 +++++----- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/tests/test_framework/phpbb_database_connection_helper.php b/tests/test_framework/phpbb_database_connection_helper.php index e1c50655ed..6ba527b5d9 100644 --- a/tests/test_framework/phpbb_database_connection_helper.php +++ b/tests/test_framework/phpbb_database_connection_helper.php @@ -1,4 +1,12 @@ get_database_config(); //Firebird requires table and column names to be uppercase - if($db_config['dbms'] == 'firebird') + if ($db_config['dbms'] == 'firebird') { $xml_data = file_get_contents($path); $xml_data = preg_replace_callback('/(?:(
      ))/', 'phpbb_database_test_case::to_upper', $xml_data); diff --git a/tests/test_framework/phpbb_database_test_connection_manager.php b/tests/test_framework/phpbb_database_test_connection_manager.php index 328d90fca9..6e3f602ab7 100644 --- a/tests/test_framework/phpbb_database_test_connection_manager.php +++ b/tests/test_framework/phpbb_database_test_connection_manager.php @@ -86,9 +86,9 @@ class phpbb_database_test_connection_manager //These require different connection strings on the phpBB side than they do in PDO //so you must provide a DSN string for ODBC separately - if($this->config['dbms'] == 'mssql' || $this->config['dbms'] == 'firebird') + if ($this->config['dbms'] == 'mssql' || $this->config['dbms'] == 'firebird') { - if(!empty($this->config['custom_dsn'])) + if (!empty($this->config['custom_dsn'])) { $dsn = 'odbc:' . $this->config['custom_dsn']; } @@ -96,7 +96,7 @@ class phpbb_database_test_connection_manager try { - switch($this->config['dbms']) + switch ($this->config['dbms']) { case 'mssql': case 'mssql_odbc': @@ -104,7 +104,7 @@ class phpbb_database_test_connection_manager break; case 'firebird': - if(!empty($this->config['custom_dsn'])) + if (!empty($this->config['custom_dsn'])) { $this->pdo = new phpbb_database_connection_ODBC_PDO_wrapper('firebird', 0, $dsn, $this->config['dbuser'], $this->config['dbpasswd']); break; @@ -408,7 +408,7 @@ class phpbb_database_test_connection_manager break; } - foreach($queries as $query) + foreach ($queries as $query) { $this->pdo->exec($query); } From 0a596c4b8c4d003d0c8af79af65cb5264e9754fe Mon Sep 17 00:00:00 2001 From: Patrick Webster Date: Sun, 4 Mar 2012 17:19:33 -0600 Subject: [PATCH 161/441] [ticket/10678] More formatting requests PHPBB3-10678 --- .../test_framework/phpbb_database_connection_helper.php | 4 ++-- .../phpbb_database_test_connection_manager.php | 9 +++------ 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/tests/test_framework/phpbb_database_connection_helper.php b/tests/test_framework/phpbb_database_connection_helper.php index 6ba527b5d9..fbb85784f8 100644 --- a/tests/test_framework/phpbb_database_connection_helper.php +++ b/tests/test_framework/phpbb_database_connection_helper.php @@ -16,10 +16,10 @@ */ class phpbb_database_connection_ODBC_PDO_wrapper extends PDO { - //Name of the driver being used (i.e. mssql, firebird) + // Name of the driver being used (i.e. mssql, firebird) public $driver = ''; - //Version number of driver since PDO::getAttribute(PDO::ATTR_CLIENT_VERSION) is pretty useless for this + // Version number of driver since PDO::getAttribute(PDO::ATTR_CLIENT_VERSION) is pretty useless for this public $version = 0; function __construct($dbms, $version, $dsn, $user, $pass) diff --git a/tests/test_framework/phpbb_database_test_connection_manager.php b/tests/test_framework/phpbb_database_test_connection_manager.php index 6e3f602ab7..2334e08f78 100644 --- a/tests/test_framework/phpbb_database_test_connection_manager.php +++ b/tests/test_framework/phpbb_database_test_connection_manager.php @@ -8,7 +8,7 @@ */ require_once dirname(__FILE__) . '/../../phpBB/includes/functions_install.php'; -require_once 'phpbb_database_connection_helper.php'; +require_once dirname(__FILE__) . '/phpbb_database_connection_helper.php'; class phpbb_database_test_connection_manager { @@ -86,12 +86,9 @@ class phpbb_database_test_connection_manager //These require different connection strings on the phpBB side than they do in PDO //so you must provide a DSN string for ODBC separately - if ($this->config['dbms'] == 'mssql' || $this->config['dbms'] == 'firebird') + if (!empty($this->config['custom_dsn']) && ($this->config['dbms'] == 'mssql' || $this->config['dbms'] == 'firebird')) { - if (!empty($this->config['custom_dsn'])) - { - $dsn = 'odbc:' . $this->config['custom_dsn']; - } + $dsn = 'odbc:' . $this->config['custom_dsn']; } try From 9bb2785da0c84bcc4a95f737b7da14c58c5d4380 Mon Sep 17 00:00:00 2001 From: Patrick Webster Date: Mon, 2 Apr 2012 05:57:48 -0500 Subject: [PATCH 162/441] [ticket/10678] More formatting and docblocks PHPBB3-10678 --- tests/test_framework/phpbb_database_test_case.php | 10 +++++++++- .../phpbb_database_test_connection_manager.php | 6 +++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/tests/test_framework/phpbb_database_test_case.php b/tests/test_framework/phpbb_database_test_case.php index b8be6a852a..53c3702aa6 100644 --- a/tests/test_framework/phpbb_database_test_case.php +++ b/tests/test_framework/phpbb_database_test_case.php @@ -32,7 +32,7 @@ abstract class phpbb_database_test_case extends PHPUnit_Extensions_Database_Test { $db_config = $this->get_database_config(); - //Firebird requires table and column names to be uppercase + // Firebird requires table and column names to be uppercase if ($db_config['dbms'] == 'firebird') { $xml_data = file_get_contents($path); @@ -129,6 +129,14 @@ abstract class phpbb_database_test_case extends PHPUnit_Extensions_Database_Test return new phpbb_database_test_connection_manager($config); } + /** + * Converts a match in the middle of a string to uppercase. + * This is necessary for tranforming the fixture information for Firebird tests + * + * @param $matches The array of matches from a regular expression + * + * @return string The string with the specified match converted to uppercase + */ public static function to_upper($matches) { return $matches[1] . strtoupper($matches[2]) . $matches[3]; diff --git a/tests/test_framework/phpbb_database_test_connection_manager.php b/tests/test_framework/phpbb_database_test_connection_manager.php index 2334e08f78..3c4a112d0d 100644 --- a/tests/test_framework/phpbb_database_test_connection_manager.php +++ b/tests/test_framework/phpbb_database_test_connection_manager.php @@ -84,8 +84,8 @@ class phpbb_database_test_connection_manager break; } - //These require different connection strings on the phpBB side than they do in PDO - //so you must provide a DSN string for ODBC separately + // These require different connection strings on the phpBB side than they do in PDO + // so you must provide a DSN string for ODBC separately if (!empty($this->config['custom_dsn']) && ($this->config['dbms'] == 'mssql' || $this->config['dbms'] == 'firebird')) { $dsn = 'odbc:' . $this->config['custom_dsn']; @@ -106,7 +106,7 @@ class phpbb_database_test_connection_manager $this->pdo = new phpbb_database_connection_ODBC_PDO_wrapper('firebird', 0, $dsn, $this->config['dbuser'], $this->config['dbpasswd']); break; } - //Fall through if they're using the firebird PDO driver and not the generic ODBC driver + // Fall through if they're using the firebird PDO driver and not the generic ODBC driver default: $this->pdo = new PDO($dsn, $this->config['dbuser'], $this->config['dbpasswd']); From ceacb63abfdc8144ce88c0d9ce763ccc74836be5 Mon Sep 17 00:00:00 2001 From: Patrick Webster Date: Thu, 12 Apr 2012 20:10:20 -0500 Subject: [PATCH 163/441] [ticket/10678] Lowercase class name, adjust comment width PHPBB3-10678 --- tests/RUNNING_TESTS.txt | 26 +++++++++++-------- .../phpbb_database_connection_helper.php | 2 +- ...phpbb_database_test_connection_manager.php | 4 +-- 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/tests/RUNNING_TESTS.txt b/tests/RUNNING_TESTS.txt index 705fb28d07..487320f736 100644 --- a/tests/RUNNING_TESTS.txt +++ b/tests/RUNNING_TESTS.txt @@ -36,8 +36,9 @@ found on the wiki (see below). $dbuser = 'user'; $dbpasswd = 'password'; -Alternatively you can specify parameters in the environment, so e.g. the following -will run phpunit with the same parameters as in the shown test_config.php file: +Alternatively you can specify parameters in the environment, so e.g. the +following will run phpunit with the same parameters as in the shown +test_config.php file: $ PHPBB_TEST_DBMS='mysqli' PHPBB_TEST_DBHOST='localhost' \ PHPBB_TEST_DBNAME='database' PHPBB_TEST_DBUSER='user' \ @@ -46,9 +47,10 @@ will run phpunit with the same parameters as in the shown test_config.php file: Special Database Cases ---------------------- In order to run tests on some of the databases that we support, it will be -necessary to provide a custom DSN string in test_config.php. This is only needed for -MSSQL 2000+ (PHP module), MSSQL via ODBC, and Firebird when PDO_Firebird does not work -on your system (https://bugs.php.net/bug.php?id=61183). The variable must be named $custom_dsn. +necessary to provide a custom DSN string in test_config.php. This is only +needed for MSSQL 2000+ (PHP module), MSSQL via ODBC, and Firebird when +PDO_Firebird does not work on your system +(https://bugs.php.net/bug.php?id=61183). The variable must be named $custom_dsn. Examples: Firebird using http://www.firebirdsql.org/en/odbc-driver/ @@ -57,15 +59,17 @@ $custom_dsn = "Driver={Firebird/InterBase(r) driver};dbname=$dbhost:$dbname"; MSSQL $custom_dsn = "Driver={SQL Server Native Client 10.0};Server=$dbhost;Database=$dbname"; -The other fields in test_config.php should be filled out as you would normally to connect -to that database in phpBB. +The other fields in test_config.php should be filled out as you would normally +to connect to that database in phpBB. -Additionally, you will need to be running the DbUnit fork from https://github.com/phpbb/dbunit/tree/phpbb. +Additionally, you will need to be running the DbUnit fork from +https://github.com/phpbb/dbunit/tree/phpbb. Running ======= -Once the prerequisites are installed, run the tests from the project root directory (above phpBB): +Once the prerequisites are installed, run the tests from the project root +directory (above phpBB): $ phpunit @@ -73,8 +77,8 @@ Slow tests -------------- Certain tests, such as the UTF-8 normalizer or the DNS tests tend to be slow. Thus these tests are in the `slow` group, which is excluded by default. You can -enable slow tests by copying the phpunit.xml.all file to phpunit.xml. If you only -want the slow tests, run: +enable slow tests by copying the phpunit.xml.all file to phpunit.xml. If you +only want the slow tests, run: $ phpunit --group slow diff --git a/tests/test_framework/phpbb_database_connection_helper.php b/tests/test_framework/phpbb_database_connection_helper.php index fbb85784f8..5eba2e7a2e 100644 --- a/tests/test_framework/phpbb_database_connection_helper.php +++ b/tests/test_framework/phpbb_database_connection_helper.php @@ -14,7 +14,7 @@ * * This is used in the custom PHPUnit ODBC driver */ -class phpbb_database_connection_ODBC_PDO_wrapper extends PDO +class phpbb_database_connection_odbc_pdo_wrapper extends PDO { // Name of the driver being used (i.e. mssql, firebird) public $driver = ''; diff --git a/tests/test_framework/phpbb_database_test_connection_manager.php b/tests/test_framework/phpbb_database_test_connection_manager.php index 3c4a112d0d..8e214121f3 100644 --- a/tests/test_framework/phpbb_database_test_connection_manager.php +++ b/tests/test_framework/phpbb_database_test_connection_manager.php @@ -97,13 +97,13 @@ class phpbb_database_test_connection_manager { case 'mssql': case 'mssql_odbc': - $this->pdo = new phpbb_database_connection_ODBC_PDO_wrapper('mssql', 0, $dsn, $this->config['dbuser'], $this->config['dbpasswd']); + $this->pdo = new phpbb_database_connection_odbc_pdo_wrapper('mssql', 0, $dsn, $this->config['dbuser'], $this->config['dbpasswd']); break; case 'firebird': if (!empty($this->config['custom_dsn'])) { - $this->pdo = new phpbb_database_connection_ODBC_PDO_wrapper('firebird', 0, $dsn, $this->config['dbuser'], $this->config['dbpasswd']); + $this->pdo = new phpbb_database_connection_odbc_pdo_wrapper('firebird', 0, $dsn, $this->config['dbuser'], $this->config['dbpasswd']); break; } // Fall through if they're using the firebird PDO driver and not the generic ODBC driver From 3cdcd44c4b056211f3e3291a4e58beddbb81e25d Mon Sep 17 00:00:00 2001 From: Patrick Webster Date: Fri, 13 Apr 2012 01:40:55 -0500 Subject: [PATCH 164/441] [ticket/10678] Rename helper class file PHPBB3-10678 --- ...elper.php => phpbb_database_connection_odbc_pdo_wrapper.php} | 0 tests/test_framework/phpbb_database_test_connection_manager.php | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename tests/test_framework/{phpbb_database_connection_helper.php => phpbb_database_connection_odbc_pdo_wrapper.php} (100%) diff --git a/tests/test_framework/phpbb_database_connection_helper.php b/tests/test_framework/phpbb_database_connection_odbc_pdo_wrapper.php similarity index 100% rename from tests/test_framework/phpbb_database_connection_helper.php rename to tests/test_framework/phpbb_database_connection_odbc_pdo_wrapper.php diff --git a/tests/test_framework/phpbb_database_test_connection_manager.php b/tests/test_framework/phpbb_database_test_connection_manager.php index 8e214121f3..0335c0de36 100644 --- a/tests/test_framework/phpbb_database_test_connection_manager.php +++ b/tests/test_framework/phpbb_database_test_connection_manager.php @@ -8,7 +8,7 @@ */ require_once dirname(__FILE__) . '/../../phpBB/includes/functions_install.php'; -require_once dirname(__FILE__) . '/phpbb_database_connection_helper.php'; +require_once dirname(__FILE__) . '/phpbb_database_connection_odbc_pdo_wrapper.php'; class phpbb_database_test_connection_manager { From 711d09633a17ef40e9efe67433f2285fa11f0608 Mon Sep 17 00:00:00 2001 From: Patrick Webster Date: Tue, 8 May 2012 04:34:19 -0500 Subject: [PATCH 165/441] [ticket/10678] Move config changes to new location PHPBB3-10678 --- tests/test_framework/phpbb_test_case_helpers.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/test_framework/phpbb_test_case_helpers.php b/tests/test_framework/phpbb_test_case_helpers.php index b46c36efaa..3622fb1b1a 100644 --- a/tests/test_framework/phpbb_test_case_helpers.php +++ b/tests/test_framework/phpbb_test_case_helpers.php @@ -69,6 +69,7 @@ class phpbb_test_case_helpers 'dbname' => $dbname, 'dbuser' => $dbuser, 'dbpasswd' => $dbpasswd, + 'custom_dsn' => isset($custom_dsn) ? $custom_dsn : '', )); if (isset($phpbb_functional_url)) @@ -85,7 +86,8 @@ class phpbb_test_case_helpers 'dbport' => isset($_SERVER['PHPBB_TEST_DBPORT']) ? $_SERVER['PHPBB_TEST_DBPORT'] : '', 'dbname' => isset($_SERVER['PHPBB_TEST_DBNAME']) ? $_SERVER['PHPBB_TEST_DBNAME'] : '', 'dbuser' => isset($_SERVER['PHPBB_TEST_DBUSER']) ? $_SERVER['PHPBB_TEST_DBUSER'] : '', - 'dbpasswd' => isset($_SERVER['PHPBB_TEST_DBPASSWD']) ? $_SERVER['PHPBB_TEST_DBPASSWD'] : '' + 'dbpasswd' => isset($_SERVER['PHPBB_TEST_DBPASSWD']) ? $_SERVER['PHPBB_TEST_DBPASSWD'] : '', + 'custom_dsn' => isset($_SERVER['PHPBB_TEST_CUSTOM_DSN']) ? $_SERVER['PHPBB_TEST_CUSTOM_DSN'] : '', )); } From 1496a4198a930e3f9412f6beb6c0307ddeeb6dda Mon Sep 17 00:00:00 2001 From: Patrick Webster Date: Tue, 8 May 2012 04:35:47 -0500 Subject: [PATCH 166/441] [ticket/10678] Add port handling for MSSQL tests PHPBB3-10678 --- .../phpbb_database_test_connection_manager.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/test_framework/phpbb_database_test_connection_manager.php b/tests/test_framework/phpbb_database_test_connection_manager.php index 0335c0de36..2e93b6799c 100644 --- a/tests/test_framework/phpbb_database_test_connection_manager.php +++ b/tests/test_framework/phpbb_database_test_connection_manager.php @@ -63,6 +63,13 @@ class phpbb_database_test_connection_manager // e.g. Driver={SQL Server Native Client 10.0};Server=(local)\SQLExpress; $dsn .= $this->config['dbhost']; + // Primarily for MSSQL Native/Azure as ODBC needs it in $dbhost, attached to the Server param + if ($this->config['dbport']) + { + $port_delimiter = (defined('PHP_OS') && substr(PHP_OS, 0, 3) === 'WIN') ? ',' : ':'; + $dsn .= $port_delimiter . $this->config['dbport']; + } + if ($use_db) { $dsn .= ';Database=' . $this->config['dbname']; From e52d23848a1b116d32fbad9dd384e0755553b829 Mon Sep 17 00:00:00 2001 From: Patrick Webster Date: Tue, 8 May 2012 18:44:43 -0500 Subject: [PATCH 167/441] [ticket/10858] Fix MSSQL Native's row seeking behavior The result_mssqlnative class remains in case someone wants to use it PHPBB3-10858 --- phpBB/includes/db/mssqlnative.php | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/phpBB/includes/db/mssqlnative.php b/phpBB/includes/db/mssqlnative.php index 7fbc374e77..6391664a3e 100644 --- a/phpBB/includes/db/mssqlnative.php +++ b/phpBB/includes/db/mssqlnative.php @@ -447,14 +447,39 @@ class dbal_mssqlnative extends dbal { global $cache; + if ($query_id === false) + { + $query_id = $this->query_result; + } + if (isset($cache->sql_rowset[$query_id])) { return $cache->sql_rowseek($rownum, $query_id); } - $seek = new result_mssqlnative($query_id); - $row = $seek->seek($rownum); - return ($row = $seek->fetch()) ? $row : false; + if ($query_id === false) + { + return false; + } + + $this->sql_freeresult($query_id); + $query_id = $this->sql_query($this->last_query_text); + + if ($query_id === false) + { + return false; + } + + // We do not fetch the row for rownum == 0 because then the next resultset would be the second row + for ($i = 0; $i < $rownum; $i++) + { + if (!$this->sql_fetchrow($query_id)) + { + return false; + } + } + + return true; } /** From afbaa6979b62acb16fa09247ec4613d5d7d683fa Mon Sep 17 00:00:00 2001 From: Patrick Webster Date: Tue, 8 May 2012 18:45:51 -0500 Subject: [PATCH 168/441] [ticket/10858] Tests for row seeking with fetchfield() PHPBB3-10858 --- tests/dbal/select_test.php | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/tests/dbal/select_test.php b/tests/dbal/select_test.php index 21b12777dc..1b04450fcd 100644 --- a/tests/dbal/select_test.php +++ b/tests/dbal/select_test.php @@ -125,6 +125,32 @@ class phpbb_dbal_select_test extends phpbb_database_test_case $this->assertEquals($expected, $ary); } + public static function fetchfield_seek_data() + { + return array( + array(1, 'foobar'), + array(0, 'barfoo'), + array(2, 'bertie'), + ); + } + + /** + * @dataProvider fetchfield_seek_data + */ + public function test_fetchfield_seek($rownum, $expected) + { + $db = $this->new_dbal(); + + $result = $db->sql_query('SELECT username_clean + FROM phpbb_users + ORDER BY user_id ASC'); + + $field = $db->sql_fetchfield('username_clean', $rownum, $result); + $db->sql_freeresult($result); + + $this->assertEquals($expected, $field); + } + public static function query_limit_data() { return array( From 09d49fb7b2be51a29f5a03c0a1a3816d7e55a466 Mon Sep 17 00:00:00 2001 From: Patrick Webster Date: Tue, 8 May 2012 19:41:22 -0500 Subject: [PATCH 169/441] [ticket/10858] Move generic row seeking to DBAL Removed from: firebird, mssql_odbc, and mssqlnative PHPBB3-10858 --- phpBB/includes/db/dbal.php | 43 +++++++++++++++++++++++++++++++ phpBB/includes/db/firebird.php | 43 ------------------------------- phpBB/includes/db/mssql_odbc.php | 43 ------------------------------- phpBB/includes/db/mssqlnative.php | 43 ------------------------------- 4 files changed, 43 insertions(+), 129 deletions(-) diff --git a/phpBB/includes/db/dbal.php b/phpBB/includes/db/dbal.php index 5d456c2ff0..358df50402 100644 --- a/phpBB/includes/db/dbal.php +++ b/phpBB/includes/db/dbal.php @@ -194,6 +194,49 @@ class dbal return false; } + /** + * Seek to given row number + * rownum is zero-based + */ + function sql_rowseek($rownum, &$query_id) + { + global $cache; + + if ($query_id === false) + { + $query_id = $this->query_result; + } + + if (isset($cache->sql_rowset[$query_id])) + { + return $cache->sql_rowseek($rownum, $query_id); + } + + if ($query_id === false) + { + return false; + } + + $this->sql_freeresult($query_id); + $query_id = $this->sql_query($this->last_query_text); + + if ($query_id === false) + { + return false; + } + + // We do not fetch the row for rownum == 0 because then the next resultset would be the second row + for ($i = 0; $i < $rownum; $i++) + { + if (!$this->sql_fetchrow($query_id)) + { + return false; + } + } + + return true; + } + /** * Fetch field * if rownum is false, the current row is used, else it is pointing to the row (zero-based) diff --git a/phpBB/includes/db/firebird.php b/phpBB/includes/db/firebird.php index 7e3f15ed1d..7072c58ac0 100644 --- a/phpBB/includes/db/firebird.php +++ b/phpBB/includes/db/firebird.php @@ -359,49 +359,6 @@ class dbal_firebird extends dbal return (sizeof($row)) ? $row : false; } - /** - * Seek to given row number - * rownum is zero-based - */ - function sql_rowseek($rownum, &$query_id) - { - global $cache; - - if ($query_id === false) - { - $query_id = $this->query_result; - } - - if (isset($cache->sql_rowset[$query_id])) - { - return $cache->sql_rowseek($rownum, $query_id); - } - - if ($query_id === false) - { - return; - } - - $this->sql_freeresult($query_id); - $query_id = $this->sql_query($this->last_query_text); - - if ($query_id === false) - { - return false; - } - - // We do not fetch the row for rownum == 0 because then the next resultset would be the second row - for ($i = 0; $i < $rownum; $i++) - { - if (!$this->sql_fetchrow($query_id)) - { - return false; - } - } - - return true; - } - /** * Get last inserted id after insert statement */ diff --git a/phpBB/includes/db/mssql_odbc.php b/phpBB/includes/db/mssql_odbc.php index 75a080b1b7..34f7a87337 100644 --- a/phpBB/includes/db/mssql_odbc.php +++ b/phpBB/includes/db/mssql_odbc.php @@ -255,49 +255,6 @@ class dbal_mssql_odbc extends dbal return ($query_id !== false) ? @odbc_fetch_array($query_id) : false; } - /** - * Seek to given row number - * rownum is zero-based - */ - function sql_rowseek($rownum, &$query_id) - { - global $cache; - - if ($query_id === false) - { - $query_id = $this->query_result; - } - - if (isset($cache->sql_rowset[$query_id])) - { - return $cache->sql_rowseek($rownum, $query_id); - } - - if ($query_id === false) - { - return false; - } - - $this->sql_freeresult($query_id); - $query_id = $this->sql_query($this->last_query_text); - - if ($query_id === false) - { - return false; - } - - // We do not fetch the row for rownum == 0 because then the next resultset would be the second row - for ($i = 0; $i < $rownum; $i++) - { - if (!$this->sql_fetchrow($query_id)) - { - return false; - } - } - - return true; - } - /** * Get last inserted id after insert statement */ diff --git a/phpBB/includes/db/mssqlnative.php b/phpBB/includes/db/mssqlnative.php index 6391664a3e..92ac9b1fb9 100644 --- a/phpBB/includes/db/mssqlnative.php +++ b/phpBB/includes/db/mssqlnative.php @@ -439,49 +439,6 @@ class dbal_mssqlnative extends dbal return $row; } - /** - * Seek to given row number - * rownum is zero-based - */ - function sql_rowseek($rownum, &$query_id) - { - global $cache; - - if ($query_id === false) - { - $query_id = $this->query_result; - } - - if (isset($cache->sql_rowset[$query_id])) - { - return $cache->sql_rowseek($rownum, $query_id); - } - - if ($query_id === false) - { - return false; - } - - $this->sql_freeresult($query_id); - $query_id = $this->sql_query($this->last_query_text); - - if ($query_id === false) - { - return false; - } - - // We do not fetch the row for rownum == 0 because then the next resultset would be the second row - for ($i = 0; $i < $rownum; $i++) - { - if (!$this->sql_fetchrow($query_id)) - { - return false; - } - } - - return true; - } - /** * Get last inserted id after insert statement */ From 9a38a034e56fc6e30207f1fee385f0b18de0dcc2 Mon Sep 17 00:00:00 2001 From: Oleg Pudeyev Date: Thu, 10 May 2012 03:23:48 -0400 Subject: [PATCH 170/441] [ticket/10882] Add test for an invalid template tag. PHPBB3-10882 --- tests/template/invalid_constructs_test.php | 43 +++++++++++++++++++ .../templates/invalid/output/unknown_tag.html | 1 + .../templates/invalid/unknown_tag.html | 1 + 3 files changed, 45 insertions(+) create mode 100644 tests/template/invalid_constructs_test.php create mode 100644 tests/template/templates/invalid/output/unknown_tag.html create mode 100644 tests/template/templates/invalid/unknown_tag.html diff --git a/tests/template/invalid_constructs_test.php b/tests/template/invalid_constructs_test.php new file mode 100644 index 0000000000..08fb5d4289 --- /dev/null +++ b/tests/template/invalid_constructs_test.php @@ -0,0 +1,43 @@ +template->cachepath . str_replace('/', '.', $file) . '.php'; + + $this->assertFileNotExists($cache_file); + + $expected = file_get_contents(dirname(__FILE__) . '/templates/' . $expected); + // apparently the template engine does not put + // the trailing newline into compiled templates + $expected = trim($expected); + $this->run_template($file, $vars, $block_vars, $destroy, $expected, $cache_file); + } +} diff --git a/tests/template/templates/invalid/output/unknown_tag.html b/tests/template/templates/invalid/output/unknown_tag.html new file mode 100644 index 0000000000..1489e5e31a --- /dev/null +++ b/tests/template/templates/invalid/output/unknown_tag.html @@ -0,0 +1 @@ + diff --git a/tests/template/templates/invalid/unknown_tag.html b/tests/template/templates/invalid/unknown_tag.html new file mode 100644 index 0000000000..1489e5e31a --- /dev/null +++ b/tests/template/templates/invalid/unknown_tag.html @@ -0,0 +1 @@ + From 720d07c9b3942a103ceedc1996fb11e13c1bc2f0 Mon Sep 17 00:00:00 2001 From: Oleg Pudeyev Date: Thu, 10 May 2012 03:28:54 -0400 Subject: [PATCH 171/441] [ticket/10882] Add test for an ENDIF without IF. PHPBB3-10882 --- tests/template/invalid_constructs_test.php | 12 ++++++++++++ .../template/templates/invalid/endif_without_if.html | 1 + .../templates/invalid/output/endif_without_if.html | 1 + 3 files changed, 14 insertions(+) create mode 100644 tests/template/templates/invalid/endif_without_if.html create mode 100644 tests/template/templates/invalid/output/endif_without_if.html diff --git a/tests/template/invalid_constructs_test.php b/tests/template/invalid_constructs_test.php index 08fb5d4289..8d54df5014 100644 --- a/tests/template/invalid_constructs_test.php +++ b/tests/template/invalid_constructs_test.php @@ -22,6 +22,18 @@ class phpbb_template_template_test extends phpbb_template_template_test_case array(), 'invalid/output/unknown_tag.html', ), + /* + * Produces a parse error which is fatal, therefore + * destroying the test suite. + array( + 'ENDIF without IF', + 'invalid/endif_without_if.html', + array(), + array(), + array(), + 'invalid/output/endif_without_if.html', + ), + */ ); } diff --git a/tests/template/templates/invalid/endif_without_if.html b/tests/template/templates/invalid/endif_without_if.html new file mode 100644 index 0000000000..e371ffd150 --- /dev/null +++ b/tests/template/templates/invalid/endif_without_if.html @@ -0,0 +1 @@ + diff --git a/tests/template/templates/invalid/output/endif_without_if.html b/tests/template/templates/invalid/output/endif_without_if.html new file mode 100644 index 0000000000..5f2239c964 --- /dev/null +++ b/tests/template/templates/invalid/output/endif_without_if.html @@ -0,0 +1 @@ +Parse error (fatal, destroys php runtime). From 56b2b87423c9afd62312fd36b5c2f6fff2d1d8a7 Mon Sep 17 00:00:00 2001 From: Oleg Pudeyev Date: Thu, 10 May 2012 03:36:58 -0400 Subject: [PATCH 172/441] [ticket/10882] Add a test for including a nonexistent file. PHPBB3-10882 --- tests/template/invalid_constructs_test.php | 32 +++++++++++++++++++ .../invalid/include_nonexistent_file.html | 1 + .../output/include_nonexistent_file.html | 1 + 3 files changed, 34 insertions(+) create mode 100644 tests/template/templates/invalid/include_nonexistent_file.html create mode 100644 tests/template/templates/invalid/output/include_nonexistent_file.html diff --git a/tests/template/invalid_constructs_test.php b/tests/template/invalid_constructs_test.php index 8d54df5014..2430b5b9b1 100644 --- a/tests/template/invalid_constructs_test.php +++ b/tests/template/invalid_constructs_test.php @@ -37,6 +37,21 @@ class phpbb_template_template_test extends phpbb_template_template_test_case ); } + public function template_data_error() + { + return array( + array( + 'Include a nonexistent file', + 'invalid/include_nonexistent_file.html', + array(), + array(), + array(), + E_USER_ERROR, + 'invalid/output/include_nonexistent_file.html', + ), + ); + } + /** * @dataProvider template_data */ @@ -52,4 +67,21 @@ class phpbb_template_template_test extends phpbb_template_template_test_case $expected = trim($expected); $this->run_template($file, $vars, $block_vars, $destroy, $expected, $cache_file); } + + /** + * @dataProvider template_data_error + */ + public function test_template_error($description, $file, $vars, $block_vars, $destroy, $error, $expected) + { + $cache_file = $this->template->cachepath . str_replace('/', '.', $file) . '.php'; + + $this->assertFileNotExists($cache_file); + + $expected = file_get_contents(dirname(__FILE__) . '/templates/' . $expected); + // apparently the template engine does not put + // the trailing newline into compiled templates + $expected = trim($expected); + $this->setExpectedTriggerError($error, $expected); + $this->run_template($file, $vars, $block_vars, $destroy, '', $cache_file); + } } diff --git a/tests/template/templates/invalid/include_nonexistent_file.html b/tests/template/templates/invalid/include_nonexistent_file.html new file mode 100644 index 0000000000..617d2fdaaa --- /dev/null +++ b/tests/template/templates/invalid/include_nonexistent_file.html @@ -0,0 +1 @@ + diff --git a/tests/template/templates/invalid/output/include_nonexistent_file.html b/tests/template/templates/invalid/output/include_nonexistent_file.html new file mode 100644 index 0000000000..8a118d2713 --- /dev/null +++ b/tests/template/templates/invalid/output/include_nonexistent_file.html @@ -0,0 +1 @@ +style resource locator: File for handle nonexistent.html does not exist. Could not find: From 226743d10bd1c31095c8bf970de8698789ca6e61 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Thu, 10 May 2012 11:43:25 +0200 Subject: [PATCH 173/441] [ticket/10881] Replace old (and unify) file headers in develop files. This especially also fixes the problem of the copyright symbol being represented using 0xA9, which is neither ASCII nor the appropriate UTF8 byte sequence for the copyright symbol. PHPBB3-10881 --- phpBB/develop/add_permissions.php | 18 ++++++---------- phpBB/develop/calc_email_hash.php | 18 ++++++---------- phpBB/develop/change_smiley_ref.php | 24 ++++++--------------- phpBB/develop/check_flash_bbcodes.php | 4 +--- phpBB/develop/create_variable_overview.php | 22 ++++++++----------- phpBB/develop/fill.php | 17 +++++++-------- phpBB/develop/merge_attachment_tables.php | 18 ++++++---------- phpBB/develop/merge_post_tables.php | 25 ++++++---------------- phpBB/develop/mysql_upgrader.php | 1 - 9 files changed, 53 insertions(+), 94 deletions(-) diff --git a/phpBB/develop/add_permissions.php b/phpBB/develop/add_permissions.php index 035c23f49c..6f26bf6ac6 100644 --- a/phpBB/develop/add_permissions.php +++ b/phpBB/develop/add_permissions.php @@ -1,15 +1,11 @@ Date: Mon, 26 Mar 2012 22:59:35 +0530 Subject: [PATCH 174/441] [ticket/10308] disable retain/ delete posts option when deleting a user When deleting a user, it asks whether the posts by user should be retained or deleted. The selection should be disable if the user has no posts. PHPBB3-10308 --- phpBB/adm/style/acp_users_overview.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/adm/style/acp_users_overview.html b/phpBB/adm/style/acp_users_overview.html index 9237e45daf..0eeb7cde8b 100644 --- a/phpBB/adm/style/acp_users_overview.html +++ b/phpBB/adm/style/acp_users_overview.html @@ -140,7 +140,7 @@ {L_DELETE_USER}

      {L_DELETE_USER_EXPLAIN}
      -
      +

      From 239e6016a308cd80135ebe9d7057c2eb102af29d Mon Sep 17 00:00:00 2001 From: Dhruv Goel Date: Mon, 9 Apr 2012 02:21:45 +0530 Subject: [PATCH 175/441] [ticket/10308] Displays message to user if there are no posts. While deletng the user, if the user has no posts in addition to the options being disabled an added message is displayed. PHPBB3-10308 --- phpBB/adm/style/acp_users_overview.html | 3 +++ phpBB/language/en/acp/users.php | 1 + 2 files changed, 4 insertions(+) diff --git a/phpBB/adm/style/acp_users_overview.html b/phpBB/adm/style/acp_users_overview.html index 0eeb7cde8b..b158995563 100644 --- a/phpBB/adm/style/acp_users_overview.html +++ b/phpBB/adm/style/acp_users_overview.html @@ -141,6 +141,9 @@


      {L_DELETE_USER_EXPLAIN}
      + +
      {L_NO_POSTS}
      +

      diff --git a/phpBB/language/en/acp/users.php b/phpBB/language/en/acp/users.php index eda9659795..928699fd11 100644 --- a/phpBB/language/en/acp/users.php +++ b/phpBB/language/en/acp/users.php @@ -77,6 +77,7 @@ $lang = array_merge($lang, array( 'MOVE_POSTS_EXPLAIN' => 'Please select the forum to which you wish to move all the posts this user has made.', + 'NO_POSTS' => 'The user has no posts.', 'NO_SPECIAL_RANK' => 'No special rank assigned', 'NO_WARNINGS' => 'No warnings.', 'NOT_MANAGE_FOUNDER' => 'You tried to manage a user with founder status. Only founders are allowed to manage other founders.', From 8f7e85604bb36679db1baa37588fc5e39a8b853f Mon Sep 17 00:00:00 2001 From: Dhruv Goel Date: Wed, 11 Apr 2012 03:00:16 +0530 Subject: [PATCH 176/441] [ticket/10308] fixes language entity. Language key has been changed and has been made more specific to avoid conflicts PHPBB3-10308 --- phpBB/adm/style/acp_users_overview.html | 2 +- phpBB/language/en/acp/users.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/phpBB/adm/style/acp_users_overview.html b/phpBB/adm/style/acp_users_overview.html index b158995563..73be17c4c1 100644 --- a/phpBB/adm/style/acp_users_overview.html +++ b/phpBB/adm/style/acp_users_overview.html @@ -142,7 +142,7 @@


      {L_DELETE_USER_EXPLAIN}
      -
      {L_NO_POSTS}
      +
      {L_USER_NO_POSTS}

      diff --git a/phpBB/language/en/acp/users.php b/phpBB/language/en/acp/users.php index 928699fd11..25e172e55c 100644 --- a/phpBB/language/en/acp/users.php +++ b/phpBB/language/en/acp/users.php @@ -77,7 +77,6 @@ $lang = array_merge($lang, array( 'MOVE_POSTS_EXPLAIN' => 'Please select the forum to which you wish to move all the posts this user has made.', - 'NO_POSTS' => 'The user has no posts.', 'NO_SPECIAL_RANK' => 'No special rank assigned', 'NO_WARNINGS' => 'No warnings.', 'NOT_MANAGE_FOUNDER' => 'You tried to manage a user with founder status. Only founders are allowed to manage other founders.', @@ -125,6 +124,7 @@ $lang = array_merge($lang, array( 'USER_GROUP_SPECIAL' => 'Pre-defined groups user is a member of', 'USER_LIFTED_NR' => 'Successfully removed the user’s newly registered status.', 'USER_NO_ATTACHMENTS' => 'There are no attached files to display.', + 'USER_NO_POSTS' => 'The user has no posts.', 'USER_OUTBOX_EMPTIED' => 'Successfully emptied user’s private message outbox.', 'USER_OUTBOX_EMPTY' => 'The user’s private message outbox was already empty.', 'USER_OVERVIEW_UPDATED' => 'User details updated.', From 59177a86c4160a4879aaf77e602f91ccea0fb107 Mon Sep 17 00:00:00 2001 From: Dhruv Goel Date: Fri, 20 Apr 2012 17:11:07 +0530 Subject: [PATCH 177/441] [ticket/10308] fix language and user's total posts language modified to be clear and select box disappears in case no posts by user. user's total posts are fetched using a new query. PHPBB3-10308 --- phpBB/adm/style/acp_users_overview.html | 8 +++++--- phpBB/includes/acp/acp_users.php | 8 ++++++++ phpBB/language/en/acp/users.php | 2 +- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/phpBB/adm/style/acp_users_overview.html b/phpBB/adm/style/acp_users_overview.html index 73be17c4c1..e6a1411bbb 100644 --- a/phpBB/adm/style/acp_users_overview.html +++ b/phpBB/adm/style/acp_users_overview.html @@ -140,9 +140,11 @@ {L_DELETE_USER}


      {L_DELETE_USER_EXPLAIN}
      -
      - -
      {L_USER_NO_POSTS}
      +
      + + {L_USER_NO_POSTS} + +

      diff --git a/phpBB/includes/acp/acp_users.php b/phpBB/includes/acp/acp_users.php index 363c900edc..1f0f053a85 100644 --- a/phpBB/includes/acp/acp_users.php +++ b/phpBB/includes/acp/acp_users.php @@ -1009,6 +1009,13 @@ class acp_users $user_row['posts_in_queue'] = (int) $db->sql_fetchfield('posts_in_queue'); $db->sql_freeresult($result); + $sql = 'SELECT COUNT(post_id) as user_total_posts + FROM ' . POSTS_TABLE . ' + WHERE poster_id = '. $user_id; + $result = $db->sql_query($sql); + $user_row['user_total_posts'] = (int) $db->sql_fetchfield('user_total_posts'); + $db->sql_freeresult($result); + $template->assign_vars(array( 'L_NAME_CHARS_EXPLAIN' => sprintf($user->lang[$config['allow_name_chars'] . '_EXPLAIN'], $config['min_name_chars'], $config['max_name_chars']), 'L_CHANGE_PASSWORD_EXPLAIN' => sprintf($user->lang[$config['pass_complex'] . '_EXPLAIN'], $config['min_pass_chars'], $config['max_pass_chars']), @@ -1036,6 +1043,7 @@ class acp_users 'USER_EMAIL' => $user_row['user_email'], 'USER_WARNINGS' => $user_row['user_warnings'], 'USER_POSTS' => $user_row['user_posts'], + 'USER_TOTAL_POSTS' => $user_row['user_total_posts'], 'USER_INACTIVE_REASON' => $inactive_reason, )); diff --git a/phpBB/language/en/acp/users.php b/phpBB/language/en/acp/users.php index 25e172e55c..7f3a3d2a48 100644 --- a/phpBB/language/en/acp/users.php +++ b/phpBB/language/en/acp/users.php @@ -124,7 +124,7 @@ $lang = array_merge($lang, array( 'USER_GROUP_SPECIAL' => 'Pre-defined groups user is a member of', 'USER_LIFTED_NR' => 'Successfully removed the user’s newly registered status.', 'USER_NO_ATTACHMENTS' => 'There are no attached files to display.', - 'USER_NO_POSTS' => 'The user has no posts.', + 'USER_NO_POSTS' => 'The user has no posts to retain or delete.', 'USER_OUTBOX_EMPTIED' => 'Successfully emptied user’s private message outbox.', 'USER_OUTBOX_EMPTY' => 'The user’s private message outbox was already empty.', 'USER_OVERVIEW_UPDATED' => 'User details updated.', From faf232219ef3b7a5dcc3d22639d4005040b0d8ad Mon Sep 17 00:00:00 2001 From: Dhruv Goel Date: Fri, 20 Apr 2012 23:11:55 +0530 Subject: [PATCH 178/441] [ticket/10308] renames language key to USER_NO_POSTS_DELETE language key renamed to make its usability more clearer. PHPBB3-10308 --- phpBB/adm/style/acp_users_overview.html | 2 +- phpBB/language/en/acp/users.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/phpBB/adm/style/acp_users_overview.html b/phpBB/adm/style/acp_users_overview.html index e6a1411bbb..2a27cc2a63 100644 --- a/phpBB/adm/style/acp_users_overview.html +++ b/phpBB/adm/style/acp_users_overview.html @@ -142,7 +142,7 @@


      {L_DELETE_USER_EXPLAIN}
      - {L_USER_NO_POSTS} + {L_USER_NO_POSTS_DELETE}
      diff --git a/phpBB/language/en/acp/users.php b/phpBB/language/en/acp/users.php index 7f3a3d2a48..52b7a35eac 100644 --- a/phpBB/language/en/acp/users.php +++ b/phpBB/language/en/acp/users.php @@ -124,7 +124,7 @@ $lang = array_merge($lang, array( 'USER_GROUP_SPECIAL' => 'Pre-defined groups user is a member of', 'USER_LIFTED_NR' => 'Successfully removed the user’s newly registered status.', 'USER_NO_ATTACHMENTS' => 'There are no attached files to display.', - 'USER_NO_POSTS' => 'The user has no posts to retain or delete.', + 'USER_NO_POSTS_DELETE' => 'The user has no posts to retain or delete.', 'USER_OUTBOX_EMPTIED' => 'Successfully emptied user’s private message outbox.', 'USER_OUTBOX_EMPTY' => 'The user’s private message outbox was already empty.', 'USER_OVERVIEW_UPDATED' => 'User details updated.', From cf303c34788b32e1c09f483e2760b77eff3e05ca Mon Sep 17 00:00:00 2001 From: Dhruv Goel Date: Sat, 21 Apr 2012 14:29:21 +0530 Subject: [PATCH 179/441] [ticket/10308] fixes user deletion if no posts introduces a hidden input field with retain posts as the mode in case user has no posts. PHPBB3-10308 --- phpBB/adm/style/acp_users_overview.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/adm/style/acp_users_overview.html b/phpBB/adm/style/acp_users_overview.html index 2a27cc2a63..fdc1d55855 100644 --- a/phpBB/adm/style/acp_users_overview.html +++ b/phpBB/adm/style/acp_users_overview.html @@ -142,7 +142,7 @@

      {L_DELETE_USER_EXPLAIN}
      - {L_USER_NO_POSTS_DELETE} + {L_USER_NO_POSTS_DELETE}
      From 164054f0679caaa68fb8400d3469b1149022db29 Mon Sep 17 00:00:00 2001 From: Dhruv Goel Date: Sun, 22 Apr 2012 00:36:38 +0530 Subject: [PATCH 180/441] [ticket/10308] fixes sql query, limit it to 1 instead of fetching all posts by user we limit the query to 1 to check if a user has posts or not PHPBB3-10308 --- phpBB/adm/style/acp_users_overview.html | 2 +- phpBB/includes/acp/acp_users.php | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/phpBB/adm/style/acp_users_overview.html b/phpBB/adm/style/acp_users_overview.html index fdc1d55855..ea2700e5e4 100644 --- a/phpBB/adm/style/acp_users_overview.html +++ b/phpBB/adm/style/acp_users_overview.html @@ -141,7 +141,7 @@

      {L_DELETE_USER_EXPLAIN}
      - + {L_USER_NO_POSTS_DELETE}
      diff --git a/phpBB/includes/acp/acp_users.php b/phpBB/includes/acp/acp_users.php index 1f0f053a85..7565d43690 100644 --- a/phpBB/includes/acp/acp_users.php +++ b/phpBB/includes/acp/acp_users.php @@ -1009,11 +1009,11 @@ class acp_users $user_row['posts_in_queue'] = (int) $db->sql_fetchfield('posts_in_queue'); $db->sql_freeresult($result); - $sql = 'SELECT COUNT(post_id) as user_total_posts + $sql = 'SELECT post_id FROM ' . POSTS_TABLE . ' WHERE poster_id = '. $user_id; - $result = $db->sql_query($sql); - $user_row['user_total_posts'] = (int) $db->sql_fetchfield('user_total_posts'); + $result = $db->sql_query_limit($sql, 1); + $user_row['user_has_posts'] = ($db->sql_fetchfield('post_id') ? 1 : 0); $db->sql_freeresult($result); $template->assign_vars(array( @@ -1043,7 +1043,7 @@ class acp_users 'USER_EMAIL' => $user_row['user_email'], 'USER_WARNINGS' => $user_row['user_warnings'], 'USER_POSTS' => $user_row['user_posts'], - 'USER_TOTAL_POSTS' => $user_row['user_total_posts'], + 'USER_HAS_POSTS' => $user_row['user_has_posts'], 'USER_INACTIVE_REASON' => $inactive_reason, )); From 23ea588880a6793b53f2f4da0eb0609bed3fc90c Mon Sep 17 00:00:00 2001 From: Dhruv Goel Date: Wed, 9 May 2012 21:41:12 +0530 Subject: [PATCH 181/441] [ticket/10308] makes variable boolean makes user_row['user_has_posts'] boolean instead of 1 or 0. PHPBB3-10308 --- phpBB/includes/acp/acp_users.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/includes/acp/acp_users.php b/phpBB/includes/acp/acp_users.php index 7565d43690..70e08f79f2 100644 --- a/phpBB/includes/acp/acp_users.php +++ b/phpBB/includes/acp/acp_users.php @@ -1013,7 +1013,7 @@ class acp_users FROM ' . POSTS_TABLE . ' WHERE poster_id = '. $user_id; $result = $db->sql_query_limit($sql, 1); - $user_row['user_has_posts'] = ($db->sql_fetchfield('post_id') ? 1 : 0); + $user_row['user_has_posts'] = (bool) $db->sql_fetchfield('post_id'); $db->sql_freeresult($result); $template->assign_vars(array( From cf556f92c91816f6aef9028d911b5584f08842af Mon Sep 17 00:00:00 2001 From: Dhruv Goel Date: Wed, 9 May 2012 21:46:27 +0530 Subject: [PATCH 182/441] [ticket/10308] fixes language variable name Language variable has be renamed for better understanding PHPBB3-10308 --- phpBB/adm/style/acp_users_overview.html | 2 +- phpBB/language/en/acp/users.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/phpBB/adm/style/acp_users_overview.html b/phpBB/adm/style/acp_users_overview.html index ea2700e5e4..1969428e38 100644 --- a/phpBB/adm/style/acp_users_overview.html +++ b/phpBB/adm/style/acp_users_overview.html @@ -142,7 +142,7 @@

      {L_DELETE_USER_EXPLAIN}
      - {L_USER_NO_POSTS_DELETE} + {L_USER_NO_POSTS_TO_DELETE}
      diff --git a/phpBB/language/en/acp/users.php b/phpBB/language/en/acp/users.php index 52b7a35eac..785283faea 100644 --- a/phpBB/language/en/acp/users.php +++ b/phpBB/language/en/acp/users.php @@ -124,7 +124,7 @@ $lang = array_merge($lang, array( 'USER_GROUP_SPECIAL' => 'Pre-defined groups user is a member of', 'USER_LIFTED_NR' => 'Successfully removed the user’s newly registered status.', 'USER_NO_ATTACHMENTS' => 'There are no attached files to display.', - 'USER_NO_POSTS_DELETE' => 'The user has no posts to retain or delete.', + 'USER_NO_POSTS_TO_DELETE' => 'The user has no posts to retain or delete.', 'USER_OUTBOX_EMPTIED' => 'Successfully emptied user’s private message outbox.', 'USER_OUTBOX_EMPTY' => 'The user’s private message outbox was already empty.', 'USER_OVERVIEW_UPDATED' => 'User details updated.', From 8393b8e755150593dbf85f545ac7ca3d8798e58c Mon Sep 17 00:00:00 2001 From: Senky Date: Tue, 10 Apr 2012 11:14:05 +0200 Subject: [PATCH 183/441] [ticket/9896] Links changed Link to languaged updated to http://www.phpbb.com/languages/ Link to styles updated to http://www.phpbb.com/customise/db/styles-2/ Link to MODs updated to http://www.phpbb.com/customise/db/modifications-1/ Link to Community Forums updated to http://www.phpbb.com/community/ PHPBB3-9896 --- phpBB/docs/README.html | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/phpBB/docs/README.html b/phpBB/docs/README.html index aa60d7dd25..0bdf94d181 100644 --- a/phpBB/docs/README.html +++ b/phpBB/docs/README.html @@ -130,9 +130,9 @@

      2.i. Internationalisation (i18n)

      -

      A number of language packs and style localisations are available. You can find them on our official download page:

      +

      A number of language packs and style localisations are available. You can find them on our official language packs page:

      -

      http://www.phpbb.com/downloads/

      +

      http://www.phpbb.com/languages/

      This is the official location for all supported language sets. If you download a package from a 3rd party site you do so with the understanding that we cannot offer support. So please, do not ask for help in these cases!

      @@ -144,7 +144,7 @@

      Although phpBB Group are rather proud of the included styles we realise that it may not be to everyones tastes. Therefore phpBB3 allows styles to be switched with relative ease. Firstly you need to locate and download a style you like. We maintain such a site at

      -

      http://www.phpbb.com/styles/

      +

      http://www.phpbb.com/customise/db/styles-2/

      Please note that 3rd party styles downloaded for versions of phpBB2 will not work in phpBB3.

      @@ -156,7 +156,7 @@

      Although not officially supported by phpBB Group, phpBB has a thriving modification scene. These third party modifications to the standard phpBB extend its capabilities still further and can be found at:

      -

      http://www.phpbb.com/mods/

      +

      http://www.phpbb.com/customise/db/modifications-1/

      Please remember that any bugs or other issues that occur after you have added any modification should NOT be reported to the bug tracker (see below). First remove the modification and see if the problem is resolved.

      @@ -192,7 +192,7 @@

      phpBB Group maintains a thriving community where a number of people have generously decided to donate their time to help support users. This site can be found at:

      -

      http://www.phpbb.com/

      +

      http://www.phpbb.com/community/

      If you do seek help via our forums please be sure to do a Search before posting. This may well save both you and us time and allow the developer, moderator and support groups to spend more time responding to people with unknown issues and problems. Please also remember that phpBB is an entirely volunteer effort, no one receives any compensation for the time they give, this includes moderators as well as developers. So please be respectful and mindful when awaiting responses.

      From 041b7be77ecd4e52048b94b4e47ad8268716a032 Mon Sep 17 00:00:00 2001 From: Dhruv Goel Date: Fri, 11 May 2012 01:50:36 +0530 Subject: [PATCH 184/441] [ticket/10308] fixes indentation indentation is fixed and user_posts variable is compared as a boolean variable. PHPBB3-10308 --- phpBB/adm/style/acp_users_overview.html | 38 ++++++++++++------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/phpBB/adm/style/acp_users_overview.html b/phpBB/adm/style/acp_users_overview.html index 1969428e38..e2dcdb6307 100644 --- a/phpBB/adm/style/acp_users_overview.html +++ b/phpBB/adm/style/acp_users_overview.html @@ -135,24 +135,24 @@ -
      -
      - {L_DELETE_USER} -
      -

      {L_DELETE_USER_EXPLAIN}
      -
      - - {L_USER_NO_POSTS_TO_DELETE} - -
      - -
      -

      - - - {S_FORM_TOKEN} -

      -
      - +
      +
      + {L_DELETE_USER} +
      +

      {L_DELETE_USER_EXPLAIN}
      +
      + +
      + + {L_USER_NO_POSTS_TO_DELETE} + +
      +

      + + + {S_FORM_TOKEN} +

      +
      + From 1019226dfa359cb223d68e7b9132006a8cd2a859 Mon Sep 17 00:00:00 2001 From: Oleg Pudeyev Date: Thu, 10 May 2012 23:22:35 -0400 Subject: [PATCH 185/441] [ticket/10887] Split auto increment test from db tools test. Auto increment test does not need any particular columns and should not depend, in particular, on correct handling of binary data. This commit moves auto increment test into its own file and gives it its own table with a simple schema. PHPBB3-10887 --- tests/dbal/auto_increment_test.php | 100 +++++++++++++++++++++++++++++ tests/dbal/db_tools_test.php | 45 ------------- 2 files changed, 100 insertions(+), 45 deletions(-) create mode 100644 tests/dbal/auto_increment_test.php diff --git a/tests/dbal/auto_increment_test.php b/tests/dbal/auto_increment_test.php new file mode 100644 index 0000000000..c18e589861 --- /dev/null +++ b/tests/dbal/auto_increment_test.php @@ -0,0 +1,100 @@ +createXMLDataSet(dirname(__FILE__).'/fixtures/config.xml'); + } + + protected function setUp() + { + parent::setUp(); + + $this->db = $this->new_dbal(); + $this->tools = new phpbb_db_tools($this->db); + + $this->table_data = array( + 'COLUMNS' => array( + 'c_id' => array('UINT', NULL, 'auto_increment'), + 'c_uint' => array('UINT', 4), + ), + 'PRIMARY_KEY' => 'c_id', + ); + $this->tools->sql_create_table('prefix_table_name', $this->table_data); + $this->table_exists = true; + } + + protected function tearDown() + { + if ($this->table_exists) + { + $this->tools->sql_table_drop('prefix_table_name'); + } + + parent::tearDown(); + } + + static protected function get_default_values() + { + return array( + 'c_uint' => 0, + ); + } + + public function test_auto_increment() + { + $sql = 'DELETE FROM prefix_table_name'; + $result = $this->db->sql_query($sql); + + $row1 = array_merge(self::get_default_values(), array( + 'c_uint' => 1, + )); + $row2 = array_merge(self::get_default_values(), array( + 'c_uint' => 2, + )); + + $sql = 'INSERT INTO prefix_table_name ' . $this->db->sql_build_array('INSERT', $row1); + $result = $this->db->sql_query($sql); + $id1 = $this->db->sql_nextid(); + + $sql = 'INSERT INTO prefix_table_name ' . $this->db->sql_build_array('INSERT', $row2); + $result = $this->db->sql_query($sql); + $id2 = $this->db->sql_nextid(); + + $this->assertGreaterThan($id1, $id2, 'Auto increment should increase the id value'); + + $sql = "SELECT * + FROM prefix_table_name WHERE c_id = $id1"; + $result = $this->db->sql_query($sql); + $row_actual = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + $row1['c_id'] = $id1; + $this->assertEquals($row1, $row_actual); + + $sql = "SELECT * + FROM prefix_table_name WHERE c_id = $id2"; + $result = $this->db->sql_query($sql); + $row_actual = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + $row2['c_id'] = $id2; + $this->assertEquals($row2, $row_actual); + } +} diff --git a/tests/dbal/db_tools_test.php b/tests/dbal/db_tools_test.php index c7ddb88ce8..516fb9e739 100644 --- a/tests/dbal/db_tools_test.php +++ b/tests/dbal/db_tools_test.php @@ -189,51 +189,6 @@ class phpbb_dbal_db_tools_test extends phpbb_database_test_case $this->assertEquals($row_expect[$column_name], $row_actual[$column_name], "Column $column_name of type $type should have equal return and input value."); } - public function test_auto_increment() - { - $sql = 'DELETE FROM prefix_table_name'; - $result = $this->db->sql_query($sql); - - $row1 = array_merge(self::get_default_values(), array( - 'c_uint' => 1, - 'c_vchar' => '1', // these values are necessary to avoid unique index issues - 'c_vchar_size' => '1', - )); - $row2 = array_merge(self::get_default_values(), array( - 'c_uint' => 2, - 'c_vchar' => '2', - 'c_vchar_size' => '2', - )); - - $sql = 'INSERT INTO prefix_table_name ' . $this->db->sql_build_array('INSERT', $row1); - $result = $this->db->sql_query($sql); - $id1 = $this->db->sql_nextid(); - - $sql = 'INSERT INTO prefix_table_name ' . $this->db->sql_build_array('INSERT', $row2); - $result = $this->db->sql_query($sql); - $id2 = $this->db->sql_nextid(); - - $this->assertGreaterThan($id1, $id2, 'Auto increment should increase the id value'); - - $sql = "SELECT * - FROM prefix_table_name WHERE c_id = $id1"; - $result = $this->db->sql_query($sql); - $row_actual = $this->db->sql_fetchrow($result); - $this->db->sql_freeresult($result); - - $row1['c_id'] = $id1; - $this->assertEquals($row1, $row_actual); - - $sql = "SELECT * - FROM prefix_table_name WHERE c_id = $id2"; - $result = $this->db->sql_query($sql); - $row_actual = $this->db->sql_fetchrow($result); - $this->db->sql_freeresult($result); - - $row2['c_id'] = $id2; - $this->assertEquals($row2, $row_actual); - } - public function test_list_columns() { $this->assertEquals( From 74e9245df3b6652db10e46302510d27a54db827e Mon Sep 17 00:00:00 2001 From: Senky Date: Fri, 11 May 2012 08:09:56 +0200 Subject: [PATCH 186/441] [ticket/10835] changing "e-mail" to "email" PHPBB3-10835 --- phpBB/language/en/ucp.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/language/en/ucp.php b/phpBB/language/en/ucp.php index 6f6b319d48..7df26e040f 100644 --- a/phpBB/language/en/ucp.php +++ b/phpBB/language/en/ucp.php @@ -137,7 +137,7 @@ $lang = array_merge($lang, array( 'CREATE_FOLDER' => 'Add folder…', 'CURRENT_IMAGE' => 'Current image', 'CURRENT_PASSWORD' => 'Current password', - 'CURRENT_PASSWORD_EXPLAIN' => 'You must enter your current password if you wish to alter your e-mail address or username.', + 'CURRENT_PASSWORD_EXPLAIN' => 'You must enter your current password if you wish to alter your email address or username.', 'CURRENT_CHANGE_PASSWORD_EXPLAIN' => 'To change your password, your email address, or your username, you must enter your current password.', 'CUR_PASSWORD_EMPTY' => 'You did not enter your current password.', 'CUR_PASSWORD_ERROR' => 'The current password you entered is incorrect.', From b5b65c214dc42a9e7a9cf15ebc00600d00331985 Mon Sep 17 00:00:00 2001 From: Oleg Pudeyev Date: Fri, 11 May 2012 05:06:46 -0400 Subject: [PATCH 187/441] [ticket/10887] Add spaces. PHPBB3-10887 --- tests/dbal/auto_increment_test.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/dbal/auto_increment_test.php b/tests/dbal/auto_increment_test.php index c18e589861..e87fc1c6bd 100644 --- a/tests/dbal/auto_increment_test.php +++ b/tests/dbal/auto_increment_test.php @@ -19,7 +19,7 @@ class phpbb_dbal_auto_increment_test extends phpbb_database_test_case public function getDataSet() { - return $this->createXMLDataSet(dirname(__FILE__).'/fixtures/config.xml'); + return $this->createXMLDataSet(dirname(__FILE__) . '/fixtures/config.xml'); } protected function setUp() From e5afe39987200779df35b55259900ab947ce46d0 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Tue, 10 Apr 2012 02:41:33 +0200 Subject: [PATCH 188/441] [ticket/10889] Make default value for c_char_size a CHAR(4) as defined. PHPBB3-10889 --- tests/dbal/db_tools_test.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/dbal/db_tools_test.php b/tests/dbal/db_tools_test.php index 516fb9e739..9bed0648cd 100644 --- a/tests/dbal/db_tools_test.php +++ b/tests/dbal/db_tools_test.php @@ -106,7 +106,7 @@ class phpbb_dbal_db_tools_test extends phpbb_database_test_case 'c_bool' => 0, 'c_vchar' => '', 'c_vchar_size' => '', - 'c_char_size' => '', + 'c_char_size' => 'abcd', 'c_xstext' => '', 'c_stext' => '', 'c_text' => '', From 1960629240679965ca22a98e69973dcfe2e05476 Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Fri, 11 May 2012 15:17:13 +0200 Subject: [PATCH 189/441] [ticket/10492] Skip functional tests on PHP 5.2 on travis PHPBB3-10492 --- travis/phpunit-mysql-travis.xml | 4 ++++ travis/phpunit-postgres-travis.xml | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/travis/phpunit-mysql-travis.xml b/travis/phpunit-mysql-travis.xml index 36845a7f71..e54b2bb77b 100644 --- a/travis/phpunit-mysql-travis.xml +++ b/travis/phpunit-mysql-travis.xml @@ -13,6 +13,10 @@ ../tests/ + tests/functional + + + ../tests/functional diff --git a/travis/phpunit-postgres-travis.xml b/travis/phpunit-postgres-travis.xml index 461a53bcb1..55ba996548 100644 --- a/travis/phpunit-postgres-travis.xml +++ b/travis/phpunit-postgres-travis.xml @@ -13,6 +13,10 @@ ../tests/ + tests/functional + + + ../tests/functional From 3a604145921b3df90379c4e44370a040165c43ef Mon Sep 17 00:00:00 2001 From: Patrick Webster Date: Thu, 12 Apr 2012 20:10:20 -0500 Subject: [PATCH 190/441] [ticket/10892] Reformat RUNNING_TESTS.txt to 80 char lines. PHPBB3-10892 --- tests/RUNNING_TESTS.txt | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/tests/RUNNING_TESTS.txt b/tests/RUNNING_TESTS.txt index 59197acc0f..3ac8bfcd67 100644 --- a/tests/RUNNING_TESTS.txt +++ b/tests/RUNNING_TESTS.txt @@ -36,8 +36,9 @@ found on the wiki (see below). $dbuser = 'user'; $dbpasswd = 'password'; -Alternatively you can specify parameters in the environment, so e.g. the following -will run phpunit with the same parameters as in the shown test_config.php file: +Alternatively you can specify parameters in the environment, so e.g. the +following will run phpunit with the same parameters as in the shown +test_config.php file: $ PHPBB_TEST_DBMS='mysqli' PHPBB_TEST_DBHOST='localhost' \ PHPBB_TEST_DBNAME='database' PHPBB_TEST_DBUSER='user' \ @@ -46,7 +47,8 @@ will run phpunit with the same parameters as in the shown test_config.php file: Running ======= -Once the prerequisites are installed, run the tests from the project root directory (above phpBB): +Once the prerequisites are installed, run the tests from the project root +directory (above phpBB): $ phpunit @@ -54,8 +56,8 @@ Slow tests -------------- Certain tests, such as the UTF-8 normalizer or the DNS tests tend to be slow. Thus these tests are in the `slow` group, which is excluded by default. You can -enable slow tests by copying the phpunit.xml.all file to phpunit.xml. If you only -want the slow tests, run: +enable slow tests by copying the phpunit.xml.all file to phpunit.xml. If you +only want the slow tests, run: $ phpunit --group slow From 07fb16edb583008ea2bc11556370cbeb41ff7c5e Mon Sep 17 00:00:00 2001 From: Oleg Pudeyev Date: Fri, 11 May 2012 22:10:19 -0400 Subject: [PATCH 191/441] [ticket/10892] Reformat RUNNING_TESTS.txt to 79 char lines. PHPBB3-10892 --- tests/RUNNING_TESTS.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/RUNNING_TESTS.txt b/tests/RUNNING_TESTS.txt index 3ac8bfcd67..dac6753187 100644 --- a/tests/RUNNING_TESTS.txt +++ b/tests/RUNNING_TESTS.txt @@ -24,9 +24,9 @@ Database Tests By default all tests requiring a database connection will use sqlite. If you do not have sqlite installed the tests will be skipped. If you wish to run the tests on a different database you have to create a test_config.php file within -your tests directory following the same format as phpBB's config.php. An example -for mysqli can be found below. More information on configuration options can be -found on the wiki (see below). +your tests directory following the same format as phpBB's config.php. An +example for mysqli can be found below. More information on configuration +options can be found on the wiki (see below). Date: Fri, 11 May 2012 22:14:12 -0400 Subject: [PATCH 192/441] [ticket/10892] Add empty lines for consistency. Some headings had empty lines after them, some did not. Add missing empty lines. PHPBB3-10892 --- tests/RUNNING_TESTS.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/RUNNING_TESTS.txt b/tests/RUNNING_TESTS.txt index dac6753187..ebc61360de 100644 --- a/tests/RUNNING_TESTS.txt +++ b/tests/RUNNING_TESTS.txt @@ -21,6 +21,7 @@ the following PHP extensions must be installed and enabled to run unit tests: Database Tests -------------- + By default all tests requiring a database connection will use sqlite. If you do not have sqlite installed the tests will be skipped. If you wish to run the tests on a different database you have to create a test_config.php file within @@ -54,6 +55,7 @@ directory (above phpBB): Slow tests -------------- + Certain tests, such as the UTF-8 normalizer or the DNS tests tend to be slow. Thus these tests are in the `slow` group, which is excluded by default. You can enable slow tests by copying the phpunit.xml.all file to phpunit.xml. If you From 2592fbf8e927b064f41b744b8725341f18e02e68 Mon Sep 17 00:00:00 2001 From: Oleg Pudeyev Date: Fri, 11 May 2012 22:14:40 -0400 Subject: [PATCH 193/441] [ticket/10892] Update wiki link to mediawiki. PHPBB3-10892 --- tests/RUNNING_TESTS.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/RUNNING_TESTS.txt b/tests/RUNNING_TESTS.txt index ebc61360de..c80c42a83d 100644 --- a/tests/RUNNING_TESTS.txt +++ b/tests/RUNNING_TESTS.txt @@ -67,4 +67,4 @@ More Information ================ Further information is available on phpbb wiki: -http://wiki.phpbb.com/display/DEV/Unit+Tests +http://wiki.phpbb.com/Unit_Tests From 725db1ba29960aa8ad2a24c7324078c69c6c8ced Mon Sep 17 00:00:00 2001 From: Oleg Pudeyev Date: Fri, 11 May 2012 22:24:01 -0400 Subject: [PATCH 194/441] [ticket/10891] Allow specifying test_config.php path via environment. PHPBB3-10891 --- tests/RUNNING_TESTS.txt | 6 ++++++ tests/test_framework/phpbb_test_case_helpers.php | 14 ++++++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/tests/RUNNING_TESTS.txt b/tests/RUNNING_TESTS.txt index 59197acc0f..b92423c1f4 100644 --- a/tests/RUNNING_TESTS.txt +++ b/tests/RUNNING_TESTS.txt @@ -36,6 +36,12 @@ found on the wiki (see below). $dbuser = 'user'; $dbpasswd = 'password'; +It is possible to have multiple test_config.php files, for example if you +are testing on multiple databases. You can specify which test_config.php file +to use in the environment as follows: + + $ PHPBB_TEST_CONFIG=tests/test_config.php phpunit + Alternatively you can specify parameters in the environment, so e.g. the following will run phpunit with the same parameters as in the shown test_config.php file: diff --git a/tests/test_framework/phpbb_test_case_helpers.php b/tests/test_framework/phpbb_test_case_helpers.php index b46c36efaa..2a3c27f9f9 100644 --- a/tests/test_framework/phpbb_test_case_helpers.php +++ b/tests/test_framework/phpbb_test_case_helpers.php @@ -58,9 +58,19 @@ class phpbb_test_case_helpers )); } - if (file_exists(dirname(__FILE__) . '/../test_config.php')) + if (isset($_SERVER['PHPBB_TEST_CONFIG'])) { - include(dirname(__FILE__) . '/../test_config.php'); + // Could be an absolute path + $test_config = $_SERVER['PHPBB_TEST_CONFIG']; + } + else + { + $test_config = dirname(__FILE__) . '/../test_config.php'; + } + + if (file_exists($test_config)) + { + include($test_config); $config = array_merge($config, array( 'dbms' => $dbms, From 47c6b32d874826e4994c6589ed21a4fd9b4556d5 Mon Sep 17 00:00:00 2001 From: Joseph Warner Date: Sun, 13 May 2012 13:05:20 -0400 Subject: [PATCH 195/441] [ticket/10893] Update the usage of Composer Changes 'vendor/.composer/autoload.php' to 'vendor/autoload.php' as per the change in the way that composer works as noted https://groups.google.com/forum/#!msg/composer-dev/fWIs3KocwoA/nU3aLko9LhQJ PHPBB3-10893 --- phpBB/includes/startup.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/phpBB/includes/startup.php b/phpBB/includes/startup.php index f75d70e366..441eaec6b1 100644 --- a/phpBB/includes/startup.php +++ b/phpBB/includes/startup.php @@ -150,7 +150,7 @@ if (function_exists('date_default_timezone_set') && function_exists('date_defaul // Autoloading of dependencies. // Three options are supported: // 1. If dependencies are installed with Composer, Composer will create a -// vendor/.composer/autoload.php. If this file exists it will be +// vendor/autoload.php. If this file exists it will be // automatically used by phpBB. This is the default mode that phpBB // will use when shipped. // 2. To disable composer autoloading, PHPBB_NO_COMPOSER_AUTOLOAD can be specified. @@ -171,11 +171,11 @@ if (getenv('PHPBB_NO_COMPOSER_AUTOLOAD')) } else { - if (!file_exists($phpbb_root_path . 'vendor/.composer/autoload.php')) + if (!file_exists($phpbb_root_path . 'vendor/autoload.php')) { trigger_error('You have not set up composer dependencies. See http://getcomposer.org/.', E_USER_ERROR); } - require($phpbb_root_path . 'vendor/.composer/autoload.php'); + require($phpbb_root_path . 'vendor/autoload.php'); } $starttime = explode(' ', microtime()); From 29b36b214a809b6ae49f941a4e3965ffba2b8741 Mon Sep 17 00:00:00 2001 From: Patrick Webster Date: Sun, 13 May 2012 16:56:07 -0500 Subject: [PATCH 196/441] [ticket/10678] Typo and formatting PHPBB3-10678 --- .../phpbb_database_connection_odbc_pdo_wrapper.php | 2 +- tests/test_framework/phpbb_database_test_case.php | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/test_framework/phpbb_database_connection_odbc_pdo_wrapper.php b/tests/test_framework/phpbb_database_connection_odbc_pdo_wrapper.php index 5eba2e7a2e..cb5956be9f 100644 --- a/tests/test_framework/phpbb_database_connection_odbc_pdo_wrapper.php +++ b/tests/test_framework/phpbb_database_connection_odbc_pdo_wrapper.php @@ -25,7 +25,7 @@ class phpbb_database_connection_odbc_pdo_wrapper extends PDO function __construct($dbms, $version, $dsn, $user, $pass) { $this->driver = $dbms; - $this->version = (double)$version; + $this->version = (double) $version; parent::__construct($dsn, $user, $pass); } diff --git a/tests/test_framework/phpbb_database_test_case.php b/tests/test_framework/phpbb_database_test_case.php index 53c3702aa6..bb86df0ef0 100644 --- a/tests/test_framework/phpbb_database_test_case.php +++ b/tests/test_framework/phpbb_database_test_case.php @@ -39,11 +39,11 @@ abstract class phpbb_database_test_case extends PHPUnit_Extensions_Database_Test $xml_data = preg_replace_callback('/(?:(
      ))/', 'phpbb_database_test_case::to_upper', $xml_data); $xml_data = preg_replace_callback('/(?:())([a-z_]+)(?:(<\/column>))/', 'phpbb_database_test_case::to_upper', $xml_data); - $temp = tmpfile(); - fwrite($temp, $xml_data); - fseek($temp, 0); + $new_fixture = tmpfile(); + fwrite($new_fixture, $xml_data); + fseek($new_fixture, 0); - $meta_data = stream_get_meta_data($temp); + $meta_data = stream_get_meta_data($new_fixture); $path = $meta_data['uri']; } @@ -131,7 +131,7 @@ abstract class phpbb_database_test_case extends PHPUnit_Extensions_Database_Test /** * Converts a match in the middle of a string to uppercase. - * This is necessary for tranforming the fixture information for Firebird tests + * This is necessary for transforming the fixture information for Firebird tests * * @param $matches The array of matches from a regular expression * From f71a9d369c84ec938408a2134b09ea259f6cbbab Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Mon, 14 May 2012 00:34:42 +0200 Subject: [PATCH 197/441] [ticket/10605] Put end of array on its own line because start of array is too. PHPBB3-10605 --- phpBB/install/database_update.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/phpBB/install/database_update.php b/phpBB/install/database_update.php index 0737061887..2a361aae26 100644 --- a/phpBB/install/database_update.php +++ b/phpBB/install/database_update.php @@ -2043,7 +2043,8 @@ function change_database_data(&$no_updates, $version) 'ON' => 'p.msg_id = t.msg_id', ), ), - 'WHERE' => 't.user_id IS NULL'); + 'WHERE' => 't.user_id IS NULL', + ); $sql = $db->sql_build_query('SELECT', $sql_array); do From 95e1d4e9db8d2174c8ee5c6bb35be06abc57e3cf Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Mon, 14 May 2012 00:36:18 +0200 Subject: [PATCH 198/441] [ticket/10605] Use database updater function _sql() instead of $db->sql_query() PHPBB3-10605 --- phpBB/install/database_update.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/install/database_update.php b/phpBB/install/database_update.php index 2a361aae26..95a0282878 100644 --- a/phpBB/install/database_update.php +++ b/phpBB/install/database_update.php @@ -2062,7 +2062,7 @@ function change_database_data(&$no_updates, $version) { $sql = 'DELETE FROM ' . PRIVMSGS_TABLE . ' WHERE ' . $db->sql_in_set('msg_id', $delete_pms); - $db->sql_query($sql); + _sql($sql, $errored, $error_ary); } } while (sizeof($delete_pms) == $batch_size); From fc3a19567f1852389dfa78472cca4b1d01387bfa Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Wed, 16 May 2012 13:44:40 +0200 Subject: [PATCH 199/441] [ticket/10811] Make it easier for MODs/Extensions to define the alt-text PHPBB3-10811 --- phpBB/includes/functions_display.php | 1 + phpBB/styles/prosilver/template/overall_footer.html | 6 +++--- phpBB/styles/subsilver2/template/viewtopic_body.html | 4 ++-- phpBB/viewforum.php | 2 ++ phpBB/viewtopic.php | 10 ++++++---- 5 files changed, 14 insertions(+), 9 deletions(-) diff --git a/phpBB/includes/functions_display.php b/phpBB/includes/functions_display.php index 18db64cc68..7c1d007d55 100644 --- a/phpBB/includes/functions_display.php +++ b/phpBB/includes/functions_display.php @@ -1219,6 +1219,7 @@ function watch_topic_forum($mode, &$s_watching, $user_id, $forum_id, $topic_id, { $s_watching['link'] = append_sid("{$phpbb_root_path}view$mode.$phpEx", "$u_url=$match_id&" . (($is_watching) ? 'unwatch' : 'watch') . "=$mode&start=$start&hash=" . generate_link_hash("{$mode}_$match_id")); $s_watching['title'] = $user->lang[(($is_watching) ? 'STOP' : 'START') . '_WATCHING_' . strtoupper($mode)]; + $s_watching['toggle'] = $user->lang[((!$is_watching) ? 'STOP' : 'START') . '_WATCHING_' . strtoupper($mode)]; $s_watching['is_watching'] = $is_watching; } diff --git a/phpBB/styles/prosilver/template/overall_footer.html b/phpBB/styles/prosilver/template/overall_footer.html index 972d90305e..1aab6528cd 100644 --- a/phpBB/styles/prosilver/template/overall_footer.html +++ b/phpBB/styles/prosilver/template/overall_footer.html @@ -8,9 +8,9 @@ + + +
      {L_PROFILE_NO_AUTOLOGIN_KEYS}
  • diff --git a/phpBB/styles/subsilver2/template/ucp_profile_autologin_keys.html b/phpBB/styles/subsilver2/template/ucp_profile_autologin_keys.html index 365b6f4a52..2d3b9f98f8 100644 --- a/phpBB/styles/subsilver2/template/ucp_profile_autologin_keys.html +++ b/phpBB/styles/subsilver2/template/ucp_profile_autologin_keys.html @@ -13,29 +13,28 @@ - - - {L_PROFILE_AUTOLOGIN_KEYS} + + + {L_PROFILE_AUTOLOGIN_KEYS} + + + {L_MARK} + {L_LOGIN_KEY} + {L_IP} + {L_LOGIN_TIME} + + + + + + {sessions.IP} + {sessions.LOGIN_TIME} - - {L_MARK} - {L_LOGIN_KEY} - {L_IP} - {L_LOGIN_TIME} - - - - - - {sessions.IP} - {sessions.LOGIN_TIME} - - - + {L_PROFILE_NO_AUTOLOGIN_KEYS} - + From 73ca5edb296bfe2d599e001d593cc2d952be3941 Mon Sep 17 00:00:00 2001 From: Dhruv Goel Date: Thu, 17 May 2012 14:08:50 +0530 Subject: [PATCH 212/441] [feature/delete-auto-logins] fixes style removes reset button and some minor style fixes in subsilver2 and prosilver. PHPBB3-9647 --- .../prosilver/template/ucp_profile_autologin_keys.html | 5 ++--- .../subsilver2/template/ucp_profile_autologin_keys.html | 5 ++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/phpBB/styles/prosilver/template/ucp_profile_autologin_keys.html b/phpBB/styles/prosilver/template/ucp_profile_autologin_keys.html index a8af932cb6..a6c19508e2 100644 --- a/phpBB/styles/prosilver/template/ucp_profile_autologin_keys.html +++ b/phpBB/styles/prosilver/template/ucp_profile_autologin_keys.html @@ -34,7 +34,7 @@ {sessions.LOGIN_TIME} - {L_PROFILE_NO_AUTOLOGIN_KEYS} + {L_PROFILE_NO_AUTOLOGIN_KEYS} @@ -44,8 +44,7 @@
    - {S_HIDDEN_FIELDS}  - + {S_HIDDEN_FIELDS} {S_FORM_TOKEN}
    diff --git a/phpBB/styles/subsilver2/template/ucp_profile_autologin_keys.html b/phpBB/styles/subsilver2/template/ucp_profile_autologin_keys.html index 2d3b9f98f8..1dab9acb9c 100644 --- a/phpBB/styles/subsilver2/template/ucp_profile_autologin_keys.html +++ b/phpBB/styles/subsilver2/template/ucp_profile_autologin_keys.html @@ -32,15 +32,14 @@ - {L_PROFILE_NO_AUTOLOGIN_KEYS} + {L_PROFILE_NO_AUTOLOGIN_KEYS} - {S_HIDDEN_FIELDS}  - + {S_HIDDEN_FIELDS} {S_FORM_TOKEN} From 70be7e109f067d6f6d1add488338294dd59c7785 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Fri, 18 May 2012 11:15:53 +0200 Subject: [PATCH 213/441] [ticket/10898] Do not write ?> into config.php to avoid whitespace output. PHPBB3-10898 --- phpBB/includes/functions_install.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/phpBB/includes/functions_install.php b/phpBB/includes/functions_install.php index 633b2755f0..9e9c48ff58 100644 --- a/phpBB/includes/functions_install.php +++ b/phpBB/includes/functions_install.php @@ -559,8 +559,6 @@ function phpbb_create_config_file_data($data, $dbms, $load_extensions, $debug = $config_data .= "// @define('DEBUG_EXTRA', true);\n"; } - $config_data .= '?' . '>'; // Done this to prevent highlighting editors getting confused! - return $config_data; } From e2d286d9f133ffb5128262fc88bfd86766f7b50f Mon Sep 17 00:00:00 2001 From: Rahul R Date: Sat, 19 May 2012 01:59:25 +0530 Subject: [PATCH 214/441] [ticket/10650] Subject is cleared if no permissions exist The subject line will be cleared before passing to the template in case the user doesn't have sufficient permissions. PHPBB3-10650 --- phpBB/includes/functions_display.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/phpBB/includes/functions_display.php b/phpBB/includes/functions_display.php index 950c1f0cd8..0c5b80c609 100644 --- a/phpBB/includes/functions_display.php +++ b/phpBB/includes/functions_display.php @@ -465,8 +465,8 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod 'FORUM_FOLDER_IMG_ALT' => isset($user->lang[$folder_alt]) ? $user->lang[$folder_alt] : '', 'FORUM_IMAGE' => ($row['forum_image']) ? '' . $user->lang[$folder_alt] . '' : '', 'FORUM_IMAGE_SRC' => ($row['forum_image']) ? $phpbb_root_path . $row['forum_image'] : '', - 'LAST_POST_SUBJECT' => censor_text($last_post_subject), - 'LAST_POST_SUBJECT_TRUNCATED' => $last_post_subject_truncated, + 'LAST_POST_SUBJECT' => (!$row['forum_password'] && $auth->acl_get('f_read', $row['forum_id'])) ? censor_text($last_post_subject) : "", + 'LAST_POST_SUBJECT_TRUNCATED' => (!$row['forum_password'] && $auth->acl_get('f_read', $row['forum_id'])) ? $last_post_subject_truncated : "", 'LAST_POST_TIME' => $last_post_time, 'LAST_POSTER' => get_username_string('username', $row['forum_last_poster_id'], $row['forum_last_poster_name'], $row['forum_last_poster_colour']), 'LAST_POSTER_COLOUR' => get_username_string('colour', $row['forum_last_poster_id'], $row['forum_last_poster_name'], $row['forum_last_poster_colour']), From 7ec6254078e28e94410adb51cd95d5ea687ae39d Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Tue, 22 May 2012 01:25:19 +0200 Subject: [PATCH 215/441] [ticket/10890] Fix test_sql_fetchrow_returns_false_when_empty() on MS and ORA. Fix phpbb_dbal_select_test::test_sql_fetchrow_returns_false_when_empty() on MSSQL and Oracle by specifying an existing table in the query. PHPBB3-10890 --- tests/dbal/select_test.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/dbal/select_test.php b/tests/dbal/select_test.php index 1b04450fcd..81cd13b006 100644 --- a/tests/dbal/select_test.php +++ b/tests/dbal/select_test.php @@ -375,7 +375,9 @@ class phpbb_dbal_select_test extends phpbb_database_test_case { $db = $this->new_dbal(); - $sql = 'SELECT * FROM (SELECT 1) AS TBL WHERE 1 = 0'; + $sql = 'SELECT user_id + FROM phpbb_users + WHERE 1 = 0'; $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); From ee875c0a43ac734d1693cdd7393c8f4277233426 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Tue, 22 May 2012 02:24:31 +0200 Subject: [PATCH 216/441] [ticket/10790] Remove a (kind of) dead code section from submit_pm(). The type of $user->data['user_id'] is (almost) guranteed to be integer since session::session_create() casts it to integer. The type of $row['user_id'] is only an integer if the DB driver adjusts the PHP type according to the DB type. This is only done by some of our not-so-popular DB drivers and is not the case for MySQL. As such this comparison is (almost) never true and a PM is also sent to the author itself when it is sent to a group the author is also a member of. Since this behaviour seems to have been accepted by the communty, the dead code is removed and current behaviour is kept. Also, checking this in the loop seems to be a rather bad idea. Introduced by 78b1c4caaa17cc8760b685ad41c19f15f9d89b68. PHPBB3-10790 --- phpBB/includes/functions_privmsgs.php | 6 ------ 1 file changed, 6 deletions(-) diff --git a/phpBB/includes/functions_privmsgs.php b/phpBB/includes/functions_privmsgs.php index d2fce000aa..261ed45727 100644 --- a/phpBB/includes/functions_privmsgs.php +++ b/phpBB/includes/functions_privmsgs.php @@ -1522,12 +1522,6 @@ function submit_pm($mode, $subject, &$data, $put_in_outbox = true) while ($row = $db->sql_fetchrow($result)) { - // Additionally, do not include the sender if he is in the group he wants to send to. ;) - if ($row['user_id'] === $user->data['user_id']) - { - continue; - } - $field = ($data['address_list']['g'][$row['group_id']] == 'to') ? 'to' : 'bcc'; $recipients[$row['user_id']] = $field; } From efbf14f029b7e6a1724fb1c5aa32294eb33017bc Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Tue, 22 May 2012 03:08:39 +0200 Subject: [PATCH 217/441] [ticket/10565] update_forum_tracking_info(): Remove unnecessary GROUP BY clause PHPBB3-10565 --- phpBB/includes/functions.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index ce80dc4a66..b415b2742d 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -1924,8 +1924,7 @@ function update_forum_tracking_info($forum_id, $forum_last_post_time, $f_mark_ti AND t.topic_last_post_time > ' . $mark_time_forum . ' AND t.topic_moved_id = 0 ' . $sql_update_unapproved . ' - AND (tt.topic_id IS NULL OR tt.mark_time < t.topic_last_post_time) - GROUP BY t.forum_id'; + AND (tt.topic_id IS NULL OR tt.mark_time < t.topic_last_post_time)'; $result = $db->sql_query_limit($sql, 1); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); From 896b43aa5b7fe439106beb50cf56d6f066928537 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Tue, 22 May 2012 03:11:53 +0200 Subject: [PATCH 218/441] [ticket/10565] Add line breaks to query in order to follow coding guidelines. PHPBB3-10565 --- phpBB/includes/functions.php | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index b415b2742d..bc811cc75b 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -1918,13 +1918,17 @@ function update_forum_tracking_info($forum_id, $forum_last_post_time, $f_mark_ti } else { - $sql = 'SELECT t.forum_id FROM ' . TOPICS_TABLE . ' t - LEFT JOIN ' . TOPICS_TRACK_TABLE . ' tt ON (tt.topic_id = t.topic_id AND tt.user_id = ' . $user->data['user_id'] . ') + $sql = 'SELECT t.forum_id + FROM ' . TOPICS_TABLE . ' t + LEFT JOIN ' . TOPICS_TRACK_TABLE . ' tt + ON (tt.topic_id = t.topic_id + AND tt.user_id = ' . $user->data['user_id'] . ') WHERE t.forum_id = ' . $forum_id . ' AND t.topic_last_post_time > ' . $mark_time_forum . ' AND t.topic_moved_id = 0 ' . $sql_update_unapproved . ' - AND (tt.topic_id IS NULL OR tt.mark_time < t.topic_last_post_time)'; + AND (tt.topic_id IS NULL + OR tt.mark_time < t.topic_last_post_time)'; $result = $db->sql_query_limit($sql, 1); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); From ea1e2ed36280b8e3a4078885a07f7d3398ce5703 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Tue, 22 May 2012 03:32:54 +0200 Subject: [PATCH 219/441] [ticket/10401] Return correct type when ldap_bind() fails in ldap_login(). ldap_login() is supposed to return an array. PHPBB3-10401 --- phpBB/includes/auth/auth_ldap.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/phpBB/includes/auth/auth_ldap.php b/phpBB/includes/auth/auth_ldap.php index 5dfa74ddab..eebf147d48 100644 --- a/phpBB/includes/auth/auth_ldap.php +++ b/phpBB/includes/auth/auth_ldap.php @@ -156,7 +156,11 @@ function login_ldap(&$username, &$password) { if (!@ldap_bind($ldap, htmlspecialchars_decode($config['ldap_user']), htmlspecialchars_decode($config['ldap_password']))) { - return $user->lang['LDAP_NO_SERVER_CONNECTION']; + return array( + 'status' => LOGIN_ERROR_EXTERNAL_AUTH, + 'error_msg' => 'LDAP_NO_SERVER_CONNECTION', + 'user_row' => array('user_id' => ANONYMOUS), + ); } } From 9fa7ab62ad45abf3a5035cc792748893d6cd8a4d Mon Sep 17 00:00:00 2001 From: Oleg Pudeyev Date: Mon, 21 May 2012 23:02:12 -0400 Subject: [PATCH 220/441] [ticket/10828] Connect to postgres database by default. When not connecting to a specific database, connect to postgres database which specifically exists as a default database to connect to. PHPBB3-10828 --- .../phpbb_database_test_connection_manager.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/test_framework/phpbb_database_test_connection_manager.php b/tests/test_framework/phpbb_database_test_connection_manager.php index c734c90a1a..ae21be6c34 100644 --- a/tests/test_framework/phpbb_database_test_connection_manager.php +++ b/tests/test_framework/phpbb_database_test_connection_manager.php @@ -80,6 +80,21 @@ class phpbb_database_test_connection_manager { $dsn .= ';dbname=' . $this->config['dbname']; } + else if ($this->dbms['PDO'] == 'pgsql') + { + // Postgres always connects to a + // database. If the database is not + // specified here, but the username + // is specified, then connection + // will be to the database named + // as the username. + // + // For greater compatibility, connect + // instead to postgres database which + // should always exist: + // http://www.postgresql.org/docs/9.0/static/manage-ag-templatedbs.html + $dsn .= ';dbname=postgres'; + } break; } From ffabfefe459c8fd94bf0706766134dd821d294a7 Mon Sep 17 00:00:00 2001 From: David King Date: Tue, 22 May 2012 10:14:20 -0400 Subject: [PATCH 221/441] [ticket/10906] Add setting for last post topic title in schema_data.sql PHPBB3-10906 --- phpBB/install/schemas/schema_data.sql | 1 + 1 file changed, 1 insertion(+) diff --git a/phpBB/install/schemas/schema_data.sql b/phpBB/install/schemas/schema_data.sql index 2ea5eca768..5489fd4e3d 100644 --- a/phpBB/install/schemas/schema_data.sql +++ b/phpBB/install/schemas/schema_data.sql @@ -88,6 +88,7 @@ INSERT INTO phpbb_config (config_name, config_value) VALUES ('dbms_version', '') INSERT INTO phpbb_config (config_name, config_value) VALUES ('default_dateformat', 'D M d, Y g:i a'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('default_style', '1'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('display_last_edited', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('display_last_subject', '1'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('display_order', '0'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('edit_time', '0'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('delete_time', '0'); From b96c05069569dd1db48a5bffa15c2fcd69369e6b Mon Sep 17 00:00:00 2001 From: David King Date: Tue, 22 May 2012 10:46:36 -0400 Subject: [PATCH 222/441] [task/functional] Change property visibility, remove globals, reword comment PHPBB3-10758 --- tests/test_framework/phpbb_functional_test_case.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/test_framework/phpbb_functional_test_case.php b/tests/test_framework/phpbb_functional_test_case.php index 177f93cf3b..59579c1c33 100644 --- a/tests/test_framework/phpbb_functional_test_case.php +++ b/tests/test_framework/phpbb_functional_test_case.php @@ -14,14 +14,16 @@ class phpbb_functional_test_case extends phpbb_test_case { protected $client; protected $root_url; + /** * @var string Session ID for current test's session (each test makes its own) */ protected $sid; + /** * @var array Language array used by phpBB */ - private $lang = array(); + protected $lang = array(); static protected $config = array(); static protected $already_installed = false; @@ -187,8 +189,8 @@ class phpbb_functional_test_case extends phpbb_test_case $login = $this->client->submit($form, array('username' => 'admin', 'password' => 'admin')); $cookies = $this->cookieJar->all(); - $sid = ''; - // get the SID from the cookie + + // The session id is stored in a cookie that ends with _sid - we assume there is only one such cookie foreach ($cookies as $key => $cookie); { if (substr($key, -4) == '_sid') @@ -200,8 +202,6 @@ class phpbb_functional_test_case extends phpbb_test_case protected function add_lang($lang_file) { - global $phpbb_root_path, $phpEx; - if (is_array($lang_file)) { foreach ($lang_file as $file) @@ -210,7 +210,7 @@ class phpbb_functional_test_case extends phpbb_test_case } } - $lang_path = "{$phpbb_root_path}language/en/$lang_file.$phpEx"; + $lang_path = "./phpBB/language/en/$lang_file.php"; $lang = array(); From 819accedc87921a6fd1788fa2164d023f6d97f98 Mon Sep 17 00:00:00 2001 From: David King Date: Tue, 22 May 2012 10:52:49 -0400 Subject: [PATCH 223/441] [task/functional] Fix $lang_path variable PHPBB3-10758 --- tests/test_framework/phpbb_functional_test_case.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_framework/phpbb_functional_test_case.php b/tests/test_framework/phpbb_functional_test_case.php index 59579c1c33..1bcc3928df 100644 --- a/tests/test_framework/phpbb_functional_test_case.php +++ b/tests/test_framework/phpbb_functional_test_case.php @@ -210,7 +210,7 @@ class phpbb_functional_test_case extends phpbb_test_case } } - $lang_path = "./phpBB/language/en/$lang_file.php"; + $lang_path = __DIR__ . "/../../phpBB/language/en/$lang_file.php"; $lang = array(); From 09d15db1fabe22fc241d80c528fbd95e0d9fa122 Mon Sep 17 00:00:00 2001 From: David King Date: Tue, 22 May 2012 12:06:27 -0300 Subject: [PATCH 224/441] [task/functional] Use proper format for @var doc blocks. PHPBB3-10758 --- tests/test_framework/phpbb_functional_test_case.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/test_framework/phpbb_functional_test_case.php b/tests/test_framework/phpbb_functional_test_case.php index 1bcc3928df..76fed76fae 100644 --- a/tests/test_framework/phpbb_functional_test_case.php +++ b/tests/test_framework/phpbb_functional_test_case.php @@ -16,12 +16,14 @@ class phpbb_functional_test_case extends phpbb_test_case protected $root_url; /** - * @var string Session ID for current test's session (each test makes its own) + * Session ID for current test's session (each test makes its own) + * @var string */ protected $sid; /** - * @var array Language array used by phpBB + * Language array used by phpBB + * @var array */ protected $lang = array(); From bad91d8e74eea420d9ea7d9a0ac0ecf47d23fdb7 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Tue, 22 May 2012 18:41:15 +0200 Subject: [PATCH 225/441] [ticket/10907] Mark (var)binary tests as incomplete on non-MySQL DBMSes. PHPBB3-10907 --- tests/dbal/db_tools_test.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/dbal/db_tools_test.php b/tests/dbal/db_tools_test.php index 9bed0648cd..c20e46011f 100644 --- a/tests/dbal/db_tools_test.php +++ b/tests/dbal/db_tools_test.php @@ -165,6 +165,11 @@ class phpbb_dbal_db_tools_test extends phpbb_database_test_case */ public function test_created_column($column_name, $column_value) { + if ($column_name === 'c_varbinary' && stripos(get_class($this->db), 'mysql') === false) + { + $this->markTestIncomplete('Binary handling is not implemented properly on non-MySQL DBMSes.'); + } + $row_insert = self::get_default_values(); $row_insert[$column_name] = $column_value; From a32a5925b357f78eb8735c0aaf1595935305c126 Mon Sep 17 00:00:00 2001 From: Vinny Date: Tue, 22 May 2012 15:34:39 -0300 Subject: [PATCH 226/441] [ticket/10905] Last topic title for subsilver2 PHPBB3-10905 --- phpBB/styles/subsilver2/template/forumlist_body.html | 3 +++ 1 file changed, 3 insertions(+) diff --git a/phpBB/styles/subsilver2/template/forumlist_body.html b/phpBB/styles/subsilver2/template/forumlist_body.html index 334fd7a968..be32d1fb77 100644 --- a/phpBB/styles/subsilver2/template/forumlist_body.html +++ b/phpBB/styles/subsilver2/template/forumlist_body.html @@ -56,6 +56,9 @@

    {forumrow.POSTS}

    + +

    {forumrow.LAST_POST_SUBJECT_TRUNCATED}

    +

    {UNAPPROVED_IMG} {forumrow.LAST_POST_TIME}

    {forumrow.LAST_POSTER_FULL} {LAST_POST_IMG} From 22cc7c73fdb26420bdf5b7a509da9a22925e274a Mon Sep 17 00:00:00 2001 From: Callum Macrae Date: Tue, 22 May 2012 19:38:30 +0100 Subject: [PATCH 227/441] [ticket/10855] Fixed a couple issues in coding guidelines. PHPBB3-10855 --- phpBB/docs/coding-guidelines.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/phpBB/docs/coding-guidelines.html b/phpBB/docs/coding-guidelines.html index 237bc18d20..ae4655e094 100644 --- a/phpBB/docs/coding-guidelines.html +++ b/phpBB/docs/coding-guidelines.html @@ -301,7 +301,7 @@ PHPBB_QA (Set board to QA-Mode, which means the updater also c

    $current_user is right, but $currentuser and $currentUser are not.

    -

    In JavaScript, variable names should use camel caps:

    +

    In JavaScript, variable names should use camel case:

    currentUser is right, but currentuser and current_user are not.

    @@ -532,7 +532,7 @@ $post_url = "{$phpbb_root_path}posting.$phpEx?mode=$mode&amp;start=$start";

    In SQL statements mixing single and double quotes is partly allowed (following the guidelines listed here about SQL formatting), else one should try to only use one method - mostly single quotes.

    Commas after every array element:

    -

    If an array is defined with each element on its own line, you still have to modify the previous line to add a comma when appending a new element. PHP allows for trailing (useless) commas in array definitions. These should always be used so each element including the comma can be appended with a single line. In JavaScript, you should not use the trailing comma, as IE doesn't like it.

    +

    If an array is defined with each element on its own line, you still have to modify the previous line to add a comma when appending a new element. PHP allows for trailing (useless) commas in array definitions. These should always be used so each element including the comma can be appended with a single line. In JavaScript, do not use the trailing comma, as it causes browsers to throw errors.

    // wrong

    
    From af3a730d9193307d908c3bd14329761cf2bbc098 Mon Sep 17 00:00:00 2001
    From: Vinny 
    Date: Wed, 11 Apr 2012 17:15:39 -0300
    Subject: [PATCH 228/441] [ticket/10789] Remove unnecessary variables from PM
     print - prosilver
    
    PHPBB3-10789
    ---
     .../styles/prosilver/template/ucp_pm_viewmessage_print.html  | 5 ++---
     1 file changed, 2 insertions(+), 3 deletions(-)
    
    diff --git a/phpBB/styles/prosilver/template/ucp_pm_viewmessage_print.html b/phpBB/styles/prosilver/template/ucp_pm_viewmessage_print.html
    index ce2a376768..d92abb06dd 100644
    --- a/phpBB/styles/prosilver/template/ucp_pm_viewmessage_print.html
    +++ b/phpBB/styles/prosilver/template/ucp_pm_viewmessage_print.html
    @@ -23,10 +23,9 @@
     
     	
     
     	
    From c31996ea84fff5038328974b511c95d95fcd3fe7 Mon Sep 17 00:00:00 2001 From: David King Date: Sat, 26 May 2012 21:21:22 -0400 Subject: [PATCH 229/441] [ticket/10912] Default last post subject to empty lacking last post info PHPBB3-10912 --- phpBB/includes/functions_display.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/includes/functions_display.php b/phpBB/includes/functions_display.php index 0c5b80c609..1f45d5e8e1 100644 --- a/phpBB/includes/functions_display.php +++ b/phpBB/includes/functions_display.php @@ -403,7 +403,7 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod } else { - $last_post_subject = $last_post_time = $last_post_url = ''; + $last_post_subject = $last_post_time = $last_post_url = $last_post_subject_truncated = ''; } // Output moderator listing ... if applicable From 8cb9004ab3ba01e0833ae25418691f8f69bf0172 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Sun, 27 May 2012 12:30:12 +0200 Subject: [PATCH 230/441] [ticket/10909] Also test develop-olympus with low PHP 5.3 version on travis. Also test develop-olympus with low PHP 5.3 version (i.e. PHP 5.3.3) on travis. PHPBB3-10909 --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index d73bbd2a48..6a1ecedac4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,7 @@ language: php php: - 5.2 + - 5.3.3 - 5.3 - 5.4 From 13f30e8d9d05b69f8b7fda451fa6062b199dd7f7 Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Tue, 29 May 2012 14:27:25 +0200 Subject: [PATCH 231/441] [ticket/10908] Download files only up to max_upload_filesize if limit is 0 PHPBB3-10908 --- phpBB/includes/functions_upload.php | 33 +++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/phpBB/includes/functions_upload.php b/phpBB/includes/functions_upload.php index d5bbd80242..73ac1df2d2 100644 --- a/phpBB/includes/functions_upload.php +++ b/phpBB/includes/functions_upload.php @@ -751,6 +751,31 @@ class fileupload $filename = $url['path']; $filesize = 0; + $remote_max_filesize = $this->max_filesize; + if (!$remote_max_filesize) + { + $max_filesize = @ini_get('upload_max_filesize'); + + if (!empty($max_filesize)) + { + $unit = strtolower(substr($max_filesize, -1, 1)); + $remote_max_filesize = (int) $max_filesize; + + switch ($unit) + { + case 'g': + $remote_max_filesize *= 1024; + // no break + case 'm': + $remote_max_filesize *= 1024; + // no break + case 'k': + $remote_max_filesize *= 1024; + // no break + } + } + } + $errno = 0; $errstr = ''; @@ -779,9 +804,9 @@ class fileupload $block = @fread($fsock, 1024); $filesize += strlen($block); - if ($this->max_filesize && $filesize > $this->max_filesize) + if ($remote_max_filesize && $filesize > $remote_max_filesize) { - $max_filesize = get_formatted_filesize($this->max_filesize, false); + $max_filesize = get_formatted_filesize($remote_max_filesize, false); $file = new fileerror(sprintf($user->lang[$this->error_prefix . 'WRONG_FILESIZE'], $max_filesize['value'], $max_filesize['unit'])); return $file; @@ -807,9 +832,9 @@ class fileupload { $length = (int) str_replace('content-length: ', '', strtolower($line)); - if ($length && $length > $this->max_filesize) + if ($remote_max_filesize && $length && $length > $remote_max_filesize) { - $max_filesize = get_formatted_filesize($this->max_filesize, false); + $max_filesize = get_formatted_filesize($remote_max_filesize, false); $file = new fileerror(sprintf($user->lang[$this->error_prefix . 'WRONG_FILESIZE'], $max_filesize['value'], $max_filesize['unit'])); return $file; From 42dd60edad6c3533f6b718e731d43661641fd1fc Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Tue, 29 May 2012 14:54:04 +0200 Subject: [PATCH 232/441] [ticket/10913] Redirect to index if session id is required but was not sent PHPBB3-10913 --- phpBB/includes/session.php | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/phpBB/includes/session.php b/phpBB/includes/session.php index a894242a39..496c12a0d1 100644 --- a/phpBB/includes/session.php +++ b/phpBB/includes/session.php @@ -322,8 +322,15 @@ class session } } - // Is session_id is set or session_id is set and matches the url param if required - if (!empty($this->session_id) && (!defined('NEED_SID') || (isset($_GET['sid']) && $this->session_id === $_GET['sid']))) + // if no session id is set, redirect to index.php + if (defined('NEED_SID') && (!isset($_GET['sid']) || $this->session_id !== $_GET['sid'])) + { + send_status_line(401, 'Not authorized'); + redirect(append_sid("{$phpbb_root_path}index.$phpEx")); + } + + // if session id is set + if (!empty($this->session_id)) { $sql = 'SELECT u.*, s.* FROM ' . SESSIONS_TABLE . ' s, ' . USERS_TABLE . " u From 701bf571dfffa171271d567759cf92c3830d159c Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Tue, 29 May 2012 15:29:31 +0200 Subject: [PATCH 233/441] [ticket/10550] Sort not installed styles list in the styles section of the ACP. PHPBB3-10550 --- phpBB/includes/acp/acp_styles.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/phpBB/includes/acp/acp_styles.php b/phpBB/includes/acp/acp_styles.php index d7b0484af8..47cd02bca7 100644 --- a/phpBB/includes/acp/acp_styles.php +++ b/phpBB/includes/acp/acp_styles.php @@ -667,7 +667,9 @@ inherit_from = {INHERIT_FROM} if ($name && !in_array($name, $installed)) { - $new_ary[] = array( + // The array key is used for sorting later on. + // $file is appended because $name doesn't have to be unique. + $new_ary[$name . $file] = array( 'path' => $file, 'name' => $name, 'copyright' => $items['copyright'], @@ -683,6 +685,8 @@ inherit_from = {INHERIT_FROM} if (sizeof($new_ary)) { + ksort($new_ary); + foreach ($new_ary as $cfg) { $template->assign_block_vars('uninstalled', array( From c494abc8c765f2398b0b782fc6979a5e033bb0f5 Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Tue, 29 May 2012 15:49:52 +0200 Subject: [PATCH 234/441] [ticket/10908] Document that 0 filesize configuration means limited by PHP PHPBB3-10908 --- phpBB/language/en/acp/attachments.php | 2 +- phpBB/language/en/acp/board.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/phpBB/language/en/acp/attachments.php b/phpBB/language/en/acp/attachments.php index 1821b8c867..6aeb3c2188 100644 --- a/phpBB/language/en/acp/attachments.php +++ b/phpBB/language/en/acp/attachments.php @@ -57,7 +57,7 @@ $lang = array_merge($lang, array( 'ATTACH_EXT_GROUPS_URL' => 'Extension groups', 'ATTACH_ID' => 'ID', 'ATTACH_MAX_FILESIZE' => 'Maximum file size', - 'ATTACH_MAX_FILESIZE_EXPLAIN' => 'Maximum size of each file, with 0 being unlimited.', + 'ATTACH_MAX_FILESIZE_EXPLAIN' => 'Maximum size of each file. If this value is 0, the uploadable filesize is only limited by your PHP configuration.', 'ATTACH_MAX_PM_FILESIZE' => 'Maximum file size messaging', 'ATTACH_MAX_PM_FILESIZE_EXPLAIN' => 'Maximum size of each file, with 0 being unlimited, attached to a private message.', 'ATTACH_ORPHAN_URL' => 'Orphan attachments', diff --git a/phpBB/language/en/acp/board.php b/phpBB/language/en/acp/board.php index 6e6d4302cd..f24376f8aa 100644 --- a/phpBB/language/en/acp/board.php +++ b/phpBB/language/en/acp/board.php @@ -108,7 +108,7 @@ $lang = array_merge($lang, array( 'MAX_AVATAR_SIZE' => 'Maximum avatar dimensions', 'MAX_AVATAR_SIZE_EXPLAIN' => 'Width x Height in pixels.', 'MAX_FILESIZE' => 'Maximum avatar file size', - 'MAX_FILESIZE_EXPLAIN' => 'For uploaded avatar files.', + 'MAX_FILESIZE_EXPLAIN' => 'For uploaded avatar files. If this value is 0, the uploaded filesize is only limited by your PHP configuration.', 'MIN_AVATAR_SIZE' => 'Minimum avatar dimensions', 'MIN_AVATAR_SIZE_EXPLAIN' => 'Width x Height in pixels.', )); From 6036b948ff8ff02f890d46000aafea5dd157d025 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Wed, 30 May 2012 13:38:41 +0200 Subject: [PATCH 235/441] [ticket/10611] Generate db_tools instance in acp_database module. PHPBB3-10611 --- phpBB/includes/acp/acp_database.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/phpBB/includes/acp/acp_database.php b/phpBB/includes/acp/acp_database.php index 62bcd43a47..6380f221f8 100644 --- a/phpBB/includes/acp/acp_database.php +++ b/phpBB/includes/acp/acp_database.php @@ -21,6 +21,7 @@ if (!defined('IN_PHPBB')) */ class acp_database { + var $db_tools; var $u_action; function main($id, $mode) @@ -28,6 +29,12 @@ class acp_database global $cache, $db, $user, $auth, $template, $table_prefix; global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx; + if (!class_exists('phpbb_db_tools')) + { + require($phpbb_root_path . 'includes/db/db_tools.' . $phpEx); + } + $this->db_tools = new phpbb_db_tools($db); + $user->add_lang('acp/database'); $this->tpl_name = 'acp_database'; From 515c27270fe04b5e2f69a0cedc5007ef889fdf77 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Wed, 30 May 2012 13:41:36 +0200 Subject: [PATCH 236/441] [ticket/10611] Use phpbb_db_tools::sql_list_tables() instead of get_tables(). get_tables() was deprecated by phpbb_db_tools::sql_list_tables() This prevents unnecessarily loading functions_install.php PHPBB3-10611 --- phpBB/includes/acp/acp_database.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/phpBB/includes/acp/acp_database.php b/phpBB/includes/acp/acp_database.php index 6380f221f8..885760f859 100644 --- a/phpBB/includes/acp/acp_database.php +++ b/phpBB/includes/acp/acp_database.php @@ -180,8 +180,7 @@ class acp_database break; default: - include($phpbb_root_path . 'includes/functions_install.' . $phpEx); - $tables = get_tables($db); + $tables = $this->db_tools->sql_list_tables(); asort($tables); foreach ($tables as $table_name) { From 9240ddbfa7cc4deb2076dcb989e6bfb318652e47 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Wed, 30 May 2012 13:45:00 +0200 Subject: [PATCH 237/441] [ticket/10611] Filter out not existing database tables when making a backup. Using $this->db_tools->sql_list_tables() as the first argument gives us table names as array keys as a by-product which might be useful at some point. PHPBB3-10611 --- phpBB/includes/acp/acp_database.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/includes/acp/acp_database.php b/phpBB/includes/acp/acp_database.php index 885760f859..758cd10434 100644 --- a/phpBB/includes/acp/acp_database.php +++ b/phpBB/includes/acp/acp_database.php @@ -57,7 +57,7 @@ class acp_database { case 'download': $type = request_var('type', ''); - $table = request_var('table', array('')); + $table = array_intersect($this->db_tools->sql_list_tables(), request_var('table', array(''))); $format = request_var('method', ''); $where = request_var('where', ''); From de4dff8bb077e98e203e0e83bd52630053970ee0 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Wed, 30 May 2012 21:01:25 +0200 Subject: [PATCH 238/441] [ticket/10162] Add test cases for top level domain names longer than 6 chars. PHPBB3-10162 --- tests/regex/email_test.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/regex/email_test.php b/tests/regex/email_test.php index 17f93259c3..b4ea5b23aa 100644 --- a/tests/regex/email_test.php +++ b/tests/regex/email_test.php @@ -28,6 +28,8 @@ class phpbb_regex_email_test extends phpbb_test_case array('alice_foo@bar.phpbb.com'), array('alice+tag@foo.phpbb.com'), array('alice&tag@foo.phpbb.com'), + array('alice@phpbb.australia'), + array('alice@phpbb.topZlevelZdomainZnamesZcanZbeZupZtoZsixtyZthreeZcharactersZlong'), //array('"John Doe"@example.com'), //array('Alice@[192.168.2.1]'), // IPv4 @@ -96,6 +98,7 @@ class phpbb_regex_email_test extends phpbb_test_case array('! "#$%(),/;<>[]`|@invalidCharsInLocal.org'), array('invalidCharsInDomain@! "#$%(),/;<>_[]`|.org'), array('local@SecondLevelDomainNamesAreInvalidIfTheyAreLongerThan64Charactersss.org'), + array('alice@phpbb.topZlevelZdomainZnamesZcanZbeZupZtoZsixtyZthreeZcharactersZlongZ'), ); } From 037b95eccc1f039e687360d9f804f7323a65e9df Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Wed, 30 May 2012 21:09:30 +0200 Subject: [PATCH 239/441] [ticket/10162] Increase maximum length of email address TLD from 6 to 63. Increase maximum length of email address top level domains from 6 to 63. PHPBB3-10162 --- phpBB/includes/functions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index bc811cc75b..5914831539 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -3456,7 +3456,7 @@ function get_preg_expression($mode) case 'email': // Regex written by James Watts and Francisco Jose Martin Moreno // http://fightingforalostcause.net/misc/2006/compare-email-regex.php - return '([\w\!\#$\%\&\'\*\+\-\/\=\?\^\`{\|\}\~]+\.)*(?:[\w\!\#$\%\'\*\+\-\/\=\?\^\`{\|\}\~]|&)+@((((([a-z0-9]{1}[a-z0-9\-]{0,62}[a-z0-9]{1})|[a-z])\.)+[a-z]{2,6})|(\d{1,3}\.){3}\d{1,3}(\:\d{1,5})?)'; + return '([\w\!\#$\%\&\'\*\+\-\/\=\?\^\`{\|\}\~]+\.)*(?:[\w\!\#$\%\'\*\+\-\/\=\?\^\`{\|\}\~]|&)+@((((([a-z0-9]{1}[a-z0-9\-]{0,62}[a-z0-9]{1})|[a-z])\.)+[a-z]{2,63})|(\d{1,3}\.){3}\d{1,3}(\:\d{1,5})?)'; break; case 'bbcode_htm': From 643a86504a30f6b9fbe0f073bb03009b4fbd0f43 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Thu, 31 May 2012 11:44:41 +0200 Subject: [PATCH 240/441] [ticket/10751] Add sql_lower_text() to database abstraction layer. On MSSQL, LOWER() can only be called on bounded strings (i.e. varchar or char). So, in order to use it on a text column, we have to convert it to an appropriate type. We do so using the SUBSTRING function. PHPBB3-10751 --- phpBB/includes/db/dbal.php | 12 ++++++++++++ phpBB/includes/db/mssql.php | 8 ++++++++ phpBB/includes/db/mssql_odbc.php | 8 ++++++++ phpBB/includes/db/mssqlnative.php | 8 ++++++++ 4 files changed, 36 insertions(+) diff --git a/phpBB/includes/db/dbal.php b/phpBB/includes/db/dbal.php index 358df50402..9cc337955b 100644 --- a/phpBB/includes/db/dbal.php +++ b/phpBB/includes/db/dbal.php @@ -500,6 +500,18 @@ class dbal return $column_name . ' | ' . (1 << $bit) . (($compare) ? ' ' . $compare : ''); } + /** + * Run LOWER() on DB column of type text (i.e. neither varchar nor char). + * + * @param string $column_name The column name to use + * + * @return string A SQL statement like "LOWER($column_name)" + */ + function sql_lower_text($column_name) + { + return "LOWER($column_name)"; + } + /** * Run more than one insert statement. * diff --git a/phpBB/includes/db/mssql.php b/phpBB/includes/db/mssql.php index 6899a73902..b7178593dc 100644 --- a/phpBB/includes/db/mssql.php +++ b/phpBB/includes/db/mssql.php @@ -332,6 +332,14 @@ class dbal_mssql extends dbal return str_replace(array("'", "\0"), array("''", ''), $msg); } + /** + * {@inheritDoc} + */ + function sql_lower_text($column_name) + { + return "LOWER(SUBSTRING($column_name, 1, DATALENGTH($column_name)))"; + } + /** * Build LIKE expression * @access private diff --git a/phpBB/includes/db/mssql_odbc.php b/phpBB/includes/db/mssql_odbc.php index 34f7a87337..2ecc42cadf 100644 --- a/phpBB/includes/db/mssql_odbc.php +++ b/phpBB/includes/db/mssql_odbc.php @@ -310,6 +310,14 @@ class dbal_mssql_odbc extends dbal return str_replace(array("'", "\0"), array("''", ''), $msg); } + /** + * {@inheritDoc} + */ + function sql_lower_text($column_name) + { + return "LOWER(SUBSTRING($column_name, 1, DATALENGTH($column_name)))"; + } + /** * Build LIKE expression * @access private diff --git a/phpBB/includes/db/mssqlnative.php b/phpBB/includes/db/mssqlnative.php index 92ac9b1fb9..c91cc188b0 100644 --- a/phpBB/includes/db/mssqlnative.php +++ b/phpBB/includes/db/mssqlnative.php @@ -492,6 +492,14 @@ class dbal_mssqlnative extends dbal return str_replace(array("'", "\0"), array("''", ''), $msg); } + /** + * {@inheritDoc} + */ + function sql_lower_text($column_name) + { + return "LOWER(SUBSTRING($column_name, 1, DATALENGTH($column_name)))"; + } + /** * Build LIKE expression * @access private From 9ab5ad2986a836554bbf137d577c38155540c0a8 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Thu, 31 May 2012 11:48:56 +0200 Subject: [PATCH 241/441] [ticket/10751] Use sql_lower_text() in view_log(). log_data is a text column. PHPBB3-10751 --- phpBB/includes/functions_admin.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/phpBB/includes/functions_admin.php b/phpBB/includes/functions_admin.php index 0e1a11b4aa..204fa9a43d 100644 --- a/phpBB/includes/functions_admin.php +++ b/phpBB/includes/functions_admin.php @@ -2557,7 +2557,8 @@ function view_log($mode, &$log, &$log_count, $limit = 0, $offset = 0, $forum_id { $sql_keywords .= $db->sql_in_set('l.log_operation', $operations) . ' OR '; } - $sql_keywords .= 'LOWER(l.log_data) ' . implode(' OR LOWER(l.log_data) ', $keywords) . ')'; + $sql_lower = $db->sql_lower_text('l.log_data'); + $sql_keywords .= "$sql_lower " . implode(" OR $sql_lower ", $keywords) . ')'; } if ($log_count !== false) From d22e7ce9df7d54591430fb542f2c2e14535c18cc Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Thu, 31 May 2012 19:57:13 +0200 Subject: [PATCH 242/441] [ticket/10788] Add Arty to the list of phpBB developers in docs/AUTHORS. PHPBB3-10788 --- phpBB/docs/AUTHORS | 1 + 1 file changed, 1 insertion(+) diff --git a/phpBB/docs/AUTHORS b/phpBB/docs/AUTHORS index 57adec6a67..446b204a08 100644 --- a/phpBB/docs/AUTHORS +++ b/phpBB/docs/AUTHORS @@ -23,6 +23,7 @@ involved in phpBB. phpBB Lead Developer: naderman (Nils Adermann) phpBB Developers: Acyd Burn (Meik Sievertsen) [Lead 09/2005 - 01/2010] + Arty (Vjacheslav Trushkin) bantu (Andreas Fischer) imkingdavid (David King) igorw (Igor Wiedler) From d8ddda512180be56100a890410dece8046aade28 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Thu, 31 May 2012 20:19:28 +0200 Subject: [PATCH 243/441] [develop-olympus] Bumping version numbers to final for 3.0.11 releases. --- phpBB/docs/INSTALL.html | 4 ++-- phpBB/install/convertors/convert_phpbb20.php | 2 +- phpBB/styles/prosilver/imageset/imageset.cfg | 2 +- phpBB/styles/prosilver/style.cfg | 2 +- phpBB/styles/prosilver/template/template.cfg | 2 +- phpBB/styles/prosilver/theme/theme.cfg | 2 +- phpBB/styles/subsilver2/imageset/imageset.cfg | 2 +- phpBB/styles/subsilver2/style.cfg | 2 +- phpBB/styles/subsilver2/template/template.cfg | 2 +- phpBB/styles/subsilver2/theme/theme.cfg | 2 +- 10 files changed, 11 insertions(+), 11 deletions(-) diff --git a/phpBB/docs/INSTALL.html b/phpBB/docs/INSTALL.html index 6ab118e3ee..e17f496c56 100644 --- a/phpBB/docs/INSTALL.html +++ b/phpBB/docs/INSTALL.html @@ -274,7 +274,7 @@

    This package is meant for those wanting to only replace changed files from a previous version to the latest version. This package normally contains the changed files from up to five previous versions.

    -

    This package contains a number of archives, each contains the files changed from a given release to the latest version. You should select the appropriate archive for your current version, e.g. if you currently have 3.0.9 you should select the phpBB-3.0.9_to_3.0.10.zip/tar.gz file.

    +

    This package contains a number of archives, each contains the files changed from a given release to the latest version. You should select the appropriate archive for your current version, e.g. if you currently have 3.0.10 you should select the phpBB-3.0.10_to_3.0.11.zip/tar.gz file.

    The directory structure has been preserved enabling you (if you wish) to simply upload the contents of the archive to the appropriate location on your server, i.e. simply overwrite the existing files with the new versions. Do not forget that if you have installed any MODs these files will overwrite the originals possibly destroying them in the process. You will need to re-add MODs to any affected file before uploading.

    @@ -286,7 +286,7 @@

    The patch file is one solution for those with many Modifications (MODs) or other changes who do not want to re-add them back to all the changed files if they use the method explained above. To use this you will need command line access to a standard UNIX type patch application. If you do not have access to such an application but still want to use this update approach, we strongly recommend the Automatic update package explained below. It is also the recommended update method.

    -

    A number of patch files are provided to allow you to update from previous stable releases. Select the correct patch, e.g. if your current version is 3.0.9 you need the phpBB-3.0.9_to_3.0.10.patch file. Place the correct patch in the parent directory containing the phpBB3 core files (i.e. index.php, viewforum.php, etc.). With this done you should run the following command: patch -cl -d [PHPBB DIRECTORY] -p1 < [PATCH NAME] (where PHPBB DIRECTORY is the directory name your phpBB Installation resides in, for example phpBB3, and where PATCH NAME is the relevant filename of the selected patch file). This should complete quickly, hopefully without any HUNK FAILED comments.

    +

    A number of patch files are provided to allow you to update from previous stable releases. Select the correct patch, e.g. if your current version is 3.0.10 you need the phpBB-3.0.10_to_3.0.11.patch file. Place the correct patch in the parent directory containing the phpBB3 core files (i.e. index.php, viewforum.php, etc.). With this done you should run the following command: patch -cl -d [PHPBB DIRECTORY] -p1 < [PATCH NAME] (where PHPBB DIRECTORY is the directory name your phpBB Installation resides in, for example phpBB3, and where PATCH NAME is the relevant filename of the selected patch file). This should complete quickly, hopefully without any HUNK FAILED comments.

    If you do get failures you should look at using the Changed files only package to replace the files which failed to patch, please note that you will need to manually re-add any Modifications (MODs) to these particular files. Alternatively if you know how you can examine the .rej files to determine what failed where and make manual adjustments to the relevant source.

    diff --git a/phpBB/install/convertors/convert_phpbb20.php b/phpBB/install/convertors/convert_phpbb20.php index 81cc2f68f3..7d6fed6164 100644 --- a/phpBB/install/convertors/convert_phpbb20.php +++ b/phpBB/install/convertors/convert_phpbb20.php @@ -32,7 +32,7 @@ unset($dbpasswd); $convertor_data = array( 'forum_name' => 'phpBB 2.0.x', 'version' => '1.0.3', - 'phpbb_version' => '3.0.10', + 'phpbb_version' => '3.0.11', 'author' => 'phpBB Group', 'dbms' => $dbms, 'dbhost' => $dbhost, diff --git a/phpBB/styles/prosilver/imageset/imageset.cfg b/phpBB/styles/prosilver/imageset/imageset.cfg index 5a703d9e47..d7ba7690f6 100644 --- a/phpBB/styles/prosilver/imageset/imageset.cfg +++ b/phpBB/styles/prosilver/imageset/imageset.cfg @@ -19,7 +19,7 @@ # General Information about this style name = prosilver copyright = © phpBB Group, 2007 -version = 3.0.10 +version = 3.0.11 # Images img_site_logo = site_logo.gif*52*139 diff --git a/phpBB/styles/prosilver/style.cfg b/phpBB/styles/prosilver/style.cfg index 95d8d287e4..97e8aced01 100644 --- a/phpBB/styles/prosilver/style.cfg +++ b/phpBB/styles/prosilver/style.cfg @@ -19,4 +19,4 @@ # General Information about this style name = prosilver copyright = © phpBB Group, 2007 -version = 3.0.10 \ No newline at end of file +version = 3.0.11 \ No newline at end of file diff --git a/phpBB/styles/prosilver/template/template.cfg b/phpBB/styles/prosilver/template/template.cfg index 0b0533573a..eb3df8bfd3 100644 --- a/phpBB/styles/prosilver/template/template.cfg +++ b/phpBB/styles/prosilver/template/template.cfg @@ -19,7 +19,7 @@ # General Information about this template name = prosilver copyright = © phpBB Group, 2007 -version = 3.0.10 +version = 3.0.11 # Defining a different template bitfield template_bitfield = lNg= diff --git a/phpBB/styles/prosilver/theme/theme.cfg b/phpBB/styles/prosilver/theme/theme.cfg index e8698f7fe4..ec489d0b3d 100644 --- a/phpBB/styles/prosilver/theme/theme.cfg +++ b/phpBB/styles/prosilver/theme/theme.cfg @@ -21,7 +21,7 @@ # General Information about this theme name = prosilver copyright = © phpBB Group, 2007 -version = 3.0.10 +version = 3.0.11 # Some configuration options diff --git a/phpBB/styles/subsilver2/imageset/imageset.cfg b/phpBB/styles/subsilver2/imageset/imageset.cfg index 75a4aad038..c943db6735 100644 --- a/phpBB/styles/subsilver2/imageset/imageset.cfg +++ b/phpBB/styles/subsilver2/imageset/imageset.cfg @@ -19,7 +19,7 @@ # General Information about this style name = subsilver2 copyright = © phpBB Group, 2003 -version = 3.0.10 +version = 3.0.11 # Images img_site_logo = site_logo.gif*94*170 diff --git a/phpBB/styles/subsilver2/style.cfg b/phpBB/styles/subsilver2/style.cfg index 13e44435c6..4c40ee4438 100644 --- a/phpBB/styles/subsilver2/style.cfg +++ b/phpBB/styles/subsilver2/style.cfg @@ -19,4 +19,4 @@ # General Information about this style name = subsilver2 copyright = © 2005 phpBB Group -version = 3.0.10 +version = 3.0.11 diff --git a/phpBB/styles/subsilver2/template/template.cfg b/phpBB/styles/subsilver2/template/template.cfg index d557edba87..6568aeca08 100644 --- a/phpBB/styles/subsilver2/template/template.cfg +++ b/phpBB/styles/subsilver2/template/template.cfg @@ -19,7 +19,7 @@ # General Information about this template name = subsilver2 copyright = © phpBB Group, 2003 -version = 3.0.10 +version = 3.0.11 # Template inheritance # See http://blog.phpbb.com/2008/07/31/templating-just-got-easier/ diff --git a/phpBB/styles/subsilver2/theme/theme.cfg b/phpBB/styles/subsilver2/theme/theme.cfg index d7837a3766..5bd4480eef 100644 --- a/phpBB/styles/subsilver2/theme/theme.cfg +++ b/phpBB/styles/subsilver2/theme/theme.cfg @@ -21,7 +21,7 @@ # General Information about this theme name = subsilver2 copyright = © phpBB Group, 2003 -version = 3.0.10 +version = 3.0.11 # Some configuration options From 2011085c29d3141d66d390449b52ba6bd069ab69 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Thu, 31 May 2012 20:26:28 +0200 Subject: [PATCH 244/441] [develop-olympus] Bump version numbers for 3.0.11-RC1 release. --- build/build.xml | 6 +++--- phpBB/includes/constants.php | 2 +- phpBB/install/database_update.php | 6 +++--- phpBB/install/schemas/schema_data.sql | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/build/build.xml b/build/build.xml index 3d8d3de640..c1179015eb 100644 --- a/build/build.xml +++ b/build/build.xml @@ -2,9 +2,9 @@ - - - + + + diff --git a/phpBB/includes/constants.php b/phpBB/includes/constants.php index a0444ea594..5b72d89795 100644 --- a/phpBB/includes/constants.php +++ b/phpBB/includes/constants.php @@ -25,7 +25,7 @@ if (!defined('IN_PHPBB')) */ // phpBB Version -define('PHPBB_VERSION', '3.0.11-dev'); +define('PHPBB_VERSION', '3.0.11-RC1'); // QA-related // define('PHPBB_QA', 1); diff --git a/phpBB/install/database_update.php b/phpBB/install/database_update.php index c700b483a5..c1fe144c62 100644 --- a/phpBB/install/database_update.php +++ b/phpBB/install/database_update.php @@ -8,7 +8,7 @@ * */ -define('UPDATES_TO_VERSION', '3.0.11-dev'); +define('UPDATES_TO_VERSION', '3.0.11-RC1'); // Enter any version to update from to test updates. The version within the db will not be updated. define('DEBUG_FROM_VERSION', false); @@ -951,7 +951,7 @@ function database_update_info() // this column was removed from the database updater // after 3.0.9-RC3 was released. It might still exist // in 3.0.9-RCX installations and has to be dropped in - // 3.0.11 after the db_tools class is capable of properly + // 3.0.12 after the db_tools class is capable of properly // removing a primary key. // 'attempt_id' => array('UINT', NULL, 'auto_increment'), 'attempt_ip' => array('VCHAR:40', ''), @@ -996,7 +996,7 @@ function database_update_info() // No changes from 3.0.10 to 3.0.11-RC1 '3.0.10' => array(), - /** @todo DROP LOGIN_ATTEMPT_TABLE.attempt_id in 3.0.11-RC1 */ + /** @todo DROP LOGIN_ATTEMPT_TABLE.attempt_id in 3.0.12-RC1 */ ); } diff --git a/phpBB/install/schemas/schema_data.sql b/phpBB/install/schemas/schema_data.sql index ba2d18da00..99b8f7f96d 100644 --- a/phpBB/install/schemas/schema_data.sql +++ b/phpBB/install/schemas/schema_data.sql @@ -246,7 +246,7 @@ INSERT INTO phpbb_config (config_name, config_value) VALUES ('topics_per_page', INSERT INTO phpbb_config (config_name, config_value) VALUES ('tpl_allow_php', '0'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('upload_icons_path', 'images/upload_icons'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('upload_path', 'files'); -INSERT INTO phpbb_config (config_name, config_value) VALUES ('version', '3.0.11-dev'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('version', '3.0.11-RC1'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('warnings_expire_days', '90'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('warnings_gc', '14400'); From 19a47dfbbc4265e33c14d6679b5693d80120db4b Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Thu, 31 May 2012 20:56:40 +0200 Subject: [PATCH 245/441] [develop-olympus] Add changelog for 3.0.11 release. --- phpBB/docs/CHANGELOG.html | 155 +++++++++++++++++++++++++++++++++----- 1 file changed, 136 insertions(+), 19 deletions(-) diff --git a/phpBB/docs/CHANGELOG.html b/phpBB/docs/CHANGELOG.html index 2d3b6a6809..71e28be9bc 100644 --- a/phpBB/docs/CHANGELOG.html +++ b/phpBB/docs/CHANGELOG.html @@ -53,6 +53,7 @@
    1. Changelog
        +
      1. Changes since 3.0.10
      2. Changes since 3.0.9
      3. Changes since 3.0.8
      4. Changes since 3.0.7-PL1
      5. @@ -91,7 +92,123 @@
        -

        1.i. Changes since 3.0.9

        +

        1.i. Changes since 3.0.10

        + +

        Bug

        +
          +
        • [PHPBB3-7432] - Unclear language for Inactive Users on ACP main page
        • +
        • [PHPBB3-8652] - Duplicate Emails Sent When Subscribed to Forum and Topic
        • +
        • [PHPBB3-9079] - Display backtrace on all E_USER_ERROR errors, not only SQL errors (when DEBUG_EXTRA is enabled)
        • +
        • [PHPBB3-9084] - Unable to display 'option equal to non entered value' if dropdown CPF is not required
        • +
        • [PHPBB3-9089] - PM message title box not accessible via Tab key
        • +
        • [PHPBB3-9220] - Blue border width when table in a div
        • +
        • [PHPBB3-9681] - Password length not in security settings
        • +
        • [PHPBB3-9813] - fulltext_native.php on innodb loading deadly slow for big indexes
        • +
        • [PHPBB3-9831] - Cannot change default of Boolean checkbox custom profile field
        • +
        • [PHPBB3-10094] - Clear cache before phpBB installation
        • +
        • [PHPBB3-10129] - Missing apostrophes in ACP user management -> permissions
        • +
        • [PHPBB3-10349] - Unit tests do not remove comments from schemas
        • +
        • [PHPBB3-10399] - Special characters aren't parsed in style component variables
        • +
        • [PHPBB3-10401] - auth_ldap has an incorrect return value in login_ldap()
        • +
        • [PHPBB3-10407] - Incorrect check for empty image file paths during conversion
        • +
        • [PHPBB3-10428] - optionget/optionset functions in session.php and acp_users.php incorrectly check whether $data is at its default value
        • +
        • [PHPBB3-10456] - Subsilver2 does not define $CAPTCHA_TAB_INDEX
        • +
        • [PHPBB3-10508] - Marking forums as read displays misleading language
        • +
        • [PHPBB3-10511] - Grammar defect in permissions language
        • +
        • [PHPBB3-10512] - Test failure when no default timezone is set in php
        • +
        • [PHPBB3-10532] - Out of range $start causes a page with no search results but with pagination
        • +
        • [PHPBB3-10538] - Special character are not correctly parsed for SMTP protocol
        • +
        • [PHPBB3-10542] - Incorrect class="postlink" in styles/subsilver2/template/faq_body.html
        • +
        • [PHPBB3-10546] - Argument missing for adm_back_link() in acp_captcha.php
        • +
        • [PHPBB3-10561] - All users can choose deactivated styles.
        • +
        • [PHPBB3-10569] - template/ucp_main_front.html does not correctly handle active topic with the name "0"
        • +
        • [PHPBB3-10580] - Default tz in registration dropdown not the same as the board default tz
        • +
        • [PHPBB3-10589] - user_birthday does not use table alias in $leap_year_birthdays variable definition
        • +
        • [PHPBB3-10605] - Orpahned privmsgs are left in the prvmsgs table, with no ties in privmsgs_to table
        • +
        • [PHPBB3-10606] - $s_hidden_fields -> incorrect array name (3 files affected)
        • +
        • [PHPBB3-10611] - Add a check for selected tables existence for ACP database backup tool
        • +
        • [PHPBB3-10615] - Static calls in utf normalizer yield E_STRICT spam on php 5.4
        • +
        • [PHPBB3-10630] - Prune Users produced unnecessarily long query; Got a packet bigger than 'max_allowed_packet' bytes
        • +
        • [PHPBB3-10633] - Users are able to get the real filename of attachment
        • +
        • [PHPBB3-10639] - negative value of ranks message
        • +
        • [PHPBB3-10658] - Rank-item is not shown on team-list
        • +
        • [PHPBB3-10675] - Use more descriptive message when disk is out of space
        • +
        • [PHPBB3-10684] - Function user_notification() prevents notifications for users with stale bans
        • +
        • [PHPBB3-10689] - Bug in the popup " Find a member" when select by letter.
        • +
        • [PHPBB3-10691] - Search index creation CLI script incorrectly calculates indexing speed
        • +
        • [PHPBB3-10699] - Long h2 title breaks div.minitabs in MCP
        • +
        • [PHPBB3-10708] - After a conversion, passwords with UTF8 characters do not work when user_pass_convert is set.
        • +
        • [PHPBB3-10717] - memberlist_view.html: including admin defined profile fields doesnt work
        • +
        • [PHPBB3-10723] - Do not use SQLite on PHP 5.4 in Tests on Travis
        • +
        • [PHPBB3-10731] - JS function addquote() works incorrectly in Opera
        • +
        • [PHPBB3-10751] - MS SQL Error when searching Admin Log
        • +
        • [PHPBB3-10760] - In pre-commit git hook, syntax error is thrown, but is not specifically described
        • +
        • [PHPBB3-10767] - Git hooks do not work properly with git GUIs
        • +
        • [PHPBB3-10774] - db_tools::create_unique_index does not use specified index names on MySQL
        • +
        • [PHPBB3-10790] - Strict comparison on user_id for sending pms
        • +
        • [PHPBB3-10797] - Template var for user rank not filled
        • +
        • [PHPBB3-10835] - Misleading message in UCP when no permission to change password
        • +
        • [PHPBB3-10846] - Missing alias for MAX(post_id) in SQL query in acp_main.php
        • +
        • [PHPBB3-10849] - Missing BBCode Help Text in subsilver2
        • +
        • [PHPBB3-10858] - $db->sql_fetchfield returns false with mssqlnative
        • +
        • [PHPBB3-10860] - Side-by-side diff styling javascript bug
        • +
        • [PHPBB3-10881] - Some files use 0xA9 as the copyright symbol which is neither ASCII nor the UTF8 copyright symbol.
        • +
        • [PHPBB3-10887] - Auto increment tests depend on varbinary handling
        • +
        • [PHPBB3-10889] - Default value for c_char_size in database unit tests is an empty string instead of a char(4)
        • +
        • [PHPBB3-10890] - test_sql_fetchrow_returns_false_when_empty() fails on MSSQL and Oracle
        • +
        • [PHPBB3-10908] - No remote avatar size limit results in files limited only by PHP memory limit
        • +
        • [PHPBB3-10913] - Admin is logged out when accessing any url under adm/ without session id
        • +
        +

        Improvement

        +
          +
        • [PHPBB3-8599] - Add "Select All" to "Add multiple smilies" screen
        • +
        • [PHPBB3-8636] - Add resync option to topic_view moderation page
        • +
        • [PHPBB3-9876] - Names and descriptions for roles "Newly registered User" in "User roles" and "Forum roles" must be different
        • +
        • [PHPBB3-9914] - Add backup warning to Automatic DB Updater
        • +
        • [PHPBB3-9916] - License in header not linking to version 2 of GNU GPL
        • +
        • [PHPBB3-10093] - Make commit-msg hook always not fatal
        • +
        • [PHPBB3-10162] - Allow TLDs over 6 characters in email addresses
        • +
        • [PHPBB3-10280] - Change the ACP user activation display
        • +
        • [PHPBB3-10308] - Disable Retain/Delete Posts selection if the user has no posts.
        • +
        • [PHPBB3-10453] - PM viewmessage page is misplacing the online icon
        • +
        • [PHPBB3-10492] - Port functional tests to develop-olympus
        • +
        • [PHPBB3-10507] - Sort installed styles list in admin control panel - styles
        • +
        • [PHPBB3-10550] - Sort not installed styles list in admin control panel - styles
        • +
        • [PHPBB3-10563] - ACP usability improvement: show deactivated styles below active styles in styles list
        • +
        • [PHPBB3-10565] - Performance: Unneeded GROUP BY in update_forum_tracking_info
        • +
        • [PHPBB3-10607] - phpBB Credit Line Hardcoded
        • +
        • [PHPBB3-10653] - Add ability to count table rows to database abstraction layer
        • +
        • [PHPBB3-10730] - Add label tags around "select" text in post splitting UI in MCP
        • +
        • [PHPBB3-10764] - FAQ mentions SourceForge
        • +
        • [PHPBB3-10812] - Installer should not display register globals UI for php 5.4+
        • +
        • [PHPBB3-10815] - Enable Feeds by default
        • +
        • [PHPBB3-10819] - Improve side-by-side diff styling
        • +
        • [PHPBB3-10834] - Backport general development language changes in readme files
        • +
        • [PHPBB3-10836] - Enable Avatars by default
        • +
        • [PHPBB3-10891] - Allow specifying test config file name via environment variable
        • +
        • [PHPBB3-10892] - Cosmetic improvements to RUNNING_TESTS.txt
        • +
        • [PHPBB3-10898] - Do not write ?> into config.php to avoid whitespace output
        • +
        +

        New Feature

        + +

        Sub-task

        +
          +
        • [PHPBB3-10907] - Mark (var)binary tests as incomplete on non-MySQL DBMSes
        • +
        +

        Task

        +
          +
        • [PHPBB3-9896] - Update links in docs/readme.html
        • +
        • [PHPBB3-10434] - Add a script that allows creating a search index from CLI
        • +
        • [PHPBB3-10455] - Remove NOTE from header files
        • +
        • [PHPBB3-10694] - Update notification in ACP (Olympus) for increase of minimum PHP version to 5.3.2
        • +
        • [PHPBB3-10718] - Add Travis CI
        • +
        • [PHPBB3-10788] - Update docs/AUTHORS for 3.0.11-RC1
        • +
        • [PHPBB3-10909] - Update Travis Test Configuration: Travis no longer supports PHP 5.3.2
        • +
        + +

        1.ii. Changes since 3.0.9

        Bug

          @@ -227,7 +344,7 @@
        • [PHPBB3-10480] - Automate changelog building
        -

        1.ii. Changes since 3.0.8

        +

        1.iii. Changes since 3.0.8

        Bug

        @@ -595,7 +712,7 @@ -

        1.iii. Changes since 3.0.7-PL1

        +

        1.iv. Changes since 3.0.7-PL1

        Security

          @@ -1053,13 +1170,13 @@
        -

        1.iiv. Changes since 3.0.7

        +

        1.iv. Changes since 3.0.7

        • [Sec] Do not expose forum content of forums with ACL entries but no actual permission in ATOM Feeds. (Bug #58595)
        -

        1.v. Changes since 3.0.6

        +

        1.vi. Changes since 3.0.6

        • [Fix] Allow ban reason and length to be selected and copied in ACP and subsilver2 MCP. (Bug #51095)
        • @@ -1163,7 +1280,7 @@
        -

        1.vi. Changes since 3.0.5

        +

        1.vii. Changes since 3.0.5

        • [Fix] Allow whitespaces in avatar gallery names. (Bug #44955)
        • @@ -1385,7 +1502,7 @@
        • [Feature] Send anonymous statistical information to phpBB on installation and update (optional).
        -

        1.vii. Changes since 3.0.4

        +

        1.viii. Changes since 3.0.4

        • [Fix] Delete user entry from ban list table upon user deletion (Bug #40015 - Patch by TerraFrost)
        • @@ -1474,7 +1591,7 @@
        • [Sec] Only use forum id supplied for posting if global announcement detected. (Reported by nickvergessen)
        -

        1.viii. Changes since 3.0.3

        +

        1.ix. Changes since 3.0.3

        • [Fix] Allow mixed-case template directories to be inherited (Bug #36725)
        • @@ -1506,7 +1623,7 @@
        • [Sec] Ask for forum password if post within passworded forum quoted in private message. (Reported by nickvergessen)
        -

        1.ix. Changes since 3.0.2

        +

        1.x. Changes since 3.0.2

        • [Fix] Correctly set topic starter if first post in topic removed (Bug #30575 - Patch by blueray2048)
        • @@ -1605,7 +1722,7 @@
        • [Sec Precaution] Stricter validation of the HTTP_HOST header (Thanks to Techie-Micheal et al for pointing out possible issues in derived code)
        -

        1.x. Changes since 3.0.1

        +

        1.xi. Changes since 3.0.1

        • [Fix] Ability to set permissions on non-mysql dbms (Bug #24955)
        • @@ -1653,7 +1770,7 @@
        • [Sec] Only allow urls gone through redirect() being used within login_box(). (thanks nookieman)
        -

        1.xi Changes since 3.0.0

        +

        1.xii Changes since 3.0.0

        • [Change] Validate birthdays (Bug #15004)
        • @@ -1724,7 +1841,7 @@
        • [Fix] Find and display colliding usernames correctly when converting from one database to another (Bug #23925)
        -

        1.xii. Changes since 3.0.RC8

        +

        1.xiii. Changes since 3.0.RC8

        • [Fix] Cleaned usernames contain only single spaces, so "a_name" and "a__name" are treated as the same name (Bug #15634)
        • @@ -1733,7 +1850,7 @@
        • [Fix] Call garbage_collection() within database updater to correctly close connections (affects Oracle for example)
        -

        1.xiii. Changes since 3.0.RC7

        +

        1.xiv. Changes since 3.0.RC7

        • [Fix] Fixed MSSQL related bug in the update system
        • @@ -1768,7 +1885,7 @@
        • [Fix] No duplication of active topics (Bug #15474)
        -

        1.xiv. Changes since 3.0.RC6

        +

        1.xv. Changes since 3.0.RC6

        • [Fix] Submitting language changes using acp_language (Bug #14736)
        • @@ -1778,7 +1895,7 @@
        • [Fix] Able to request new password (Bug #14743)
        -

        1.xv. Changes since 3.0.RC5

        +

        1.xvi. Changes since 3.0.RC5

        • [Feature] Removing constant PHPBB_EMBEDDED in favor of using an exit_handler(); the constant was meant to achive this more or less.
        • @@ -1841,7 +1958,7 @@
        • [Sec] New password hashing mechanism for storing passwords (#i42)
        -

        1.xvi. Changes since 3.0.RC4

        +

        1.xvii. Changes since 3.0.RC4

        • [Fix] MySQL, PostgreSQL and SQLite related database fixes (Bug #13862)
        • @@ -1892,7 +2009,7 @@
        • [Fix] odbc_autocommit causing existing result sets to be dropped (Bug #14182)
        -

        1.xvii. Changes since 3.0.RC3

        +

        1.xviii. Changes since 3.0.RC3

        • [Fix] Fixing some subsilver2 and prosilver style issues
        • @@ -2001,7 +2118,7 @@
        -

        1.xviii. Changes since 3.0.RC2

        +

        1.xviv. Changes since 3.0.RC2

        • [Fix] Re-allow searching within the memberlist
        • @@ -2047,7 +2164,7 @@
        -

        1.xix. Changes since 3.0.RC1

        +

        1.xx. Changes since 3.0.RC1

        • [Fix] (X)HTML issues within the templates (Bug #11255, #11255)
        • From 118c5d90daa783ff55319e6121c0fc77166fe58c Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Thu, 31 May 2012 22:07:34 +0200 Subject: [PATCH 246/441] [develop-olympus] Incrementing the version to 3.0.12-dev in develop-olympus. --- phpBB/includes/constants.php | 2 +- phpBB/install/database_update.php | 2 +- phpBB/install/schemas/schema_data.sql | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/phpBB/includes/constants.php b/phpBB/includes/constants.php index 5b72d89795..17c25ee3c6 100644 --- a/phpBB/includes/constants.php +++ b/phpBB/includes/constants.php @@ -25,7 +25,7 @@ if (!defined('IN_PHPBB')) */ // phpBB Version -define('PHPBB_VERSION', '3.0.11-RC1'); +define('PHPBB_VERSION', '3.0.12-dev'); // QA-related // define('PHPBB_QA', 1); diff --git a/phpBB/install/database_update.php b/phpBB/install/database_update.php index c1fe144c62..a52a329f20 100644 --- a/phpBB/install/database_update.php +++ b/phpBB/install/database_update.php @@ -8,7 +8,7 @@ * */ -define('UPDATES_TO_VERSION', '3.0.11-RC1'); +define('UPDATES_TO_VERSION', '3.0.12-dev'); // Enter any version to update from to test updates. The version within the db will not be updated. define('DEBUG_FROM_VERSION', false); diff --git a/phpBB/install/schemas/schema_data.sql b/phpBB/install/schemas/schema_data.sql index 99b8f7f96d..b139857d28 100644 --- a/phpBB/install/schemas/schema_data.sql +++ b/phpBB/install/schemas/schema_data.sql @@ -246,7 +246,7 @@ INSERT INTO phpbb_config (config_name, config_value) VALUES ('topics_per_page', INSERT INTO phpbb_config (config_name, config_value) VALUES ('tpl_allow_php', '0'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('upload_icons_path', 'images/upload_icons'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('upload_path', 'files'); -INSERT INTO phpbb_config (config_name, config_value) VALUES ('version', '3.0.11-RC1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('version', '3.0.12-dev'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('warnings_expire_days', '90'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('warnings_gc', '14400'); From a9549cbe6ab66732fcf9c321496b74943e2972e7 Mon Sep 17 00:00:00 2001 From: Dhruv Goel Date: Sun, 3 Jun 2012 15:56:55 +0530 Subject: [PATCH 247/441] [feature-delete-auto-logins] adds module to database update ucp delete auto-login keys module is added to database_update.php under 3.1-dev --- phpBB/install/database_update.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/phpBB/install/database_update.php b/phpBB/install/database_update.php index 665db1f2f0..a5bd5e7bfe 100644 --- a/phpBB/install/database_update.php +++ b/phpBB/install/database_update.php @@ -2305,6 +2305,13 @@ function change_database_data(&$no_updates, $version) 'auth' => 'acl_a_styles', 'cat' => 'ACP_STYLE_MANAGEMENT', ), + 'autologin_keys' => array( + 'base' => 'ucp_profile', + 'class' => 'ucp', + 'title' => 'UCP_PROFILE_AUTOLOGIN_KEYS', + 'auth' => '', + 'cat' => 'UCP_PROFILE', + ), ); _add_modules($modules_to_install); From 0191e1313ca8179bb09a2fc6f3d06de95768bc96 Mon Sep 17 00:00:00 2001 From: wagnerch Date: Sun, 22 Jul 2007 22:23:00 +0000 Subject: [PATCH 248/441] [feature/postgresql-fulltext-search] PostgreSQL fulltext search, version 1. PHPBB3-9730 --- README.fulltext_postgres | 23 + phpBB/includes/search/fulltext_postgres.php | 893 ++++++++++++++++++++ phpBB/install/schemas/fulltext_postgres.sql | 3 + phpBB/language/en/acp/search.php | 14 + 4 files changed, 933 insertions(+) create mode 100644 README.fulltext_postgres create mode 100644 phpBB/includes/search/fulltext_postgres.php create mode 100644 phpBB/install/schemas/fulltext_postgres.sql diff --git a/README.fulltext_postgres b/README.fulltext_postgres new file mode 100644 index 0000000000..b7b6aec9fd --- /dev/null +++ b/README.fulltext_postgres @@ -0,0 +1,23 @@ + +Fulltext Search for PostgreSQL +============================== + +Installation Instructions +1. Install the tsearch2 contribution by executing the tsearch2.sql script + from the PostgreSQL contrib directory. +2. Apply the fulltext_postgres.diff patch using patch(1) to the root + directory of your phpBB3 forum. + + $ patch -p0 word_length = array('min' => $config['fulltext_postgres_min_word_len'], 'max' => $config['fulltext_postgres_max_word_len']); + + if (version_compare(PHP_VERSION, '5.1.0', '>=') || (version_compare(PHP_VERSION, '5.0.0-dev', '<=') && version_compare(PHP_VERSION, '4.4.0', '>='))) + { + // While this is the proper range of PHP versions, PHP may not be linked with the bundled PCRE lib and instead with an older version + if (@preg_match('/\p{L}/u', 'a') !== false) + { + $this->pcre_properties = true; + } + } + + if (function_exists('mb_ereg')) + { + $this->mbstring_regex = true; + } + + if ($db->sql_layer == 'postgres') + { + $pgsql_version = explode('.', substr($db->sql_server_info(), 10)); + if ($pgsql_version[0] >= 8 && $pgsql_version[1] >= 3) + { + $this->tsearch_builtin = true; + } + + + if (!$this->tsearch_builtin) { + $db->sql_query("SELECT set_curcfg('" . $db->sql_escape($config['fulltext_postgres_ts_name']) . "')"); + } + } + + $error = false; + } + + /** + * Checks for correct PostgreSQL version and stores min/max word length in the config + */ + function init() + { + global $db; + + if ($db->sql_layer != 'postgres') + { + return $user->lang['FULLTEXT_POSTGRES_INCOMPATIBLE_VERSION']; + } + + if (!$this->tsearch_builtin) { + $sql = "SELECT c.relname + FROM pg_catalog.pg_class c + WHERE c.relkind = 'r' + AND c.relname = 'pg_ts_cfg' + AND pg_catalog.pg_table_is_visible(c.oid)"; + $result = $db->sql_query($sql); + $row = $db->sql_fetchrow($result); + $db->sql_freeresult($result); + + if (empty ($row['relname'])) + { + return $user->lang['FULLTEXT_POSTGRES_TS_NOT_FOUND']; + } + } + + return false; + } + + /** + * Splits keywords entered by a user into an array of words stored in $this->split_words + * Stores the tidied search query in $this->search_query + * + * @param string &$keywords Contains the keyword as entered by the user + * @param string $terms is either 'all' or 'any' + * @return bool false if no valid keywords were found and otherwise true + */ + function split_keywords(&$keywords, $terms) + { + global $config; + + if ($terms == 'all') + { + $match = array('#\sand\s#iu', '#\sor\s#iu', '#\snot\s#iu', '#\+#', '#-#', '#\|#'); + $replace = array(' +', ' |', ' -', ' +', ' -', ' |'); + + $keywords = preg_replace($match, $replace, $keywords); + } + + // Filter out as above + $split_keywords = preg_replace("#[\"\n\r\t]+#", ' ', trim(htmlspecialchars_decode($keywords))); + + // Split words + if ($this->pcre_properties) + { + $split_keywords = preg_replace('#([^\p{L}\p{N}\'*"()])#u', '$1$1', str_replace('\'\'', '\' \'', trim($split_keywords))); + } + else if ($this->mbstring_regex) + { + $split_keywords = mb_ereg_replace('([^\w\'*"()])', '\\1\\1', str_replace('\'\'', '\' \'', trim($split_keywords))); + } + else + { + $split_keywords = preg_replace('#([^\w\'*"()])#u', '$1$1', str_replace('\'\'', '\' \'', trim($split_keywords))); + } + + if ($this->pcre_properties) + { + $matches = array(); + preg_match_all('#(?:[^\p{L}\p{N}*"()]|^)([+\-|]?(?:[\p{L}\p{N}*"()]+\'?)*[\p{L}\p{N}*"()])(?:[^\p{L}\p{N}*"()]|$)#u', $split_keywords, $matches); + $this->split_words = $matches[1]; + } + else if ($this->mbstring_regex) + { + mb_regex_encoding('UTF-8'); + mb_ereg_search_init($split_keywords, '(?:[^\w*"()]|^)([+\-|]?(?:[\w*"()]+\'?)*[\w*"()])(?:[^\w*"()]|$)'); + + while (($word = mb_ereg_search_regs())) + { + $this->split_words[] = $word[1]; + } + } + else + { + $matches = array(); + preg_match_all('#(?:[^\w*"()]|^)([+\-|]?(?:[\w*"()]+\'?)*[\w*"()])(?:[^\w*"()]|$)#u', $split_keywords, $matches); + $this->split_words = $matches[1]; + } + + // to allow phrase search, we need to concatenate quoted words + $tmp_split_words = array(); + $phrase = ''; + foreach ($this->split_words as $word) + { + if ($phrase) + { + $phrase .= ' ' . $word; + if (strpos($word, '"') !== false && substr_count($word, '"') % 2 == 1) + { + $tmp_split_words[] = $phrase; + $phrase = ''; + } + } + else if (strpos($word, '"') !== false && substr_count($word, '"') % 2 == 1) + { + $phrase = $word; + } + else + { + $tmp_split_words[] = $word . ' '; + } + } + if ($phrase) + { + $tmp_split_words[] = $phrase; + } + + $this->split_words = $tmp_split_words; + + unset($tmp_split_words); + unset($phrase); + + foreach ($this->split_words as $i => $word) + { + $clean_word = preg_replace('#^[+\-|"]#', '', $word); + + // check word length + $clean_len = utf8_strlen(str_replace('*', '', $clean_word)); + if (($clean_len < $config['fulltext_postgres_min_word_len']) || ($clean_len > $config['fulltext_postgres_max_word_len'])) + { + $this->common_words[] = $word; + unset($this->split_words[$i]); + } + } + + if ($terms == 'any') + { + $this->search_query = ''; + $this->tsearch_query = ''; + foreach ($this->split_words as $word) + { + if ((strpos($word, '+') === 0) || (strpos($word, '-') === 0) || (strpos($word, '|') === 0)) + { + $word = substr($word, 1); + } + $this->search_query .= $word . ' '; + $this->tsearch_query .= '|' . $word . ' '; + } + } + else + { + $this->search_query = ''; + $this->tsearch_query = ''; + foreach ($this->split_words as $word) + { + if (strpos($word, '+') === 0) + { + $this->search_query .= $word . ' '; + $this->tsearch_query .= '&' . substr($word, 1) . ' '; + } + elseif (strpos($word, '-') === 0) + { + $this->search_query .= $word . ' '; + $this->tsearch_query .= '&!' . substr($word, 1) . ' '; + } + elseif (strpos($word, '|') === 0) + { + $this->search_query .= $word . ' '; + $this->tsearch_query .= '|' . substr($word, 1) . ' '; + } + else + { + $this->search_query .= '+' . $word . ' '; + $this->tsearch_query .= '&' . $word . ' '; + } + } + } + + $this->tsearch_query = substr($this->tsearch_query, 1); + $this->search_query = utf8_htmlspecialchars($this->search_query); + + if ($this->search_query) + { + $this->split_words = array_values($this->split_words); + sort($this->split_words); + return true; + } + return false; + } + + /** + * Turns text into an array of words + */ + function split_message($text) + { + global $config; + + // Split words + if ($this->pcre_properties) + { + $text = preg_replace('#([^\p{L}\p{N}\'*])#u', '$1$1', str_replace('\'\'', '\' \'', trim($text))); + } + else if ($this->mbstring_regex) + { + $text = mb_ereg_replace('([^\w\'*])', '\\1\\1', str_replace('\'\'', '\' \'', trim($text))); + } + else + { + $text = preg_replace('#([^\w\'*])#u', '$1$1', str_replace('\'\'', '\' \'', trim($text))); + } + + if ($this->pcre_properties) + { + $matches = array(); + preg_match_all('#(?:[^\p{L}\p{N}*]|^)([+\-|]?(?:[\p{L}\p{N}*]+\'?)*[\p{L}\p{N}*])(?:[^\p{L}\p{N}*]|$)#u', $text, $matches); + $text = $matches[1]; + } + else if ($this->mbstring_regex) + { + mb_regex_encoding('UTF-8'); + mb_ereg_search_init($text, '(?:[^\w*]|^)([+\-|]?(?:[\w*]+\'?)*[\w*])(?:[^\w*]|$)'); + + $text = array(); + while (($word = mb_ereg_search_regs())) + { + $text[] = $word[1]; + } + } + else + { + $matches = array(); + preg_match_all('#(?:[^\w*]|^)([+\-|]?(?:[\w*]+\'?)*[\w*])(?:[^\w*]|$)#u', $text, $matches); + $text = $matches[1]; + } + + // remove too short or too long words + $text = array_values($text); + for ($i = 0, $n = sizeof($text); $i < $n; $i++) + { + $text[$i] = trim($text[$i]); + if (utf8_strlen($text[$i]) < $config['fulltext_postgres_min_word_len'] || utf8_strlen($text[$i]) > $config['fulltext_postgres_max_word_len']) + { + unset($text[$i]); + } + } + + return array_values($text); + } + + /** + * Performs a search on keywords depending on display specific params. You have to run split_keywords() first. + * + * @param string $type contains either posts or topics depending on what should be searched for + * @param string &$fields contains either titleonly (topic titles should be searched), msgonly (only message bodies should be searched), firstpost (only subject and body of the first post should be searched) or all (all post bodies and subjects should be searched) + * @param string &$terms is either 'all' (use query as entered, words without prefix should default to "have to be in field") or 'any' (ignore search query parts and just return all posts that contain any of the specified words) + * @param array &$sort_by_sql contains SQL code for the ORDER BY part of a query + * @param string &$sort_key is the key of $sort_by_sql for the selected sorting + * @param string &$sort_dir is either a or d representing ASC and DESC + * @param string &$sort_days specifies the maximum amount of days a post may be old + * @param array &$ex_fid_ary specifies an array of forum ids which should not be searched + * @param array &$m_approve_fid_ary specifies an array of forum ids in which the searcher is allowed to view unapproved posts + * @param int &$topic_id is set to 0 or a topic id, if it is not 0 then only posts in this topic should be searched + * @param array &$author_ary an array of author ids if the author should be ignored during the search the array is empty + * @param array &$id_ary passed by reference, to be filled with ids for the page specified by $start and $per_page, should be ordered + * @param int $start indicates the first index of the page + * @param int $per_page number of ids each page is supposed to contain + * @return boolean|int total number of results + * + * @access public + */ + function keyword_search($type, &$fields, &$terms, &$sort_by_sql, &$sort_key, &$sort_dir, &$sort_days, &$ex_fid_ary, &$m_approve_fid_ary, &$topic_id, &$author_ary, &$id_ary, $start, $per_page) + { + global $config, $db; + + // No keywords? No posts. + if (!$this->search_query) + { + return false; + } + + // generate a search_key from all the options to identify the results + $search_key = md5(implode('#', array( + implode(', ', $this->split_words), + $type, + $fields, + $terms, + $sort_days, + $sort_key, + $topic_id, + implode(',', $ex_fid_ary), + implode(',', $m_approve_fid_ary), + implode(',', $author_ary) + ))); + + // try reading the results from cache + $result_count = 0; + if ($this->obtain_ids($search_key, $result_count, $id_ary, $start, $per_page, $sort_dir) == SEARCH_RESULT_IN_CACHE) + { + return $result_count; + } + + $id_ary = array(); + + $join_topic = ($type == 'posts') ? false : true; + + // Build sql strings for sorting + $sql_sort = $sort_by_sql[$sort_key] . (($sort_dir == 'a') ? ' ASC' : ' DESC'); + $sql_sort_table = $sql_sort_join = ''; + + switch ($sql_sort[0]) + { + case 'u': + $sql_sort_table = USERS_TABLE . ' u, '; + $sql_sort_join = ($type == 'posts') ? ' AND u.user_id = p.poster_id ' : ' AND u.user_id = t.topic_poster '; + break; + + case 't': + $join_topic = true; + break; + + case 'f': + $sql_sort_table = FORUMS_TABLE . ' f, '; + $sql_sort_join = ' AND f.forum_id = p.forum_id '; + break; + } + + // Build some display specific sql strings + switch ($fields) + { + case 'titleonly': + $sql_match = 'p.post_subject'; + $sql_match_where = ' AND p.post_id = t.topic_first_post_id'; + $join_topic = true; + break; + + case 'msgonly': + $sql_match = 'p.post_text'; + $sql_match_where = ''; + break; + + case 'firstpost': + $sql_match = 'p.post_subject, p.post_text'; + $sql_match_where = ' AND p.post_id = t.topic_first_post_id'; + $join_topic = true; + break; + + default: + $sql_match = 'p.post_subject, p.post_text'; + $sql_match_where = ''; + break; + } + + if (!sizeof($m_approve_fid_ary)) + { + $m_approve_fid_sql = ' AND p.post_approved = 1'; + } + else if ($m_approve_fid_ary === array(-1)) + { + $m_approve_fid_sql = ''; + } + else + { + $m_approve_fid_sql = ' AND (p.post_approved = 1 OR ' . $db->sql_in_set('p.forum_id', $m_approve_fid_ary, true) . ')'; + } + + $sql_select = ($type == 'posts') ? 'p.post_id' : 'DISTINCT t.topic_id'; + $sql_from = ($join_topic) ? TOPICS_TABLE . ' t, ' : ''; + $field = ($type == 'posts') ? 'post_id' : 'topic_id'; + $sql_author = (sizeof($author_ary) == 1) ? ' = ' . $author_ary[0] : 'IN (' . implode(', ', $author_ary) . ')'; + + $sql_where_options = $sql_sort_join; + $sql_where_options .= ($topic_id) ? ' AND p.topic_id = ' . $topic_id : ''; + $sql_where_options .= ($join_topic) ? ' AND t.topic_id = p.topic_id' : ''; + $sql_where_options .= (sizeof($ex_fid_ary)) ? ' AND ' . $db->sql_in_set('p.forum_id', $ex_fid_ary, true) : ''; + $sql_where_options .= $m_approve_fid_sql; + $sql_where_options .= (sizeof($author_ary)) ? ' AND p.poster_id ' . $sql_author : ''; + $sql_where_options .= ($sort_days) ? ' AND p.post_time >= ' . (time() - ($sort_days * 86400)) : ''; + $sql_where_options .= $sql_match_where; + + $tmp_sql_match = array(); + foreach (explode(',', $sql_match) as $sql_match_column) + { + if ($this->tsearch_builtin) + { + $tmp_sql_match[] = "to_tsvector ('" . $db->sql_escape($config['fulltext_postgres_ts_name']) . "', " . $sql_match_column . ") @@ to_tsquery ('" . $db->sql_escape($config['fulltext_postgres_ts_name']) . "', '" . $db->sql_escape($this->tsearch_query) . "')"; + } + else + { + $tmp_sql_match[] = "to_tsvector (" . $sql_match_column . ") @@ to_tsquery ('" . $db->sql_escape($this->tsearch_query) . "')"; + } + } + + $sql = "SELECT $sql_select + FROM $sql_from$sql_sort_table" . POSTS_TABLE . " p + WHERE (" . implode(' OR ', $tmp_sql_match) . ") + $sql_where_options + ORDER BY $sql_sort"; + $result = $db->sql_query_limit($sql, $config['search_block_size'], $start); + + while ($row = $db->sql_fetchrow($result)) + { + $id_ary[] = $row[$field]; + } + $db->sql_freeresult($result); + + $id_ary = array_unique($id_ary); + + if (!sizeof($id_ary)) + { + return false; + } + + // if the total result count is not cached yet, retrieve it from the db + if (!$result_count) + { + $result_count = sizeof ($id_ary); + + if (!$result_count) + { + return false; + } + } + + // store the ids, from start on then delete anything that isn't on the current page because we only need ids for one page + $this->save_ids($search_key, implode(' ', $this->split_words), $author_ary, $result_count, $id_ary, $start, $sort_dir); + $id_ary = array_slice($id_ary, 0, (int) $per_page); + + return $result_count; + } + + /** + * Performs a search on an author's posts without caring about message contents. Depends on display specific params + * + * @param array &$id_ary passed by reference, to be filled with ids for the page specified by $start and $per_page, should be ordered + * @param int $start indicates the first index of the page + * @param int $per_page number of ids each page is supposed to contain + * @return total number of results + */ + function author_search($type, $firstpost_only, &$sort_by_sql, &$sort_key, &$sort_dir, &$sort_days, &$ex_fid_ary, &$m_approve_fid_ary, &$topic_id, &$author_ary, &$id_ary, $start, $per_page) + { + global $config, $db; + + // No author? No posts. + if (!sizeof($author_ary)) + { + return 0; + } + + // generate a search_key from all the options to identify the results + $search_key = md5(implode('#', array( + '', + $type, + ($firstpost_only) ? 'firstpost' : '', + '', + '', + $sort_days, + $sort_key, + $topic_id, + implode(',', $ex_fid_ary), + implode(',', $m_approve_fid_ary), + implode(',', $author_ary) + ))); + + // try reading the results from cache + $result_count = 0; + if ($this->obtain_ids($search_key, $result_count, $id_ary, $start, $per_page, $sort_dir) == SEARCH_RESULT_IN_CACHE) + { + return $result_count; + } + + $id_ary = array(); + + // Create some display specific sql strings + $sql_author = $db->sql_in_set('p.poster_id', $author_ary); + $sql_fora = (sizeof($ex_fid_ary)) ? ' AND ' . $db->sql_in_set('p.forum_id', $ex_fid_ary, true) : ''; + $sql_topic_id = ($topic_id) ? ' AND p.topic_id = ' . (int) $topic_id : ''; + $sql_time = ($sort_days) ? ' AND p.post_time >= ' . (time() - ($sort_days * 86400)) : ''; + $sql_firstpost = ($firstpost_only) ? ' AND p.post_id = t.topic_first_post_id' : ''; + + // Build sql strings for sorting + $sql_sort = $sort_by_sql[$sort_key] . (($sort_dir == 'a') ? ' ASC' : ' DESC'); + $sql_sort_table = $sql_sort_join = ''; + switch ($sql_sort[0]) + { + case 'u': + $sql_sort_table = USERS_TABLE . ' u, '; + $sql_sort_join = ($type == 'posts') ? ' AND u.user_id = p.poster_id ' : ' AND u.user_id = t.topic_poster '; + break; + + case 't': + $sql_sort_table = ($type == 'posts') ? TOPICS_TABLE . ' t, ' : ''; + $sql_sort_join = ($type == 'posts') ? ' AND t.topic_id = p.topic_id ' : ''; + break; + + case 'f': + $sql_sort_table = FORUMS_TABLE . ' f, '; + $sql_sort_join = ' AND f.forum_id = p.forum_id '; + break; + } + + if (!sizeof($m_approve_fid_ary)) + { + $m_approve_fid_sql = ' AND p.post_approved = 1'; + } + else if ($m_approve_fid_ary == array(-1)) + { + $m_approve_fid_sql = ''; + } + else + { + $m_approve_fid_sql = ' AND (p.post_approved = 1 OR ' . $db->sql_in_set('p.forum_id', $m_approve_fid_ary, true) . ')'; + } + + // Build the query for really selecting the post_ids + if ($type == 'posts') + { + $sql = "SELECT p.post_id + FROM " . $sql_sort_table . POSTS_TABLE . ' p' . (($firstpost_only) ? ', ' . TOPICS_TABLE . ' t ' : ' ') . " + WHERE $sql_author + $sql_topic_id + $sql_firstpost + $m_approve_fid_sql + $sql_fora + $sql_sort_join + $sql_time + ORDER BY $sql_sort"; + $field = 'post_id'; + } + else + { + $sql = "SELECT t.topic_id + FROM " . $sql_sort_table . TOPICS_TABLE . ' t, ' . POSTS_TABLE . " p + WHERE $sql_author + $sql_topic_id + $sql_firstpost + $m_approve_fid_sql + $sql_fora + AND t.topic_id = p.topic_id + $sql_sort_join + $sql_time + GROUP BY t.topic_id, $sort_by_sql[$sort_key] + ORDER BY $sql_sort"; + $field = 'topic_id'; + } + + // Only read one block of posts from the db and then cache it + $result = $db->sql_query_limit($sql, $config['search_block_size'], $start); + + while ($row = $db->sql_fetchrow($result)) + { + $id_ary[] = $row[$field]; + } + $db->sql_freeresult($result); + + // retrieve the total result count if needed + if (!$result_count) + { + $result_count = sizeof ($id_ary); + + if (!$result_count) + { + return false; + } + } + + if (sizeof($id_ary)) + { + $this->save_ids($search_key, '', $author_ary, $result_count, $id_ary, $start, $sort_dir); + $id_ary = array_slice($id_ary, 0, $per_page); + + return $result_count; + } + return false; + } + + /** + * Destroys cached search results, that contained one of the new words in a post so the results won't be outdated. + * + * @param string $mode contains the post mode: edit, post, reply, quote ... + */ + function index($mode, $post_id, &$message, &$subject, $poster_id, $forum_id) + { + global $db; + + // Split old and new post/subject to obtain array of words + $split_text = $this->split_message($message); + $split_title = ($subject) ? $this->split_message($subject) : array(); + + $words = array_unique(array_merge($split_text, $split_title)); + + unset($split_text); + unset($split_title); + + // destroy cached search results containing any of the words removed or added + $this->destroy_cache($words, array($poster_id)); + + unset($words); + } + + /** + * Destroy cached results, that might be outdated after deleting a post + */ + function index_remove($post_ids, $author_ids, $forum_ids) + { + $this->destroy_cache(array(), $author_ids); + } + + /** + * Destroy old cache entries + */ + function tidy() + { + global $db, $config; + + // destroy too old cached search results + $this->destroy_cache(array()); + + set_config('search_last_gc', time(), true); + } + + /** + * Create fulltext index + */ + function create_index($acp_module, $u_action) + { + global $db, $config; + + // Make sure we can actually use PostgreSQL with fulltext indexes + if ($error = $this->init()) + { + return $error; + } + + if (empty($this->stats)) + { + $this->get_stats(); + } + + if (!isset($this->stats['post_subject'])) + { + $db->sql_query("CREATE INDEX " . POSTS_TABLE . "_" . $config['fulltext_postgres_ts_name'] . "_post_subject ON " . POSTS_TABLE . " USING gin (to_tsvector ('" . $db->sql_escape($config['fulltext_postgres_ts_name']) . "', post_subject))"); + } + + if (!isset($this->stats['post_text'])) + { + $db->sql_query("CREATE INDEX " . POSTS_TABLE . "_" . $config['fulltext_postgres_ts_name'] . "_post_text ON " . POSTS_TABLE . " USING gin (to_tsvector ('" . $db->sql_escape($config['fulltext_postgres_ts_name']) . "', post_text))"); + } + + $db->sql_query('TRUNCATE TABLE ' . SEARCH_RESULTS_TABLE); + + return false; + } + + /** + * Drop fulltext index + */ + function delete_index($acp_module, $u_action) + { + global $db; + + // Make sure we can actually use PostgreSQL with fulltext indexes + if ($error = $this->init()) + { + return $error; + } + + if (empty($this->stats)) + { + $this->get_stats(); + } + + if (isset($this->stats['post_subject'])) + { + $db->sql_query('DROP INDEX ' . $this->stats['post_subject']['relname']); + } + + if (isset($this->stats['post_text'])) + { + $db->sql_query('DROP INDEX ' . $this->stats['post_text']['relname']); + } + + $db->sql_query('TRUNCATE TABLE ' . SEARCH_RESULTS_TABLE); + + return false; + } + + /** + * Returns true if both FULLTEXT indexes exist + */ + function index_created() + { + if (empty($this->stats)) + { + $this->get_stats(); + } + + return (isset($this->stats['post_text']) && isset($this->stats['post_subject'])) ? true : false; + } + + /** + * Returns an associative array containing information about the indexes + */ + function index_stats() + { + global $user; + + if (empty($this->stats)) + { + $this->get_stats(); + } + + return array( + $user->lang['FULLTEXT_POSTGRES_TOTAL_POSTS'] => ($this->index_created()) ? $this->stats['total_posts'] : 0, + ); + } + + function get_stats() + { + global $db, $config; + + $sql = "SELECT c2.relname, pg_catalog.pg_get_indexdef(i.indexrelid, 0, true) AS indexdef + FROM pg_catalog.pg_class c1, pg_catalog.pg_index i, pg_catalog.pg_class c2 + WHERE c1.relname = '" . POSTS_TABLE . "' + AND pg_catalog.pg_table_is_visible(c1.oid) + AND c1.oid = i.indrelid + AND i.indexrelid = c2.oid"; + $result = $db->sql_query($sql); + + while ($row = $db->sql_fetchrow($result)) + { + // deal with older PostgreSQL versions which didn't use Index_type + if (strpos($row['indexdef'], 'to_tsvector') !== false) + { + if ($row['relname'] == POSTS_TABLE . '_' . $config['fulltext_postgres_ts_name'] . '_post_text' || $row['relname'] == POSTS_TABLE . '_post_text') + { + $this->stats['post_text'] = $row; + } + else if ($row['relname'] == POSTS_TABLE . '_' . $config['fulltext_postgres_ts_name'] . '_post_subject' || $row['relname'] == POSTS_TABLE . '_post_subject') + { + $this->stats['post_subject'] = $row; + } + } + } + $db->sql_freeresult($result); + + $this->stats['total_posts'] = $config['num_posts']; + } + + /** + * Display a note, that UTF-8 support is not available with certain versions of PHP + */ + function acp() + { + global $user, $config, $db; + + $tpl = ' +
          +

          ' . $user->lang['FULLTEXT_POSTGRES_PCRE_EXPLAIN'] . '
          +
          ' . (($this->pcre_properties) ? $user->lang['YES'] : $user->lang['NO']) . ' (PHP ' . PHP_VERSION . ')
          +
          +
          +

          ' . $user->lang['FULLTEXT_POSTGRES_MBSTRING_EXPLAIN'] . '
          +
          ' . (($this->mbstring_regex) ? $user->lang['YES'] : $user->lang['NO']). '
          +
          +
          +

          ' . $user->lang['FULLTEXT_POSTGRES_TS_NAME_EXPLAIN'] . '
          +
          +
          +
          +

          ' . $user->lang['FULLTEXT_POSTGRES_MIN_WORD_LEN_EXPLAIN'] . '
          +
          +
          +
          +

          ' . $user->lang['FULLTEXT_POSTGRES_MAX_WORD_LEN_EXPLAIN'] . '
          +
          +
          + '; + + // These are fields required in the config table + return array( + 'tpl' => $tpl, + 'config' => array('fulltext_postgres_ts_name' => 'string', 'fulltext_postgres_min_word_len' => 'integer:0:255', 'fulltext_postgres_max_word_len' => 'integer:0:255') + ); + } +} + +?> diff --git a/phpBB/install/schemas/fulltext_postgres.sql b/phpBB/install/schemas/fulltext_postgres.sql new file mode 100644 index 0000000000..0be6648d0c --- /dev/null +++ b/phpBB/install/schemas/fulltext_postgres.sql @@ -0,0 +1,3 @@ +INSERT INTO phpbb_config (config_name, config_value) VALUES ('fulltext_postgres_max_word_len', '254'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('fulltext_postgres_min_word_len', '4'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('fulltext_postgres_ts_name', 'default'); diff --git a/phpBB/language/en/acp/search.php b/phpBB/language/en/acp/search.php index 3dc89570bf..5fa5acbe40 100644 --- a/phpBB/language/en/acp/search.php +++ b/phpBB/language/en/acp/search.php @@ -61,6 +61,20 @@ $lang = array_merge($lang, array( 'FULLTEXT_MYSQL_MIN_SEARCH_CHARS_EXPLAIN' => 'Words with at least this many characters will be indexed for searching. You or your host can only change this setting by changing the mysql configuration.', 'FULLTEXT_MYSQL_MAX_SEARCH_CHARS_EXPLAIN' => 'Words with no more than this many characters will be indexed for searching. You or your host can only change this setting by changing the mysql configuration.', + 'FULLTEXT_POSTGRES_INCOMPATIBLE_VERSION' => 'The PostgreSQL fulltext backend can only be used with PostgreSQL.', + 'FULLTEXT_POSTGRES_TS_NOT_FOUND' => 'The PostgreSQL fulltext backend can only be used with Tsearch2.', + 'FULLTEXT_POSTGRES_TOTAL_POSTS' => 'Total number of indexed posts', + 'FULLTEXT_POSTGRES_MBSTRING' => 'Support for non-latin UTF-8 characters using mbstring:', + 'FULLTEXT_POSTGRES_PCRE' => 'Support for non-latin UTF-8 characters using PCRE:', + 'FULLTEXT_POSTGRES_TS_NAME' => 'Tsearch2 Configuration Profile:', + 'FULLTEXT_POSTGRES_MIN_WORD_LEN' => 'Minimum word length for keywords', + 'FULLTEXT_POSTGRES_MAX_WORD_LEN' => 'Maximum word length for keywords', + 'FULLTEXT_POSTGRES_MBSTRING_EXPLAIN' => 'If PCRE does not have unicode character properties, the search backend will try to use mbstring’s regular expression engine.', + 'FULLTEXT_POSTGRES_PCRE_EXPLAIN' => 'This search backend requires PCRE unicode character properties, only available in PHP 4.4, 5.1 and above, if you want to search for non-latin characters.', + 'FULLTEXT_POSTGRES_TS_NAME_EXPLAIN' => 'The Tsearch2 configuration profile used to determine the parser and dictionary.', + 'FULLTEXT_POSTGRES_MIN_WORD_LEN_EXPLAIN' => 'Words with at least this many characters will be included in the query to the database.', + 'FULLTEXT_POSTGRES_MAX_WORD_LEN_EXPLAIN' => 'Words with no more than this many characters will be included in the query to the database.', + 'GENERAL_SEARCH_SETTINGS' => 'General search settings', 'GO_TO_SEARCH_INDEX' => 'Go to search index page', From fa470c3792b1030c48f6eaa8216a2bcbb975cb11 Mon Sep 17 00:00:00 2001 From: wagnerch Date: Tue, 7 Aug 2007 03:52:00 +0000 Subject: [PATCH 249/441] [feature/postgresql-fulltext-search] PostgreSQL fulltext search, version 2. PHPBB3-9730 --- phpBB/includes/search/fulltext_postgres.php | 76 +++++++-------------- 1 file changed, 24 insertions(+), 52 deletions(-) diff --git a/phpBB/includes/search/fulltext_postgres.php b/phpBB/includes/search/fulltext_postgres.php index 5f70ec2b24..0de456c2cd 100644 --- a/phpBB/includes/search/fulltext_postgres.php +++ b/phpBB/includes/search/fulltext_postgres.php @@ -35,7 +35,6 @@ class fulltext_postgres extends search_backend var $common_words = array(); var $pcre_properties = false; var $mbstring_regex = false; - var $tsearch_builtin = false; function fulltext_postgres(&$error) { @@ -59,16 +58,7 @@ class fulltext_postgres extends search_backend if ($db->sql_layer == 'postgres') { - $pgsql_version = explode('.', substr($db->sql_server_info(), 10)); - if ($pgsql_version[0] >= 8 && $pgsql_version[1] >= 3) - { - $this->tsearch_builtin = true; - } - - - if (!$this->tsearch_builtin) { - $db->sql_query("SELECT set_curcfg('" . $db->sql_escape($config['fulltext_postgres_ts_name']) . "')"); - } + $db->sql_query("SELECT set_curcfg('" . $db->sql_escape($config['fulltext_postgres_ts_name']) . "')"); } $error = false; @@ -86,20 +76,18 @@ class fulltext_postgres extends search_backend return $user->lang['FULLTEXT_POSTGRES_INCOMPATIBLE_VERSION']; } - if (!$this->tsearch_builtin) { - $sql = "SELECT c.relname - FROM pg_catalog.pg_class c - WHERE c.relkind = 'r' - AND c.relname = 'pg_ts_cfg' - AND pg_catalog.pg_table_is_visible(c.oid)"; - $result = $db->sql_query($sql); - $row = $db->sql_fetchrow($result); - $db->sql_freeresult($result); + $sql = "SELECT c.relname + FROM pg_catalog.pg_class c + WHERE c.relkind = 'r' + AND c.relname = 'pg_ts_cfg' + AND pg_catalog.pg_table_is_visible(c.oid)"; + $result = $db->sql_query($sql); + $row = $db->sql_fetchrow($result); + $db->sql_freeresult($result); - if (empty ($row['relname'])) - { - return $user->lang['FULLTEXT_POSTGRES_TS_NOT_FOUND']; - } + if (empty ($row['relname'])) + { + return $user->lang['FULLTEXT_POSTGRES_TS_NOT_FOUND']; } return false; @@ -126,7 +114,7 @@ class fulltext_postgres extends search_backend } // Filter out as above - $split_keywords = preg_replace("#[\"\n\r\t]+#", ' ', trim(htmlspecialchars_decode($keywords))); + $split_keywords = preg_replace("#[\n\r\t]+#", ' ', trim(htmlspecialchars_decode($keywords))); // Split words if ($this->pcre_properties) @@ -458,14 +446,7 @@ class fulltext_postgres extends search_backend $tmp_sql_match = array(); foreach (explode(',', $sql_match) as $sql_match_column) { - if ($this->tsearch_builtin) - { - $tmp_sql_match[] = "to_tsvector ('" . $db->sql_escape($config['fulltext_postgres_ts_name']) . "', " . $sql_match_column . ") @@ to_tsquery ('" . $db->sql_escape($config['fulltext_postgres_ts_name']) . "', '" . $db->sql_escape($this->tsearch_query) . "')"; - } - else - { - $tmp_sql_match[] = "to_tsvector (" . $sql_match_column . ") @@ to_tsquery ('" . $db->sql_escape($this->tsearch_query) . "')"; - } + $tmp_sql_match[] = "to_tsvector (" . $sql_match_column . ") @@ to_tsquery ('" . $db->sql_escape($this->tsearch_query) . "')"; } $sql = "SELECT $sql_select @@ -616,7 +597,7 @@ class fulltext_postgres extends search_backend AND t.topic_id = p.topic_id $sql_sort_join $sql_time - GROUP BY t.topic_id, $sort_by_sql[$sort_key] + GROUP BY t.topic_id ORDER BY $sql_sort"; $field = 'topic_id'; } @@ -701,7 +682,7 @@ class fulltext_postgres extends search_backend */ function create_index($acp_module, $u_action) { - global $db, $config; + global $db; // Make sure we can actually use PostgreSQL with fulltext indexes if ($error = $this->init()) @@ -716,12 +697,12 @@ class fulltext_postgres extends search_backend if (!isset($this->stats['post_subject'])) { - $db->sql_query("CREATE INDEX " . POSTS_TABLE . "_" . $config['fulltext_postgres_ts_name'] . "_post_subject ON " . POSTS_TABLE . " USING gin (to_tsvector ('" . $db->sql_escape($config['fulltext_postgres_ts_name']) . "', post_subject))"); + $db->sql_query('CREATE INDEX ' . POSTS_TABLE . '_post_subject ON ' . POSTS_TABLE . ' USING gist (to_tsvector (post_subject))'); } if (!isset($this->stats['post_text'])) { - $db->sql_query("CREATE INDEX " . POSTS_TABLE . "_" . $config['fulltext_postgres_ts_name'] . "_post_text ON " . POSTS_TABLE . " USING gin (to_tsvector ('" . $db->sql_escape($config['fulltext_postgres_ts_name']) . "', post_text))"); + $db->sql_query('CREATE INDEX ' . POSTS_TABLE . '_post_text ON ' . POSTS_TABLE . ' USING gist (to_tsvector (post_text))'); } $db->sql_query('TRUNCATE TABLE ' . SEARCH_RESULTS_TABLE); @@ -749,12 +730,12 @@ class fulltext_postgres extends search_backend if (isset($this->stats['post_subject'])) { - $db->sql_query('DROP INDEX ' . $this->stats['post_subject']['relname']); + $db->sql_query('DROP INDEX ' . POSTS_TABLE . '_post_subject'); } if (isset($this->stats['post_text'])) { - $db->sql_query('DROP INDEX ' . $this->stats['post_text']['relname']); + $db->sql_query('DROP INDEX ' . POSTS_TABLE . '_post_text'); } $db->sql_query('TRUNCATE TABLE ' . SEARCH_RESULTS_TABLE); @@ -809,11 +790,11 @@ class fulltext_postgres extends search_backend // deal with older PostgreSQL versions which didn't use Index_type if (strpos($row['indexdef'], 'to_tsvector') !== false) { - if ($row['relname'] == POSTS_TABLE . '_' . $config['fulltext_postgres_ts_name'] . '_post_text' || $row['relname'] == POSTS_TABLE . '_post_text') + if ($row['relname'] == POSTS_TABLE . '_post_text') { $this->stats['post_text'] = $row; } - else if ($row['relname'] == POSTS_TABLE . '_' . $config['fulltext_postgres_ts_name'] . '_post_subject' || $row['relname'] == POSTS_TABLE . '_post_subject') + else if ($row['relname'] == POSTS_TABLE . '_post_subject') { $this->stats['post_subject'] = $row; } @@ -846,17 +827,8 @@ class fulltext_postgres extends search_backend if ($db->sql_layer == 'postgres') { - if ($this->tsearch_builtin) - { - $sql = 'SELECT cfgname AS ts_name - FROM pg_ts_config'; - } - else - { - $sql = 'SELECT * - FROM pg_ts_cfg'; - } - + $sql = 'SELECT * + FROM pg_ts_cfg'; $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) From 07e946c1893751e9a9ede5297ed85df0f43cad1c Mon Sep 17 00:00:00 2001 From: we3b Date: Wed, 10 Feb 2010 10:31:00 +0000 Subject: [PATCH 250/441] [feature/postgresql-fulltext-search] PostgreSQL fulltext search, version 3. PHPBB3-9730 --- phpBB/includes/search/fulltext_postgres.php | 163 ++++++++++++++------ 1 file changed, 114 insertions(+), 49 deletions(-) diff --git a/phpBB/includes/search/fulltext_postgres.php b/phpBB/includes/search/fulltext_postgres.php index 0de456c2cd..64ff923692 100644 --- a/phpBB/includes/search/fulltext_postgres.php +++ b/phpBB/includes/search/fulltext_postgres.php @@ -2,7 +2,7 @@ /** * * @package search -* @version $Id: fulltext_postgres.php,v 1.47 2007/06/09 11:08:57 acydburn Exp $ +* @version $Id: fulltext_postgres.php,v 1.49 2010/02/12 10:10:36 frantic Exp $ * @copyright (c) 2005 phpBB Group * @license http://opensource.org/licenses/gpl-license.php GNU Public License * @@ -35,6 +35,7 @@ class fulltext_postgres extends search_backend var $common_words = array(); var $pcre_properties = false; var $mbstring_regex = false; + var $tsearch_builtin = false; function fulltext_postgres(&$error) { @@ -58,7 +59,16 @@ class fulltext_postgres extends search_backend if ($db->sql_layer == 'postgres') { - $db->sql_query("SELECT set_curcfg('" . $db->sql_escape($config['fulltext_postgres_ts_name']) . "')"); + $pgsql_version = explode('.', substr($db->sql_server_info(), 10)); + if ($pgsql_version[0] >= 8 && $pgsql_version[1] >= 3) + { + $this->tsearch_builtin = true; + } + + + if (!$this->tsearch_builtin) { + $db->sql_query("SELECT set_curcfg('" . $db->sql_escape($config['fulltext_postgres_ts_name']) . "')"); + } } $error = false; @@ -76,18 +86,20 @@ class fulltext_postgres extends search_backend return $user->lang['FULLTEXT_POSTGRES_INCOMPATIBLE_VERSION']; } - $sql = "SELECT c.relname - FROM pg_catalog.pg_class c - WHERE c.relkind = 'r' - AND c.relname = 'pg_ts_cfg' - AND pg_catalog.pg_table_is_visible(c.oid)"; - $result = $db->sql_query($sql); - $row = $db->sql_fetchrow($result); - $db->sql_freeresult($result); + if (!$this->tsearch_builtin) { + $sql = "SELECT c.relname + FROM pg_catalog.pg_class c + WHERE c.relkind = 'r' + AND c.relname = 'pg_ts_cfg' + AND pg_catalog.pg_table_is_visible(c.oid)"; + $result = $db->sql_query($sql); + $row = $db->sql_fetchrow($result); + $db->sql_freeresult($result); - if (empty ($row['relname'])) - { - return $user->lang['FULLTEXT_POSTGRES_TS_NOT_FOUND']; + if (empty ($row['relname'])) + { + return $user->lang['FULLTEXT_POSTGRES_TS_NOT_FOUND']; + } } return false; @@ -114,7 +126,7 @@ class fulltext_postgres extends search_backend } // Filter out as above - $split_keywords = preg_replace("#[\n\r\t]+#", ' ', trim(htmlspecialchars_decode($keywords))); + $split_keywords = preg_replace("#[\"\n\r\t]+#", ' ', trim(htmlspecialchars_decode($keywords))); // Split words if ($this->pcre_properties) @@ -317,16 +329,17 @@ class fulltext_postgres extends search_backend * Performs a search on keywords depending on display specific params. You have to run split_keywords() first. * * @param string $type contains either posts or topics depending on what should be searched for - * @param string &$fields contains either titleonly (topic titles should be searched), msgonly (only message bodies should be searched), firstpost (only subject and body of the first post should be searched) or all (all post bodies and subjects should be searched) - * @param string &$terms is either 'all' (use query as entered, words without prefix should default to "have to be in field") or 'any' (ignore search query parts and just return all posts that contain any of the specified words) - * @param array &$sort_by_sql contains SQL code for the ORDER BY part of a query - * @param string &$sort_key is the key of $sort_by_sql for the selected sorting - * @param string &$sort_dir is either a or d representing ASC and DESC - * @param string &$sort_days specifies the maximum amount of days a post may be old - * @param array &$ex_fid_ary specifies an array of forum ids which should not be searched - * @param array &$m_approve_fid_ary specifies an array of forum ids in which the searcher is allowed to view unapproved posts - * @param int &$topic_id is set to 0 or a topic id, if it is not 0 then only posts in this topic should be searched - * @param array &$author_ary an array of author ids if the author should be ignored during the search the array is empty + * @param string $fields contains either titleonly (topic titles should be searched), msgonly (only message bodies should be searched), firstpost (only subject and body of the first post should be searched) or all (all post bodies and subjects should be searched) + * @param string $terms is either 'all' (use query as entered, words without prefix should default to "have to be in field") or 'any' (ignore search query parts and just return all posts that contain any of the specified words) + * @param array $sort_by_sql contains SQL code for the ORDER BY part of a query + * @param string $sort_key is the key of $sort_by_sql for the selected sorting + * @param string $sort_dir is either a or d representing ASC and DESC + * @param string $sort_days specifies the maximum amount of days a post may be old + * @param array $ex_fid_ary specifies an array of forum ids which should not be searched + * @param array $m_approve_fid_ary specifies an array of forum ids in which the searcher is allowed to view unapproved posts + * @param int $topic_id is set to 0 or a topic id, if it is not 0 then only posts in this topic should be searched + * @param array $author_ary an array of author ids if the author should be ignored during the search the array is empty + * @param string $author_name specifies the author match, when ANONYMOUS is also a search-match * @param array &$id_ary passed by reference, to be filled with ids for the page specified by $start and $per_page, should be ordered * @param int $start indicates the first index of the page * @param int $per_page number of ids each page is supposed to contain @@ -334,7 +347,7 @@ class fulltext_postgres extends search_backend * * @access public */ - function keyword_search($type, &$fields, &$terms, &$sort_by_sql, &$sort_key, &$sort_dir, &$sort_days, &$ex_fid_ary, &$m_approve_fid_ary, &$topic_id, &$author_ary, &$id_ary, $start, $per_page) + function keyword_search($type, $fields, $terms, $sort_by_sql, $sort_key, $sort_dir, $sort_days, $ex_fid_ary, $m_approve_fid_ary, $topic_id, $author_ary, $author_name, &$id_ary, $start, $per_page) { global $config, $db; @@ -433,20 +446,41 @@ class fulltext_postgres extends search_backend $sql_from = ($join_topic) ? TOPICS_TABLE . ' t, ' : ''; $field = ($type == 'posts') ? 'post_id' : 'topic_id'; $sql_author = (sizeof($author_ary) == 1) ? ' = ' . $author_ary[0] : 'IN (' . implode(', ', $author_ary) . ')'; - + + if (sizeof($author_ary) && $author_name) + { + // first one matches post of registered users, second one guests and deleted users + $sql_author = '(' . $db->sql_in_set('p.poster_id', array_diff($author_ary, array(ANONYMOUS)), false, true) . ' OR p.post_username ' . $author_name . ')'; + } + else if (sizeof($author_ary)) + { + $sql_author = ' AND ' . $db->sql_in_set('p.poster_id', $author_ary); + } + else + { + $sql_author = ''; + } + $sql_where_options = $sql_sort_join; $sql_where_options .= ($topic_id) ? ' AND p.topic_id = ' . $topic_id : ''; $sql_where_options .= ($join_topic) ? ' AND t.topic_id = p.topic_id' : ''; $sql_where_options .= (sizeof($ex_fid_ary)) ? ' AND ' . $db->sql_in_set('p.forum_id', $ex_fid_ary, true) : ''; $sql_where_options .= $m_approve_fid_sql; - $sql_where_options .= (sizeof($author_ary)) ? ' AND p.poster_id ' . $sql_author : ''; + $sql_where_options .= $sql_author; $sql_where_options .= ($sort_days) ? ' AND p.post_time >= ' . (time() - ($sort_days * 86400)) : ''; $sql_where_options .= $sql_match_where; $tmp_sql_match = array(); foreach (explode(',', $sql_match) as $sql_match_column) { - $tmp_sql_match[] = "to_tsvector (" . $sql_match_column . ") @@ to_tsquery ('" . $db->sql_escape($this->tsearch_query) . "')"; + if ($this->tsearch_builtin) + { + $tmp_sql_match[] = "to_tsvector ('" . $db->sql_escape($config['fulltext_postgres_ts_name']) . "', " . $sql_match_column . ") @@ to_tsquery ('" . $db->sql_escape($config['fulltext_postgres_ts_name']) . "', '" . $db->sql_escape($this->tsearch_query) . "')"; + } + else + { + $tmp_sql_match[] = "to_tsvector (" . $sql_match_column . ") @@ to_tsquery ('" . $db->sql_escape($this->tsearch_query) . "')"; + } } $sql = "SELECT $sql_select @@ -490,12 +524,25 @@ class fulltext_postgres extends search_backend /** * Performs a search on an author's posts without caring about message contents. Depends on display specific params * - * @param array &$id_ary passed by reference, to be filled with ids for the page specified by $start and $per_page, should be ordered - * @param int $start indicates the first index of the page - * @param int $per_page number of ids each page is supposed to contain - * @return total number of results + * @param string $type contains either posts or topics depending on what should be searched for + * @param boolean $firstpost_only if true, only topic starting posts will be considered + * @param array $sort_by_sql contains SQL code for the ORDER BY part of a query + * @param string $sort_key is the key of $sort_by_sql for the selected sorting + * @param string $sort_dir is either a or d representing ASC and DESC + * @param string $sort_days specifies the maximum amount of days a post may be old + * @param array $ex_fid_ary specifies an array of forum ids which should not be searched + * @param array $m_approve_fid_ary specifies an array of forum ids in which the searcher is allowed to view unapproved posts + * @param int $topic_id is set to 0 or a topic id, if it is not 0 then only posts in this topic should be searched + * @param array $author_ary an array of author ids + * @param string $author_name specifies the author match, when ANONYMOUS is also a search-match + * @param array &$id_ary passed by reference, to be filled with ids for the page specified by $start and $per_page, should be ordered + * @param int $start indicates the first index of the page + * @param int $per_page number of ids each page is supposed to contain + * @return boolean|int total number of results + * + * @access public */ - function author_search($type, $firstpost_only, &$sort_by_sql, &$sort_key, &$sort_dir, &$sort_days, &$ex_fid_ary, &$m_approve_fid_ary, &$topic_id, &$author_ary, &$id_ary, $start, $per_page) + function author_search($type, $firstpost_only, $sort_by_sql, $sort_key, $sort_dir, $sort_days, $ex_fid_ary, $m_approve_fid_ary, $topic_id, $author_ary, $author_name, &$id_ary, $start, $per_page) { global $config, $db; @@ -517,7 +564,8 @@ class fulltext_postgres extends search_backend $topic_id, implode(',', $ex_fid_ary), implode(',', $m_approve_fid_ary), - implode(',', $author_ary) + implode(',', $author_ary), + $author_name, ))); // try reading the results from cache @@ -528,9 +576,17 @@ class fulltext_postgres extends search_backend } $id_ary = array(); - + // Create some display specific sql strings - $sql_author = $db->sql_in_set('p.poster_id', $author_ary); + if ($author_name) + { + // first one matches post of registered users, second one guests and deleted users + $sql_author = '(' . $db->sql_in_set('p.poster_id', array_diff($author_ary, array(ANONYMOUS)), false, true) . ' OR p.post_username ' . $author_name . ')'; + } + else + { + $sql_author = $db->sql_in_set('p.poster_id', $author_ary); + } $sql_fora = (sizeof($ex_fid_ary)) ? ' AND ' . $db->sql_in_set('p.forum_id', $ex_fid_ary, true) : ''; $sql_topic_id = ($topic_id) ? ' AND p.topic_id = ' . (int) $topic_id : ''; $sql_time = ($sort_days) ? ' AND p.post_time >= ' . (time() - ($sort_days * 86400)) : ''; @@ -547,8 +603,8 @@ class fulltext_postgres extends search_backend break; case 't': - $sql_sort_table = ($type == 'posts') ? TOPICS_TABLE . ' t, ' : ''; - $sql_sort_join = ($type == 'posts') ? ' AND t.topic_id = p.topic_id ' : ''; + $sql_sort_table = ($type == 'posts' && !$firstpost_only) ? TOPICS_TABLE . ' t, ' : ''; + $sql_sort_join = ($type == 'posts' && !$firstpost_only) ? ' AND t.topic_id = p.topic_id ' : ''; break; case 'f': @@ -569,7 +625,7 @@ class fulltext_postgres extends search_backend { $m_approve_fid_sql = ' AND (p.post_approved = 1 OR ' . $db->sql_in_set('p.forum_id', $m_approve_fid_ary, true) . ')'; } - + // Build the query for really selecting the post_ids if ($type == 'posts') { @@ -597,7 +653,7 @@ class fulltext_postgres extends search_backend AND t.topic_id = p.topic_id $sql_sort_join $sql_time - GROUP BY t.topic_id + GROUP BY t.topic_id, $sort_by_sql[$sort_key] ORDER BY $sql_sort"; $field = 'topic_id'; } @@ -682,7 +738,7 @@ class fulltext_postgres extends search_backend */ function create_index($acp_module, $u_action) { - global $db; + global $db, $config; // Make sure we can actually use PostgreSQL with fulltext indexes if ($error = $this->init()) @@ -697,12 +753,12 @@ class fulltext_postgres extends search_backend if (!isset($this->stats['post_subject'])) { - $db->sql_query('CREATE INDEX ' . POSTS_TABLE . '_post_subject ON ' . POSTS_TABLE . ' USING gist (to_tsvector (post_subject))'); + $db->sql_query("CREATE INDEX " . POSTS_TABLE . "_" . $config['fulltext_postgres_ts_name'] . "_post_subject ON " . POSTS_TABLE . " USING gin (to_tsvector ('" . $db->sql_escape($config['fulltext_postgres_ts_name']) . "', post_subject))"); } if (!isset($this->stats['post_text'])) { - $db->sql_query('CREATE INDEX ' . POSTS_TABLE . '_post_text ON ' . POSTS_TABLE . ' USING gist (to_tsvector (post_text))'); + $db->sql_query("CREATE INDEX " . POSTS_TABLE . "_" . $config['fulltext_postgres_ts_name'] . "_post_text ON " . POSTS_TABLE . " USING gin (to_tsvector ('" . $db->sql_escape($config['fulltext_postgres_ts_name']) . "', post_text))"); } $db->sql_query('TRUNCATE TABLE ' . SEARCH_RESULTS_TABLE); @@ -730,12 +786,12 @@ class fulltext_postgres extends search_backend if (isset($this->stats['post_subject'])) { - $db->sql_query('DROP INDEX ' . POSTS_TABLE . '_post_subject'); + $db->sql_query('DROP INDEX ' . $this->stats['post_subject']['relname']); } if (isset($this->stats['post_text'])) { - $db->sql_query('DROP INDEX ' . POSTS_TABLE . '_post_text'); + $db->sql_query('DROP INDEX ' . $this->stats['post_text']['relname']); } $db->sql_query('TRUNCATE TABLE ' . SEARCH_RESULTS_TABLE); @@ -790,11 +846,11 @@ class fulltext_postgres extends search_backend // deal with older PostgreSQL versions which didn't use Index_type if (strpos($row['indexdef'], 'to_tsvector') !== false) { - if ($row['relname'] == POSTS_TABLE . '_post_text') + if ($row['relname'] == POSTS_TABLE . '_' . $config['fulltext_postgres_ts_name'] . '_post_text' || $row['relname'] == POSTS_TABLE . '_post_text') { $this->stats['post_text'] = $row; } - else if ($row['relname'] == POSTS_TABLE . '_post_subject') + else if ($row['relname'] == POSTS_TABLE . '_' . $config['fulltext_postgres_ts_name'] . '_post_subject' || $row['relname'] == POSTS_TABLE . '_post_subject') { $this->stats['post_subject'] = $row; } @@ -827,8 +883,17 @@ class fulltext_postgres extends search_backend if ($db->sql_layer == 'postgres') { - $sql = 'SELECT * - FROM pg_ts_cfg'; + if ($this->tsearch_builtin) + { + $sql = 'SELECT cfgname AS ts_name + FROM pg_ts_config'; + } + else + { + $sql = 'SELECT * + FROM pg_ts_cfg'; + } + $result = $db->sql_query($sql); while ($row = $db->sql_fetchrow($result)) From ca974e2f2a3fc49564d0a595b2d55d04006b9ce5 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Mon, 11 Jun 2012 13:18:00 +0200 Subject: [PATCH 251/441] [ticket/10931] Add wrapper class for ini_get function. Provides easier handling of the different interpretations of ini values. PHPBB3-10931 --- phpBB/includes/php/ini.php | 165 +++++++++++++++++++++++++++++++++++++ 1 file changed, 165 insertions(+) create mode 100644 phpBB/includes/php/ini.php diff --git a/phpBB/includes/php/ini.php b/phpBB/includes/php/ini.php new file mode 100644 index 0000000000..5c2cadb052 --- /dev/null +++ b/phpBB/includes/php/ini.php @@ -0,0 +1,165 @@ +get($varname); + + if ($value === false) + { + return false; + } + + return trim($value); + } + + /** + * Gets configuration option value as a boolean. + * Interprets the string value 'off' as false. + * + * @param string $varname The configuration option name. + * @return bool False if configuration option does not exist. + * False if configuration option is disabled. + * True otherwise. + */ + public function get_bool($varname) + { + $value = strtolower($this->get_string($varname)); + + if (empty($value) || $value == 'off') + { + return false; + } + + return true; + } + + /** + * Gets configuration option value as an integer. + * + * @param string $varname The configuration option name. + * @return bool|int False if configuration option does not exist, + * the configuration option value (integer) otherwise. + */ + public function get_int($varname) + { + $value = $this->get_string($varname); + + if (!is_numeric($value)) + { + return false; + } + + return (int) $value; + } + + /** + * Gets configuration option value as a float. + * + * @param string $varname The configuration option name. + * @return bool|float False if configuration option does not exist, + * the configuration option value (float) otherwise. + */ + public function get_float($varname) + { + $value = $this->get_string($varname); + + if (!is_numeric($value)) + { + return false; + } + + return (float) $value; + } + + /** + * Gets configuration option value in bytes. + * Converts strings like '128M' to bytes (integer or float). + * + * @param string $varname The configuration option name. + * @return bool|int|float False if configuration option does not exist, + * the configuration option value otherwise. + */ + public function get_bytes($varname) + { + $value = strtolower($this->get_string($varname)); + + if ($value === false) + { + return false; + } + + if (is_numeric($value)) + { + return $value; + } + else if (strlen($value) < 2) + { + return false; + } + + $value_numeric = (int) $value; + + switch ($value[strlen($value) - 1]) + { + case 'g': + $value_numeric *= 1024; + case 'm': + $value_numeric *= 1024; + case 'k': + $value_numeric *= 1024; + break; + + default: + // It's not already in bytes (and thus numeric) + // and does not carry a unit. + return false; + } + + return $value_numeric; + } +} From afd6f86892fbbbe06aa0b1295dba361fab29fd5f Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Mon, 11 Jun 2012 13:22:11 +0200 Subject: [PATCH 252/441] [ticket/10931] Unit tests for phpbb_php_ini class. PHPBB3-10931 --- tests/mock/phpbb_php_ini.php | 16 ++++++++ tests/wrapper/phpbb_php_ini_test.php | 58 ++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 tests/mock/phpbb_php_ini.php create mode 100644 tests/wrapper/phpbb_php_ini_test.php diff --git a/tests/mock/phpbb_php_ini.php b/tests/mock/phpbb_php_ini.php new file mode 100644 index 0000000000..249c1b014a --- /dev/null +++ b/tests/mock/phpbb_php_ini.php @@ -0,0 +1,16 @@ +php_ini = new phpbb_mock_phpbb_php_ini; + } + + public function test_get_string() + { + $this->assertEquals('phpbb', $this->php_ini->get_string(' phpbb ')); + } + + public function test_get_bool() + { + $this->assertEquals(true, $this->php_ini->get_bool('ON')); + $this->assertEquals(true, $this->php_ini->get_bool('on')); + $this->assertEquals(true, $this->php_ini->get_bool('1')); + + $this->assertEquals(false, $this->php_ini->get_bool('OFF')); + $this->assertEquals(false, $this->php_ini->get_bool('off')); + $this->assertEquals(false, $this->php_ini->get_bool('0')); + $this->assertEquals(false, $this->php_ini->get_bool('')); + } + + public function test_get_int() + { + $this->assertEquals(1234, $this->php_ini->get_int('1234')); + $this->assertEquals(false, $this->php_ini->get_int('phpBB')); + } + + public function test_get_float() + { + $this->assertEquals(1234.0, $this->php_ini->get_float('1234')); + $this->assertEquals(false, $this->php_ini->get_float('phpBB')); + } + + public function test_get_bytes() + { + $this->assertEquals(false, $this->php_ini->get_bytes('phpBB')); + $this->assertEquals(false, $this->php_ini->get_bytes('M')); + $this->assertEquals(32 * pow(2, 20), $this->php_ini->get_bytes('32M')); + $this->assertEquals(8 * pow(2, 30), $this->php_ini->get_bytes('8G')); + $this->assertEquals(1234, $this->php_ini->get_bytes('1234')); + } +} From 5bea6ed94658d3302dda54eceaeb326e6f888286 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Mon, 11 Jun 2012 13:40:14 +0200 Subject: [PATCH 253/441] [ticket/10931] Let us try ini_get() without error suppression. PHPBB3-10931 --- phpBB/includes/php/ini.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/includes/php/ini.php b/phpBB/includes/php/ini.php index 5c2cadb052..92965e7f94 100644 --- a/phpBB/includes/php/ini.php +++ b/phpBB/includes/php/ini.php @@ -34,7 +34,7 @@ class phpbb_php_ini */ public function get($varname) { - return @ini_get($varname); + return ini_get($varname); } /** From 63b2e364929c941d814f6ba493551d458076941a Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Mon, 11 Jun 2012 13:45:39 +0200 Subject: [PATCH 254/441] [ticket/10931] Correct method description of get_string(). PHPBB3-10931 --- phpBB/includes/php/ini.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/phpBB/includes/php/ini.php b/phpBB/includes/php/ini.php index 92965e7f94..3910700163 100644 --- a/phpBB/includes/php/ini.php +++ b/phpBB/includes/php/ini.php @@ -38,8 +38,7 @@ class phpbb_php_ini } /** - * Gets configuration option value as a string and performs various - * normalisation on the returned value. + * Gets the configuration option value as a trimmed string. * * @param string $varname The configuration option name. * @return bool|string False if configuration option does not exist, From 7501ea825af8d25309f81ed0159c45597086b78b Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Mon, 11 Jun 2012 13:53:17 +0200 Subject: [PATCH 255/441] [ticket/10931] Document that false is also returned if value is not well formed PHPBB3-10931 --- phpBB/includes/php/ini.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/phpBB/includes/php/ini.php b/phpBB/includes/php/ini.php index 3910700163..baafee5273 100644 --- a/phpBB/includes/php/ini.php +++ b/phpBB/includes/php/ini.php @@ -82,6 +82,7 @@ class phpbb_php_ini * * @param string $varname The configuration option name. * @return bool|int False if configuration option does not exist, + * false if configuration option value is not numeric, * the configuration option value (integer) otherwise. */ public function get_int($varname) @@ -101,6 +102,7 @@ class phpbb_php_ini * * @param string $varname The configuration option name. * @return bool|float False if configuration option does not exist, + * false if configuration option value is not numeric, * the configuration option value (float) otherwise. */ public function get_float($varname) @@ -121,6 +123,7 @@ class phpbb_php_ini * * @param string $varname The configuration option name. * @return bool|int|float False if configuration option does not exist, + * false if configuration option value is not well-formed, * the configuration option value otherwise. */ public function get_bytes($varname) From 5086366662d78d79bb6daf4b132709d9273c2f8c Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Mon, 11 Jun 2012 14:18:21 +0200 Subject: [PATCH 256/441] [ticket/10931] Make it clear that we are mocking the ini_get() function. PHPBB3-10931 --- .../phpbb_php_ini.php => wrapper/phpbb_php_ini_fake.php} | 2 +- tests/wrapper/phpbb_php_ini_test.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) rename tests/{mock/phpbb_php_ini.php => wrapper/phpbb_php_ini_fake.php} (79%) diff --git a/tests/mock/phpbb_php_ini.php b/tests/wrapper/phpbb_php_ini_fake.php similarity index 79% rename from tests/mock/phpbb_php_ini.php rename to tests/wrapper/phpbb_php_ini_fake.php index 249c1b014a..14ec77c644 100644 --- a/tests/mock/phpbb_php_ini.php +++ b/tests/wrapper/phpbb_php_ini_fake.php @@ -7,7 +7,7 @@ * */ -class phpbb_mock_phpbb_php_ini extends phpbb_php_ini +class phpbb_php_ini_fake extends phpbb_php_ini { function get($varname) { diff --git a/tests/wrapper/phpbb_php_ini_test.php b/tests/wrapper/phpbb_php_ini_test.php index 164966fba4..5494f1864d 100644 --- a/tests/wrapper/phpbb_php_ini_test.php +++ b/tests/wrapper/phpbb_php_ini_test.php @@ -7,7 +7,7 @@ * */ -require_once dirname(__FILE__) . '/../mock/phpbb_php_ini.php'; +require_once dirname(__FILE__) . '/phpbb_php_ini_fake.php'; class phpbb_wrapper_phpbb_php_ini_test extends phpbb_test_case { @@ -15,7 +15,7 @@ class phpbb_wrapper_phpbb_php_ini_test extends phpbb_test_case public function setUp() { - $this->php_ini = new phpbb_mock_phpbb_php_ini; + $this->php_ini = new phpbb_php_ini_fake; } public function test_get_string() From 80dfa53ee3f04dfdba11efe9eb3f49d739bb602b Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Mon, 11 Jun 2012 14:24:30 +0200 Subject: [PATCH 257/441] [ticket/10931] Correctly use GNU GPL version 2. PHPBB3-10931 --- phpBB/includes/php/ini.php | 2 +- tests/wrapper/phpbb_php_ini_fake.php | 2 +- tests/wrapper/phpbb_php_ini_test.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/phpBB/includes/php/ini.php b/phpBB/includes/php/ini.php index baafee5273..882464275b 100644 --- a/phpBB/includes/php/ini.php +++ b/phpBB/includes/php/ini.php @@ -3,7 +3,7 @@ * * @package phpBB * @copyright (c) 2011 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/tests/wrapper/phpbb_php_ini_fake.php b/tests/wrapper/phpbb_php_ini_fake.php index 14ec77c644..49bc5936e5 100644 --- a/tests/wrapper/phpbb_php_ini_fake.php +++ b/tests/wrapper/phpbb_php_ini_fake.php @@ -3,7 +3,7 @@ * * @package testing * @copyright (c) 2011 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/tests/wrapper/phpbb_php_ini_test.php b/tests/wrapper/phpbb_php_ini_test.php index 5494f1864d..cdfee802f2 100644 --- a/tests/wrapper/phpbb_php_ini_test.php +++ b/tests/wrapper/phpbb_php_ini_test.php @@ -3,7 +3,7 @@ * * @package testing * @copyright (c) 2011 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ From fb279c9677641db5efa38f24c51db93df004cb46 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Mon, 11 Jun 2012 14:31:09 +0200 Subject: [PATCH 258/441] [ticket/10931] Also test lower case units in test_get_bytes(). PHPBB3-10931 --- tests/wrapper/phpbb_php_ini_test.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/wrapper/phpbb_php_ini_test.php b/tests/wrapper/phpbb_php_ini_test.php index cdfee802f2..cbb05e98e9 100644 --- a/tests/wrapper/phpbb_php_ini_test.php +++ b/tests/wrapper/phpbb_php_ini_test.php @@ -50,8 +50,9 @@ class phpbb_wrapper_phpbb_php_ini_test extends phpbb_test_case public function test_get_bytes() { $this->assertEquals(false, $this->php_ini->get_bytes('phpBB')); + $this->assertEquals(false, $this->php_ini->get_bytes('k')); $this->assertEquals(false, $this->php_ini->get_bytes('M')); - $this->assertEquals(32 * pow(2, 20), $this->php_ini->get_bytes('32M')); + $this->assertEquals(32 * pow(2, 20), $this->php_ini->get_bytes('32m')); $this->assertEquals(8 * pow(2, 30), $this->php_ini->get_bytes('8G')); $this->assertEquals(1234, $this->php_ini->get_bytes('1234')); } From 3872abd824c9371af6cbb45e6e9bbfcb31094f98 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Mon, 11 Jun 2012 14:35:18 +0200 Subject: [PATCH 259/441] [ticket/10931] Also test for negative values. PHPBB3-10931 --- tests/wrapper/phpbb_php_ini_test.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/wrapper/phpbb_php_ini_test.php b/tests/wrapper/phpbb_php_ini_test.php index cbb05e98e9..84e2b5e92e 100644 --- a/tests/wrapper/phpbb_php_ini_test.php +++ b/tests/wrapper/phpbb_php_ini_test.php @@ -38,12 +38,14 @@ class phpbb_wrapper_phpbb_php_ini_test extends phpbb_test_case public function test_get_int() { $this->assertEquals(1234, $this->php_ini->get_int('1234')); + $this->assertEquals(-12345, $this->php_ini->get_int('-12345')); $this->assertEquals(false, $this->php_ini->get_int('phpBB')); } public function test_get_float() { $this->assertEquals(1234.0, $this->php_ini->get_float('1234')); + $this->assertEquals(-12345.0, $this->php_ini->get_float('-12345')); $this->assertEquals(false, $this->php_ini->get_float('phpBB')); } @@ -51,9 +53,14 @@ class phpbb_wrapper_phpbb_php_ini_test extends phpbb_test_case { $this->assertEquals(false, $this->php_ini->get_bytes('phpBB')); $this->assertEquals(false, $this->php_ini->get_bytes('k')); + $this->assertEquals(false, $this->php_ini->get_bytes('-k')); $this->assertEquals(false, $this->php_ini->get_bytes('M')); + $this->assertEquals(false, $this->php_ini->get_bytes('-M')); $this->assertEquals(32 * pow(2, 20), $this->php_ini->get_bytes('32m')); + $this->assertEquals(- 32 * pow(2, 20), $this->php_ini->get_bytes('-32m')); $this->assertEquals(8 * pow(2, 30), $this->php_ini->get_bytes('8G')); + $this->assertEquals(- 8 * pow(2, 30), $this->php_ini->get_bytes('-8G')); $this->assertEquals(1234, $this->php_ini->get_bytes('1234')); + $this->assertEquals(-12345, $this->php_ini->get_bytes('-12345')); } } From 44287e57bf9536bd91933347ad64f289ef2a0391 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Mon, 11 Jun 2012 14:43:50 +0200 Subject: [PATCH 260/441] [ticket/10931] Use strict assertSame() instead of assertEquals(). PHPBB3-10931 --- tests/wrapper/phpbb_php_ini_test.php | 38 ++++++++++++++-------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/tests/wrapper/phpbb_php_ini_test.php b/tests/wrapper/phpbb_php_ini_test.php index 84e2b5e92e..5c312300d3 100644 --- a/tests/wrapper/phpbb_php_ini_test.php +++ b/tests/wrapper/phpbb_php_ini_test.php @@ -20,42 +20,42 @@ class phpbb_wrapper_phpbb_php_ini_test extends phpbb_test_case public function test_get_string() { - $this->assertEquals('phpbb', $this->php_ini->get_string(' phpbb ')); + $this->assertSame('phpbb', $this->php_ini->get_string(' phpbb ')); } public function test_get_bool() { - $this->assertEquals(true, $this->php_ini->get_bool('ON')); - $this->assertEquals(true, $this->php_ini->get_bool('on')); - $this->assertEquals(true, $this->php_ini->get_bool('1')); + $this->assertSame(true, $this->php_ini->get_bool('ON')); + $this->assertSame(true, $this->php_ini->get_bool('on')); + $this->assertSame(true, $this->php_ini->get_bool('1')); - $this->assertEquals(false, $this->php_ini->get_bool('OFF')); - $this->assertEquals(false, $this->php_ini->get_bool('off')); - $this->assertEquals(false, $this->php_ini->get_bool('0')); - $this->assertEquals(false, $this->php_ini->get_bool('')); + $this->assertSame(false, $this->php_ini->get_bool('OFF')); + $this->assertSame(false, $this->php_ini->get_bool('off')); + $this->assertSame(false, $this->php_ini->get_bool('0')); + $this->assertSame(false, $this->php_ini->get_bool('')); } public function test_get_int() { - $this->assertEquals(1234, $this->php_ini->get_int('1234')); - $this->assertEquals(-12345, $this->php_ini->get_int('-12345')); - $this->assertEquals(false, $this->php_ini->get_int('phpBB')); + $this->assertSame(1234, $this->php_ini->get_int('1234')); + $this->assertSame(-12345, $this->php_ini->get_int('-12345')); + $this->assertSame(false, $this->php_ini->get_int('phpBB')); } public function test_get_float() { - $this->assertEquals(1234.0, $this->php_ini->get_float('1234')); - $this->assertEquals(-12345.0, $this->php_ini->get_float('-12345')); - $this->assertEquals(false, $this->php_ini->get_float('phpBB')); + $this->assertSame(1234.0, $this->php_ini->get_float('1234')); + $this->assertSame(-12345.0, $this->php_ini->get_float('-12345')); + $this->assertSame(false, $this->php_ini->get_float('phpBB')); } public function test_get_bytes() { - $this->assertEquals(false, $this->php_ini->get_bytes('phpBB')); - $this->assertEquals(false, $this->php_ini->get_bytes('k')); - $this->assertEquals(false, $this->php_ini->get_bytes('-k')); - $this->assertEquals(false, $this->php_ini->get_bytes('M')); - $this->assertEquals(false, $this->php_ini->get_bytes('-M')); + $this->assertSame(false, $this->php_ini->get_bytes('phpBB')); + $this->assertSame(false, $this->php_ini->get_bytes('k')); + $this->assertSame(false, $this->php_ini->get_bytes('-k')); + $this->assertSame(false, $this->php_ini->get_bytes('M')); + $this->assertSame(false, $this->php_ini->get_bytes('-M')); $this->assertEquals(32 * pow(2, 20), $this->php_ini->get_bytes('32m')); $this->assertEquals(- 32 * pow(2, 20), $this->php_ini->get_bytes('-32m')); $this->assertEquals(8 * pow(2, 30), $this->php_ini->get_bytes('8G')); From e9348b172a5b0661b26a8f3a0fe3368568539edb Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Mon, 11 Jun 2012 15:06:52 +0200 Subject: [PATCH 261/441] [ticket/10931] Correctly handle inputs such as '-k' as invalid in get_bytes(). PHPBB3-10931 --- phpBB/includes/php/ini.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/phpBB/includes/php/ini.php b/phpBB/includes/php/ini.php index 882464275b..de1cb5096c 100644 --- a/phpBB/includes/php/ini.php +++ b/phpBB/includes/php/ini.php @@ -137,10 +137,17 @@ class phpbb_php_ini if (is_numeric($value)) { + // Already in bytes. return $value; } else if (strlen($value) < 2) { + // Single character. + return false; + } + else if (strlen($value) < 3 && $value[0] === '-') + { + // Two characters but the first one is a minus. return false; } From cffcef1e46f7502d679dcd489820e39bcf1f6709 Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Mon, 11 Jun 2012 15:08:50 +0200 Subject: [PATCH 262/441] [ticket/10932] Adding composer.phar to the repository to version it PHPBB3-10932 --- composer.phar | Bin 0 -> 499053 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100755 composer.phar diff --git a/composer.phar b/composer.phar new file mode 100755 index 0000000000000000000000000000000000000000..3572477546e40a03179dda19e93507477060dd3c GIT binary patch literal 499053 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

        • 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 literal 0 HcmV?d00001 From 09fb9a9efe048cef102471d1ce79cdeff932776a Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Mon, 11 Jun 2012 15:15:08 +0200 Subject: [PATCH 263/441] [ticket/10931] Make sure get_bytes() always returns either an int or a float. PHPBB3-10931 --- phpBB/includes/php/ini.php | 17 +++++++++++++-- tests/wrapper/phpbb_php_ini_test.php | 31 +++++++++++++++++++++------- 2 files changed, 39 insertions(+), 9 deletions(-) diff --git a/phpBB/includes/php/ini.php b/phpBB/includes/php/ini.php index de1cb5096c..bbe592a7df 100644 --- a/phpBB/includes/php/ini.php +++ b/phpBB/includes/php/ini.php @@ -138,7 +138,7 @@ class phpbb_php_ini if (is_numeric($value)) { // Already in bytes. - return $value; + return $this->to_numeric($value); } else if (strlen($value) < 2) { @@ -151,7 +151,7 @@ class phpbb_php_ini return false; } - $value_numeric = (int) $value; + $value_numeric = $this->to_numeric($value); switch ($value[strlen($value) - 1]) { @@ -171,4 +171,17 @@ class phpbb_php_ini return $value_numeric; } + + /** + * Casts a numeric string $input to an appropriate numeric type (i.e. integer or float) + * + * @param string $input A numeric string. + * + * @return int|float Integer $input if $input fits integer, + * float $input otherwise. + */ + protected function to_numeric($input) + { + return ($input > PHP_INT_MAX) ? (float) $input : (int) $input; + } } diff --git a/tests/wrapper/phpbb_php_ini_test.php b/tests/wrapper/phpbb_php_ini_test.php index 5c312300d3..4d8e583eb8 100644 --- a/tests/wrapper/phpbb_php_ini_test.php +++ b/tests/wrapper/phpbb_php_ini_test.php @@ -49,18 +49,35 @@ class phpbb_wrapper_phpbb_php_ini_test extends phpbb_test_case $this->assertSame(false, $this->php_ini->get_float('phpBB')); } - public function test_get_bytes() + public function test_get_bytes_invalid() { $this->assertSame(false, $this->php_ini->get_bytes('phpBB')); $this->assertSame(false, $this->php_ini->get_bytes('k')); $this->assertSame(false, $this->php_ini->get_bytes('-k')); $this->assertSame(false, $this->php_ini->get_bytes('M')); $this->assertSame(false, $this->php_ini->get_bytes('-M')); - $this->assertEquals(32 * pow(2, 20), $this->php_ini->get_bytes('32m')); - $this->assertEquals(- 32 * pow(2, 20), $this->php_ini->get_bytes('-32m')); - $this->assertEquals(8 * pow(2, 30), $this->php_ini->get_bytes('8G')); - $this->assertEquals(- 8 * pow(2, 30), $this->php_ini->get_bytes('-8G')); - $this->assertEquals(1234, $this->php_ini->get_bytes('1234')); - $this->assertEquals(-12345, $this->php_ini->get_bytes('-12345')); + } + + /** + * @dataProvider get_bytes_data + */ + public function test_get_bytes($expected, $value) + { + $actual = $this->php_ini->get_bytes($value); + + $this->assertTrue(is_float($actual) || is_int($actual)); + $this->assertEquals($expected, $actual); + } + + static public function get_bytes_data() + { + return array( + array(32 * pow(2, 20), '32m'), + array(- 32 * pow(2, 20), '-32m'), + array(8 * pow(2, 30), '8G'), + array(- 8 * pow(2, 30), '-8G'), + array(1234, '1234'), + array(-12345, '-12345'), + ); } } From 171d661765afaeb34213bfa8e049891e7661137c Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Mon, 11 Jun 2012 15:32:02 +0200 Subject: [PATCH 264/441] [ticket/10932] Use included composer.phar in build process PHPBB3-10932 --- build/build.xml | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/build/build.xml b/build/build.xml index bc65cd0b38..1b8d42a660 100644 --- a/build/build.xml +++ b/build/build.xml @@ -45,13 +45,7 @@ - - @@ -169,13 +163,7 @@ checkreturn="true" /> - - From cbff02db4f84c83c62bdd1f7450b8afbf39a5270 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Mon, 11 Jun 2012 15:22:55 +0200 Subject: [PATCH 265/441] [ticket/10931] Make to_numeric function globally available. PHPBB3-10931 --- phpBB/includes/functions.php | 13 +++++++++++++ phpBB/includes/php/ini.php | 17 ++--------------- tests/wrapper/phpbb_php_ini_test.php | 1 + 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index 95f2cf8d26..ad64471388 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -4987,3 +4987,16 @@ function phpbb_pcre_utf8_support() } return $utf8_pcre_properties; } + +/** +* Casts a numeric string $input to an appropriate numeric type (i.e. integer or float) +* +* @param string $input A numeric string. +* +* @return int|float Integer $input if $input fits integer, +* float $input otherwise. +*/ +function phpbb_to_numeric($input) +{ + return ($input > PHP_INT_MAX) ? (float) $input : (int) $input; +} diff --git a/phpBB/includes/php/ini.php b/phpBB/includes/php/ini.php index bbe592a7df..02c2b7ccc6 100644 --- a/phpBB/includes/php/ini.php +++ b/phpBB/includes/php/ini.php @@ -138,7 +138,7 @@ class phpbb_php_ini if (is_numeric($value)) { // Already in bytes. - return $this->to_numeric($value); + return phpbb_to_numeric($value); } else if (strlen($value) < 2) { @@ -151,7 +151,7 @@ class phpbb_php_ini return false; } - $value_numeric = $this->to_numeric($value); + $value_numeric = phpbb_to_numeric($value); switch ($value[strlen($value) - 1]) { @@ -171,17 +171,4 @@ class phpbb_php_ini return $value_numeric; } - - /** - * Casts a numeric string $input to an appropriate numeric type (i.e. integer or float) - * - * @param string $input A numeric string. - * - * @return int|float Integer $input if $input fits integer, - * float $input otherwise. - */ - protected function to_numeric($input) - { - return ($input > PHP_INT_MAX) ? (float) $input : (int) $input; - } } diff --git a/tests/wrapper/phpbb_php_ini_test.php b/tests/wrapper/phpbb_php_ini_test.php index 4d8e583eb8..418448f102 100644 --- a/tests/wrapper/phpbb_php_ini_test.php +++ b/tests/wrapper/phpbb_php_ini_test.php @@ -8,6 +8,7 @@ */ require_once dirname(__FILE__) . '/phpbb_php_ini_fake.php'; +require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; class phpbb_wrapper_phpbb_php_ini_test extends phpbb_test_case { From 72212077ebecee639c49c473646a38340908d058 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Mon, 11 Jun 2012 15:31:25 +0200 Subject: [PATCH 266/441] [ticket/10931] Also test get_bytes() and get_string() with false. PHPBB3-10931 --- tests/wrapper/phpbb_php_ini_test.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/wrapper/phpbb_php_ini_test.php b/tests/wrapper/phpbb_php_ini_test.php index 418448f102..8e08d5c204 100644 --- a/tests/wrapper/phpbb_php_ini_test.php +++ b/tests/wrapper/phpbb_php_ini_test.php @@ -21,6 +21,7 @@ class phpbb_wrapper_phpbb_php_ini_test extends phpbb_test_case public function test_get_string() { + $this->assertSame(false, $this->php_ini->get_string(false)); $this->assertSame('phpbb', $this->php_ini->get_string(' phpbb ')); } @@ -52,6 +53,7 @@ class phpbb_wrapper_phpbb_php_ini_test extends phpbb_test_case public function test_get_bytes_invalid() { + $this->assertSame(false, $this->php_ini->get_bytes(false)); $this->assertSame(false, $this->php_ini->get_bytes('phpBB')); $this->assertSame(false, $this->php_ini->get_bytes('k')); $this->assertSame(false, $this->php_ini->get_bytes('-k')); From 4468847107103c44936468e6e3c1badeb333ff52 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Mon, 11 Jun 2012 15:45:30 +0200 Subject: [PATCH 267/441] [ticket/10931] Apply strtolower() correctly, i.e. not on false. PHPBB3-10931 --- phpBB/includes/php/ini.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/phpBB/includes/php/ini.php b/phpBB/includes/php/ini.php index 02c2b7ccc6..17e8c54a57 100644 --- a/phpBB/includes/php/ini.php +++ b/phpBB/includes/php/ini.php @@ -67,9 +67,9 @@ class phpbb_php_ini */ public function get_bool($varname) { - $value = strtolower($this->get_string($varname)); + $value = $this->get_string($varname); - if (empty($value) || $value == 'off') + if (empty($value) || strtolower($value) == 'off') { return false; } @@ -128,7 +128,7 @@ class phpbb_php_ini */ public function get_bytes($varname) { - $value = strtolower($this->get_string($varname)); + $value = $this->get_string($varname); if ($value === false) { @@ -151,9 +151,10 @@ class phpbb_php_ini return false; } + $value_lower = strtolower($value); $value_numeric = phpbb_to_numeric($value); - switch ($value[strlen($value) - 1]) + switch ($value_lower[strlen($value_lower) - 1]) { case 'g': $value_numeric *= 1024; From 241033ae88fdaa4aa45da0ee70b94f636e6d0360 Mon Sep 17 00:00:00 2001 From: Oleg Pudeyev Date: Mon, 11 Jun 2012 18:50:05 -0400 Subject: [PATCH 268/441] [ticket/10882] Fix test name - oops. PHPBB3-10882 --- tests/template/invalid_constructs_test.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/template/invalid_constructs_test.php b/tests/template/invalid_constructs_test.php index 2430b5b9b1..19d192b8b6 100644 --- a/tests/template/invalid_constructs_test.php +++ b/tests/template/invalid_constructs_test.php @@ -9,7 +9,7 @@ require_once dirname(__FILE__) . '/template_test_case.php'; -class phpbb_template_template_test extends phpbb_template_template_test_case +class phpbb_template_invalid_constructs_test extends phpbb_template_template_test_case { public function template_data() { From 33b72ec62bd8b6e6c890e4c474d28389f048632a Mon Sep 17 00:00:00 2001 From: Vjacheslav Trushkin Date: Mon, 2 Apr 2012 11:45:26 +0300 Subject: [PATCH 269/441] [ticket/10743] Changing obtain_cfg_items Changing obtain_cfg_items to work only with style because other components no longer exist PHPBB3-10743 --- phpBB/includes/cache/service.php | 63 +++++++++++++------------------- phpBB/includes/user.php | 3 -- 2 files changed, 26 insertions(+), 40 deletions(-) diff --git a/phpBB/includes/cache/service.php b/phpBB/includes/cache/service.php index aa225ade69..37f32aa753 100644 --- a/phpBB/includes/cache/service.php +++ b/phpBB/includes/cache/service.php @@ -321,50 +321,39 @@ class phpbb_cache_service /** * Obtain cfg file data */ - function obtain_cfg_items($theme) + function obtain_cfg_items($style) { global $config, $phpbb_root_path; - $parsed_items = array( - 'theme' => array(), - 'template' => array(), - 'imageset' => array() - ); + $parsed_array = $this->driver->get('_cfg_' . $style['style_path']); - foreach ($parsed_items as $key => $parsed_array) + if ($parsed_array === false) { - $parsed_array = $this->driver->get('_cfg_' . $key . '_' . $theme[$key . '_path']); - - if ($parsed_array === false) - { - $parsed_array = array(); - } - - $reparse = false; - $filename = $phpbb_root_path . 'styles/' . $theme[$key . '_path'] . '/' . $key . '/' . $key . '.cfg'; - - if (!file_exists($filename)) - { - continue; - } - - if (!isset($parsed_array['filetime']) || (($config['load_tplcompile'] && @filemtime($filename) > $parsed_array['filetime']))) - { - $reparse = true; - } - - // Re-parse cfg file - if ($reparse) - { - $parsed_array = parse_cfg_file($filename); - $parsed_array['filetime'] = @filemtime($filename); - - $this->driver->put('_cfg_' . $key . '_' . $theme[$key . '_path'], $parsed_array); - } - $parsed_items[$key] = $parsed_array; + $parsed_array = array(); } - return $parsed_items; + $reparse = false; + $filename = $phpbb_root_path . 'styles/' . $style['style_path'] . '/style.cfg'; + + if (!file_exists($filename)) + { + continue; + } + + if (!isset($parsed_array['filetime']) || (($config['load_tplcompile'] && @filemtime($filename) > $parsed_array['filetime']))) + { + $reparse = true; + } + + // Re-parse cfg file + if ($reparse) + { + $parsed_array = parse_cfg_file($filename); + $parsed_array['filetime'] = @filemtime($filename); + + $this->driver->put('_cfg_' . $style['style_path'], $parsed_array); + } + return $parsed_array; } /** diff --git a/phpBB/includes/user.php b/phpBB/includes/user.php index ce9c804f23..1db2364f76 100644 --- a/phpBB/includes/user.php +++ b/phpBB/includes/user.php @@ -188,9 +188,6 @@ class phpbb_user extends phpbb_session // Now parse the cfg file and cache it $parsed_items = $cache->obtain_cfg_items($this->theme); - // We are only interested in the theme configuration for now - $parsed_items = $parsed_items['theme']; - $check_for = array( 'pagination_sep' => (string) ', ' ); From 71ca9b4fe69dea8150a5d3c6f30dd177c488ff2b Mon Sep 17 00:00:00 2001 From: Vjacheslav Trushkin Date: Mon, 2 Apr 2012 11:50:13 +0300 Subject: [PATCH 270/441] [ticket/10743] Renaming user->theme Renaming user->theme to user->style PHPBB3-10743 --- phpBB/includes/bbcode.php | 2 +- phpBB/includes/functions.php | 18 +++++++++--------- phpBB/includes/style/style.php | 4 ++-- phpBB/includes/user.php | 18 +++++++++--------- 4 files changed, 21 insertions(+), 21 deletions(-) diff --git a/phpBB/includes/bbcode.php b/phpBB/includes/bbcode.php index fde917e5b1..444446e9c3 100644 --- a/phpBB/includes/bbcode.php +++ b/phpBB/includes/bbcode.php @@ -130,7 +130,7 @@ class bbcode if (empty($this->template_filename)) { - $this->template_bitfield = new bitfield($user->theme['bbcode_bitfield']); + $this->template_bitfield = new bitfield($user->style['bbcode_bitfield']); $style_resource_locator = new phpbb_style_resource_locator(); $style_path_provider = new phpbb_style_extension_path_provider($phpbb_extension_manager, new phpbb_style_path_provider()); diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index ad64471388..ddbe1c2c36 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -4772,9 +4772,9 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0 'T_ASSETS_VERSION' => $config['assets_version'], 'T_ASSETS_PATH' => "{$web_path}assets", - 'T_THEME_PATH' => "{$web_path}styles/" . rawurlencode($user->theme['style_path']) . '/theme', - 'T_TEMPLATE_PATH' => "{$web_path}styles/" . rawurlencode($user->theme['style_path']) . '/template', - 'T_SUPER_TEMPLATE_PATH' => "{$web_path}styles/" . rawurlencode($user->theme['style_path']) . '/template', + 'T_THEME_PATH' => "{$web_path}styles/" . rawurlencode($user->style['style_path']) . '/theme', + 'T_TEMPLATE_PATH' => "{$web_path}styles/" . rawurlencode($user->style['style_path']) . '/template', + 'T_SUPER_TEMPLATE_PATH' => "{$web_path}styles/" . rawurlencode($user->style['style_path']) . '/template', 'T_IMAGES_PATH' => "{$web_path}images/", 'T_SMILIES_PATH' => "{$web_path}{$config['smilies_path']}/", 'T_AVATAR_PATH' => "{$web_path}{$config['avatar_path']}/", @@ -4782,16 +4782,16 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0 'T_ICONS_PATH' => "{$web_path}{$config['icons_path']}/", 'T_RANKS_PATH' => "{$web_path}{$config['ranks_path']}/", 'T_UPLOAD_PATH' => "{$web_path}{$config['upload_path']}/", - 'T_STYLESHEET_LINK' => "{$web_path}styles/" . rawurlencode($user->theme['style_path']) . '/theme/stylesheet.css?assets_version=' . $config['assets_version'], - 'T_STYLESHEET_LANG_LINK' => "{$web_path}styles/" . rawurlencode($user->theme['style_path']) . '/theme/' . $user->lang_name . '/stylesheet.css?assets_version=' . $config['assets_version'], - 'T_STYLESHEET_NAME' => $user->theme['style_name'], + 'T_STYLESHEET_LINK' => "{$web_path}styles/" . rawurlencode($user->style['style_path']) . '/theme/stylesheet.css?assets_version=' . $config['assets_version'], + 'T_STYLESHEET_LANG_LINK' => "{$web_path}styles/" . rawurlencode($user->style['style_path']) . '/theme/' . $user->lang_name . '/stylesheet.css?assets_version=' . $config['assets_version'], + 'T_STYLESHEET_NAME' => $user->style['style_name'], 'T_JQUERY_LINK' => ($config['load_jquery_cdn'] && !empty($config['load_jquery_url'])) ? $config['load_jquery_url'] : "{$web_path}assets/javascript/jquery.js?assets_version=" . $config['assets_version'], 'S_JQUERY_FALLBACK' => ($config['load_jquery_cdn']) ? true : false, - 'T_THEME_NAME' => rawurlencode($user->theme['style_path']), + 'T_THEME_NAME' => rawurlencode($user->style['style_path']), 'T_THEME_LANG_NAME' => $user->data['user_lang'], - 'T_TEMPLATE_NAME' => $user->theme['style_path'], - 'T_SUPER_TEMPLATE_NAME' => rawurlencode((isset($user->theme['style_parent_tree']) && $user->theme['style_parent_tree']) ? $user->theme['style_parent_tree'] : $user->theme['style_path']), + 'T_TEMPLATE_NAME' => $user->style['style_path'], + 'T_SUPER_TEMPLATE_NAME' => rawurlencode((isset($user->style['style_parent_tree']) && $user->style['style_parent_tree']) ? $user->style['style_parent_tree'] : $user->style['style_path']), 'T_IMAGES' => 'images', 'T_SMILIES' => $config['smilies_path'], 'T_AVATAR' => $config['avatar_path'], diff --git a/phpBB/includes/style/style.php b/phpBB/includes/style/style.php index 3f470015f6..8d38deb85c 100644 --- a/phpBB/includes/style/style.php +++ b/phpBB/includes/style/style.php @@ -89,8 +89,8 @@ class phpbb_style */ public function set_style() { - $style_name = $this->user->theme['style_path']; - $style_dirs = ($this->user->theme['style_parent_id']) ? array_reverse(explode('/', $this->user->theme['style_parent_tree'])) : array(); + $style_name = $this->user->style['style_path']; + $style_dirs = ($this->user->style['style_parent_id']) ? array_reverse(explode('/', $this->user->style['style_parent_tree'])) : array(); $paths = array($this->get_style_path($style_name)); foreach ($style_dirs as $dir) { diff --git a/phpBB/includes/user.php b/phpBB/includes/user.php index 1db2364f76..cf9e6b9994 100644 --- a/phpBB/includes/user.php +++ b/phpBB/includes/user.php @@ -27,7 +27,7 @@ class phpbb_user extends phpbb_session { var $lang = array(); var $help = array(); - var $theme = array(); + var $style = array(); var $date_format; var $timezone; var $dst; @@ -159,11 +159,11 @@ class phpbb_user extends phpbb_session FROM ' . STYLES_TABLE . " s WHERE s.style_id = $style_id"; $result = $db->sql_query($sql, 3600); - $this->theme = $db->sql_fetchrow($result); + $this->style = $db->sql_fetchrow($result); $db->sql_freeresult($result); // User has wrong style - if (!$this->theme && $style_id == $this->data['user_style']) + if (!$this->style && $style_id == $this->data['user_style']) { $style_id = $this->data['user_style'] = $config['default_style']; @@ -176,17 +176,17 @@ class phpbb_user extends phpbb_session FROM ' . STYLES_TABLE . " s WHERE s.style_id = $style_id"; $result = $db->sql_query($sql, 3600); - $this->theme = $db->sql_fetchrow($result); + $this->style = $db->sql_fetchrow($result); $db->sql_freeresult($result); } - if (!$this->theme) + if (!$this->style) { trigger_error('Could not get style data', E_USER_ERROR); } // Now parse the cfg file and cache it - $parsed_items = $cache->obtain_cfg_items($this->theme); + $parsed_items = $cache->obtain_cfg_items($this->style); $check_for = array( 'pagination_sep' => (string) ', ' @@ -194,12 +194,12 @@ class phpbb_user extends phpbb_session foreach ($check_for as $key => $default_value) { - $this->theme[$key] = (isset($parsed_items[$key])) ? $parsed_items[$key] : $default_value; - settype($this->theme[$key], gettype($default_value)); + $this->style[$key] = (isset($parsed_items[$key])) ? $parsed_items[$key] : $default_value; + settype($this->style[$key], gettype($default_value)); if (is_string($default_value)) { - $this->theme[$key] = htmlspecialchars($this->theme[$key]); + $this->style[$key] = htmlspecialchars($this->style[$key]); } } From 699aab8e8e52bf5980a8078fc460d30cedd65347 Mon Sep 17 00:00:00 2001 From: Oleg Pudeyev Date: Mon, 11 Jun 2012 21:00:22 -0400 Subject: [PATCH 271/441] [ticket/10829] $style_name -> $style_path in style class. Here the style path is taken and the variable name should be $style_path. PHPBB3-10829 --- phpBB/includes/style/style.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/phpBB/includes/style/style.php b/phpBB/includes/style/style.php index 8d38deb85c..22e0f1d67a 100644 --- a/phpBB/includes/style/style.php +++ b/phpBB/includes/style/style.php @@ -89,9 +89,9 @@ class phpbb_style */ public function set_style() { - $style_name = $this->user->style['style_path']; + $style_path = $this->user->style['style_path']; $style_dirs = ($this->user->style['style_parent_id']) ? array_reverse(explode('/', $this->user->style['style_parent_tree'])) : array(); - $paths = array($this->get_style_path($style_name)); + $paths = array($this->get_style_path($style_path)); foreach ($style_dirs as $dir) { $paths[] = $this->get_style_path($dir); @@ -100,7 +100,7 @@ class phpbb_style // Add 'all' path, used as last fallback path by hooks and extensions $paths[] = $this->get_style_path('all'); - return $this->set_custom_style($style_name, $paths); + return $this->set_custom_style($style_path, $paths); } /** From 2a9698a13a5df8ff6c3b62df0674de07ebebdfc9 Mon Sep 17 00:00:00 2001 From: Oleg Pudeyev Date: Mon, 11 Jun 2012 21:03:12 -0400 Subject: [PATCH 272/441] [ticket/10829] Delete T_STYLESHEET_NAME - no longer used. PHPBB3-10829 --- phpBB/includes/functions.php | 1 - 1 file changed, 1 deletion(-) diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index ddbe1c2c36..e40df93194 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -4784,7 +4784,6 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0 'T_UPLOAD_PATH' => "{$web_path}{$config['upload_path']}/", 'T_STYLESHEET_LINK' => "{$web_path}styles/" . rawurlencode($user->style['style_path']) . '/theme/stylesheet.css?assets_version=' . $config['assets_version'], 'T_STYLESHEET_LANG_LINK' => "{$web_path}styles/" . rawurlencode($user->style['style_path']) . '/theme/' . $user->lang_name . '/stylesheet.css?assets_version=' . $config['assets_version'], - 'T_STYLESHEET_NAME' => $user->style['style_name'], 'T_JQUERY_LINK' => ($config['load_jquery_cdn'] && !empty($config['load_jquery_url'])) ? $config['load_jquery_url'] : "{$web_path}assets/javascript/jquery.js?assets_version=" . $config['assets_version'], 'S_JQUERY_FALLBACK' => ($config['load_jquery_cdn']) ? true : false, From e127ba17ea3259d1fa9a135b8ae5ab9136bc7712 Mon Sep 17 00:00:00 2001 From: Dhruv Goel Date: Tue, 12 Jun 2012 18:40:48 +0530 Subject: [PATCH 273/441] [ticket/10936] fix language key Language key changes from INCOMPATIBLE_VERSION to INCOMPATIBLE_DATABASE to make it more meaningfull. PHPBB3-10936 --- phpBB/includes/search/fulltext_mysql.php | 2 +- phpBB/language/en/acp/search.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/phpBB/includes/search/fulltext_mysql.php b/phpBB/includes/search/fulltext_mysql.php index 7c94038cc9..c84bfcdcb0 100644 --- a/phpBB/includes/search/fulltext_mysql.php +++ b/phpBB/includes/search/fulltext_mysql.php @@ -70,7 +70,7 @@ class phpbb_search_fulltext_mysql extends phpbb_search_base if ($db->sql_layer != 'mysql4' && $db->sql_layer != 'mysqli') { - return $user->lang['FULLTEXT_MYSQL_INCOMPATIBLE_VERSION']; + return $user->lang['FULLTEXT_MYSQL_INCOMPATIBLE_DATABASE']; } $result = $db->sql_query('SHOW TABLE STATUS LIKE \'' . POSTS_TABLE . '\''); diff --git a/phpBB/language/en/acp/search.php b/phpBB/language/en/acp/search.php index 3dc89570bf..2badb082d6 100644 --- a/phpBB/language/en/acp/search.php +++ b/phpBB/language/en/acp/search.php @@ -51,7 +51,7 @@ $lang = array_merge($lang, array( 'DELETING_INDEX_IN_PROGRESS' => 'Deleting the index in progress', 'DELETING_INDEX_IN_PROGRESS_EXPLAIN' => 'The search backend is currently cleaning its index. This can take a few minutes.', - 'FULLTEXT_MYSQL_INCOMPATIBLE_VERSION' => 'The MySQL fulltext backend can only be used with MySQL4 and above.', + 'FULLTEXT_MYSQL_INCOMPATIBLE_DATABASE' => 'The MySQL fulltext backend can only be used with MySQL4 and above.', 'FULLTEXT_MYSQL_NOT_MYISAM' => 'MySQL fulltext indexes can only be used with MyISAM tables.', 'FULLTEXT_MYSQL_TOTAL_POSTS' => 'Total number of indexed posts', 'FULLTEXT_MYSQL_MBSTRING' => 'Support for non-latin UTF-8 characters using mbstring:', From 96cb75dedb73dc0e36b842492f6a176db9147023 Mon Sep 17 00:00:00 2001 From: Dhruv Goel Date: Wed, 13 Jun 2012 01:43:32 +0530 Subject: [PATCH 274/441] [ticket/10936] remove PCRE and mbstring support check Since PCRE UTF8 support already has a global check no need for mbstring or PCRE check here. PHPBB3-10936 --- phpBB/includes/search/fulltext_mysql.php | 99 ++---------------------- phpBB/language/en/acp/search.php | 4 - 2 files changed, 8 insertions(+), 95 deletions(-) diff --git a/phpBB/includes/search/fulltext_mysql.php b/phpBB/includes/search/fulltext_mysql.php index c84bfcdcb0..b59d9908c3 100644 --- a/phpBB/includes/search/fulltext_mysql.php +++ b/phpBB/includes/search/fulltext_mysql.php @@ -27,8 +27,6 @@ class phpbb_search_fulltext_mysql extends phpbb_search_base var $split_words = array(); var $search_query; var $common_words = array(); - var $pcre_properties = false; - var $mbstring_regex = false; public function __construct(&$error) { @@ -36,18 +34,6 @@ class phpbb_search_fulltext_mysql extends phpbb_search_base $this->word_length = array('min' => $config['fulltext_mysql_min_word_len'], 'max' => $config['fulltext_mysql_max_word_len']); - // PHP may not be linked with the bundled PCRE lib and instead with an older version - if (phpbb_pcre_utf8_support()) - { - $this->pcre_properties = true; - } - - if (function_exists('mb_ereg')) - { - $this->mbstring_regex = true; - mb_regex_encoding('UTF-8'); - } - $error = false; } @@ -133,40 +119,10 @@ class phpbb_search_fulltext_mysql extends phpbb_search_base $split_keywords = preg_replace("#[\n\r\t]+#", ' ', trim(htmlspecialchars_decode($keywords))); // Split words - if ($this->pcre_properties) - { - $split_keywords = preg_replace('#([^\p{L}\p{N}\'*"()])#u', '$1$1', str_replace('\'\'', '\' \'', trim($split_keywords))); - } - else if ($this->mbstring_regex) - { - $split_keywords = mb_ereg_replace('([^\w\'*"()])', '\\1\\1', str_replace('\'\'', '\' \'', trim($split_keywords))); - } - else - { - $split_keywords = preg_replace('#([^\w\'*"()])#u', '$1$1', str_replace('\'\'', '\' \'', trim($split_keywords))); - } - - if ($this->pcre_properties) - { - $matches = array(); - preg_match_all('#(?:[^\p{L}\p{N}*"()]|^)([+\-|]?(?:[\p{L}\p{N}*"()]+\'?)*[\p{L}\p{N}*"()])(?:[^\p{L}\p{N}*"()]|$)#u', $split_keywords, $matches); - $this->split_words = $matches[1]; - } - else if ($this->mbstring_regex) - { - mb_ereg_search_init($split_keywords, '(?:[^\w*"()]|^)([+\-|]?(?:[\w*"()]+\'?)*[\w*"()])(?:[^\w*"()]|$)'); - - while (($word = mb_ereg_search_regs())) - { - $this->split_words[] = $word[1]; - } - } - else - { - $matches = array(); - preg_match_all('#(?:[^\w*"()]|^)([+\-|]?(?:[\w*"()]+\'?)*[\w*"()])(?:[^\w*"()]|$)#u', $split_keywords, $matches); - $this->split_words = $matches[1]; - } + $split_keywords = preg_replace('#([^\p{L}\p{N}\'*"()])#u', '$1$1', str_replace('\'\'', '\' \'', trim($split_keywords))); + $matches = array(); + preg_match_all('#(?:[^\p{L}\p{N}*"()]|^)([+\-|]?(?:[\p{L}\p{N}*"()]+\'?)*[\p{L}\p{N}*"()])(?:[^\p{L}\p{N}*"()]|$)#u', $split_keywords, $matches); + $this->split_words = $matches[1]; // We limit the number of allowed keywords to minimize load on the database if ($config['max_num_search_keywords'] && sizeof($this->split_words) > $config['max_num_search_keywords']) @@ -271,41 +227,10 @@ class phpbb_search_fulltext_mysql extends phpbb_search_base global $config; // Split words - if ($this->pcre_properties) - { - $text = preg_replace('#([^\p{L}\p{N}\'*])#u', '$1$1', str_replace('\'\'', '\' \'', trim($text))); - } - else if ($this->mbstring_regex) - { - $text = mb_ereg_replace('([^\w\'*])', '\\1\\1', str_replace('\'\'', '\' \'', trim($text))); - } - else - { - $text = preg_replace('#([^\w\'*])#u', '$1$1', str_replace('\'\'', '\' \'', trim($text))); - } - - if ($this->pcre_properties) - { - $matches = array(); - preg_match_all('#(?:[^\p{L}\p{N}*]|^)([+\-|]?(?:[\p{L}\p{N}*]+\'?)*[\p{L}\p{N}*])(?:[^\p{L}\p{N}*]|$)#u', $text, $matches); - $text = $matches[1]; - } - else if ($this->mbstring_regex) - { - mb_ereg_search_init($text, '(?:[^\w*]|^)([+\-|]?(?:[\w*]+\'?)*[\w*])(?:[^\w*]|$)'); - - $text = array(); - while (($word = mb_ereg_search_regs())) - { - $text[] = $word[1]; - } - } - else - { - $matches = array(); - preg_match_all('#(?:[^\w*]|^)([+\-|]?(?:[\w*]+\'?)*[\w*])(?:[^\w*]|$)#u', $text, $matches); - $text = $matches[1]; - } + $text = preg_replace('#([^\p{L}\p{N}\'*])#u', '$1$1', str_replace('\'\'', '\' \'', trim($text))); + $matches = array(); + preg_match_all('#(?:[^\p{L}\p{N}*]|^)([+\-|]?(?:[\p{L}\p{N}*]+\'?)*[\p{L}\p{N}*])(?:[^\p{L}\p{N}*]|$)#u', $text, $matches); + $text = $matches[1]; // remove too short or too long words $text = array_values($text); @@ -908,14 +833,6 @@ class phpbb_search_fulltext_mysql extends phpbb_search_base global $user, $config; $tpl = ' -
          -

          ' . $user->lang['FULLTEXT_MYSQL_PCRE_EXPLAIN'] . '
          -
          ' . (($this->pcre_properties) ? $user->lang['YES'] : $user->lang['NO']) . ' (PHP ' . PHP_VERSION . ')
          -
          -
          -

          ' . $user->lang['FULLTEXT_MYSQL_MBSTRING_EXPLAIN'] . '
          -
          ' . (($this->mbstring_regex) ? $user->lang['YES'] : $user->lang['NO']). '
          -

          ' . $user->lang['FULLTEXT_MYSQL_MIN_SEARCH_CHARS_EXPLAIN'] . '
          ' . $config['fulltext_mysql_min_word_len'] . '
          diff --git a/phpBB/language/en/acp/search.php b/phpBB/language/en/acp/search.php index 2badb082d6..2f46856557 100644 --- a/phpBB/language/en/acp/search.php +++ b/phpBB/language/en/acp/search.php @@ -54,10 +54,6 @@ $lang = array_merge($lang, array( 'FULLTEXT_MYSQL_INCOMPATIBLE_DATABASE' => 'The MySQL fulltext backend can only be used with MySQL4 and above.', 'FULLTEXT_MYSQL_NOT_MYISAM' => 'MySQL fulltext indexes can only be used with MyISAM tables.', 'FULLTEXT_MYSQL_TOTAL_POSTS' => 'Total number of indexed posts', - 'FULLTEXT_MYSQL_MBSTRING' => 'Support for non-latin UTF-8 characters using mbstring:', - 'FULLTEXT_MYSQL_PCRE' => 'Support for non-latin UTF-8 characters using PCRE:', - 'FULLTEXT_MYSQL_MBSTRING_EXPLAIN' => 'If PCRE does not have unicode character properties, the search backend will try to use mbstring’s regular expression engine.', - 'FULLTEXT_MYSQL_PCRE_EXPLAIN' => 'This search backend requires PCRE unicode character properties, only available in PHP 4.4, 5.1 and above, if you want to search for non-latin characters.', 'FULLTEXT_MYSQL_MIN_SEARCH_CHARS_EXPLAIN' => 'Words with at least this many characters will be indexed for searching. You or your host can only change this setting by changing the mysql configuration.', 'FULLTEXT_MYSQL_MAX_SEARCH_CHARS_EXPLAIN' => 'Words with no more than this many characters will be indexed for searching. You or your host can only change this setting by changing the mysql configuration.', From 53d846477665ea6b8a3463318f03050282aec89a Mon Sep 17 00:00:00 2001 From: Michael Cullum Date: Sat, 11 Feb 2012 21:12:36 +0000 Subject: [PATCH 275/441] [ticket/10640] Change maximum subject length PHPBB3-10640 --- phpBB/includes/functions_content.php | 2 +- phpBB/styles/prosilver/template/posting_editor.html | 2 +- phpBB/styles/prosilver/template/quickreply_editor.html | 2 +- phpBB/styles/subsilver2/template/posting_body.html | 2 +- phpBB/styles/subsilver2/template/quickreply_editor.html | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/phpBB/includes/functions_content.php b/phpBB/includes/functions_content.php index 6b2ee98d7a..752ebe0f13 100644 --- a/phpBB/includes/functions_content.php +++ b/phpBB/includes/functions_content.php @@ -1107,7 +1107,7 @@ function extension_allowed($forum_id, $extension, &$extensions) * NOTE: This parameter can cause undesired behavior (returning strings longer than $max_store_length) and is deprecated. * @param string $append String to be appended */ -function truncate_string($string, $max_length = 60, $max_store_length = 255, $allow_reply = false, $append = '') +function truncate_string($string, $max_length = 120, $max_store_length = 255, $allow_reply = false, $append = '') { $chars = array(); diff --git a/phpBB/styles/prosilver/template/posting_editor.html b/phpBB/styles/prosilver/template/posting_editor.html index 60766495c6..d1c86e7e13 100644 --- a/phpBB/styles/prosilver/template/posting_editor.html +++ b/phpBB/styles/prosilver/template/posting_editor.html @@ -103,7 +103,7 @@
          -
          +
          diff --git a/phpBB/styles/prosilver/template/quickreply_editor.html b/phpBB/styles/prosilver/template/quickreply_editor.html index 724fdb85b8..5fcdf0f5d4 100644 --- a/phpBB/styles/prosilver/template/quickreply_editor.html +++ b/phpBB/styles/prosilver/template/quickreply_editor.html @@ -5,7 +5,7 @@
          -
          +
          diff --git a/phpBB/styles/subsilver2/template/posting_body.html b/phpBB/styles/subsilver2/template/posting_body.html index 712c02b856..ae7d2f88d6 100644 --- a/phpBB/styles/subsilver2/template/posting_body.html +++ b/phpBB/styles/subsilver2/template/posting_body.html @@ -173,7 +173,7 @@ {L_SUBJECT}: - + {L_MESSAGE_BODY}:
          {L_MESSAGE_BODY_EXPLAIN} 

          diff --git a/phpBB/styles/subsilver2/template/quickreply_editor.html b/phpBB/styles/subsilver2/template/quickreply_editor.html index 4c3f7a3d0b..7a68a8f605 100644 --- a/phpBB/styles/subsilver2/template/quickreply_editor.html +++ b/phpBB/styles/subsilver2/template/quickreply_editor.html @@ -6,7 +6,7 @@ {L_SUBJECT}: - + {L_MESSAGE}: From a259db71058cd20eb54ac3b45a88b558c66e4cb5 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Wed, 2 May 2012 13:13:20 +0200 Subject: [PATCH 276/441] [ticket/10640] Do not change default value of truncate_string() The default value should be kept, so we do not change the behaviour for MODs and Extensions that use the function with its default values. PHPBB3-10640 --- phpBB/includes/functions_content.php | 2 +- phpBB/includes/functions_posting.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/phpBB/includes/functions_content.php b/phpBB/includes/functions_content.php index 752ebe0f13..6b2ee98d7a 100644 --- a/phpBB/includes/functions_content.php +++ b/phpBB/includes/functions_content.php @@ -1107,7 +1107,7 @@ function extension_allowed($forum_id, $extension, &$extensions) * NOTE: This parameter can cause undesired behavior (returning strings longer than $max_store_length) and is deprecated. * @param string $append String to be appended */ -function truncate_string($string, $max_length = 120, $max_store_length = 255, $allow_reply = false, $append = '') +function truncate_string($string, $max_length = 60, $max_store_length = 255, $allow_reply = false, $append = '') { $chars = array(); diff --git a/phpBB/includes/functions_posting.php b/phpBB/includes/functions_posting.php index f77f54679f..c549f99091 100644 --- a/phpBB/includes/functions_posting.php +++ b/phpBB/includes/functions_posting.php @@ -1657,8 +1657,8 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u // First of all make sure the subject and topic title are having the correct length. // To achieve this without cutting off between special chars we convert to an array and then count the elements. - $subject = truncate_string($subject); - $data['topic_title'] = truncate_string($data['topic_title']); + $subject = truncate_string($subject, 120); + $data['topic_title'] = truncate_string($data['topic_title'], 120); // Collect some basic information about which tables and which rows to update/insert $sql_data = $topic_row = array(); From 7a6a5738db3c43b385a15a84c6956c2b295cc709 Mon Sep 17 00:00:00 2001 From: Michael Cullum Date: Sun, 17 Jun 2012 19:01:17 +0100 Subject: [PATCH 277/441] [ticket/10640] Change subject length in MCP PHPBB3-10640 --- phpBB/styles/prosilver/template/mcp_topic.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/styles/prosilver/template/mcp_topic.html b/phpBB/styles/prosilver/template/mcp_topic.html index 2a6de3ce9d..8d0294d226 100644 --- a/phpBB/styles/prosilver/template/mcp_topic.html +++ b/phpBB/styles/prosilver/template/mcp_topic.html @@ -67,7 +67,7 @@ onload_functions.push('subPanels()');
          -
          +
          From a41f86f2f724c31b2bb6e55d278b65e2660697c1 Mon Sep 17 00:00:00 2001 From: Michael Cullum Date: Sun, 17 Jun 2012 19:22:50 +0100 Subject: [PATCH 278/441] [ticket/10640] Change subject length in mcp in subsilver PHPBB3-10640 --- phpBB/styles/subsilver2/template/mcp_topic.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/styles/subsilver2/template/mcp_topic.html b/phpBB/styles/subsilver2/template/mcp_topic.html index 8ff648da39..6bbf13e12c 100644 --- a/phpBB/styles/subsilver2/template/mcp_topic.html +++ b/phpBB/styles/subsilver2/template/mcp_topic.html @@ -12,7 +12,7 @@ {L_SPLIT_SUBJECT} - + {L_SPLIT_FORUM} From 50936cb2eff3f80d99390c76ef6ac535e73f6cc3 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Mon, 4 Jun 2012 19:06:46 +0200 Subject: [PATCH 279/441] [feature/new-tz-handling] Fix selecting and validating of timezone in UCP PHPBB3-9558 --- phpBB/includes/functions.php | 24 ++++++++++++++---------- phpBB/includes/functions_user.php | 16 ++++++++++++++++ phpBB/includes/ucp/ucp_prefs.php | 4 ++-- phpBB/language/en/ucp.php | 1 + 4 files changed, 33 insertions(+), 12 deletions(-) diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index 3ec4b76091..55f7f0531c 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -1139,34 +1139,38 @@ function tz_select($default = '', $truncate = false) if (!isset($timezones)) { - $timezones = DateTimeZone::listIdentifiers(); + $unsorted_timezones = DateTimeZone::listIdentifiers(); + $timezones = array(); - foreach ($timezones as &$timezone) + foreach ($unsorted_timezones as $timezone) { $tz = new DateTimeZone($timezone); $dt = new phpbb_datetime('now', $tz); $offset = $dt->getOffset(); $offset_string = phpbb_format_timezone_offset($offset); - $timezone = 'GMT' . $offset_string . ' - ' . $timezone; + $timezones['GMT' . $offset_string . ' - ' . $timezone] = array( + 'tz' => $timezone, + 'label' => 'GMT' . $offset_string . ' - ' . $timezone, + ); } - unset($timezone); + unset($unsorted_timezones); - usort($timezones, 'tz_select_compare'); + uksort($timezones, 'tz_select_compare'); } $tz_select = ''; foreach ($timezones as $timezone) { - if (isset($user->lang['timezones'][$timezone])) + if (isset($user->lang['timezones'][$timezone['tz']])) { - $title = $label = $user->lang['timezones'][$timezone]; + $title = $label = $user->lang['timezones'][$timezone['tz']]; } else { // No label, we'll figure one out // @todo rtl languages? - $bits = explode('/', str_replace('_', ' ', $timezone)); + $bits = explode('/', str_replace('_', ' ', $timezone['label'])); $title = $label = implode(' - ', $bits); } @@ -1176,8 +1180,8 @@ function tz_select($default = '', $truncate = false) $label = truncate_string($label, 50, 255, false, '...'); } - $selected = ($timezone === $default) ? ' selected="selected"' : ''; - $tz_select .= ''; + $selected = ($timezone['tz'] === $default) ? ' selected="selected"' : ''; + $tz_select .= ''; } return $tz_select; diff --git a/phpBB/includes/functions_user.php b/phpBB/includes/functions_user.php index 9b102b7387..3a77407c20 100644 --- a/phpBB/includes/functions_user.php +++ b/phpBB/includes/functions_user.php @@ -1395,6 +1395,22 @@ function validate_language_iso_name($lang_iso) return ($lang_id) ? false : 'WRONG_DATA'; } +/** +* 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 validate_timezone($timezone) +{ + return (in_array($timezone, DateTimeZone::listIdentifiers())) ? 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. diff --git a/phpBB/includes/ucp/ucp_prefs.php b/phpBB/includes/ucp/ucp_prefs.php index 0c9f20f266..45e3bb8951 100644 --- a/phpBB/includes/ucp/ucp_prefs.php +++ b/phpBB/includes/ucp/ucp_prefs.php @@ -41,7 +41,7 @@ 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']), @@ -72,7 +72,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')) diff --git a/phpBB/language/en/ucp.php b/phpBB/language/en/ucp.php index a80862890a..f9558bc6d3 100644 --- a/phpBB/language/en/ucp.php +++ b/phpBB/language/en/ucp.php @@ -422,6 +422,7 @@ $lang = array_merge($lang, array( 'SORT_SIZE' => 'File size', 'TIMEZONE' => 'Timezone', + 'TIMEZONE_INVALID' => 'The timezone you selected is invalid.', 'TO' => 'To', 'TOO_MANY_RECIPIENTS' => 'You tried to send a private message to too many recipients.', 'TOO_MANY_REGISTERS' => 'You have exceeded the maximum number of registration attempts for this session. Please try again later.', From 00b5e5345dc44c99340bba932522b6b05b48dab2 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Mon, 4 Jun 2012 19:19:34 +0200 Subject: [PATCH 280/441] [feature/new-tz-handling] Fix displaying of "All times are" string PHPBB3-9558 --- phpBB/includes/functions.php | 10 +++++++++- phpBB/language/en/common.php | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index 55f7f0531c..44346c7795 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -4769,6 +4769,14 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0 } } + $dt = new phpbb_datetime('now', $user->tz); + $timezone_offset = 'GMT' . phpbb_format_timezone_offset($dt->getOffset()); + $timezone_name = $user->tz->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'], @@ -4836,7 +4844,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/language/en/common.php b/phpBB/language/en/common.php index 023ee2c89f..bbafb54108 100644 --- a/phpBB/language/en/common.php +++ b/phpBB/language/en/common.php @@ -74,7 +74,7 @@ $lang = array_merge($lang, array( 'ALL_FORUMS' => 'All forums', 'ALL_MESSAGES' => 'All messages', 'ALL_POSTS' => 'All posts', - 'ALL_TIMES' => 'All times are %1$s %2$s', + 'ALL_TIMES' => 'All times are %1$s', 'ALL_TOPICS' => 'All Topics', 'AND' => 'And', 'ARE_WATCHING_FORUM' => 'You have subscribed to be notified of new posts in this forum.', From 09499fb128802bd19cee1550bf6e9af80a9388e2 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Mon, 4 Jun 2012 22:33:03 +0200 Subject: [PATCH 281/441] [feature/new-tz-handling] Fix handling of timezone and dst in dateformat_select PHPBB3-9558 --- phpBB/includes/acp/acp_board.php | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/phpBB/includes/acp/acp_board.php b/phpBB/includes/acp/acp_board.php index d537885ef1..ce2ddc3b0b 100644 --- a/phpBB/includes/acp/acp_board.php +++ b/phpBB/includes/acp/acp_board.php @@ -906,11 +906,13 @@ class acp_board global $user, $config; // 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; + $old_tz = $user->tz; + if (is_numeric($config['board_timezone'])) + { + // Might still be numeric by chance + $config['board_timezone'] = sprintf('Etc/GMT%+d', $config['board_timezone']); + } + $user->tz = new DateTimeZone($config['board_timezone']); $dateformat_options = ''; @@ -929,8 +931,7 @@ class acp_board $dateformat_options .= '>' . $user->lang['CUSTOM_DATEFORMAT'] . ''; // Reset users date options - $user->timezone = $old_tz; - $user->dst = $old_dst; + $user->tz = $old_tz; return " "; From 66ae9ee2ea8b65ddb4c39b4bc9add8d2aca2e73d Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Mon, 4 Jun 2012 22:39:35 +0200 Subject: [PATCH 282/441] [feature/new-tz-handling] Fix timezone selection on registration page PHPBB3-9558 --- phpBB/includes/ucp/ucp_register.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/phpBB/includes/ucp/ucp_register.php b/phpBB/includes/ucp/ucp_register.php index 5d85029e62..aee55711b2 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']), )); } @@ -172,7 +172,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 +189,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,7 +279,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_timezone' => $data['tz'], 'user_dst' => $is_dst, 'user_lang' => $data['lang'], 'user_type' => $user_type, @@ -453,7 +453,7 @@ 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' => tz_select($data['tz'], true), 'S_CONFIRM_REFRESH' => ($config['enable_confirm'] && $config['confirm_refresh']) ? true : false, 'S_REGISTRATION' => true, 'S_COPPA' => $coppa, From f9bc8252641ec69983acfc6d392770934b7a37a4 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Mon, 4 Jun 2012 22:40:09 +0200 Subject: [PATCH 283/441] [feature/new-tz-handling] Fix timezone validation in ACP user section PHPBB3-9558 --- phpBB/includes/acp/acp_users.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/phpBB/includes/acp/acp_users.php b/phpBB/includes/acp/acp_users.php index 17687b05c7..825bba514f 100644 --- a/phpBB/includes/acp/acp_users.php +++ b/phpBB/includes/acp/acp_users.php @@ -1458,7 +1458,7 @@ 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']), @@ -1495,7 +1495,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), From 963d4afc2cf5fb2903ed02ada20cdbf0188d57db Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Mon, 4 Jun 2012 23:14:41 +0200 Subject: [PATCH 284/441] [feature/new-tz-handling] Replace gmmktime() and mktime() with phpbb_datetime PHPBB3-9558 --- phpBB/includes/functions_user.php | 7 ++++--- phpBB/includes/ucp/ucp_register.php | 7 ++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/phpBB/includes/functions_user.php b/phpBB/includes/functions_user.php index 3a77407c20..f235b2be55 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->tz->getOffset(new DateTime('UTC'))); } else { diff --git a/phpBB/includes/ucp/ucp_register.php b/phpBB/includes/ucp/ucp_register.php index aee55711b2..ac002a26c2 100644 --- a/phpBB/includes/ucp/ucp_register.php +++ b/phpBB/includes/ucp/ucp_register.php @@ -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( @@ -280,7 +282,6 @@ class ucp_register 'user_email' => $data['email'], 'group_id' => (int) $group_id, 'user_timezone' => $data['tz'], - 'user_dst' => $is_dst, 'user_lang' => $data['lang'], 'user_type' => $user_type, 'user_actkey' => $user_actkey, From 3c6272ff0475dc19cc67553f370ce227214d0613 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Mon, 4 Jun 2012 23:28:48 +0200 Subject: [PATCH 285/441] [feature/new-tz-handling] Remove appearances of board_dst and user_dst PHPBB3-9558 --- phpBB/develop/mysql_upgrader.php | 3 +-- phpBB/develop/repair_bots.php | 2 +- phpBB/includes/acp/acp_board.php | 1 - phpBB/includes/acp/acp_users.php | 3 --- phpBB/includes/functions_convert.php | 2 +- phpBB/includes/questionnaire/questionnaire.php | 1 - phpBB/includes/ucp/ucp_prefs.php | 3 --- phpBB/includes/user.php | 2 +- phpBB/install/database_update.php | 2 +- phpBB/install/install_install.php | 2 +- phpBB/install/schemas/schema_data.sql | 3 +-- 11 files changed, 7 insertions(+), 17 deletions(-) diff --git a/phpBB/develop/mysql_upgrader.php b/phpBB/develop/mysql_upgrader.php index 0498f826ab..7f82ebfeab 100644 --- a/phpBB/develop/mysql_upgrader.php +++ b/phpBB/develop/mysql_upgrader.php @@ -1229,8 +1229,7 @@ function get_schema_struct() 'user_inactive_time' => array('TIMESTAMP', 0), 'user_posts' => array('UINT', 0), 'user_lang' => array('VCHAR:30', ''), - 'user_timezone' => array('DECIMAL', 0), - 'user_dst' => array('BOOL', 0), + 'user_timezone' => array('VCHAR:100', 'UTC'), 'user_dateformat' => array('VCHAR_UNI:30', 'd M Y H:i'), 'user_style' => array('UINT', 0), 'user_rank' => array('UINT', 0), diff --git a/phpBB/develop/repair_bots.php b/phpBB/develop/repair_bots.php index 790d3d9f2f..2c6e9ce091 100644 --- a/phpBB/develop/repair_bots.php +++ b/phpBB/develop/repair_bots.php @@ -128,7 +128,7 @@ function add_bots($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/acp/acp_board.php b/phpBB/includes/acp/acp_board.php index ce2ddc3b0b..e018655407 100644 --- a/phpBB/includes/acp/acp_board.php +++ b/phpBB/includes/acp/acp_board.php @@ -58,7 +58,6 @@ class acp_board '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), '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), diff --git a/phpBB/includes/acp/acp_users.php b/phpBB/includes/acp/acp_users.php index 825bba514f..b863a9ed80 100644 --- a/phpBB/includes/acp/acp_users.php +++ b/phpBB/includes/acp/acp_users.php @@ -1460,7 +1460,6 @@ class acp_users 'lang' => basename(request_var('lang', $user_row['user_lang'])), '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']), @@ -1531,7 +1530,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'], @@ -1654,7 +1652,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'], 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/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/ucp/ucp_prefs.php b/phpBB/includes/ucp/ucp_prefs.php index 45e3bb8951..3f5f573389 100644 --- a/phpBB/includes/ucp/ucp_prefs.php +++ b/phpBB/includes/ucp/ucp_prefs.php @@ -43,7 +43,6 @@ class ucp_prefs 'style' => request_var('style', (int) $user->data['user_style']), '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']), @@ -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'], @@ -145,7 +143,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']), diff --git a/phpBB/includes/user.php b/phpBB/includes/user.php index 4c62dd93d7..a36d837fbd 100644 --- a/phpBB/includes/user.php +++ b/phpBB/includes/user.php @@ -126,7 +126,7 @@ class phpbb_user extends phpbb_session if (is_numeric($this->tz)) { // Might still be numeric by chance - $this->tz = sprintf('Etc/GMT%+d', ($this->tz + ($this->data['user_id'] != ANONYMOUS ? $this->data['user_dst'] : $config['board_dst']))); + $this->tz = sprintf('Etc/GMT%+d', $this->tz); } $this->tz = new DateTimeZone($this->tz); diff --git a/phpBB/install/database_update.php b/phpBB/install/database_update.php index 9758ad3b2b..b6f7f82785 100644 --- a/phpBB/install/database_update.php +++ b/phpBB/install/database_update.php @@ -1971,7 +1971,7 @@ function change_database_data(&$no_updates, $version) 'user_email' => '', 'user_lang' => $config['default_lang'], 'user_style' => $config['default_style'], - 'user_timezone' => 0, + 'user_timezone' => 'UTC', 'user_dateformat' => $config['default_dateformat'], 'user_allow_massemail' => 0, ); diff --git a/phpBB/install/install_install.php b/phpBB/install/install_install.php index ef384edb78..bafcefe3f5 100644 --- a/phpBB/install/install_install.php +++ b/phpBB/install/install_install.php @@ -1795,7 +1795,7 @@ class install_install extends module 'user_email' => '', 'user_lang' => $data['default_lang'], 'user_style' => 1, - 'user_timezone' => 0, + 'user_timezone' => 'UTC', 'user_dateformat' => $lang['default_dateformat'], 'user_allow_massemail' => 0, ); diff --git a/phpBB/install/schemas/schema_data.sql b/phpBB/install/schemas/schema_data.sql index 5489fd4e3d..307864825c 100644 --- a/phpBB/install/schemas/schema_data.sql +++ b/phpBB/install/schemas/schema_data.sql @@ -54,12 +54,11 @@ INSERT INTO phpbb_config (config_name, config_value) VALUES ('avatar_salt', 'php INSERT INTO phpbb_config (config_name, config_value) VALUES ('board_contact', 'contact@yourdomain.tld'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('board_disable', '0'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('board_disable_msg', ''); -INSERT INTO phpbb_config (config_name, config_value) VALUES ('board_dst', '0'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('board_email', 'address@yourdomain.tld'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('board_email_form', '0'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('board_email_sig', '{L_CONFIG_BOARD_EMAIL_SIG}'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('board_hide_emails', '1'); -INSERT INTO phpbb_config (config_name, config_value) VALUES ('board_timezone', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('board_timezone', 'UTC'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('browser_check', '1'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('bump_interval', '10'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('bump_type', 'd'); From 66f7d45603417df7619323977de62aebce0bf676 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 5 Jun 2012 21:44:44 +0200 Subject: [PATCH 286/441] [feature/new-tz-handling] Introduce 2 step timezone selection using javascript PHPBB3-9558 --- phpBB/includes/functions.php | 43 ++++++++++--- phpBB/includes/ucp/ucp_prefs.php | 4 +- phpBB/language/en/common.php | 1 + phpBB/language/en/ucp.php | 3 + phpBB/styles/prosilver/template/timezone.js | 63 +++++++++++++++---- .../template/ucp_prefs_personal.html | 10 ++- phpBB/styles/prosilver/theme/forms.css | 5 ++ 7 files changed, 107 insertions(+), 22 deletions(-) diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index 44346c7795..9263833b4c 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -1129,14 +1129,14 @@ function tz_select_compare($a, $b) /** * Pick a timezone -* @todo Possible HTML escaping */ -function tz_select($default = '', $truncate = false) +function tz_select($default = '', $truncate = false, $return_tzs_only = true) { global $user; static $timezones; + $default_offset = ''; if (!isset($timezones)) { $unsorted_timezones = DateTimeZone::listIdentifiers(); @@ -1147,21 +1147,37 @@ function tz_select($default = '', $truncate = false) $tz = new DateTimeZone($timezone); $dt = new phpbb_datetime('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, - 'label' => 'GMT' . $offset_string . ' - ' . $timezone, + 'offest' => 'GMT' . $offset_string, + 'current' => $current_time, ); + if ($timezone === $default) + { + $default_offset = 'GMT' . $offset_string; + } } unset($unsorted_timezones); uksort($timezones, 'tz_select_compare'); } - $tz_select = ''; + $tz_select = $tz_dates = $opt_group = ''; foreach ($timezones as $timezone) { + if ($opt_group != $timezone['offest']) + { + $tz_select .= ($opt_group) ? '' : ''; + $tz_select .= ''; + $opt_group = $timezone['offest']; + + $selected = ($default_offset == $timezone['offest']) ? ' selected="selected"' : ''; + $tz_dates .= ''; + } + if (isset($user->lang['timezones'][$timezone['tz']])) { $title = $label = $user->lang['timezones'][$timezone['tz']]; @@ -1169,10 +1185,10 @@ function tz_select($default = '', $truncate = false) else { // No label, we'll figure one out - // @todo rtl languages? - $bits = explode('/', str_replace('_', ' ', $timezone['label'])); + $bits = explode('/', str_replace('_', ' ', $timezone['tz'])); - $title = $label = implode(' - ', $bits); + $label = implode(' - ', $bits); + $title = $timezone['offest'] . ' - ' . $label; } if ($truncate) @@ -1181,10 +1197,19 @@ function tz_select($default = '', $truncate = false) } $selected = ($timezone['tz'] === $default) ? ' selected="selected"' : ''; - $tz_select .= ''; + $tz_select .= ''; + } + $tz_select .= ''; + + if ($return_tzs_only) + { + return $tz_select; } - return $tz_select; + return array( + 'tz_select' => $tz_select, + 'tz_dates' => $tz_dates, + ); } // Functions handling topic/post tracking/marking diff --git a/phpBB/includes/ucp/ucp_prefs.php b/phpBB/includes/ucp/ucp_prefs.php index 3f5f573389..4239afc96e 100644 --- a/phpBB/includes/ucp/ucp_prefs.php +++ b/phpBB/includes/ucp/ucp_prefs.php @@ -131,6 +131,7 @@ class ucp_prefs } $dateformat_options .= '>' . $user->lang['CUSTOM_DATEFORMAT'] . ''; + $tz_select = tz_select($data['tz'], true, false); $template->assign_vars(array( 'ERROR' => (sizeof($error)) ? implode('
          ', $error) : '', @@ -153,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' => $tz_select['tz_select'], + 'S_TZ_DATE_OPTIONS' => $tz_select['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/language/en/common.php b/phpBB/language/en/common.php index bbafb54108..d0afb846b4 100644 --- a/phpBB/language/en/common.php +++ b/phpBB/language/en/common.php @@ -42,6 +42,7 @@ $lang = array_merge($lang, array( 'TRANSLATION_INFO' => '', 'DIRECTION' => 'ltr', 'DATE_FORMAT' => '|d M Y|', // 01 Jan 2007 (with Relative days enabled) + 'DATETIME_FORMAT' => '|d M Y, H:i|', // 01 Jan 2007, 13:37 (with Relative days enabled) 'USER_LANG' => 'en-gb', // You can define different rules for the determination of plural forms here. diff --git a/phpBB/language/en/ucp.php b/phpBB/language/en/ucp.php index f9558bc6d3..64a434d89c 100644 --- a/phpBB/language/en/ucp.php +++ b/phpBB/language/en/ucp.php @@ -412,6 +412,7 @@ $lang = array_merge($lang, array( 'SIGNATURE_EXPLAIN' => 'This is a block of text that can be added to posts you make. There is a %d character limit.', 'SIGNATURE_PREVIEW' => 'Your signature will appear like this in posts', 'SIGNATURE_TOO_LONG' => 'Your signature is too long.', + 'SELECT_CURRENT_TIME' => 'Select current time', 'SELECT_TIMEZONE' => 'Select timezone', 'SORT' => 'Sort', 'SORT_COMMENT' => 'File comment', @@ -422,7 +423,9 @@ $lang = array_merge($lang, array( 'SORT_SIZE' => 'File size', 'TIMEZONE' => 'Timezone', + 'TIMEZONE_DATE_SUGGESTION' => 'Suggestion: %s', 'TIMEZONE_INVALID' => 'The timezone you selected is invalid.', + 'TIMEZONE_SELECTED' => '(currently selected)', 'TO' => 'To', 'TOO_MANY_RECIPIENTS' => 'You tried to send a private message to too many recipients.', 'TOO_MANY_REGISTERS' => 'You have exceeded the maximum number of registration attempts for this session. Please try again later.', diff --git a/phpBB/styles/prosilver/template/timezone.js b/phpBB/styles/prosilver/template/timezone.js index 5d07b1d3ad..deebbf36a8 100644 --- a/phpBB/styles/prosilver/template/timezone.js +++ b/phpBB/styles/prosilver/template/timezone.js @@ -1,10 +1,37 @@ -function phpbb_preselect_tz_select() +function phpbb_switch_tz_date(keep_selection) { - var selector = document.getElementsByClassName('tz_select')[0]; - if (selector.value) - { - return; + var timezone_groups = document.getElementById("timezone"); + for (var i = 0; i < timezone_groups.childElementCount; i++) { + if (timezone_groups.children[i].tagName == "OPTGROUP" && + timezone_groups.children[i].label != document.getElementById("tz_date").value) + { + timezone_groups.children[i].style.display = "none"; + } + else if (timezone_groups.children[i].tagName == "OPTGROUP") + { + // Display other options + timezone_groups.children[i].style.display = "block"; + } } + if (typeof keep_selection !== 'undefined') + { + if (!keep_selection) + { + timezone_groups.children[0].selected = true; + } + } +} + +function phpbb_enable_tz_dates() +{ + var tz_select_date = document.getElementById("tz_select_date"); + tz_select_date.style.display = "block"; +} + +function phpbb_preselect_tz_select(force_selector, l_suggestion) +{ + + var selector = document.getElementById('tz_date'); // The offset returned here is in minutes and negated. // http://www.w3schools.com/jsref/jsref_getTimezoneOffset.asp var offset = (new Date()).getTimezoneOffset(); @@ -42,12 +69,26 @@ function phpbb_preselect_tz_select() var option = selector.options[i]; if (option.value.substring(0, prefix_length) == prefix) { - // Firefox scrolls the selector only to put the option into view; - // for negative-offset timezones, this means the first timezone - // of a particular offset will be the bottom one, and selected, - // with all other timezones not visible. Not much can be done - // about that here unfortunately. - option.selected = true; + if (selector.value && selector.value != option.value && !force_selector) + { + // We do not select the option for the user, but notify him, + // that we would suggest a different setting. + document.getElementById("tz_select_date_suggest").style.display = "inline"; + document.getElementById("tz_select_date_suggest").title = l_suggestion.replace("%s", option.innerHTML); + document.getElementById("tz_select_date_suggest").innerHTML = l_suggestion.replace("%s", option.innerHTML.substring(0, 9)); + phpbb_switch_tz_date(true); + } + else + { + // Firefox scrolls the selector only to put the option into view; + // for negative-offset timezones, this means the first timezone + // of a particular offset will be the bottom one, and selected, + // with all other timezones not visible. Not much can be done + // about that here unfortunately. + option.selected = true; + phpbb_switch_tz_date(!force_selector); + document.getElementById("tz_select_date_suggest").style.display = "none"; + } break; } } diff --git a/phpBB/styles/prosilver/template/ucp_prefs_personal.html b/phpBB/styles/prosilver/template/ucp_prefs_personal.html index b09e7b1591..c798b1a1f2 100644 --- a/phpBB/styles/prosilver/template/ucp_prefs_personal.html +++ b/phpBB/styles/prosilver/template/ucp_prefs_personal.html @@ -75,6 +75,13 @@
          +
          + + {S_TZ_DATE_OPTIONS} + + +
          + +
          + + + + + +
          +
          diff --git a/phpBB/styles/prosilver/template/ucp_prefs_personal.html b/phpBB/styles/prosilver/template/ucp_prefs_personal.html index c798b1a1f2..29c01e03b9 100644 --- a/phpBB/styles/prosilver/template/ucp_prefs_personal.html +++ b/phpBB/styles/prosilver/template/ucp_prefs_personal.html @@ -73,22 +73,7 @@
          -
          -
          - -
          - -
          -
          +

          {L_BOARD_DATE_FORMAT_EXPLAIN}
          @@ -146,8 +131,4 @@ // ]]> - - - - diff --git a/phpBB/styles/prosilver/template/ucp_register.html b/phpBB/styles/prosilver/template/ucp_register.html index 95e125fdea..994356efe6 100644 --- a/phpBB/styles/prosilver/template/ucp_register.html +++ b/phpBB/styles/prosilver/template/ucp_register.html @@ -53,15 +53,8 @@
          -
          -
          -
          - -
          -
          + +
          {L_ITEMS_REQUIRED}
          From a6bace039ab18ce5138a7f6ffa6d74c543bd6222 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 12 Jun 2012 19:51:55 +0200 Subject: [PATCH 288/441] [feature/new-tz-handling] Fix timezone selection in subsilver2 PHPBB3-9558 --- phpBB/styles/subsilver2/template/timezone.js | 95 +++++++++++++++++++ .../subsilver2/template/timezone_option.html | 22 +++++ .../template/ucp_prefs_personal.html | 7 +- .../subsilver2/template/ucp_register.html | 7 +- 4 files changed, 121 insertions(+), 10 deletions(-) create mode 100644 phpBB/styles/subsilver2/template/timezone.js create mode 100644 phpBB/styles/subsilver2/template/timezone_option.html diff --git a/phpBB/styles/subsilver2/template/timezone.js b/phpBB/styles/subsilver2/template/timezone.js new file mode 100644 index 0000000000..deebbf36a8 --- /dev/null +++ b/phpBB/styles/subsilver2/template/timezone.js @@ -0,0 +1,95 @@ +function phpbb_switch_tz_date(keep_selection) +{ + var timezone_groups = document.getElementById("timezone"); + for (var i = 0; i < timezone_groups.childElementCount; i++) { + if (timezone_groups.children[i].tagName == "OPTGROUP" && + timezone_groups.children[i].label != document.getElementById("tz_date").value) + { + timezone_groups.children[i].style.display = "none"; + } + else if (timezone_groups.children[i].tagName == "OPTGROUP") + { + // Display other options + timezone_groups.children[i].style.display = "block"; + } + } + if (typeof keep_selection !== 'undefined') + { + if (!keep_selection) + { + timezone_groups.children[0].selected = true; + } + } +} + +function phpbb_enable_tz_dates() +{ + var tz_select_date = document.getElementById("tz_select_date"); + tz_select_date.style.display = "block"; +} + +function phpbb_preselect_tz_select(force_selector, l_suggestion) +{ + + var selector = document.getElementById('tz_date'); + // The offset returned here is in minutes and negated. + // http://www.w3schools.com/jsref/jsref_getTimezoneOffset.asp + var offset = (new Date()).getTimezoneOffset(); + if (offset < 0) + { + var sign = '+'; + offset = -offset; + } + else + { + var sign = '-'; + } + var minutes = offset % 60; + var hours = (offset - minutes) / 60; + if (hours < 10) + { + hours = '0' + hours.toString(); + } + else + { + hours = hours.toString(); + } + if (minutes < 10) + { + minutes = '0' + minutes.toString(); + } + else + { + minutes = minutes.toString(); + } + var prefix = 'GMT' + sign + hours + ':' + minutes; + var prefix_length = prefix.length; + for (var i = 0; i < selector.options.length; ++i) + { + var option = selector.options[i]; + if (option.value.substring(0, prefix_length) == prefix) + { + if (selector.value && selector.value != option.value && !force_selector) + { + // We do not select the option for the user, but notify him, + // that we would suggest a different setting. + document.getElementById("tz_select_date_suggest").style.display = "inline"; + document.getElementById("tz_select_date_suggest").title = l_suggestion.replace("%s", option.innerHTML); + document.getElementById("tz_select_date_suggest").innerHTML = l_suggestion.replace("%s", option.innerHTML.substring(0, 9)); + phpbb_switch_tz_date(true); + } + else + { + // Firefox scrolls the selector only to put the option into view; + // for negative-offset timezones, this means the first timezone + // of a particular offset will be the bottom one, and selected, + // with all other timezones not visible. Not much can be done + // about that here unfortunately. + option.selected = true; + phpbb_switch_tz_date(!force_selector); + document.getElementById("tz_select_date_suggest").style.display = "none"; + } + break; + } + } +} diff --git a/phpBB/styles/subsilver2/template/timezone_option.html b/phpBB/styles/subsilver2/template/timezone_option.html new file mode 100644 index 0000000000..184722ef7e --- /dev/null +++ b/phpBB/styles/subsilver2/template/timezone_option.html @@ -0,0 +1,22 @@ + + {L_BOARD_TIMEZONE}: + + + + + + + + + + + diff --git a/phpBB/styles/subsilver2/template/ucp_prefs_personal.html b/phpBB/styles/subsilver2/template/ucp_prefs_personal.html index 357e1fe100..bf0e67d68b 100644 --- a/phpBB/styles/subsilver2/template/ucp_prefs_personal.html +++ b/phpBB/styles/subsilver2/template/ucp_prefs_personal.html @@ -71,12 +71,7 @@ - - {L_BOARD_TIMEZONE}: - - - - + {L_BOARD_DATE_FORMAT}:
          {L_BOARD_DATE_FORMAT_EXPLAIN} diff --git a/phpBB/styles/subsilver2/template/ucp_register.html b/phpBB/styles/subsilver2/template/ucp_register.html index 0c3533292d..095c97ed49 100644 --- a/phpBB/styles/subsilver2/template/ucp_register.html +++ b/phpBB/styles/subsilver2/template/ucp_register.html @@ -53,10 +53,9 @@ {L_LANGUAGE}: - - {L_TIMEZONE}: - - + + + {L_ITEMS_REQUIRED} From 435573a9cb82060ddae673aa1e1572bd78c7741d Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 12 Jun 2012 19:52:33 +0200 Subject: [PATCH 289/441] [feature/new-tz-handling] Fix Timezone selection on registration page PHPBB3-9558 --- phpBB/includes/ucp/ucp_register.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/phpBB/includes/ucp/ucp_register.php b/phpBB/includes/ucp/ucp_register.php index ac002a26c2..804bd2e0e2 100644 --- a/phpBB/includes/ucp/ucp_register.php +++ b/phpBB/includes/ucp/ucp_register.php @@ -442,6 +442,7 @@ class ucp_register break; } + $tz_select = tz_select($data['tz'], true, false); $template->assign_vars(array( 'ERROR' => (sizeof($error)) ? implode('
          ', $error) : '', 'USERNAME' => $data['username'], @@ -454,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'], true), + 'S_TZ_OPTIONS' => $tz_select['tz_select'], + 'S_TZ_DATE_OPTIONS' => $tz_select['tz_dates'], 'S_CONFIRM_REFRESH' => ($config['enable_confirm'] && $config['confirm_refresh']) ? true : false, 'S_REGISTRATION' => true, 'S_COPPA' => $coppa, From 5f96e5d374d1702d3d81591b7c69ede1cafebfa7 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 12 Jun 2012 19:54:26 +0200 Subject: [PATCH 290/441] [feature/new-tz-handling] Fix timezone option when editing a user in the ACP PHPBB3-9558 --- phpBB/adm/style/acp_users_prefs.html | 5 +---- phpBB/adm/style/timezone.js | 29 ++++++++++++++++++++++++++++ phpBB/adm/style/timezone_option.html | 20 +++++++++++++++++++ phpBB/includes/acp/acp_users.php | 4 +++- phpBB/language/en/acp/common.php | 2 ++ 5 files changed, 55 insertions(+), 5 deletions(-) create mode 100644 phpBB/adm/style/timezone.js create mode 100644 phpBB/adm/style/timezone_option.html diff --git a/phpBB/adm/style/acp_users_prefs.html b/phpBB/adm/style/acp_users_prefs.html index 90db62984e..9439f0cf03 100644 --- a/phpBB/adm/style/acp_users_prefs.html +++ b/phpBB/adm/style/acp_users_prefs.html @@ -52,10 +52,7 @@
          -
          -
          -
          -
          +

          {L_BOARD_DATE_FORMAT_EXPLAIN}
          diff --git a/phpBB/adm/style/timezone.js b/phpBB/adm/style/timezone.js new file mode 100644 index 0000000000..d02c965ab5 --- /dev/null +++ b/phpBB/adm/style/timezone.js @@ -0,0 +1,29 @@ +function phpbb_switch_tz_date(keep_selection) +{ + var timezone_groups = document.getElementById("timezone"); + for (var i = 0; i < timezone_groups.childElementCount; i++) { + if (timezone_groups.children[i].tagName == "OPTGROUP" && + timezone_groups.children[i].label != document.getElementById("tz_date").value) + { + timezone_groups.children[i].style.display = "none"; + } + else if (timezone_groups.children[i].tagName == "OPTGROUP") + { + // Display other options + timezone_groups.children[i].style.display = "block"; + } + } + if (typeof keep_selection !== 'undefined') + { + if (!keep_selection) + { + timezone_groups.children[0].selected = true; + } + } +} + +function phpbb_enable_tz_dates() +{ + var tz_select_date = document.getElementById("tz_select_date"); + tz_select_date.style.display = "block"; +} diff --git a/phpBB/adm/style/timezone_option.html b/phpBB/adm/style/timezone_option.html new file mode 100644 index 0000000000..12e6e3700a --- /dev/null +++ b/phpBB/adm/style/timezone_option.html @@ -0,0 +1,20 @@ +
          +
          + + + +
          + + + + +
          +
          diff --git a/phpBB/includes/acp/acp_users.php b/phpBB/includes/acp/acp_users.php index b863a9ed80..949109abaf 100644 --- a/phpBB/includes/acp/acp_users.php +++ b/phpBB/includes/acp/acp_users.php @@ -1639,6 +1639,7 @@ class acp_users ${'s_sort_' . $sort_option . '_dir'} .= ''; } + $tz_select = tz_select($data['tz'], true, false); $template->assign_vars(array( 'S_PREFS' => true, 'S_JABBER_DISABLED' => ($config['jab_enable'] && $user_row['user_jabber'] && @extension_loaded('xml')) ? false : true, @@ -1678,7 +1679,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' => $tz_select['tz_select'], + 'S_TZ_DATE_OPTIONS' => $tz_select['tz_dates'], ) ); diff --git a/phpBB/language/en/acp/common.php b/phpBB/language/en/acp/common.php index dc35969955..5cebcc89d7 100644 --- a/phpBB/language/en/acp/common.php +++ b/phpBB/language/en/acp/common.php @@ -401,6 +401,8 @@ $lang = array_merge($lang, array( 'STATISTIC' => 'Statistic', 'STATISTIC_RESYNC_OPTIONS' => 'Resynchronise or reset statistics', + 'TIMEZONE_INVALID' => 'The timezone you selected is invalid.', + 'TIMEZONE_SELECTED' => '(currently selected)', 'TOPICS_PER_DAY' => 'Topics per day', 'UPLOAD_DIR_SIZE' => 'Size of posted attachments', From 5441ee1ee489ef9ad1727f110c440dde5417cc1f Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Sun, 17 Jun 2012 16:54:12 +0200 Subject: [PATCH 291/441] [feature/new-tz-handling] Use jQuery and INCLUDEJS for javascript PHPBB3-9558 --- phpBB/adm/style/timezone.js | 28 +++++------ phpBB/adm/style/timezone_option.html | 3 +- phpBB/styles/prosilver/template/timezone.js | 47 ++++++++++--------- .../prosilver/template/timezone_option.html | 8 ++-- phpBB/styles/subsilver2/template/timezone.js | 47 ++++++++++--------- .../subsilver2/template/timezone_option.html | 8 ++-- 6 files changed, 72 insertions(+), 69 deletions(-) diff --git a/phpBB/adm/style/timezone.js b/phpBB/adm/style/timezone.js index d02c965ab5..a1ffeb17c5 100644 --- a/phpBB/adm/style/timezone.js +++ b/phpBB/adm/style/timezone.js @@ -1,29 +1,27 @@ function phpbb_switch_tz_date(keep_selection) { - var timezone_groups = document.getElementById("timezone"); - for (var i = 0; i < timezone_groups.childElementCount; i++) { - if (timezone_groups.children[i].tagName == "OPTGROUP" && - timezone_groups.children[i].label != document.getElementById("tz_date").value) - { - timezone_groups.children[i].style.display = "none"; - } - else if (timezone_groups.children[i].tagName == "OPTGROUP") - { - // Display other options - timezone_groups.children[i].style.display = "block"; - } + $('#timezone > optgroup').css("display", "none"); + $("#timezone > optgroup[label='" + $('#tz_date').val() + "']").css("display", "block"); + + if ($("#timezone > optgroup[label='" + $('#tz_date').val() + "'] > option").size() == 1) + { + // If there is only one timezone for the selected date, we just select that automatically. + $("#timezone > optgroup[label='" + $('#tz_date').val() + "'] > option:first").attr("selected", true); + keep_selection = true; } + if (typeof keep_selection !== 'undefined') { if (!keep_selection) { - timezone_groups.children[0].selected = true; + $('#timezone > option:first').attr("selected", true); } } } function phpbb_enable_tz_dates() { - var tz_select_date = document.getElementById("tz_select_date"); - tz_select_date.style.display = "block"; + $('#tz_select_date').css("display", "block"); } + +phpbb_enable_tz_dates(); diff --git a/phpBB/adm/style/timezone_option.html b/phpBB/adm/style/timezone_option.html index 12e6e3700a..e12219b1c0 100644 --- a/phpBB/adm/style/timezone_option.html +++ b/phpBB/adm/style/timezone_option.html @@ -14,7 +14,6 @@ {S_TZ_OPTIONS} - - +
          diff --git a/phpBB/styles/prosilver/template/timezone.js b/phpBB/styles/prosilver/template/timezone.js index deebbf36a8..f73a82a063 100644 --- a/phpBB/styles/prosilver/template/timezone.js +++ b/phpBB/styles/prosilver/template/timezone.js @@ -1,37 +1,32 @@ function phpbb_switch_tz_date(keep_selection) { - var timezone_groups = document.getElementById("timezone"); - for (var i = 0; i < timezone_groups.childElementCount; i++) { - if (timezone_groups.children[i].tagName == "OPTGROUP" && - timezone_groups.children[i].label != document.getElementById("tz_date").value) - { - timezone_groups.children[i].style.display = "none"; - } - else if (timezone_groups.children[i].tagName == "OPTGROUP") - { - // Display other options - timezone_groups.children[i].style.display = "block"; - } + $('#timezone > optgroup').css("display", "none"); + $("#timezone > optgroup[label='" + $('#tz_date').val() + "']").css("display", "block"); + + if ($("#timezone > optgroup[label='" + $('#tz_date').val() + "'] > option").size() == 1) + { + // If there is only one timezone for the selected date, we just select that automatically. + $("#timezone > optgroup[label='" + $('#tz_date').val() + "'] > option:first").attr("selected", true); + keep_selection = true; } + if (typeof keep_selection !== 'undefined') { if (!keep_selection) { - timezone_groups.children[0].selected = true; + $('#timezone > option:first').attr("selected", true); } } } function phpbb_enable_tz_dates() { - var tz_select_date = document.getElementById("tz_select_date"); - tz_select_date.style.display = "block"; + $('#tz_select_date').css("display", "block"); } function phpbb_preselect_tz_select(force_selector, l_suggestion) { - var selector = document.getElementById('tz_date'); // The offset returned here is in minutes and negated. // http://www.w3schools.com/jsref/jsref_getTimezoneOffset.asp var offset = (new Date()).getTimezoneOffset(); @@ -62,20 +57,23 @@ function phpbb_preselect_tz_select(force_selector, l_suggestion) { minutes = minutes.toString(); } + var prefix = 'GMT' + sign + hours + ':' + minutes; var prefix_length = prefix.length; - for (var i = 0; i < selector.options.length; ++i) + + var selector_options = $('#tz_date > option'); + for (var i = 0; i < selector_options.length; ++i) { - var option = selector.options[i]; + var option = selector_options[i]; if (option.value.substring(0, prefix_length) == prefix) { - if (selector.value && selector.value != option.value && !force_selector) + if ($('#tz_date').val() != option.value && !force_selector) { // We do not select the option for the user, but notify him, // that we would suggest a different setting. - document.getElementById("tz_select_date_suggest").style.display = "inline"; - document.getElementById("tz_select_date_suggest").title = l_suggestion.replace("%s", option.innerHTML); - document.getElementById("tz_select_date_suggest").innerHTML = l_suggestion.replace("%s", option.innerHTML.substring(0, 9)); + $('#tz_select_date_suggest').css("display", "inline"); + $('#tz_select_date_suggest').attr("title", l_suggestion.replace("%s", option.innerHTML)); + $('#tz_select_date_suggest').html(l_suggestion.replace("%s", option.innerHTML.substring(0, 9))); phpbb_switch_tz_date(true); } else @@ -87,9 +85,12 @@ function phpbb_preselect_tz_select(force_selector, l_suggestion) // about that here unfortunately. option.selected = true; phpbb_switch_tz_date(!force_selector); - document.getElementById("tz_select_date_suggest").style.display = "none"; + $('#tz_select_date_suggest').css("display", "none"); } break; } } } + +phpbb_enable_tz_dates(); +phpbb_preselect_tz_select(is_registration, l_timezone_date_suggestion); diff --git a/phpBB/styles/prosilver/template/timezone_option.html b/phpBB/styles/prosilver/template/timezone_option.html index 6a6a937977..3a08de1a46 100644 --- a/phpBB/styles/prosilver/template/timezone_option.html +++ b/phpBB/styles/prosilver/template/timezone_option.html @@ -15,8 +15,10 @@ {S_TZ_OPTIONS} - - - + + diff --git a/phpBB/styles/subsilver2/template/timezone.js b/phpBB/styles/subsilver2/template/timezone.js index deebbf36a8..f73a82a063 100644 --- a/phpBB/styles/subsilver2/template/timezone.js +++ b/phpBB/styles/subsilver2/template/timezone.js @@ -1,37 +1,32 @@ function phpbb_switch_tz_date(keep_selection) { - var timezone_groups = document.getElementById("timezone"); - for (var i = 0; i < timezone_groups.childElementCount; i++) { - if (timezone_groups.children[i].tagName == "OPTGROUP" && - timezone_groups.children[i].label != document.getElementById("tz_date").value) - { - timezone_groups.children[i].style.display = "none"; - } - else if (timezone_groups.children[i].tagName == "OPTGROUP") - { - // Display other options - timezone_groups.children[i].style.display = "block"; - } + $('#timezone > optgroup').css("display", "none"); + $("#timezone > optgroup[label='" + $('#tz_date').val() + "']").css("display", "block"); + + if ($("#timezone > optgroup[label='" + $('#tz_date').val() + "'] > option").size() == 1) + { + // If there is only one timezone for the selected date, we just select that automatically. + $("#timezone > optgroup[label='" + $('#tz_date').val() + "'] > option:first").attr("selected", true); + keep_selection = true; } + if (typeof keep_selection !== 'undefined') { if (!keep_selection) { - timezone_groups.children[0].selected = true; + $('#timezone > option:first').attr("selected", true); } } } function phpbb_enable_tz_dates() { - var tz_select_date = document.getElementById("tz_select_date"); - tz_select_date.style.display = "block"; + $('#tz_select_date').css("display", "block"); } function phpbb_preselect_tz_select(force_selector, l_suggestion) { - var selector = document.getElementById('tz_date'); // The offset returned here is in minutes and negated. // http://www.w3schools.com/jsref/jsref_getTimezoneOffset.asp var offset = (new Date()).getTimezoneOffset(); @@ -62,20 +57,23 @@ function phpbb_preselect_tz_select(force_selector, l_suggestion) { minutes = minutes.toString(); } + var prefix = 'GMT' + sign + hours + ':' + minutes; var prefix_length = prefix.length; - for (var i = 0; i < selector.options.length; ++i) + + var selector_options = $('#tz_date > option'); + for (var i = 0; i < selector_options.length; ++i) { - var option = selector.options[i]; + var option = selector_options[i]; if (option.value.substring(0, prefix_length) == prefix) { - if (selector.value && selector.value != option.value && !force_selector) + if ($('#tz_date').val() != option.value && !force_selector) { // We do not select the option for the user, but notify him, // that we would suggest a different setting. - document.getElementById("tz_select_date_suggest").style.display = "inline"; - document.getElementById("tz_select_date_suggest").title = l_suggestion.replace("%s", option.innerHTML); - document.getElementById("tz_select_date_suggest").innerHTML = l_suggestion.replace("%s", option.innerHTML.substring(0, 9)); + $('#tz_select_date_suggest').css("display", "inline"); + $('#tz_select_date_suggest').attr("title", l_suggestion.replace("%s", option.innerHTML)); + $('#tz_select_date_suggest').html(l_suggestion.replace("%s", option.innerHTML.substring(0, 9))); phpbb_switch_tz_date(true); } else @@ -87,9 +85,12 @@ function phpbb_preselect_tz_select(force_selector, l_suggestion) // about that here unfortunately. option.selected = true; phpbb_switch_tz_date(!force_selector); - document.getElementById("tz_select_date_suggest").style.display = "none"; + $('#tz_select_date_suggest').css("display", "none"); } break; } } } + +phpbb_enable_tz_dates(); +phpbb_preselect_tz_select(is_registration, l_timezone_date_suggestion); diff --git a/phpBB/styles/subsilver2/template/timezone_option.html b/phpBB/styles/subsilver2/template/timezone_option.html index 184722ef7e..0806186c9c 100644 --- a/phpBB/styles/subsilver2/template/timezone_option.html +++ b/phpBB/styles/subsilver2/template/timezone_option.html @@ -15,8 +15,10 @@ {S_TZ_OPTIONS} - - - + + From 8d65f1f7d263d9f6e76cbac2765da02a0877c87f Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Mon, 18 Jun 2012 10:20:15 +0200 Subject: [PATCH 292/441] [feature/new-tz-handling] Add doc blocks to js functions PHPBB3-9558 --- phpBB/adm/style/timezone.js | 8 ++++++++ phpBB/styles/prosilver/template/timezone.js | 19 ++++++++++++++----- phpBB/styles/subsilver2/template/timezone.js | 19 ++++++++++++++----- 3 files changed, 36 insertions(+), 10 deletions(-) diff --git a/phpBB/adm/style/timezone.js b/phpBB/adm/style/timezone.js index a1ffeb17c5..d1667699da 100644 --- a/phpBB/adm/style/timezone.js +++ b/phpBB/adm/style/timezone.js @@ -1,3 +1,8 @@ +/** +* Hide the optgroups that are not the selected timezone +* +* @param bool keep_selection Shall we keep the value selected, or shall the user be forced to repick one. +*/ function phpbb_switch_tz_date(keep_selection) { $('#timezone > optgroup').css("display", "none"); @@ -19,6 +24,9 @@ function phpbb_switch_tz_date(keep_selection) } } +/** +* Display the date/time select +*/ function phpbb_enable_tz_dates() { $('#tz_select_date').css("display", "block"); diff --git a/phpBB/styles/prosilver/template/timezone.js b/phpBB/styles/prosilver/template/timezone.js index f73a82a063..b91aae6244 100644 --- a/phpBB/styles/prosilver/template/timezone.js +++ b/phpBB/styles/prosilver/template/timezone.js @@ -1,3 +1,8 @@ +/** +* Hide the optgroups that are not the selected timezone +* +* @param bool keep_selection Shall we keep the value selected, or shall the user be forced to repick one. +*/ function phpbb_switch_tz_date(keep_selection) { $('#timezone > optgroup').css("display", "none"); @@ -19,11 +24,20 @@ function phpbb_switch_tz_date(keep_selection) } } +/** +* Display the date/time select +*/ function phpbb_enable_tz_dates() { $('#tz_select_date').css("display", "block"); } +/** +* Preselect a date/time or suggest one, if it is not picked. +* +* @param bool force_selector Shall we select the suggestion? +* @param string l_suggestion The language string which we use, to display the selection +*/ function phpbb_preselect_tz_select(force_selector, l_suggestion) { @@ -78,11 +92,6 @@ function phpbb_preselect_tz_select(force_selector, l_suggestion) } else { - // Firefox scrolls the selector only to put the option into view; - // for negative-offset timezones, this means the first timezone - // of a particular offset will be the bottom one, and selected, - // with all other timezones not visible. Not much can be done - // about that here unfortunately. option.selected = true; phpbb_switch_tz_date(!force_selector); $('#tz_select_date_suggest').css("display", "none"); diff --git a/phpBB/styles/subsilver2/template/timezone.js b/phpBB/styles/subsilver2/template/timezone.js index f73a82a063..b91aae6244 100644 --- a/phpBB/styles/subsilver2/template/timezone.js +++ b/phpBB/styles/subsilver2/template/timezone.js @@ -1,3 +1,8 @@ +/** +* Hide the optgroups that are not the selected timezone +* +* @param bool keep_selection Shall we keep the value selected, or shall the user be forced to repick one. +*/ function phpbb_switch_tz_date(keep_selection) { $('#timezone > optgroup').css("display", "none"); @@ -19,11 +24,20 @@ function phpbb_switch_tz_date(keep_selection) } } +/** +* Display the date/time select +*/ function phpbb_enable_tz_dates() { $('#tz_select_date').css("display", "block"); } +/** +* Preselect a date/time or suggest one, if it is not picked. +* +* @param bool force_selector Shall we select the suggestion? +* @param string l_suggestion The language string which we use, to display the selection +*/ function phpbb_preselect_tz_select(force_selector, l_suggestion) { @@ -78,11 +92,6 @@ function phpbb_preselect_tz_select(force_selector, l_suggestion) } else { - // Firefox scrolls the selector only to put the option into view; - // for negative-offset timezones, this means the first timezone - // of a particular offset will be the bottom one, and selected, - // with all other timezones not visible. Not much can be done - // about that here unfortunately. option.selected = true; phpbb_switch_tz_date(!force_selector); $('#tz_select_date_suggest').css("display", "none"); From c21275fa951bd4d8608cc335a5c39d9a05bc4904 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Mon, 18 Jun 2012 10:53:47 +0200 Subject: [PATCH 293/441] [feature/new-tz-handling] Use js and data attributes to create the events PHPBB3-9558 --- phpBB/styles/prosilver/template/timezone.js | 13 ++++++++----- .../styles/prosilver/template/timezone_option.html | 6 +----- phpBB/styles/subsilver2/template/timezone.js | 13 ++++++++----- .../styles/subsilver2/template/timezone_option.html | 2 +- 4 files changed, 18 insertions(+), 16 deletions(-) diff --git a/phpBB/styles/prosilver/template/timezone.js b/phpBB/styles/prosilver/template/timezone.js index b91aae6244..b8d3c2f152 100644 --- a/phpBB/styles/prosilver/template/timezone.js +++ b/phpBB/styles/prosilver/template/timezone.js @@ -36,9 +36,8 @@ function phpbb_enable_tz_dates() * Preselect a date/time or suggest one, if it is not picked. * * @param bool force_selector Shall we select the suggestion? -* @param string l_suggestion The language string which we use, to display the selection */ -function phpbb_preselect_tz_select(force_selector, l_suggestion) +function phpbb_preselect_tz_select(force_selector) { // The offset returned here is in minutes and negated. @@ -86,8 +85,8 @@ function phpbb_preselect_tz_select(force_selector, l_suggestion) // We do not select the option for the user, but notify him, // that we would suggest a different setting. $('#tz_select_date_suggest').css("display", "inline"); - $('#tz_select_date_suggest').attr("title", l_suggestion.replace("%s", option.innerHTML)); - $('#tz_select_date_suggest').html(l_suggestion.replace("%s", option.innerHTML.substring(0, 9))); + $('#tz_select_date_suggest').attr("title", $('#tz_select_date_suggest').attr('data-l-suggestion').replace("%s", option.innerHTML)); + $('#tz_select_date_suggest').attr("value", $('#tz_select_date_suggest').attr('data-l-suggestion').replace("%s", option.innerHTML.substring(0, 9))); phpbb_switch_tz_date(true); } else @@ -101,5 +100,9 @@ function phpbb_preselect_tz_select(force_selector, l_suggestion) } } +$('#tz_select_date_suggest').click(function(){ + phpbb_preselect_tz_select(true, ''); +}); + phpbb_enable_tz_dates(); -phpbb_preselect_tz_select(is_registration, l_timezone_date_suggestion); +phpbb_preselect_tz_select($('#tz_select_date_suggest').attr('data-is-registration') == "true"); diff --git a/phpBB/styles/prosilver/template/timezone_option.html b/phpBB/styles/prosilver/template/timezone_option.html index 3a08de1a46..8840e9e5e8 100644 --- a/phpBB/styles/prosilver/template/timezone_option.html +++ b/phpBB/styles/prosilver/template/timezone_option.html @@ -6,7 +6,7 @@ {S_TZ_DATE_OPTIONS} - +
          @@ -15,10 +15,6 @@ {S_TZ_OPTIONS} -
          diff --git a/phpBB/styles/subsilver2/template/timezone.js b/phpBB/styles/subsilver2/template/timezone.js index b91aae6244..b8d3c2f152 100644 --- a/phpBB/styles/subsilver2/template/timezone.js +++ b/phpBB/styles/subsilver2/template/timezone.js @@ -36,9 +36,8 @@ function phpbb_enable_tz_dates() * Preselect a date/time or suggest one, if it is not picked. * * @param bool force_selector Shall we select the suggestion? -* @param string l_suggestion The language string which we use, to display the selection */ -function phpbb_preselect_tz_select(force_selector, l_suggestion) +function phpbb_preselect_tz_select(force_selector) { // The offset returned here is in minutes and negated. @@ -86,8 +85,8 @@ function phpbb_preselect_tz_select(force_selector, l_suggestion) // We do not select the option for the user, but notify him, // that we would suggest a different setting. $('#tz_select_date_suggest').css("display", "inline"); - $('#tz_select_date_suggest').attr("title", l_suggestion.replace("%s", option.innerHTML)); - $('#tz_select_date_suggest').html(l_suggestion.replace("%s", option.innerHTML.substring(0, 9))); + $('#tz_select_date_suggest').attr("title", $('#tz_select_date_suggest').attr('data-l-suggestion').replace("%s", option.innerHTML)); + $('#tz_select_date_suggest').attr("value", $('#tz_select_date_suggest').attr('data-l-suggestion').replace("%s", option.innerHTML.substring(0, 9))); phpbb_switch_tz_date(true); } else @@ -101,5 +100,9 @@ function phpbb_preselect_tz_select(force_selector, l_suggestion) } } +$('#tz_select_date_suggest').click(function(){ + phpbb_preselect_tz_select(true, ''); +}); + phpbb_enable_tz_dates(); -phpbb_preselect_tz_select(is_registration, l_timezone_date_suggestion); +phpbb_preselect_tz_select($('#tz_select_date_suggest').attr('data-is-registration') == "true"); diff --git a/phpBB/styles/subsilver2/template/timezone_option.html b/phpBB/styles/subsilver2/template/timezone_option.html index 0806186c9c..affeee91ac 100644 --- a/phpBB/styles/subsilver2/template/timezone_option.html +++ b/phpBB/styles/subsilver2/template/timezone_option.html @@ -7,7 +7,7 @@ {S_TZ_DATE_OPTIONS}
          -
          +
        + From bbd3204a9cf15155ccbc1c9270575d2ba44097cb Mon Sep 17 00:00:00 2001 From: Dhruv Goel Date: Tue, 19 Jun 2012 20:03:57 +0530 Subject: [PATCH 304/441] [ticket/9551] uncomment line and change length to 255 incase of partial collation change post_subject field will be changed back to the default collation and length 255. PHPBB3-9551 --- phpBB/includes/search/fulltext_mysql.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/includes/search/fulltext_mysql.php b/phpBB/includes/search/fulltext_mysql.php index 779ec1d216..bd4c003397 100644 --- a/phpBB/includes/search/fulltext_mysql.php +++ b/phpBB/includes/search/fulltext_mysql.php @@ -747,7 +747,7 @@ class fulltext_mysql extends search_backend { if ($db->sql_layer == 'mysqli' || version_compare($db->sql_server_info(true), '4.1.3', '>=')) { - //$alter[] = 'MODIFY post_subject varchar(100) COLLATE utf8_unicode_ci DEFAULT \'\' NOT NULL'; + $alter[] = 'MODIFY post_subject varchar(255) COLLATE utf8_unicode_ci DEFAULT \'\' NOT NULL'; } else { From 3f7d55a0533d0f8e935cb7da4495817a2a76a163 Mon Sep 17 00:00:00 2001 From: Callum Macrae Date: Tue, 19 Jun 2012 17:16:42 +0100 Subject: [PATCH 305/441] [ticket/10801] Fixed quickmod tools. Fixes 10801, 10802, 10807 and 10808. PHPBB3-10801 --- phpBB/styles/prosilver/template/viewtopic_body.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/styles/prosilver/template/viewtopic_body.html b/phpBB/styles/prosilver/template/viewtopic_body.html index 9110cea4e9..1af512732d 100644 --- a/phpBB/styles/prosilver/template/viewtopic_body.html +++ b/phpBB/styles/prosilver/template/viewtopic_body.html @@ -263,7 +263,7 @@ -
        +
        + diff --git a/phpBB/styles/subsilver2/template/timezone.js b/phpBB/styles/subsilver2/template/timezone.js index b8d3c2f152..da0a2b0bfd 100644 --- a/phpBB/styles/subsilver2/template/timezone.js +++ b/phpBB/styles/subsilver2/template/timezone.js @@ -1,108 +1,19 @@ -/** -* Hide the optgroups that are not the selected timezone -* -* @param bool keep_selection Shall we keep the value selected, or shall the user be forced to repick one. -*/ -function phpbb_switch_tz_date(keep_selection) -{ - $('#timezone > optgroup').css("display", "none"); - $("#timezone > optgroup[label='" + $('#tz_date').val() + "']").css("display", "block"); +(function($) { // Avoid conflicts with other libraries - if ($("#timezone > optgroup[label='" + $('#tz_date').val() + "'] > option").size() == 1) - { - // If there is only one timezone for the selected date, we just select that automatically. - $("#timezone > optgroup[label='" + $('#tz_date').val() + "'] > option:first").attr("selected", true); - keep_selection = true; - } - - if (typeof keep_selection !== 'undefined') - { - if (!keep_selection) - { - $('#timezone > option:first').attr("selected", true); - } - } -} - -/** -* Display the date/time select -*/ -function phpbb_enable_tz_dates() -{ - $('#tz_select_date').css("display", "block"); -} - -/** -* Preselect a date/time or suggest one, if it is not picked. -* -* @param bool force_selector Shall we select the suggestion? -*/ -function phpbb_preselect_tz_select(force_selector) -{ - - // The offset returned here is in minutes and negated. - // http://www.w3schools.com/jsref/jsref_getTimezoneOffset.asp - var offset = (new Date()).getTimezoneOffset(); - if (offset < 0) - { - var sign = '+'; - offset = -offset; - } - else - { - var sign = '-'; - } - var minutes = offset % 60; - var hours = (offset - minutes) / 60; - if (hours < 10) - { - hours = '0' + hours.toString(); - } - else - { - hours = hours.toString(); - } - if (minutes < 10) - { - minutes = '0' + minutes.toString(); - } - else - { - minutes = minutes.toString(); - } - - var prefix = 'GMT' + sign + hours + ':' + minutes; - var prefix_length = prefix.length; - - var selector_options = $('#tz_date > option'); - for (var i = 0; i < selector_options.length; ++i) - { - var option = selector_options[i]; - if (option.value.substring(0, prefix_length) == prefix) - { - if ($('#tz_date').val() != option.value && !force_selector) - { - // We do not select the option for the user, but notify him, - // that we would suggest a different setting. - $('#tz_select_date_suggest').css("display", "inline"); - $('#tz_select_date_suggest').attr("title", $('#tz_select_date_suggest').attr('data-l-suggestion').replace("%s", option.innerHTML)); - $('#tz_select_date_suggest').attr("value", $('#tz_select_date_suggest').attr('data-l-suggestion').replace("%s", option.innerHTML.substring(0, 9))); - phpbb_switch_tz_date(true); - } - else - { - option.selected = true; - phpbb_switch_tz_date(!force_selector); - $('#tz_select_date_suggest').css("display", "none"); - } - break; - } - } -} - -$('#tz_select_date_suggest').click(function(){ - phpbb_preselect_tz_select(true, ''); +$('#tz_date').change(function() { + phpbb.timezone_switch_date(false); }); -phpbb_enable_tz_dates(); -phpbb_preselect_tz_select($('#tz_select_date_suggest').attr('data-is-registration') == "true"); +$('#tz_select_date_suggest').click(function(){ + phpbb.timezone_preselect_select(true); +}); + +$(document).ready( + phpbb.timezone_enable_date_selection +); + +$(document).ready( + phpbb.timezone_preselect_select($('#tz_select_date_suggest').attr('data-is-registration') == 'true') +); + +})(jQuery); // Avoid conflicts with other libraries diff --git a/phpBB/styles/subsilver2/template/timezone_option.html b/phpBB/styles/subsilver2/template/timezone_option.html index affeee91ac..3f1e14b33d 100644 --- a/phpBB/styles/subsilver2/template/timezone_option.html +++ b/phpBB/styles/subsilver2/template/timezone_option.html @@ -3,7 +3,7 @@ @@ -250,13 +257,13 @@

        While we very much appreciate receiving bug reports (the more reports the more stable phpBB will be) we ask you carry out a few steps before adding new entries:

          -
        • Firstly determine if your bug is reproduceable, how to determine this depends on the bug in question. Only if the bug is reproduceable it is likely to be a problem with phpBB3 (or in some way connected). If something cannot be reproduced it may turn out to have been your hosting provider working on something, a user doing something silly, etc. Bug reports for non-reproduceable events can slow down our attempts to fix real, reproduceable issues.

        • -
        • Next please read or search through the existing bug reports to see if your bug (or one very similar to it) is already listed. If it is please add to that existing bug rather than creating a new duplicate entry (all this does is slow us down).

        • -
        • Check the forums (use search!) to see if people have discussed anything that sounds similar to what you are seeing. However, as noted above please DO NOT post your particular bug to the forum unless it's non-reproduceable or you are sure it's related to something you have done rather phpBB3.

        • -
        • If no existing bug exists then please feel free to add it.
        • +
        • First, determine if your bug is reproduceable; how to determine this depends on the bug in question. Only if the bug is reproduceable is it likely to be a problem with phpBB3 (or in some way connected). If something cannot be reproduced it may turn out to have been your hosting provider working on something, a user doing something silly, etc. Bug reports for non-reproduceable events can slow down our attempts to fix real, reproduceable issues

        • +
        • Next, please read or search through the existing bug reports to see if your bug (or one very similar to it) is already listed. If it is please add to that existing bug rather than creating a new duplicate entry (all this does is slow us down).

        • +
        • Check the forums (use search!) to see if people have discussed anything that sounds similar to what you are seeing. However, as noted above please DO NOT post your particular bug to the forum unless it's non-reproduceable or you are sure it’s related to something you have done rather than phpBB3

        • +
        • If no existing bug exists then please feel free to add it
        -

        If you do post a new bug (i.e. one that isn't already listed in the bug tracker) firstly make sure you have logged in (your username and password are the same as for the community forums) then please include the following details:

        +

        If you do post a new bug (i.e. one that isn't already listed in the bug tracker) first make sure that you have logged in (your username and password are the same as for the community forums) then please include the following details:

        • Your server type/version, e.g. Apache 1.3.28, IIS 4, Sambar, etc.
        • @@ -294,7 +301,7 @@
          -

          This list is not complete but does represent those bugs which may effect users on a wider scale. Other bugs listed in the tracker have typically been shown to be limited to certain setups or methods of installation, updating and/or conversions.

          +

          This list is not complete but does represent those bugs which may affect users on a wider scale. Other bugs listed in the tracker have typically been shown to be limited to certain setups or methods of installation, updating and/or conversions.

          • Conversions may fail to complete on large boards under some hosts
          • @@ -322,7 +329,7 @@

            Please remember that running any application on a developmental version of PHP can lead to strange/unexpected results which may appear to be bugs in the application (which may not be true). Therefore we recommend you upgrade to the newest stable version of PHP before running phpBB3. If you are running a developmental version of PHP please check any bugs you find on a system running a stable release before submitting.

            -

            This board has been developed and tested under Linux and Windows (amongst others) running Apache using MySQL 3.23, 4.x, 5.x, MSSQL Server 2000, PostgreSQL 7.x, Oracle 8, SQLite and Firebird. Versions of PHP used range from 4.3.3 to 5.4.x without problem.

            +

            This board has been developed and tested under Linux and Windows (amongst others) running Apache using MySQL 3.23, 4.x, 5.x, MSSQL Server 2000, PostgreSQL 7.x, Oracle 8, SQLite 2 and Firebird. Versions of PHP used range from 4.3.3 to 5.4.x without problem.

            7.i. Notice on PHP security issues

            @@ -344,7 +351,7 @@
            -

            This application is opensource software released under the GNU General Public License v2. Please see source code and the docs directory for more details. This package and its contents are Copyright (c) phpBB Group, All Rights Reserved.

            +

            This application is opensource software released under the GNU General Public License v2. Please see source code and the docs directory for more details. This package and its contents are Copyright © phpBB Group, All Rights Reserved.

            From 6203ef0c61b2896d85922d99edebf9df03896126 Mon Sep 17 00:00:00 2001 From: Patrick Webster Date: Fri, 29 Jun 2012 12:10:14 -0500 Subject: [PATCH 326/441] [ticket/10441] Typo PHPBB3-10441 --- phpBB/docs/README.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/docs/README.html b/phpBB/docs/README.html index a4cbe65254..6b6b21d8ae 100644 --- a/phpBB/docs/README.html +++ b/phpBB/docs/README.html @@ -232,7 +232,7 @@

            http://area51.phpbb.com/phpBB/

            -

            Please note that the devolopment forums should NOT be used to seek support for or ask questions about phpBB 2.0.x or phpBB 3.0.x, the main community forums are the place for this. Any such posts will be locked and go unanswered.

            +

            Please note that the development forums should NOT be used to seek support for or ask questions about phpBB 2.0.x or phpBB 3.0.x, the main community forums are the place for this. Any such posts will be locked and go unanswered.

          From 0fd02035d8dd12db4a793af5be564911fca4f900 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Sat, 30 Jun 2012 13:00:41 +0200 Subject: [PATCH 327/441] [ticket/10942] Make unit tests for sql_case simpler PHPBB3-10942 --- tests/dbal/case_test.php | 50 +++++++++++++++------------------------- 1 file changed, 19 insertions(+), 31 deletions(-) diff --git a/tests/dbal/case_test.php b/tests/dbal/case_test.php index 7e966c0ec1..684f2c26a9 100644 --- a/tests/dbal/case_test.php +++ b/tests/dbal/case_test.php @@ -18,47 +18,35 @@ class phpbb_dbal_case_test extends phpbb_database_test_case { $db = $this->new_dbal(); - $sql = 'SELECT config_name, ' . $db->sql_case('is_dynamic = 1', "'" . $db->sql_escape('true') . "'", "'" . $db->sql_escape('false') . "'") . ' AS string + $sql = 'SELECT ' . $db->sql_case('1 = 1', '1', '0') . ' AS bool FROM phpbb_config'; - $result = $db->sql_query($sql); + $result = $db->sql_query_limit($sql, 1); - $db->sql_return_on_error(false); + $this->assertEquals(true, (bool) $db->sql_fetchfield('bool')); - $this->assertEquals(array( - array( - 'config_name' => 'config1', - 'string' => 'false', - ), - array( - 'config_name' => 'config2', - 'string' => 'true', - ), - ), - $db->sql_fetchrowset($result) - ); + $sql = 'SELECT ' . $db->sql_case('1 = 0', '1', '0') . ' AS bool + FROM phpbb_config'; + $result = $db->sql_query_limit($sql, 1); + + $this->assertEquals(false, (bool) $db->sql_fetchfield('bool')); } public function test_case_statement() { $db = $this->new_dbal(); - $sql = 'SELECT config_name, ' . $db->sql_case('is_dynamic = 1', 'is_dynamic', 'config_value') . ' AS string - FROM phpbb_config'; - $result = $db->sql_query($sql); + $sql = 'SELECT ' . $db->sql_case('is_dynamic = 1', 'is_dynamic', '0') . " AS bool + FROM phpbb_config + WHERE is_dynamic = 1"; + $result = $db->sql_query_limit($sql, 1); - $db->sql_return_on_error(false); + $this->assertEquals(true, (bool) $db->sql_fetchfield('bool')); - $this->assertEquals(array( - array( - 'config_name' => 'config1', - 'string' => 'foo', - ), - array( - 'config_name' => 'config2', - 'string' => '1', - ), - ), - $db->sql_fetchrowset($result) - ); + $sql = 'SELECT ' . $db->sql_case('is_dynamic = 1', '1', 'is_dynamic') . " AS bool + FROM phpbb_config + WHERE is_dynamic = 0"; + $result = $db->sql_query_limit($sql, 1); + + $this->assertEquals(false, (bool) $db->sql_fetchfield('bool')); } } From 625333ea2ed4b89ea479786f599948d5530c7202 Mon Sep 17 00:00:00 2001 From: Patrick Webster Date: Sat, 30 Jun 2012 12:21:37 -0500 Subject: [PATCH 328/441] [ticket/10773] ACP logo with registered trademark symbol PHPBB3-10773 --- phpBB/adm/images/phpbb_logo.gif | Bin 3883 -> 0 bytes phpBB/adm/images/phpbb_logo.png | Bin 0 -> 9313 bytes phpBB/adm/style/admin.css | 6 +++--- 3 files changed, 3 insertions(+), 3 deletions(-) delete mode 100644 phpBB/adm/images/phpbb_logo.gif create mode 100644 phpBB/adm/images/phpbb_logo.png diff --git a/phpBB/adm/images/phpbb_logo.gif b/phpBB/adm/images/phpbb_logo.gif deleted file mode 100644 index 239993182be84e618e95bd214c904a8ff3f8cb24..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3883 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 diff --git a/phpBB/adm/images/phpbb_logo.png b/phpBB/adm/images/phpbb_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..c3f9248ed79bb8e6ddaded8f136091ba9ac42051 GIT binary patch literal 9313 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
          a?DufKqt@WZwvx(9mILbNo1w}^$9bD1DzWTS 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 Date: Mon, 2 Jul 2012 11:10:02 +0200 Subject: [PATCH 329/441] [ticket/10942] Require same data type and do not cast expressions automatically PHPBB3-10942 --- phpBB/includes/db/dbal.php | 2 ++ phpBB/includes/db/mssql.php | 13 ------------- phpBB/includes/db/mssql_odbc.php | 13 ------------- phpBB/includes/db/mssqlnative.php | 13 ------------- phpBB/includes/db/oracle.php | 13 ------------- phpBB/includes/db/postgres.php | 13 ------------- 6 files changed, 2 insertions(+), 65 deletions(-) diff --git a/phpBB/includes/db/dbal.php b/phpBB/includes/db/dbal.php index 9eb74ab617..8dbcd73b58 100644 --- a/phpBB/includes/db/dbal.php +++ b/phpBB/includes/db/dbal.php @@ -286,6 +286,8 @@ 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 diff --git a/phpBB/includes/db/mssql.php b/phpBB/includes/db/mssql.php index 8888bb3939..d24cbf329f 100644 --- a/phpBB/includes/db/mssql.php +++ b/phpBB/includes/db/mssql.php @@ -91,19 +91,6 @@ class dbal_mssql extends dbal return ($this->sql_server_version) ? 'MSSQL
          ' . $this->sql_server_version : 'MSSQL'; } - /** - * {@inheritDoc} - */ - function sql_case($condition, $action_true, $action_false = false) - { - // To ensure, that both expressions have the same type, we cast them to varchar manually - $sql_case = 'CASE WHEN ' . $condition; - $sql_case .= ' THEN CAST(' . $action_true . ' AS VARCHAR)'; - $sql_case .= ($action_false !== false) ? ' ELSE CAST(' . $action_false . ' AS VARCHAR)' : ''; - $sql_case .= ' END'; - return $sql_case; - } - /** * {@inheritDoc} */ diff --git a/phpBB/includes/db/mssql_odbc.php b/phpBB/includes/db/mssql_odbc.php index a14d6adb14..d64264470e 100644 --- a/phpBB/includes/db/mssql_odbc.php +++ b/phpBB/includes/db/mssql_odbc.php @@ -109,19 +109,6 @@ class dbal_mssql_odbc extends dbal return ($this->sql_server_version) ? 'MSSQL (ODBC)
          ' . $this->sql_server_version : 'MSSQL (ODBC)'; } - /** - * {@inheritDoc} - */ - function sql_case($condition, $action_true, $action_false = false) - { - // To ensure, that both expressions have the same type, we cast them to varchar manually - $sql_case = 'CASE WHEN ' . $condition; - $sql_case .= ' THEN CAST(' . $action_true . ' AS VARCHAR)'; - $sql_case .= ($action_false !== false) ? ' ELSE CAST(' . $action_false . ' AS VARCHAR)' : ''; - $sql_case .= ' END'; - return $sql_case; - } - /** * {@inheritDoc} */ diff --git a/phpBB/includes/db/mssqlnative.php b/phpBB/includes/db/mssqlnative.php index 0001bc4ba7..31c3a3721a 100644 --- a/phpBB/includes/db/mssqlnative.php +++ b/phpBB/includes/db/mssqlnative.php @@ -257,19 +257,6 @@ class dbal_mssqlnative extends dbal return ($this->sql_server_version) ? 'MSSQL
          ' . $this->sql_server_version : 'MSSQL'; } - /** - * {@inheritDoc} - */ - function sql_case($condition, $action_true, $action_false = false) - { - // To ensure, that both expressions have the same type, we cast them to varchar manually - $sql_case = 'CASE WHEN ' . $condition; - $sql_case .= ' THEN CAST(' . $action_true . ' AS VARCHAR)'; - $sql_case .= ($action_false !== false) ? ' ELSE CAST(' . $action_false . ' AS VARCHAR)' : ''; - $sql_case .= ' END'; - return $sql_case; - } - /** * {@inheritDoc} */ diff --git a/phpBB/includes/db/oracle.php b/phpBB/includes/db/oracle.php index dc405ab08a..2e801532f0 100644 --- a/phpBB/includes/db/oracle.php +++ b/phpBB/includes/db/oracle.php @@ -89,19 +89,6 @@ class dbal_oracle extends dbal return $this->sql_server_version; } - /** - * {@inheritDoc} - */ - function sql_case($condition, $action_true, $action_false = false) - { - // To ensure, that both expressions have the same type, we cast them to clob manually - $sql_case = 'CASE WHEN ' . $condition; - $sql_case .= ' THEN CAST(' . $action_true . ' AS clob)'; - $sql_case .= ($action_false !== false) ? ' ELSE CAST(' . $action_false . ' AS clob)' : ''; - $sql_case .= ' END'; - return $sql_case; - } - /** * SQL Transaction * @access private diff --git a/phpBB/includes/db/postgres.php b/phpBB/includes/db/postgres.php index c3116601ae..a31181b4d4 100644 --- a/phpBB/includes/db/postgres.php +++ b/phpBB/includes/db/postgres.php @@ -154,19 +154,6 @@ class dbal_postgres extends dbal return ($raw) ? $this->sql_server_version : 'PostgreSQL ' . $this->sql_server_version; } - /** - * {@inheritDoc} - */ - function sql_case($condition, $action_true, $action_false = false) - { - // To ensure, that both expressions have the same type, we cast them to text manually - $sql_case = 'CASE WHEN ' . $condition; - $sql_case .= ' THEN CAST(' . $action_true . ' AS TEXT)'; - $sql_case .= ($action_false !== false) ? ' ELSE CAST(' . $action_false . ' AS TEXT)' : ''; - $sql_case .= ' END'; - return $sql_case; - } - /** * {@inheritDoc} */ From ad9d6506594f90ac7c6cdf20a5718d28042059c9 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Mon, 2 Jul 2012 11:10:58 +0200 Subject: [PATCH 330/441] [ticket/10942] Fix up unit tests for sql_case() PHPBB3-10942 --- tests/dbal/case_test.php | 39 ++++++++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/tests/dbal/case_test.php b/tests/dbal/case_test.php index 684f2c26a9..5219defa06 100644 --- a/tests/dbal/case_test.php +++ b/tests/dbal/case_test.php @@ -14,39 +14,56 @@ class phpbb_dbal_case_test extends phpbb_database_test_case return $this->createXMLDataSet(dirname(__FILE__).'/fixtures/config.xml'); } + public function test_case_int() + { + $db = $this->new_dbal(); + + $sql = 'SELECT ' . $db->sql_case('1 = 1', '1', '2') . ' AS num + FROM phpbb_config'; + $result = $db->sql_query_limit($sql, 1); + + $this->assertEquals(1, (int) $db->sql_fetchfield('num')); + + $sql = 'SELECT ' . $db->sql_case('1 = 0', '1', '2') . ' AS num + FROM phpbb_config'; + $result = $db->sql_query_limit($sql, 1); + + $this->assertEquals(2, (int) $db->sql_fetchfield('num')); + } + public function test_case_string() { $db = $this->new_dbal(); - $sql = 'SELECT ' . $db->sql_case('1 = 1', '1', '0') . ' AS bool + $sql = 'SELECT ' . $db->sql_case('1 = 1', "'foo'", "'bar'") . ' AS string FROM phpbb_config'; $result = $db->sql_query_limit($sql, 1); - $this->assertEquals(true, (bool) $db->sql_fetchfield('bool')); + $this->assertEquals('foo', $db->sql_fetchfield('string')); - $sql = 'SELECT ' . $db->sql_case('1 = 0', '1', '0') . ' AS bool + $sql = 'SELECT ' . $db->sql_case('1 = 0', "'foo'", "'bar'") . ' AS string FROM phpbb_config'; $result = $db->sql_query_limit($sql, 1); - $this->assertEquals(false, (bool) $db->sql_fetchfield('bool')); + $this->assertEquals('bar', $db->sql_fetchfield('string')); } - public function test_case_statement() + public function test_case_column() { $db = $this->new_dbal(); - $sql = 'SELECT ' . $db->sql_case('is_dynamic = 1', 'is_dynamic', '0') . " AS bool + $sql = 'SELECT ' . $db->sql_case("config_name = 'config1'", 'config_name', 'config_value') . " AS string FROM phpbb_config - WHERE is_dynamic = 1"; + WHERE config_name = 'config1'"; $result = $db->sql_query_limit($sql, 1); - $this->assertEquals(true, (bool) $db->sql_fetchfield('bool')); + $this->assertEquals('config1', $db->sql_fetchfield('string')); - $sql = 'SELECT ' . $db->sql_case('is_dynamic = 1', '1', 'is_dynamic') . " AS bool + $sql = 'SELECT ' . $db->sql_case("config_name = 'config1'", 'config_name', 'config_value') . " AS string FROM phpbb_config - WHERE is_dynamic = 0"; + WHERE config_value = 'bar'"; $result = $db->sql_query_limit($sql, 1); - $this->assertEquals(false, (bool) $db->sql_fetchfield('bool')); + $this->assertEquals('bar', $db->sql_fetchfield('string')); } } From fe1f21d1a55ac15b278d99c3a73a8e3424a38fd5 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Mon, 2 Jul 2012 23:11:21 +0200 Subject: [PATCH 331/441] [ticket/10942] Use ANSI SQL standard || in dbal.php PHPBB3-10942 --- phpBB/includes/db/dbal.php | 2 +- phpBB/includes/db/firebird.php | 8 -------- phpBB/includes/db/mysql.php | 8 ++++++++ phpBB/includes/db/mysqli.php | 8 ++++++++ phpBB/includes/db/postgres.php | 8 -------- phpBB/includes/db/sqlite.php | 8 -------- 6 files changed, 17 insertions(+), 25 deletions(-) diff --git a/phpBB/includes/db/dbal.php b/phpBB/includes/db/dbal.php index 8dbcd73b58..fded27a001 100644 --- a/phpBB/includes/db/dbal.php +++ b/phpBB/includes/db/dbal.php @@ -311,7 +311,7 @@ class dbal */ function sql_concatenate($expr1, $expr2) { - return 'CONCAT(' . $expr1 . ', ' . $expr2 . ')'; + return $expr1 . ' || ' . $expr2; } /** diff --git a/phpBB/includes/db/firebird.php b/phpBB/includes/db/firebird.php index d6b16d0342..7709e8fdf5 100644 --- a/phpBB/includes/db/firebird.php +++ b/phpBB/includes/db/firebird.php @@ -110,14 +110,6 @@ class dbal_firebird extends dbal return ($raw) ? '2.1' : 'Firebird/Interbase'; } - /** - * {@inheritDoc} - */ - function sql_concatenate($expr1, $expr2) - { - return $expr1 . ' || ' . $expr2; - } - /** * SQL Transaction * @access private diff --git a/phpBB/includes/db/mysql.php b/phpBB/includes/db/mysql.php index eb38e3e913..3cda5cc1e0 100644 --- a/phpBB/includes/db/mysql.php +++ b/phpBB/includes/db/mysql.php @@ -119,6 +119,14 @@ class dbal_mysql extends dbal return ($raw) ? $this->sql_server_version : 'MySQL ' . $this->sql_server_version; } + /** + * {@inheritDoc} + */ + 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..e3828d9599 100644 --- a/phpBB/includes/db/mysqli.php +++ b/phpBB/includes/db/mysqli.php @@ -122,6 +122,14 @@ class dbal_mysqli extends dbal return ($raw) ? $this->sql_server_version : 'MySQL(i) ' . $this->sql_server_version; } + /** + * {@inheritDoc} + */ + function sql_concatenate($expr1, $expr2) + { + return 'CONCAT(' . $expr1 . ', ' . $expr2 . ')'; + } + /** * SQL Transaction * @access private diff --git a/phpBB/includes/db/postgres.php b/phpBB/includes/db/postgres.php index a31181b4d4..bf22cffafa 100644 --- a/phpBB/includes/db/postgres.php +++ b/phpBB/includes/db/postgres.php @@ -154,14 +154,6 @@ class dbal_postgres extends dbal return ($raw) ? $this->sql_server_version : 'PostgreSQL ' . $this->sql_server_version; } - /** - * {@inheritDoc} - */ - function sql_concatenate($expr1, $expr2) - { - return $expr1 . ' || ' . $expr2; - } - /** * SQL Transaction * @access private diff --git a/phpBB/includes/db/sqlite.php b/phpBB/includes/db/sqlite.php index 6eb77e5a70..86bfa75a13 100644 --- a/phpBB/includes/db/sqlite.php +++ b/phpBB/includes/db/sqlite.php @@ -72,14 +72,6 @@ class dbal_sqlite extends dbal return ($raw) ? $this->sql_server_version : 'SQLite ' . $this->sql_server_version; } - /** - * {@inheritDoc} - */ - function sql_concatenate($expr1, $expr2) - { - return $expr1 . ' || ' . $expr2; - } - /** * SQL Transaction * @access private From 03ddfbbaf1ba078df16638c642f8a3a9d8ca8c1c Mon Sep 17 00:00:00 2001 From: Fyorl Date: Fri, 15 Jun 2012 14:10:20 +0100 Subject: [PATCH 332/441] [ticket/10963] Modified filespec::is_image() to check actual mimetype Modified filespec::is_image() to check the Fileinfo mimetype rather than trusting the browser. PHPBB3-10963 --- phpBB/includes/functions_upload.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/phpBB/includes/functions_upload.php b/phpBB/includes/functions_upload.php index f70e20e616..f3ae9d6cc4 100644 --- a/phpBB/includes/functions_upload.php +++ b/phpBB/includes/functions_upload.php @@ -151,7 +151,10 @@ class filespec */ function is_image() { - return (strpos($this->mimetype, 'image/') !== false) ? true : false; + $finfo = new finfo(FILEINFO_MIME_TYPE); + $mimetype = $finfo->file($this->filename); + + return (strpos($mimetype, 'image/') !== false) ? true : false; } /** @@ -342,6 +345,7 @@ class filespec // Remove temporary filename @unlink($this->filename); + $this->filename = $this->destination_file; if (sizeof($this->error)) { From f208b59c5984e686a3589eb83d5edb0b69bc020b Mon Sep 17 00:00:00 2001 From: Fyorl Date: Tue, 19 Jun 2012 13:27:27 +0100 Subject: [PATCH 333/441] [ticket/10963] Removed superfluous ternary statement and strpos now stricter PHPBB3-10963 --- phpBB/includes/functions_upload.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/includes/functions_upload.php b/phpBB/includes/functions_upload.php index f3ae9d6cc4..aedf361000 100644 --- a/phpBB/includes/functions_upload.php +++ b/phpBB/includes/functions_upload.php @@ -154,7 +154,7 @@ class filespec $finfo = new finfo(FILEINFO_MIME_TYPE); $mimetype = $finfo->file($this->filename); - return (strpos($mimetype, 'image/') !== false) ? true : false; + return (strpos($mimetype, 'image/') === 0); } /** From 81d5327e4411a7044f1c90e002505cad309372d6 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Wed, 20 Jun 2012 13:56:11 +0200 Subject: [PATCH 334/441] [ticket/10937] Comment removal functions: Restore backward compatibility PHPBB3-10937 --- phpBB/includes/functions_admin.php | 15 +++++++ phpBB/includes/functions_install.php | 42 ++++++++++++++++--- phpBB/install/install_install.php | 4 +- ...phpbb_database_test_connection_manager.php | 2 +- 4 files changed, 55 insertions(+), 8 deletions(-) diff --git a/phpBB/includes/functions_admin.php b/phpBB/includes/functions_admin.php index 204fa9a43d..7352b3d1f3 100644 --- a/phpBB/includes/functions_admin.php +++ b/phpBB/includes/functions_admin.php @@ -2293,6 +2293,21 @@ function auto_prune($forum_id, $prune_mode, $prune_flags, $prune_days, $prune_fr return; } +/** +* 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_install.php b/phpBB/includes/functions_install.php index 9e9c48ff58..f8437e0055 100644 --- a/phpBB/includes/functions_install.php +++ b/phpBB/includes/functions_install.php @@ -50,6 +50,7 @@ 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,6 +60,7 @@ 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, @@ -68,6 +70,7 @@ 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, @@ -77,6 +80,7 @@ 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, @@ -86,6 +90,7 @@ 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, @@ -95,6 +100,7 @@ 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, @@ -104,6 +110,7 @@ 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, @@ -113,6 +120,7 @@ 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, @@ -122,6 +130,7 @@ 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, @@ -465,16 +474,39 @@ function connect_check_db($error_connect, &$error, $dbms_details, $table_prefix, /** * Removes comments from schema files +* +* @deprecated Use phpbb_remove_comments() instead. */ -function remove_comments($sql) +function remove_remarks(&$sql) { - // Remove /* */ comments (http://ostermiller.org/findcomment.html) - $sql = preg_replace('#/\*(.|[\r\n])*?\*/#', "\n", $sql); - // Remove # style comments $sql = preg_replace('/\n{2,}/', "\n", preg_replace('/^#.*$/m', "\n", $sql)); - return $sql; + // Return by reference +} + +/** +* Removes comments from $input. +* +* @param string $input Input string +* +* @return string Input string with comments removed +*/ +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 # style comments + remove_remarks($input); + + return $input; } /** diff --git a/phpBB/install/install_install.php b/phpBB/install/install_install.php index 8e3fe0387c..f1003b07d7 100644 --- a/phpBB/install/install_install.php +++ b/phpBB/install/install_install.php @@ -1164,7 +1164,7 @@ class install_install extends module $sql_query = preg_replace('#phpbb_#i', $data['table_prefix'], $sql_query); - $sql_query = remove_comments($sql_query); + $sql_query = phpbb_remove_comments($sql_query); $sql_query = split_sql_file($sql_query, $delimiter); @@ -1202,7 +1202,7 @@ class install_install extends module // Change language strings... $sql_query = preg_replace_callback('#\{L_([A-Z0-9\-_]*)\}#s', 'adjust_language_keys_callback', $sql_query); - $sql_query = remove_comments($sql_query); + $sql_query = phpbb_remove_comments($sql_query); $sql_query = split_sql_file($sql_query, ';'); foreach ($sql_query as $sql) diff --git a/tests/test_framework/phpbb_database_test_connection_manager.php b/tests/test_framework/phpbb_database_test_connection_manager.php index c734c90a1a..dd022451b7 100644 --- a/tests/test_framework/phpbb_database_test_connection_manager.php +++ b/tests/test_framework/phpbb_database_test_connection_manager.php @@ -243,7 +243,7 @@ class phpbb_database_test_connection_manager $filename = $directory . $schema . '_schema.sql'; $queries = file_get_contents($filename); - $sql = remove_comments($queries); + $sql = phpbb_remove_comments($queries); $sql = split_sql_file($sql, $this->dbms['DELIM']); From 2c12f31cdf5f4c459d4f282acb92829e11accfd2 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Sun, 1 Jul 2012 00:48:40 +0200 Subject: [PATCH 335/441] [ticket/10937] Update documentation to say which comment styles are removed. PHPBB3-10937 --- phpBB/includes/functions_install.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/includes/functions_install.php b/phpBB/includes/functions_install.php index f8437e0055..89dfb7cd2f 100644 --- a/phpBB/includes/functions_install.php +++ b/phpBB/includes/functions_install.php @@ -486,7 +486,7 @@ function remove_remarks(&$sql) } /** -* Removes comments from $input. +* Removes "/* style" as well as "# style" comments from $input. * * @param string $input Input string * From 5d0aa8e516d15122fcdcee351aa44cacf02ca4ff Mon Sep 17 00:00:00 2001 From: Patrick Webster Date: Mon, 2 Jul 2012 21:38:27 -0500 Subject: [PATCH 336/441] [ticket/10441] Make CDB linking more consistent PHPBB3-10441 --- phpBB/docs/README.html | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/phpBB/docs/README.html b/phpBB/docs/README.html index 6b6b21d8ae..86340ac882 100644 --- a/phpBB/docs/README.html +++ b/phpBB/docs/README.html @@ -134,7 +134,7 @@

          A number of language packs with included style localisations are available. You can find them listed in the Language Packs pages of our downloads section or from the Language Packs section of the Customisation Database.

          -

          http://www.phpbb.com/languages/

          +

          For more information about language packs, please see: http://www.phpbb.com/languages/

          This is the official location for all supported language sets. If you download a package from a 3rd party site you do so with the understanding that we cannot offer support. So please, do not ask for help in these cases!

          @@ -144,9 +144,9 @@

          2.ii. Styles

          -

          Although the phpBB Group is rather proud of the included styles, we realise that they may not be to everyone's taste. Therefore, phpBB3 allows styles to be switched with relative ease. First, you need to locate and download a style you like. We maintain such a section in the Customisation Database.

          +

          Although the phpBB Group is rather proud of the included styles, we realise that they may not be to everyone's taste. Therefore, phpBB3 allows styles to be switched with relative ease. First, you need to locate and download a style you like. You can find them listed in the Styles section of our Customisation Database.

          -

          http://www.phpbb.com/customise/db/styles-2/

          +

          For more information about styles, please see: http://www.phpbb.com/styles/

          Please note that 3rd party styles downloaded for versions of phpBB2 will not work in phpBB3. It is also important to ensure that the style is updated to match the current version of the phpBB software you are using.

          @@ -156,9 +156,9 @@

          2.iii. Modifications

          -

          Although not officially supported by the phpBB Group, phpBB has a thriving modification scene. These third party modifications to the standard phpBB software, known as MODs, extend its capabilities still further. Information on MODs can be found at:

          +

          Although not officially supported by the phpBB Group, phpBB has a thriving modification scene. These third party modifications to the standard phpBB software, known as MODs, extend its capabilities still further. You can browse through many of the MODs in the Modifications section of our Customisation Database.

          -

          http://www.phpbb.com/mods

          +

          For more information about MODs, please see: http://www.phpbb.com/mods/

          Please remember that any bugs or other issues that occur after you have added any modification should NOT be reported to the bug tracker (see below). First remove the MOD and see if the problem is resolved. Any support for a MOD should only be sought in the "Discussion/Support" forum for that MOD.

          From 6776feb0de667340d640744462d00436f893c45f Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Wed, 4 Jul 2012 14:05:03 +0200 Subject: [PATCH 337/441] [ticket/10942] Add access modifiers PHPBB3-10942 --- phpBB/includes/db/dbal.php | 4 ++-- phpBB/includes/db/mssql.php | 2 +- phpBB/includes/db/mssql_odbc.php | 2 +- phpBB/includes/db/mssqlnative.php | 2 +- phpBB/includes/db/mysql.php | 2 +- phpBB/includes/db/mysqli.php | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/phpBB/includes/db/dbal.php b/phpBB/includes/db/dbal.php index fded27a001..159703d3be 100644 --- a/phpBB/includes/db/dbal.php +++ b/phpBB/includes/db/dbal.php @@ -293,7 +293,7 @@ class dbal * @param string $action_else SQL expression that is used, if the condition is false, optional * @return string CASE expression including the condition and statements */ - function sql_case($condition, $action_true, $action_false = false) + public function sql_case($condition, $action_true, $action_false = false) { $sql_case = 'CASE WHEN ' . $condition; $sql_case .= ' THEN ' . $action_true; @@ -309,7 +309,7 @@ class dbal * @param string $expr2 SQL expression that is appended to the first expression * @return string Concatenated string */ - function sql_concatenate($expr1, $expr2) + public function sql_concatenate($expr1, $expr2) { return $expr1 . ' || ' . $expr2; } diff --git a/phpBB/includes/db/mssql.php b/phpBB/includes/db/mssql.php index d24cbf329f..fb044b492f 100644 --- a/phpBB/includes/db/mssql.php +++ b/phpBB/includes/db/mssql.php @@ -94,7 +94,7 @@ class dbal_mssql extends dbal /** * {@inheritDoc} */ - function sql_concatenate($expr1, $expr2) + public function sql_concatenate($expr1, $expr2) { return $expr1 . ' + ' . $expr2; } diff --git a/phpBB/includes/db/mssql_odbc.php b/phpBB/includes/db/mssql_odbc.php index d64264470e..64fa9634d1 100644 --- a/phpBB/includes/db/mssql_odbc.php +++ b/phpBB/includes/db/mssql_odbc.php @@ -112,7 +112,7 @@ class dbal_mssql_odbc extends dbal /** * {@inheritDoc} */ - function sql_concatenate($expr1, $expr2) + public function sql_concatenate($expr1, $expr2) { return $expr1 . ' + ' . $expr2; } diff --git a/phpBB/includes/db/mssqlnative.php b/phpBB/includes/db/mssqlnative.php index 31c3a3721a..7878615acc 100644 --- a/phpBB/includes/db/mssqlnative.php +++ b/phpBB/includes/db/mssqlnative.php @@ -260,7 +260,7 @@ class dbal_mssqlnative extends dbal /** * {@inheritDoc} */ - function sql_concatenate($expr1, $expr2) + public function sql_concatenate($expr1, $expr2) { return $expr1 . ' + ' . $expr2; } diff --git a/phpBB/includes/db/mysql.php b/phpBB/includes/db/mysql.php index 3cda5cc1e0..8d1f805870 100644 --- a/phpBB/includes/db/mysql.php +++ b/phpBB/includes/db/mysql.php @@ -122,7 +122,7 @@ class dbal_mysql extends dbal /** * {@inheritDoc} */ - function sql_concatenate($expr1, $expr2) + public function sql_concatenate($expr1, $expr2) { return 'CONCAT(' . $expr1 . ', ' . $expr2 . ')'; } diff --git a/phpBB/includes/db/mysqli.php b/phpBB/includes/db/mysqli.php index e3828d9599..e07cd35e24 100644 --- a/phpBB/includes/db/mysqli.php +++ b/phpBB/includes/db/mysqli.php @@ -125,7 +125,7 @@ class dbal_mysqli extends dbal /** * {@inheritDoc} */ - function sql_concatenate($expr1, $expr2) + public function sql_concatenate($expr1, $expr2) { return 'CONCAT(' . $expr1 . ', ' . $expr2 . ')'; } From 4fbcf4eaadea0425c7f8bf0ff02a60bd2165136b Mon Sep 17 00:00:00 2001 From: Fyorl Date: Wed, 4 Jul 2012 13:27:55 +0100 Subject: [PATCH 338/441] [ticket/10963] filespec::get_mimetype now used filespec::get_mimetype now uses the finfo class in order to detect the mimetype of a given filename. filespec::is_image() now uses this method. PHPBB3-10963 --- phpBB/includes/functions_upload.php | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/phpBB/includes/functions_upload.php b/phpBB/includes/functions_upload.php index aedf361000..33cb585b19 100644 --- a/phpBB/includes/functions_upload.php +++ b/phpBB/includes/functions_upload.php @@ -151,9 +151,7 @@ class filespec */ function is_image() { - $finfo = new finfo(FILEINFO_MIME_TYPE); - $mimetype = $finfo->file($this->filename); - + $mimetype = $this->get_mimetype($this->filename); return (strpos($mimetype, 'image/') === 0); } @@ -203,17 +201,12 @@ class filespec } /** - * Get mimetype. Utilize mime_content_type if the function exist. - * Not used at the moment... + * Get mimetype. Utilises the finfo class. */ function get_mimetype($filename) { - $mimetype = ''; - - if (function_exists('mime_content_type')) - { - $mimetype = mime_content_type($filename); - } + $finfo = new finfo(FILEINFO_MIME_TYPE); + $mimetype = $finfo->file($filename); // Some browsers choke on a mimetype of application/octet-stream if (!$mimetype || $mimetype == 'application/octet-stream') From f1056a9b2fd6e4ff7bc107372e9210bae9e077f0 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 5 Jul 2012 00:30:02 +0200 Subject: [PATCH 339/441] [ticket/10811] Make toogle_subscribe more generic so it can toogle all links PHPBB3-10811 --- phpBB/assets/javascript/core.js | 35 +++++++++++-------- phpBB/includes/functions_display.php | 3 +- .../prosilver/template/overall_footer.html | 4 +-- .../subsilver2/template/viewforum_body.html | 2 +- phpBB/viewforum.php | 8 +++-- phpBB/viewtopic.php | 6 ++-- 6 files changed, 35 insertions(+), 23 deletions(-) diff --git a/phpBB/assets/javascript/core.js b/phpBB/assets/javascript/core.js index 3c1e39fca6..76615eb051 100644 --- a/phpBB/assets/javascript/core.js +++ b/phpBB/assets/javascript/core.js @@ -452,24 +452,31 @@ phpbb.add_ajax_callback('alt_text', function() { * It replaces the current text with the text in the alt-text data attribute, * and replaces the text in the attribute with the current text so that the * process can be repeated. - * Additionally it replaces the icon of the link and changes the link itself. + * Additionally it replaces the class of the link's parent + * and changes the link itself. */ -phpbb.add_ajax_callback('toggle_subscribe', function() { +phpbb.add_ajax_callback('toggle_link', function() { var el = $(this), - alt_text; + toggle_text, + toggle_url, + toggle_class; - phpbb.ajax_callbacks['alt_text'].call(this); + // Toggle link text - if (el.attr('href').indexOf('unwatch') !== -1) - { - el.attr('href', el.attr('href').replace('unwatch', 'watch')); - el.parent().attr('class', 'icon-subscribe'); - } - else - { - el.attr('href', el.attr('href').replace('watch', 'unwatch')); - el.parent().attr('class', 'icon-unsubscribe'); - } + toggle_text = el.attr('data-toggle-text'); + el.attr('data-toggle-text', el.text()); + el.attr('title', toggle_text); + el.text(toggle_text); + + // Toggle link url + toggle_url = el.attr('data-toggle-url'); + el.attr('data-toggle-url', el.attr('href')); + el.attr('href', toggle_url); + + // Toggle class of link parent + toggle_class = el.attr('data-toggle-class'); + el.attr('data-toggle-class', el.parent().attr('class')); + el.parent().attr('class', toggle_class); }); })(jQuery); // Avoid conflicts with other libraries diff --git a/phpBB/includes/functions_display.php b/phpBB/includes/functions_display.php index 7c1d007d55..bbfd6fd6b6 100644 --- a/phpBB/includes/functions_display.php +++ b/phpBB/includes/functions_display.php @@ -1218,8 +1218,9 @@ function watch_topic_forum($mode, &$s_watching, $user_id, $forum_id, $topic_id, if ($can_watch) { $s_watching['link'] = append_sid("{$phpbb_root_path}view$mode.$phpEx", "$u_url=$match_id&" . (($is_watching) ? 'unwatch' : 'watch') . "=$mode&start=$start&hash=" . generate_link_hash("{$mode}_$match_id")); + $s_watching['link_toggle'] = append_sid("{$phpbb_root_path}view$mode.$phpEx", "$u_url=$match_id&" . ((!$is_watching) ? 'unwatch' : 'watch') . "=$mode&start=$start&hash=" . generate_link_hash("{$mode}_$match_id")); $s_watching['title'] = $user->lang[(($is_watching) ? 'STOP' : 'START') . '_WATCHING_' . strtoupper($mode)]; - $s_watching['toggle'] = $user->lang[((!$is_watching) ? 'STOP' : 'START') . '_WATCHING_' . strtoupper($mode)]; + $s_watching['title_toggle'] = $user->lang[((!$is_watching) ? 'STOP' : 'START') . '_WATCHING_' . strtoupper($mode)]; $s_watching['is_watching'] = $is_watching; } diff --git a/phpBB/styles/prosilver/template/overall_footer.html b/phpBB/styles/prosilver/template/overall_footer.html index 1aab6528cd..b473e7022c 100644 --- a/phpBB/styles/prosilver/template/overall_footer.html +++ b/phpBB/styles/prosilver/template/overall_footer.html @@ -8,8 +8,8 @@
          -
          -

          ' . $user->lang['FULLTEXT_POSTGRES_MBSTRING_EXPLAIN'] . '
          -
          ' . (($this->mbstring_regex) ? $user->lang['YES'] : $user->lang['NO']). '
          -

          ' . $user->lang['FULLTEXT_POSTGRES_TS_NAME_EXPLAIN'] . '
          disabled="diabled" />
          +
          disabled="disabled" />
          From f3e6547acf15bc7310b0c1cd7695253ed01f694c Mon Sep 17 00:00:00 2001 From: Nathan Date: Fri, 13 Jul 2012 22:18:28 -0500 Subject: [PATCH 403/441] [ticket/7598] Inactive users action notification (ACP) When performing an action on users in the ACP Inactive Users, such as activating, deleting, or reminding, trigger_error is now called to give a notification that the action was performed PHPBB3-7598 --- phpBB/includes/acp/acp_inactive.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/phpBB/includes/acp/acp_inactive.php b/phpBB/includes/acp/acp_inactive.php index 78d6a0b2f3..6d14365ce9 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_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_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(', ', $usernames) . ' ' . adm_back_link($this->u_action))); } $db->sql_freeresult($result); From 97350944e3bcc4042ff030af4eb130facdd253c1 Mon Sep 17 00:00:00 2001 From: Nathan Date: Sat, 14 Jul 2012 17:40:37 -0500 Subject: [PATCH 404/441] [ticket/7598] Use $user->lang['COMMA_SEPARATOR'] PHPBB3-7598 --- phpBB/includes/acp/acp_inactive.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/phpBB/includes/acp/acp_inactive.php b/phpBB/includes/acp/acp_inactive.php index 6d14365ce9..f098b772ee 100644 --- a/phpBB/includes/acp/acp_inactive.php +++ b/phpBB/includes/acp/acp_inactive.php @@ -137,7 +137,7 @@ class acp_inactive add_log('user', $row['user_id'], 'LOG_USER_ACTIVE_USER'); } - trigger_error(sprintf($user->lang['LOG_INACTIVE_ACTIVATE'], implode(', ', $user_affected) . ' ' . adm_back_link($this->u_action))); + 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 @@ -162,7 +162,7 @@ class acp_inactive add_log('admin', 'LOG_INACTIVE_' . strtoupper($action), implode(', ', $user_affected)); - trigger_error(sprintf($user->lang['LOG_INACTIVE_DELETE'], implode(', ', $user_affected) . ' ' . adm_back_link($this->u_action))); + trigger_error(sprintf($user->lang['LOG_INACTIVE_DELETE'], implode($user->lang['COMMA_SEPARATOR'], $user_affected) . ' ' . adm_back_link($this->u_action))); } else { @@ -235,7 +235,7 @@ class acp_inactive add_log('admin', 'LOG_INACTIVE_REMIND', implode(', ', $usernames)); - trigger_error(sprintf($user->lang['LOG_INACTIVE_REMIND'], implode(', ', $usernames) . ' ' . adm_back_link($this->u_action))); + trigger_error(sprintf($user->lang['LOG_INACTIVE_REMIND'], implode($user->lang['COMMA_SEPARATOR'], $usernames) . ' ' . adm_back_link($this->u_action))); } $db->sql_freeresult($result); From 1b826842aadc16ad35485479f4bb3bdef03b534c Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Mon, 16 Jul 2012 16:59:40 +0200 Subject: [PATCH 405/441] [ticket/10942] Avoid possible conflicts with magic words in unit tests PHPBB3-10942 --- tests/dbal/case_test.php | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/tests/dbal/case_test.php b/tests/dbal/case_test.php index 5219defa06..57a1729a39 100644 --- a/tests/dbal/case_test.php +++ b/tests/dbal/case_test.php @@ -18,52 +18,52 @@ class phpbb_dbal_case_test extends phpbb_database_test_case { $db = $this->new_dbal(); - $sql = 'SELECT ' . $db->sql_case('1 = 1', '1', '2') . ' AS num + $sql = 'SELECT ' . $db->sql_case('1 = 1', '1', '2') . ' AS test_num FROM phpbb_config'; $result = $db->sql_query_limit($sql, 1); - $this->assertEquals(1, (int) $db->sql_fetchfield('num')); + $this->assertEquals(1, (int) $db->sql_fetchfield('test_num')); - $sql = 'SELECT ' . $db->sql_case('1 = 0', '1', '2') . ' AS num + $sql = 'SELECT ' . $db->sql_case('1 = 0', '1', '2') . ' AS test_num FROM phpbb_config'; $result = $db->sql_query_limit($sql, 1); - $this->assertEquals(2, (int) $db->sql_fetchfield('num')); + $this->assertEquals(2, (int) $db->sql_fetchfield('test_num')); } public function test_case_string() { $db = $this->new_dbal(); - $sql = 'SELECT ' . $db->sql_case('1 = 1', "'foo'", "'bar'") . ' AS string + $sql = 'SELECT ' . $db->sql_case('1 = 1', "'foo'", "'bar'") . ' AS test_string FROM phpbb_config'; $result = $db->sql_query_limit($sql, 1); - $this->assertEquals('foo', $db->sql_fetchfield('string')); + $this->assertEquals('foo', $db->sql_fetchfield('test_string')); - $sql = 'SELECT ' . $db->sql_case('1 = 0', "'foo'", "'bar'") . ' AS string + $sql = 'SELECT ' . $db->sql_case('1 = 0', "'foo'", "'bar'") . ' AS test_string FROM phpbb_config'; $result = $db->sql_query_limit($sql, 1); - $this->assertEquals('bar', $db->sql_fetchfield('string')); + $this->assertEquals('bar', $db->sql_fetchfield('test_string')); } public function test_case_column() { $db = $this->new_dbal(); - $sql = 'SELECT ' . $db->sql_case("config_name = 'config1'", 'config_name', 'config_value') . " AS string + $sql = 'SELECT ' . $db->sql_case("config_name = 'config1'", 'config_name', 'config_value') . " AS test_string FROM phpbb_config WHERE config_name = 'config1'"; $result = $db->sql_query_limit($sql, 1); - $this->assertEquals('config1', $db->sql_fetchfield('string')); + $this->assertEquals('config1', $db->sql_fetchfield('test_string')); - $sql = 'SELECT ' . $db->sql_case("config_name = 'config1'", 'config_name', 'config_value') . " AS string + $sql = 'SELECT ' . $db->sql_case("config_name = 'config1'", 'config_name', 'config_value') . " AS test_string FROM phpbb_config WHERE config_value = 'bar'"; $result = $db->sql_query_limit($sql, 1); - $this->assertEquals('bar', $db->sql_fetchfield('string')); + $this->assertEquals('bar', $db->sql_fetchfield('test_string')); } } From 91050356d3b8322098650bf660c07f8a49ddb02d Mon Sep 17 00:00:00 2001 From: Fyorl Date: Thu, 12 Jul 2012 18:38:20 +0100 Subject: [PATCH 406/441] [ticket/10992] Modified upload tests to work with new version PHPBB3-10992 --- tests/functional/fileupload_form_test.php | 41 +++++++++++++---------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/tests/functional/fileupload_form_test.php b/tests/functional/fileupload_form_test.php index 6ba55eeba7..9c7bed359c 100644 --- a/tests/functional/fileupload_form_test.php +++ b/tests/functional/fileupload_form_test.php @@ -22,41 +22,48 @@ class phpbb_functional_fileupload_form_test extends phpbb_functional_test_case $this->login(); } + private function upload_file($filename, $mimetype) + { + $file = array( + 'tmp_name' => $this->path . $filename, + 'name' => $filename, + 'type' => $mimetype, + 'size' => filesize($this->path . $filename), + 'error' => UPLOAD_ERR_OK, + ); + + $crawler = $this->client->request( + 'POST', + 'posting.php?mode=reply&f=2&t=1&sid=' . $this->sid, + array('add_file' => $this->lang('ADD_FILE')), + array('fileupload' => $file) + ); + + return $crawler; + } + public function test_empty_file() { - $crawler = $this->request('GET', 'posting.php?mode=reply&f=2&t=1&sid=' . $this->sid); - $form = $crawler->selectButton('add_file')->form(); - $form['fileupload']->upload($this->path . 'empty.png'); - $crawler = $this->client->submit($form); + $crawler = $this->upload_file('empty.jpg', 'image/jpeg'); $this->assertEquals($this->lang('ATTACHED_IMAGE_NOT_IMAGE'), $crawler->filter('div#message p')->text()); } public function test_invalid_extension() { - $crawler = $this->request('GET', 'posting.php?mode=reply&f=2&t=1&sid=' . $this->sid); - $form = $crawler->selectButton('add_file')->form(); - $form['fileupload']->upload($this->path . 'illegal-extension.bif'); - $crawler = $this->client->submit($form); + $crawler = $this->upload_file('illegal-extension.bif', 'application/octetstream'); $this->assertEquals($this->lang('DISALLOWED_EXTENSION', 'bif'), $crawler->filter('p.error')->text()); } public function test_too_large() { $this->markTestIncomplete('Functional tests use an admin account which ignores maximum upload size.'); - $crawler = $this->request('GET', 'posting.php?mode=reply&f=2&t=1&sid=' . $this->sid); - $form = $crawler->selectButton('add_file')->form(); - $form['fileupload']->upload($this->path . 'too-large.png'); - $crawler = $this->client->submit($form); + $crawler = $this->upload_file('too-large.png', 'image/png'); $this->assertEquals($this->lang('WRONG_FILESIZE', '256', 'KiB'), $crawler->filter('p.error')->text()); } public function test_valid_file() { - $crawler = $this->request('GET', 'posting.php?mode=reply&f=2&t=1&sid=' . $this->sid); - $form = $crawler->selectButton('add_file')->form(); - $form['fileupload']->upload($this->path . 'valid.jpg'); - $crawler = $this->client->submit($form); - $this->assertEquals(0, $crawler->filter('p.error')->count()); + $crawler = $this->upload_file('valid.jpg', 'image/jpeg'); $this->assertContains($this->lang('POSTED_ATTACHMENTS'), $crawler->filter('#postform h3')->eq(1)->text()); } } From e9a1189bfc75609de912bc5cb8c733f3323e58c6 Mon Sep 17 00:00:00 2001 From: Fyorl Date: Fri, 13 Jul 2012 20:43:11 +0100 Subject: [PATCH 407/441] [ticket/10992] test_empty_file() now tries to upload the correct file PHPBB3-10992 --- tests/functional/fileupload_form_test.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/functional/fileupload_form_test.php b/tests/functional/fileupload_form_test.php index 9c7bed359c..00ff303591 100644 --- a/tests/functional/fileupload_form_test.php +++ b/tests/functional/fileupload_form_test.php @@ -44,7 +44,7 @@ class phpbb_functional_fileupload_form_test extends phpbb_functional_test_case public function test_empty_file() { - $crawler = $this->upload_file('empty.jpg', 'image/jpeg'); + $crawler = $this->upload_file('empty.png', 'image/png'); $this->assertEquals($this->lang('ATTACHED_IMAGE_NOT_IMAGE'), $crawler->filter('div#message p')->text()); } From fa4eaeb30668ada5d81aa8dcbac3246a3f59d05c Mon Sep 17 00:00:00 2001 From: Fyorl Date: Fri, 13 Jul 2012 20:09:11 +0100 Subject: [PATCH 408/441] [ticket/10992] Changed octetstream to octet-stream PHPBB3-10992 --- tests/functional/fileupload_form_test.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/functional/fileupload_form_test.php b/tests/functional/fileupload_form_test.php index 00ff303591..f7267fa659 100644 --- a/tests/functional/fileupload_form_test.php +++ b/tests/functional/fileupload_form_test.php @@ -50,7 +50,7 @@ class phpbb_functional_fileupload_form_test extends phpbb_functional_test_case public function test_invalid_extension() { - $crawler = $this->upload_file('illegal-extension.bif', 'application/octetstream'); + $crawler = $this->upload_file('illegal-extension.bif', 'application/octet-stream'); $this->assertEquals($this->lang('DISALLOWED_EXTENSION', 'bif'), $crawler->filter('p.error')->text()); } From f5bb145040a483a76fd734bb9d4025c54e7917a0 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Mon, 16 Jul 2012 18:29:31 +0200 Subject: [PATCH 409/441] [feature/new-tz-handling] Require user argument on phpbb_datetime PHPBB3-9558 --- phpBB/includes/datetime.php | 7 +++---- phpBB/includes/functions.php | 4 ++-- phpBB/includes/user.php | 4 ++-- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/phpBB/includes/datetime.php b/phpBB/includes/datetime.php index 317376431d..0d80c77115 100644 --- a/phpBB/includes/datetime.php +++ b/phpBB/includes/datetime.php @@ -35,10 +35,9 @@ class phpbb_datetime extends DateTime * @param DateTimeZone $timezone Time zone of the time. * @param user User object for context. */ - public function __construct($time = 'now', DateTimeZone $timezone = null, $user = null) + public function __construct($user, $time = 'now', DateTimeZone $timezone = null) { - $this->user = $user ?: $GLOBALS['user']; - + $this->user = $user; $timezone = $timezone ?: $this->user->tz; parent::__construct($time, $timezone); @@ -56,7 +55,7 @@ class phpbb_datetime extends DateTime $format = $format ? $format : $this->user->date_format; $format = self::format_cache($format, $this->user); $relative = ($format['is_short'] && !$force_absolute); - $now = new self('now', $this->user->tz, $this->user); + $now = new self($this->user, 'now', $this->user->tz); $timestamp = $this->getTimestamp(); $now_ts = $now->getTimeStamp(); diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index 98a08ea4d3..4fc2739f33 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -1164,7 +1164,7 @@ function tz_select($default = '', $truncate = false, $return_tzs_only = true) foreach ($unsorted_timezones as $timezone) { $tz = new DateTimeZone($timezone); - $dt = new phpbb_datetime('now', $tz, $user); + $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); @@ -4813,7 +4813,7 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0 } } - $dt = new phpbb_datetime('now', $user->tz, $user); + $dt = new phpbb_datetime($user, 'now', $user->tz); $timezone_offset = 'GMT' . phpbb_format_timezone_offset($dt->getOffset()); $timezone_name = $user->tz->getName(); if (isset($user->lang['timezones'][$timezone_name])) diff --git a/phpBB/includes/user.php b/phpBB/includes/user.php index df8f048c89..cc50d2b98e 100644 --- a/phpBB/includes/user.php +++ b/phpBB/includes/user.php @@ -631,7 +631,7 @@ class phpbb_user extends phpbb_session $utc = new DateTimeZone('UTC'); } - $time = new phpbb_datetime("@$gmepoch", $utc, $this); + $time = new phpbb_datetime($this, "@$gmepoch", $utc); $time->setTimezone($this->tz); return $time->format($format, $forcedate); @@ -648,7 +648,7 @@ class phpbb_user extends phpbb_session public function create_datetime($time = 'now', DateTimeZone $timezone = null) { $timezone = $timezone ?: $this->tz; - return new phpbb_datetime($time, $timezone, $this); + return new phpbb_datetime($this, $time, $timezone); } /** From b61ac43abecafdd4e9597022fe8b09323854aac9 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Mon, 16 Jul 2012 18:41:30 +0200 Subject: [PATCH 410/441] [feature/new-tz-handling] Allow phpbb prefix for user data validation functions PHPBB3-9558 --- phpBB/includes/functions_user.php | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/phpBB/includes/functions_user.php b/phpBB/includes/functions_user.php index f235b2be55..27f4b60189 100644 --- a/phpBB/includes/functions_user.php +++ b/phpBB/includes/functions_user.php @@ -1248,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); + } } } } @@ -1407,7 +1418,7 @@ function validate_language_iso_name($lang_iso) * a string which will be used as the error message * (with the variable name appended) */ -function validate_timezone($timezone) +function phpbb_validate_timezone($timezone) { return (in_array($timezone, DateTimeZone::listIdentifiers())) ? false : 'TIMEZONE_INVALID'; } From 48d3c68290b96c7d2a0e875ec3338f067a529b22 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Mon, 16 Jul 2012 18:44:13 +0200 Subject: [PATCH 411/441] [feature/new-tz-handling] Use tmp variable for user timezone PHPBB3-9558 --- phpBB/includes/user.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/phpBB/includes/user.php b/phpBB/includes/user.php index cc50d2b98e..7dfb375a9b 100644 --- a/phpBB/includes/user.php +++ b/phpBB/includes/user.php @@ -82,13 +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->tz = $this->data['user_timezone']; + $user_timezone = $this->data['user_timezone']; } else { $this->lang_name = basename($config['default_lang']); $this->date_format = $config['default_dateformat']; - $this->tz = $config['board_timezone']; + $user_timezone = $config['board_timezone']; /** * If a guest user is surfing, we try to guess his/her language first by obtaining the browser language @@ -127,13 +127,13 @@ class phpbb_user extends phpbb_session */ } - if (is_numeric($this->tz)) + if (is_numeric($user_timezone)) { // Might still be numeric - $this->tz = sprintf('Etc/GMT%+d', $this->tz); + $user_timezone = sprintf('Etc/GMT%+d', $user_timezone); } - $this->tz = new DateTimeZone($this->tz); + $this->tz = new DateTimeZone($user_timezone); // We include common language file here to not load it every time a custom language file is included $lang = &$this->lang; From 797ee16eaf2e8dc562185cd940351bcfd311cf53 Mon Sep 17 00:00:00 2001 From: Fyorl Date: Mon, 16 Jul 2012 17:33:05 +0100 Subject: [PATCH 412/441] [ticket/10981] Added goutte via composer composer.phar added and autoloaded before tests PHPBB3-10981 --- composer.phar | Bin 0 -> 533673 bytes phpBB/composer.json | 6 ++ phpBB/composer.lock | 55 ++++++++++++++++++ tests/bootstrap.php | 15 +++++ .../phpbb_functional_test_case.php | 2 - vendor/goutte.phar | Bin 267414 -> 0 bytes 6 files changed, 76 insertions(+), 2 deletions(-) create mode 100755 composer.phar create mode 100644 phpBB/composer.json create mode 100644 phpBB/composer.lock delete mode 100644 vendor/goutte.phar diff --git a/composer.phar b/composer.phar new file mode 100755 index 0000000000000000000000000000000000000000..8b6eddbf21a06da1b6cc983749e5f3a755c674d5 GIT binary patch literal 533673 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

          &sc&YV^OBtLs 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 I&t5$Hf6wo5eE=')) { + if (getenv('PHPBB_NO_COMPOSER_AUTOLOAD')) + { + if (getenv('PHPBB_AUTOLOAD')) + { + require(getenv('PHPBB_AUTOLOAD')); + } + } + else + { + if (!file_exists($phpbb_root_path . 'vendor/autoload.php')) + { + trigger_error('You have not set up composer dependencies. See http://getcomposer.org/.', E_USER_ERROR); + } + require($phpbb_root_path . 'vendor/autoload.php'); + } require_once 'test_framework/phpbb_functional_test_case.php'; } diff --git a/tests/test_framework/phpbb_functional_test_case.php b/tests/test_framework/phpbb_functional_test_case.php index 76fed76fae..2b6a6aaf29 100644 --- a/tests/test_framework/phpbb_functional_test_case.php +++ b/tests/test_framework/phpbb_functional_test_case.php @@ -36,8 +36,6 @@ class phpbb_functional_test_case extends phpbb_test_case { self::markTestSkipped('phar extension is not loaded'); } - - require_once 'phar://' . __DIR__ . '/../../vendor/goutte.phar'; } public function setUp() diff --git a/vendor/goutte.phar b/vendor/goutte.phar deleted file mode 100644 index 20b7166a6717aa5b904859fc1ffe3b32106d55a8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 267414 zcmdqK3vgW5c_yf2C)pWhvw2Tyc9WVb1`+^~Ao_7{KOl)xKSe}*z#vG+B4li%y8*Nb zppotdACj1{{FLp;FU4^b$FUVVBiphp$+9I|mc*)nw3D4JO3ch|gfw$`@x>=`@TTy}1E#+UG1 z>h`vm51@Gb);)V#E6zk~bE($p)Xq`lj+Aa+8X!JtU57^!hd<68R?hW0wR&$!;2d8l%rD%!r_=0hcQ$X`b3tfw=R~Uu ztS82R&iu*B{HgKz%9~D9jxQ{on4cZLmx(c`#*xaxp<`vO)CYq3?%WQJ+*Mf^cOH1a ziFXvLHh1j!!uTW;I*k5md!pCbZer|X8?B9I7hD!*?g0(9y5r962c6XZJ>zx$YrNMy z*PGs2ueCPEsjz?P)>hxj`}XxKZuA=cir4xTuD4hF6?ZoK7WdBe`qe(y?b{&a||0 zy*Yhu>TR_%wQjxB+UgO=jaEa+Q`>H|+SB|lR6zG*oArcINC4}Dg?}3``S!>oB z&CbN$Qmww$oGP_9d!6?BjI-IEs#D2+XJfnDo9Z;r)Ye;#TCcemjZB-lPHlCg7F4Eh zd&ZV)-R5R(qY2$Ne@+;yiV9@oZ-hvyU9ndUJEa!c9j*eUZ_mE@4Ec$H@Z;0^|vNf{h=fIXHpC90CvwNrw#b6Gtb;YT(ChrnC=aW|xYG z8EwLG6RvZ#-E*q#?ac;_vRPkiJ9}>zliy;g6%d63+7&_WBT;Qt9c zjl)wlH@h%e@TA0EGf2`HaBphi{8n?uu^gJkOjGA@b91$~CM;dS5WB7Wgr+38wFVVQ z--eSM4~gezcY10pjESH^wZz@VzC#{wcans!uP3!&)VnoI@jzRvYwP&0w-m>(KM^3Y z1JL=Kpb0`Ej{6*2{Px_xr`v;1sXJ^J5aa1vyVF{Q^xnFs-rnr?oV)G;pA+YjiA2H_ z74J!LS;{IqQaFA$7pAR34$V+HzEodt**Y*~yim{OUo$<~x>BvgA**ragDu{ra>nk%e=m5oIhtXtvbE{TA zJu!X~;W2Cb#Byu1);T}9LUJUHTnbLdHc;Dq9H$Vw(S|Spms$f~a>;y3Bz^4gspP%T zA!FkBho=`w=t_-0qA~MYM3vu91FEn7*i(Ls(P5opWbs z%MPQ@7Yw7(YEFz-=I4*i&p0rmt(7Jafr*Bak^O5pXKP(&FT@f25Yr9F2gdh0aJ}2> z4QIJ2Uu9e{rhAF-5U?>a0~nGJeo4tawn0N#K{4B`i!K`GZkizOT_VkmA@b-`Cno?TW4qV*tj> z_oap)%*yQZp|`O`ae$GD8|5p!)Qzn!riQH^(P}~h0~XsZr~vIFyUsxPZK;cpOXhum zL?#fzfnWqS)T$2$a_inn=SG-MRag5fLF33G+GsGSeM#-@Mlz#DB5a_Ozq6dyFyAwxZg=+v)TQQnJ6*>R=^?* zRK*HYOK=?!ylgZ)aZ$#U$^=z)xYNXRpt-QIRVBwOQnKI2a5##0GRwBMdrL6&5oi`x3fe-W1;Hff(ovgG57JDg zT}e8uR)o^^^(L$V93w~ez8*0yr;LRp#3tbg;0=OU)@GkSXl^H60G$g?6J8BQZ8utJ zGhvI08}Vd9KQKk$)>gK7l=ZcZHauFK2Ix7H$xzSyzdbTZ2n&z;T()vLPmq2!%|cCM zzS@`>IOxDSOw1jcTRL_eY<=_WQN;IwVZe|%jyhB8h{!iL&rFOj9GOF{J4nE+_nF|m zLKO%x4GYH5p2kA3)CP=C)2IOkc0u&VlvwQ`UJ~b?rm;>}hL0j99 z2@L`iBbMbGDWFlmX~!pK3bp};?RPjTK_mc722@I#S{%Drt&=Y1U}NiuQ-I1CrIrRj z@BxquN1QhXneR}9!T`DefHDk{9k^5>JtZCGH@J5MKccXxi@)~mBZ{N*<|b+k=vKPX zA!?ud(CMvcNIu87A)S(f9;OAsHN#?5(M-$G*l`3|n2u9EAZVv#)|N0a--bc+k*ZCf zT%JBzpFY``KG~c;i3EZ_3%0sUfe}PTCPNtVsWbuaZgr47U6~laX`6z~{`L0Uj9_|2 z|8EeuEP)$qqqDX{1M3GWMJy3Ep-PGw)vulxV%-A+pt<+@(HKSYmPSzLedV~HA%dar zoEJ+(vW@Hq*=UNQ$LcgB{(g#3-=h)jSe;D`&By9?{LD?^WAC(M<2n(H06|23>xqIX z6PHVmk!Bo|(-2HNCsZ8WNhup#aWr9}dZBY-A4&JrYPq zOK84#c9XM44yWNaYwHq^I^-b`bz$=BG%5JST>XGQ@eptaPzI3rz+%xm1tCJ&BxRVw z1BbApqLJ3UH*F&UQ18^!sR=V55xgN0mZ*+~BJyAL)7|Y2LDO^&5khX>VX%x%bh5Y9 zKh_x2z=&pk5ohH`39IYv<%#iIVDl+RSTWMXK2_H_P|C#`C!)?B&YhhN4zKVsu?1l@k+X3akMk(n=^kQa5Y5BG&}?@t8t~W(KRGS_!RkU^iz&K(DTbk9Bi08VsT)A*0t7jn{`o=^YSU;epi zpBUEuq$GwxM*lB@bslX97kYkp@s&R@umIYSJx(1T!gPW1wwS{BB?R-kNYxVu1SA{jmJe&Wx{23+bo!Tlm5H~qg0GsL6}}Q2LNX<;= zKaE~!?DRa+`_KR8x*@gOr(4X~JAOFH3c z=9^vExh|9IlA2L^ZvFIMUo^0WjR=rtmcQ*K)0DtFy6u|U+^Y1-y(g4177)xV-X_6TN`^_H`u=M=G#UI=< zV6)c;*2c7~oT2AWoc`i>4anQB3*_u3at$F=J3lC>((@00;q7$;_m1m=yMQPcDV|yg z^i%2|>G@aR9lO(j-ajg6jGvfP{YgQQp1=O%KlKaO3+FIm7J~C{l`Hi8q5o_7j|?1l z7(S(L_jq%i6JXQU-vsaGpAx+2dFY@0*WWYn3ZugFef0Dk(kD&-m4L4R2$?NjGakPoW((DN@= zpZ%5rSsaxHj3(R^mKmB2Lums&rACsTe{s*VpEJ<&*9E<@-rRsEGC;qpDAV&-Qult^ z0G+umptR?Q!Yc#y!5AU?{q3PIv`;rV@_kaVqvy}v^`;LQ?5xOVxEe7eOeooDw=o4E+R^ii z*S`Bn18rp5F|^~n?Ti%i7B%Yh{P`b#_&x(~WbA%v4oTI@xh=--Sq-!3`R*)EH+wQ+KP;S}{3Wb0K;15)W==n=;djBmW131*{@#N~=sw4Eg z^v=KX9qRaQ7#yj!)_ZNj;gnhxdVc%EUtKde?Ar|l+nsg7>py7}PtT)Ie%V*m`C)kV1L!jzdeZ8(kS4f~cm4V0 z)Z3>3l~_s7xBk_?`+bA{@$aR#GnA6(tCgSA?&$gIcmCM-)<@rXcgMDS$5!TRo2y|- z|84Dwp2dIExyuaf?l<1k{Prg8V+_&nH?$jiF4sTp&+@;AZWho75^kYxzM|dG^X<=k zVV@a|6^)H1Wg)0`^!!7&eCjt0R4W=A4Jyq0Ii6(yD@^)Hoap&T{=c{eq7^%j2Jtxd zW;S`U{op?pko5cypS|c$kgp%4A5heln)H16nGg6XcHKI=pb3G!8dK2o|NXPgA2GwW z5&|O)n>6x(Iskfpd+Bi6z#3Vid=?M&kG9}`^4K^097YK=8R#EvGZS>vPcLjo^S}O+ z?>=irVa062DdK}Cn!H&VM$g}Fef+l!w22XsB^dwrT_Q*H{MJW5`owj>2y$CLDKPH9 z^T_s`pP(J;GlXb%R_i9664Ud)-u&d-4JzebhvQRaC~x1d<}xBCTNP`If)_IX_8bWe5kLXA)=A!Q|kFu_Qqjhn|1< z55DM6)P_bh%n}2PQ2Nh5Cs62l=(T_RFU-g=O}!zs-Oy9*q~|RM{?$yVqJ5mEp@XF7 zwHsbJVJeo|Tj#MSa;@h~V6iflz;ZkONjlZqGIFubTpRlp>aAvH&mP*DjQy{)eG$9S z)|#E>@_A>qQ^Pd1vERW;X47e}ICX3qTE#YT>^iD#o_FYU4jQzVdpOk5+FW&NP8~h& zK}~F~?K<7|O7ARkP^jF%8dtYnZ($!(!)dhZ97A)2z$=8#YrJ65|b-)SSuC-2=?GyBGoC ziS6#~Mr(zhO&-?P_VRkGyS5+us|fV+b`LeNDFH_qupJnGV;s|1!o(8VI`)`uwQ%Nz z#~NVAb%;Ko4f^*%!G1IDFFMQv=>Jf~Iex6V@aDpN#hE?s%*`J=Ia{ujoxO$Qc*n}@n`dzt z>BNGA8uNvt3vY3bRh`1ow>Wpt9xd;8D!(*0Upao4f*$T>LkCqOfD9;|f z%PFGW(PInF;n^dz3jn%s%%Khy)NBRqs?L$heCZG%7mBloXBXbGe@}IG;V8kZ;sjR# zN4n-0W=kgy7v`P06Z1I6R6+M;fIT{Uv^tMoDn}|u7Y?9TlsT1?cyW$nmGUrkwWn|b z*v}JwPU+a(Tjpo)I<(*%I(E2RL1D21%nHTB73m6tDjhD&9@+1d3r7lf5q9&=F+iE$ zL)8R3=go(3I;%2I{T1;4rG?pJM`;+PV@DU}@wy+QoL}&pzIpa|WxrFHpFK_lsm>oe zvVRYe6D99q_G(nhAu=2@p- z9a=`#T2lu*ygJ(K9L2I<7kj3$QAWFCPY@e;qc9!Nz3leY5C}O$!hv**Za%XzHNfWA|3)g2R@!9%?up{`60@x?1s*o*hg!PKQ)77VImv^!FuXOwjnkfgH`i``FDiC4XH71mq zv|7>7a#xs!kpS|}TSS(XQqKp4^l0pzbY zGJ0V>_R(@zea1bslU;|*fN@lX4vwtw5f*U0yS2V#cH3az6YWL8X+p8FEXS~qWU|?^ zk5dSTth!kk(H#2x2w@cCK6TAj}>IBDWPX-iIHG$CEKd|%SyDF z0v}&ogarq1?(!7xV$&CNX||#A$Ne}_MX-5q6%m4W1CP-e0@UnvrSqkAQ9wDhH;P_TMQj|Hj78n7>i1WqW-Lb)(Z!BSQi~f)EUqN`{Mw zimVzC5fP(vBk_J0roGXj#~CK0{u|)d-x|gj;vpVIl#8?haM9lY2+=jGzBtdQdjY|< z0j*6OIIo-jns-N%8X;nJV^`!Lfx41qqqkRUI*=M}NuEDl)KFiYU@h%{2Rl?I)&IU*<|m+}!gf*ys#7ffgvZ9|_1bcqWw z{4UK9Xm`2nhcreo3XpBJL87;Yy=Xj>Sd8YICdPf3n3LDmv2CVt9^BHEj3%9925tf# zsQ8qf04b2N0iEf{ry_&8F+^Zc&37JU2dS4j-qHci8rx7V!xn1hr^LlH|HazWTc4zh43T<9Oh zGwcZWBin#yW~{IzUNMk`K;C^YQYHTJ4>Jq^A^>HA7A%=A5tkFD2?eUjr zCmM>tgfv!M=#74@se|nm96-h*5CS>~vcMrgL#cigM-S=H1W{cEjI5y?O+DQ_?~Dta zabbXQ%?2~m=UoBfLudr#6fFc6Sn$K8GouVMHp1g^I751Eb>}t4ZQ@XxPu*RuosN~m zW&*G8QPnjh2$S8y$3OJDL`M;!AKP`1LFRbosvQK`V>o2IO3~;RQmvc4nHfsAy=AFz zdFiN(pqTNd~2zxDQTWxG=g;^0)LN{7SNz&V$Y^b<=^!U-jkqXLl(eh*S+GRfUWxjHkwn%0|A1K3lyORcj zTfQ3_>*D;&2BK!G2x+^{EDo}U3fHi&K2$&{;&1^b;GqI+W$v60m8{TRGLY3!Aur_9 zHhJ1e!m}&B34zH6l@n z`p&sTfs9HgloLTUza(6d$QM-Nw{Qg_Kv03-A{D?rs{*}+E4+!g8Pt&1a1}(n%-*1u zUqTfl)S=V0@fghykQWDSyqYlQz?^Yxw?i}~D^L&Y^dOB=W0Etx{Zdk`F556a7*_U@t{BMyS~&QL zv(20hrTojJbI?i9`7D!f2tM)YS={7;!)|iHkg>T@pF#;1A}EWRv^QGImlP>TFrDy- zIwq@?AS6OQ03X~R!H2~8#-kW4g>55rBg9`2U<+U&Wb~gED2i1CQZ!ZE>f*RidmU?Y zc52r2BxWp#`}?_5OI1~^aRUPz5oo)3X|7_aCJ?p7G_JnV9>UEE4={T07jlFJJ>|Vt z!pY_!r-aGv>e2>|>EmX?2i`h8J#p%-%X9y z1O!{{ExOP`8Z$xEc%epX!v7Ir~WqQ!g)9!9SmuPCT%R@ ze$DU*$#VfI!z!z709#naP^fy?cC-1!9hN9Y1`S^sFCR{S*p&V=2uTBfq+-4O_WYH) zzLDKZpujACM(x7_bn2}vJpEK9AtYUudgtY^BVw^k}=2vtJ3BwqLJpQUO-+5dh=3D&-L%h1irqrUq_M(iJ>x zj1NIA3$PNKEgg>-3%oCB$^vN@0p>eP5>lna-d`9Ap5K%}8p#C+dW{P1 zCXRN|w%s757m^DejV(cB-T2V(X5ESlJH8}UC1j;dPI zD+7c@MPGmm=RldsK|e+^ZZtjH6E2Zaf->CZhE6Y7Qw!`irVC+le;h`I3B_S!j%(N{ zXVPq#*y*eS69zMdAUc^TgGC3_VA-|_jVOmj$|#iFDM3Z$cJH{xQie+az?JDv7qwty z83;cr2ayaNctR<4;ZHlwb@N@=>jM&_d!wmgX{SNVhmJ03EXJt;gototG%DB1H^#%% zBb>$V0&9Y0ysYA9<~}^vha?R0a#i3<`jD-V>}h%yYwKy_CXe7D29zAe@putBKMhK#T2sekA1hqLj;9|N4#{gmZkB*op1)Xd6aEKN(cyQ-5T9X=Un4 zx@YPjnHS*C7wO|3I(io%QldPFSSyOzneGq~%fj`sT68O4ObmI0&>T*}(ae@7PuSLi zg~{;;CZ=W19qDgBXQ%dKgKOokrQ_JCx*!?krBY#T;RH6nK45=3dTa@|y)C?jw2p*h zXivV(`lk4ecg9mE#Qvs3nT_*`a~BD)B`k=w>vHcNS3xA?;|FAetpi~|v^9eB`n(rK zr|d*)77qCWVZaI=n1`E*DU)HaIHfJ=f%3~E6X>C*zm16rtaj-mC-lDh9p18!637Wnr&sJAh$4Xt7}lTl_F z5q08kRBMY8<+R#s;u-z|X_Oj-pkV};48YhAbmQYRF>k+?frZhOA2la5{S;u3=OY_; zqs$cQ0@lzQ=O19v$stbgcPk@77AVZA0E|E7WBO7# zFEAlA2kYM$^9aawvW|xEJu{Bh!e~v;W*q@0BGYpu0<%4ld?hKZu#2n-K@qDm0`uAG zvbD9CPNtfnu%#IR%9~^{NmO4o5tBeMAZig9KGy(f*o|QK;XdfZ_)Vz<9&0${ytKUC zT5l|I)d|y>WLL*%V92MDXysd(F=JG$(V8L}vH5#{Kth+-|Gy9+|))?NWhir%~Lft!F}wKlZ^1n<2+ zbzze5^Eu8VYt}YHgTu59UBd(!8#u}+$h?S&LqiZ1UrhybCp}lt z#eY-D@JW-<*w;e)0;LZ-U^mNmnpEuzT6ZE00A1ef68g0D>WzWNUIy%c7yx~CtI%j5 z(S%(}WbXp<^dE$(h%bY?NKe=@GI7N&V#bjmjH2-TD)iCJ_N)aVjer=)ZBCL`K=}nL zzkHQ$KcIg6W0sML=2RD2%uOXi_iGnO%7n*p0>MTW=y2`Mbg=9@4J*Hpp&7xh3lR{a}}x zt`NVp%wm|q=lVHj#X8}b=B63n%>7;Ap^S0}6FGli=Hc6&)^T3(CN?nxF?sg4k_TVE zA6yK2i&)J7M~j<5ZDThHeS0$pVpWZY?YQ^=JoXfJ2hDI~>_dT-;%M5AgRJdAeoR4` z*CE6mu<#_t10fFXU4WOR=mK`w+=Fkv(f~LP;awF64#ba7Dw z&1)#iA@#%so_2AGKhNVDIW;vF8LK1^Fe zf?K+}2adCqA?#>Mp?kihwhLeLw}eI7V1blrfJC_a6uKWi7TwQBdDk}%L{W**BaBKq zKt;FVqQ5RqXvo^Ste6SWm=Ux&j%7*fAo}JAo}`2VOpZsv5t1UaHYdg5ercx_g8)1v z0aSKr!wYJIIVxJ=MwsUEK2201L+gvHuR#iDh!XL-oxh?5B(QYHt6V2^^Dnd(V=%{g zDB=jd`_Tz)^`JWqB8%$WufJ_O8d2)}ZtygTNT?}+b_eOf+D5P)+8O8hUTf=&%l8}T zR2@eSbP5`pVbY#+oIdc|WJYU~K^w#00InV%uZ96o&P%}YpN zfOUhvA3jzp9G2@mbN~U#Ml6iWrNR%vo#WA@n){OA%_ zlb=~fIKz4IV1L@6$`(aTh-GAlK#WL|Ie0ZYl_Rl_Xty=NRNF|u+1S8NtMv-+Z)}v1 z_~}mQ$6=8itoHO!nTt&E@YD4OQUlLKj&sBj@np*+<4N*O65bwEct$pSbOK=45eRrr z@AjYaM90K15LW7W<7@`Esr#@T(5*q(4)!kdC+;qHSCzMc^C{N&OQ2q_Huk zeli648bs9EgllVVP?96kG?W~PI9Ssb9aBr&7jXd%#fZ6h*aXfZ?3Q5}pN{0wc`9QD zg1&+|;GhG9zVSw+=%1`>xofP0_Q8 zL|r-Mk8AP}XTrhXiW}Kr5b4)Ah61mAt%4LlIx>xXn>@*{7+&?>^kQH0vb zTBk+7dm6-SK($Z31uW|Tp3lx!m zth_6RFbE=Tl39U1>igX|)g2twW1nh&!8FbI+c6pn>JA>4j|;}7TaPBB6>T^|b2e8( zi(#lyP1_1l3wkH)%$}q$Mg5*nS>uxJN!OKD-;49_I(+_RUeY(5l%gZ_G$IF>;S790 zAUy~_h$kUzKswV>m=O40Gr*`Q1Vr+$?9#rm3E93G#+35yFoY!CF{FjVi4I8^MD8dy zOG~h)h-5nWx${nsnaT2E3OFIerkK50Sf7jm6fXKQ2z&7~?I{*Pj2X-81g^Bdc>!31CnoJ$K zNKxzUjw50tq5HR|s$>1oej(}hp;s&+lZm*lT&P`}!`d6@lM+l5J;>@r_ z`MSt<1}7*skv4{qoU}j!#8doxzyYSWMlBC6K@7ffWo^H^RUAY>xWbbZxcZ6+eXy|v9gQZLaz(+9 zSx8*Ww|J!6H@>UTuiIko5c51s0)VlN2VEiE<*Qs+GZf!Q9IhEzuC{wf5VH(%)NJ?z z5HyCnO&fN7>l~3q-mlM6Xw~80G7mLs1s7oiU>EgANkrRp;Gv!@n1p0-W-~yiKjfej zo2Y|e^I-x-M&^L(XRa$Q95+9NY<1Jc^%Sj@mbpjF7y=q=KdOUq0p=`Gmc0+a&UVf8 zNQ{2O+fy6%-DDh$FbAzIL6u|)dM(Q>DR$?CpN%j4RRE(O@@qBU*F$8iUPO4~h*&_P z%Nfw*I7*f@{B2305TwsMl}tx?_-|AgN9^MJCX>ERi}IkqSZI*v%h$l+kN}V*%JqZD zgwxgf=VxX@muvC;+e=35ntF$7KxmLX+8$_4#F|OKYH`RvqKOll20YebjK#4HqHjw` z9^WWeeNFM9#TiHup4J;kwIMnI{fg^EOwC4t?9V_*%_Pwh&G5P`|tAG#^ z@h5>EA!jMcL9;I9U+fvr7Ghfj-Tda13PZPJpmdb_WhwOS~EYs7%0&<$oPOLU9*y<%?J|+s; zjBa2XIfhcOJBu{sMW*MxxrG>+M)t%}01g>_h zx3=)RER+siSa0~fo;Z5<(PM8u8gFoVvwe0`Y6i26F_TyHC;T9ZuAPc#50bQl&fak| zBXnw8m{H<_VO%+aOGs)Ct*9DQ9sFzxCqPzlu6Gl8c9BK8!bEGBV*#JUOuKh#~Ljhs8(&BCi8Oa_B3O~rA6BeLq89t;z0Abej*Lf!02f2FZtQCp<} z_5u#^5@(IkAUPYqskh#^X*`BQAkZ{(x7hEGQt#6Ma`ra#*xJs zmNUo(U|$LSz{_~8!T&bp-%gvKEBx;&|J&k!*ZJQK{&$oAm72fIe|O~Htr|b+T<3VL z+mg2)zisosXZhcA{O^7A?=sg}Ugp0UlV!$anK4*q43^jUE90@;l4ft?B1UJK(OG76 zmKl*{MqrscUOvM$x#Q*Y{5M0WbH_M`Mn!d|M4kJubI*0|xz0V;x##+6uE}($bH{b= zxXvBd+fvkSZ*euoqt1h_GX`}Ybe%D%GX{ud&~<}H(qP~XhS6Yv4X)E<#F`BT)Z_+D z#td-_8aH{MO&&v&>#Q)YD-3jnfvzyn6$ZM(tyX#Ht4#A%9`hxPA*)x6;6|K+X?&VFX$Xs>KMj`0Lvk$lJL2+qmZ2kQ<_QZ)3zy^Y_y{ z-qSqZ(>&hO+~PEMcv@;Q?9)7y(>#>Z%${|o)dLcdt7IX)_I8Q zOuTi5v%wHHxa|fH9Z?=I++eIW7^@AT!v+K0V47?&iW`jL1`lncz06&2Fv1&5k_|>+ zgAv$Z1U49f4J`9-3j{`Gg9o<361pL1@$fboIf}#yrA3|eY-xMqiO>2S?1*Xc3`yF9=ybD_(vx{OMfQR(vdx~y4UMytzc zbs4QLqt#`6x{O?x@#%73T_$svvFb7ndfZo!`|33rP>)C7<1TyLWsf`Sac4cL!=3fG zvmSTWV()%ub;L^jF zK6L3LmmazF@k@_h`oyJAUV7}(XDJG%kR4U zp34ti{=nsrTz=&8$1Z>T@}rkOaru*%KXv)B%b&UYyO$ro{KVxaFF$qpnaj^!{_5rD zFTZg4#mg_>dw+6&CVgRSy0uNe3^ZPt9}UmX>^wfT^M#!+?mW5k%+$_TcV3JEIzAep zAp`!HKjcsOgZ?~*{Uiqd3=jQlI{0Ad4`2S!z~O&BPJkHJ3)h1+$oyEGgvHr=7|8e` z%>hgoTlevgM#9w|S%8JtA5!ye-I6N}|gQF2X zlr{|;O2>{wzqL2a$8u$ao&#MaO?{Ac^FURzr=+cqT>6xyuTNh3JOuX%72Ovu zy?p6K*4c-kwI5)yefaVtm%awgeH6M&n)?`Z_jjSYkE`B(9-8}v>h8;zV=7m^djz~c z3yM7#m#4}|>I!*!eCKn@_h$^}fA9Gy?TewTn#A2LMASIG52TLU zh{xDG_OTCP1=;VU`y==JkN*BA!lQ8eSG@A!D_^|wcfIoNSKjl=dtZ6zmG`~! z{#QQm%CEli@GBn-cjoo)?A51Vedg6KzxwQ}UwQSbuRizc^RIsG)vv$$!mHnS^~G0T zdiCX3FJ687)d#P>PKuUxzM+_j4_A*{}hAcUXY`Q4r8 z?17RKylVs_edRq@9=h_rEAPMZt5-fab>*=upP@l9EkK0d!0128w4l*HgkeAI6XDTo zFMZ<(x*`TlF)&MjFG=+j~OHURT}iQi;rN`czi;J{Y87&D2|zdLt+L3_Y;`C zL!;=W*wklXCE$19OrMF82S3w$Y#hQcJeVQM{&O}qa5^@KfhrE`!Y;3W&jXbY&8VLz zcb8` znS;>36RvG`6!%0Ue+m3Y)U@+5Wa7DkACadXmXUSco*cE)n{Ix)eC>{ zD1AxgQx~qi@Zhx<-g)hXcVGL)v(XVAtq6ewmgA?c4bP8`qz=~~MIRMA+qchS^LOpS zE}9As)Z)R`a~FFtAatR@sil6xx1nDn(?8sf+Vj?3?DinDx{F=3&FNqr-0uvqpQBlA z(x16e;{9ioC4J{Qb0f@EM#HBMdtZHe3X$6jQ&%4%d3U|Ug{zNT{n*vtxccbT-@N); zS3hM-{9q>u190h`Q4{f&A}K_6KS9>9~@Z*1zl-^mYf zy94N(O!SSKS?eU&`3glWoaDij5b2wb!OZ_|*vR82F_QhkJihZpm@LUuyka0gS3jy^ z^NFa~B-8PB;030&lrD&5Ie?Gbw>l)?ak$-YAj|NnOV3=6h-T93-)M-fOJ@2v`7E*` zn8o%%EZesM5^0}A((J34R6iLZSgvmajD%*&PwaeY=PQv0`Th+=g2a}}B>4+yP6@Iv zAxZM|4o#OO1;Z*q_LZp1;TUxy-M|$FG+CunT|dgF5u8d(#UeYAJb<{o{g=RXE|a;Q+=dP&F8>hD~PvMb$3vS_rSY{S)$T>UkS{o{Z5k?`o# zeWdG;K0NhDU$CpO8y^(F+rGt!@(aNCv(V3{fbVlq_Aij41N%>d>0hU@U4CTeGdo|6 z^|4#DF0tFE0Wt6;B*^e2QCRc4O~zFqqV0|shQ*Hu=$1~z37J%qr@4tty1*fG#x(`5 z7Gz{1oXBMIA@L+)9v>wpB3slqn|S=Xa=(9frkTfoaTsaMDh)aB>&vPyj6e@!S|y=8 zswmScuJWkjmYItcgnyL1NL0Ky(-z*?Oz!)>$h7cgCbKm?@)Pq5BPcP&7Vv$ag5o|N zRgROR$ZcQ*UfhXgw@%8cL1a3-^Y)zwciyq{&Yg#L-naAqonPH~c;}-#kL>)~&c}8h z-TBR(Pip-887l%NuR)4W?*64q?|_tl7;6KcyY%_XpS%3|Z+`llkA3s0Z$1rHCMyNu zX|hs{^YqWY_T+ay@zOwg(dXa#z`)P1Kljq>&%NXI=YI3`=RY(^v>Q1Usm97m%ntnJ zKY#SkzxLEX_}}@^(|`W;mxq1+w-0`1;OEyK|Mt6Id;GO$@ZT2(VHeo3lq+^Dm5CcR zws>wz4V|kM+?*6-EAq@`@AgwU594wci>%VI<46Xa>YtQ_B!S?kpz4!Gmefjk-J^K1n55NAUkG=lXLxV71HkNF; zk0tx|gHYUOUwi)B@Be$FxRH$}t;VJtf3WtIn9T;_t~k?{%u>F9(iBM#fAM;1DnUVA zDdyU=Tvx*d2qy{&2t$(^x~60~#iU0N!%IQD&XUa1hj=z!%1t_Ua982{DCdZzsYVSJ z4uab-FOueQ53|`;jUg6NYYotI`PyHr^xF{OlNy$vkB!iB^09B0gN}W(ymP;A#x+O3 zMZ~VX)obCjizRft51W;+%cr_!*Df|WgYghj{z8}H;nnOO*4Ne+f8_IN)J^2zZRls- zqy6$hR6cQOzR>ph+Gf3pQ)F@ut<>IJX{|2GgAYlWsyGUyf8qjzc0qm|hmHmDSyF;Z zw|WaDOielY8bF|fS#*I0s;%;EL}NW%=%W`E@+F1beo22uNgHCA3|@ZHAq-pE6Upd^ z^?=rTYs%pEMC0$JJ(x1IxxpDI@`#CSe%U@Ml;dGKVE>3VPHi0%*_klaK@9&yqkql~ zBsKM{19LH`@rM06z+o^Vx6tx*^Srs9M6Q#>UP~Vp>ku6P@v$KvPoJrbaDRZrwt?VI z%H@*H*#>@GUI}xGl|z0ft3OEMp|!P-{6WXJ$VcfDH2Rb zkgX;o9oZN87&b<+ii3u!^2L=b$y@TtuFVNI{&OU(Y%v>#8=IH`46tC}x)AQW+31U+ zF;o-sV=<=gbzw@kGl~J^OAaX)|48G4 zf4tdT`vTKy6;4iC_oN2nVE1HN#0An^FDzbucFr~;a*2i+d*72^eMq7AHzUgZt-oQaW`pq|rp>XbS9cO?ifSk`&!C|7_-ljWVtonSRI4(EG<*5HH1;j|) zuH%Y>xqTxRE}CS+9W-EkS=^>BgtHd9}}nE zdH}yXwLh7-Fe&=l+=P?1ISFPfB)NYj7NGQNp>hXOwHk;dx^j&dE+3~`+-&H6%teRv zKouNn^?wyiyTvWrD(r@xz5!utX_P6rZ_CufXJBvRvVc=~1I>VSb`c$pMR{jk-7c45 z^ZmHMnJF@nFzf4BN#Ui8R3pgoG9N*FgN#1{@l5_5!sfeAxKm7!ZJdwxf8UZQH7OSi z5ZTZ2oI>!(4>gnxY_h-C>1 z-})828=iwYI8trbgdUvRoSK3GrE6;VSGFuT=s{7Fv*PAv1K$z{U0{m|UD!_~4gmmE z|JMVeu2RiNU#u*Y9(Vx14~j~-GF?F(Xn4Rh!!T`wpG9L3a+wC0pGgZxV@3=#>b2u)7MKqxs^qYQK`{XS2>LV` zqK9Gh47vTz2DT*Xvi7qViOW*p4y^0v$SVwq2+SP>AY!1`teDI}33n_jC>R(X(@6I1 zlQ&UnRvl678=*CQq68lO2pH+D1^uLrtcS5deIUh8ybl7Rzdj?nJ-XL59z7y?q{N2S zzOgqmrEo-u^b@0Y5XsSv2~4v3gDBJgIvR{8IvV_@ z4=%Q#OW1)U?5p@=?GDxz?%XiWuc+>ZZfl+xqu+-`G=t}D^aDW(>{hao=NLP^t%h&3 zYqD9C<*-}@fT92_$!^c6~BuLwCEL4Z92oWUSo8_RF-b{?IU83 z@o(8M##D96adTi>64ApQ_$6#ENu_`;e%4*yG9JFC0NnqM66 zTKc_(2Z9g1+A1SK*kc~aM5jKI0-K64?-X9_)BaN#`p5&G(iTQE1v&@|xI_ovc`M!I zr)B9^NxIH0&O|zck#k)DK=jsVuJ>xd2h&naNQkcx2(VE(OqG46Oghs}HUWY$5oCbT z?SfR%!2jKPR12?tORz6)bX)TH7;C!b89Hxk4!m!tR^z-dp$qatjE!;Qfb z3|&DJ4$^3!lg=rtSP9JhouwVP8_LN*`{1rTzKN8;9+nynQxq~8EzsIjCMluNjXR*1 zsi~0F7;Ew6w#JBnC16K#lC!wXI=Zl}aZ1`l$O$wdPmI+doCnL*LU*@oe&c?b`tTd+ zLMj*TAJikD^)*aPr3ry1*UfQ-X*ZE{ZbNJE6Y>Y*Dq2?SWIhFJpg^312OZIoa8>-u z8ubJ$thzTNo+l;^?pA+6D-26OrBbd13f(4+c-kn2`wbz9#GZ5?8CAH6Ch<(&fvBd2 zP$=alBB+XNhKCjI*FqHo8x2>h4J?~M`TB=PobD5gkLvh4fU{8GI9>e@7fvfVcFLIR7#{y0vfCPYy%c$8npNe`g=61u@U=H{tm`;aaTg zxs5K0MCewn;a8^xmyyM9&eDh4-w1c6b`;la^PrnzhYIzg6%ni5Xd7B{Ij7 zD%MXaj@qI8=;E*rQG;BD%%l2Fe_7n`r9|9~#*XzH7zz}Q=jMC+Z{)Hp{a#$0~rH)kM247Z?)n#Ag?hZ(Lz);M3|jB8 zG)W%BImpwXJ~H7x27>q=y6}gwI}RKW^>LG7dk;~FPE8}(lE4S~^KSaZ8I(Zz;PzGSgLKlfRi zT0#DeR-4=lGn4mcFN8`K@3R-;iF#v9o)WFv5{-Cuc}bH4F+$muZ*zDOphJ#hGV?$j zoqdxtD2$g=DlR~K@{Tx~Bo}t?5XxP;pP9TP-qHP;Fg;LX1{LG|MLD@^pt)!+%JOwo zL#clEq|ruiSFi9$c&YG-g+8aJc@6RYL^`W``qPoE!2?fBqoZ0~J8EQW(Yr$IJ4LJm zW^{7U+-c=sm0%yR+5O6*@A*=*=pn~`=kJkgMure$OdDe2k0c#`z*Ejo;1518fhV7f zNV`dWPnIswPveerZJaZcCm+v9yQv(XzQ7-Rx&qIlDd1xmX&1*S=m-=3&?f1O1ut#d zr?uC#Hq-NKY1idDA@JloA@IyAJWo;a(iS`~YrgU+kF<-k?9zQk+h;0Tkk$5CQzNT2 zvZjZe;*ythT4^_*wYtiiY6S&UFqACt>8-SjlP1!4F(Fhdrc8lihXeOgqokuO8T@fN zC7^oA;9SM2DVZADch!ulS_!)HR0q;tLa5;-6tb60 z^B}yWpz7f!9md^D@(IJV2SL#Sp_`Xd)_bXf)kDfu^Y{c$+QZ_8wDUv;JWq$~DbG9{ zS(F;!70Hs9^-O^_(X#+)FPF2r$|(apIRljT@&LQ%~mgenRnLs3Ga2D|1`LrJ zS)ocs4qK%&hW?qH*34O|lF1psd7*9w*SH8AWlSb7GL*@yaAXRK0#rw87Da3`B^BEY zRL0kkOv&_6Qb6FRv@0v1ifIQ%^3ZYFjMRYqQ$bdbW2Unz=~+lR*T^O<4apj*&O(s6 zT}p*2t7Oj_vS;N;S~@FdaPid9WkG3f>Z!D3L1}+5*^E*rtMZ>U@}JEL?%Ax0Z8oPk z7)j59fDAb= zkOJHv_gjFwy$5=mGvz`Ynq6C>XjIiX!&~$gk8;gHnK{ z)&g-(1!J-cW$__}vKb7R5p;zJN7^C8;lUun(E{zNV!EmdA&W*#i}1bFq?lCN7d4nE znqa1AoBE2Blb0h87V6aeFvcZdU@isi2fp)|HY{qXbJYHPS-Q5~wBx zu0^GiMv5g9DV8)+ESX5Lgt2oE8O5QL6@HY=@JlNCB_sMJ2(mwz60EfJtFe2@c*v64 z-IB4prIL1K{fC36{(HMJ`vFyy|=kUcIiVprDLR@sPM z8Pdfyj8K(b8D<#~hQL5%;dfQ`l)UAv(7T*91vydEvN0fKm5wq33IU|_DjRy0)zp@a zsV&1a1YMcPx~$SvHqum9i(ED?u3QuWE}NL6ta4U1CZY_N#=|rgp65 zj3+B28s~OCiE*S~3RDTpRZ+sS5zPw1bE;8EsG3yL)^xIxR=-mll&F|cqN0&Q)tKa}Mt@Zk{Z)11Sxso)RW*%O$U0+Jg-P_gs_GRf>8eg?s<4kz zO@rmC36`svHPWc6aHm>BAh1Vs9UB@s{IyPLp`7p5z`2#Rh3-U5J-r4iO3OT#jbr?@cu!7`4g$he!x zv0cGaRM|}wn45SCMco9PbI_HJ6?q@F(s-J_WteV4hlxK}PF&nv!^6ZM3Rzt+3bcmK zi`@i#LC_WaF_Fhjg17QioRi{*-DFbK5Pz`i##5BtP0AbqPw^pc5{k+&bQ+9;Kmze1 z2GLE*91KrWp!7;+lsrk%OE;;pJpK?~C36N{aSCoyor0Sz21Wue!gM!@ITK@q2uFq~ zAv!*oVTwAqNmU2@A@oXV+Qm&tV1cKin}XE)1WaKt3^^s!6gP#5xfCeQDT8xLtcIIX ztKp_Z>+v)&B(veBGyq1XE=behMah$f4Wv<}#YH2Hr-Fx^hkVGWXr?7*bkiC$;tyeB z8j%KLnMR7tA50n%rIaEy#XaZ*#C63eG%bifgdiEC z(izOt{jM@lXC7+?9+hy;NC1qd8pw=9fo?{lKsN(kb4{bk869rM3^#*WWYB|7CEZM( z{U4snhzxXu0qLY2LL?R-W5|@jtdVPAj?GwRWk%p;bpqgKk!$d~%4)*F%_2yrc3Dhx z<*6Las=j8Sulzy7EH^6?C_I%OSxh_wz#7@OIrS$w<4O!BdS-4vQkx zRStfU$B>gbHVPD}9F)NCDwk6Pa*_sjb5I0nCv!v;s1oH0LYEl=HvosJXP^E72)QLnB^pXfKsZ_$*W(;8^4gpk_7clDG5e5Z;M&p zh*=(~H?F2JGIIOcPN|Yt%aF%hTi}2o+yeeW3al9fjDhJ6PJ*j}ky1@^Y;IoTUHls_6NxFnoSj6{OI3tQBN>sH=+3>)ncqMa76kRlBNcS6)IE+whdW zJ-v7xPa&X}f~_!J;YBpS%ScRtrR#@2a6k*S#Wfp{|*td*pxlz1G zR~b*%GVl~?WHK_@%VhLA#!Nq01(6^^#ET+O&P!Ki#9$1$B1xD` zMUyZY5*X^Tq9J28A-7KADaIk2l!XvHg`!v(38Hzt2xKgius_99L=rxcO(3WvCNP_p z%m#d<3^SXSNCi((;jAaoJf7MW1vN%2vL5DkG>EJxb2>atJIMiLJxxAg$%NGbPa$A7 zC)~`EtTK#(_FXW27htLUt_lc~xmr=|P`0Rc2umdbxo994#Y$(3YNfMfm<_^`XwNVx zJ3s{$UHHi*ttbI6OgB7*ZdmtVKZ>W|kW0xLJf6Z;EQGKv#8X%V=PoePI*ZF;O5qO% zYAFoJW#qC$JVkvM!(0^^ttinz7kjw)+e**vZ7akZRwW!AOwIa#2=Q<$F5%Tx|eg|hD*2B4p64F4#A z+L}ZH5n{Mr=(lr{>P-{LY;-qK=(7K$xm_^jM(g1qjddw}%G}YLs>LcMLlu`rLlUXj zrX;zx&-_MY+Mt-u#2}_^h(oqHC0)Cs+4Ylf<6V1pMYH{*&t9u!h%KIO>q&UX6Nky2 z4DrQNNlJJzz9d78$(T`R;uS-j!GS4OltdPOD%^D{#2I7C5?M@cBNaoO$s34yOn@R4 zQ#N_>Mkw+z98)3A6b!^d9Abzw1p~1VhZy2a(LgN5A%-|pG!Tn%h#}6HpTh?pT)8G~qZCYdl7I>#*!j>!dnG82P{V^S85W+P8B6C1T_b0(QFUB}hcwKYB_VG6{3WwKbX>h%-4O6gkZDBVC6$V+0qse8(z= zIAi1yG7+ul*_=rw5G>GOQgM0oY|f;Nn5B|2`{>!6NhQ^DA-arpZF2@GXzkjK<7jgx zWwbCAAGK$5CS^vQs$!ueOh?b=Osc923HT#c(dJAV+k}}s=|1GKIfEp(sThZ7b0%%* zm`)r8BDx% z)F5PZFg9n>CiqClO-jb*4E6~NM7JEr(dLYwzktt-b!~G7K2snTknW4(Xmh4ODS1+b z0`e@8idma8_V0+rD%zZZKN5)LxOdIkoGBZp3C9(KXmh4&Vv1_qv1e`0V98Ost`=kJ znzcDoHMuvaOss30Gu4XDvhhc(qRp9VMNLXIuC7^|Gf+as5jCR(w>bkT)0!!4Vv1JH z*}O?r4b4;4Ld-MZG|X*xY^`nWaW-ok&F)sM-gNH4q145baz>}!xvpaby7@g}_TnaV zjoGZK!f0^r2v440;~7kCVKHPDolfZ1#RT#}W`=`8ZK6wgWceYR5PP2R;3+xSiu8$h zNexzX4YXpfx>XW9%|s>1c~)f8uv?LhOL!_!O!T-D&H7g)QGoBkwp+YtPns64NEXJe z$hHzZIcbHbEKXE3(ON;moPk@(3b!H~obXhjy1Yj6#Ax0H%w<6-^CSWM2#_b0!B*rIoJV&>jv3u8SlUtm6d0uw=*|b-}5EU3T)W zG?aXiTajEHo(c@oC-s6{4i*U&T}i^?U4diKg)7T^8s$neWFVznX^kv!fSImn>sAt% zwvupVB%kG}KqQ6gRacLkWq z=0CTBRZ^}jTT$??!zn8xuoFeTD=^t{f$X=nG+&Wi6bhB_l1ah4Hj)iPu5MGoQ#+Ln zuXqpgoi1%zp&n^tiacd_l(mv~0a`_Nh2K?YtE#hAEQtEUtm^iUsxFFFVXCr!Ub6RuWeFCOYE5=dzWnCYreRW?JpRmqy+DRQP;a`3JgXBDXA?twI+Wb6u~jB25@zraD*EJqlG-FE}G_x6`>GU(zUOu?g*)>hE!D}s=B^cl}*VmZ6pdXlYQJMRKly|S7i?t%9Tc{ z0Te=Wr;=86tF{JIRRgN30acZJa^&1d7EKV?E4Nhxs=9zx#R6728L>6Z7 zt{91H!@FW8ThsBb7>asfB`k0#UP9CePi6p~Ycn@fX7q;nM zLXObjsqeCqfn!!W9ND{ocO8i=N8>$6+*UP5x`C}+v{bblD0+Bs6_0Ru#`@lgpYw%wz>V~{gEwUL;0yenq1 zrOZoMLW>uzEE{C-u0Tb2y@UuWp2`r}aO}~HjXF!(ONvR^V2DB)p6)&KlCmC#rXtUVTMS4_NQFY}No+peg?lvF=T2l74Nmdtu*IC?J#Z*qQbH#@ z6$9B_g?Ax1vOfYWqr+37PRhvz)C+t7&I#)9RKk-g;mFDe5S8?#*nE#N?~JJ&a=^Q# z=t;5tC{#=&9>cp1TQ!2F;tT{+MR_U`2+4e*O-j`7B_%GyQ&}(D0PwDzh;P6_N9D4F zTzI!Jlei0oDmSu+0`E#IaVU6KOeN&$YF`KbF5bbqFoQU^o(G#MkDb>gSQZ(a)P***hO z>Sa=D9a0j^p^^+YrPd;))*_{bAf<*N1;r15$zeh-r3#-?g-@x%r_?*qouQ18dZm=a zYhKEV&ph2nil)W)jq)k^)nOPsvUyl#5QLB#!e^ z*a*+SB#y(oWzT3MD}PkimXf)Ymy)>@p2|(xYk(uhDjKo`jCUKD>R?KBFr_+}lHkru zsSc)8-BPM-KB*^npvRsX)n4*;JH&YVq;iGDT`p=YX*7Q;m?BS`Hs@kPg?U0GFxM_3_ z*(SmuEz=)7rRTH;foWB{wC=}AYw(A}NB|7UQ~{z+Hmy!J4V`1)8vG&isqeyl+AzZ3 z;ctC8OKT*UR^3a>+zDGq#Kfd!FA3ho0HjsT(yC@@s969^@)aKPnbMOwW87Du??Nlw zB%tq#u?B^>6u<(ex{34nQW+B~Mqiz7TFxk7lZ$8w4zlZa#ng@*(;7LZWsi`TmYx52 zDkiFVp{!TT6Hk3E-*=@4{`I=CFXNQ^lzWsic0C zwk6SUb(ajDLU7&Lk9Vz)30i=e&eB|UuCDq~R}~uv3f-9Sp*N8yQML7j)7~;i*42VE+T_%()w;=rU5SY^)qeLPoA?BS^*p)L`dcBNBwjo7nm0n->2`){?95?*!IRTqf7wR~6g za#fvNc(njC+4tumXR4JI6ICBqHAIh6;HZRr$0VNXV;&v=)4NVQOep1}dMiwx^j$;+ zj#b{(;dttBX!D|vnWw@DYbcdv{~>NU5!yiTq+Dlrp30%8aU7lM2!N@>@HB|?)M0q) z8$3z6;j_q_r{-Jtw4%DD0iMd0r|}oI?FuFuhj}`u@^nsxUA*#L&Af-{P=J}H7CgyW zd!FRc@KhS9FYx5>ndhmzc{(lf5RwJJR0us4LQj2xr@p{bAK_ci~<}=jIvp z{2BH1_SqPZwtbMbz(!3lM)38bw0!>nxR^s+j2)GhFM7usdjHPYUj0GNi8S)KA_)#T`LC@-rSnXJlJ zR^=v25n3g@14nxddfaR?K=1_xGNJA>5;fXSY7eAJ$GPL$J-DLB!gz%?4mX|^F} zEfsk=oz~=ZI+IiHl#^vzd>2v3X^v4(J9s%wFXkXB0cL8i^q87Q$JBT@nnlRT_Is3z zL7?+#{9SY5IfzaGOfz^n^-ekUMmhCDIdwQWbu>8@9ldr3p3lZi7C})c@}pPr;7p6s zNWD=`y%8O9W6X5YVV`yLaw=yzO^D~zj?t|>+(;)KIh8x?qt|jV06BQCV3-;j<#aNU zlcPT#w%AJ}okU<~y}WA@PLI`L@2(}ZITc#E<%coRta{D}uNuL;CIIqk-|{N7d3(Z- zUmIW`d7bd*)vo2$u3^u^!;_tQwa0$;+!{&8uh6YXTsTNk;%o-Mt=b^z=9* zZo(6xrDKhZfvQnngTcId{5nclbD=3+>cl{FmREou4S*?k z3OcJRs3|HaBZ^A!qJ~sOxvSJGs&y&aR->rap{Q%VMfHb8H2`{LlUG#5FKSd&)XZPe z+Og!(<~u^0u3?g=xc#Ckcu^I+s0vVL(x5Z$%BIifRCg$~`?> zi&>B`rig5VPcuE1<TiqI77MSaR^tDo?#;X7IF5Ah|L>=0(ewbcMN-&$p+~a2tGg}T ztL>1K@607-9*6`*j6r~d#gb<1`Rwl#@%*YXdjmk(o-?l(7BV|4D>5>+jEsz&uvDBt zR}+--1gSwHs)Gr}UL>MQNNZznf=HR*OPrv&ISzR+L4!|NbWCvJPgs0Rv ztNao~Ji%g|u+E&I+2ahe+nIPLBKFc5lpeb`;oe2NWgqXsu(;}fU{amF<} zL#Q?qqNOu&eg23c+^{C%;P^qqvb#akN0PB@kL}yk`vDD-w!t87kPZ#|1PxN6K>|0p zaT+9XBXglZhV|TFJvZzNG%V;F%!dZ)(jZ+L+&+z@OX-Y#fQEg5h6PxI)M$_z4dT7Q zENIvlXzKj{@}tRt0xn?i2KQm4NlP5D-PSlP>L9YFWqs|!Z?L8t+&2x|X$?Htz=I9D z)(vjN2F>5p+iN6TJ80m&2CKS3vy)xzpn+2wIG}+8np&ebc-0#W;Ra4E=LMl^{N*N{+bB1sv==)&C z!k)Npm5o#4xDSZi*0WM5Glbj>5}C1wGQ(n=vD_hE`yj&nW4JR6oH~V_DvgU7%N^pk zRqxr1jCT1lR?m#(PsD4xzA_Ku9J?z$<&lvh%UD4(te}}gun%U4C_=GSu8h4Ia%;vy ze+H4xSh>tFWM&ZU41*?49_L4^P}zLrBip?<8s8!3^OT$@_9x2*(-Tg*wz) zX_#yp&B&rLgPmr$9A<>w&9FsguoKbL%3WUZ<_v=*lKSPBadFLvG2ooOaz0tVlJiex z>wuXgZW$)7hZz!f23yTwry1--i1on?cA8;(%p{3RXYkkz*Tbx3FBW2iVk`HD(Gkf5 zV+4d|XHJl=GqMY)(z8Uow#p`nIj#!gv=8Rk9CO6`T;jcShK!#hqj+O3?Sg9NU8U zZj~(qVqL{NXnWJ##xFqJRQ07uV1u~)n3I5i;3!TC6k&iKF z55}Iu!x8+Q^;)@<&S2mmXIV36Q;Q&R{cev-1dCUlflyQ&5#!nsGR4pF zd(2_@h#*ghSlP_0V?qZ+kn73tFqP))c+GKF6H%^q7NT>kBpm>&AY+9xM}N-IpG1@^ z%bLaW96dTmkIvDX5j-pbIK8Cf{5d>5DVxpubr84;ISf6M81+oqu4k@v^~?#@!s| zOgqF?PGZy(+}NboW@FNwo_x$IQssJ>-sn>$!!qxw3?w%GR0d}@0{d}*I7cMC+LDGU zllS@`nXUBX%VsB)`G}1|m6;Gb0<2v( zn0<7?2P9*2RAokBecAuW?4)NA+bZxS>qnJ=$of%bCcrBdl|9SEy6ZNPshQ-c=7ou-gvo6|wEXMmw;T5*!qEBGz3|0iM+z+p;PHnQd8>>D-%HiXH%n z$_!N{IB=Ygu7xoJ?|5ylG6;v=2v=7cC3vQzW^k#(GE$} zcI5o+qz0L8mD&?JgMD^LRu> zjgDO};8ZTQh6;vg*Qan*1|n41F4~KT^8T(juk@syR(IV5?AnLjk1+E<^e((dWVy;l z_%7_G%aGj;tyV{r_am!tcH&J0m3bL9+qLVVzYCk~!e+a$Swxl>$n2%+@1oL(Fjtw6 zz&^V+0{gpg#IB7$mFo$BJ%}9d@7jm0Cx}N|?V_zBf;>k8=j@783S>6w6qy6gV4q$4 zuvO3Op|y5x?5Q4fXq8uWW+^~Kd7p^#K9S^ln&F8cSD8*wM7vT%r8B#q`$UlI2_&#p zq-@S%!B)Gl)h_I`TeH)ymw>uEiYa&CjLP5))wXN5wCXJwc2RW^fnFf<5>bsTC3bBw z_6bAR(<*P*t3QV~<8MMxyMauHjC?%7GAvS(XKG29uPvgb9H;<&2W z+_O`+uPfBt7UI=ML2G3w_tw{V~*f&l}%rJ zUJj|ugj4~5sswzr(H>fe^oB~|X?EI!jrP11+23=hkDkS`q=NP09&EG++w8#^x^cr0 z!x033_xHSKtY{AApv5L6(ec-i&*0vwpYfg2dA}gR32V8LiiDL+>iSc^JPqVVvrShNqcOQItE!k z@&$yS(gnB^ zUf;2(O0$#BAko;6>6DAhb};pImV~lLLhQ2YE7H)33>tYhb^5?%dx({e-K27Wxj{m2&~O2rMkQ%v-@12Tt;bxweDUtz6PXRLG;g6YNx$;b|yFJpBd zAS@3cYK6%8cM)}g%nqY|+#s1RBPMHz^&!Vj>*6m?PJM}=HsAxU;GMu5D%I=g!u69jbu7x8Z)O|vz^@Id4(Y5c! zOF#_A9AG9K)aJnf=7IJ#{1U=aTN0EZVoZ9u;i(75l?S=c9RqqYT-ZpCGQY&iSN@wU z%U{FOBaknn%%No=Nuaun11WOQ22sZao_=}) z`n3+|V{0hSwHv`!M2_oSIzcD&@fr2e4SiYR9Xs`5r#|cycYx-Xu{rv%Ph7%~^{`PN zo1?GY#?l$KMc=_63ULP~C=4Ra74puo;0PklRbMS$2|HI@Jcve7#2umuiCw7uzP+V- zLQ2@cec8YTGAO?fh4(QJh%6T>nFws&KDwZf?c0~lTRO8#RWAVvi&?_YGyix(h+#|w zdY=e%Ju736@N-ofSA?Id?AaYa`Eko>bV}s8o+gn&y?7mb#eH>MK|6~fV#5Zx0H ziP5tiiYV?%?S?skZ3e7xl^)!UVIO4$rwk;H+vpE4a0azwDUwCzmtdy>{@DTS6S3_6 zopxB|gt6<&kV*#(yeFbcPrv|EUFpT$3G5Y#C9_j+i-<8i%Y$lvQ*PqatR_TXmCPE(-2iPB7n$Vn@Y4=(EOGU$l3~|G3*&MPZGQld z62h-CICKcV%FHSz{h*2s?GIS#64I|S#0f(WSj-L_PN2JtnMKE3sa)~q0LC6*>EO-l|FM(13B@~tu<(q4rFF!mzdXuQOE06mSXxC%Gx(NaSkOL4i2>nnN2Ieh8TN8IAn+&7uNz8$Y2+4;poRL963CUI<5@va~MHSa0sUi z#VMsTwmXKXydlQkkhM`<+LN8b8Ii6&%c#IOUr;*3sEah2(J1co@zcaPV)-+|y)#0K zjl7Ak_LUMIv7Heo5V8~evK%sysbQRP$UtQqdm~)0^Pq4(1FUHP3{#^na&(- z(;vZ3Bed42W~UJjq!C(b#J0u=4&a)C(up62<;Px1`=nm(+EYQ`v|DF&>Z2PjSHFGzMcShj>84A;VelxOrWy0 z)Ci+*1bdB8JaLYoK*pMB1Y3<@qY=j5$kBy;u6WiHlEE<$=Lkw?j_}pJ^3az9XjEo+ za0rJCRL}6>l(>nhbcUAU(1A=;aD$~dLZOUMD7qxUxMBlPcO+DuvCJ949wUst5zCwr zI~W{3(1}aqbPQ*Vt9V-d=&2sV9%DFQi~@;^A!63JyjoAwS=UWP-)jyvm**$7k;V85s3Pw5PA z!5B6fV~>sD0FFIqnZQSJ2#i_y$BBp18LrZ}L^~lw7mOj+G1k!-9S~PxXFKR}tVK!b z46o;yUFtE8%rQhe#tIsW9YKJgGP7#fM{IzV+@%whRc{`_ZT`GBbmq0*|-XU z?Q@1gPfzs(+hPJ8O;{<%o!Buv&Qj=UT`|#$xEp5Nh@Fif4KBv+b02n}vlV)p@+ZtX zw_&TkQYaIqo&y+K#Ch0p2X=l06P~NE^}D4AXEFMd+H{{d6j7C?Yz|(iY@INHM7S+m zXOj6CR(hPZD8s}RKfz?5AS^j!(VrkJIb)$RAH@qFS)@y6(Ak7#@&tOD_^h?oth~&o z6=yC~&ji%2)d|bxIB1bL!o@nlp)`U1CajPr*cuarX51Q8AcH75GodS`Y;#O-EKS(^ zoj|M;Yz~f1XmwpVNjNK^O7q?XhtdQ|%56#g3AP8vBUCo~O(aYUWKejVjmTj-B1!9b z^WX&Af)fooQEqf_en3n7%B12Dfhzr_1}mCd$oma)t-+NV_sYdb<2pG%E66wxAm@QO zfpY*Vn|%oF?-SCmr*Ycg@N5)|&<(ReqsKkw`6Y;z5dVIIM(28Sl`S+ImW++$Tj>l< z-r$~T90J>KP|gj8aD#GgpvSoVEIuLQZXAZL9~q8Q{-_Lu!~r!d85@?2^REzY?#US)S4cg4qS#yNs+m{T-0_dO|xf@gC|_`np0MbCOTsCdd&+*m6bU>f>W0G!{V5W6Dv4VlLsN5dL5)mDoM2GdoH0e>PBBZT zX!NNhZ|RIx9hccFHH4)Fw_3@eXPH06?Bu>S)ica`hkuIXjC<=7p$Nw*M9Qu8eO(FQ z-`RJXBLCvXtO6OrkYf*WA=(_}*n`T<8W!agy5ppSl37&j#0_hzw4~*DgUa9zVL3%u za?(Kw`T3~mtw4ru9MsOLZdThGag9MX#@3i2re}z0jzjcGW3MNjV~);hpCe}_)X4P2nF%EX zVHlXBGl-kC_5B$Owps1hAYFZ*^z?etiBqzuY+jt3W+M918I;cng+3<~ z^kkNiz;Qw$Cklx>gA?L#Lg@?+m?3dzZ~!M1`jG@aJAo58l%RShOvGF|Lz0rWz0ctS zJuS95RG>01<7eaCfSmJ{*q*af&*1_6XvA_JpwD>#Jq=-;2M9>xo;yG5&LGk`L^x*$ zme77Bm@%#h=~vkh&T$abA^qAb;7i!HbLfoJ>)J!Ge49gWb8K0n^ZRox{5zb@AwE*E zYvTd%k*sqh>KyZdDEz+e>F_XRK9tTNMxyT3$f9V@+KE7VZDe>th>7pdStiZv&_n{` z`*Unm0^(IRL(h@0b2R%LdLtHIx3gBJ`y4u&Lq~HYDp}LDmBQ@e#hT;ABKBQZyjHfx z90^L+bp6Q7NYXi)d(O^&WJ^zyFx_c?rr=D49FCr;ZS>5}24qLqGiO`RlqPy+XL{0J zLb9CzRVLl&NhkJF4LjQtMCcdDS@c)N2DQ^`M?WVo%F}C}~}Hn~bife~+l>fN)1{!)^kIhE@`%q56FJ4C!JQl?E%@W^<-G)QEd*=*nwC|Q{{;w0$62!ul#4) zL^LsS&#lTJ+PtbV!(*a$%%j?L1PwBH3eN0Y(~m%Af11i5+J=o1X90=*A1c#cI-%=~ z+|jy%&bTAecMuW0F^jw2*VNObunT)}AMaqd3eHu*v$$)kT4j?4X`WT4Q}4B?%tztP z2-+=>d7U}XC2WSo&JmS8s|4$+>|yOXC)0r7Ts?~tR)H^j-KnxkVb{(PB^Lv7=!`Vb z+TEpIx}rd4r-yz7e6KUL1?*Yg^?FlfUiOxxZil8UTcvbnr<(SS`O!{al^K?;@xiWb z5P&$JccWsbp^O?rpHPrqy5ZV=?vgwZG%PJQgpiOETTT!SCgx(NT83>`j zUE3f7U2x?I6a5v)AU@rDmp|%mDL=izr=4&^vIpJmd8b14w66?g-KK4}*t6lQGM(A> zP}!V7RO?{Rehod1jy?G|I>-od)sH5LJ+JBpd$vLJq%%ji4v1#eUcDJVqF763Ud1W@ zoN-6=s>(o&0wH=;^`^_nG92u-CsHY$p-}dG1ZhBYs-gkR*u;t|xgC($TQwjyRL_bu zB3p2N!G3@J2x1|PJ)4_@J!YL;zAA%T&2oVZQ4_g&vs0#g5A{#FU8UReu!#v(*^tLo z(OqZz%;rAQW8Z7@!9KILk2E3NQ}u>up9!lkw;$}=>!c@N@>*PFBYNMKqspGuNNyV= zh?^e$EK5XHdR8J})IaiN%z}MpnWVSMCTRNFM<7J(Xc;E6NNlL?AvZhi!|)ONnIG}u zLidyNF*N(WbVljSAvuci;3ardw~)CLuaNb-*@|qjDl=?(VoGPsB4L}lU6^6O(EH4; zE{n;|NhPbih@M^DeNsBp1t&D}mvnQ8%U%&H`h=G-_H-=-zgwE<9)+qij67W!;6{*& z()Lp}Q4{t#Ana42Ek;Y^sqKb&0DVQ$+Ca2YeeX92@G^Oz zjKJ;;ZA46{>P=t7gbtJq*X?TUq#UtS(g{RLl3NAmFdVd$@}jyuR#F`ss>TcpqE*UL z8q>KqMF+%=>Ipi$98$R+roB$81V>(*4+tdHlZimZkx5tee6)(bQ6(gS9Y!FjVvZP& zU8yQVLS8cs4!l;^v(ipVedS@H7nRM5GW3PvtYl2oGn=rN5(!na>4lY|p6J92d6mH> zym)}nJV1X&`rRZY*>Qz5yzm-Cz^H!&@km%=L={@a$Iz!bm+$u47cHH6p`{Cd`H~k} zDl;4;Zd@`RAJc(hp8mKFfR@g5aMM4+RuSu&FWJ$gU@nU!9fYFZ!`E38mnD%q$aFNp zmG=KD=*y&_2zu&GGUW1AFc_UX)J)|{Zz>wsFJX@n#;Me*bmpTXDl;sInjF6a1@~2u zVYCspsULyF3w)J9Sqx^BicH{&u!}MmsAYwcdS5Q1*o~oyF#CsniSD=R5%k^41 zvzJPlVi^V$PvYP~A00qgr^*Z;V(yEWOJ^(v`}Y42w4LKGLd4oMp$vo&v3&fl7ZI1v z9Q!#SyRe?%2t`9yVbw!t7=`xKad5a+1yMyKZ8WV zgCVm%WVVMgBRa^2IFN`I91tz2r)P7BxjAHAK&;+i$b=26%pa;Wxa9I33{kE_M9z>U z;t**vM1Kywaic8Jm9;%&s)tN9v3iPdHSUPjQyECnn}p#FhFUL_VcOxXN+9&^j>w9a znQe0YDq_~`H$){yxLxTCkwTc=V95G168{FJ6K1C;oiocrZxD)xE7BlrZZJeD3|T4? zA*YyKGd@9YB7A>j#B4{2Th*7HR~1az1hc8^i6E$LKrox0bcSFcm`$O|)e>=pN*f^^ zMz|n|M;nmbR!=&^E{i0$F+mZZR)&dPMp9b^Lt82kho&+(!(ll>Ta7TiBCl=f40;+N zHAr$h7$H4I_H8TDnpwneMm(A#uj>iG-WuUABmPW{z#ZCXgh@4WAhTp5BM{vc$gsCY z_%BA-UBsVBc3L-#Q80v3B*q6i%; zo%uX~a=u$Xj#;6MF}21J>lnY;7{A#V(G*E?OJ~?+V+R*0fxK}+#$1&d4*rcXE0wWh zmZdr>oDpZHPaTlRCB8Fh(ej zQH5hUS;_<;97znUmq0iR`Y}XJkehU~d34OWA%fmYXV_t5$6=^3!@>bDh6Bdv*T^oM zbclW(*B;~ulk<;2gmN9j31b`pW9+gqo@65Gbikp)*~HF>4rIB=V5~JHet7i@VmhT%{{>ZFu^@ds$@tB(h{YR_7g?fD6F4XX_NXx6!IiBT+tm_~nyiPwF zp$#&=VOdR>-Jrq3Y;adM*d!5dS2|;*K^k6Nk!Y zH)!xWH4tUPerJR2LD-!R8=2n7sH<|t0S%6#24W<dj{4_Eni-<0G1ixVvFa5!+M5_7rFC6!AS}gC=70Vpvl+Vd_*s zI&W4j_(=q;N^<}SfK@glM*`sN1hGD4cV~(fG!>^5$nZiDv!}~yEP|%&>P(#%NQd0a z3B>fNY?T)=eWf#G{uFzEim5ckI-0^p#PaFHoJnYkZkSe4`1%n@Fqx+40#XwXrm)wP zh5wXIhACdHsjR00879<}E$%6HK7oH)O`ABUc(X`lta>1<{j?Dcm z0|Ni_WI|xCX%zsdAI)o1b||K-C#SFx`H!{Ew{Rp6vdX+CE2<0=9wVAiP63OUDeF$6 z3RMq8Y+{i&S@o5HJjD)+5W^fUJU1l@Vv24c%24MV%_&3~s$8kMDT~r6yhxH|H8P`5 zQ7j}|)?rB?XYo3fVkyI9F)_uIBB`=2PvRwbafUZ*2HO!`sLPeA&WI*drFn0L)*)(e zFvBW}sKG$P3`H}8b0T1{gN!IaHKH@vXvSh=#$scJwM4#TIcQ8$v)bh~VLc zW)6uR5Iv};^(s+>D)aFwnozDE<7URPnW#e5^JV;KGgizq*l7mGM3i9}CM%H{p5YnW z95YNRk|*nEE0ExcAz!lUE4@j`;ecexdRns1U@JlqRnPEYvl&j`nM|$%nS*cT*oTVVMwxDmHn|fxFv#4_0=%v>?_SN zN9TwjlG_eQZmXwpMkL*U2s%BhVa}0DB(>F##@QUvMBdr~d298w93z5G&XHqtwu~Y#ZE!?{+ZCK)9?YGHNk5vt$V02L*=WvI(wx=b9J4jT@k(d- zGld8yi@G9r*>Y2FIGgYHJ zv3yhuvlcQP?gj!=xXOIdehig!0(AHrh`gz)OXB#r^lItMwySiT6KMW|-EmD)Z4wY79T}7LlId%FbPtQ(NgtCpL&x z24@x!!^j?6hG_#>l?>C;Lgi$9U6===t)x}vqb6>Zi}yeUzGRK9GPtmE)~$Qs%F0<~ zKI*L``PGZDrvkX~f=p#_VHDg6QEYO6?*;M9Z7T?1i5p(IxJNl|* zR-x=2uiCU{Wk%nHxOXA$U5Gjox^|tB)m1N<_adun&=KLCdKzbhc`Ad3aYX`Gm5UNq z!NVXHRAoA|`Khu=Viyh}MpWrIJd%hNEs)vl9Fn+IPveXjQI*Z3Byv^R6F>r2-St^R zh7O1r&m11QVAqzS_V<7c9k6S^hW7g`x*{iQfy@@8egteg<5Z>-*os(C?Gw@ox?xvr zRysp5>>}fLz0so7Bp}-UHI+>gyIyN4WeMoeo=fS>3oiW#;t}7wh;MSPD$j|DcNb0} z_p0hE5fq766IV7^hPzNc=}}dt6UVfu%!I%Rb!@191R}4MR0daw^If~2hr4jbt_>TN z>9jg*ple&9aM)uPS-)#5N54bNa7d&>jgjnO*zC!$>2S6Od+cG|kRDZyP5FBcI2{sj zs;7yZfK%=MRw5{JrRJBQXaY)yd+2~Yubou3T-$@F2{cuGMH+ih^qxI<+F$mR@7e9F zvWH0;Rb5nTvA%~Dv{wbp4EHct2rO0Eh$Wy@Wlzu^wnzk)=18zX_GDNWoOv0ed^jcn z0!>v0B3soedzSYQ>wDN9k>Rv-=3PQ_MDlELD;oCI&j(gZ_wK9g?h6&x!-~uqpOzO>0Bnbhl@Jn##Is2W;vx@wAK|!fN0jO<*Xs1Bsx%Jvy;GqwUqndmBP90` zlKWl-4)>wQec2ubG7OM?Y>j;k=6!_azL(F#eXs8H1TB~q`=Yu*mt0Vl0Jb;*}kPSBqq64l?;m6 zbnxwvw5WPg@7O&hi!#F>NOX0b5kIR8Qs&JA$F!(ywmD!yc7Plso>sqmmRo7N~ ziiwj|*|T|o+&X}s4iHfXcIzlz6(845S%C~XBLr5BjH3f=-AI2L96-iXJx#nsyAC6> zY3Ynr+JW6T`q83C*WJ4l=tVcyqRIZ4YXw;#u{PfER!2{@x0Mp@t9hr(T z0&?#St6W3Ig6e>^(*ep>*K)aY%un4r9#hmm;}n%p!S3 z_4F+3Vhh)!Pj$0HnE+j`;2-Uf)V1fHMP)p9y~KmrB!< z(!x?UqDcWd>|^v1GdfiAOSh9~DxI+wA_jD*++=Qq2vVjnmr;dEMCCFo7^Uf{I)eoI zkO0{^he|o)msr*)=Zecn86qP$|8iO-bU?01T?3_a)H1z~$^$I1zF>}@+ zg+3xkr;4fPB~&62mF5Y*HB3lD2RHL&ow4L;63{V8%4TpPGIgK5aT^IZy9v-? zLN{jRp;LL3Y0M%+N3>jzYScL#m#fXvp^m;#X@ryeQqgwQd&5R$4>xjN23iz`&$F5U za$o94I&u}x7ly=y>dA00;Yrmv9O8)? zirz|Rs4Vg`>O&wNw;-t*Rd13QVoDJss^HannD`FK)2JUAHmZ%-P(`{@k4ZnodK%WM zZiuQIV&{{BQIWAA9HJevgd~Pk*)7}OD>HP6-9><@8ktx}$h8rsJpre~5ps+aj0(f8 zv=h;%sx;A#d|**!Iz^5Vh^l!qX^=HhvAmT@HG-le`ZS1igxxiQm`BL75kyR&sRDud zm_%1Mn*@}KA}l#a$S<-as@|MHLPSxF>1>4iunsiUk9@&_rb7Zu^<>!ix<{-tM-VHC z5Y?`tvk|_;5lVIh(T*JaA)589jaYwk#o79hfZF~-+DM&gdK=f)`Ev7#kPXHfDOIph(NBJ0WJjRnUhQh~~nPbHB7`Nb<#mAV%M`T$n!^AB}^r}R<8F}moCY8+*M6nJd znWgx&zjp)>b z2>0OFiJa7~o=uj|W85}lWc?Teg=keBY=E5*>l4h@i5%(OFo{}~rn7LIu*{j@zL~&- z6ZSzTEW1e(Da}~njHp#r`pZPGs%-WmdUZHqbCl>+l}#EG>4X9qzMlwX4V)0Qs;8yG z1a>1@bx4v(J=@)e1WRVSdOx6Hy-9Au zVS}h4SaR6lpCwpQWjX~dbIdkzYh+svcZRbQQ>uTMgSA4f3l& zel>Vp8kX5aVh)MK)U#rz2DdU1m^wRUdYdAOrVgN2y&)tLQ)Q26szCYLnF3X=q{b92 zL(HDm77Wt~bW{cc{Ig{KQyO@4OoZumkj;FoK?@VF#mVfavWG{k-f)JCe})TehN%_d zccn8&rw(V>{WBjxQ`usChU=B^I@KG}875am)RoRy(UP2RIK#A>VN%T?jTvHm#w?SU zPucA&qMb42GyJYIrhbNXG=l_Y_|s-sM>DLWnZ$X43^_JKrq8f~NXj>y;S8A}iXus0 zkjf0d+Dz-y(iwC_5Bdf9xDvgU~~*qUjuapJaWi_XNzL&$;NcbjE(>9A!I)NC{cg zlH7Io$H zI|u+A&Y>&v@u_UBHkbA)ow0tLqr$kTUXA%Oa%_%uO@N@B4i*G+DWK9BPTe_LXbzpt zape;bC=Ue_f`TD1Q1zAGBuU?pXhA(K^XC}ITwJeuI>S)r0(;#^QB<7@Y24|VLQ&6@ z@p>j(>6sItXW~-N9G;$u1|8b1JG1*wm2_t9q%xgaOR1ciT+f71&*Tg}%P>{oOQvvn zZBpXu3B=xXP??YU*p14(r^RkN0VC1_>Io$FF{+%BR!<=Dj;qRaVk=y(q9Qd^pc9L0 zm3i6brpn;VoS<^s891x9J#-HU!|}3NWrpMBv&wwThYnN*VvBo~i`Z6yFIo1FJ~Dgh zNvDo8Q<+Y@4W}}*tCe)Ynb!ewk0pEP2_*J;tIRCg_pLIsXxmridN%D)(sd`yq7{tF zbZ!Te%1O+6(z%!6Di?XC0*JJ>k>ifxdHJj|!?UfcGVSf?)Lkn@Z>m6J@6pNo$1u#u zx`>6@bj*v6r30~zLY0eWPX!QZ+d>z%Fbo@kaw+=d9m{^5Z8z!c*h3@lV#Q874m%l< zYEe%^#+~shr!LUbA0-9jXa`c-5eap(xdZ)hcl?M{jCvY(gdnO6L|*o&%tu58r88TK zBd&ed)59bbaYU4%p42moJ2n?oUy%mazUy2+xUqXsWxniXjV`${Y3wko-0-gYqEK`L z4vidDsIq65Yuy{u7m*kJSD9E@ZW>00a(XP$a(Jpc@QZ;s@v5PPyZ=-G*GER1F2B>TzCRL-# zKxhj<2^}h;C6I5#W$Jp;7%8%g)Y!FoI*R+yWjX3;qK>Q23uJab>qk$-uHDWmo56RX zw_TeJ^5B~!2(wd4iHgn$ryK1e1$M2uRc3eyf?e-ejJOkAPd+ZCTp(li2xc4Yp z5(KX)(T8Vi&x;6^fy~CAwp>hyd-j$pAxN#e%w}Xu91%jMXGOGRMH~?drYFN=7WeHIR6U(x z0qmps^|X9qAe3Fk%!Fm}ZI1Tm9vPEVub07Y_uB@j90N@s9C@jtqA%o6kf#wQL) z=~_$@2Pl{W%!mjDDxKLiuf{-vZNa6*qXRD<^fYfCc)g&qiMdWdr`yiVnT2XvU<_M-cSwnoxaZ>=Cjv>SJ?| z_Dy9=hrT!8waI8D-A4y-d#~y%M%Q)YIcvHB+)s3XZgi$>+;F?EQs9_G2<_1hW@T&i zF;M#UU+71MXBU^s#vwW4Mv)^fNJe+H@~jwLH=j~zgzA1#%4Q$k@=2KypjdP(qwBTb z*-ZdJMI+r^$dBzy344?h{tMiB~ry@m@Wfm`vO&JmOwqJ;9|tFe-yftR^CyRKL&} zIKp(&y)OPDl&%X=C<77JlCB|fy{zwoGrMVY?;o>=^3@FvZtMtP?R-NDj&)HPNVP&P zo!PfDBK%2D^B`eQD*Gi8(y44x;of1DD|X@%;t^p`dYbW-$vh!bGIE|CR%EXWq9swC zo|SOqvSHn1Xi`w(V>d?TD`PNa<5tOhU4~Z&wGQC^VD0`JXT(zJT0}ZUgA*pDdLV>H z<7(gzXQaFvaX+x0;0)d*hD!B7Xg9RVKw8D@DGq^`y_cdg2u7hO&zpzE5|OKbN6NxR zec4`9C0~FCxe8dfJTh$9ixhfFu*C$igj6=7YM6FVsu7*qw>?s78GjkEPC%BfkmMt* z8{(qgf-@+Y)OU)wV74Gq9SC-(nD{!DOW8yncj|VX=|E=wNNPOg1@p@UYN_m(bqJAm zo=qLBbGdfk5WS_C50iq}HQ9l=KM69gIQT33dLu@_nH3S>9_QwDSV8DNDz@C$UOC9W|e@N5qFpBX-*i+@F|cn zn*_*+BEXrCEU9c#7_&qqCPww1sECCrong2T5Tl!aEl~-GQQ7o1W;Vx;-&U*}AFblg zR0)olRWh^b8etEUa21se$pptacbh73u9^TYI#nev;}e>&XqdpW6TAi!hm?sSJP{L# z^=_CGyy?WUh+Amnct@3uGcvWQ>|qn*qH-l1$-p)u^O~MO2x)MK>4@-@5!aFGY5JSg zOGLs>l*-Z+P1uRb#wGdBMiZ>>2_!=vG}YI`gpMXi2d*0(O|Yut8qpwH@}KExx}323 zi&SR?XV4Ybh$?&$9AOww5CjueeG>%01d@vUXr(g@;|YfF1p1kvI40N_4YqEBxxjU! zO5Ry9dV|5+peRV1CYk5qku*(ZnwmG={QWt0QJIcC2 zSvNX^Q6K~HT!A@i(A4Dek_s@cNXMnJJ0&PYgsQ^3mLRV+=8j6>5zODLUdM}R5NC2hD4oVl5;boEGiT0%u%hftUv=obym+NH#ClB ztk$@xQDw_|B1cpP;mqzFhM!mI9h9lqUnVj{ww%Arjf}GC%w}A^IGQ8(h~H3jdd28- ztY+dd^rL5Oju0e;)QC$KM`VlAlaJKSIN~$(qbZw|QYxEh=kRW%j0(ih5uRj=k`-EQ z{LOvnZbWd0o}SIQl-=l|#U@_BP|teW28MQ?I= zapcl1Ui~4b@gyco5#XYyc>g#+P3_g-piB2i;Es8Ir{NZKh}8Z{b%o`UcBu6VfOgRXJ38U z`?$CD(Sx0>-}K&{pIsikygYi8GPkq?yCZ~7zWjjy&cu%9fd#M-he^Q2|-xddWcrNOB^r!}r?|;~RO@DQr zYuJBX8Q{gy<)?|B?Ylw2YX9fMldGc&0gt`Q^oO(a zS9)nn%yRegr*}vCJ0{)}{piv7o2Q??n2eu%)>NNlN<3S=t>|s5_wgq^`rT^#b!A)n zu(uT-aAkhVBkt&b61yJ-s*m3uNzi3^FDhb|4!;*kG66}x=7(on zpFVy1^^0$w%pSiO|9&&)GV#A3|yf;2MWPclYjvsJ~&j?rhCy3kK_c=f@}d)KbUCr?1Zf34x&F3t?dUZd5(n zx_tZYMToYoZ}0W~>7OKsdV#YwKWd_1tLJDNQqFJtO_R#&!xL$)kM;KU-B*W~hidh^ zc;kie5qd&8>ryCK`K)m8pS{aBQvAKsqaS+DA77mY_so8LdGs!{%=VpcP7l93IqF@W zNp>8*>P4r$t^e%6khQ{B65?MbnHt4@mQszjlJjl$H{F zRXAGybn+?~vn>?K7b8N<#gN(tG5?ls$wZU0SJJiuWuf-T<>BR(=5M*aC3-VY(a@dP zHe|J&TZE$iB?kA`_qEOD$EPwBp8L_6Br@HE;B$Rz**bXXpSJJ5dvkamvk;2z`!xR^ zMAcSHkVz#+Kgt3SeYA~}EUr#Zj!*woRR-YMM13W-e65bk?;rL;*4o6}(zIsNm}a`pQ4(fRS|_n|8amsz%ooMSL8 ziv{p85UKODlq6YSoFBbAk*&M^;>Gl{$1h$y*m@}GoH{;R3oiIUqj-0I^nLfjonQRo zj$6uVexa_8-@W+Z&GDtkCi+YIO^F^@l4N=HYJPt9_KDgF)`UQ0L*Gf&iGXKYFGSPo z?&>=s{@qrZDcxY2ljA4)CDmedtJXgpeYdIg|2_I{p>-m6di476>f|ziSo)Smv)EmY z>a%wXn7)$fE5Q^%B=Bp9JY;JNZz1nHxytC>d4TX%tIv;L9;v(Sdk^l2761K8`uWA# zsn#E5P9*owLS!UPexn~g9e@7xMf24cUw`)b?6L51XM+q-_Z=EmfT$$d=V#v^zbtZW z>#1~e@9R&;k1fJp9-j8jPEUU7eRmYAAqh6kr6l1|ulfA52SL8?1yVQS0@Bw1>ghiZ zf0d8kuX+hUkYG=Myc41K&R*vS%`v^J%j1*d%by<5zI|=`<-Okg@H;KXdS7cbar*LD z{Ql3cv*vdfUc)^Qw|}zqUViT4?CM--Z@+qR_1(Y8QVL-nBmLsDr#&qxVyaX=ybQp; zyE=V!a`dYG`VV4O{iYx2>gCxh4d682&u%~eteJiJWY&WHP|F^f@~g7D;#{;@S@ra` z=p{IHfihJ7v!wjl`9qeg54+{+!zPwxpNoc$&L4hrdaT9G#o9)>)A`1I`Tpk8XeV@ zRXQndjUca$Q|4HzrH01qHVq&+qewBDv@%U86p-`y)FpzQ?%aSVf z+r@{yw#OHjXD__Wz1vpV{8?kWT<1&L4LfrF)Sv3(>sKJ7adKq={hOedT18BL!I|zq1MaVg(?;(OLaDe7b;(x z{uk$jU-Rt8tpYf_Wt{VC3&9j1R#}D~Uz`O!reP_s z@I@@*!#(qn$dZ6tH*1CP zMG9Z?U#0WuQ@eRS>1~~yy*xa5Bb6L#Vc9ViKA9GsyS*ZuLPKcf;qQpXSBYd5-0i!6 zI{Ha3{dviw>Q0`;uh;uiWzH?JS=;3+uSY}`Te-+Y)okPWFw*PqX!3vCPDWiHoJVKt z1|ygk-(FkcP079GcY*uO70B}G&5 z&Vny@6*{_)Z->x1f7|U+BtaG^5yt;bx>ioDHhZcA;zGR$LW9fcO15FIl>AVHmQUB2T6I5p< zc=zR-!_)7NpnO$_Vu<;Rud4_qM5tO7oSj@<9>s9u$IyOeul572;a9VyhT%qPp3;1g zp=3l}%-+7clNfN7CjWRf=ETP(|6K_9xDaUEqe-c2JTo!g)PrvwDe%aiJ zyZGrM_a`oov=1V@hTnbb>FkTIH~ebnt0B;?=GAE+)j|rmLOeaWdKnPB01;jP*E`Pq5*YNaW| zpL%{Qzs`Tib=-j`{46x?mVRnMs6e-;(9K0R{Tl9?c5861sk+V;dKLyiuIf4~`orE& zXIGk3c|zqKJd-o+{8*m8Fsw`e_j(qN7|?5AX&KrQ6~WdC+?s2ksTT2hci)5iq`u|&|Tkh*Ooot}>I?L|6 zLm6oGcv_j2xU+ymG5MEH+WXB9y=D|mtlC$yVSYF~fA#aa?_R#{3+G4Sz5jV1=xl-O zKCmc*^FzVv5*0E&mZfo^@j8MR6+>^mAGBPI)nMzv=$3q+Ftmlq*%*DV6mc$5_v z%fKy}aF24gZezNkVj1JT2k~l)R_!r*>%Mf?Zb??AY(ek!8K`J|I}GGkBk!`}TJ zTiWdoCo}CIHPxE;^LJ;lcbm-x$-UmMd$Fl14@V4Ewom-j!3$L^j`J6P+}1!JK797a zhu{AC-t&hKes%X3ny#(8J3;&f@G|T*5*MDSMb~4Sww(ru&NeJyT54@M4cSMhsiMDd z{ETg!{C&wFDs^9X>#wjXx`mc(qta&X)tz9fYoDa|kQji{xRv$s@r5BIrr+BqPE27& z*NOPVE`JWEmL$lfg8U+e<7lo$?4kTy?K-iyHT|&ns`o|jUwfZEI(~G~dm1wob@#ux z|I?bf#ddn}-+I5#7ynf+3hXk48IZA1kt^(lnxh}zX&?7up)Lq(q2krq+r#72g{q4q zk&k?r)z@OJ7MrgNm9lzs6|Tx_+{SI_NW!P70ID!Z(@EU29VNq~Uo!x}ps1AIR=wQ< zqN-SJMSrKU!}%&9X&Z)g2nJpFF)EQi35yzQz541XUf;&A)(QJ|Y-&_O6kEY*f^R!% ze{VGoSaJ7;u5>RJ_uH}46P?Gi`|2WYyp(L~J=DkF8_o)ugcUuaej}GOPYqg~anpBfeHEL_uY1$Xsn|k87i<|~8#|3Jqc7A#B z@h@ZVtwK*%XeR@)o8!s2E29!D)Ez$%{rslK4>t`GBWvy-q@+nrfwnQg z#`r3{t{1oT3J;mwcmD z1qLO)h+JHj46lW72m!b?%VI;3LX0mzBL$p7RI_jryt(z8m>G8s36$tLX;YM`UJ~jh zU_V~jo%rlj%zFH4eE$8_TluuQxPfg2nH(t=JR;jeFDovncjuQEciIhze2cZyi5z1~ zQH8;3EsP%v##CA_F5Vo!j<}o{g$Q9+AX`M#iXqrO7tQ+UTX(CrTPahj`Ygu}P-OlT zh*DL|ZCy6CWKGDSMLAzOwMMZ=uYeP4}l(S7cTOTBgtws06%Qr`kXAK)Wm|6z?2U1LB zx=NEgH*tA<>YYuf`dLe9fuW!r1v|c}++m;E%ViCFBN{44#DHI}hI@w<2V{uT|v?HkNOnlXAEyY$+glNpB~-w0E}d*v#qP7wR_r zK!^8*|1jmcH)672yRPoT-cGK>0_h!Nt?KGzvUtfxK+7){ZfRn~kNQAo1gxJ&9^yN#%8d58C4fa#DH;cj&SQp*%aF@FOqT z>+)HADTTDgIb`#6)nBDIa<yxXCHz3j9 zRCr$JBwp}zRbLKfNvGHD9^9^?O%OjxO&TZ<0PKO?|?~Fs1nR(8{DfdbD9}aBP{i3b{gq zk}<&c^>em7CF@XF9X--$HD=4`i&kn0k&LCIyA2;*vNGEf4yNs5xrgod;nLoDj20R$ z3kKB{j4u&I>ac>?(7iPew9+b(Zp%R9II$(^*OFJ-c3L^)iYNP_z3jnO!-icc%fu$U zRIIEY>-H3iwzX>WkDcx6LrCM*K3hA+#&Y($^4jVL7RFo2**KmRLK1TpxHsCe{?f%J z@v%$^ihrtLYY9Z;s1T^?2Xtf*TdVK+&<6Tzdy;!tBv{)Cp7muC4SPGS(PfRZmM}v& z@O{z1DoYd^Yg;Xxw{v9xwS;ser9(_^7F}Tn|4jeur^JCSs1I39FaK0axk|OjIdGh( zuRoS!epRW|2c9djRB!Pt82~GCcIE5fb?M7%{yg|~H0GAz|N7Ur0iPY9RFDDw{T;2dmgoHj zP{XAX811p67;drjE#HXZbrAkcj&C_+f#W3`#mij?0U=-uRTB6z$0D9@p;~bYOIsqH zK(6}p2Iazwq15DNP~DP1s6|K!ZP^WNL|W?mbSVK!5mGmX7Pb<&vxvJl3|!rngn9y} zy4FBr1_X~P1FVke4P4avukMF}vG}o+x(126_zfiTjRI+_T)HxquF5lg)x>8@`tGvG!|__0Lwx-D=@KYmO}JQn*z5NQbo-xay75socO-g<8BT znEi+lcR!M?2$Rv1YFR-BW;>L&>`|zVpA1tFbqgIol>Y8^K(69;d1I@*wWW=bVozB~ zw7)J`Rp~DYU_(qFU*tLFIG^nL97X${ws?TejC>7uKWRFE7-$$;w*ch~IfYR@6Ls}Y>?H4=H1N1U? ztE8i|9*gNdf^xJF>kh_m-H#2R7y74mPU|(f!o5#$LsJ7^Jm&_lLaFG~Y{q2BeYTA~ z27-S{oNve3VYuANUKtJ~Rz;oasIekm<=2^HLQkgz&4 z`n>wPb7RR_8Ce|K)Kbr%ygT_SPijBWDYdYeLKZqe#Jcxdqv14;Xm{}tR@pb}@eCo4 zSJ$rpR+cH}M{gA*I+o8QMabHhN|zcy8oddcVoxs*efZ@0^s6tv)HgrZIxOXfsZ%eu zwen%LFohUGs4H0=sh&wX_ zR57k%P;FdegrfQz`b)F8bt$TN_~!EMNw=527|^`^<6quf-g|rUFpd&u&w6CE^U+22 z1eLe0!U$f{Ce&s0{n?YR?hl6tqx+GpETE`%DzunW6X8sMXpRMqWB~87C0=#a`g7dw zZoK^K-Y}^m`rZ0b8^N()0I=Bf5>23egrt9Yd$I;kd@j3LjF!MvY=hdW&erWwRpOAO8((!`WInoK?nW#_T)5A)91e(0#uy?!a7q#ekZ^W}Ed8_N>97HPHAlNF+_E~59M zqq8dQtCUp>oZ>HM{k31ZFk!rR|2K)V{C+zE_ukFrRbsFDy;fM3{q%ezBx}n-K(N{}B{3!IWVGOYkdzcQnwjbkEKpZEOt$`Emf>@S; zQ4IW*+<@!B2~1tHWv~IKl?GvK6-+tI?AK7opC;l}Y??1_#An)WYZjs+h>sEn%VQ4D z*!uRB11_DFYhS-ORu<0F?`@)osQsXREe2RQ8#nH=J5bE=^x99nu|9+_j`9DBLybKl)Tl~)??)T%P zpnQjZc^^{=-=MbR(@EED{NDQZrQ1}lU9p|ytrvksR#FSUmSDq-PAMGK4Y;+aS_p~) zzJ4D6>H&J&&pTAzmxZE;yOV3C?KSqR+rQ_s7_@PfWE|wJ^15 z_0_J^GzTF~)KUhy7ic=2sr0%^^yxLWPy62ePjmq3T<0B)m>U%aYea32I73-WIk(8k zQ~9Ny*G{UH==YTru~lv!f4`Sm0}p%6lP3}Pnz_<~qT?`eo294vTpJ#rexbFQ-vwKAY(I%L|3_ zrYkj0dOdoS{ePYr)=sv!6fI+q5k$A{qw$EkqG5+3@ewK;%8aQuBN-cQpvxva=Bdy3Yw9T%w1ZXAY$WllwaTl<%d64pq77%f?Tw zlJmWFOskK*ZQVynQ2`3>4Z~0QzXRO?4El2(aDmNYh;Bk~EMo&`uQEK2ls(bo`gBso zT!}V;n%J(>f!t+Xu^_eYrmYyCv-cxU3?WMH}ehPYVTGy>;jLovr70?x?PVa`{EJ418|AHCA&J`Q1BPyt<`czEh}{ zvVc~*#vNGbV<}l-R;F2=_%kG0f$M*$es-^}7My{if$EZk4Gyon8=Z(LC>FqM z_h8!1yzcXzLkEFDd3qcn>|5cR>6`{(lSHcp>G0}|Ikj-APP4WH`zUW1$e)!LR`2Ih zJSa6I(}{r3v`<1*1k`e{Mvi%nJT6I(TS3aav=WAnF14o&$GJQ5-l~= zR%qA>5&pr>=v!q$KYn*oSDoc01`#8&v_t>q@Zt}#7VMU!$EWQMw1su_O)$u|w!MyC z{^`53AA^9-4__Uh1xLz_kQn-a49=_%RgHY4k^Ps5~M`OKK>}v{WzVIQGM8JvC-QW zo8@^RLrXYC!5@pDrLk;`F^;Pz{(m->oZuAS%hR$vb?|33LE#xIxC(MA;=eMK-6Sas zr5jWb5^`z6SNjW0+XL4TCSPp3qX?U@Vn_N$_sanloxbPAmgSbHYop)0qqB$wH4qZA zrZUJ*`S`W)%T16a+A=v6q3rh~`039bT!oGQ+?fT8?$%~t2jpk5AXxzJ^6*bb9ZwuG zf^8|h5Q&T^1B}-2g#c<5Qpk~2@RE)~skM{)K{c8XR;#ZpGWE@9|2vP!K;2?gK}%~$ z#$+zC?mTNbr$OMGsBf8oyBDBZyUZUwTIRp#Gyc2GrxBo$I%j+Rp5_NjV5j%mIzS?} z=HMkB*d$>~B4d3zrDU0U3Sp;zC zX(hluycl<`TMhWMSORJ0lKhMA1P4+liOWxYd%%1iPNuYhvEW@^zy{M5NHjP|L#j zn_J(O{gKp*BURRia1;}V#%~_?BH%4*7o<#EDSX?;rh``MEzeJws%op%Xo*~X_HC%; zqL-tMN#M17NpVpmQ&}t!<05?lt*3rVD>L1w^Xf3}zx1S3U5eOza@D_76TUEiE-Y=# zv{KrUdUw~iF%~-++(K@oY|_FWM&imV!1aAY4Ix$+r?AEH2AHb%LIcxE_+*ma6MxF_ zs)Vr_-4O%&Knc5JdL)$A>FV}tOF^gX096z4euKEx>7!{E7`(X1oon~Jh<`2aMK2eb zh~0}`EpeBYtFmS?(QG3EQtFV%Ih&wIva#X__~z@+zZy?p%pN~}@!6N3y?FB3|C@c- zt19PTJ^o^~_UrNEr=N{KUugN|S1;zehikb`xqIVMwT0?t{N>XZ|M&4{PZwLy{^hBz zh0<-fVxgR-V#_A@vSkza_qWPp>5yG$3qXN0QifPYn!#h;?Vz5Gpmp-wg21U!@;-&& z`BZDA)LzQi)ns>>$;dtHl?!e1WX<{@BVUL3^A_~WmMbgAB~ND1yH;m$Xff_*Y(JG$ zVeEWdPyJW_C!B8rI>cCm@q9D0ai7|n^Jk$B+ z^^@Jgx^>-zCl-^m)*MCo8MbB2*ex70k4sJxGTFB$r=kaZB)QQW$H)OEa`;$py=w_ zwX&eZ3;@$s+WJ|$h70!3%R9|YEkNqy7GW5EC#<&k=3)<0+f}4QX-T|<*trejSblFI zlw`KqQL_!7I-@CX%H{7z|Jb9gQ=mu5u<^p_z)gF_bAvVqwRZ~UQi zMK8Vrfvm2WJ5sjDN~v#%^A!yzg69>ds$iv!oho(;rp% zXRRsJ@yl8O(2h5);BPCiPJ2rr{UhXTyF`shu9gfpFY&GieXC(_LU!QAo6OoJ4{B@e zUc`!c$=^WiOfE<*@&67`gmSX8Vj~#Qq?>AhfCpQmZRL{$$i~G_EFt~|ihC*=Q;76o z2g!ylrdCK_OLP&A7oDvt&6v)R1J_Sp=V>1IR^i%Ac{0cR-S=|`Eg{>kjMoc$oZcGL zZ9Ne;_oc?*qZ2Wj6&X`b54TD}d+LXOK8lk&sajC6?>SwY&QLBdrk-~**zO%hMK_xf z1(E)CvN=8Y9b)S~P{6nZe0$=z@YrkvY%M|L_SOg>M0t`F?F=3q$j7!duJK=a5yO z-tdHhORWq;H5i(;ptd>d+M&7qhQY;0s|fzG47R>jpI>xY?OC&Y9rpohsq*zV&hS3_ zeD-uEe^(5UZ@Oi2nA2xS<#%=OjWOfl2887-zmCz|9y8f|17fOM*EFuX{~msf$guSy z&-1?^@U_EIPLL3(F^hSW7FY((w%!uM82|d=RuiJ{mN~icvo!sizuG1qiSyeUXv_ba z{`_UdNz#q`*3^*%omhL)h63FJo$c*RTmOVZ_2MWN{ADXzXx9EFSBq@@R^DLU((&88 zrQ@Gs5gy|SRiO7C+^s%e^S;_75v-bW8ozRsB?=00Utu=V@d({xrWFXm*6OKD;-K*kGs zAyWjkoF{5r9llTGmtGbUr``Ozuvgx-81uXT3Xi;@j% z4o(;V&3YGD-(q9+U_{Ylo3{wOLHd_oz3tMO$BWhMFp2U4F7Lx6q(}?=A)?i4@B7v9 zMfg{>sh#=d*R}~lw)Bj10d1!8Y#KBdb7Dyn|3(d4I8k(b4p=D!6eJ#qF_|x}NwKbz zbJ|dmcKa+>ltw!r`29ap|D^)4`g?VzMRf#H<^}10lO8nSPg=lROE_@* z_g3Jy902&XzGRtDBJInz(yI01v3#RTGb=NM?iMT?YvC35jNbcF48JCdi%v|{tt_?# zZb`k9n)ZJr-|GH~?PZ3peva+8E@b#`Wv`gAE`&Rc*6!SN3-I#s>dFpViZsjI0&N_C zlM8e-_eTC1#hj&0)}8^w75CTnh`?6-YLAx375^sB2I|@Q-~9Q`r&R*oELtM9>Y;f+ zTT{7DyVQSjC({)_wPTO(zPA_2do$?<3U^OSFe&cCx6@U$#(z~+d^c*jBM|jVIzO?mLxMO0V*M6!IQ56u{}tkIw!a%POnmeBv)FMd|W&UOXL@*H3VK)X6cVC0OX&DPGI*0z~C`I;*?)ns)D zi$f22?JFsT6}49=cD#})ngmu=NGK(sZn1o>|LAo z*iPWI#WX*5_eLg&TKK1E`a6Rtx5CnJe?Ex1MRN&6Ms(ecm)pO66qjD!`)z&g0=e99@rI_=U%N{>JLDGO(``6Z#J86Im(55g086gugj?6yX7!lU$__@bRnc)V zBbB&WQZsAh{7WSj|I>ein6D0ZZ`v)Wnmq6BXM6s2I1amFyKhjn)rdD7`0LJ)zr46m ze)@CCchS@9;~zu5m&ND(v-A7Xy}H9s3r3q^iqer>%*=zlo3tKyPm1Jb@?ZS%`47K- zexZ9;ufixSpUL0zm6kL8;Rotery=v_5En7?%bot$AGe?X@T+^j(7(FXRh|FWO`W&X zDy{I#i)X((j=0A-sQ7K1RP={KwZ(1fO5zu}AG*Kg-uhL5?uy;@5b2`Xfav*y4x}5$ zy9my5Y;ny)PTB=g5WVUf12r zE82@2Pc+grty&N|vS9L3%*H#p2L3upSgF(UnQbAm5rW(LWz`Zj%8-ImuG)E zI#pmaq=IngC1I67=k^5#!ZvPSFswq4-HU3C45p3FT0?(+Pn6-k&-JR!-%@6Y9q z%~$oM9F3AQynNH!E;2y#k+9l4{5USRf02JHtTI0F=KSo3oMxp|(@lm2^`fA|%b=tC zpXlG9b307F5b~7s6_iM9aR# zYsMx##8o*u1R>JuHhz{4`O?BMz1BhtT~?S1LhQgcbg?Mf`Y^><_e-2a_3jtzfa)l2 zbU`jOLv}BE$kU~*;Bx(9Vwhm5u=1XNb)Lo^K`6%k!`dpEbFtViH|Q1FL&rb|5-8DGIT7^FVQ%m_@^` zX=4-0l0r)V*L)yQQuyfW1)baR)1BFm?-cJZP$f?@L(GT0?wwTcp9gj zwv-CzyR#E4Um+o`oeUy8m7^;2$EYBU+R{^eE`|_I+F5PMA|^*o^F&&<$p%BC z)00pxPEK@Oju>^&c&<`z{Kayk9!df);#-EjO&E34xLOSTcMYxcb*xTE4RYWjrs%Jg zK<>zM=2`PZO)f0OYv)I>=#8i1>Yr?(qoi6`MiquRb~n> zmKbPpvO;zgaDAwx-tuV0p04}~DoA<{C~oudCe-asUtjyNXSe=XE$F<*vyHmZlz6DE zc-%;h-xe;rouKaqmQbrlk{)g$X>u4v@t9+1Htr#OxqfP>%cj;OlSFA6hh zO$aTL#r7GDQp7~nx+b(I>$OMf>*!@2yeZG`y)UJ8Ds}6gY>QT#W`3$xt;Pp~)+K*l z%GTJZSLau!8ELV^kU?{LJ!iM>rq)rba^>rbqpMeE*L0QIc$o{3W-@IS>3*52|5}7x zab6jS0BgNUZ@IrkMB)DsSBH5tdeg*o((DF(=U&8+%Mf4Ff1##MTL=uSfE4a+XVu5Q zO-{m^>2!~WXslPm?E2M^4WZ1?+>44uO&GU18#*_)Y5di`;@P{-ru}1FS-*8R|NT|| zoB#Y*{`;5w_k*}M;C4duD+Sf0F}z-Op1p%|GxTdCppFb%6>!1rAFTXX36uA+kMgxV zqP@maO85-x-!MO#49%ANvaNB82T_N*2+&4h^Ojj(NzdlrQg@p~EmKPQ_fjX{OsBJm8 zcxN>eCd`F)IWwwR@{rV9MV-jiM0OvmSg`B3o9GZkUYNBIC!I5;5-a|(>nwil3f<2h zLj2YahWFZm#82(t-CG@7F|yVD+NGPSQZyN$wzFIZAXtLwq5sa8CHG?f@7r%BI9|MH zJ|91M^5TVtzc}cwBDN(DNlSs|-PC2cX?}U}^E&Rn*N&sBDEzlP(Va&x<}7@Bfz-ue zEV%tD1>jcc$}=UWudKtre`XeLf#m$U!&}ZyU*%P$ZD!^a>#c>pLIhGWlFlvsOFdL` zrjgnEWpetk*D>=_DpSOjW#4t54XvQ>=HQIto1jqiM5LYynX8Fb7M4YbI<^ah;N2L zmeGv}^nPM&6$Q>@>FLk=y1DxM#NxgCLG&A`UCr~7Yj{Yv?fxB@Q7KzFwywVpTECm5Tg;0Nv_)liYuIjt>z5aQxiwh-9rmBM zVLIQ>-(tdLS6^my?XrH}WQcXIB#nDcuQj&17ec{zg(R;P+wb!1NiuL9Pu|f-T0ReC zqukE+={{w8S^Cz3`62jododtf9MPf)(ze^6>TjobmiAe#d^Tyu)Hw#J8;{eRYg8?} zwqONL|6v4p)0$%4uEKSs*~ScXaTkO{eW9c465*N(Z_$O0&a5IOU_kS)ouI7DLzhwh zHI0tX<)nFW`0C%ZhB>{AU;fL#9Luy@{!KV6a->^rEL4`=kcH~dI^C+`)~wTQKS`oh zJ=~g;y7!Znx>C0Usrrl-Rq+<=mK#5X1IoZtoNE$vhUuSQpPihX{c!Y3=-0Is5M~9) z+SNr^oVQ@x_+lsOE7))3-!Nf5@W~%disDEXN$J@NoZsHgqtfZlf{R7%S?aAn+o(P* z3|^$7e6jW5mJn$UZ?On!Io^opbMn4w`Lr2x9fx(A65t9)aao4RGRZN)zyHa$ zvYJq@=q#x%=+#>kj5d8G$4fsFC-nyWm`1zQpwr6y+O-waRo84HZkegirdH>=3T*** z6R=A(T5o$L&g?Yui|Pgo>o#ciwDHxjE+DS zYC=b&lh^z&@|Ed&9{$W%^(s58&~1|R(0j&}T3qr<0UQsoPuJei&K5+#E`sCr3(^g8?9_Km{#aQQP6o<5RgEmvq*k+U98j6IoF%=fUP^J!O{A zB@*4R*3<(z?aIT@Y~FTl5kvSz2-3sl7LE?MFU;^!8&-TEWT4F?sZqcjF`uTG*DGy; zx(ao2emJZtG;D<~_+~07Pw^@E3Dw|*YYZr57ziiF7ffMm#`j$+365G1I6Rvm35M+p zN7mxVyl}hr9}b}{)2e=GWE`aV@KZ$H)_S1` zz~dQipiW@!Vv6ZB&r(3Q1S;ba?P_6)ezPK#np9>H&Co8EGpSXAA`Qz2f|nNYnC~J1 zSX$iW7F3m8yu~Lt7k6KbU+0e@le{zma9e|-2LbDIg)QBl194tsY&W%Gru$F>X^T9b z?sH=SL7FzkC3RGcdJ+DdVpKD@j#t%CjA|OE80O2ccN(0@k+9qQWA8pmN5rWGCd{4v z{INIiRRZ9}BKbraqXCzpktlY!1x*AIuu_eN@{$HsCnKOO{QQFh_Zs18+i)By$iQ~B zpEf!-sJ7tc15OWyWawG@j(KVIed9sCu7xUBs6U;otN-yb;98me?=ChDAx;Y94ci{vw;!bK<-6tpTxIY6UiOtMGFT8Dy`3dF>dlLF! zOaP1V$382NQ{E~Vc>a{!v&a3(ZmtSxMaU>?l_(k_{{)I9-a2eSKH1jdtQGBS{L$h} zVRs0sWhA3Ib)*?9L*%~Y{$=grjt}0x%KJA}Egt#mPxtq`I(>Kt{Ff`wPWxlz_@7fV z58v;s1|Lwarp<)u=okYYi)c2mx)Y0^t541Y-ilCku!fByQ*_Va%8st zOOhups!l<4`b~=S#y6lYo^rvGnt??&RvX18Yz8q=MkK`*^0{~o5J82UmpuxIzXUw# zU}o2?__Z)Ab2w)t71Pd3*pbvq)cvciVYf}k7Bolb&Rf*08EKF<=45{iiazFjrZLt4 z`3ufw=Sz5QwEQ(bM;(4O4#Tu=_^~@Cp8414z`ygEQWpF$!QlhiB)=gz`3LI^PkZyw z)jyp6pzeUkg6)A}xp_4mdz-c&g)?8m9=#*TIJb#dggYt4Sb|p|(WXHq3Jc4Ij6_CI zefl2yye51Ni$<|bghEebPfw2CF|Wfi!)}(B8?OVQo(XP;Qw;$m|6A~JzcS#cxWRry zFdzS4yJ4xoUem5*n7njDHvHP&X=Rs58B2Ltf>~p72&ehLwxq%+g{4da5o0;N&F}+) z=u69{|7@NmDbOII`5T&&Y}``S@wp^hl4ITkaN0*n2-)oX^&dYfh#mTgvf@cv7<_H} z9cEn+?APAROgjUb7;%mv&OCJ(>J)|cFiro~0$_1=Y6l8YPZwxR_g28wd6b<$K{2t) zdA&Bts`aQi=#=)RqBx(6Zs=Y!#5c?czYj*xa?NtcG2ug_FVUx5i&ASy&uFDto7iquR8*fjmJjQqDw^|4{N1Kd)NU=f z2+1}M8`=AADnWj8TPPr;A%aSPlWNs$4o?Y}KEc~u2th&IEKKwRc=zDkL8{y#P%uDEvsm6`A4BTx zN7Ip>4gGEJp(x;Zcg=giineu3*G+4Ae`Ry^=~J^ESz?jOAx_WC!|?#km*vQN@;bi& z_?vq>AK(4>tDTSU{YFO$s&%wz)h=XHc&VWh-5_n(&g}MYR#X`cRA`Aku%c4#nOBh=V{Sy%Ba9)dv|Q@S-Bg%du6`fJuV1RY@_=3XtnpS z4Vs7OP$*4@j6E1_{Y-}o9XQn4Wk=jOz~AM4NX23G(*CiY8MiWxivQ!XH` z!I8jFW)bBW`R|0`4*y|NAf;!*H6Q%7&3|}S>ks%3EhYV*`HzmJ%orE@JRe{8(g5o0 zH>|!*<1xK(9po84Nih&JjTGw@b46Gz=i0hUF#Y#k>mBVE0h*)g_HF*r#8ZEPwq`8w z9xcKP{RRIeb~8QNUoZBfnYc3vkuIFYdwQa^+1}_BSw}3uJ7|?F)jmiW^iV#>I zujD;~+3yzRR7;H-08*Fumwc931A^P%*>QTao9Nq^ow%6&WURmg%kb#PQYXSzNfLSH zWS4;<>jS$FgP4G^l1!%;CwPSx6l!$$3_|CO$qRh&g0CCn%1JN+3`~O_js`(=bbMqZ za8+CA{`fy=MZ(vz?QlcV@S~ z`g!{=`RlD)WHg~|;MgdcF@{5qD$iiC7@F9M&qy+b|D$_JO92)YE8y*!G7ljW7VePC zfWuhhTxec7cAvRn{)(OwXJjA*Tvzz#A^-V=|9r}SKI1>X<3Inve}2z@{=k2zIP|~a zKdb!b5&v1^Kacs(i2v;JpFRE~h$XP`iUJZ*gM@;o)R~u5fC{4^!aourX*f{NHj*Un zEPYRk5Ytupo!Ww~e@Oj!kEw+L=mS(rDOFPD zCQy3~UYvJcDFa~Uj0J4kAGH?bz`8OfZf5gvbdbutwU^|fi(btEm0J?C)sw1ChoftY zd8)WV#i;}_SpMesF6bPc!`b2F09MsXql6hE-oW5=^6>Vni6#P+CLPas7qh+=nB~l4 z_2+||v1vK2lCQ47HnDhpr+@5}9Rv3iD_& zaQc+y$iC8#^tl3rSa?jnNmewt2rSW7Z4Wrg+FJoNZEf7oU*F}(iAHhIIaY?bZN~%3 zwG?re6euUXL<6mGt_D4{09&B0*|uf~3tHey+T3fT2|JgZ_c>Do>#95jFsp5 zonT~Ze-&qGe~XNk@^QQV$M-5}I320{nm;-Kd9UMJh?6=Hx{8QZR`OCt*iX+7#};CoP+zr5ga7## z?v`lDQiH;JP|D$TXL)zaGSs5YRCCo}diAn`2^!`wQHA6sM0odP3~A*Oh}UKHK5)tK z5?@bygH-1gzpVw2zQ-YCbUxW@s9Exuq+@PJ1SkWZcGis3rWjnQf$d?Su_ag~F9vK& zrZ#1ZM4ZcUrhs8dCvxXJLDmbAf6w%7u0m^bSgG2Y_xVPLjtF8Lkb2AvLPP-?PyiB_ z;73w(TkO>~TFWyL)>Q`FdXw%}2R?OJ!ha^*vqDwO|i9 zmIYgT5sO2~Sa247=K|`Fv8! z)*+bGL<{Dmoe+*;fa~7Rz_*EsE1-M*Y`TZM>7gC3{W#vcIOj#a$BZ32BX;BTIJ-E2 zl041?-oHEkQ6`YPyCYo%yt{WSyU1N|MZ!>D7`%P4>75LO4Une)E>A=Tq;E z(FAG@OQrtX(ueTqpWFI4z%22cj$IbqA0Lb?k9*Jv*+X)cA=k~xkZ-Zz8n`hB1o)25 z_72yL@kapm`pVXm;pW=<%Erpp%MGOeLQ*m3p+@pZN5m6Sfs!pDEy-=6QS}6NmAP=Dsf(aUPG4$SzOSZ#M zqCa;U_&2>igKdO;>b>c!dK+2oY@ocG?+&Pn;< zo(R};PJTdq4p*044q7~AAq|LgXix}ZU0yEtk9Ey)&=tDIziDvq z8AaY5kQAq}#K8@f1QL4<$hg{egXl)xZxBd+hPWsY0pSZC$-}|%F;3igxu1>hIVwI`hoK#IYBPE0q2F;3yW&}S-GL^n9&HSK> z;@j*T@h-)0Cz7JXiKQsP#rbo@4V6RiymtXTF^!3SLB-XA@!4gW8VdM9rk%URsa&u- zrJ(xNcMeJAqi|KGz$iq=BFYJBoH3@kbiw=o!58dm#@YA?cjx)4TI%NxBa-l}ktZ}5 z{Vlyvp+=m^K<=}DEC3S?lCv?b)Vb$ZJfvfaVoQkL)sOpVY}@P}z` z+Cn;5f&hx`S>ZpW>cS6HOx}#&G3}YB{LK3r-?s;R3+L?JE!Bb-x0ef2a9&pWoNbHY z5gf@-D~zSYiBk0F^UF&btD9I>jU^6`$4EJ1=Y~O_xg+3`gH%5|o1V>JEBR739w@X1 z@$htVIcV164=bWxfwA${*%UfkI6Bk7X=|!1XDJV=jsZVgQfr+ zosy3}%HFn@QF?K!VVTie+H~RSDz*#Z$V20o7N0=sk_)y-`Wr-@{?6+zegPd3Bqa|f zgqRI{9RYGQ0*(&xv@Rv9xAzU7j{|~C+m3$`$2gtAZ99a79qt}Y_vmiL@c39>eNRiI z(5Yfev4;aj)ll$~M3YRH|ME9!k zQZIg^k|G~*4Tn!g7eKiA%ZeE7RX`=mRTdpJAjIgXsDKilT@Ca_g7S636feIbhz1M! z7XP1QXy7?F!TgD@LRUE9aLIy2G_V4DMO=!Kb%?yuUAesepBK?hE$V~P#5j#|blj!6 zIQK=@5N|b6A{wK*2mCzMSaGz zYBY>bo*<~o?+8@2{;}X}9MqJFWFASqFV4be6}lFOz>Gy-Aa9yVg0PJwNT=i;wjac75Q1FagpE zd24R=t|pBhPJX5%VKyQrsIYi%lv-0sO%ijcf-U3Q;{oBV^swEB{&)gD(EnZ`og^$| zS$S|@|I-4i2rJ7nKHhLN9-j{QgE$S^;n?$`0qCLYMaAGH&i~vhRCc-DpG{sPxEwb? z6*)Igk4iS;a-+=7r>6+o#AV675rrL+Lil^+)-j`6E0e&8Xo8Oz5EIPjbOWoHLakZG zBi=_%)v|R*%d^c_SETRu5m?kz0kDuRGKu=?5fvK=RMyd|l(wx+L6}`l0nsY+;56F> zux%|Tv(1Y=3e1Cxqq6D!g2v{xhyVPW@%UuZ*SGAVhS^L4ZEyf(Tex>@{mkiw3|GtA z)=2D-<+e8nSf|4k#4U|H;;?c{tpmYl(0Qx2oeaAytlYY>+qy*Kg_5eDV z+e7^{+#th37ixn5f_b$(p%>K)K#Ec@gX(dlIV&!)Su$EyhU}?hUjUY97b<@NgE!>( zbNay8f0~|AQ+lNI%TpL7*hzJ7>SWXe8~`*L^AuG;fnUM^k5R-ku`#Z1BCiw}Z@J@MH?8@0|Jgs_io~$^@khjxWBPGF_ z^>&&A^nSVt9Dwmdf&fZu*yfv{)^GtB*5P&jpm4yQi!6grUwpUn?CGQ7=IWER=WAFt z+#jfZd9}H=fpWVGQ?yve`$2ztx$y|!K5c9B^u^fs z*~01ggD%P(;(&^l^48=r=aDqfgqyLm-edX)5f_RbH|v3vuv;UpBVFOAS!lAqiSz(? z3>O%)<03MN9F5z2yp!2?tS|ndqlT$y2wvt^;{@55ljGQtmGc{)xAek4KKAMTg~4;)HMh|58YfCuxY{y_j;%Z_d);XzYMlV zOMhKi`j_vQZ+&%-*VwFTVC!Zxo=f^h$WPACPiusXGuS!I1UP0msyYby5KTE-{&yyd zZZvfN={j;C=N(`zWJvry{5am8cF0dZ{p3y$3z{LYp}ExL3+%&kppfGYAHCQF16%(N zoTz9)@~#xnc=>jEMniuswm9vXyuHE?kv)BAs(JocDsh_X zyxOpdUeb&}^|n|=Z&Ab^$_V#7&)B8EfxkASiR~M-irbsSxl^GL7RXYpVjII@CcR3+15V zFoEkYzydr8q8^l}_HYMR+Ou(_vgT!R%OY~fxl9O<^rWgu_VKyYo%Gk8`j@q1c!^f_ z_vyZ%!A!qX^$^X^QR#eoL!QPF&Zkvowm4>KF;0COBwpcb?CU{dlkK*O&7z38;R|X@ zqMgg{i8QRO#70+5nkXcT3L;?x5D0`$TPx$LdYl$}%7y@6NmFFtNN}ScsFbiO-=I~E za3i=ZYaa7Jh*}z?A|~bv2r{LvOChlDZA<~+SRc*S;(!(l+&XriM*2%GI-3Ujb1*b| zt^-v35R=XGCw4jjOiindxY*s*5sIOKqTE`sI~5wMJ`UOn?$x&zPlWjYpZ7*gOMtv{ zuEV12F@C`W0F*f2%zO;N5ma1PsqPl)YazV*>5N4sB5MMA399kUcUJY|bK7p9RB6T4 zkJPczD`+u*tBG$YP)OK5J~I^?!Hj|!j7_SIux&+T^u?$GG;&s@HZ^ZqI*fFl%Lic}##LM0 z$V7jz1zX2=uzUB$NH4hG^RVjy2A%HytGqvXP;-b6g|1=(^p0bb(N9^H-s<_~QgpyM zL3@97HYsaB8nhxD4HVXI_z-am6Hyz{c~z8E*RJ}FYr)nimAQv^%!dbhQJ z{XcCqK)_>zKH$IJFapSfonuz>I0tv~&MLw+PR@5$_D84KUG~DYhH3dqIm}|O>@vHh zVm3;#iC0fZYPJh;zRI&=VT7s-h7A`NcjL^mID{eNVDcJkY)3LIS;5u#^+cx|q@zuB zxIfd&@s-+sQdLMs`C)P*S@9B?f9URG>pa zTKD`xC5>XxXsuY=-pEMA58@*lhv0mULewX>*@2gmoW!TcKF@e#^%$PFNP0> zNN!G;>%}-0gKS&1n^jRa0!nIB9t08}3f^RPTWh#u{}F>tU3eR&Aze8;8^I;O!Nb}A z5d+z6FL}k9v}z$XQ9#4oJV34p_RqALVki}udM2QF6wwC71%T-}u4UZK!pINA?Ji>u4gJN^jfZwC;kb5>U*hS|hPKk*jO* z?NzIIASjogKrly2vO!oixH=e;HZ|O@fmEQt(V3D6lFAhGfy5}t-vSqWPbq+Ig6o7s z$`!xH;=4bZ7b4WM;}vsD!WFSEeAr&l6=&Xx07gO*)v<$cJ4mT-g7Za>P(j2@^wOgy zrFmnd-zywR-?4aDr#Pr;CYeB^@|JauoWvI9eI!C+b_$B8A`xLxZ)gXU1) zpy`!OM8`|Bv63L?(lvGu>ga@f5`qQR9vaP-4tc9(EMvhQ&vLd1 ziMDJJdr%Dzan|gOj%HJ~KIe{~z$-UHZbarrtF9QKyBqtxi--~%B4xBw_WCQ(XAY-t zrT)s9uC}!n(7^(GD7DepQIFQ1t!=G!?TxwJT2u7g)-MjFIGt_YsAF&2(KAk@t2YB! zEjxPUiS|aovSIEsspxZrM^~88V8NLhR+v}s@SumtG~U0RLrMzNEeHdeT+kvG|JoA4 zOhTmYGbaC=fy61u!sVy8Mz|Szq$~+EQ7)|-;K)#>OBpO7%uCjUsD4O)05fS@Ib&(S z4BM5zG}s+`b@bA@hF5Sn_9=-2puy){OUd>lVyb)GKxtS%OnaL*dbP#lS1(q%DOlH zq8qJE(g7H@63mLC`f5v58l)DKC*Xi9P zVX~KG)lz4O%i!|c1=na5;}tkHm94T|#(FNtXZvbVDY$~3RMm?t(Dl|_+|{i?rhTML z-fzGt92N7;u&yrk2Hi7UWM?orm1n&ob3=h@9D|`BxRzJjR<87=dZddFTx(ZVZ zQ7Ku#fN#QMp+i<-Iv1e4T^y{>4m)Co^r>Yv*AP%}M((>nOVJ~92Fozd{e>SA7ufz9 z3Ff7V!sUXpus_U(06Kp;G(I|nVHdkIwPi57smffJiVL6cX|U_-e2RgmjwYNroXfoh z9M26YL~0c)Vi|;i4#6TWAVC4vy>&J^nH`MJmg1p;<=);Qp6MR%GmWt&foj1TdK|(s zae6e`8xJn)1fE?wr5uL|1w{D%l&gX$8HI*P<)57*4=JSr^4b z1*~}t9tqOk$F(H;;*wwv{tb}3_j?cT-|x8*hAtTBEN~}HaNSl5VT++uhRNhoM<{Sm zU6$+gJ!g%=s_HbyWvg2MJ**ow`jeIokyi&f<}?bxCK2%rxS z%MyiQwCHs6HK&3t|3rr=#dFl=LrB`@0=D&1w}&_7#e<1V|1Ah8Ga^9gpD(xWX2lBr z4e=h=F^ZnkZq^+b(_~W5fJ66Btym19D-^46>4n!fyK5o(74qESK}>;GjXR#D*VbH6 zbI0kvN-(!s1`p=k$$rDZi{kn`&jtCe|;?0g?PqZ30_O#7{%ZN_b2LbQrs!!h?!$SuQjIGHtn-4u3V z1oZ>JEibo?0QJSZGfDT0-_)~AEJpWOkpl5N@`e`EF;KmOVtw#(M6LH?q3}^iY7b}V z_JRx%R|BZ}@PSbM^FumH%oEw}1ZjsOkXW19{ITHRlu$;gHBd?ZilSV@+ ztqd3^p{BtZ1McUfRQON4?`EDr9LGF)^;dF5M?0^gGeADIFE|7|#i5x_KxtY!M6p36 za%pRa{=1qreOHK+bKjMsa?Ie90()V_fb9g6U08er)BFz$KxPaHBf-Mr4+*0B5lGxd z_$nKu>h%e*H+`hD-fR!%qy4D&b)-zOU1KZ@3+(;g)DS_=S=iUPZ`*fk#VC`eh56bM z3Es!kci=1@|2Poz0I!5r)+fbvT!+o}&0^95s4*0aSIi+sju0L1(jB&Rk;geyv7IPV z0H`xw-C9eOhBbGoB~jJ;ZR{s}aN$*1Tr8i5m0;(g-(~Bzg?zEV3r|=>mLEq`Nc2)B zu%gq8k)?QIm35L^jb2mJ@kqFm*k0k|lD@W%RkSUJGOD`<11?8grv_T((?0ZkR$h$n zhT!@2r5nWt;HkMp)W7YH0aPhWSUJ(4Xl^Ra3Mj`l&BzPIgc&IP`T!;iB+04l7*SW* zb}|1zt{!ea83fq}bY2n~;z)8tk8|+U$f?y~qlMGbb&#|^I)ix;FLtp6?4*d^@!$noI;Pix6lcuqlZ6m)0p)b{=a?AFtUGPs6>lcgQhUB^Yx=f}N=oUw!YV zSW+!_g64xP6b;x5zFNkZwfGmW4{h;akDgu}?aPy#bP(u-Fo%s}y5Xh*jG%sn_B(*X(CF1bIO3!I6&hCMK#|F1jlMDX(QY07GrW*2f8+=XM$bJf!cY zNBy#0Y{oeL`+>hO=u`&WltB{{hm7%y;doq3HiEFa7GIJ+-)VR)DpyRSX231JnrusQ zv;BMy7WQk}B5KF~r0zC=Wh@oV7y#G5)o!cRZ*w&13}SlKBAPvqTF&QqeE*tQV z-~<&V7yZ~boYF8}@<|TuE?xS}^Bf?@t)C??v)mTOl?qZKA+X0dx{wAiqQ_%Le`5WO zwl+X?2Hro0*($>yUCtM|T}JakZz11193!3v_8MJ33gSVZ=$n(@3aiYlVIyOgh_A zzeiM2ANCj!1Y@x8;WZMcck=m%pbh$4*B^iz#I2kl;|BkWR(JTg z4J1H~Fw^x9RMdpT}_E~%|=}Y3dz&9Z9|~tqGjP&jJ5=v}RPHJ#bv{|I&3Ig(R*6c0 zS~25*I2oxgHBl#96HHA%`6%yuKdIe&vo`;fY=`gNYL``Dw`R3P{Xr08m0^gb;_KGt zi@gIpX$2jEPG-p@(-5hlBF+gg~)ErRn|7( z6Z?c@`w{oqI_4+$KW!QFp_kgMgG+tk8CYqZ@gyC~%M3&f?XPZp&!UrRGPA5C>v;J| z?nT+I%2Q}z%!=8^RCqEYKdg_ZQw$?Y3q%z>7AQK;_Tp@GEwSY%YKyhC>sJfX z#xg)q)E02zEKJ)Zw+PMc(U0abEI0U~cR2oWpP|vIjM@Mjni=lk9B;Q&b+=o++fYx5 zXCmQqkH>{=l_4fWxCnr&wq{PoWko)O;A5p-3!dv}%0@n;g)aA>Enz5@jmA*tVm?c{ z4HIx?AK~RxPxQYd~geQpswb zLW@80rxr?7F0sQKRGwC3VIKZmT=2 zAPwAMEx2N~<)yi`*0pow$@w#NKrYr|3ZLL0x}TS$3Q)Fhc-I;6Cb?e9_SrGydE zu*p#+ujjD;8?M1GWb?atZnhKC#k)X@R}avtYMLNy)Zb$H!Z{T-9YOe4f(=RZ6<`6?^QvNpn)20_f;}P z5uZ{qY2$U&du`d~2tq&6r08(?SvIKtX#hTv)f+)6!}H=9K|1I0yM{-iO4`QvXSmPQ zNCQ*veR;VO_U=-wX)J?{`sJ^2$)&}!o=l{egavu#plrDi3RxcO7q|$0oZ88?9Pl}G ze^Ueiib%B7HFs{^_7@I{^I3TD+vE1*>)*h~zl8{f@}f)O;m2h27NRT$+CkYKtcLLR zw7-(NlY?az6sU$U?cS%j#r6#-b;Isa(v&507Ko~)ho>j|;~y~!F3T5RhbM69cn5!) z934GIeppm;TSuMuT*;&UqS+%}GJw0G*q9x|4tA$gc#Tv$U8@qUaqa8S{0H;id!j)9 z&%YNZzKgbNT&-~4(6+>vQ-BlR9DZHD7B%QQ`GRPXon=3Kd39>}aPEh&`F{{+0Ap!> zcvyO!`BE-z`P4q<1#r9dkyXq_;+2tuoV!I_`#+ZX9Nf@ujHfVCoIyPVJ6p_DrHx-u zxv$5Qg??z<5oQ%X%bETVUuUHeDhdmRngg3_?Y4b0RNCCW-THQ)>zEJ@t*matt(t{> z6IHd!(K{~0!IFBihsPn4Jyu&TRe<^wf8&we8DuZr85WW&U8Dvt#ZDwih=xgljDiXx z>e~)4%5D6cK)$Weq=2!F9w0vgG)-Xu)ec zvua!^nOHK|KVIvF$p9L8;SONjmC3T=MT-j7TskoT=Nzw~AwgY+ZR8AT)W@N(QX#4N zMCJ)sXb`p9*N_s;#!b$Q!$xw^fda4Q7;biK8@^dyoaQdqC)2?of;YPYw9<9X&J^;c zI#`5i+qI{B|NCn9vKw&K1!IP%@udhn{iSe})RaKVL+32!`QzN{w}sxmD#h6KArGg0 z#cb+!J>Jj;(gpEB)kd~Ik_!F<@n=QM6vHz9Hy6ILvRAo?9v#->e^Wh6SjJ-eD}7L6 zFqZ3&RP1@k_`&~7pW?a+KKY;N)AO~BZ`asHf287kNtWMsN3+RZ`bPbKh?jV6Tf|&d ziib&9dOy|0a16y6ZvA;(qX4Bci*CWy(x~)o?ZvlxgRURd%s!YZuDw_tB8d$C^YYP} zFg7|x0+BssIKTJf(%ZLhmtc83UPAT+yTi9%Y5Vx)#`8xjTPuX}_~Ph%!sH(J)Pl!; z)GbaXSiGv4$= zb(>RJ0z1QLN?WfFF-Jr5-gNqAGPb+d)=BjY=yL+z&DK+(85&|+u^YSbsqIu6{!v&y zjt-P)v$Awp*3t3oTZGxQH@ENW7E;sJKW0T|U>jg(qqlUGoy$S(^*Ts(aL{;I!w(7GLwj|w0&GKtY2v@q5nI*M)U9hz zMX(HDk^X$HcW)ee)aM&H{vOWqa`~!@?; z7p|ScdC*_Sm0<)hi8{wzuk`$f5}hb^sP}5)Dcw+G-R`w#uldsv6OVw%uGt+A2BFE= zL_fjV!yyV6_-K+6i&<%8{}YP|R)e?y455c-)3fme3ClGr-wo&i`-pvCZft^q`W1<96hUBUDJGn@T>e5N*lamMaVSF% zBw;p*^J=PB&3Me2H>z|TVyasda5+m&kog8L0I?=QqkjY*?5~@?NpTGlTq&QVxb~$L ztzZt=bNFv`XGPR)D-a^GL{jBd9wDnzS5Jf*CM*20T(^!Td#lJ&2M0TYom+qW^6NXFFYn-g3p@9Aws*eY`Ra?G z-tWx5zrDzpQ9S_i#_VFDpJFKct^6?Lqp1WbgE73%p(MoQq>bmTkz_pfX^5^YrPfaN zsG|-HFIB~}+`=(PO!V@N436={9QA|6lhH90E_;arix6OtEOMLxD+zy@=2&!v2+^N{ z4U}VAjz`i(_$ZC2$~r$3&NiOuy{5<&vWPj*9cyH`>4LFMhmTY$FodLJ&rg=~gg+I> zv-0gp`^pz5T_G@lY-8a~0jb!Q?*sAlHL|ovbnh?yVJRq%-Q8S1A!e5y0Fs%mp^kcm z@HMTp#|oZF_yordKC*;pbe3`_6@l0S#e{7va^Q`D(ixSBlUI_PM#RTrZ4^sHUMxzX z?5IzXOLXtCZuWsVb}H}e9g{E)UZGDdPgN+iF&D@wBX5KxkM)c-|69WgzZhCPZpKzT zL4@xXM_975r7tVrJxjY|!7G{yOp>izh$yIeETCeAlfj4FdyY@uDoR5PWC+0C?%Hnc zwMj6+5QOj&0d43m$K-+L*PoY+8CRcJRKI*?$?2FJu~i%`@<@h(D?Ne5z)2x_9#jjw zscMbp*czYGqYe6v=JwnX$d>OMrLKPKi;4m}N>&rc_jv@I(|}8nS~yqByS>Wiv4ngm zopadM>dUx)|haRt!Hbc95HE z&rr9q7QEp_6&nCp+E+U@o7Bukq);mKK6H+6kzJcsk|a)8(J{|+G`h7NT_{Q|DlHEK zMN3Qmh|6{BR*%Ero~VZFyYO*s&=6%T+pJD9(NHYIy8?GMQH(QfELQDn z6r%?1+?B7~v}#AyuU z>sx%ZqiKv$f8#F0+A(?v6W?+-I@8DUijU|}PaNZnucJN=4XXj3Iataa*|q^ey{SdZ z7EY6IYYRqWZDW~2()c!uwaTiebyrh9tx)Rc9_@+D82*!v$%PuSXDUciEz`gpQ*;%K ztWm{2H#Lny`wUZ&j{DX@Xp2>Yq+LOF&f807;el~W!NG1TT8PaLG^Z&P1XrG)*Eb8XVc?NZR!EkRQvq?i=S*V@0rfp zZ~+#X{_esHh2$Y$eY0*b-7df@Jkdw(Km|oJ;Ppx}QN2KsZtKJ%lpnw2SwdgaTqOZX zy~I_a>o45f{^HK(y`6J~8Qp*I$v>3@v+ykp6p67-!49=HR_ST7z58kYkRZfElc}=p<7b=abSE8tOxzMZh-MoJWcK zx->olvBu-!9#M5L?21>m(SjKqnZC)oXT1Cux_4q=;^*i5zvfPB(Vh7;_bVLQcwvI( zVpqcGJMlm1L2*XHH4&Su9%&b?N^#yMP6l3#a8dNDKuoRzL?4hBLt$}w;!MY+IlQ>J z&iUp&9kO~usRy${^!>iCr<5)8905 z<#748nuDq$Pb!i(7+7IKsUn+h2v)-dGC^+vTNzR|d;>D34V+TAla{XC$s zMZYVt%`WSlI(1+;@9x3Aw{-!M^eA#T8_X9?LhwywXNvqKK7FK^h~fB0WYY#AM?-#| z!>hYOSq4R#3#MZ^hqco{@z@Ky9TsK02_+$%?(4s#_qGzcMyKZF>w)>Si*d34oA0@&>l%c^iys{6I zIL&e*3;;lls-HtN5l1i!af7x@>LBK!(FbhJbO2j9>s3iW`OMJeTJV5X(<_+ zr_AV&+ge(c^ebo)d=u~M17am^!IX2rBSLR)@8YGP*!NX}s~ig&yQ*3jE0u3=%-L{F zeGc|1&k;#5g*;R0;)+ZO@q5$gf<_Kb+jyQkk+RRI;);n|vMrV;*qJV2aSibMFQ)EN zfGfXu2ou2W7_)GTfM+k+6Y}yBg&Qp^TG&+2D^5J=9FF3eB@auAz>gGpi=QFvQ(jBo z<)DHzb?>W`2XSIF!t^$-?%1V$;s`;^M^mJ$^$t*EI#|RTST9MTv3-Fk7ldbk*P*%& zj{jt7!M$nEV--}bY=QGl|F=5DELs;RU^vup_hNFiKU7&zavIXyTi6u8C5mlG%+rRn zehi(wdrzQz*Wx^iKE~gmRHxRg7S(Emu83ZsOoA~X}I_(zzW=ViliN5PMY?0 zc1nN6h35Vg5lDr3(QmymUxUrl=I4Njhg!b7SPV-y1T8lTEQ1fSL8X%RxCe>?1U}fo z&9LF93h`BAq{djTjT&wYiXe0R+@tuW9?nvW1bKG5N$iN8c})$Q+X(=ZXJOlbfeDS`s8&Dv@w?dazY9|DXY zbgXJK2X~9Lj+wL&#M$^Q!rw#702$RMfX!Q3N1Yn0bKdY<0KS=$HBIVE00(p#6>*Fx zlp1AQP}VFTyp%FV*-iQ1H78=W+W#t!ekT{F1L;mAzeIqk9_S+`k)W5Z5r6^;_cc{% zqZ;XHHc_ilKcS_uqNmD9$?QmB8BGM}Ci=pDIC~6BWx$#*i~zgf9~sJkd+E!`EF4tO zKp9f7D7Bv{;J|%zJt%(0S_ewg$Q*GVi$>C|R@}sa{9=awAk#j%{|TK<15$S#H`M@M zOPe#dtB3MiRe-9F^}zHa9|;vJr+ku@!GLm?;dabL?6{BvEYSq;sw+e>a03CxZO@IQ z>7yA@39IU)5%d-ksn4rj2+WBck|4oo8S4VW86dmHrhvyYf5*sQASU9%P>&3o z%TY`ug?oI(h@f1KPEC17&qfW0&)T6VqNP zF;u7l=u8bzFFsqss@cUZ2ByFE{P0c>@!I%hsId}Ue!B&2d*L3{&e|N*qjiT9tEG7j zWC)=5z1z1F(KLLqj;A91LOc#&fY+72KgRgMgen2-JS~P&9HdOV=g{ozhIh3mNJz}f zx)%xx>GOD{K}{%h4Li~^*liiSf&#*<(|`R}WKB4NIR->d3098n z&uOQAmV2mudWSxAwczYytIuyY*{9$8{GIqfMWC4m#Pv0X86kaLjumXq2!d`kBy#O5 z^y+r!SaY-Z$}Hb(Pk#zL@|haE@ny?QZ@j&=f|FANf>>tOsyx?H;%tFY4NEJ0&1Jcf z7@}yIX)gP8jhYx;U~A}c7B)Xj0qOKs@bQV}9=nj0wsoPUpI?8o!U!K|e4xujXTu7a zEU@$RG#8;~HzlCp_AzWt;owg!DR!3czw})v#^;R3heEU}_ZXyA+NAN~g?;(Q(b@9y z>dTk^<>}fG>4%@b_?CHxS63)}B}aXn28p}JkU)DCgZn)lNaGPN1NfM}SaOov-|VbC z7}C*WW9M~}lg^eX+={$5hvgYC4j+QlYBafyT&Ttpt7GTP6j9T;w)@^S1T2rIx;KYV|O)p)A8<5_exKYyjx_f(=GSc zz;ZWFPA0U94f@9v;rM!&eGI2KHPNq0miF7;LoNF8?$Z;x?LcX5-SX_;THasTTz&d9 z4mNXfp>b^fAb8ttGY>be`<4JMJgz}o6?D*AT3|f@7u~dixR|OClR+3Q3n9AV*%3(K z>T;AlMvf&Sm(S8deL)DmSeOhDCy%JH6uJrvf2Z+tbrciI?kjahxn22Q9mfLrqAgaM ze1_OmAYXG#Y=m8ay+4w9slT+e^e<~K9?>XokNYfw5~2jm-o*)%;H zBWToab|MOhwUK%*bNwsBWG%zPEjeOEbOskcS;$}mD3mwa#rxD85JL8y)GK1=l9$md(+Df^sy%MbzbAvWKr@5nQMyS%k8| zKnn#IG9<$A;Cl*j5fIJOV_p{=9UZ;9Yp*x0!%%_P7-$)K!Kid8EH7ibY?v#bdAJdp zfIL=+GU~m7`KE^y13sXxX%q(;2^!&%Vetka%D&Tp4jI$d3rSL-n<8P5s3GRj7{@E14s{3%y^d8>5e-}YhYr|KYYa7EC zFSnkqu3`RM0Ui+Ip&76k@F9tjkP%iSu^L%9 z#y(;dQok@fT7%l;i+G)gN-rv=<4((j4V20dHnqz~$n~=L&g;=deq8}eLO*#n=9`^D z4dn`9&qru~+&(@y4c#QY!>N7-T(`xH2u>sw$^4QgC#tY#dc7SL3Yukl3Ngb2Z%KIdJ#}L^lalJl?XqylQ zMoCpFN+yD7q!bH}CI|(Y;eFTX3EVVHoeN7@B}^&&{GLZJ`y4MQG`lYvsiUZg zzAnyA)aRwk!NckkKMC_(4P3{07k@g%7|B*|JLptvEz{0wzj{({ZMp#HM+R3LR9EUM z#@0DPzcZ*t;)5NwhP=|S1^LkbM#(@D&7hj;} zKs1raLK0ZRHma*WH=4?eDe_|WX1Id^lOH6Tf^4ebwq2QswP#IR9g=`=#Wu0srJtLG zBRQPmjtKJ_2Hzvk`9P91w1atq)W#1{1_6#kuw4Q(CSaHE0!*w2q$1}Wrnvg|1;2x| zz)Fp3+W>|Bru>%8Xlis6lmZ|#t-;ACa|ej%J!j1PfjXD^cYkM z?4i?2ksal}qwa+Ac}Y3AG=T>E*T%yi4vbSM3OH>3<&UctIw#i_RP}lY&42H3FemVy zLyF4s7EXyUy7OGzAnqPf{}5bAFN&c5Px#NL48E5n@X&kPb$)c<2h1>EfD)is#%sap zVfM4$@dZr(hoc`5gecCL?K{bvXxOfdX+_)=zkF2d%f|INis~u@IvvI#&S;P|G6}eP z20fYF3OcgCYUVV8z2>c*M$FH}C!c-w= zrr~e{5m&(9Vl7J{V?{~h_8MluGEFU{fgkIQB4mZF5eZy{=%2LeoRd)qM1V71FV(S> z#qHCZG5?gA*vnalG0Tx753T0WhGFA53=;sS(vQt?(J#-Ngbg2?2*GsCu&XoS#N;1( zLL2b(t7Q8z!S)e{FGCr<_4W61-2P*vA0);P@NDh#-4&0f#%bMSuad)Gw(gVx2s*if0~D+foqeIQX8xWluupO#2ihh#9;bif+T)XM8w~Tvxz^W zos+vORVaWWdQRSjn&!d#oDMuX5hr8J7Tbku1n#9npK8lakEO7X7PkmiDZkyHn8x@5 zV}J;bErITEb~rh(Oatf0CwvF4E&%4URWu7@kzT~I zI`-8|!l5se_*z7Mgl1ZPvppaT3g57=0ZW&}-%zk*y9` zKubp4BOjs!Hx>eDNGod+lJ@M$iOEXlIr)x?db!SA19fHi<|?~yD{5;DxgBjeEnx`y zNd4uc6_|R0k552G_6jFJgd-p@s?hf=QGrwf+`6t%66Rv9;3AUo57%WZ7b^>P_z&)` zl0>|7LX=x*;iv^+Hy@wUA^JWJ_LfkC`@<4sSa22IXfGWxeWL`{$TX4bB)>@EBrxG@ z6iZtOF28a`uq6N*Z~KsKSM#3$_trbvhp9hW4#sZzQgVjqV(H5&djS#^3ZVtP1r3<% z9f8bciPB!_9W3MoF4H12^D!{8X=2)hP z_vV4Ikt73T58YvSkyO6e0EKpEu$gvee*=62ry3D&A9I)5iezZM&&t!CwHI|5`$L~z zO;XMnfbRQ%)89?Q+^LWVX>G238&X*MKi*KxSBP#XaKof@^K|{wA#Wy6*-Yyaq2pKtk<+X#h|( zAZ&}5Nv6C13i)LxA!$C*_+5I%@UaLUFabfo>NtTnrEQ<$O;AnI>(ns{SSvnpN#mHX>P&7y>*SU;xevVbrQj5qv{Rwc7f6U>RC&0MI(N6A5qdBJF7^ltI`+q^ zcu@dkAnRUz>IM^S!vg4`#!i6ke|ysJx00Px*WaAjHQ+Jy1w}k_2|~@S(I#lhHJCX6 z@Mq^WCRb|W2oPn+wK?~-eEk&Pljh@h1s z#xYKy24Ua33d4h=&c+rFFfT<^D@L%loH;R*)##9z&fYDxg@TD={gGNWK@ z7rrN>Eo>#-ew&sQ7_AcV)NQcy7KpWee01C^R#dB?QS1w&JXpiA~&gU?X%;?ae znA`-JEJ9WD8S_Biy)csfgaV;Sb6FXCPD}`6Cl!{%1ow>)1{9&LE5WT;t9GaUa+DsL z#{k6JB4<}gCs@^QC1|foy*dqwh2YedSbTfBOrassR2!#<>je&yTc%aO?!0T!r_*>Dm zWZbUOvvI0iqM=ep3O!5aV8KA!W32!zYNyMCn4V6w&coBs5_AZlR1Vy+KOv8QIM7jS zxNBmsJw}qQqBuMa;tvjHXEy*{oa+{GQ5{ev%P?@tqAOifk8bh-04=qwHA9CP^NA(Q zm^;v|`;C(_MsGbjgrNwY%G3uz-dW+vBz+C8lg%%!9l}|9e0q-LB)PK!Ah{Y~ENTJ* z3__H%l@H{b2l#7_TrRcGT9s@qyNzV|l^htPka=L%b2VzkkNrs~;>e793H!5NXB1Is zGb^5u%RS6}pz$Sn?E&5mo|nsyA6^yMAoLe3jMbgYF7G$)i8ph;vPF>e(~HZr|gE0SBZ zuTxeF43RUVp!T5F1bQnN(NGB&F++^YQ+YxEF?T{Vr>}$vvzFyuS3!oOwiOh^h?@J< zRl5Mi5TeqIAMf%qBvqd6qSqEI(u1w>m)~5X7{)Kp9)mIBy-RraX1Ifl62b zN?7v}>t+pDt`A}tMB!`Yo#o}r;mQEvF9)P#d3BeXM-f!AxiB0Etqp;Kk|@A*OmPI0 zVS3+HI3d+SlOyp=oNWA(u(^BW(e98>o8xh!xQV7dTSFd_=rnkoud`x(=m#} zKuS{oO?9zsXcJ;C9!NFM_-f+V34sGT{6>|cYMo_$)p3u}ZpJO)X3=XnvMZK$r)cY~ zmaw=S2y4;ZA14xF&DQ9u-D(#cSn|BevXN}d@qOR6Ey)lWi~;|}o(cW>wk~_oiSC-i zp+AQt_$YDy^~K52n;q` zKsd&O`*^$*MVoIYmM@^U4uYEQO^;^y`p_G^{4e@pRaZe@@RqCOp&G9!X@(blqM{em zlO^64L2?6L?LoLO-&Dl&K+00YoGgq68}~J*C;Pg9)q6a`9V*TIfz8~p*IQFUl-|~K+It2knRRW5@G47; z%hdNNvifmkU$m2aN#;2ocp3G!;AK(;!;7~E!EEULZ{leaG&?((1fm`oqSoZc5;W+{)w*~tKmt)^f_7P$5Y;rs~ z?@<#UBR03+11Bn!Wf$s|G78>GflKmAS=Jtm4^_K0K~`62FV~5jp=TM7f_b`H+|h&_ zJVoHZn3~SYYzul1-E#ZTcjFm1vgd1gIQ9O-e#bLuF&+-X`w``1B83G2TBC<~IlCqu zYmzwEf+puw4aC32%f=PIX|j-nOqMx?!iVJMw}+%U$XQz6qM9FOxv<>hBNQ^yS_qMg zzL5PFdwd}Yxjl;DJqf*AGK#1nWwbYQH9&fEpr{Bq>i_(go&BA=JNt`2gP=oczdp*6 zby*uGt(a3hv&Wd`>K;5>J}=`6rmf*7V9XBg2WHUKnZfM9)+(#I@wKV^7y*7A$qXN8u?vmwWI zr7=Z|*LN`Pcw9ij%w`7{M`lb(BlNBgN=h#npggz{C?St;4#+1r7&jdRu$9WAUzoJZ zO<>f47Ee5E0mreE*#Rbesqz$$8`O7D~HeJ-Go*vy;J4ky!|bpZJ-J`FT}hRY@wS<>1k_sDXn)te@Bd-D7^ zg*x+S?vvV4EUMc|m{@9U^qn7L3yN^`B|gyFZZmRlrW04O8M&qETL=I?_aks~EN2oO z?Tm_;@UuRcbK<$}1}+!a+W!QbYvbM4TO?l6Ro`HK{)xOK8O#m04#Ku~&GV!q-<%-T zm8jRA3;Aqiw&~25=b($(5T`6kSr0VXJ;UD%JBaG#)Bq}e^4u#HShOfUFHk7li+nJ? z#P8v4w8@Z@=3l-l?~!}w%<`dSSzDR>e2E)4lsp7_1S#Bi@gOUmo%)sr;_=y~k7-#h z#W|4-g4$?k&&?57sP%1MQ|FX2iQ^NNwlx?f%vX?HUChMb@2h#(xb}-MZ_yg-?KS$Z zPTnA{>O|Lexz0$yD=EZJK;%zbNlXZG>nu2UGh2C&E4 z1OARv0Un_}40i_@Z@TeBQnQc7({Tzp-hPOeT}%j647lEd?K4AYLsY6B!(@}6s@CtltN z#%c(P2;elG0_lbW_*_E|Lfm@gbCrY`Xn|?q-#PVL$EkG7ZtRJ|8XL(tD}hinPt+{M zvyViaxk6c&dd}4Ccu;OR5&JLNs?ODI?^QXwZ^#FFeJF&Gq)!K!EoT{ORH#<8bkDhE7Zt^hK572!$ z{t>wM`>tX_rS}+G_P~M>YIKd0=td zp*(nMS~1VI^#&|ag-t^_a=_+n5!8T6RUA>%QZ?udN8BJgsC=NY2Pq$yd0j(aBuP8~hF4YFhrU;c|~1q^lp@3?6&UPq5stW#x9| z6ZM@D)a$pa*q;Yt>73tiQ@a`1vEf}bWftbJkeL~~5na3Mv-f}W@V|Q>>p#7Zds|GN z%1nCPEtD`!q6$YB+mhAnh+}?KGVE%+si#HQu%2&g8()pKc+K`Q8}r1pLP9sQ_#jE=BmQVs!Xb z5Ah8jyep9awm92sGS857^u^{{fPF6*!Eky4m(Otc=;_9Ac(;EKj>0K(bKgBZJcZaC z4xg+%+d{JT=j+HFxq(Oo`HRu-8M5OjYVO(e^<*yvRt@@^(fX5>4I3EGJolz2NAGy) z842p}7%(CV1s9S*&{^ReT{l7o={-6K)fBnz@@pu3CfByge)8GBw L-+lYd^KbrtSl@Ba From d88411e10de898d8ad58b1adf9dcedf0f170b67f Mon Sep 17 00:00:00 2001 From: Fyorl Date: Mon, 16 Jul 2012 17:45:43 +0100 Subject: [PATCH 413/441] [ticket/10981] Modified functional framework to account for goutte changes PHPBB3-10981 --- tests/test_framework/phpbb_functional_test_case.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tests/test_framework/phpbb_functional_test_case.php b/tests/test_framework/phpbb_functional_test_case.php index 2b6a6aaf29..e1a45a1bc4 100644 --- a/tests/test_framework/phpbb_functional_test_case.php +++ b/tests/test_framework/phpbb_functional_test_case.php @@ -46,7 +46,10 @@ class phpbb_functional_test_case extends phpbb_test_case } $this->cookieJar = new CookieJar; - $this->client = new Goutte\Client(array(), array(), null, $this->cookieJar); + $this->client = new Goutte\Client(array(), null, $this->cookieJar); + // Reset the curl handle because it is 0 at this point and not a valid + // resource + $this->client->getClient()->getCurlMulti()->reset(true); $this->root_url = self::$config['phpbb_functional_url']; // Clear the language array so that things // that were added in other tests are gone @@ -191,9 +194,9 @@ class phpbb_functional_test_case extends phpbb_test_case $cookies = $this->cookieJar->all(); // The session id is stored in a cookie that ends with _sid - we assume there is only one such cookie - foreach ($cookies as $key => $cookie); + foreach ($cookies as $cookie); { - if (substr($key, -4) == '_sid') + if (substr($cookie->getName(), -4) == '_sid') { $this->sid = $cookie->getValue(); } From cb9a25ca8048a85ce4a078ad9fe6af16bbaad591 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Tue, 17 Jul 2012 02:28:04 +0200 Subject: [PATCH 414/441] [ticket/10993] Use composer.phar from our repository in README.md PHPBB3-10993 --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index a7feb8db40..1fc670422f 100644 --- a/README.md +++ b/README.md @@ -13,8 +13,7 @@ Find support and lots more on [phpBB.com](http://www.phpbb.com)! Discuss the dev To be able to run an installation from the repo (and not from a pre-built package) you need to run the following commands to install phpBB's dependencies. cd phpBB - curl -s http://getcomposer.org/installer | php - php composer.phar install + php ../composer.phar install ## CONTRIBUTE From 3637cd395e39c1fa5b7279222abe1da5d2abcd00 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 17 Jul 2012 16:09:05 +0200 Subject: [PATCH 415/441] [feature/new-tz-handling] Properly name new timezone selection function Marked the old one as deprecated and made it using the new function. PHPBB3-9558 --- phpBB/includes/acp/acp_board.php | 12 +++++++++++- phpBB/includes/acp/acp_users.php | 6 +++--- phpBB/includes/functions.php | 28 ++++++++++++++++++---------- phpBB/includes/ucp/ucp_prefs.php | 6 +++--- phpBB/includes/ucp/ucp_register.php | 6 +++--- 5 files changed, 38 insertions(+), 20 deletions(-) diff --git a/phpBB/includes/acp/acp_board.php b/phpBB/includes/acp/acp_board.php index 59f7bf707f..159435c64c 100644 --- a/phpBB/includes/acp/acp_board.php +++ b/phpBB/includes/acp/acp_board.php @@ -57,7 +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' => 'timezone', 'type' => 'select', 'function' => 'tz_select', 'params' => array('{CONFIG_VALUE}', 1), 'explain' => true), + '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), @@ -896,6 +896,16 @@ class acp_board '

          '; } + /** + * Select guest timezone + */ + function timezone_select($value, $key) + { + $timezone_select = phpbb_timezone_select($value, true); + $timezone_select['tz_select']; + + return ''; + } /** * Select default dateformat diff --git a/phpBB/includes/acp/acp_users.php b/phpBB/includes/acp/acp_users.php index 949109abaf..a228e07c22 100644 --- a/phpBB/includes/acp/acp_users.php +++ b/phpBB/includes/acp/acp_users.php @@ -1639,7 +1639,7 @@ class acp_users ${'s_sort_' . $sort_option . '_dir'} .= ''; } - $tz_select = tz_select($data['tz'], true, false); + $timezone_selects = phpbb_timezone_select($data['tz'], true, false); $template->assign_vars(array( 'S_PREFS' => true, 'S_JABBER_DISABLED' => ($config['jab_enable'] && $user_row['user_jabber'] && @extension_loaded('xml')) ? false : true, @@ -1679,8 +1679,8 @@ class acp_users 'S_LANG_OPTIONS' => language_select($data['lang']), 'S_STYLE_OPTIONS' => style_select($data['style']), - 'S_TZ_OPTIONS' => $tz_select['tz_select'], - 'S_TZ_DATE_OPTIONS' => $tz_select['tz_dates'], + 'S_TZ_OPTIONS' => $timezone_selects['tz_select'], + 'S_TZ_DATE_OPTIONS' => $timezone_selects['tz_dates'], ) ); diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index 4fc2739f33..3533a4ca00 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -1143,13 +1143,26 @@ function phpbb_tz_select_compare($a, $b) * * @param string $default A timezone to select * @param boolean $truncate Shall we truncate the options text -* @param boolean $return_tzs_only Shall we just return the options for the timezone selector, -* or also return the options for the time selector. * -* @return string/array Returns either the options for timezone selector -* or an array, also containing the options for the time selector. +* @return string Returns the options for timezone selector only +* +* @deprecated */ -function tz_select($default = '', $truncate = false, $return_tzs_only = true) +function tz_select($default = '', $truncate = false) +{ + $timezone_select = phpbb_timezone_select($default, $truncate); + return $timezone_select['tz_select']; +} + +/** +* Options to pick a timezone and date/time +* +* @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($default = '', $truncate = false) { global $user; @@ -1220,11 +1233,6 @@ function tz_select($default = '', $truncate = false, $return_tzs_only = true) } $tz_select .= ''; - if ($return_tzs_only) - { - return $tz_select; - } - return array( 'tz_select' => $tz_select, 'tz_dates' => $tz_dates, diff --git a/phpBB/includes/ucp/ucp_prefs.php b/phpBB/includes/ucp/ucp_prefs.php index 4239afc96e..f63758c52d 100644 --- a/phpBB/includes/ucp/ucp_prefs.php +++ b/phpBB/includes/ucp/ucp_prefs.php @@ -131,7 +131,7 @@ class ucp_prefs } $dateformat_options .= '>' . $user->lang['CUSTOM_DATEFORMAT'] . ''; - $tz_select = tz_select($data['tz'], true, false); + $timezone_selects = phpbb_timezone_select($data['tz'], true, false); $template->assign_vars(array( 'ERROR' => (sizeof($error)) ? implode('
          ', $error) : '', @@ -154,8 +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['tz_select'], - 'S_TZ_DATE_OPTIONS' => $tz_select['tz_dates'], + '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 804bd2e0e2..705000d7a8 100644 --- a/phpBB/includes/ucp/ucp_register.php +++ b/phpBB/includes/ucp/ucp_register.php @@ -442,7 +442,7 @@ class ucp_register break; } - $tz_select = tz_select($data['tz'], true, false); + $timezone_selects = phpbb_timezone_select($data['tz'], true, false); $template->assign_vars(array( 'ERROR' => (sizeof($error)) ? implode('
          ', $error) : '', 'USERNAME' => $data['username'], @@ -455,8 +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['tz_select'], - 'S_TZ_DATE_OPTIONS' => $tz_select['tz_dates'], + '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, From 6aea4db6c7adbcee4fffa7cbc39564481fa6e211 Mon Sep 17 00:00:00 2001 From: Fyorl Date: Tue, 17 Jul 2012 17:36:09 +0100 Subject: [PATCH 416/441] [ticket/10944] Reverted changes in PHPBB3-10963 is_image now just checks the mimetype reported by the browser and get_mimetype goes back to being unused. PHPBB3-10944 --- phpBB/includes/functions_upload.php | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/phpBB/includes/functions_upload.php b/phpBB/includes/functions_upload.php index 33cb585b19..f70e20e616 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/') !== false) ? true : false; } /** @@ -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)) { From e71474abb5e90d0aeee61d7d9a2d4648aed61426 Mon Sep 17 00:00:00 2001 From: Fyorl Date: Tue, 17 Jul 2012 17:39:19 +0100 Subject: [PATCH 417/441] [ticket/10944] strpos now stricter and removed superfluous ternary PHPBB3-10944 --- phpBB/includes/functions_upload.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/includes/functions_upload.php b/phpBB/includes/functions_upload.php index f70e20e616..d4c6b42cf4 100644 --- a/phpBB/includes/functions_upload.php +++ b/phpBB/includes/functions_upload.php @@ -151,7 +151,7 @@ class filespec */ function is_image() { - return (strpos($this->mimetype, 'image/') !== false) ? true : false; + return (strpos($this->mimetype, 'image/') === 0); } /** From ae07e80a6513b7277ba4a6a282df8281d2a37576 Mon Sep 17 00:00:00 2001 From: Patrick Webster Date: Tue, 17 Jul 2012 12:08:13 -0500 Subject: [PATCH 418/441] [ticket/10995] Return false in mssqlnative sql_fetchrow on empty result PHPBB3-10995 --- phpBB/includes/db/mssqlnative.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/includes/db/mssqlnative.php b/phpBB/includes/db/mssqlnative.php index c91cc188b0..ff2f369706 100644 --- a/phpBB/includes/db/mssqlnative.php +++ b/phpBB/includes/db/mssqlnative.php @@ -436,7 +436,7 @@ class dbal_mssqlnative extends dbal unset($row['line2'], $row['line3']); } } - return $row; + return (sizeof($row)) ? $row : false; } /** From 7a412f846a9c4c8d712525cf03caa0b5549755ce Mon Sep 17 00:00:00 2001 From: Fyorl Date: Mon, 16 Jul 2012 18:03:47 +0100 Subject: [PATCH 419/441] [ticket/10981] Removed setupBeforeClass PHPBB3-10981 --- tests/test_framework/phpbb_functional_test_case.php | 8 -------- 1 file changed, 8 deletions(-) diff --git a/tests/test_framework/phpbb_functional_test_case.php b/tests/test_framework/phpbb_functional_test_case.php index e1a45a1bc4..ed8ce9d040 100644 --- a/tests/test_framework/phpbb_functional_test_case.php +++ b/tests/test_framework/phpbb_functional_test_case.php @@ -30,14 +30,6 @@ class phpbb_functional_test_case extends phpbb_test_case static protected $config = array(); static protected $already_installed = false; - static public function setUpBeforeClass() - { - if (!extension_loaded('phar')) - { - self::markTestSkipped('phar extension is not loaded'); - } - } - public function setUp() { if (!isset(self::$config['phpbb_functional_url'])) From 74074994ba7a1af3ccd017006fc1808c2527706b Mon Sep 17 00:00:00 2001 From: Fyorl Date: Mon, 16 Jul 2012 18:07:20 +0100 Subject: [PATCH 420/441] [ticket/10981] Modified travis to use composer with --dev PHPBB3-10981 --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index 6a1ecedac4..1a584add86 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,6 +15,9 @@ before_script: - sh -c "if [ '$DB' = 'mysql' ]; then mysql -e 'create database IF NOT EXISTS phpbb_tests;'; fi" - sh -c "if [ '$TRAVIS_PHP_VERSION' = '5.2' ]; then pear install --force phpunit/DbUnit; else pyrus install --force phpunit/DbUnit; fi" - phpenv rehash + - cd phpBB + - php ../composer.phar install --dev + - cd .. script: - phpunit --configuration travis/phpunit-$DB-travis.xml From aa2f7bcc2c56fdd82cb07e9794d6114d4b2c359c Mon Sep 17 00:00:00 2001 From: Fyorl Date: Mon, 16 Jul 2012 18:45:10 +0100 Subject: [PATCH 421/441] [ticket/10981] Added check for PHP version before running composer PHPBB3-10981 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 1a584add86..7c7ba36bfb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,7 +16,7 @@ before_script: - sh -c "if [ '$TRAVIS_PHP_VERSION' = '5.2' ]; then pear install --force phpunit/DbUnit; else pyrus install --force phpunit/DbUnit; fi" - phpenv rehash - cd phpBB - - php ../composer.phar install --dev + - sh -c "if [ '$TRAVIS_PHP_VERSION' != '5.2' ]; then php ../composer.phar install --dev; fi" - cd .. script: From d157c3b3f40d4779a69af691bf8a304d7666c74d Mon Sep 17 00:00:00 2001 From: Patrick Webster Date: Wed, 18 Jul 2012 01:22:24 -0500 Subject: [PATCH 422/441] [ticket/10996] Use correct DBMS name in Travis config for PostgreSQL PHPBB3-10996 --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 6a1ecedac4..2dbc2fc6d8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,8 +10,8 @@ env: - DB=postgres before_script: - - sh -c "if [ '$DB' = 'pgsql' ]; then psql -c 'DROP DATABASE IF EXISTS phpbb_tests;' -U postgres; fi" - - sh -c "if [ '$DB' = 'pgsql' ]; then psql -c 'create database phpbb_tests;' -U postgres; fi" + - sh -c "if [ '$DB' = 'postgres' ]; then psql -c 'DROP DATABASE IF EXISTS phpbb_tests;' -U postgres; fi" + - sh -c "if [ '$DB' = 'postgres' ]; then psql -c 'create database phpbb_tests;' -U postgres; fi" - sh -c "if [ '$DB' = 'mysql' ]; then mysql -e 'create database IF NOT EXISTS phpbb_tests;'; fi" - sh -c "if [ '$TRAVIS_PHP_VERSION' = '5.2' ]; then pear install --force phpunit/DbUnit; else pyrus install --force phpunit/DbUnit; fi" - phpenv rehash From 7ce66deca8dbe8187b86e130e8011be998580b4e Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Wed, 18 Jul 2012 14:48:28 +0200 Subject: [PATCH 423/441] [feature/new-tz-handling] Correctly update user and board timezones on update PHPBB3-9558 --- phpBB/install/database_update.php | 33 +++++++++++++++---------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/phpBB/install/database_update.php b/phpBB/install/database_update.php index 360e12e0b6..a3a51324a9 100644 --- a/phpBB/install/database_update.php +++ b/phpBB/install/database_update.php @@ -2613,25 +2613,24 @@ function change_database_data(&$no_updates, $version) // If the column exists, we did not yet update the users timezone if ($db_tools->sql_column_exists(USERS_TABLE, 'user_dst')) { - // Update timezones - // user_dst is 0 if not in dst and 1 if in dst; - // this happens to be exactly the correction that should be added to the timezone offset - // to obtain dst offset. - // Parenthesize here because we operate on this value later. - $active_offset = '(user_timezone + user_dst)'; + // Update user timezones + $sql = 'SELECT user_dst, user_timezone + FROM ' . USERS_TABLE . ' + GROUP BY user_timezone, user_dst'; + $result = $db->sql_query($sql); - // Now we have a tricky problem of forcing the plus sign into the expression. - // Build it via a conditional since there cannot be a portable printf equivalent in databases. - // Note that active offset is not an absolute value here - it is an expression that will - // be evaluated by the database during query execution. - // We don't print - (minus) here because it will come from active offset. - $sign = $db->sql_conditional("$active_offset < 0", '', '+'); + while ($row = $db->sql_fetchrow($result)) + { + $sql = 'UPDATE ' . USERS_TABLE . " + SET user_timezone = '" . $db->sql_escape(_convert_phpbb30_timezone($row['user_timezone'], $row['user_dst'])) . "' + WHERE user_timezone = '" . $db->sql_escape($row['user_timezone']) . "' + AND user_dst = " . (int) $row['user_dst']; + _sql($sql, $errored, $error_ary); + } + $db->sql_freeresult($result); - // Use database-specific escaping because strings are quoted differently by different databases. - $new_value = $db->sql_concatenate($db->sql_escape('GMT'), $sign, $active_offset); - $sql = 'UPDATE ' . USERS_TABLE . ' - SET user_timezone = ' . $new_value; - _sql($sql, $errored, $error_ary); + // Update board default timezone + set_config('board_timezone', _convert_phpbb30_timezone($config['board_timezone'], $config['board_dst'])); // After we have calculated the timezones we can delete user_dst column from user table. $db_tools->sql_column_remove(USERS_TABLE, 'user_dst'); From 8078a04f3a3816b4515da01eb3635ae8141db26b Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Wed, 18 Jul 2012 14:52:51 +0200 Subject: [PATCH 424/441] [feature/new-tz-handling] Add function to update the timezone PHPBB3-9558 --- phpBB/install/database_update.php | 99 +++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) diff --git a/phpBB/install/database_update.php b/phpBB/install/database_update.php index a3a51324a9..43363babe1 100644 --- a/phpBB/install/database_update.php +++ b/phpBB/install/database_update.php @@ -809,6 +809,105 @@ function _add_modules($modules_to_install) $_module->remove_cache_file(); } +/** +* Determinate 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' . $offset; //'[UTC - 12] Baker Island Time' + case '-11': + return 'Etc/GMT' . $offset; //'[UTC - 11] Niue Time, Samoa Standard Time' + case '-10': + return 'Etc/GMT' . $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' . $offset; //'[UTC - 9] Alaska Standard Time, Gambier Island Time' + case '-8': + return 'Etc/GMT' . $offset; //'[UTC - 8] Pacific Standard Time' + case '-7': + return 'Etc/GMT' . $offset; //'[UTC - 7] Mountain Standard Time' + case '-6': + return 'Etc/GMT' . $offset; //'[UTC - 6] Central Standard Time' + case '-5': + return 'Etc/GMT' . $offset; //'[UTC - 5] Eastern Standard Time' + case '-4.5': + return 'America/Caracas'; //'[UTC - 4:30] Venezuelan Standard Time' + case '-4': + return 'Etc/GMT' . $offset; //'[UTC - 4] Atlantic Standard Time' + case '-3.5': + return 'America/St_Johns'; //'[UTC - 3:30] Newfoundland Standard Time' + case '-3': + return 'Etc/GMT' . $offset; //'[UTC - 3] Amazon Standard Time, Central Greenland Time' + case '-2': + return 'Etc/GMT' . $offset; //'[UTC - 2] Fernando de Noronha Time, South Georgia & the South Sandwich Islands Time' + case '-1': + return 'Etc/GMT' . $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'; + } +} + /**************************************************************************** * ADD YOUR DATABASE SCHEMA CHANGES HERE * *****************************************************************************/ From 515e1662a900526342b595692d73372f4fb7bbf9 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Wed, 18 Jul 2012 14:56:42 +0200 Subject: [PATCH 425/441] [feature/new-tz-handling] Remove "timezone might be numeric" As we updated all of the used values, there really shouldn't be one anymore. PHPBB3-9558 --- phpBB/includes/acp/acp_board.php | 5 ----- phpBB/includes/user.php | 6 ------ 2 files changed, 11 deletions(-) diff --git a/phpBB/includes/acp/acp_board.php b/phpBB/includes/acp/acp_board.php index 159435c64c..47a08b0bab 100644 --- a/phpBB/includes/acp/acp_board.php +++ b/phpBB/includes/acp/acp_board.php @@ -916,11 +916,6 @@ class acp_board // Let the format_date function operate with the acp values $old_tz = $user->tz; - if (is_numeric($config['board_timezone'])) - { - // Might still be numeric - $config['board_timezone'] = sprintf('Etc/GMT%+d', $config['board_timezone']); - } $user->tz = new DateTimeZone($config['board_timezone']); $dateformat_options = ''; diff --git a/phpBB/includes/user.php b/phpBB/includes/user.php index fb6c1552e8..c3bdc71774 100644 --- a/phpBB/includes/user.php +++ b/phpBB/includes/user.php @@ -127,12 +127,6 @@ class phpbb_user extends phpbb_session */ } - if (is_numeric($user_timezone)) - { - // Might still be numeric - $user_timezone = sprintf('Etc/GMT%+d', $user_timezone); - } - $this->tz = new DateTimeZone($user_timezone); // We include common language file here to not load it every time a custom language file is included From 922147f05a75d5a0e00b34f0102bc014583df984 Mon Sep 17 00:00:00 2001 From: Drae Date: Wed, 4 Jul 2012 23:19:59 +0100 Subject: [PATCH 426/441] [ticket/10968] Render pagination within the template Since phpBB 2 pagination has been rendered mostly within the source. This limits just what designers can do with pagination. The current form is also questionable in terms of "best practice". The aim is to move rendering completely to the template via the use of a block element. Enabling S_ template vars also allows for control over specific aspects of the pagination output such as next, previous, active and ellipsis. Related to this - merging the capabilities of the topic_generate_pagination with generate_pagination removes an element of duplication. PHPBB3-10968 --- phpBB/adm/style/acp_attachments.html | 21 +++- phpBB/adm/style/acp_groups.html | 16 ++- phpBB/adm/style/acp_icons.html | 15 ++- phpBB/adm/style/acp_inactive.html | 16 ++- phpBB/adm/style/acp_logs.html | 16 ++- phpBB/adm/style/acp_users.html | 32 ++++-- phpBB/adm/style/acp_users_feedback.html | 32 ++++-- phpBB/includes/acp/acp_attachments.php | 3 +- phpBB/includes/acp/acp_groups.php | 3 +- phpBB/includes/acp/acp_icons.php | 6 +- phpBB/includes/acp/acp_inactive.php | 4 +- phpBB/includes/acp/acp_logs.php | 3 +- phpBB/includes/acp/acp_users.php | 9 +- phpBB/includes/functions.php | 98 +++++++++++-------- phpBB/includes/functions_display.php | 42 -------- phpBB/includes/functions_posting.php | 5 +- phpBB/includes/mcp/mcp_forum.php | 3 +- phpBB/includes/mcp/mcp_logs.php | 3 +- phpBB/includes/mcp/mcp_notes.php | 3 +- phpBB/includes/mcp/mcp_pm_reports.php | 3 +- phpBB/includes/mcp/mcp_queue.php | 3 +- phpBB/includes/mcp/mcp_reports.php | 3 +- phpBB/includes/mcp/mcp_topic.php | 6 +- phpBB/includes/mcp/mcp_warn.php | 3 +- phpBB/includes/ucp/ucp_attachments.php | 3 +- phpBB/includes/ucp/ucp_groups.php | 3 +- phpBB/includes/ucp/ucp_main.php | 6 +- phpBB/includes/ucp/ucp_pm_viewfolder.php | 3 +- phpBB/memberlist.php | 3 +- phpBB/search.php | 9 +- .../styles/prosilver/template/mcp_forum.html | 61 ++++++++++-- phpBB/styles/prosilver/template/mcp_logs.html | 42 +++++++- .../prosilver/template/mcp_notes_user.html | 42 +++++++- .../styles/prosilver/template/mcp_queue.html | 42 +++++++- .../prosilver/template/mcp_reports.html | 42 +++++++- .../styles/prosilver/template/mcp_topic.html | 23 ++++- .../prosilver/template/mcp_warn_list.html | 42 +++++++- .../prosilver/template/memberlist_body.html | 44 ++++++++- .../prosilver/template/posting_smilies.html | 19 +++- .../prosilver/template/search_results.html | 63 ++++++++++-- .../prosilver/template/ucp_attachments.html | 42 +++++++- .../prosilver/template/ucp_groups_manage.html | 19 +++- .../template/ucp_main_bookmarks.html | 36 ++++++- .../prosilver/template/ucp_main_front.html | 15 ++- .../template/ucp_main_subscribed.html | 36 ++++++- .../template/ucp_pm_message_header.html | 21 +++- .../prosilver/template/ucp_pm_viewfolder.html | 21 +++- .../prosilver/template/viewforum_body.html | 67 ++++++++++--- .../prosilver/template/viewonline_body.html | 42 +++++++- .../prosilver/template/viewtopic_body.html | 40 ++++++-- phpBB/styles/prosilver/theme/colours.css | 23 +++-- phpBB/styles/prosilver/theme/common.css | 39 +++----- phpBB/styles/prosilver/theme/content.css | 4 +- .../subsilver2/template/pagination.html | 12 ++- .../subsilver2/template/posting_smilies.html | 15 ++- .../subsilver2/template/search_results.html | 13 ++- .../template/ucp_main_bookmarks.html | 13 ++- .../template/ucp_main_subscribed.html | 13 ++- .../subsilver2/template/viewforum_body.html | 26 ++++- .../subsilver2/template/viewonline_body.html | 4 +- phpBB/viewforum.php | 6 +- phpBB/viewonline.php | 2 +- phpBB/viewtopic.php | 3 +- 63 files changed, 1039 insertions(+), 268 deletions(-) diff --git a/phpBB/adm/style/acp_attachments.html b/phpBB/adm/style/acp_attachments.html index c2f8b34792..f3d67d2bfa 100644 --- a/phpBB/adm/style/acp_attachments.html +++ b/phpBB/adm/style/acp_attachments.html @@ -378,11 +378,26 @@

          {L_TITLE} - + + {L_NUMBER_FILES}: {TOTAL_FILES} • {L_TOTAL_SIZE}: {TOTAL_SIZE} • + + {S_ON_PAGE} • + + + {S_ON_PAGE} + +
    diff --git a/phpBB/adm/style/acp_groups.html b/phpBB/adm/style/acp_groups.html index ed94fa985e..ca68bc7528 100644 --- a/phpBB/adm/style/acp_groups.html +++ b/phpBB/adm/style/acp_groups.html @@ -239,11 +239,21 @@
    - + + {S_ON_PAGE} • + +
    diff --git a/phpBB/adm/style/acp_icons.html b/phpBB/adm/style/acp_icons.html index a8864d42f7..6f42165414 100644 --- a/phpBB/adm/style/acp_icons.html +++ b/phpBB/adm/style/acp_icons.html @@ -255,7 +255,20 @@ -
    {PAGINATION}
    +

       

    diff --git a/phpBB/adm/style/acp_inactive.html b/phpBB/adm/style/acp_inactive.html index 0889eaf400..12cc11d742 100644 --- a/phpBB/adm/style/acp_inactive.html +++ b/phpBB/adm/style/acp_inactive.html @@ -10,11 +10,21 @@
    - + + {S_ON_PAGE} • + +
    diff --git a/phpBB/adm/style/acp_logs.html b/phpBB/adm/style/acp_logs.html index f1c770d33b..3b2d448a44 100644 --- a/phpBB/adm/style/acp_logs.html +++ b/phpBB/adm/style/acp_logs.html @@ -12,11 +12,21 @@ {L_SEARCH_KEYWORDS}:   - + + {S_ON_PAGE} • + +
     

    diff --git a/phpBB/adm/style/acp_users.html b/phpBB/adm/style/acp_users.html index a8794176a9..02cdab55b2 100644 --- a/phpBB/adm/style/acp_users.html +++ b/phpBB/adm/style/acp_users.html @@ -157,11 +157,21 @@ - + + {S_ON_PAGE} • + +
    @@ -196,11 +206,21 @@
    - + + {S_ON_PAGE} • + +
    diff --git a/phpBB/adm/style/acp_users_feedback.html b/phpBB/adm/style/acp_users_feedback.html index aa92353807..6b7761ed46 100644 --- a/phpBB/adm/style/acp_users_feedback.html +++ b/phpBB/adm/style/acp_users_feedback.html @@ -1,10 +1,20 @@ - + + {S_ON_PAGE} • + +
    @@ -44,11 +54,21 @@
    - + + {S_ON_PAGE} • + +
    diff --git a/phpBB/includes/acp/acp_attachments.php b/phpBB/includes/acp/acp_attachments.php index abe304c282..4b621cb18d 100644 --- a/phpBB/includes/acp/acp_attachments.php +++ b/phpBB/includes/acp/acp_attachments.php @@ -1222,10 +1222,11 @@ class acp_attachments } $db->sql_freeresult($result); + generate_pagination($this->u_action . "&$u_sort_param", $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_LIMIT_DAYS' => $s_limit_days, diff --git a/phpBB/includes/acp/acp_groups.php b/phpBB/includes/acp/acp_groups.php index 607254adb5..ded28252dc 100644 --- a/phpBB/includes/acp/acp_groups.php +++ b/phpBB/includes/acp/acp_groups.php @@ -682,13 +682,14 @@ class acp_groups $s_action_options .= ''; } + generate_pagination($this->u_action . "&action=$action&g=$group_id", $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), '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..fdf0fbde2f 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) - ); + + generate_pagination($this->u_action, $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 f098b772ee..c7f9e5398e 100644 --- a/phpBB/includes/acp/acp_inactive.php +++ b/phpBB/includes/acp/acp_inactive.php @@ -288,6 +288,8 @@ class acp_inactive $option_ary += array('remind' => 'REMIND'); } + generate_pagination($this->u_action . "&$u_sort_param&users_per_page=$per_page", $inactive_count, $per_page, $start); + $template->assign_vars(array( 'S_INACTIVE_USERS' => true, 'S_INACTIVE_OPTIONS' => build_select($option_ary), @@ -296,7 +298,7 @@ class acp_inactive '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), + '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..43cf15cb4d 100644 --- a/phpBB/includes/acp/acp_logs.php +++ b/phpBB/includes/acp/acp_logs.php @@ -129,13 +129,14 @@ 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); + generate_pagination($this->u_action . "&$u_sort_param$keywords_param", $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_LIMIT_DAYS' => $s_limit_days, 'S_SORT_KEY' => $s_sort_key, diff --git a/phpBB/includes/acp/acp_users.php b/phpBB/includes/acp/acp_users.php index 17687b05c7..e98c015f8b 100644 --- a/phpBB/includes/acp/acp_users.php +++ b/phpBB/includes/acp/acp_users.php @@ -1120,10 +1120,11 @@ 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); + generate_pagination($this->u_action . "&u=$user_id&$u_sort_param", $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_LIMIT_DAYS' => $s_limit_days, 'S_SORT_KEY' => $s_sort_key, @@ -2035,14 +2036,14 @@ class acp_users } $db->sql_freeresult($result); + generate_pagination($this->u_action . "&u=$user_id&sk=$sort_key&sd=$sort_dir", $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_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/functions.php b/phpBB/includes/functions.php index e40df93194..b7b8ccda0f 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -1884,85 +1884,99 @@ function tracking_unserialize($string, $max_depth = 3) * Pagination routine, generates page number sequence * tpl_prefix is for using different pagination blocks at one page */ -function generate_pagination($base_url, $num_items, $per_page, $start_item, $add_prevnext_text = false, $tpl_prefix = '') +function generate_pagination($base_url, $num_items, $per_page, $start_item = 1, $tpl_prefix = '', $reverse_count = false, $ignore_on_page = false, $block_var_name = '') { global $template, $user; // Make sure $per_page is a valid value $per_page = ($per_page <= 0) ? 1 : $per_page; - $separator = '' . $user->lang['COMMA_SEPARATOR'] . ''; $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) ? '1' : '1'; - - if ($total_pages > 5) + $block_var_name = ($block_var_name) ? $block_var_name . '.pagination' : 'pagination'; + + 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) ? ' ... ' : $separator; - - for ($i = $start_cnt + 1; $i < $end_cnt; $i++) - { - $page_string .= ($i == $on_page) ? '' . $i . '' : '' . $i . ''; - if ($i < $end_cnt - 1) - { - $page_string .= $separator; - } - } - - $page_string .= ($end_cnt < $total_pages) ? ' ... ' : $separator; + $start_cnt = ($total_pages > 5) ? $total_pages - 3 : 1; + $end_cnt = $total_pages; } else { - $page_string .= $separator; - - for ($i = 2; $i < $total_pages; $i++) - { - $page_string .= ($i == $on_page) ? '' . $i . '' : '' . $i . ''; - if ($i < $total_pages) - { - $page_string .= $separator; - } - } + $start_cnt = ($total_pages > 5) ? min(max(1, $on_page - 4), $total_pages - 5) : 1; + $end_cnt = ($total_pages > 5) ? max(min($total_pages, $on_page + 4), 6) : $total_pages; } - $page_string .= ($on_page == $total_pages) ? '' . $total_pages . '' : '' . $total_pages . ''; - - if ($add_prevnext_text) + if ($on_page != $total_pages) { - if ($on_page != 1) + $template->assign_block_vars($block_var_name, array( + 'PAGE_NUMBER' => '', + 'PAGE_URL' => $base_url . "{$url_delim}start=" . ($on_page * $per_page), + 'S_IS_CURRENT' => false, + 'S_IS_PREV' => false, + 'S_IS_NEXT' => true, + 'S_IS_ELLIPSIS' => false, + )); + } + + $i = 1; + do + { + $page_url = $base_url . (($i == 1) ? '' : $url_delim . 'start=' . (($i - 1) * $per_page)); + + $template->assign_block_vars($block_var_name, array( + 'PAGE_NUMBER' => $i, + 'PAGE_URL' => $page_url, + 'S_IS_CURRENT' => (!$ignore_on_page && $i == $on_page) ? true : false, + 'S_IS_NEXT' => false, + 'S_IS_PREV' => false, + 'S_IS_ELLIPSIS' => ($i == 2 && $start_cnt > 1) || ($i == $total_pages - 1 && $end_cnt < $total_pages) ? true : false, + )); + + if ($i > 1 && $i < $start_cnt - 1) { - $page_string = '' . $user->lang['PREVIOUS'] . '  ' . $page_string; + $i = $start_cnt; } - - if ($on_page != $total_pages) + elseif ($i == $end_cnt && $end_cnt < $total_pages - 1) { - $page_string .= '  ' . $user->lang['NEXT'] . ''; + $i = $total_pages - 1; + } + else + { + $i++; } } + while ($i <= $total_pages); + if ($on_page != 1) + { + $template->assign_block_vars($block_var_name, array( + 'PAGE_NUMBER' => '', + 'PAGE_URL' => $base_url . "{$url_delim}start=" . (($on_page - 2) * $per_page), + 'S_IS_CURRENT' => false, + 'S_IS_PREV' => true, + 'S_IS_NEXT' => false, + 'S_IS_ELLIPSIS' => false, + )); + } + $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; + return; } /** diff --git a/phpBB/includes/functions_display.php b/phpBB/includes/functions_display.php index 545f75ad67..00efd281c0 100644 --- a/phpBB/includes/functions_display.php +++ b/phpBB/includes/functions_display.php @@ -639,48 +639,6 @@ function get_forum_parents(&$forum_data) return $forum_parents; } -/** -* 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 .= '' . $times . ''; - if ($times == 1 && $total_pages > 5) - { - $pagination .= ' ... '; - - // Display the last three pages - $times = $total_pages - 3; - $j += ($total_pages - 4) * $per_page; - } - else if ($times < $total_pages) - { - $pagination .= '' . $user->lang['COMMA_SEPARATOR'] . ''; - } - $times++; - } - } - else - { - $pagination = ''; - } - - return $pagination; -} - /** * Obtain list of moderators of each forum */ 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/mcp/mcp_forum.php b/phpBB/includes/mcp/mcp_forum.php index fec1edc872..936f85ccc2 100644 --- a/phpBB/includes/mcp/mcp_forum.php +++ b/phpBB/includes/mcp/mcp_forum.php @@ -101,6 +101,8 @@ 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)) : ''; + 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); + $template->assign_vars(array( 'ACTION' => $action, 'FORUM_NAME' => $forum_info['forum_name'], @@ -129,7 +131,6 @@ 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), '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..2b5e847e26 100644 --- a/phpBB/includes/mcp/mcp_logs.php +++ b/phpBB/includes/mcp/mcp_logs.php @@ -171,10 +171,11 @@ 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); + generate_pagination($this->u_action . "&$u_sort_param$keywords_param", $log_count, $config['topics_per_page'], $start); + $template->assign_vars(array( 'PAGE_NUMBER' => on_page($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..7e0dd69a2f 100644 --- a/phpBB/includes/mcp/mcp_notes.php +++ b/phpBB/includes/mcp/mcp_notes.php @@ -215,6 +215,8 @@ class mcp_notes } } + generate_pagination($this->u_action . "&$u_sort_param$keywords_param", $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, @@ -226,7 +228,6 @@ 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), '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..3e2ce4bfd3 100644 --- a/phpBB/includes/mcp/mcp_pm_reports.php +++ b/phpBB/includes/mcp/mcp_pm_reports.php @@ -298,6 +298,8 @@ class mcp_pm_reports } } + generate_pagination($this->u_action . "&st=$sort_days&sk=$sort_key&sd=$sort_dir", $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,7 +309,6 @@ 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), '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..86fffbcf93 100644 --- a/phpBB/includes/mcp/mcp_queue.php +++ b/phpBB/includes/mcp/mcp_queue.php @@ -419,6 +419,8 @@ class mcp_queue } unset($rowset, $forum_names); + generate_pagination($this->u_action . "&f=$forum_id&st=$sort_days&sk=$sort_key&sd=$sort_dir", $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,7 +432,6 @@ 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), '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..3c5f51ee05 100644 --- a/phpBB/includes/mcp/mcp_reports.php +++ b/phpBB/includes/mcp/mcp_reports.php @@ -411,6 +411,8 @@ class mcp_reports unset($report_ids, $row); } + 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); + // 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,7 +423,6 @@ 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), 'TOPIC_ID' => $topic_id, 'TOTAL' => $total, diff --git a/phpBB/includes/mcp/mcp_topic.php b/phpBB/includes/mcp/mcp_topic.php index d4ba89b04c..c2f44bd360 100644 --- a/phpBB/includes/mcp/mcp_topic.php +++ b/phpBB/includes/mcp/mcp_topic.php @@ -306,6 +306,11 @@ function mcp_topic_view($id, $mode, $action) 'post_ids' => $post_id_list, )); + if ($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); + } + $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']), @@ -345,7 +350,6 @@ function mcp_topic_view($id, $mode, $action) 'RETURN_FORUM' => sprintf($user->lang['RETURN_FORUM'], '', ''), '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), '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..31822dd147 100644 --- a/phpBB/includes/mcp/mcp_warn.php +++ b/phpBB/includes/mcp/mcp_warn.php @@ -175,6 +175,8 @@ class mcp_warn )); } + 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); + $template->assign_vars(array( 'U_POST_ACTION' => $this->u_action, 'S_CLEAR_ALLOWED' => ($auth->acl_get('a_clearlogs')) ? true : false, @@ -183,7 +185,6 @@ class mcp_warn '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), 'TOTAL_USERS' => $user->lang('LIST_USERS', (int) $user_count), )); } diff --git a/phpBB/includes/ucp/ucp_attachments.php b/phpBB/includes/ucp/ucp_attachments.php index 836185f105..fb2dfaabee 100644 --- a/phpBB/includes/ucp/ucp_attachments.php +++ b/phpBB/includes/ucp/ucp_attachments.php @@ -170,9 +170,10 @@ class ucp_attachments } $db->sql_freeresult($result); + generate_pagination($this->u_action . "&sk=$sort_key&sd=$sort_dir", $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), '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..d919208aca 100644 --- a/phpBB/includes/ucp/ucp_groups.php +++ b/phpBB/includes/ucp/ucp_groups.php @@ -844,11 +844,12 @@ class ucp_groups $s_action_options .= ''; } + generate_pagination($this->u_action . "&action=$action&g=$group_id", $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), 'U_ACTION' => $this->u_action . "&g=$group_id", 'S_UCP_ACTION' => $this->u_action . "&g=$group_id", diff --git a/phpBB/includes/ucp/ucp_main.php b/phpBB/includes/ucp/ucp_main.php index 00b7b55f27..fed844de96 100644 --- a/phpBB/includes/ucp/ucp_main.php +++ b/phpBB/includes/ucp/ucp_main.php @@ -670,8 +670,9 @@ class ucp_main if ($topics_count) { + generate_pagination($this->u_action, $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), '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), )); + + generate_pagination(append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'f=' . $row['forum_id'] . "&t=$topic_id"), $replies + 1, $config['posts_per_page'], 1, '', true, true, 'topicrow'); } } } diff --git a/phpBB/includes/ucp/ucp_pm_viewfolder.php b/phpBB/includes/ucp/ucp_pm_viewfolder.php index 8b1cd419f4..168280bd96 100644 --- a/phpBB/includes/ucp/ucp_pm_viewfolder.php +++ b/phpBB/includes/ucp/ucp_pm_viewfolder.php @@ -451,8 +451,9 @@ function get_pm_from($folder_id, $folder, $user_id) $sql_limit_time = ''; } + 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); + $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), 'TOTAL_MESSAGES' => $user->lang('VIEW_PM_MESSAGES', (int) $pm_count), diff --git a/phpBB/memberlist.php b/phpBB/memberlist.php index ed87b6c448..f837a21666 100644 --- a/phpBB/memberlist.php +++ b/phpBB/memberlist.php @@ -1572,9 +1572,10 @@ switch ($mode) } } + generate_pagination($pagination_url, $total_users, $config['topics_per_page'], $start); + // Generate page $template->assign_vars(array( - 'PAGINATION' => generate_pagination($pagination_url, $total_users, $config['topics_per_page'], $start), 'PAGE_NUMBER' => on_page($total_users, $config['topics_per_page'], $start), 'TOTAL_USERS' => $user->lang('LIST_USERS', (int) $total_users), diff --git a/phpBB/search.php b/phpBB/search.php index 93cd0c31fd..fefe7f9b0e 100644 --- a/phpBB/search.php +++ b/phpBB/search.php @@ -603,13 +603,14 @@ if ($keywords || $author || $author_id || $search_id || $submit) $phrase_search_disabled = $search->supports_phrase_search() ? false : true; } + generate_pagination($u_search, $total_match_count, $per_page, $start); + $template->assign_vars(array( 'SEARCH_TITLE' => $l_search_title, 'SEARCH_MATCHES' => $l_search_matches, 'SEARCH_WORDS' => $keywords, 'SEARCHED_QUERY' => $search->search_query, 'IGNORED_WORDS' => (sizeof($search->common_words)) ? implode(' ', $search->common_words) : '', - 'PAGINATION' => generate_pagination($u_search, $total_match_count, $per_page, $start), 'PAGE_NUMBER' => on_page($total_match_count, $per_page, $start), 'PHRASE_SEARCH_DISABLED' => $phrase_search_disabled, @@ -899,7 +900,6 @@ if ($keywords || $author || $author_id || $search_id || $submit) 'LAST_POST_AUTHOR_COLOUR' => get_username_string('colour', $row['topic_last_poster_id'], $row['topic_last_poster_name'], $row['topic_last_poster_colour']), 'LAST_POST_AUTHOR_FULL' => get_username_string('full', $row['topic_last_poster_id'], $row['topic_last_poster_name'], $row['topic_last_poster_colour']), - 'PAGINATION' => topic_generate_pagination($replies, $view_topic_url), 'TOPIC_TYPE' => $topic_type, 'TOPIC_IMG_STYLE' => $folder_img, @@ -1003,6 +1003,11 @@ if ($keywords || $author || $author_id || $search_id || $submit) 'U_VIEW_FORUM' => append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $forum_id), 'U_VIEW_POST' => (!empty($row['post_id'])) ? append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f=$forum_id&t=" . $row['topic_id'] . '&p=' . $row['post_id'] . (($u_hilit) ? '&hilit=' . $u_hilit : '')) . '#p' . $row['post_id'] : '') )); + + if ($show_results == 'topics') + { + generate_pagination($view_topic_url, $replies + 1, $config['posts_per_page'], 1, '', true, true, 'searchresults'); + } } if ($topic_id && ($topic_id == $result_topic_id)) diff --git a/phpBB/styles/prosilver/template/mcp_forum.html b/phpBB/styles/prosilver/template/mcp_forum.html index afd4f2308a..a31e0fc74a 100644 --- a/phpBB/styles/prosilver/template/mcp_forum.html +++ b/phpBB/styles/prosilver/template/mcp_forum.html @@ -10,11 +10,28 @@
    - + @@ -42,7 +59,20 @@ {REPORTED_IMG}  [ {L_DELETE_SHADOW_TOPIC} ]
    - {topicrow.PAGINATION} + + + {topicrow.ATTACH_ICON_IMG} {L_POST_BY_AUTHOR} {topicrow.TOPIC_AUTHOR_FULL} » {topicrow.FIRST_POST_TIME}
    {topicrow.REPLIES} {L_REPLIES}
    {L_LAST_POST} {L_POST_BY_AUTHOR} {topicrow.LAST_POST_AUTHOR_FULL}
    {topicrow.LAST_POST_TIME}
    @@ -72,11 +102,28 @@
    - + diff --git a/phpBB/styles/prosilver/template/mcp_logs.html b/phpBB/styles/prosilver/template/mcp_logs.html index b5561687b2..af101f8d24 100644 --- a/phpBB/styles/prosilver/template/mcp_logs.html +++ b/phpBB/styles/prosilver/template/mcp_logs.html @@ -12,8 +12,25 @@ {L_SEARCH_KEYWORDS}:   @@ -62,8 +79,25 @@ {S_FORM_TOKEN} diff --git a/phpBB/styles/prosilver/template/mcp_notes_user.html b/phpBB/styles/prosilver/template/mcp_notes_user.html index afe904dab3..ea484e5628 100644 --- a/phpBB/styles/prosilver/template/mcp_notes_user.html +++ b/phpBB/styles/prosilver/template/mcp_notes_user.html @@ -55,8 +55,25 @@ {L_SEARCH_KEYWORDS}:   @@ -102,8 +119,25 @@ diff --git a/phpBB/styles/prosilver/template/mcp_queue.html b/phpBB/styles/prosilver/template/mcp_queue.html index e9a477a24c..5dd4308f7a 100644 --- a/phpBB/styles/prosilver/template/mcp_queue.html +++ b/phpBB/styles/prosilver/template/mcp_queue.html @@ -18,8 +18,25 @@
      @@ -73,8 +90,25 @@ diff --git a/phpBB/styles/prosilver/template/mcp_reports.html b/phpBB/styles/prosilver/template/mcp_reports.html index 95e7d9e021..431f50d346 100644 --- a/phpBB/styles/prosilver/template/mcp_reports.html +++ b/phpBB/styles/prosilver/template/mcp_reports.html @@ -20,8 +20,25 @@
        @@ -74,8 +91,25 @@
        diff --git a/phpBB/styles/prosilver/template/mcp_topic.html b/phpBB/styles/prosilver/template/mcp_topic.html index 8d0294d226..2a7b749027 100644 --- a/phpBB/styles/prosilver/template/mcp_topic.html +++ b/phpBB/styles/prosilver/template/mcp_topic.html @@ -139,11 +139,28 @@ onload_functions.push('subPanels()');
        - + diff --git a/phpBB/styles/prosilver/template/mcp_warn_list.html b/phpBB/styles/prosilver/template/mcp_warn_list.html index e4f82bbe67..27adcf40e3 100644 --- a/phpBB/styles/prosilver/template/mcp_warn_list.html +++ b/phpBB/styles/prosilver/template/mcp_warn_list.html @@ -12,8 +12,25 @@ @@ -48,8 +65,25 @@ diff --git a/phpBB/styles/prosilver/template/memberlist_body.html b/phpBB/styles/prosilver/template/memberlist_body.html index d5154761e9..bb3ce814d3 100644 --- a/phpBB/styles/prosilver/template/memberlist_body.html +++ b/phpBB/styles/prosilver/template/memberlist_body.html @@ -41,8 +41,26 @@
      @@ -150,7 +168,27 @@
      diff --git a/phpBB/styles/prosilver/template/posting_smilies.html b/phpBB/styles/prosilver/template/posting_smilies.html index d3d6293586..097d08244d 100644 --- a/phpBB/styles/prosilver/template/posting_smilies.html +++ b/phpBB/styles/prosilver/template/posting_smilies.html @@ -17,7 +17,24 @@
    -
    {PAGINATION}
    + {L_CLOSE_WINDOW} diff --git a/phpBB/styles/prosilver/template/search_results.html b/phpBB/styles/prosilver/template/search_results.html index 0a58605b31..7b4ecaab72 100644 --- a/phpBB/styles/prosilver/template/search_results.html +++ b/phpBB/styles/prosilver/template/search_results.html @@ -11,7 +11,7 @@

    {L_RETURN_TO_SEARCH_ADV}

    - +
    @@ -26,7 +26,26 @@
    @@ -59,7 +78,20 @@ {searchresults.TOPIC_TITLE} {searchresults.ATTACH_ICON_IMG} {searchresults.UNAPPROVED_IMG} {REPORTED_IMG}
    - {searchresults.PAGINATION} + + + {L_POST_BY_AUTHOR} {searchresults.TOPIC_AUTHOR_FULL} » {searchresults.FIRST_POST_TIME} » {L_IN} {searchresults.FORUM_TITLE}
    {searchresults.TOPIC_REPLIES}
    @@ -127,7 +159,7 @@ - +
    @@ -144,10 +176,29 @@
    - + diff --git a/phpBB/styles/prosilver/template/ucp_attachments.html b/phpBB/styles/prosilver/template/ucp_attachments.html index 84e4c2e875..b57376344f 100644 --- a/phpBB/styles/prosilver/template/ucp_attachments.html +++ b/phpBB/styles/prosilver/template/ucp_attachments.html @@ -12,8 +12,25 @@ @@ -55,8 +72,25 @@ diff --git a/phpBB/styles/prosilver/template/ucp_groups_manage.html b/phpBB/styles/prosilver/template/ucp_groups_manage.html index a13c043e48..680d39ea1e 100644 --- a/phpBB/styles/prosilver/template/ucp_groups_manage.html +++ b/phpBB/styles/prosilver/template/ucp_groups_manage.html @@ -159,7 +159,24 @@ diff --git a/phpBB/styles/prosilver/template/ucp_main_bookmarks.html b/phpBB/styles/prosilver/template/ucp_main_bookmarks.html index 89502bbc3d..895fce5e51 100644 --- a/phpBB/styles/prosilver/template/ucp_main_bookmarks.html +++ b/phpBB/styles/prosilver/template/ucp_main_bookmarks.html @@ -36,7 +36,20 @@ {NEWEST_POST_IMG} {topicrow.TOPIC_TITLE} {topicrow.UNAPPROVED_IMG} {REPORTED_IMG}
    - {topicrow.PAGINATION} + + + {topicrow.ATTACH_ICON_IMG} {L_POST_BY_AUTHOR} {topicrow.TOPIC_AUTHOR_FULL} » {topicrow.FIRST_POST_TIME}
    {L_LAST_POST} {L_POST_BY_AUTHOR} {topicrow.LAST_POST_AUTHOR_FULL} @@ -50,8 +63,25 @@ diff --git a/phpBB/styles/prosilver/template/ucp_main_front.html b/phpBB/styles/prosilver/template/ucp_main_front.html index b7a0619227..04767b6c01 100644 --- a/phpBB/styles/prosilver/template/ucp_main_front.html +++ b/phpBB/styles/prosilver/template/ucp_main_front.html @@ -16,7 +16,20 @@
    style="background-image: url({T_ICONS_PATH}{topicrow.TOPIC_ICON_IMG}); background-repeat: no-repeat;"> {NEWEST_POST_IMG} {topicrow.TOPIC_TITLE}
    - {topicrow.PAGINATION} + + + {topicrow.ATTACH_ICON_IMG} {L_POST_BY_AUTHOR} {topicrow.TOPIC_AUTHOR_FULL} » {topicrow.FIRST_POST_TIME}
    {L_LAST_POST} {L_POST_BY_AUTHOR} {topicrow.LAST_POST_AUTHOR_FULL} diff --git a/phpBB/styles/prosilver/template/ucp_main_subscribed.html b/phpBB/styles/prosilver/template/ucp_main_subscribed.html index ab65d9b3ae..0324218149 100644 --- a/phpBB/styles/prosilver/template/ucp_main_subscribed.html +++ b/phpBB/styles/prosilver/template/ucp_main_subscribed.html @@ -56,7 +56,20 @@ {NEWEST_POST_IMG} {topicrow.TOPIC_TITLE} {topicrow.UNAPPROVED_IMG} {REPORTED_IMG}
    - {topicrow.PAGINATION} + + + {topicrow.ATTACH_ICON_IMG} {L_POST_BY_AUTHOR} {topicrow.TOPIC_AUTHOR_FULL} » {topicrow.FIRST_POST_TIME}
    {L_LAST_POST} {L_POST_BY_AUTHOR} {topicrow.LAST_POST_AUTHOR_FULL} @@ -69,8 +82,25 @@ diff --git a/phpBB/styles/prosilver/template/ucp_pm_message_header.html b/phpBB/styles/prosilver/template/ucp_pm_message_header.html index d6659fad0f..9af2bf07a5 100644 --- a/phpBB/styles/prosilver/template/ucp_pm_message_header.html +++ b/phpBB/styles/prosilver/template/ucp_pm_message_header.html @@ -20,8 +20,25 @@ diff --git a/phpBB/styles/prosilver/template/ucp_pm_viewfolder.html b/phpBB/styles/prosilver/template/ucp_pm_viewfolder.html index 20394b254e..8f969a7018 100644 --- a/phpBB/styles/prosilver/template/ucp_pm_viewfolder.html +++ b/phpBB/styles/prosilver/template/ucp_pm_viewfolder.html @@ -103,8 +103,25 @@ diff --git a/phpBB/styles/prosilver/template/viewforum_body.html b/phpBB/styles/prosilver/template/viewforum_body.html index f5ff1d3f98..4e368120b8 100644 --- a/phpBB/styles/prosilver/template/viewforum_body.html +++ b/phpBB/styles/prosilver/template/viewforum_body.html @@ -34,7 +34,7 @@ - +
    style="margin-top: 2em;"> @@ -55,11 +55,27 @@
    - + @@ -142,7 +158,20 @@ style="background-image: url({T_ICONS_PATH}{topicrow.TOPIC_ICON_IMG}); background-repeat: no-repeat;" title="{topicrow.TOPIC_FOLDER_IMG_ALT}">{NEWEST_POST_IMG} {topicrow.TOPIC_TITLE} {topicrow.UNAPPROVED_IMG} {REPORTED_IMG}
    - {topicrow.PAGINATION} + + + {topicrow.ATTACH_ICON_IMG} {L_POST_BY_AUTHOR} {topicrow.TOPIC_AUTHOR_FULL} » {topicrow.FIRST_POST_TIME} » {L_IN} {topicrow.FORUM_NAME} @@ -193,13 +222,29 @@ - + diff --git a/phpBB/styles/prosilver/template/viewonline_body.html b/phpBB/styles/prosilver/template/viewonline_body.html index 9da8202783..775f182c07 100644 --- a/phpBB/styles/prosilver/template/viewonline_body.html +++ b/phpBB/styles/prosilver/template/viewonline_body.html @@ -4,7 +4,26 @@

    {TOTAL_GUEST_USERS_ONLINE}{L_SWITCH_GUEST_DISPLAY}

    @@ -50,7 +69,26 @@

    {L_LEGEND}: {LEGEND}

    diff --git a/phpBB/styles/prosilver/template/viewtopic_body.html b/phpBB/styles/prosilver/template/viewtopic_body.html index 1af512732d..29786f7b86 100644 --- a/phpBB/styles/prosilver/template/viewtopic_body.html +++ b/phpBB/styles/prosilver/template/viewtopic_body.html @@ -45,10 +45,24 @@
    - + @@ -252,10 +266,24 @@ - + diff --git a/phpBB/styles/prosilver/theme/colours.css b/phpBB/styles/prosilver/theme/colours.css index fe6a7a7fda..29968cbb14 100644 --- a/phpBB/styles/prosilver/theme/colours.css +++ b/phpBB/styles/prosilver/theme/colours.css @@ -145,25 +145,30 @@ dl.details dd { /* Pagination ---------------------------------------- */ -.pagination span strong { - color: #FFFFFF; - background-color: #4692BF; - border-color: #4692BF; -} - -.pagination span a, .pagination span a:link, .pagination span a:visited { +.pagination li a, .pagination li a:link, .pagination li a:visited { color: #5C758C; background-color: #ECEDEE; border-color: #B4BAC0; } -.pagination span a:hover { +.pagination li.ellipsis span { + background-color: transparent; + color: #000 +} + +.pagination li.active span { + color: #FFFFFF; + background-color: #4692BF; + border-color: #4692BF; +} + +.pagination li a:hover, .pagination .active a:hover { border-color: #368AD2; background-color: #368AD2; color: #FFF; } -.pagination span a:active { +.pagination li a:active, .pagination li.active a:active { color: #5C758C; background-color: #ECEDEE; border-color: #B4BAC0; diff --git a/phpBB/styles/prosilver/theme/common.css b/phpBB/styles/prosilver/theme/common.css index 3dda343829..d49b54475f 100644 --- a/phpBB/styles/prosilver/theme/common.css +++ b/phpBB/styles/prosilver/theme/common.css @@ -483,6 +483,7 @@ dl.details dd { overflow: hidden; } + /* Pagination ---------------------------------------- */ .pagination { @@ -493,51 +494,43 @@ dl.details dd { float: right; } -.pagination span.page-sep { - display: none; -} - li.pagination { margin-top: 0; } -.pagination strong, .pagination b { - font-weight: normal; +.pagination img { + vertical-align: middle; } -.pagination span strong { - padding: 0 2px; - margin: 0 2px; - font-weight: normal; - border: 1px solid transparent; - font-size: 0.9em; +.pagination ul { + display: inline-block; + *display: inline; /* IE7 inline-block hack */ + *zoom: 1; + margin-left: 0; + margin-bottom: 0; } -.pagination span a, .pagination span a:link, .pagination span a:visited, .pagination span a:active { +.pagination ul li, dl .pagination ul li, dl.icon .pagination ul li { + display: inline; + padding: 0; +} + +.pagination li a, .pagnation li span, li .pagination li a, li .pagnation li span, .pagination li.active span, .pagination li.ellipsis span { font-weight: normal; text-decoration: none; - margin: 0 2px; padding: 0 2px; border: 1px solid transparent; font-size: 0.9em; line-height: 1.5em; } -.pagination span a:hover { - text-decoration: none; -} - -.pagination img { - vertical-align: middle; -} - /* Pagination in viewforum for multipage topics */ .row .pagination { display: block; float: right; width: auto; margin-top: 0; - padding: 1px 0 1px 15px; + padding: 1px 0 1px 8px; font-size: 0.9em; background: none 0 50% no-repeat; } diff --git a/phpBB/styles/prosilver/theme/content.css b/phpBB/styles/prosilver/theme/content.css index 60903911dd..81f3567aba 100644 --- a/phpBB/styles/prosilver/theme/content.css +++ b/phpBB/styles/prosilver/theme/content.css @@ -1,6 +1,8 @@ /* Content Styles ---------------------------------------- */ +/* Forum and topic lists +---------------------------------------- */ ul.topiclist { display: block; list-style-type: none; @@ -701,4 +703,4 @@ dl.pmlist dt textarea { dl.pmlist dd { margin-left: 61% !important; margin-bottom: 2px; -} +} \ No newline at end of file diff --git a/phpBB/styles/subsilver2/template/pagination.html b/phpBB/styles/subsilver2/template/pagination.html index a36eb88d8f..f78bb554fc 100644 --- a/phpBB/styles/subsilver2/template/pagination.html +++ b/phpBB/styles/subsilver2/template/pagination.html @@ -1 +1,11 @@ -{L_GOTO_PAGE} {L_PREVIOUS}  {PAGINATION}  {L_NEXT} + + {L_GOTO_PAGE} + + {pagination.PAGE_NUMBER} + {pagination.PAGE_NUMBER} + {L_ELLIPSIS} + {pagination.PAGE_NUMBER} + {pagination.PAGE_NUMBER} + + + diff --git a/phpBB/styles/subsilver2/template/posting_smilies.html b/phpBB/styles/subsilver2/template/posting_smilies.html index 691ba239b2..30a80e26ab 100644 --- a/phpBB/styles/subsilver2/template/posting_smilies.html +++ b/phpBB/styles/subsilver2/template/posting_smilies.html @@ -16,7 +16,20 @@
    - +
    {L_SMILIES}
    {smiley.SMILEY_CODE}
    {PAGINATION}
    {L_CLOSE_WINDOW}
    {smiley.SMILEY_CODE}
    + + {L_GOTO_PAGE} + + {pagination.PAGE_NUMBER} + {pagination.PAGE_NUMBER} + {L_ELLIPSIS} + {pagination.PAGE_NUMBER} + {pagination.PAGE_NUMBER} + + +
    + + {L_CLOSE_WINDOW}
    diff --git a/phpBB/styles/subsilver2/template/search_results.html b/phpBB/styles/subsilver2/template/search_results.html index d8a1879ca7..a143a186d7 100644 --- a/phpBB/styles/subsilver2/template/search_results.html +++ b/phpBB/styles/subsilver2/template/search_results.html @@ -42,8 +42,17 @@ {REPORTED_IMG}  - -

    [ {GOTO_PAGE_IMG}{L_GOTO_PAGE}: {searchresults.PAGINATION} ]

    + +

    [ {GOTO_PAGE_IMG}{L_GOTO_PAGE}: + + + {searchresults.pagination.PAGE_NUMBER} + {L_ELLIPSIS} + + {searchresults.pagination.PAGE_NUMBER} + + + ]

    {L_IN} {searchresults.FORUM_TITLE}

    diff --git a/phpBB/styles/subsilver2/template/ucp_main_bookmarks.html b/phpBB/styles/subsilver2/template/ucp_main_bookmarks.html index 2fa8f6ac2e..ba19c45eab 100644 --- a/phpBB/styles/subsilver2/template/ucp_main_bookmarks.html +++ b/phpBB/styles/subsilver2/template/ucp_main_bookmarks.html @@ -43,8 +43,17 @@

    {NEWEST_POST_IMG} {topicrow.ATTACH_ICON_IMG} {topicrow.TOPIC_TITLE}

    {L_GLOBAL_ANNOUNCEMENT}{L_FORUM}: {topicrow.FORUM_NAME} - -

    [ {GOTO_PAGE_IMG}{L_GOTO_PAGE}: {topicrow.PAGINATION} ]

    + +

    [ {GOTO_PAGE_IMG}{L_GOTO_PAGE}: + + + {topicrow.pagination.PAGE_NUMBER} + {L_ELLIPSIS} + + {topicrow.pagination.PAGE_NUMBER} + + + ]

    diff --git a/phpBB/styles/subsilver2/template/ucp_main_subscribed.html b/phpBB/styles/subsilver2/template/ucp_main_subscribed.html index 42a452549b..13d2935757 100644 --- a/phpBB/styles/subsilver2/template/ucp_main_subscribed.html +++ b/phpBB/styles/subsilver2/template/ucp_main_subscribed.html @@ -52,8 +52,17 @@

    {NEWEST_POST_IMG} {topicrow.ATTACH_ICON_IMG} {topicrow.TOPIC_TITLE}

    {L_GLOBAL_ANNOUNCEMENT}{L_FORUM}: {topicrow.FORUM_NAME} - -

    [ {GOTO_PAGE_IMG}{L_GOTO_PAGE}: {topicrow.PAGINATION} ]

    + +

    [ {GOTO_PAGE_IMG}{L_GOTO_PAGE}: + + + {topicrow.pagination.PAGE_NUMBER} + {L_ELLIPSIS} + + {topicrow.pagination.PAGE_NUMBER} + + + ]

    diff --git a/phpBB/styles/subsilver2/template/viewforum_body.html b/phpBB/styles/subsilver2/template/viewforum_body.html index afb8426799..7f241ce874 100644 --- a/phpBB/styles/subsilver2/template/viewforum_body.html +++ b/phpBB/styles/subsilver2/template/viewforum_body.html @@ -48,8 +48,17 @@ {REPORTED_IMG}  - -

    [ {GOTO_PAGE_IMG}{L_GOTO_PAGE}: {topicrow.PAGINATION} ]

    + +

    [ {GOTO_PAGE_IMG}{L_GOTO_PAGE}: + + + {topicrow.pagination.PAGE_NUMBER} + {L_ELLIPSIS} + + {topicrow.pagination.PAGE_NUMBER} + + + ]

    {topicrow.TOPIC_AUTHOR_FULL}

    @@ -199,8 +208,17 @@ {REPORTED_IMG}  - -

    [ {GOTO_PAGE_IMG}{L_GOTO_PAGE}: {topicrow.PAGINATION} ]

    + +

    [ {GOTO_PAGE_IMG}{L_GOTO_PAGE}: + + + {topicrow.pagination.PAGE_NUMBER} + {L_ELLIPSIS} + + {topicrow.pagination.PAGE_NUMBER} + + + ]

    {L_IN} {topicrow.FORUM_NAME}

    diff --git a/phpBB/styles/subsilver2/template/viewonline_body.html b/phpBB/styles/subsilver2/template/viewonline_body.html index 1c8734d06a..b05a9470e0 100644 --- a/phpBB/styles/subsilver2/template/viewonline_body.html +++ b/phpBB/styles/subsilver2/template/viewonline_body.html @@ -8,7 +8,7 @@ - +
    {L_GOTO_PAGE} {L_PREVIOUS}  {PAGINATION}  {L_NEXT}
    @@ -39,7 +39,7 @@ - +
    {L_GOTO_PAGE} {L_PREVIOUS}  {PAGINATION}  {L_NEXT}
    diff --git a/phpBB/viewforum.php b/phpBB/viewforum.php index 6a39f10394..f1c10e347e 100644 --- a/phpBB/viewforum.php +++ b/phpBB/viewforum.php @@ -590,8 +590,9 @@ if ($s_display_active) // otherwise the number is different from the one on the forum list $total_topic_count = $topics_count - sizeof($global_announce_forums); +generate_pagination(append_sid("{$phpbb_root_path}viewforum.$phpEx", "f=$forum_id" . ((strlen($u_sort_param)) ? "&$u_sort_param" : '')), $topics_count, $config['topics_per_page'], $start); + $template->assign_vars(array( - 'PAGINATION' => generate_pagination(append_sid("{$phpbb_root_path}viewforum.$phpEx", "f=$forum_id" . ((strlen($u_sort_param)) ? "&$u_sort_param" : '')), $topics_count, $config['topics_per_page'], $start), 'PAGE_NUMBER' => on_page($topics_count, $config['topics_per_page'], $start), 'TOTAL_TOPICS' => ($s_display_active) ? false : $user->lang('VIEW_FORUM_TOPICS', (int) $total_topic_count), )); @@ -702,7 +703,6 @@ if (sizeof($topic_list)) 'LAST_POST_AUTHOR_COLOUR' => get_username_string('colour', $row['topic_last_poster_id'], $row['topic_last_poster_name'], $row['topic_last_poster_colour']), 'LAST_POST_AUTHOR_FULL' => get_username_string('full', $row['topic_last_poster_id'], $row['topic_last_poster_name'], $row['topic_last_poster_colour']), - 'PAGINATION' => topic_generate_pagination($replies, $view_topic_url), 'REPLIES' => $replies, 'VIEWS' => $row['topic_views'], 'TOPIC_TITLE' => censor_text($row['topic_title']), @@ -744,6 +744,8 @@ if (sizeof($topic_list)) 'S_TOPIC_TYPE_SWITCH' => ($s_type_switch == $s_type_switch_test) ? -1 : $s_type_switch_test) ); + generate_pagination($view_topic_url, $replies + 1, $config['posts_per_page'], 1, '', true, true, 'topicrow'); + $s_type_switch = ($row['topic_type'] == POST_ANNOUNCE || $row['topic_type'] == POST_GLOBAL) ? 1 : 0; if ($unread_topic) diff --git a/phpBB/viewonline.php b/phpBB/viewonline.php index 08ca7f7a04..546152f647 100644 --- a/phpBB/viewonline.php +++ b/phpBB/viewonline.php @@ -342,7 +342,7 @@ while ($row = $db->sql_fetchrow($result)) $db->sql_freeresult($result); unset($prev_id, $prev_ip); -$pagination = generate_pagination(append_sid("{$phpbb_root_path}viewonline.$phpEx", "sg=$show_guests&sk=$sort_key&sd=$sort_dir"), $counter, $config['topics_per_page'], $start); +generate_pagination(append_sid("{$phpbb_root_path}viewonline.$phpEx", "sg=$show_guests&sk=$sort_key&sd=$sort_dir"), $counter, $config['topics_per_page'], $start); $order_legend = ($config['legend_sort_groupname']) ? 'group_name' : 'group_legend'; // Grab group details for legend display diff --git a/phpBB/viewtopic.php b/phpBB/viewtopic.php index 0d6e9afd54..98a4f123be 100644 --- a/phpBB/viewtopic.php +++ b/phpBB/viewtopic.php @@ -546,7 +546,7 @@ foreach($quickmod_array as $option => $qm_ary) } // If we've got a hightlight set pass it on to pagination. -$pagination = generate_pagination(append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f=$forum_id&t=$topic_id" . ((strlen($u_sort_param)) ? "&$u_sort_param" : '') . (($highlight_match) ? "&hilit=$highlight" : '')), $total_posts, $config['posts_per_page'], $start); +generate_pagination(append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f=$forum_id&t=$topic_id" . ((strlen($u_sort_param)) ? "&$u_sort_param" : '') . (($highlight_match) ? "&hilit=$highlight" : '')), $total_posts, $config['posts_per_page'], $start); // Navigation links generate_forum_nav($topic_data); @@ -598,7 +598,6 @@ $template->assign_vars(array( 'TOPIC_AUTHOR_COLOUR' => get_username_string('colour', $topic_data['topic_poster'], $topic_data['topic_first_poster_name'], $topic_data['topic_first_poster_colour']), 'TOPIC_AUTHOR' => get_username_string('username', $topic_data['topic_poster'], $topic_data['topic_first_poster_name'], $topic_data['topic_first_poster_colour']), - 'PAGINATION' => $pagination, 'PAGE_NUMBER' => on_page($total_posts, $config['posts_per_page'], $start), 'TOTAL_POSTS' => $user->lang('VIEW_TOPIC_POSTS', (int) $total_posts), 'U_MCP' => ($auth->acl_get('m_', $forum_id)) ? append_sid("{$phpbb_root_path}mcp.$phpEx", "i=main&mode=topic_view&f=$forum_id&t=$topic_id" . (($start == 0) ? '' : "&start=$start") . ((strlen($u_sort_param)) ? "&$u_sort_param" : ''), true, $user->session_id) : '', From dc71c0629e60acccd39b59538f2e7f5b09b32509 Mon Sep 17 00:00:00 2001 From: Drae Date: Thu, 5 Jul 2012 18:56:14 +0100 Subject: [PATCH 427/441] [feature/pagination-as-list] Various fixes and improvements Extracted common template code for prosilver as per subsilver2. Various other fixups and oversight corrections, changed name of the "new" template function and re-introduced existing version. Altered on_page to compensate for removal of some templating vars from pagination routine. PHPBB3-10968 --- phpBB/adm/style/acp_attachments.html | 17 +- phpBB/adm/style/acp_groups.html | 12 +- phpBB/adm/style/acp_icons.html | 11 +- phpBB/adm/style/acp_inactive.html | 12 +- phpBB/adm/style/acp_logs.html | 12 +- phpBB/adm/style/acp_users.html | 24 +-- phpBB/adm/style/acp_users_feedback.html | 24 +-- phpBB/adm/style/pagination.html | 12 ++ phpBB/includes/acp/acp_attachments.php | 5 +- phpBB/includes/acp/acp_groups.php | 5 +- phpBB/includes/acp/acp_icons.php | 2 +- phpBB/includes/acp/acp_inactive.php | 5 +- phpBB/includes/acp/acp_logs.php | 5 +- phpBB/includes/acp/acp_users.php | 10 +- phpBB/includes/functions.php | 199 ++++++++++++++---- phpBB/includes/mcp/mcp_forum.php | 5 +- phpBB/includes/mcp/mcp_logs.php | 5 +- phpBB/includes/mcp/mcp_notes.php | 5 +- phpBB/includes/mcp/mcp_pm_reports.php | 7 +- phpBB/includes/mcp/mcp_queue.php | 5 +- phpBB/includes/mcp/mcp_reports.php | 5 +- phpBB/includes/mcp/mcp_topic.php | 5 +- phpBB/includes/mcp/mcp_warn.php | 5 +- phpBB/includes/ucp/ucp_attachments.php | 5 +- phpBB/includes/ucp/ucp_groups.php | 5 +- phpBB/includes/ucp/ucp_main.php | 6 +- phpBB/includes/ucp/ucp_pm_viewfolder.php | 5 +- phpBB/memberlist.php | 4 +- phpBB/search.php | 6 +- .../styles/prosilver/template/mcp_forum.html | 15 +- phpBB/styles/prosilver/template/mcp_logs.html | 30 +-- .../prosilver/template/mcp_notes_user.html | 30 +-- .../styles/prosilver/template/mcp_queue.html | 30 +-- .../prosilver/template/mcp_reports.html | 30 +-- .../styles/prosilver/template/mcp_topic.html | 15 +- .../prosilver/template/mcp_warn_list.html | 15 +- .../prosilver/template/memberlist_body.html | 30 +-- .../styles/prosilver/template/pagination.html | 15 ++ .../prosilver/template/posting_smilies.html | 15 +- .../prosilver/template/search_results.html | 15 +- .../prosilver/template/ucp_attachments.html | 30 +-- .../prosilver/template/ucp_groups_manage.html | 15 +- .../template/ucp_main_bookmarks.html | 15 +- .../template/ucp_main_subscribed.html | 15 +- .../template/ucp_pm_message_header.html | 15 +- .../prosilver/template/ucp_pm_viewfolder.html | 15 +- .../prosilver/template/viewforum_body.html | 30 +-- .../prosilver/template/viewonline_body.html | 30 +-- .../prosilver/template/viewtopic_body.html | 12 +- phpBB/styles/prosilver/theme/content.css | 4 +- phpBB/viewforum.php | 7 +- phpBB/viewonline.php | 7 +- phpBB/viewtopic.php | 9 +- 53 files changed, 303 insertions(+), 569 deletions(-) create mode 100644 phpBB/adm/style/pagination.html create mode 100644 phpBB/styles/prosilver/template/pagination.html diff --git a/phpBB/adm/style/acp_attachments.html b/phpBB/adm/style/acp_attachments.html index f3d67d2bfa..bdec9eb3cb 100644 --- a/phpBB/adm/style/acp_attachments.html +++ b/phpBB/adm/style/acp_attachments.html @@ -379,20 +379,11 @@ {L_TITLE} {L_CLOSE_WINDOW} diff --git a/phpBB/styles/prosilver/template/search_results.html b/phpBB/styles/prosilver/template/search_results.html index 7b4ecaab72..063cc8c8ea 100644 --- a/phpBB/styles/prosilver/template/search_results.html +++ b/phpBB/styles/prosilver/template/search_results.html @@ -29,20 +29,7 @@ {SEARCH_MATCHES} • - {PAGE_NUMBER} • - + {PAGE_NUMBER} diff --git a/phpBB/styles/prosilver/template/ucp_attachments.html b/phpBB/styles/prosilver/template/ucp_attachments.html index b57376344f..2160d8fcf7 100644 --- a/phpBB/styles/prosilver/template/ucp_attachments.html +++ b/phpBB/styles/prosilver/template/ucp_attachments.html @@ -14,20 +14,7 @@