Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
609a6ba
Add notifications for Status change
iMattPro Aug 7, 2025
14f442a
Fix not sending notifications for subsequent status changes
iMattPro Aug 7, 2025
20ba328
Make available only for users with ideas forum access
iMattPro Aug 7, 2025
ebc5a88
Little fixes and housekeeping
iMattPro Aug 7, 2025
e7135a2
This is hacky, right?
iMattPro Aug 8, 2025
a391b47
Fix avatars
iMattPro Aug 8, 2025
30a4eaf
Fix language not showing in UCP
iMattPro Aug 8, 2025
c4e2967
Add email notification
iMattPro Aug 8, 2025
d8619ca
Fix exisiting tests
iMattPro Aug 8, 2025
8554876
Use a notification custom identifier
iMattPro Aug 8, 2025
0a0e5db
Rename lang key with better specificity
iMattPro Aug 8, 2025
3c8c3b6
Update some tests
iMattPro Aug 8, 2025
02e7faf
Add unit tests
iMattPro Aug 8, 2025
a90b2c7
Add functional testing of notification option
iMattPro Aug 9, 2025
470c45c
Absolutely over these damn view online tests failing whenever they wa…
iMattPro Aug 9, 2025
f26dcc9
Fix emails not going to users
iMattPro Aug 9, 2025
1401f62
House-keeping
iMattPro Aug 9, 2025
d853234
Fix the email link URL
iMattPro Aug 9, 2025
3e32cca
Get authorised users
iMattPro Aug 10, 2025
777d4f3
Complete test coverage
iMattPro Aug 10, 2025
a66fd1c
Query users for user_loader the way intended
iMattPro Aug 10, 2025
936bf7c
Refactor to follow interface more closely
iMattPro Aug 10, 2025
c088d1a
Refactor to use idea id so we can update/delete notifications
iMattPro Aug 10, 2025
fef66f0
Cache idea data loading during notifications
iMattPro Aug 11, 2025
5537380
Fixes and housekeeping
iMattPro Aug 12, 2025
9ba7e72
Reword the notifications and use the avatar of the status changer
iMattPro Aug 22, 2025
a1cb5e8
mention status in notification
iMattPro Aug 23, 2025
812b929
Check for existing notifications using the manager
iMattPro Aug 23, 2025
7b68523
Drop scrutinizer-ci
iMattPro Aug 23, 2025
9edb493
Move idea logic out of the notification type and back to idea factory
iMattPro Aug 24, 2025
3c65585
Further improve notification text layout
iMattPro Aug 24, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ The official Ideas Centre used at [phpBB.com](https://www.phpbb.com/ideas/). Thi

[![Build Status](https://github.com/phpbb/ideas/actions/workflows/tests.yml/badge.svg)](https://github.com/phpbb/ideas/actions)
[![codecov](https://codecov.io/gh/phpbb/ideas/graph/badge.svg?token=74AITS9CPZ)](https://codecov.io/gh/phpbb/ideas)
[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/phpbb/ideas/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/phpbb/ideas/?branch=master)

## Contribute

Expand Down
11 changes: 11 additions & 0 deletions config/services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ services:
- '@config'
- '@dbal.conn'
- '@language'
- '@notification_manager'
- '@user'
- '%tables.ideas_ideas%'
- '%tables.ideas_votes%'
Expand Down Expand Up @@ -122,3 +123,13 @@ services:
- [set_name, [cron.task.prune_orphaned_ideas]]
tags:
- { name: cron.task }

# ----- Notifications -----
phpbb.ideas.notification.type.status:
class: phpbb\ideas\notification\type\status
parent: notification.type.base
shared: false
calls:
- [set_additional_services, ['@config', '@controller.helper', '@user_loader']]
tags:
- { name: notification.type }
87 changes: 68 additions & 19 deletions ext.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@
namespace phpbb\ideas;

/**
* This ext class is optional and can be omitted if left empty.
* However, you can add special (un)installation commands in the
* methods enable_step(), disable_step() and purge_step(). As it is,
* these methods are defined in \phpbb\extension\base, which this
* class extends, but you can overwrite them to give special
* instructions for those cases.
*/
* This ext class is optional and can be omitted if left empty.
* However, you can add special (un)installation commands in the
* methods enable_step(), disable_step() and purge_step(). As it is,
* these methods are defined in \phpbb\extension\base, which this
* class extends, but you can overwrite them to give special
* instructions for those cases.
*/
class ext extends \phpbb\extension\base
{
public const SORT_AUTHOR = 'author';
Expand All @@ -30,44 +30,93 @@ class ext extends \phpbb\extension\base
public const SORT_MYIDEAS = 'egosearch';
public const SUBJECT_LENGTH = 120;
public const NUM_IDEAS = 5;
public const NOTIFICATION_TYPE_STATUS = 'phpbb.ideas.notification.type.status';

/** @var array Idea status names and IDs */
public static $statuses = array(
public static $statuses = [
'NEW' => 1,
'IN_PROGRESS' => 2,
'IMPLEMENTED' => 3,
'DUPLICATE' => 4,
'INVALID' => 5,
);
];

/** @var array Cached flipped statuses array */
private static $status_names;

/**
* Return the status name from the status ID.
*
* @param int $id ID of the status.
*
* @return string The status name.
* @static
* @access public
*/
public static function status_name($id)
{
return array_flip(self::$statuses)[$id];
if (self::$status_names === null)
{
self::$status_names = array_flip(self::$statuses);
}

return self::$status_names[$id];
}

/**
* Check whether the extension can be enabled.
*
* Requires phpBB >= 3.2.3 due to removal of deprecated Twig functions (ie Twig_SimpleFunction)
* Requires phpBB >= 3.3.0 due to use of PHP 7 features
* Requires PHP >= 7.1.0
* Requires PHP >= 7.2.0
*
* @return bool
* @access public
*/
public function is_enableable()
{
return !(PHP_VERSION_ID < 70100 ||
phpbb_version_compare(PHPBB_VERSION, '3.3.0', '<') ||
phpbb_version_compare(PHPBB_VERSION, '4.0.0-dev', '>='));
return PHP_VERSION_ID >= 70200
&& phpbb_version_compare(PHPBB_VERSION, '3.3.0', '>=')
&& phpbb_version_compare(PHPBB_VERSION, '4.0.0-dev', '<');
}

/**
* Handle notification management for extension lifecycle
*
* @param string $method The notification manager method to call
* @return string
*/
private function handle_notifications($method)
{
$this->container->get('notification_manager')->$method(self::NOTIFICATION_TYPE_STATUS);
return 'notification';
}

/**
* Enable notifications for the extension
*
* @param mixed $old_state
* @return bool|string
*/
public function enable_step($old_state)
{
return $old_state === false ? $this->handle_notifications('enable_notifications') : parent::enable_step($old_state);
}

/**
* Disable notifications for the extension
*
* @param mixed $old_state
* @return bool|string
*/
public function disable_step($old_state)
{
return $old_state === false ? $this->handle_notifications('disable_notifications') : parent::disable_step($old_state);
}

/**
* Purge notifications for the extension
*
* @param mixed $old_state
* @return bool|string
*/
public function purge_step($old_state)
{
return $old_state === false ? $this->handle_notifications('purge_notifications') : parent::purge_step($old_state);
}
}
24 changes: 15 additions & 9 deletions factory/base.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use phpbb\config\config;
use phpbb\db\driver\driver_interface;
use phpbb\language\language;
use phpbb\notification\manager as notification_manager;
use phpbb\user;

/**
Expand All @@ -33,6 +34,9 @@ class base
/** @var language */
protected $language;

/** @var notification_manager */
protected $notification_manager;

/* @var user */
protected $user;

Expand All @@ -51,22 +55,24 @@ class base
/**
* Constructor
*
* @param auth $auth
* @param config $config
* @param auth $auth
* @param config $config
* @param driver_interface $db
* @param language $language
* @param user $user
* @param string $table_ideas
* @param string $table_votes
* @param string $table_topics
* @param string $phpEx
* @param language $language
* @param notification_manager $notification_manager
* @param user $user
* @param string $table_ideas
* @param string $table_votes
* @param string $table_topics
* @param string $phpEx
*/
public function __construct(auth $auth, config $config, driver_interface $db, language $language, user $user, $table_ideas, $table_votes, $table_topics, $phpEx)
public function __construct(auth $auth, config $config, driver_interface $db, language $language, notification_manager $notification_manager, user $user, $table_ideas, $table_votes, $table_topics, $phpEx)
{
$this->auth = $auth;
$this->config = $config;
$this->db = $db;
$this->language = $language;
$this->notification_manager = $notification_manager;
$this->user = $user;

$this->php_ext = $phpEx;
Expand Down
24 changes: 22 additions & 2 deletions factory/idea.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,20 @@ public function set_status($idea_id, $status)
);

$this->update_idea_data($sql_ary, $idea_id, $this->table_ideas);

// Send a notification
$idea = $this->get_idea($idea_id);
$notifications = $this->notification_manager->get_notified_users(ext::NOTIFICATION_TYPE_STATUS, ['item_id' => (int) $idea_id]);
$this->notification_manager->{empty($notifications) ? 'add_notifications' : 'update_notifications'}(
ext::NOTIFICATION_TYPE_STATUS,
[
'idea_id' => (int) $idea_id,
'status' => (int) $status,
'user_id' => (int) $this->user->data['user_id'],
'idea_author' => (int) $idea['idea_author'],
'idea_title' => $idea['idea_title'],
]
);
}

/**
Expand Down Expand Up @@ -262,8 +276,14 @@ public function delete($id, $topic_id = 0)
// Delete idea
$deleted = $this->delete_idea_data($id, $this->table_ideas);

// Delete votes
$this->delete_idea_data($id, $this->table_votes);
if ($deleted)
{
// Delete votes
$this->delete_idea_data($id, $this->table_votes);

// Delete notifications
$this->notification_manager->delete_notifications(ext::NOTIFICATION_TYPE_STATUS, $id);
}

return $deleted;
}
Expand Down
2 changes: 2 additions & 0 deletions language/en/common.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
'IDEA_DELETED' => 'Idea successfully deleted.',
'IDEA_LIST' => 'Idea List',
'IDEA_NOT_FOUND' => 'Idea not found',
'IDEA_STATUS_CHANGE' => '<strong>Idea status changed</strong> by %s:',
'IDEA_STORED_MOD' => 'Your idea has been submitted successfully, but it will need to be approved by a moderator before it is publicly viewable. You will be notified when your idea has been approved.<br /><br /><a href="%s">Return to Ideas</a>.',
'IDEAS_TITLE' => 'phpBB Ideas',
'IDEAS_NOT_AVAILABLE' => 'Ideas is not available at this time.',
Expand Down Expand Up @@ -66,6 +67,7 @@
'NEW' => 'New',
'NEW_IDEA' => 'New Idea',
'NO_IDEAS_DISPLAY' => 'There are no ideas to display.',
'NOTIFICATION_STATUS' => '<em>Status: <strong>%s</strong></em>',

'OPEN_IDEAS' => 'Open ideas',

Expand Down
10 changes: 10 additions & 0 deletions language/en/email/status_notification.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Subject: Idea status - "{IDEA_TITLE}"

Hello {USERNAME},

The status of your Idea topic "{IDEA_TITLE}" at "{SITENAME}" has been updated by {UPDATED_BY} to {STATUS}.

If you want to view the Idea, click the following link:
{U_VIEW_IDEA}

{EMAIL_SIG}
39 changes: 39 additions & 0 deletions language/en/info_ucp_ideas.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php
/**
*
* Ideas extension for the phpBB Forum Software package.
*
* @copyright (c) phpBB Limited <https://www.phpbb.com>
* @license GNU General Public License, version 2 (GPL-2.0)
*
*/

if (!defined('IN_PHPBB'))
{
exit;
}

if (empty($lang) || !is_array($lang))
{
$lang = [];
}

// DEVELOPERS PLEASE NOTE
//
// All language files should use UTF-8 as their encoding and the files must not contain a BOM.
//
// Placeholders can now contain order information, e.g. instead of
// 'Page %s of %s' you can (and should) write 'Page %1$s of %2$s', this allows
// translators to re-order the output of data while ensuring it remains correct
//
// You do not need this where single placeholders are used, e.g. 'Message %d' is fine
// equally where a string contains only two placeholders which are used to wrap text
// in a url you again do not need to specify an order e.g., 'Click %sHERE%s' is fine
//
// Some characters you may want to copy&paste:
// ’ » “ ” …
//

$lang = array_merge($lang, [
'NOTIFICATION_TYPE_IDEAS' => 'Your Idea in the Ideas forum has a status change',
]);
Loading
Loading