aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--phpBB/config/services.yml5
-rw-r--r--phpBB/includes/constants.php1
-rw-r--r--phpBB/includes/notifications/method/base.php51
-rw-r--r--phpBB/includes/notifications/method/email.php28
-rw-r--r--phpBB/includes/notifications/method/interface.php24
-rw-r--r--phpBB/includes/notifications/service.php197
-rw-r--r--phpBB/includes/notifications/type/base.php128
-rw-r--r--phpBB/includes/notifications/type/interface.php31
-rw-r--r--phpBB/includes/notifications/type/post.php65
9 files changed, 530 insertions, 0 deletions
diff --git a/phpBB/config/services.yml b/phpBB/config/services.yml
index 133a43b77e..b9c697b481 100644
--- a/phpBB/config/services.yml
+++ b/phpBB/config/services.yml
@@ -89,6 +89,11 @@ services:
- .%core.php_ext%
- @cache.driver
+ notifications:
+ class: phpbb_notifications_service
+ arguments:
+ - @container
+
processor.config:
class: phpbb_di_processor_ext
arguments:
diff --git a/phpBB/includes/constants.php b/phpBB/includes/constants.php
index 68af41ab20..de289c73dc 100644
--- a/phpBB/includes/constants.php
+++ b/phpBB/includes/constants.php
@@ -239,6 +239,7 @@ define('LOG_TABLE', $table_prefix . 'log');
define('LOGIN_ATTEMPT_TABLE', $table_prefix . 'login_attempts');
define('MODERATOR_CACHE_TABLE', $table_prefix . 'moderator_cache');
define('MODULES_TABLE', $table_prefix . 'modules');
+define('NOTIFICATIONS_TABLE', $table_prefix . 'notifications');
define('POLL_OPTIONS_TABLE', $table_prefix . 'poll_options');
define('POLL_VOTES_TABLE', $table_prefix . 'poll_votes');
define('POSTS_TABLE', $table_prefix . 'posts');
diff --git a/phpBB/includes/notifications/method/base.php b/phpBB/includes/notifications/method/base.php
new file mode 100644
index 0000000000..a70f37db95
--- /dev/null
+++ b/phpBB/includes/notifications/method/base.php
@@ -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');
+ }
+}
diff --git a/phpBB/includes/notifications/method/email.php b/phpBB/includes/notifications/method/email.php
new file mode 100644
index 0000000000..b06e2c018e
--- /dev/null
+++ b/phpBB/includes/notifications/method/email.php
@@ -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
+ }
+}
diff --git a/phpBB/includes/notifications/method/interface.php b/phpBB/includes/notifications/method/interface.php
new file mode 100644
index 0000000000..2d8a8b605e
--- /dev/null
+++ b/phpBB/includes/notifications/method/interface.php
@@ -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
+{
+}
diff --git a/phpBB/includes/notifications/service.php b/phpBB/includes/notifications/service.php
new file mode 100644
index 0000000000..8f5d559867
--- /dev/null
+++ b/phpBB/includes/notifications/service.php
@@ -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();
+ }
+ }
+}
diff --git a/phpBB/includes/notifications/type/base.php b/phpBB/includes/notifications/type/base.php
new file mode 100644
index 0000000000..959516fd19
--- /dev/null
+++ b/phpBB/includes/notifications/type/base.php
@@ -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;
+ }
+}
diff --git a/phpBB/includes/notifications/type/interface.php b/phpBB/includes/notifications/type/interface.php
new file mode 100644
index 0000000000..ace5ca67da
--- /dev/null
+++ b/phpBB/includes/notifications/type/interface.php
@@ -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);
+}
diff --git a/phpBB/includes/notifications/type/post.php b/phpBB/includes/notifications/type/post.php
new file mode 100644
index 0000000000..eb8d92c79c
--- /dev/null
+++ b/phpBB/includes/notifications/type/post.php
@@ -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);
+ }
+}