aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--phpBB/adm/style/acp_forums.html5
-rw-r--r--phpBB/assets/javascript/core.js103
-rw-r--r--phpBB/includes/acp/acp_forums.php3
-rw-r--r--phpBB/includes/functions_display.php4
-rw-r--r--phpBB/includes/ucp/ucp_register.php14
-rw-r--r--phpBB/language/en/acp/forums.php2
-rw-r--r--phpBB/phpbb/db/migration/data/v330/forums_legend_limit.php49
-rw-r--r--phpBB/posting.php12
-rw-r--r--phpBB/styles/prosilver/template/memberlist_search.html2
-rw-r--r--phpBB/styles/prosilver/theme/colours.css5
-rw-r--r--phpBB/styles/prosilver/theme/forms.css2
-rw-r--r--tests/functional/subforum_test.php113
12 files changed, 292 insertions, 22 deletions
diff --git a/phpBB/adm/style/acp_forums.html b/phpBB/adm/style/acp_forums.html
index 20bcd2e9f9..f51ce98776 100644
--- a/phpBB/adm/style/acp_forums.html
+++ b/phpBB/adm/style/acp_forums.html
@@ -211,6 +211,11 @@
<label><input type="radio" class="radio" name="display_subforum_list" value="0"<!-- IF not S_DISPLAY_SUBFORUM_LIST --> id="display_subforum_list" checked="checked"<!-- ENDIF --> /> {L_NO}</label></dd>
</dl>
<dl>
+ <dt><label for="display_subforum_limit">{L_LIMIT_SUBFORUMS}{L_COLON}</label><br /><span>{L_LIMIT_SUBFORUMS_EXPLAIN}</span></dt>
+ <dd><label><input type="radio" class="radio" name="display_subforum_limit" value="1"<!-- IF S_DISPLAY_SUBFORUM_LIMIT --> id="display_subforum_limit" checked="checked"<!-- ENDIF --> /> {L_YES}</label>
+ <label><input type="radio" class="radio" name="display_subforum_limit" value="0"<!-- IF not S_DISPLAY_SUBFORUM_LIMIT --> id="display_subforum_limit" checked="checked"<!-- ENDIF --> /> {L_NO}</label></dd>
+ </dl>
+ <dl>
<dt><label for="display_on_index">{L_LIST_INDEX}{L_COLON}</label><br /><span>{L_LIST_INDEX_EXPLAIN}</span></dt>
<dd><label><input type="radio" class="radio" name="display_on_index" value="1"<!-- IF S_DISPLAY_ON_INDEX --> id="display_on_index" checked="checked"<!-- ENDIF --> /> {L_YES}</label>
<label><input type="radio" class="radio" name="display_on_index" value="0"<!-- IF not S_DISPLAY_ON_INDEX --> id="display_on_index" checked="checked"<!-- ENDIF --> /> {L_NO}</label></dd>
diff --git a/phpBB/assets/javascript/core.js b/phpBB/assets/javascript/core.js
index bb38441622..4a61490615 100644
--- a/phpBB/assets/javascript/core.js
+++ b/phpBB/assets/javascript/core.js
@@ -11,7 +11,9 @@ phpbb.alertTime = 100;
var keymap = {
TAB: 9,
ENTER: 13,
- ESC: 27
+ ESC: 27,
+ ARROW_UP: 38,
+ ARROW_DOWN: 40
};
var $dark = $('#darkenwrapper');
@@ -561,7 +563,7 @@ phpbb.search.setValue = function($input, value, multiline) {
phpbb.search.setValueOnClick = function($input, value, $row, $container) {
$row.click(function() {
phpbb.search.setValue($input, value.result, $input.attr('data-multiline'));
- $container.hide();
+ phpbb.search.closeResults($input, $container);
});
};
@@ -575,7 +577,7 @@ phpbb.search.setValueOnClick = function($input, value, $row, $container) {
* @param {object} event Onkeyup event object.
* @param {function} sendRequest Function to execute AJAX request.
*
- * @returns {bool} Returns false.
+ * @returns {boolean} Returns false.
*/
phpbb.search.filter = function(data, event, sendRequest) {
var $this = $(this),
@@ -584,9 +586,16 @@ phpbb.search.filter = function(data, event, sendRequest) {
searchID = $this.attr('data-results'),
keyword = phpbb.search.getKeyword($this, data[dataName], $this.attr('data-multiline')),
cache = phpbb.search.cache.get(searchID),
+ key = event.keyCode || event.which,
proceed = true;
data[dataName] = keyword;
+ // No need to search if enter was pressed
+ // for selecting a value from the results.
+ if (key === keymap.ENTER) {
+ return false;
+ }
+
if (cache.timeout) {
clearTimeout(cache.timeout);
}
@@ -697,22 +706,106 @@ phpbb.search.showResults = function(results, $input, $container, callback) {
row.appendTo($resultContainer).show();
});
$container.show();
+
+ phpbb.search.navigateResults($input, $container, $resultContainer);
};
/**
* Clear search results.
*
- * @param {jQuery} $container Search results container.
+ * @param {jQuery} $container Search results container.
*/
phpbb.search.clearResults = function($container) {
$container.children(':not(.search-result-tpl)').remove();
};
+/**
+ * Close search results.
+ *
+ * @param {jQuery} $input Search input|textarea.
+ * @param {jQuery} $container Search results container.
+ */
+phpbb.search.closeResults = function($input, $container) {
+ $input.off('.phpbb.search');
+ $container.hide();
+};
+
+/**
+ * Navigate search results.
+ *
+ * @param {jQuery} $input Search input|textarea.
+ * @param {jQuery} $container Search results container.
+ * @param {jQuery} $resultContainer Search results list container.
+ */
+phpbb.search.navigateResults = function($input, $container, $resultContainer) {
+ // Add a namespace to the event (.phpbb.search),
+ // so it can be unbound specifically later on.
+ $input.on('keydown.phpbb.search', function(event) {
+ var key = event.keyCode || event.which,
+ $active = $resultContainer.children('.active');
+
+ switch (key) {
+ // Close the results
+ case keymap.ESC:
+ phpbb.search.closeResults($input, $container);
+ break;
+
+ // Set the value for the selected result
+ case keymap.ENTER:
+ if ($active.length) {
+ var value = $active.find('.search-result > span').text();
+
+ phpbb.search.setValue($input, value, $input.attr('data-multiline'));
+ }
+
+ phpbb.search.closeResults($input, $container);
+
+ // Do not submit the form
+ event.preventDefault();
+ break;
+
+ // Navigate the results
+ case keymap.ARROW_DOWN:
+ case keymap.ARROW_UP:
+ var up = key === keymap.ARROW_UP,
+ $children = $resultContainer.children();
+
+ if (!$active.length) {
+ if (up) {
+ $children.last().addClass('active');
+ } else {
+ $children.first().addClass('active');
+ }
+ } else if ($children.length > 1) {
+ if (up) {
+ if ($active.is(':first-child')) {
+ $children.last().addClass('active');
+ } else {
+ $active.prev().addClass('active');
+ }
+ } else {
+ if ($active.is(':last-child')) {
+ $children.first().addClass('active');
+ } else {
+ $active.next().addClass('active');
+ }
+ }
+
+ $active.removeClass('active');
+ }
+
+ // Do not change cursor position in the input element
+ event.preventDefault();
+ break;
+ }
+ });
+};
+
$('#phpbb').click(function() {
var $this = $(this);
if (!$this.is('.live-search') && !$this.parents().is('.live-search')) {
- $('.live-search').hide();
+ phpbb.search.closeResults($('input, textarea'), $('.live-search'));
}
});
diff --git a/phpBB/includes/acp/acp_forums.php b/phpBB/includes/acp/acp_forums.php
index 572ae3692a..ba3901f67a 100644
--- a/phpBB/includes/acp/acp_forums.php
+++ b/phpBB/includes/acp/acp_forums.php
@@ -132,6 +132,7 @@ class acp_forums
'forum_image' => $request->variable('forum_image', ''),
'forum_style' => $request->variable('forum_style', 0),
'display_subforum_list' => $request->variable('display_subforum_list', true),
+ 'display_subforum_limit'=> $request->variable('display_subforum_limit', false),
'display_on_index' => $request->variable('display_on_index', true),
'forum_topics_per_page' => $request->variable('topics_per_page', 0),
'enable_indexing' => $request->variable('enable_indexing', true),
@@ -454,6 +455,7 @@ class acp_forums
'forum_image' => '',
'forum_style' => 0,
'display_subforum_list' => true,
+ 'display_subforum_limit' => false,
'display_on_index' => true,
'forum_topics_per_page' => 0,
'enable_indexing' => true,
@@ -676,6 +678,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_SUBFORUM_LIMIT' => ($forum_data['display_subforum_limit']) ? true : false,
'S_DISPLAY_ON_INDEX' => ($forum_data['display_on_index']) ? true : false,
'S_PRUNE_ENABLE' => ($forum_data['enable_prune']) ? true : false,
'S_PRUNE_SHADOW_ENABLE' => ($forum_data['enable_shadow_prune']) ? true : false,
diff --git a/phpBB/includes/functions_display.php b/phpBB/includes/functions_display.php
index 9be1ff950b..44478dbe49 100644
--- a/phpBB/includes/functions_display.php
+++ b/phpBB/includes/functions_display.php
@@ -30,6 +30,7 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod
$forum_rows = $subforums = $forum_ids = $forum_ids_moderator = $forum_moderators = $active_forum_ary = array();
$parent_id = $visible_forums = 0;
+ $parent_subforum_limit = false;
// Mark forums read?
$mark_read = $request->variable('mark', '');
@@ -266,6 +267,7 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod
// Direct child of current branch
$parent_id = $forum_id;
+ $parent_subforum_limit = $row['display_subforum_limit'];
$forum_rows[$forum_id] = $row;
if ($row['forum_type'] == FORUM_CAT && $row['parent_id'] == $root_data['forum_id'])
@@ -278,7 +280,7 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod
}
else if ($row['forum_type'] != FORUM_CAT)
{
- $subforums[$parent_id][$forum_id]['display'] = ($row['display_on_index']) ? true : false;
+ $subforums[$parent_id][$forum_id]['display'] = ($row['display_on_index'] && (!$parent_subforum_limit || $parent_id == $row['parent_id']));
$subforums[$parent_id][$forum_id]['name'] = $row['forum_name'];
$subforums[$parent_id][$forum_id]['orig_forum_last_post_time'] = $row['forum_last_post_time'];
$subforums[$parent_id][$forum_id]['children'] = array();
diff --git a/phpBB/includes/ucp/ucp_register.php b/phpBB/includes/ucp/ucp_register.php
index 97d2631224..694aaf1351 100644
--- a/phpBB/includes/ucp/ucp_register.php
+++ b/phpBB/includes/ucp/ucp_register.php
@@ -45,6 +45,11 @@ class ucp_register
$change_lang = $request->variable('change_lang', '');
$user_lang = $request->variable('lang', $user->lang_name);
+ if ($agreed && !check_form_key('ucp_register'))
+ {
+ $agreed = false;
+ }
+
/**
* Add UCP register data before they are assigned to the template or submitted
*
@@ -67,14 +72,7 @@ class ucp_register
);
extract($phpbb_dispatcher->trigger_event('core.ucp_register_requests_after', compact($vars)));
- if ($agreed)
- {
- add_form_key('ucp_register');
- }
- else
- {
- add_form_key('ucp_register_terms');
- }
+ add_form_key('ucp_register');
if ($change_lang || $user_lang != $config['default_lang'])
{
diff --git a/phpBB/language/en/acp/forums.php b/phpBB/language/en/acp/forums.php
index d92d3f8c9e..3ab152345c 100644
--- a/phpBB/language/en/acp/forums.php
+++ b/phpBB/language/en/acp/forums.php
@@ -129,6 +129,8 @@ $lang = array_merge($lang, array(
'GENERAL_FORUM_SETTINGS' => 'General forum settings',
'LINK' => 'Link',
+ 'LIMIT_SUBFORUMS' => 'Limit legend to direct child-subforums',
+ 'LIMIT_SUBFORUMS_EXPLAIN' => 'Limits the subforums to be displayed to subforums that are direct descendants (children) of the current forum. Disabling this will display all subforums with the “List subforums in legend” option enabled, regardless of depth.',
'LIST_INDEX' => 'List subforum in parent-forum’s legend',
'LIST_INDEX_EXPLAIN' => 'Displays this forum on the index and elsewhere as a link within the legend of its parent-forum if the parent-forum’s “List subforums in legend” option is enabled.',
'LIST_SUBFORUMS' => 'List subforums in legend',
diff --git a/phpBB/phpbb/db/migration/data/v330/forums_legend_limit.php b/phpBB/phpbb/db/migration/data/v330/forums_legend_limit.php
new file mode 100644
index 0000000000..c5a4beef38
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v330/forums_legend_limit.php
@@ -0,0 +1,49 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+namespace phpbb\db\migration\data\v330;
+
+class forums_legend_limit extends \phpbb\db\migration\migration
+{
+ public function effectively_installed()
+ {
+ return $this->db_tools->sql_column_exists($this->table_prefix . 'forums', 'display_subforum_limit');
+ }
+
+ static public function depends_on()
+ {
+ return ['\phpbb\db\migration\data\v330\v330b1'];
+ }
+
+ public function update_schema()
+ {
+ return [
+ 'add_columns' => [
+ $this->table_prefix . 'forums' => [
+ 'display_subforum_limit' => ['BOOL', 0, 'after' => 'display_subforum_list'],
+ ],
+ ],
+ ];
+ }
+
+ public function revert_schema()
+ {
+ return [
+ 'drop_columns' => [
+ $this->table_prefix . 'forums' => [
+ 'display_subforum_limit',
+ ],
+ ],
+ ];
+ }
+}
diff --git a/phpBB/posting.php b/phpBB/posting.php
index da70e64877..c5d0693f35 100644
--- a/phpBB/posting.php
+++ b/phpBB/posting.php
@@ -256,12 +256,6 @@ if ($mode == 'popup')
$user->setup(array('posting', 'mcp', 'viewtopic'), $post_data['forum_style']);
-if ($config['enable_post_confirm'] && !$user->data['is_registered'])
-{
- $captcha = $phpbb_container->get('captcha.factory')->get_instance($config['captcha_plugin']);
- $captcha->init(CONFIRM_POST);
-}
-
// Use post_row values in favor of submitted ones...
$forum_id = (!empty($post_data['forum_id'])) ? (int) $post_data['forum_id'] : (int) $forum_id;
$topic_id = (!empty($post_data['topic_id'])) ? (int) $post_data['topic_id'] : (int) $topic_id;
@@ -427,6 +421,12 @@ if (!$is_authed || !empty($error))
login_box('', $message);
}
+if ($config['enable_post_confirm'] && !$user->data['is_registered'])
+{
+ $captcha = $phpbb_container->get('captcha.factory')->get_instance($config['captcha_plugin']);
+ $captcha->init(CONFIRM_POST);
+}
+
// Is the user able to post within this forum?
if ($post_data['forum_type'] != FORUM_POST && in_array($mode, array('post', 'bump', 'quote', 'reply')))
{
diff --git a/phpBB/styles/prosilver/template/memberlist_search.html b/phpBB/styles/prosilver/template/memberlist_search.html
index b1c7a81709..34915ebc41 100644
--- a/phpBB/styles/prosilver/template/memberlist_search.html
+++ b/phpBB/styles/prosilver/template/memberlist_search.html
@@ -12,7 +12,7 @@
<dt><label for="username">{L_USERNAME}{L_COLON}</label></dt>
<dd>
<!-- IF U_LIVE_SEARCH --><div class="dropdown-container dropdown-{S_CONTENT_FLOW_END}"><!-- ENDIF -->
- <input type="text" name="username" id="username" value="{USERNAME}" class="inputbox"<!-- IF U_LIVE_SEARCH --> autocomplete="off" data-filter="phpbb.search.filter" data-ajax="member_search" data-min-length="3" data-url="{U_LIVE_SEARCH}" data-results="#user-search" data-overlay="false"<!-- ENDIF --> />
+ <input type="text" name="username" id="username" value="{USERNAME}" class="inputbox"<!-- IF U_LIVE_SEARCH --> autocomplete="off" data-filter="phpbb.search.filter" data-ajax="member_search" data-min-length="3" data-url="{U_LIVE_SEARCH}" data-results="#user-search"<!-- ENDIF --> />
<!-- IF U_LIVE_SEARCH -->
<div class="dropdown live-search hidden" id="user-search">
<div class="pointer"><div class="pointer-inner"></div></div>
diff --git a/phpBB/styles/prosilver/theme/colours.css b/phpBB/styles/prosilver/theme/colours.css
index ffaa71034f..1ead493926 100644
--- a/phpBB/styles/prosilver/theme/colours.css
+++ b/phpBB/styles/prosilver/theme/colours.css
@@ -672,6 +672,11 @@ Colours and backgrounds for buttons.css
box-shadow: 0 0 10px #0075B0;
}
+.search-results li:hover,
+.search-results li.active {
+ background-color: #CFE1F6;
+}
+
/* Icon images
---------------------------------------- */
diff --git a/phpBB/styles/prosilver/theme/forms.css b/phpBB/styles/prosilver/theme/forms.css
index 5646a7d6c7..99c898f41e 100644
--- a/phpBB/styles/prosilver/theme/forms.css
+++ b/phpBB/styles/prosilver/theme/forms.css
@@ -355,7 +355,7 @@ input.button3 {
font-variant: small-caps;
}
-input[type="button"], input[type="submit"], input[type="reset"], input[type="checkbox"], input[type="radio"] {
+input[type="button"], input[type="submit"], input[type="reset"], input[type="checkbox"], input[type="radio"], .search-results li {
cursor: pointer;
}
diff --git a/tests/functional/subforum_test.php b/tests/functional/subforum_test.php
new file mode 100644
index 0000000000..6ce4f53c20
--- /dev/null
+++ b/tests/functional/subforum_test.php
@@ -0,0 +1,113 @@
+<?php
+/**
+ *
+ * This file is part of the phpBB Forum Software package.
+ *
+ * @copyright (c) phpBB Limited <https://www.phpbb.com>
+ * @license GNU General Public License, version 2 (GPL-2.0)
+ *
+ * For full copyright and license information, please see
+ * the docs/CREDITS.txt file.
+ *
+ */
+
+/**
+ * @group functional
+ */
+class phpbb_functional_subforum_test extends phpbb_functional_test_case
+{
+ public function test_setup_forums()
+ {
+ $this->login();
+ $this->admin_login();
+
+ $forum_name = 'Subforum Test #1';
+ $crawler = self::request('GET', "adm/index.php?i=acp_forums&mode=manage&sid={$this->sid}");
+ $form = $crawler->selectButton('addforum')->form([
+ 'forum_name' => $forum_name,
+ ]);
+ $crawler = self::submit($form);
+ $form = $crawler->selectButton('update')->form([
+ 'forum_perm_from' => 2,
+ ]);
+ self::submit($form);
+ $forum_id = self::get_forum_id($forum_name);
+
+ // 'Feeds #1.1' is a sub-forum of 'Feeds #1'
+ $forum_name = 'Subforum Test #1.1';
+ $crawler = self::request('GET', "adm/index.php?i=acp_forums&sid={$this->sid}&icat=6&mode=manage&parent_id={$forum_id}");
+ $form = $crawler->selectButton('addforum')->form([
+ 'forum_name' => $forum_name,
+ ]);
+ $crawler = self::submit($form);
+ $form = $crawler->selectButton('update')->form([
+ 'forum_perm_from' => 2,
+ ]);
+ self::submit($form);
+ $forum_id = self::get_forum_id('Subforum Test #1.1');
+
+ // 'Feeds #news' will be used for feed.php?mode=news
+ $crawler = self::request('GET', "adm/index.php?i=acp_forums&sid={$this->sid}&icat=6&mode=manage&parent_id={$forum_id}");
+ $form = $crawler->selectButton('addforum')->form([
+ 'forum_name' => 'Subforum Test #1.1.1',
+ ]);
+ $crawler = self::submit($form);
+ $form = $crawler->selectButton('update')->form([
+ 'forum_perm_from' => 2,
+ ]);
+ self::submit($form);
+ }
+
+ /**
+ * @depends test_setup_forums
+ */
+ public function test_display_subforums()
+ {
+ $crawler = self::request('GET', "index.php?sid={$this->sid}");
+ $this->assertContains('Subforum Test #1.1', $crawler->html());
+ $this->assertContains('Subforum Test #1.1.1', $crawler->html());
+ }
+
+ /**
+ * @depends test_display_subforums
+ */
+ public function test_display_subforums_limit()
+ {
+ $this->login();
+ $this->admin_login();
+
+ // Disable listing subforums
+ $forum_id = $this->get_forum_id('Subforum Test #1');
+ $crawler = self::request('GET', "adm/index.php?i=acp_forums&sid={$this->sid}&icat=7&mode=manage&parent_id=0&f={$forum_id}&action=edit");
+ $form = $crawler->selectButton('submit')->form([
+ 'display_subforum_limit' => 1,
+ ]);
+ self::submit($form);
+
+ $crawler = self::request('GET', "index.php?sid={$this->sid}");
+ $this->assertContains('Subforum Test #1.1', $crawler->html());
+ $this->assertNotContains('Subforum Test #1.1.1', $crawler->html());
+ }
+
+ protected function get_forum_id($forum_name)
+ {
+ $this->db = $this->get_db();
+ $forum_id = 0;
+
+ $sql = 'SELECT *
+ FROM ' . FORUMS_TABLE . '
+ WHERE ' . $this->db->sql_in_set('forum_name', $forum_name);
+ $result = $this->db->sql_query($sql);
+ while ($row = $this->db->sql_fetchrow($result))
+ {
+ if ($row['forum_name'] == $forum_name)
+ {
+ $forum_id = (int) $row['forum_id'];
+ break;
+ }
+ }
+ $this->db->sql_freeresult($result);
+
+ return $forum_id;
+ }
+}