mirror of
https://github.com/phpbb/phpbb.git
synced 2025-06-28 06:08:52 +00:00
[ticket/11103] The start of an all-encompassing notifications system
This system will take input from various systems to store notifications and send notifications to users all in one nice extendable system. This system should act something like the notifications system on other social networking sites (in that, there is a single location where a user can see all of their notifications for various events). PHPBB3-11103
This commit is contained in:
parent
7bf598954c
commit
b887fcc3d1
9 changed files with 530 additions and 0 deletions
|
@ -89,6 +89,11 @@ services:
|
||||||
- .%core.php_ext%
|
- .%core.php_ext%
|
||||||
- @cache.driver
|
- @cache.driver
|
||||||
|
|
||||||
|
notifications:
|
||||||
|
class: phpbb_notifications_service
|
||||||
|
arguments:
|
||||||
|
- @container
|
||||||
|
|
||||||
processor.config:
|
processor.config:
|
||||||
class: phpbb_di_processor_ext
|
class: phpbb_di_processor_ext
|
||||||
arguments:
|
arguments:
|
||||||
|
|
|
@ -239,6 +239,7 @@ define('LOG_TABLE', $table_prefix . 'log');
|
||||||
define('LOGIN_ATTEMPT_TABLE', $table_prefix . 'login_attempts');
|
define('LOGIN_ATTEMPT_TABLE', $table_prefix . 'login_attempts');
|
||||||
define('MODERATOR_CACHE_TABLE', $table_prefix . 'moderator_cache');
|
define('MODERATOR_CACHE_TABLE', $table_prefix . 'moderator_cache');
|
||||||
define('MODULES_TABLE', $table_prefix . 'modules');
|
define('MODULES_TABLE', $table_prefix . 'modules');
|
||||||
|
define('NOTIFICATIONS_TABLE', $table_prefix . 'notifications');
|
||||||
define('POLL_OPTIONS_TABLE', $table_prefix . 'poll_options');
|
define('POLL_OPTIONS_TABLE', $table_prefix . 'poll_options');
|
||||||
define('POLL_VOTES_TABLE', $table_prefix . 'poll_votes');
|
define('POLL_VOTES_TABLE', $table_prefix . 'poll_votes');
|
||||||
define('POSTS_TABLE', $table_prefix . 'posts');
|
define('POSTS_TABLE', $table_prefix . 'posts');
|
||||||
|
|
51
phpBB/includes/notifications/method/base.php
Normal file
51
phpBB/includes/notifications/method/base.php
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @package notifications
|
||||||
|
* @copyright (c) 2012 phpBB Group
|
||||||
|
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ignore
|
||||||
|
*/
|
||||||
|
if (!defined('IN_PHPBB'))
|
||||||
|
{
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base notifications method class
|
||||||
|
* @package notifications
|
||||||
|
*/
|
||||||
|
abstract class phpbb_notifications_method_base implements phpbb_notifications_method_interface
|
||||||
|
{
|
||||||
|
protected $phpbb_container;
|
||||||
|
protected $db;
|
||||||
|
protected $user;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* notification_id
|
||||||
|
* item_type
|
||||||
|
* item_id
|
||||||
|
*
|
||||||
|
* by_user_id (one who caused the notification)
|
||||||
|
* user_id
|
||||||
|
* time
|
||||||
|
* unread
|
||||||
|
*
|
||||||
|
* data (special serialized field that each notification type can use to store stuff)
|
||||||
|
*/
|
||||||
|
protected $data = array();
|
||||||
|
|
||||||
|
public function __construct(Symfony\Component\DependencyInjection\ContainerBuilder $phpbb_container, $data = array())
|
||||||
|
{
|
||||||
|
// phpBB Container
|
||||||
|
$this->phpbb_container = $phpbb_container;
|
||||||
|
|
||||||
|
// Some common things we're going to use
|
||||||
|
$this->db = $phpbb_container->get('dbal.conn');
|
||||||
|
$this->user = $phpbb_container->get('user');
|
||||||
|
}
|
||||||
|
}
|
28
phpBB/includes/notifications/method/email.php
Normal file
28
phpBB/includes/notifications/method/email.php
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @package notifications
|
||||||
|
* @copyright (c) 2012 phpBB Group
|
||||||
|
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ignore
|
||||||
|
*/
|
||||||
|
if (!defined('IN_PHPBB'))
|
||||||
|
{
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Email notification method class
|
||||||
|
* @package notifications
|
||||||
|
*/
|
||||||
|
class phpbb_notifications_method_email extends phpbb_notifications_method_base
|
||||||
|
{
|
||||||
|
function notify()
|
||||||
|
{
|
||||||
|
// email the user
|
||||||
|
}
|
||||||
|
}
|
24
phpBB/includes/notifications/method/interface.php
Normal file
24
phpBB/includes/notifications/method/interface.php
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @package notifications
|
||||||
|
* @copyright (c) 2012 phpBB Group
|
||||||
|
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ignore
|
||||||
|
*/
|
||||||
|
if (!defined('IN_PHPBB'))
|
||||||
|
{
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base notifications method interface
|
||||||
|
* @package notifications
|
||||||
|
*/
|
||||||
|
interface phpbb_notifications_method_interface
|
||||||
|
{
|
||||||
|
}
|
197
phpBB/includes/notifications/service.php
Normal file
197
phpBB/includes/notifications/service.php
Normal file
|
@ -0,0 +1,197 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @package notifications
|
||||||
|
* @copyright (c) 2012 phpBB Group
|
||||||
|
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ignore
|
||||||
|
*/
|
||||||
|
if (!defined('IN_PHPBB'))
|
||||||
|
{
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notifications service class
|
||||||
|
* @package notifications
|
||||||
|
*/
|
||||||
|
class phpbb_notifications_service
|
||||||
|
{
|
||||||
|
protected $phpbb_container;
|
||||||
|
protected $db;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Users loaded from the DB
|
||||||
|
*
|
||||||
|
* @var array Array of user data that we've loaded from the DB
|
||||||
|
*/
|
||||||
|
protected $users;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Desired notifications
|
||||||
|
* unique by (type, type_id, user_id, method)
|
||||||
|
* if multiple methods are desired, multiple rows will exist.
|
||||||
|
*
|
||||||
|
* method of "none" will over-ride any other options
|
||||||
|
*
|
||||||
|
* type
|
||||||
|
* type_id
|
||||||
|
* user_id
|
||||||
|
* method
|
||||||
|
* none (will never receive notifications)
|
||||||
|
* standard (listed in notifications window
|
||||||
|
* popup?
|
||||||
|
* email
|
||||||
|
* jabber
|
||||||
|
* sms?
|
||||||
|
*/
|
||||||
|
|
||||||
|
public function __construct(Symfony\Component\DependencyInjection\ContainerBuilder $phpbb_container)
|
||||||
|
{
|
||||||
|
$this->phpbb_container = $phpbb_container;
|
||||||
|
|
||||||
|
// Some common things we're going to use
|
||||||
|
$this->db = $phpbb_container->get('dbal.conn');
|
||||||
|
}
|
||||||
|
|
||||||
|
private function get_type_class_name(&$type, $safe = false)
|
||||||
|
{
|
||||||
|
if (!$safe)
|
||||||
|
{
|
||||||
|
$type = preg_replace('#[^a-z]#', '', $type);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'phpbb_notifications_type_' . $type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load the user's notifications
|
||||||
|
*
|
||||||
|
* @param array $options Optional options to control what notifications are loaded
|
||||||
|
* user_id User id to load notifications for (Default: $user->data['user_id'])
|
||||||
|
* limit Number of notifications to load (Default: 5)
|
||||||
|
* start Notifications offset (Default: 0)
|
||||||
|
*/
|
||||||
|
public function load_notifications($options = array())
|
||||||
|
{
|
||||||
|
$user = $this->phpbb_container->get('user');
|
||||||
|
|
||||||
|
// Merge default options
|
||||||
|
$options = array_merge(array(
|
||||||
|
'user_id' => $user->data['user_id'],
|
||||||
|
'limit' => 5,
|
||||||
|
'start' => 0,
|
||||||
|
), $options);
|
||||||
|
|
||||||
|
$notifications = $user_ids = array();
|
||||||
|
|
||||||
|
$sql = 'SELECT * FROM ' . NOTIFICATIONS_TABLE . '
|
||||||
|
WHERE user_id = ' . (int) $options['user_id'];
|
||||||
|
$result = $this->db->sql_query_limit($sql, $options['limit'], $options['start']);
|
||||||
|
|
||||||
|
while ($row = $this->db->sql_fetchrow($result))
|
||||||
|
{
|
||||||
|
$type_class_name = $this->get_type_class_name($row['type'], true);
|
||||||
|
|
||||||
|
$notification = new $type_class_name($this->phpbb_container, $row);
|
||||||
|
$notification->users($this->users);
|
||||||
|
|
||||||
|
$user_ids = array_merge($user_ids, $notification->users_to_query());
|
||||||
|
|
||||||
|
$notifications[] = $notification();
|
||||||
|
}
|
||||||
|
$this->db->sql_freeresult($result);
|
||||||
|
|
||||||
|
// Load the users
|
||||||
|
$user_ids = array_unique($user_ids);
|
||||||
|
|
||||||
|
// @todo do not load users we already have in $this->users
|
||||||
|
|
||||||
|
if (sizeof($user_ids))
|
||||||
|
{
|
||||||
|
// @todo do not select everything
|
||||||
|
$sql = 'SELECT * FROM ' . USERS_TABLE . '
|
||||||
|
WHERE ' . $this->db->sql_in_set('user_id', $user_ids);
|
||||||
|
$result = $this->db->sql_query($sql);
|
||||||
|
|
||||||
|
while ($row = $this->db->sql_fetchrow($result))
|
||||||
|
{
|
||||||
|
$this->users[$row['user_id']] = $row;
|
||||||
|
}
|
||||||
|
$this->db->sql_freeresult($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $notifications;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function add_notifications($type, $data)
|
||||||
|
{
|
||||||
|
$type_class_name = $this->get_type_class_name($type);
|
||||||
|
|
||||||
|
$notification_objects = array(); // 'user_id' => object
|
||||||
|
$methods = $new_rows = array();
|
||||||
|
|
||||||
|
// find out which users want to receive this type of notification
|
||||||
|
$sql = 'SELECT user_id FROM ' . USERS_TABLE . '
|
||||||
|
WHERE ' . $this->db->sql_in_set('user_id', array(2));
|
||||||
|
$result = $this->db->sql_query($sql);
|
||||||
|
|
||||||
|
while ($row = $this->db->sql_fetchrow($result))
|
||||||
|
{
|
||||||
|
$row['method'] = '';
|
||||||
|
|
||||||
|
$notification = new $type_class_name($this->phpbb_container);
|
||||||
|
|
||||||
|
$notification->user_id = $row['user_id'];
|
||||||
|
|
||||||
|
$new_rows[] = $notification->create_insert_array($data);
|
||||||
|
|
||||||
|
// setup the notification methods and add the notification to the queue
|
||||||
|
if ($row['method'])
|
||||||
|
{
|
||||||
|
if (!isset($methods[$row['method']]))
|
||||||
|
{
|
||||||
|
$method_class_name = 'phpbb_notifications_method_' . $row['method'];
|
||||||
|
$methods[$row['method']] = new $$method_class_name();
|
||||||
|
}
|
||||||
|
|
||||||
|
$methods[$row['method']]->add_to_queue($notification);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// insert into the db
|
||||||
|
$this->db->sql_multi_insert(NOTIFICATIONS_TABLE, $new_rows);
|
||||||
|
|
||||||
|
// run the queue for each method to send notifications
|
||||||
|
foreach ($methods as $method)
|
||||||
|
{
|
||||||
|
$method->run_queue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function update_notifications($type, $type_id, $data)
|
||||||
|
{
|
||||||
|
$type_class_name = $this->get_type_class_name($type);
|
||||||
|
|
||||||
|
$object = new $$type_class($this->phpbb_container);
|
||||||
|
$update = $object->update($data);
|
||||||
|
|
||||||
|
$sql = 'UPDATE ' . NOTIFICATIONS_TABLE . '
|
||||||
|
SET ' . $this->db->sql_build_array('UPDATE', $update) . "
|
||||||
|
WHERE type = '" . $this->db->sql_escape($type) . "'
|
||||||
|
AND type_id = " . (int) $type_id;
|
||||||
|
$result = $this->db->sql_query($sql);
|
||||||
|
|
||||||
|
while ($row = $this->db->sql_fetchrow($result))
|
||||||
|
{
|
||||||
|
$object = new $type_class_name($this->phpbb_container, $row);
|
||||||
|
$object->update($data);
|
||||||
|
|
||||||
|
$update_rows[] = $object->getForUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
128
phpBB/includes/notifications/type/base.php
Normal file
128
phpBB/includes/notifications/type/base.php
Normal file
|
@ -0,0 +1,128 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @package notifications
|
||||||
|
* @copyright (c) 2012 phpBB Group
|
||||||
|
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ignore
|
||||||
|
*/
|
||||||
|
if (!defined('IN_PHPBB'))
|
||||||
|
{
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base notifications class
|
||||||
|
* @package notifications
|
||||||
|
*/
|
||||||
|
abstract class phpbb_notifications_type_base implements phpbb_notifications_type_interface
|
||||||
|
{
|
||||||
|
protected $phpbb_container;
|
||||||
|
protected $db;
|
||||||
|
protected $phpbb_root_path;
|
||||||
|
protected $php_ext;
|
||||||
|
|
||||||
|
protected $users;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indentification data
|
||||||
|
* notification_id
|
||||||
|
* item_type
|
||||||
|
* item_id
|
||||||
|
* user_id
|
||||||
|
* unread
|
||||||
|
*
|
||||||
|
* time
|
||||||
|
* data (special serialized field that each notification type can use to store stuff)
|
||||||
|
*
|
||||||
|
* @var array $data Notification row from the database
|
||||||
|
* This must be private, all interaction should use __get(), __set()
|
||||||
|
*/
|
||||||
|
private $data = array();
|
||||||
|
|
||||||
|
public function __construct(Symfony\Component\DependencyInjection\ContainerBuilder $phpbb_container, $data = array())
|
||||||
|
{
|
||||||
|
// phpBB Container
|
||||||
|
$this->phpbb_container = $phpbb_container;
|
||||||
|
|
||||||
|
// Some common things we're going to use
|
||||||
|
$this->db = $phpbb_container->get('dbal.conn');
|
||||||
|
$this->phpbb_root_path = $phpbb_container->getParameter('core.root_path');
|
||||||
|
$this->php_ext = $phpbb_container->getParameter('core.php_ext');
|
||||||
|
|
||||||
|
// The row from the database (unless this is a new notification we're going to add)
|
||||||
|
$this->data = $data;
|
||||||
|
$this->data['data'] = (isset($this->data['data'])) ? unserialize($this->data['data']) : array();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __get($name)
|
||||||
|
{
|
||||||
|
return $this->data[$name];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __set($name, $value)
|
||||||
|
{
|
||||||
|
$this->data[$name] = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_data($name)
|
||||||
|
{
|
||||||
|
return $this->data['data'][$name];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set_data($name, $value)
|
||||||
|
{
|
||||||
|
$this->data['data'][$name] = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function users(&$users)
|
||||||
|
{
|
||||||
|
$this->users = $users;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Output the notification to the template
|
||||||
|
*
|
||||||
|
* @param array $options Array of options
|
||||||
|
* template_block Template block name to output to (Default: notifications)
|
||||||
|
*/
|
||||||
|
public function display($options = array())
|
||||||
|
{
|
||||||
|
$template = $this->phpbb_container->get('template');
|
||||||
|
$user = $this->phpbb_container->get('user');
|
||||||
|
|
||||||
|
// Merge default options
|
||||||
|
$options = array_merge(array(
|
||||||
|
'template_block' => 'notifications',
|
||||||
|
), $options);
|
||||||
|
|
||||||
|
$template->assign_block_vars($options['template_block'], array(
|
||||||
|
'TITLE' => $this->get_title(),
|
||||||
|
'URL' => $this->get_url(),
|
||||||
|
'TIME' => $user->format_date($this->time),
|
||||||
|
|
||||||
|
'ID' => $this->notification_id,
|
||||||
|
'UNREAD' => $this->unread,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function create_insert_array($data)
|
||||||
|
{
|
||||||
|
// Defaults
|
||||||
|
$data = array_merge(array(
|
||||||
|
'item_type' => $this->get_type(),
|
||||||
|
'time' => time(),
|
||||||
|
'unread' => true,
|
||||||
|
|
||||||
|
'data' => array(),
|
||||||
|
), $this->data);
|
||||||
|
|
||||||
|
$data['data'] = serialize($data['data']);
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
}
|
31
phpBB/includes/notifications/type/interface.php
Normal file
31
phpBB/includes/notifications/type/interface.php
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @package notifications
|
||||||
|
* @copyright (c) 2012 phpBB Group
|
||||||
|
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ignore
|
||||||
|
*/
|
||||||
|
if (!defined('IN_PHPBB'))
|
||||||
|
{
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base notifications interface
|
||||||
|
* @package notifications
|
||||||
|
*/
|
||||||
|
interface phpbb_notifications_type_interface
|
||||||
|
{
|
||||||
|
public function get_type();
|
||||||
|
|
||||||
|
public function get_title();
|
||||||
|
|
||||||
|
public function get_url();
|
||||||
|
|
||||||
|
public function create_insert_array($data);
|
||||||
|
}
|
65
phpBB/includes/notifications/type/post.php
Normal file
65
phpBB/includes/notifications/type/post.php
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @package notifications
|
||||||
|
* @copyright (c) 2012 phpBB Group
|
||||||
|
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ignore
|
||||||
|
*/
|
||||||
|
if (!defined('IN_PHPBB'))
|
||||||
|
{
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Post notifications class
|
||||||
|
* @package notifications
|
||||||
|
*/
|
||||||
|
class phpbb_notifications_type_post extends phpbb_notifications_type_base
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Get the type of notification this is
|
||||||
|
* phpbb_notifications_type_
|
||||||
|
*/
|
||||||
|
public function get_type()
|
||||||
|
{
|
||||||
|
return 'post';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_title()
|
||||||
|
{
|
||||||
|
return $this->data['post_username'] . ' posted in the topic ' . censor_text($this->data['topic_title']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_url()
|
||||||
|
{
|
||||||
|
return append_sid($this->phpbb_root_path . 'viewtopic.' . $this->php_ext, "p={$this->item_id}#p{$this->item_id}");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Users needed to query before this notification can be displayed
|
||||||
|
*
|
||||||
|
* @return array Array of user_ids
|
||||||
|
*/
|
||||||
|
public function users_to_query()
|
||||||
|
{
|
||||||
|
return array($this->data['poster_id']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function create_insert_array($post)
|
||||||
|
{
|
||||||
|
$this->item_id = $post['post_id'];
|
||||||
|
|
||||||
|
$this->set_data('poster_id', $post['poster_id']);
|
||||||
|
|
||||||
|
$this->set_data('topic_title', $post['topic_title']);
|
||||||
|
|
||||||
|
$this->set_data('post_username', $post['post_username']);
|
||||||
|
|
||||||
|
return parent::create_insert_array($post);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue