diff --git a/phpBB/adm/style/permission_roles_mask.html b/phpBB/adm/style/permission_roles_mask.html
index 277310edbf..42a7fc3e4e 100644
--- a/phpBB/adm/style/permission_roles_mask.html
+++ b/phpBB/adm/style/permission_roles_mask.html
@@ -25,7 +25,7 @@
{role_mask.groups.GROUP_NAME} ::
{L_GROUPS_NOT_ASSIGNED}
-
+
diff --git a/phpBB/includes/acp/acp_modules.php b/phpBB/includes/acp/acp_modules.php
index ab416fb406..a1e681b29c 100644
--- a/phpBB/includes/acp/acp_modules.php
+++ b/phpBB/includes/acp/acp_modules.php
@@ -575,13 +575,20 @@ class acp_modules
// format. phpbb_acp_info_acp_foo needs to be turned into
// acp_foo_info and the respective file has to be included
// manually because it does not support auto loading
- if (!class_exists($info_class))
+ $old_info_class_file = str_replace("phpbb_{$module_class}_info_", '', $cur_module);
+ $old_info_class = $old_info_class_file . '_info';
+
+ if (class_exists($old_info_class))
{
- $info_class_file = str_replace("phpbb_{$module_class}_info_", '', $cur_module);
- $info_class = $info_class_file . '_info';
- if (!class_exists($info_class) && file_exists($directory . $info_class_file . '.' . $phpEx))
+ $info_class = $old_info_class;
+ }
+ else if (!class_exists($info_class))
+ {
+ $info_class = $old_info_class;
+ // need to check class exists again because previous checks triggered autoloading
+ if (!class_exists($info_class) && file_exists($directory . $old_info_class_file . '.' . $phpEx))
{
- include($directory . $info_class_file . '.' . $phpEx);
+ include($directory . $old_info_class_file . '.' . $phpEx);
}
}
diff --git a/phpBB/includes/functions_display.php b/phpBB/includes/functions_display.php
index 143813e4ed..b1dac64bec 100644
--- a/phpBB/includes/functions_display.php
+++ b/phpBB/includes/functions_display.php
@@ -215,8 +215,9 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod
$forum_tracking_info[$forum_id] = (isset($tracking_topics['f'][$forum_id])) ? (int) (base_convert($tracking_topics['f'][$forum_id], 36, 10) + $config['board_startdate']) : $user->data['user_lastmark'];
}
- // Count the difference of real to public topics, so we can display an information to moderators
+ // Lets check whether there are unapproved topics/posts, so we can display an information to moderators
$row['forum_id_unapproved_topics'] = ($auth->acl_get('m_approve', $forum_id) && $row['forum_topics_unapproved']) ? $forum_id : 0;
+ $row['forum_id_unapproved_posts'] = ($auth->acl_get('m_approve', $forum_id) && $row['forum_posts_unapproved']) ? $forum_id : 0;
$row['forum_posts'] = $phpbb_content_visibility->get_count('forum_posts', $row, $forum_id);
$row['forum_topics'] = $phpbb_content_visibility->get_count('forum_topics', $row, $forum_id);
@@ -281,6 +282,11 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod
$forum_rows[$parent_id]['forum_id_unapproved_topics'] = $forum_id;
}
+ if (!$forum_rows[$parent_id]['forum_id_unapproved_posts'] && $row['forum_id_unapproved_posts'])
+ {
+ $forum_rows[$parent_id]['forum_id_unapproved_posts'] = $forum_id;
+ }
+
$forum_rows[$parent_id]['forum_topics'] += $row['forum_topics'];
// Do not list redirects in LINK Forums as Posts.
@@ -548,6 +554,7 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod
'L_MODERATOR_STR' => $l_moderator,
'U_UNAPPROVED_TOPICS' => ($row['forum_id_unapproved_topics']) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=queue&mode=unapproved_topics&f=' . $row['forum_id_unapproved_topics']) : '',
+ 'U_UNAPPROVED_POSTS' => ($row['forum_id_unapproved_posts']) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=queue&mode=unapproved_posts&f=' . $row['forum_id_unapproved_posts']) : '',
'U_VIEWFORUM' => $u_viewforum,
'U_LAST_POSTER' => get_username_string('profile', $row['forum_last_poster_id'], $row['forum_last_poster_name'], $row['forum_last_poster_colour']),
'U_LAST_POST' => $last_post_url,
@@ -587,6 +594,7 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod
'L_SUBFORUM' => ($visible_forums == 1) ? $user->lang['SUBFORUM'] : $user->lang['SUBFORUMS'],
'LAST_POST_IMG' => $user->img('icon_topic_latest', 'VIEW_LATEST_POST'),
'UNAPPROVED_IMG' => $user->img('icon_topic_unapproved', 'TOPICS_UNAPPROVED'),
+ 'UNAPPROVED_POST_IMG' => $user->img('icon_topic_unapproved', 'POSTS_UNAPPROVED'),
));
if ($return_moderators)
diff --git a/phpBB/styles/prosilver/template/forum_fn.js b/phpBB/styles/prosilver/template/forum_fn.js
index 1ab1387d10..eccb12e827 100644
--- a/phpBB/styles/prosilver/template/forum_fn.js
+++ b/phpBB/styles/prosilver/template/forum_fn.js
@@ -404,3 +404,22 @@ function apply_onkeypress_event() {
}
jQuery(document).ready(apply_onkeypress_event);
+
+/**
+* Adjust HTML code for IE8 and older versions
+*/
+(function($) {
+ $(document).ready(function() {
+ var test = document.createElement('div'),
+ oldBrowser = (typeof test.style.borderRadius == 'undefined');
+ delete test;
+
+ if (!oldBrowser) {
+ return;
+ }
+
+ // Fix .linkslist.bulletin lists
+ $('ul.linklist.bulletin li:first-child, ul.linklist.bulletin li.rightside:last-child').addClass('no-bulletin');
+ });
+})(jQuery);
+
diff --git a/phpBB/styles/prosilver/template/forumlist_body.html b/phpBB/styles/prosilver/template/forumlist_body.html
index 0c67de76ec..9fb6b3d951 100644
--- a/phpBB/styles/prosilver/template/forumlist_body.html
+++ b/phpBB/styles/prosilver/template/forumlist_body.html
@@ -50,7 +50,11 @@
{forumrow.TOPICS} {L_TOPICS}
{forumrow.POSTS} {L_POSTS}
- {UNAPPROVED_IMG}
+
+ {UNAPPROVED_IMG}
+
+ {UNAPPROVED_POST_IMG}
+
{L_LAST_POST}
diff --git a/phpBB/styles/prosilver/template/index_body.html b/phpBB/styles/prosilver/template/index_body.html
index 57ad540a4a..e0a9279738 100644
--- a/phpBB/styles/prosilver/template/index_body.html
+++ b/phpBB/styles/prosilver/template/index_body.html
@@ -4,9 +4,16 @@
{CURRENT_TIME}
[ {L_MCP} ]
{CURRENT_TIME}
-
+
diff --git a/phpBB/styles/prosilver/template/overall_footer.html b/phpBB/styles/prosilver/template/overall_footer.html
index eef9f53409..b948d9f627 100644
--- a/phpBB/styles/prosilver/template/overall_footer.html
+++ b/phpBB/styles/prosilver/template/overall_footer.html
@@ -5,16 +5,21 @@
diff --git a/phpBB/styles/prosilver/template/overall_header.html b/phpBB/styles/prosilver/template/overall_header.html
index 25094bbf5d..ddbd917bd6 100644
--- a/phpBB/styles/prosilver/template/overall_header.html
+++ b/phpBB/styles/prosilver/template/overall_header.html
@@ -127,7 +127,7 @@
-
+
diff --git a/phpBB/styles/prosilver/theme/buttons.css b/phpBB/styles/prosilver/theme/buttons.css
index 09021c771f..9336dd09f8 100644
--- a/phpBB/styles/prosilver/theme/buttons.css
+++ b/phpBB/styles/prosilver/theme/buttons.css
@@ -97,17 +97,9 @@ a.sendemail {
padding: 1px 0 0 17px;
}
-.icon-notification:before, .icon-notification:after {
- display: inline;
- font: inherit;
-}
-
-.icon-notification:before {
- content: '[';
-}
-
-.icon-notification:after {
- content: ']';
+ul.linklist.bulletin li.icon-home:before, ul.linklist.bulletin li.icon-ucp:before,
+ul.linklist.bulletin li.icon-bookmark:before, ul.linklist.bulletin li.icon-bump:before, ul.linklist.bulletin li.icon-subscribe:before, ul.linklist.bulletin li.icon-unsubscribe:before {
+ display: none;
}
/* Poster profile icons
diff --git a/phpBB/styles/prosilver/theme/common.css b/phpBB/styles/prosilver/theme/common.css
index 89b3ab7ada..e58386de45 100644
--- a/phpBB/styles/prosilver/theme/common.css
+++ b/phpBB/styles/prosilver/theme/common.css
@@ -356,6 +356,38 @@ ul.rightside {
text-align: right;
}
+/* Bulletin icons for list items
+----------------------------------------*/
+ul.linklist.bulletin li:before {
+ display: inline-block;
+ content: "\2022";
+ font-size: inherit;
+ line-height: inherit;
+ padding-right: 4px;
+}
+
+ul.linklist.bulletin li:first-child:before, ul.linklist.bulletin li.rightside:last-child:before {
+ display: none;
+}
+
+ul.linklist.bulletin li.no-bulletin:before {
+ display: none;
+}
+
+.icon-notification:before, ul.linklist.bulletin li.icon-notification:before, .icon-notification:after {
+ display: inline;
+ font: inherit;
+}
+
+.icon-notification:before, ul.linklist.bulletin li.icon-notification:before {
+ content: '[';
+ padding-right: 0;
+}
+
+.icon-notification:after {
+ content: ']';
+}
+
/* Table styles
----------------------------------------*/
table.table1 {
diff --git a/phpBB/styles/subsilver2/template/forumlist_body.html b/phpBB/styles/subsilver2/template/forumlist_body.html
index 3e30561f3a..a222607ae8 100644
--- a/phpBB/styles/subsilver2/template/forumlist_body.html
+++ b/phpBB/styles/subsilver2/template/forumlist_body.html
@@ -64,7 +64,14 @@
{forumrow.LAST_POST_SUBJECT_TRUNCATED}
- {UNAPPROVED_IMG} {forumrow.LAST_POST_TIME}
+
+
+ {UNAPPROVED_IMG}
+
+ {UNAPPROVED_POST_IMG}
+
+ {forumrow.LAST_POST_TIME}
+
{forumrow.LAST_POSTER_FULL}
{LAST_POST_IMG}
diff --git a/tests/avatar/manager_test.php b/tests/avatar/manager_test.php
index cb895b521a..4ebe79c9cd 100644
--- a/tests/avatar/manager_test.php
+++ b/tests/avatar/manager_test.php
@@ -19,24 +19,35 @@ class phpbb_avatar_manager_test extends PHPUnit_Framework_TestCase
$this->phpbb_container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface');
$this->phpbb_container->expects($this->any())
->method('get')
- ->with('avatar.driver.foobar')->will($this->returnValue('avatar.driver.foobar'));
+ ->will($this->returnArgument(0));
// Prepare dependencies for avatar manager and driver
$config = new phpbb_config(array());
$request = $this->getMock('phpbb_request');
$cache = $this->getMock('phpbb_cache_driver_interface');
+ // $this->avatar_foobar will be needed later on
$this->avatar_foobar = $this->getMock('phpbb_avatar_driver_foobar', array('get_name'), array($config, $phpbb_root_path, $phpEx, $cache));
$this->avatar_foobar->expects($this->any())
- ->method('get_name')
- ->will($this->returnValue('avatar.driver.foobar'));
+ ->method('get_name')
+ ->will($this->returnValue('avatar.driver.foobar'));
+ // barfoo driver can't be mocked with constructor arguments
$this->avatar_barfoo = $this->getMock('phpbb_avatar_driver_barfoo', array('get_name'));
$this->avatar_barfoo->expects($this->any())
- ->method('get_name')
- ->will($this->returnValue('avatar.driver.barfoo'));
-
+ ->method('get_name')
+ ->will($this->returnValue('avatar.driver.barfoo'));
$avatar_drivers = array($this->avatar_foobar, $this->avatar_barfoo);
+ foreach ($this->avatar_drivers() as $driver)
+ {
+ $cur_avatar = $this->getMock('phpbb_avatar_driver_' . $driver, array('get_name'), array($config, $phpbb_root_path, $phpEx, $cache));
+ $cur_avatar->expects($this->any())
+ ->method('get_name')
+ ->will($this->returnValue('avatar.driver.' . $driver));
+ $config['allow_avatar_' . get_class($cur_avatar)] = false;
+ $avatar_drivers[] = $cur_avatar;
+ }
+
$config['allow_avatar_' . get_class($this->avatar_foobar)] = true;
$config['allow_avatar_' . get_class($this->avatar_barfoo)] = false;
@@ -44,28 +55,27 @@ class phpbb_avatar_manager_test extends PHPUnit_Framework_TestCase
$this->manager = new phpbb_avatar_manager($config, $avatar_drivers, $this->phpbb_container);
}
- public function test_get_driver()
+ protected function avatar_drivers()
{
- $driver = $this->manager->get_driver('avatar.driver.foobar', false);
- $this->assertEquals('avatar.driver.foobar', $driver);
-
- $driver = $this->manager->get_driver('avatar.driver.foo_wrong', false);
- $this->assertNull($driver);
-
- $driver = $this->manager->get_driver('avatar.driver.foobar');
- $this->assertEquals('avatar.driver.foobar', $driver);
-
- $driver = $this->manager->get_driver('avatar.driver.foo_wrong');
- $this->assertNull($driver);
+ return array(
+ 'local',
+ 'upload',
+ 'remote',
+ 'gravatar',
+ );
}
public function test_get_all_drivers()
{
$drivers = $this->manager->get_all_drivers();
- $this->assertArrayHasKey('avatar.driver.foobar', $drivers);
- $this->assertArrayHasKey('avatar.driver.barfoo', $drivers);
- $this->assertEquals('avatar.driver.foobar', $drivers['avatar.driver.foobar']);
- $this->assertEquals('avatar.driver.barfoo', $drivers['avatar.driver.barfoo']);
+ $this->assertEquals(array(
+ 'avatar.driver.barfoo' => 'avatar.driver.barfoo',
+ 'avatar.driver.foobar' => 'avatar.driver.foobar',
+ 'avatar.driver.local' => 'avatar.driver.local',
+ 'avatar.driver.remote' => 'avatar.driver.remote',
+ 'avatar.driver.upload' => 'avatar.driver.upload',
+ 'avatar.driver.gravatar' => 'avatar.driver.gravatar',
+ ), $drivers);
}
public function test_get_enabled_drivers()
@@ -76,6 +86,48 @@ class phpbb_avatar_manager_test extends PHPUnit_Framework_TestCase
$this->assertEquals('avatar.driver.foobar', $drivers['avatar.driver.foobar']);
}
+ public function get_driver_data_enabled()
+ {
+ return array(
+ array('avatar.driver.foobar', 'avatar.driver.foobar'),
+ array('avatar.driver.foo_wrong', null),
+ array('avatar.driver.local', null),
+ array(AVATAR_GALLERY, null),
+ array(AVATAR_UPLOAD, null),
+ array(AVATAR_REMOTE, null),
+ );
+ }
+
+ /**
+ * @dataProvider get_driver_data_enabled
+ */
+ public function test_get_driver_enabled($driver_name, $expected)
+ {
+ $driver = $this->manager->get_driver($driver_name);
+ $this->assertEquals($expected, $driver);
+ }
+
+ public function get_driver_data_all()
+ {
+ return array(
+ array('avatar.driver.foobar', 'avatar.driver.foobar'),
+ array('avatar.driver.foo_wrong', null),
+ array('avatar.driver.local', 'avatar.driver.local'),
+ array(AVATAR_GALLERY, 'avatar.driver.local'),
+ array(AVATAR_UPLOAD, 'avatar.driver.upload'),
+ array(AVATAR_REMOTE, 'avatar.driver.remote'),
+ );
+ }
+
+ /**
+ * @dataProvider get_driver_data_all
+ */
+ public function test_get_driver_all($driver_name, $expected)
+ {
+ $driver = $this->manager->get_driver($driver_name, false);
+ $this->assertEquals($expected, $driver);
+ }
+
public function test_get_avatar_settings()
{
$avatar_settings = $this->manager->get_avatar_settings($this->avatar_foobar);
@@ -157,4 +209,38 @@ class phpbb_avatar_manager_test extends PHPUnit_Framework_TestCase
$this->assertArrayHasKey($key, $cleaned_row);
}
}
+
+ public function test_clean_driver_name()
+ {
+ $this->assertEquals('avatar.driver.local', $this->manager->clean_driver_name('avatar_driver_local'));
+ }
+
+ public function test_prepare_driver_name()
+ {
+ $this->assertEquals('avatar_driver_local', $this->manager->prepare_driver_name('avatar.driver.local'));
+ }
+
+ public function test_localize_errors()
+ {
+ $user = $this->getMock('phpbb_user');
+ $lang_array = array(
+ array('FOOBAR_OFF', 'foobar_off'),
+ array('FOOBAR_EXPLAIN', 'FOOBAR_EXPLAIN %s'),
+ );
+ $user->expects($this->any())
+ ->method('lang')
+ ->will($this->returnValueMap($lang_array));
+
+ // Pass error as string
+ $this->assertEquals(array('foobar_off'), $this->manager->localize_errors($user, array('FOOBAR_OFF')));
+
+ // Pass error as array for vsprintf()
+ $this->assertEquals(array('FOOBAR_EXPLAIN foo'), $this->manager->localize_errors($user, array(array('FOOBAR_EXPLAIN', 'foo'))));
+
+ // Pass both types
+ $this->assertEquals(array('foobar_off', 'FOOBAR_EXPLAIN foo'), $this->manager->localize_errors($user, array(
+ 'FOOBAR_OFF',
+ array('FOOBAR_EXPLAIN', 'foo'),
+ )));
+ }
}
diff --git a/tests/test_framework/phpbb_functional_test_case.php b/tests/test_framework/phpbb_functional_test_case.php
index 0850cf4112..ed307c3ce2 100644
--- a/tests/test_framework/phpbb_functional_test_case.php
+++ b/tests/test_framework/phpbb_functional_test_case.php
@@ -743,6 +743,7 @@ class phpbb_functional_test_case extends phpbb_test_case
// Any output before the doc type means there was an error
$content = self::$client->getResponse()->getContent();
+ self::assertNotContains('[phpBB Debug]', $content);
self::assertStringStartsWith('