diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index 0c74f35..be277cc 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -127,6 +127,8 @@ jobs:
db: "mysql:5.7"
- php: '8.3'
db: "mysql:5.7"
+ - php: '8.4'
+ db: "mysql:5.7"
name: PHP ${{ matrix.php }} - ${{ matrix.db_alias != '' && matrix.db_alias || matrix.db }}
@@ -270,6 +272,8 @@ jobs:
db: "postgres:14"
- php: '8.3'
db: "postgres:14"
+ - php: '8.4'
+ db: "postgres:14"
name: PHP ${{ matrix.php }} - ${{ matrix.db }}
diff --git a/adm/style/settings_add_edit.html b/adm/style/settings_add_edit.html
index 3ba82cd..18c7b68 100644
--- a/adm/style/settings_add_edit.html
+++ b/adm/style/settings_add_edit.html
@@ -30,13 +30,6 @@
{{ ba.DESCRIPTION }} |
- {{ ba.INDEX_ONLY ? lang('INDEX') : lang('BOARD_ANNOUNCEMENTS_EVERYWHERE') }} |
+
+ {% if ba.LOCATIONS is empty %}
+ {{ lang('BOARD_ANNOUNCEMENTS_EVERYWHERE') }}
+ {% else %}
+ {% set has_index = constant('\\phpbb\\boardannouncements\\ext::INDEX_ONLY') in ba.LOCATIONS %}
+ {% set has_forums = ba.LOCATIONS|filter(v => v > 0)|length > 0 %}
+ {% if has_index and has_forums %}
+ {{ lang('BOARD_ANNOUNCEMENTS_INDEX_PAGE') }}, {{ lang('BOARD_ANNOUNCEMENTS_FORUMS') }}
+ {% elseif has_index %}
+ {{ lang('BOARD_ANNOUNCEMENTS_INDEX_PAGE') }}
+ {% elseif has_forums %}
+ {{ lang('BOARD_ANNOUNCEMENTS_FORUMS') }}
+ {% endif %}
+ {% endif %}
+ |
{% if ba.USERS == constant('\\phpbb\\boardannouncements\\ext::ALL') %}
{{ lang('BOARD_ANNOUNCEMENTS_EVERYONE') }}
{% elseif ba.USERS == constant('\\phpbb\\boardannouncements\\ext::MEMBERS') %}
diff --git a/config/services.yml b/config/services.yml
index 176fd24..b428347 100644
--- a/config/services.yml
+++ b/config/services.yml
@@ -7,6 +7,7 @@ services:
class: phpbb\boardannouncements\event\listener
arguments:
- '@phpbb.boardannouncements.manager'
+ - '@auth'
- '@config'
- '@controller.helper'
- '@language'
diff --git a/controller/acp_controller.php b/controller/acp_controller.php
index a6ba334..3e4e329 100644
--- a/controller/acp_controller.php
+++ b/controller/acp_controller.php
@@ -137,12 +137,12 @@ protected function list_announcements()
$this->template->assign_block_vars('announcements' , [
'DESCRIPTION' => $row['announcement_description'],
- 'INDEX_ONLY' => $row['announcement_indexonly'],
'USERS' => $row['announcement_users'],
'CREATED_DATE' => $row['announcement_timestamp'],
'EXPIRY_DATE' => $row['announcement_expiry'],
'S_EXPIRED' => $expired,
'S_ENABLED' => $enabled,
+ 'LOCATIONS' => $this->manager->decode_json($row['announcement_locations']),
'U_EDIT' => $this->u_action . '&action=add&id=' . $row['announcement_id'],
'U_DELETE' => $this->u_action . '&action=delete&id=' . $row['announcement_id'],
'U_MOVE_UP' => $this->u_action . '&action=move&id=' . $row['announcement_id'] . '&dir=up&hash=' . generate_link_hash('up' . $row['announcement_id']),
@@ -206,7 +206,7 @@ protected function action_add()
$data['announcement_bgcolor'] = $this->request->variable('board_announcements_bgcolor', '', true);
$data['announcement_enabled'] = $this->request->variable('board_announcements_enabled', true);
$data['announcement_users'] = $this->request->variable('board_announcements_users', ext::ALL);
- $data['announcement_indexonly'] = $this->request->variable('board_announcements_index_only', false);
+ $data['announcement_locations'] = $this->request->variable('board_announcements_locations', [0]);
$data['announcement_dismissable'] = $this->request->variable('board_announcements_dismiss', true);
$data['announcement_expiry'] = $this->request->variable('board_announcements_expiry', '');
@@ -229,6 +229,9 @@ protected function action_add()
$data['announcement_expiry'] = 0;
}
+ // Locations array should be json encoded for storage in the DB
+ $data['announcement_locations'] = json_encode($data['announcement_locations']);
+
// Prepare announcement text for storage
generate_text_for_storage(
$data['announcement_text'],
@@ -269,7 +272,6 @@ protected function action_add()
$this->template->assign_vars([
'ERRORS' => implode(' ', $errors),
'BOARD_ANNOUNCEMENTS_ENABLED' => $data['announcement_enabled'],
- 'BOARD_ANNOUNCEMENTS_INDEX_ONLY'=> $data['announcement_indexonly'],
'BOARD_ANNOUNCEMENTS_DISMISS' => $data['announcement_dismissable'],
'BOARD_ANNOUNCEMENTS_DESC' => $data['announcement_description'],
'BOARD_ANNOUNCEMENTS_TEXT' => $announcement_text_edit['text'],
@@ -277,6 +279,8 @@ protected function action_add()
'BOARD_ANNOUNCEMENTS_EXPIRY' => $data['announcement_expiry'] ? $this->user->format_date($data['announcement_expiry'], ext::DATE_FORMAT) : '',
'BOARD_ANNOUNCEMENTS_BGCOLOR' => $data['announcement_bgcolor'],
+ 'BOARD_ANNOUNCEMENTS_LOCATIONS' => $this->get_location_options($data['announcement_locations']),
+
'S_BOARD_ANNOUNCEMENTS_USERS' => build_select([
ext::ALL => 'BOARD_ANNOUNCEMENTS_EVERYONE',
ext::MEMBERS => 'G_REGISTERED',
@@ -443,4 +447,29 @@ protected function log_change($msg, $params)
{
$this->log->add('admin', $this->user->data['user_id'], $this->user->ip, $msg, time(), [$params]);
}
+
+ /**
+ * Get an array of available locations for the announcement
+ *
+ * @param string $locations
+ * @return array
+ */
+ protected function get_location_options($locations)
+ {
+ $selected = !empty($locations) ? $this->manager->decode_json($locations) : [];
+
+ $forum_list = make_forum_select($selected, false, false, false, false, false, true);
+
+ // Add the index page to the list
+ $forum_list[ext::INDEX_ONLY] = [
+ 'padding' => '',
+ 'selected' => in_array(ext::INDEX_ONLY, $selected),
+ 'forum_id' => ext::INDEX_ONLY,
+ 'forum_name' => $this->language->lang('BOARD_ANNOUNCEMENTS_INDEX_PAGE')
+ ];
+
+ ksort($forum_list);
+
+ return $forum_list;
+ }
}
diff --git a/event/listener.php b/event/listener.php
index 9023ac0..166357f 100644
--- a/event/listener.php
+++ b/event/listener.php
@@ -10,6 +10,8 @@
namespace phpbb\boardannouncements\event;
+use phpbb\auth\auth;
+use phpbb\boardannouncements\ext;
use phpbb\boardannouncements\manager\manager;
use phpbb\config\config;
use phpbb\controller\helper;
@@ -27,6 +29,9 @@ class listener implements EventSubscriberInterface
/** @var manager $manager */
protected $manager;
+ /** @var auth $auth */
+ protected $auth;
+
/** @var config $config */
protected $config;
@@ -48,10 +53,20 @@ class listener implements EventSubscriberInterface
/** @var string $php_ext */
protected $php_ext;
+ /** @var array $protected_forums*/
+ protected $protected_forums;
+
+ /** @var int $location */
+ protected $location;
+
+ /** @var bool|mixed $permission */
+ protected $permission;
+
/**
* Constructor
*
- * @param manager $manager
+ * @param manager $manager Board announcements manager object
+ * @param auth $auth Auth object
* @param config $config Config object
* @param helper $controller_helper Controller helper object
* @param language $language Language object
@@ -61,9 +76,10 @@ class listener implements EventSubscriberInterface
* @param string $php_ext PHP extension
* @access public
*/
- public function __construct(manager $manager, config $config, helper $controller_helper, language $language, request $request, template $template, user $user, $php_ext)
+ public function __construct(manager $manager, auth $auth, config $config, helper $controller_helper, language $language, request $request, template $template, user $user, $php_ext)
{
$this->manager = $manager;
+ $this->auth = $auth;
$this->config = $config;
$this->controller_helper = $controller_helper;
$this->language = $language;
@@ -108,14 +124,19 @@ public function display_board_announcements()
foreach ($board_announcements_data as $data)
{
- // Do not continue if announcements are only displayed on the board index, and the user is not currently viewing the board index
- if ($data['announcement_indexonly'] && $this->user->page['page_name'] !== "index.$this->php_ext")
+ $locations = $this->manager->decode_json($data['announcement_locations']);
+
+ // Do not include announcement if user is in a location where it shouldn't be visible
+ if (!empty($locations) && ($this->location_not_in($locations) || $this->is_protected() || $this->no_permission()))
{
continue;
}
- // Do not continue if announcement has been dismissed
- if ($this->request->variable($this->config['cookie_name'] . '_ba_' . $data['announcement_id'], '', true, \phpbb\request\request_interface::COOKIE) == $data['announcement_timestamp'])
+ $cookie_name = $this->config['cookie_name'] . '_ba_' . $data['announcement_id'];
+ $announcement_dismissed = $this->request->variable($cookie_name, '', true, \phpbb\request\request_interface::COOKIE) == $data['announcement_timestamp'];
+
+ // Do not include announcement if it has been dismissed
+ if ($announcement_dismissed)
{
continue;
}
@@ -133,4 +154,60 @@ public function display_board_announcements()
]);
}
}
+
+ /**
+ * Get the current location, board index or a forum_id
+ *
+ * @return int
+ */
+ protected function get_current_location()
+ {
+ if (!isset($this->location))
+ {
+ $this->location = $this->user->page['page_name'] === "index.$this->php_ext" ? ext::INDEX_ONLY : $this->request->variable('f', 0);
+ }
+
+ return $this->location;
+ }
+
+ /**
+ * Is the current location not in the announcement's array of allowed locations?
+ *
+ * @param array|string $locations An array of locations
+ * @return bool
+ */
+ protected function location_not_in($locations)
+ {
+ return !in_array($this->get_current_location(), $locations);
+ }
+
+ /**
+ * Is the current page a password protected forum?
+ *
+ * @return bool
+ */
+ protected function is_protected()
+ {
+ if (!isset($this->protected_forums))
+ {
+ $this->protected_forums = $this->user->get_passworded_forums();
+ }
+
+ return $this->get_current_location() > 0 && !empty($this->protected_forums) && in_array($this->get_current_location(), $this->protected_forums);
+ }
+
+ /**
+ * Is the current page a forum not accessible to the current user?
+ *
+ * @return bool
+ */
+ protected function no_permission()
+ {
+ if (!isset($this->permission))
+ {
+ $this->permission = $this->auth->acl_get('f_read', $this->get_current_location());
+ }
+
+ return $this->get_current_location() > 0 && !$this->permission;
+ }
}
diff --git a/ext.php b/ext.php
index 7d3c768..ad76b48 100644
--- a/ext.php
+++ b/ext.php
@@ -15,6 +15,7 @@
*/
class ext extends \phpbb\extension\base
{
+ public const INDEX_ONLY = -1;
public const ALL = 0;
public const MEMBERS = 1;
public const GUESTS = 2;
diff --git a/language/en/boardannouncements_acp.php b/language/en/boardannouncements_acp.php
index 93e4ef1..898f70c 100644
--- a/language/en/boardannouncements_acp.php
+++ b/language/en/boardannouncements_acp.php
@@ -43,22 +43,23 @@
'BOARD_ANNOUNCEMENTS_ENABLE_ALL' => 'Enable board announcements',
- 'BOARD_ANNOUNCEMENTS_OPTIONS' => 'Announcement options',
+ 'BOARD_ANNOUNCEMENTS_OPTIONS' => 'Board announcement options',
'BOARD_ANNOUNCEMENTS_DESC' => 'Description',
'BOARD_ANNOUNCEMENTS_DESC_EXPLAIN' => 'A short description for this announcement. This will only be visible here in the ACP to help identify this announcement.',
- 'BOARD_ANNOUNCEMENTS_ENABLE' => 'Display this board announcement',
- 'BOARD_ANNOUNCEMENTS_INDEX_ONLY' => 'Display on board index only',
- 'BOARD_ANNOUNCEMENTS_USERS' => 'Who can view this board announcement',
- 'BOARD_ANNOUNCEMENTS_DISMISS' => 'Allow users to dismiss this board announcement',
+ 'BOARD_ANNOUNCEMENTS_ENABLE' => 'Display this announcement',
+ 'BOARD_ANNOUNCEMENTS_USERS' => 'Who can view this announcement',
+ 'BOARD_ANNOUNCEMENTS_DISMISS' => 'Allow users to dismiss this announcement',
+ 'BOARD_ANNOUNCEMENTS_LOCATIONS' => 'Limit where this announcement should be displayed',
+ 'BOARD_ANNOUNCEMENTS_LOCATIONS_EXPLAIN' => 'Select one or more locations to display the announcement. To display it everywhere, leave the selection empty. Use Command (Mac) or Control (Windows) click to select multiple locations.',
'BOARD_ANNOUNCEMENTS_EVERYONE' => 'Everyone',
- 'BOARD_ANNOUNCEMENTS_BGCOLOR' => 'Board announcement background color',
+ 'BOARD_ANNOUNCEMENTS_BGCOLOR' => 'Background color',
'BOARD_ANNOUNCEMENTS_BGCOLOR_EXPLAIN' => 'You can change the background color of the announcement using a hex code (e.g: FFFF80). Leave this field blank to use the default color.',
- 'BOARD_ANNOUNCEMENTS_EXPIRY' => 'Board announcement expiration date',
+ 'BOARD_ANNOUNCEMENTS_EXPIRY' => 'Expiration date',
'BOARD_ANNOUNCEMENTS_EXPIRY_EXPLAIN' => 'Set the date the announcement will expire and become disabled. Leave this field blank if you do not want the announcement to expire.',
'BOARD_ANNOUNCEMENTS_EXPIRY_INVALID' => 'The expiration date was invalid or has already expired.',
@@ -77,6 +78,8 @@
'BOARD_ANNOUNCEMENTS_TH_EXPIRED' => 'Expired',
'BOARD_ANNOUNCEMENTS_EVERYWHERE' => 'Everywhere',
+ 'BOARD_ANNOUNCEMENTS_INDEX_PAGE' => 'Board Index',
+ 'BOARD_ANNOUNCEMENTS_FORUMS' => 'Selected Forums',
'BOARD_ANNOUNCEMENTS_EMPTY' => 'There are no board announcements to display',
'BOARD_ANNOUNCEMENTS_ADD' => 'Create Announcement',
diff --git a/manager/manager.php b/manager/manager.php
index 267d8d4..d34f2c3 100644
--- a/manager/manager.php
+++ b/manager/manager.php
@@ -189,6 +189,18 @@ public function close_announcement($id, $user_id)
return (bool) $this->nestedset->insert_tracked_item($id, ['user_id' => (int) $user_id]);
}
+ /**
+ * Decode JSON data
+ *
+ * @param string $data
+ * @return mixed decoded json data or original data if not valid json
+ */
+ public function decode_json($data)
+ {
+ $result = json_decode($data, true);
+ return json_last_error() === JSON_ERROR_NONE ? $result : $data;
+ }
+
/**
* Filter members only announcements
*
@@ -245,7 +257,7 @@ public function announcement_columns()
'announcement_description' => '',
'announcement_bgcolor' => '',
'announcement_enabled' => true,
- 'announcement_indexonly' => false,
+ 'announcement_locations' => '',
'announcement_dismissable' => true,
'announcement_users' => \phpbb\boardannouncements\ext::ALL,
'announcement_timestamp' => 0,
diff --git a/migrations/v10x/m12_locations.php b/migrations/v10x/m12_locations.php
new file mode 100644
index 0000000..7c0c978
--- /dev/null
+++ b/migrations/v10x/m12_locations.php
@@ -0,0 +1,65 @@
+
+ * @license GNU General Public License, version 2 (GPL-2.0)
+ *
+ */
+
+namespace phpbb\boardannouncements\migrations\v10x;
+
+/**
+ * Migration stage 12: Add option for locations where announcement can be displayed
+ */
+class m12_locations extends \phpbb\db\migration\migration
+{
+ /**
+ * {@inheritdoc}
+ */
+ public static function depends_on()
+ {
+ return [
+ '\phpbb\boardannouncements\migrations\v10x\m9_schema_update',
+ '\phpbb\boardannouncements\migrations\v10x\m10_update_data',
+ '\phpbb\boardannouncements\migrations\v10x\m11_schema_removal',
+ ];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function effectively_installed()
+ {
+ return $this->db_tools->sql_column_exists($this->table_prefix . 'board_announcements', 'announcement_locations');
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function update_schema()
+ {
+ return [
+ 'add_columns' => [
+ $this->table_prefix . 'board_announcements' => [
+ 'announcement_locations' => ['TEXT', ''],
+ ],
+ ],
+ ];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function revert_schema()
+ {
+ return [
+ 'drop_columns' => [
+ $this->table_prefix . 'board_announcements' => [
+ 'announcement_locations',
+ ],
+ ],
+ ];
+ }
+}
diff --git a/migrations/v10x/m13_locations_data.php b/migrations/v10x/m13_locations_data.php
new file mode 100644
index 0000000..5413322
--- /dev/null
+++ b/migrations/v10x/m13_locations_data.php
@@ -0,0 +1,103 @@
+
+ * @license GNU General Public License, version 2 (GPL-2.0)
+ *
+ */
+
+namespace phpbb\boardannouncements\migrations\v10x;
+
+use phpbb\boardannouncements\ext;
+use phpbb\boardannouncements\manager\nestedset;
+
+/**
+ * Migration stage 13: Migrate existing index only data to location data
+ */
+class m13_locations_data extends \phpbb\db\migration\container_aware_migration
+{
+ /**
+ * {@inheritdoc}
+ */
+ public static function depends_on()
+ {
+ return [
+ '\phpbb\boardannouncements\migrations\v10x\m12_locations',
+ ];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function effectively_installed()
+ {
+ $sql = 'SELECT announcement_id
+ FROM ' . $this->table_prefix . "board_announcements
+ WHERE announcement_locations != ''";
+ $result = $this->db->sql_query_limit($sql, 1);
+ $row = $this->db->sql_fetchrow($result);
+ $this->db->sql_freeresult($result);
+
+ return $row !== false;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function update_data()
+ {
+ return [
+ ['custom', [[$this, 'copy_locations']]],
+ ];
+ }
+
+ /**
+ * Copy values of announcement_indexonly to announcement_locations
+ * for existing announcements. New values should be -1 for index only,
+ * empty string for everywhere (all other integers will be for forums).
+ *
+ * @return void
+ */
+ public function copy_locations()
+ {
+ $sql = 'SELECT announcement_id, announcement_indexonly
+ FROM ' . $this->table_prefix . 'board_announcements';
+ $result = $this->db->sql_query($sql);
+ $rows = $this->db->sql_fetchrowset($result);
+ $this->db->sql_freeresult($result);
+
+ if (!empty($rows))
+ {
+ $this->db->sql_transaction('begin');
+
+ foreach ($rows as $row)
+ {
+ $this->get_nestedset()->update_item($row['announcement_id'], [
+ 'announcement_locations' => $row['announcement_indexonly'] ? json_encode([ext::INDEX_ONLY]) : ''
+ ]);
+ }
+
+ $this->db->sql_transaction('commit');
+ }
+ }
+
+ /**
+ * Get the board announcements nested set object
+ *
+ * @return nestedset
+ */
+ protected function get_nestedset()
+ {
+ /** @var \phpbb\db\driver\driver_interface $db */
+ $db = $this->container->get('dbal.conn');
+
+ return new nestedset(
+ $db,
+ new \phpbb\lock\db('boardannouncements.table_lock.board_announcements_table', $this->config, $db),
+ $this->table_prefix . 'board_announcements',
+ $this->table_prefix . 'board_announcements_track'
+ );
+ }
+}
diff --git a/migrations/v10x/m14_schema_removal.php b/migrations/v10x/m14_schema_removal.php
new file mode 100644
index 0000000..2ea1bf3
--- /dev/null
+++ b/migrations/v10x/m14_schema_removal.php
@@ -0,0 +1,64 @@
+
+ * @license GNU General Public License, version 2 (GPL-2.0)
+ *
+ */
+
+namespace phpbb\boardannouncements\migrations\v10x;
+
+/**
+ * Migration stage 14: Remove old board announcement schema from tables
+ */
+class m14_schema_removal extends \phpbb\db\migration\migration
+{
+ /**
+ * {@inheritdoc}
+ */
+ public static function depends_on()
+ {
+ return [
+ '\phpbb\boardannouncements\migrations\v10x\m12_locations',
+ '\phpbb\boardannouncements\migrations\v10x\m13_locations_data',
+ ];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function effectively_installed()
+ {
+ return !$this->db_tools->sql_column_exists($this->table_prefix . 'board_announcements', 'announcement_indexonly');
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function update_schema()
+ {
+ return [
+ 'drop_columns' => [
+ $this->table_prefix . 'board_announcements' => [
+ 'announcement_indexonly',
+ ],
+ ],
+ ];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function revert_schema()
+ {
+ return [
+ 'add_columns' => [
+ $this->table_prefix . 'board_announcements' => [
+ 'announcement_indexonly' => ['VCHAR:255', ''],
+ ],
+ ],
+ ];
+ }
+}
diff --git a/tests/controller/acp_controller_test.php b/tests/controller/acp_controller_test.php
index 4acf60d..1ce3ea1 100644
--- a/tests/controller/acp_controller_test.php
+++ b/tests/controller/acp_controller_test.php
@@ -198,7 +198,7 @@ public function test_list_announcements()
'announcement_enabled' => 1,
'announcement_timestamp' => 734284394,
'announcement_expiry' => 0,
- 'announcement_indexonly' => 0,
+ 'announcement_locations' => '',
'announcement_users' => 0,
],
[
@@ -207,7 +207,7 @@ public function test_list_announcements()
'announcement_enabled' => 1,
'announcement_timestamp' => 797442794,
'announcement_expiry' => 0,
- 'announcement_indexonly' => 0,
+ 'announcement_locations' => '[-1,1]',
'announcement_users' => 0,
],
[
@@ -216,7 +216,7 @@ public function test_list_announcements()
'announcement_enabled' => 1,
'announcement_timestamp' => 681493994,
'announcement_expiry' => 1644162794,
- 'announcement_indexonly' => 0,
+ 'announcement_locations' => '[]',
'announcement_users' => 0,
],
];
@@ -262,7 +262,7 @@ public function action_add_data()
'announcement_description' => 'Announcement 1',
'announcement_bgcolor' => '',
'announcement_enabled' => true,
- 'announcement_indexonly' => false,
+ 'announcement_locations' => '',
'announcement_dismissable' => true,
'announcement_users' => \phpbb\boardannouncements\ext::ALL,
'announcement_timestamp' => '',
@@ -277,7 +277,7 @@ public function action_add_data()
'announcement_description' => 'Announcement 2',
'announcement_bgcolor' => '',
'announcement_enabled' => true,
- 'announcement_indexonly' => false,
+ 'announcement_locations' => '',
'announcement_dismissable' => true,
'announcement_users' => \phpbb\boardannouncements\ext::ALL,
'announcement_timestamp' => '',
@@ -321,7 +321,7 @@ public function test_action_add($id, $data)
'announcement_description' => '',
'announcement_bgcolor' => '',
'announcement_enabled' => true,
- 'announcement_indexonly' => false,
+ 'announcement_locations' => '',
'announcement_dismissable' => true,
'announcement_users' => \phpbb\boardannouncements\ext::ALL,
'announcement_timestamp' => 0,
@@ -350,15 +350,15 @@ public function test_action_add($id, $data)
public function action_add_submit_data()
{
return [
- [0, ['add', 0, 'Announcement Text 0', 'Announcement Description 0', 'ffffff', true, 0, false, true, '', false, false, false], false, true, true, false], // submit
- [1, ['add', 1, 'Announcement Text 1', 'Announcement Description 1', 'ffffff', true, 0, false, true, '', false, false, false], false, true, true, false], // submit
- [0, ['add', 0, 'Announcement Text 0', 'Announcement Description 0', 'ffffff', true, 0, false, true, '', false, false, false], false, true, false, true], // submit, bad form
- [0, ['add', 0, '', 'Announcement Description 0', 'ffffff', true, 0, false, true, '', false, false, false], false, true, true, true], // submit, bad text
- [0, ['add', 0, 'Announcement Text 0', 'Announcement Description 0', 'ffffff', true, 0, false, true, 'foo', false, false, false], false, true, true, true], // submit, bad expiry
- [0, ['add', 0, 'Announcement Text 0', 'Announcement Description 0', 'ffffff', true, 0, false, true, '', false, false, false], true, false, true, null], // preview
- [0, ['add', 0, 'Announcement Text 0', 'Announcement Description 0', 'ffffff', true, 0, false, true, '', false, false, false], true, false, false, null], // preview, bad form
- [1, ['add', 1, 'Announcement Text 1', 'Announcement Description 1', 'ffffff', true, 0, false, true, '', false, false, false], true, false, true, null], // preview
- [1, ['add', 1, 'Announcement Text 1', 'Announcement Description 1', 'ffffff', true, 0, false, true, '', false, false, false], true, false, false, null], // preview, bad form
+ [0, ['add', 0, 'Announcement Text 0', 'Announcement Description 0', 'ffffff', true, 0, [''], true, '', false, false, false], false, true, true, false], // submit
+ [1, ['add', 1, 'Announcement Text 1', 'Announcement Description 1', 'ffffff', true, 0, [''], true, '', false, false, false], false, true, true, false], // submit
+ [0, ['add', 0, 'Announcement Text 0', 'Announcement Description 0', 'ffffff', true, 0, [''], true, '', false, false, false], false, true, false, true], // submit, bad form
+ [0, ['add', 0, '', 'Announcement Description 0', 'ffffff', true, 0, [''], true, '', false, false, false], false, true, true, true], // submit, bad text
+ [0, ['add', 0, 'Announcement Text 0', 'Announcement Description 0', 'ffffff', true, 0, [''], true, 'foo', false, false, false], false, true, true, true], // submit, bad expiry
+ [0, ['add', 0, 'Announcement Text 0', 'Announcement Description 0', 'ffffff', true, 0, [''], true, '', false, false, false], true, false, true, null], // preview
+ [0, ['add', 0, 'Announcement Text 0', 'Announcement Description 0', 'ffffff', true, 0, [''], true, '', false, false, false], true, false, false, null], // preview, bad form
+ [1, ['add', 1, 'Announcement Text 1', 'Announcement Description 1', 'ffffff', true, 0, [''], true, '', false, false, false], true, false, true, null], // preview
+ [1, ['add', 1, 'Announcement Text 1', 'Announcement Description 1', 'ffffff', true, 0, [''], true, '', false, false, false], true, false, false, null], // preview, bad form
];
}
@@ -397,7 +397,7 @@ public function test_action_add_submit($id, $form, $preview, $submit, $valid_for
['board_announcements_bgcolor', ''],
['board_announcements_enabled', true],
['board_announcements_users', 0],
- ['board_announcements_index_only', false],
+ ['board_announcements_locations', [0]],
['board_announcements_dismiss', true],
['board_announcements_expiry', ''],
['disable_bbcode', false],
@@ -412,6 +412,10 @@ public function test_action_add_submit($id, $form, $preview, $submit, $valid_for
->withConsecutive(['submit'], ['preview'])
->willReturnOnConsecutiveCalls($submit, $preview);
+ $this->manager->expects($submit && !$errors ? self::never() : self::once())
+ ->method('decode_json')
+ ->willReturn([]);
+
$this->manager->expects(self::once())
->method('announcement_columns')
->willReturn([]);
@@ -673,3 +677,11 @@ function display_custom_bbcodes()
function build_select()
{
}
+
+/**
+ * Mock make_forum_select()
+ * Note: use the same namespace as the acp_controller
+ */
+function make_forum_select()
+{
+}
diff --git a/tests/event/listener_test.php b/tests/event/listener_test.php
index dac9212..b666267 100644
--- a/tests/event/listener_test.php
+++ b/tests/event/listener_test.php
@@ -26,6 +26,9 @@ protected static function setup_extensions()
/** @var \phpbb\boardannouncements\event\listener */
protected $listener;
+ /** @var \phpbb_mock_notifications_auth */
+ protected $auth;
+
/** @var \phpbb\config\config */
protected $config;
@@ -128,6 +131,7 @@ protected function set_listener()
{
$this->listener = new \phpbb\boardannouncements\event\listener(
$this->manager,
+ $this->auth,
$this->config,
$this->controller_helper,
$this->language,
@@ -250,6 +254,13 @@ public function test_display_board_announcements($user_id, $page, $enabled, $exp
->method('assign_block_vars')
->withConsecutive(...$expected);
+ $this->request->expects(self::atMost(10))
+ ->method('variable')
+ ->willReturnMap([
+ ['f', 0, false, \phpbb\request\request_interface::REQUEST, 0],
+ ['_ba_1', '', false, \phpbb\request\request_interface::COOKIE, ''],
+ ]);
+
$dispatcher = new \phpbb\event\dispatcher();
$dispatcher->addListener('core.page_header_after', [$this->listener, 'display_board_announcements']);
$dispatcher->trigger_event('core.page_header_after');
diff --git a/tests/fixtures/board_announcements.xml b/tests/fixtures/board_announcements.xml
index d6488b2..c9fe2c2 100644
--- a/tests/fixtures/board_announcements.xml
+++ b/tests/fixtures/board_announcements.xml
@@ -6,7 +6,7 @@
announcement_description
announcement_bgcolor
announcement_enabled
- announcement_indexonly
+ announcement_locations
announcement_dismissable
announcement_users
announcement_timestamp
@@ -24,7 +24,7 @@
ANNOUNCEMENT 1
1
- 1
+ [-1]
1
0
1586466410
@@ -43,7 +43,7 @@
ANNOUNCEMENT 2
ffffff
1
- 0
+
1
1
1586466510
@@ -62,7 +62,7 @@
ANNOUNCEMENT 3
000000
1
- 0
+
1
2
1586466610
@@ -81,7 +81,7 @@
ANNOUNCEMENT 4
1
- 0
+
0
0
1586466710
@@ -100,7 +100,7 @@
ANNOUNCEMENT 5
0
- 0
+ []
0
0
1586466810
diff --git a/tests/functional/announcement_test.php b/tests/functional/announcement_test.php
index 5b743cb..6aa00fc 100644
--- a/tests/functional/announcement_test.php
+++ b/tests/functional/announcement_test.php
@@ -10,6 +10,8 @@
namespace phpbb\boardannouncements\tests\functional;
+use phpbb\boardannouncements\ext;
+
/**
* @group functional
*/
@@ -54,30 +56,25 @@ public function test_set_acp_settings()
// Test that our settings fields are found
$this->assertContainsLang('BOARD_ANNOUNCEMENTS_ENABLE', $crawler->text());
- $this->assertContainsLang('BOARD_ANNOUNCEMENTS_INDEX_ONLY', $crawler->text());
$this->assertContainsLang('BOARD_ANNOUNCEMENTS_DISMISS', $crawler->text());
$this->assertContainsLang('BOARD_ANNOUNCEMENTS_USERS', $crawler->text());
+ $this->assertContainsLang('BOARD_ANNOUNCEMENTS_LOCATIONS', $crawler->text());
$this->assertContainsLang('BOARD_ANNOUNCEMENTS_DESC', $crawler->text());
$this->assertContainsLang('BOARD_ANNOUNCEMENTS_EXPIRY', $crawler->text());
$this->assertContainsLang('BOARD_ANNOUNCEMENTS_BGCOLOR', $crawler->text());
$this->assertContainsLang('BOARD_ANNOUNCEMENTS_TEXT', $crawler->text());
- // Set some form values
- $form = $crawler->selectButton($this->lang('SUBMIT'))->form();
$values = [
'board_announcements_enabled' => true,
- 'board_announcements_index_only' => true,
'board_announcements_users' => 0,
'board_announcements_dismiss' => true,
+ 'board_announcements_locations' => [ext::INDEX_ONLY],
'board_announcements_bgcolor' => 'ff0000',
'board_announcements_description' => 'Test announcement',
'board_announcements_text' => 'This is a board announcement test.',
];
- $form->setValues($values);
- // Submit form and test success
- $crawler = self::submit($form);
- $this->assertContainsLang('BOARD_ANNOUNCEMENTS_UPDATED', $crawler->text());
+ $this->create_announcement($values);
// Confirm the log entry has been added correctly
$crawler = self::request('GET', 'adm/index.php?i=acp_logs&mode=admin&sid=' . $this->sid);
@@ -184,6 +181,79 @@ public function test_acp_editing()
$this->assertContainsLang('BOARD_ANNOUNCEMENTS_EMPTY', $crawler->text());
}
+ /**
+ * Test announcements only show at locations where they are assigned
+ */
+ public function test_locations()
+ {
+ $this->login();
+ $this->admin_login();
+
+ // show everywhere
+ $everywhere_id = $this->create_announcement([
+ 'board_announcements_locations' => [],
+ 'board_announcements_description' => 'Everywhere announcement',
+ 'board_announcements_text' => 'Everywhere announcement',
+ ]);
+
+ // show index only
+ $index_id = $this->create_announcement([
+ 'board_announcements_locations' => [ext::INDEX_ONLY],
+ 'board_announcements_description' => 'Board index announcement',
+ 'board_announcements_text' => 'Board index announcement',
+ ]);
+
+ // show in forum 2 only
+ $forum_id = $this->create_announcement([
+ 'board_announcements_locations' => [2],
+ 'board_announcements_description' => 'Forum announcement',
+ 'board_announcements_text' => 'Forum announcement',
+ ]);
+
+ // show in forum 2 and index
+ $index_forum_id = $this->create_announcement([
+ 'board_announcements_locations' => [ext::INDEX_ONLY, 2],
+ 'board_announcements_description' => 'Forum and Index announcement',
+ 'board_announcements_text' => 'Forum and Index announcement',
+ ]);
+
+ // Test board index - see everywhere, index and index+forum
+ $crawler = self::request('GET', 'index.php?sid=' . $this->sid);
+ self::assertCount(1, $crawler->filter('#phpbb_announcement_' . $everywhere_id));
+ self::assertCount(1, $crawler->filter('#phpbb_announcement_' . $index_id));
+ self::assertCount(0, $crawler->filter('#phpbb_announcement_' . $forum_id));
+ self::assertCount(1, $crawler->filter('#phpbb_announcement_' . $index_forum_id));
+ self::assertStringContainsString('Everywhere announcement', $crawler->filter('#phpbb_announcement_' . $everywhere_id)->text());
+ self::assertStringContainsString('Board index announcement', $crawler->filter('#phpbb_announcement_' . $index_id)->text());
+ self::assertStringContainsString('Forum and Index announcement', $crawler->filter('#phpbb_announcement_' . $index_forum_id)->text());
+
+ // Test forum 2 page - see everywhere, forum and index+forum
+ $crawler = self::request('GET', 'viewforum.php?f=2&sid=' . $this->sid);
+ self::assertCount(1, $crawler->filter('#phpbb_announcement_' . $everywhere_id));
+ self::assertCount(0, $crawler->filter('#phpbb_announcement_' . $index_id));
+ self::assertCount(1, $crawler->filter('#phpbb_announcement_' . $forum_id));
+ self::assertCount(1, $crawler->filter('#phpbb_announcement_' . $index_forum_id));
+ self::assertStringContainsString('Everywhere announcement', $crawler->filter('#phpbb_announcement_' . $everywhere_id)->text());
+ self::assertStringContainsString('Forum announcement', $crawler->filter('#phpbb_announcement_' . $forum_id)->text());
+ self::assertStringContainsString('Forum and Index announcement', $crawler->filter('#phpbb_announcement_' . $index_forum_id)->text());
+
+ // Test forum 1 page - see everywhere
+ $crawler = self::request('GET', 'viewforum.php?f=1&sid=' . $this->sid);
+ self::assertCount(1, $crawler->filter('#phpbb_announcement_' . $everywhere_id));
+ self::assertCount(0, $crawler->filter('#phpbb_announcement_' . $index_id));
+ self::assertCount(0, $crawler->filter('#phpbb_announcement_' . $forum_id));
+ self::assertCount(0, $crawler->filter('#phpbb_announcement_' . $index_forum_id));
+ self::assertStringContainsString('Everywhere announcement', $crawler->filter('#phpbb_announcement_' . $everywhere_id)->text());
+
+ // Test FAQ page - see everywhere
+ $crawler = self::request('GET', 'viewonline.php?sid=' . $this->sid);
+ self::assertCount(1, $crawler->filter('#phpbb_announcement_' . $everywhere_id));
+ self::assertCount(0, $crawler->filter('#phpbb_announcement_' . $index_id));
+ self::assertCount(0, $crawler->filter('#phpbb_announcement_' . $forum_id));
+ self::assertCount(0, $crawler->filter('#phpbb_announcement_' . $index_forum_id));
+ self::assertStringContainsString('Everywhere announcement', $crawler->filter('#phpbb_announcement_' . $everywhere_id)->text());
+ }
+
/**
* Get the board announcements ACP page link to crawl
*
@@ -196,6 +266,40 @@ protected function get_acp_page($action = '', $id = 0)
return 'adm/index.php?i=\phpbb\boardannouncements\acp\board_announcements_module&mode=settings' . ($action ? "&action=$action" : '') . ($id ? "&id=$id" : '') . "&sid=$this->sid";
}
+ /**
+ * Create an announcement
+ *
+ * @param array $data
+ * @return int count of announcements created
+ */
+ protected function create_announcement($data)
+ {
+ static $counter = 0;
+
+ // Load Add page
+ $crawler = self::request('GET', $this->get_acp_page('add'));
+
+ // Set some form values
+ $form = $crawler->selectButton($this->lang('SUBMIT'))->form();
+ $values = array_merge([
+ 'board_announcements_enabled' => true,
+ 'board_announcements_dismiss' => false,
+ 'board_announcements_users' => 0,
+ 'board_announcements_locations' => [],
+ 'board_announcements_bgcolor' => 'ff0000',
+ 'board_announcements_expiry' => '',
+ 'board_announcements_description' => 'Test announcement',
+ 'board_announcements_text' => 'This is a board announcement test.',
+ ], $data);
+ $form->setValues($values);
+
+ // Submit form and test success
+ $crawler = self::submit($form);
+ $this->assertContainsLang('BOARD_ANNOUNCEMENTS_UPDATED', $crawler->text());
+
+ return ++$counter;
+ }
+
/**
* Create a link hash for the user 'admin'
*
diff --git a/tests/manager/manager_get_expired_announcements_test.php b/tests/manager/manager_get_expired_announcements_test.php
index d50f03d..bbf8603 100644
--- a/tests/manager/manager_get_expired_announcements_test.php
+++ b/tests/manager/manager_get_expired_announcements_test.php
@@ -29,7 +29,7 @@ public function data_get_expired_announcements()
'announcement_description' => 'ANNOUNCEMENT 4',
'announcement_bgcolor' => '',
'announcement_enabled' => 1,
- 'announcement_indexonly' => 0,
+ 'announcement_locations' => '',
'announcement_dismissable' => 0,
'announcement_users' => \phpbb\boardannouncements\ext::ALL,
'announcement_timestamp' => 1586466710,
diff --git a/tests/manager/manager_save_announcement_test.php b/tests/manager/manager_save_announcement_test.php
index 0e49a75..d09e5b7 100644
--- a/tests/manager/manager_save_announcement_test.php
+++ b/tests/manager/manager_save_announcement_test.php
@@ -25,7 +25,7 @@ public function data_save_announcement()
'announcement_description' => 'ANNOUNCEMENT 6',
'announcement_bgcolor' => '',
'announcement_enabled' => 1,
- 'announcement_indexonly' => 1,
+ 'announcement_locations' => json_encode([1,2,3]),
'announcement_dismissable' => 1,
'announcement_users' => 0,
'announcement_timestamp' => time(),
diff --git a/tests/manager/manager_update_announcement_test.php b/tests/manager/manager_update_announcement_test.php
index 5f86de9..bb2ddb5 100644
--- a/tests/manager/manager_update_announcement_test.php
+++ b/tests/manager/manager_update_announcement_test.php
@@ -25,7 +25,7 @@ public function data_update_announcement()
'announcement_description' => 'ANNOUNCEMENT 1 Updated',
'announcement_bgcolor' => 'cccccc',
'announcement_enabled' => 0,
- 'announcement_indexonly' => 0,
+ 'announcement_locations' => json_encode(''),
'announcement_dismissable' => 0,
'announcement_users' => 1,
'announcement_timestamp' => time(),
|