aboutsummaryrefslogtreecommitdiffstats
path: root/phpBB/phpbb
diff options
context:
space:
mode:
Diffstat (limited to 'phpBB/phpbb')
-rw-r--r--phpBB/phpbb/avatar/driver/upload.php7
-rw-r--r--phpBB/phpbb/console/command/reparser/list_all.php2
-rw-r--r--phpBB/phpbb/console/command/reparser/reparse.php195
-rw-r--r--phpBB/phpbb/db/migration/data/v310/notifications_board.php73
-rw-r--r--phpBB/phpbb/db/migration/data/v320/announce_global_permission.php41
-rw-r--r--phpBB/phpbb/filesystem/filesystem_interface.php2
-rw-r--r--phpBB/phpbb/help/manager.php1
-rw-r--r--phpBB/phpbb/notification/manager.php527
-rw-r--r--phpBB/phpbb/notification/method/base.php130
-rw-r--r--phpBB/phpbb/notification/method/board.php398
-rw-r--r--phpBB/phpbb/notification/method/email.php23
-rw-r--r--phpBB/phpbb/notification/method/jabber.php25
-rw-r--r--phpBB/phpbb/notification/method/messenger_base.php24
-rw-r--r--phpBB/phpbb/notification/method/method_interface.php104
-rw-r--r--phpBB/phpbb/notification/type/admin_activate_user.php18
-rw-r--r--phpBB/phpbb/notification/type/approve_post.php23
-rw-r--r--phpBB/phpbb/notification/type/approve_topic.php24
-rw-r--r--phpBB/phpbb/notification/type/base.php73
-rw-r--r--phpBB/phpbb/notification/type/bookmark.php32
-rw-r--r--phpBB/phpbb/notification/type/disapprove_post.php21
-rw-r--r--phpBB/phpbb/notification/type/disapprove_topic.php21
-rw-r--r--phpBB/phpbb/notification/type/group_request.php10
-rw-r--r--phpBB/phpbb/notification/type/group_request_approved.php4
-rw-r--r--phpBB/phpbb/notification/type/pm.php26
-rw-r--r--phpBB/phpbb/notification/type/post.php58
-rw-r--r--phpBB/phpbb/notification/type/post_in_queue.php21
-rw-r--r--phpBB/phpbb/notification/type/quote.php24
-rw-r--r--phpBB/phpbb/notification/type/report_pm.php12
-rw-r--r--phpBB/phpbb/notification/type/report_pm_closed.php23
-rw-r--r--phpBB/phpbb/notification/type/report_post.php10
-rw-r--r--phpBB/phpbb/notification/type/report_post_closed.php23
-rw-r--r--phpBB/phpbb/notification/type/topic.php26
-rw-r--r--phpBB/phpbb/notification/type/topic_in_queue.php21
-rw-r--r--phpBB/phpbb/notification/type/type_interface.php8
-rw-r--r--phpBB/phpbb/permissions.php1
-rw-r--r--phpBB/phpbb/session.php58
-rw-r--r--phpBB/phpbb/template/twig/node/includecss.php2
-rw-r--r--phpBB/phpbb/textformatter/s9e/factory.php5
-rw-r--r--phpBB/phpbb/textformatter/s9e/utils.php6
-rw-r--r--phpBB/phpbb/user.php4
40 files changed, 1492 insertions, 614 deletions
diff --git a/phpBB/phpbb/avatar/driver/upload.php b/phpBB/phpbb/avatar/driver/upload.php
index 4fdaee9561..60c9e9cc95 100644
--- a/phpBB/phpbb/avatar/driver/upload.php
+++ b/phpBB/phpbb/avatar/driver/upload.php
@@ -168,6 +168,13 @@ class upload extends \phpbb\avatar\driver\driver
return false;
}
+ // Delete current avatar if not overwritten
+ $ext = substr(strrchr($row['avatar'], '.'), 1);
+ if ($ext && $ext !== $file->get('extension'))
+ {
+ $this->delete($row);
+ }
+
return array(
'avatar' => $row['id'] . '_' . time() . '.' . $file->get('extension'),
'avatar_width' => $file->get('width'),
diff --git a/phpBB/phpbb/console/command/reparser/list_all.php b/phpBB/phpbb/console/command/reparser/list_all.php
index 1589836ddd..e42c3ac782 100644
--- a/phpBB/phpbb/console/command/reparser/list_all.php
+++ b/phpBB/phpbb/console/command/reparser/list_all.php
@@ -36,7 +36,7 @@ class list_all extends \phpbb\console\command\command
foreach ($reparsers as $name => $reparser)
{
// Store the names without the "text_reparser." prefix
- $this->reparser_names[] = str_replace('text_reparser.', '', $name);
+ $this->reparser_names[] = preg_replace('(^text_reparser\\.)', '', $name);
}
}
diff --git a/phpBB/phpbb/console/command/reparser/reparse.php b/phpBB/phpbb/console/command/reparser/reparse.php
index 151e196358..63124b4b8c 100644
--- a/phpBB/phpbb/console/command/reparser/reparse.php
+++ b/phpBB/phpbb/console/command/reparser/reparse.php
@@ -22,9 +22,14 @@ use Symfony\Component\Console\Style\SymfonyStyle;
class reparse extends \phpbb\console\command\command
{
/**
- * @var \phpbb\di\service_collection
+ * @var \phpbb\config\db_text
*/
- protected $reparsers;
+ protected $config_text;
+
+ /**
+ * @var InputInterface
+ */
+ protected $input;
/**
* @var SymfonyStyle
@@ -32,15 +37,32 @@ class reparse extends \phpbb\console\command\command
protected $io;
/**
+ * @var OutputInterface
+ */
+ protected $output;
+
+ /**
+ * @var \phpbb\di\service_collection
+ */
+ protected $reparsers;
+
+ /**
+ * @var array Reparser names as keys, and their last $current ID as values
+ */
+ protected $resume_data;
+
+ /**
* Constructor
*
* @param \phpbb\user $user
- * @param \phpbb\di\service_collection $reparser_collection
+ * @param \phpbb\di\service_collection $reparsers
+ * @param \phpbb\config\db_text $config_text
*/
- public function __construct(\phpbb\user $user, \phpbb\di\service_collection $reparsers)
+ public function __construct(\phpbb\user $user, \phpbb\di\service_collection $reparsers, \phpbb\config\db_text $config_text)
{
require_once __DIR__ . '/../../../../includes/functions_content.php';
+ $this->config_text = $config_text;
$this->reparsers = $reparsers;
parent::__construct($user);
}
@@ -63,6 +85,12 @@ class reparse extends \phpbb\console\command\command
$this->user->lang('CLI_DESCRIPTION_REPARSER_REPARSE_OPT_DRY_RUN')
)
->addOption(
+ 'resume',
+ null,
+ InputOption::VALUE_NONE,
+ $this->user->lang('CLI_DESCRIPTION_REPARSER_REPARSE_OPT_RESUME')
+ )
+ ->addOption(
'range-min',
null,
InputOption::VALUE_REQUIRED,
@@ -86,6 +114,44 @@ class reparse extends \phpbb\console\command\command
}
/**
+ * Create a styled progress bar
+ *
+ * @param integer $max Max value for the progress bar
+ * @return \Symfony\Component\Console\Helper\ProgressBar
+ */
+ protected function create_progress_bar($max)
+ {
+ $progress = $this->io->createProgressBar($max);
+ if ($this->output->getVerbosity() === OutputInterface::VERBOSITY_VERBOSE)
+ {
+ $progress->setFormat('<info>[%percent:3s%%]</info> %message%');
+ $progress->setOverwrite(false);
+ }
+ else if ($this->output->getVerbosity() >= OutputInterface::VERBOSITY_VERY_VERBOSE)
+ {
+ $progress->setFormat('<info>[%current:s%/%max:s%]</info><comment>[%elapsed%/%estimated%][%memory%]</comment> %message%');
+ $progress->setOverwrite(false);
+ }
+ else
+ {
+ $this->io->newLine(2);
+ $progress->setFormat(
+ " %current:s%/%max:s% %bar% %percent:3s%%\n" .
+ " %message% %elapsed:6s%/%estimated:-6s% %memory:6s%\n");
+ $progress->setBarWidth(60);
+ }
+
+ if (!defined('PHP_WINDOWS_VERSION_BUILD'))
+ {
+ $progress->setEmptyBarCharacter('░'); // light shade character \u2591
+ $progress->setProgressCharacter('');
+ $progress->setBarCharacter('▓'); // dark shade character \u2593
+ }
+
+ return $progress;
+ }
+
+ /**
* Executes the command reparser:reparse
*
* @param InputInterface $input
@@ -94,7 +160,10 @@ class reparse extends \phpbb\console\command\command
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
+ $this->input = $input;
+ $this->output = $output;
$this->io = new SymfonyStyle($input, $output);
+ $this->load_resume_data();
$name = $input->getArgument('reparser-name');
if (isset($name))
@@ -104,13 +173,13 @@ class reparse extends \phpbb\console\command\command
{
$name = 'text_reparser.' . $name;
}
- $this->reparse($input, $output, $name);
+ $this->reparse($name);
}
else
{
foreach ($this->reparsers as $name => $service)
{
- $this->reparse($input, $output, $name);
+ $this->reparse($name);
}
}
@@ -120,66 +189,74 @@ class reparse extends \phpbb\console\command\command
}
/**
- * Reparse all text handled by given reparser within given range
+ * Get an option value, adjusted for given reparser
*
- * @param InputInterface $input
- * @param OutputInterface $output
- * @param string $name Reparser name
- * @return null
+ * Will use the last saved value if --resume is set and the option was not specified
+ * on the command line
+ *
+ * @param string $reparser_name Reparser name
+ * @param string $option_name Option name
+ * @return integer
*/
- protected function reparse(InputInterface $input, OutputInterface $output, $name)
+ protected function get_option($reparser_name, $option_name)
{
- $reparser = $this->reparsers[$name];
- if ($input->getOption('dry-run'))
- {
- $reparser->disable_save();
- }
- else
+ // Return the option from the resume_data if applicable
+ if ($this->input->getOption('resume') && isset($this->resume_data[$reparser_name][$option_name]) && !$this->input->hasParameterOption('--' . $option_name))
{
- $reparser->enable_save();
+ return $this->resume_data[$reparser_name][$option_name];
}
- // Start at range-max if specified or at the highest ID otherwise
- $max = (is_null($input->getOption('range-max'))) ? $reparser->get_max_id() : $input->getOption('range-max');
- $min = $input->getOption('range-min');
- $size = $input->getOption('range-size');
+ $value = $this->input->getOption($option_name);
- if ($max === 0)
+ // range-max has no default value, it must be computed for each reparser
+ if ($option_name === 'range-max' && $value === null)
{
- return;
+ $value = $this->reparsers[$reparser_name]->get_max_id();
}
- $this->io->section($this->user->lang('CLI_REPARSER_REPARSE_REPARSING', str_replace('text_reparser.', '', $name), $min, $max));
+ return $value;
+ }
- $progress = $this->io->createProgressBar($max);
- if ($output->getVerbosity() === OutputInterface::VERBOSITY_VERBOSE)
- {
- $progress->setFormat('<info>[%percent:3s%%]</info> %message%');
- $progress->setOverwrite(false);
- }
- else if ($output->getVerbosity() >= OutputInterface::VERBOSITY_VERY_VERBOSE)
+ /**
+ * Load the resume data from the database
+ */
+ protected function load_resume_data()
+ {
+ $resume_data = $this->config_text->get('reparser_resume');
+ $this->resume_data = (empty($resume_data)) ? array() : unserialize($resume_data);
+ }
+
+ /**
+ * Reparse all text handled by given reparser within given range
+ *
+ * @param string $name Reparser name
+ */
+ protected function reparse($name)
+ {
+ $reparser = $this->reparsers[$name];
+ if ($this->input->getOption('dry-run'))
{
- $progress->setFormat('<info>[%current:s%/%max:s%]</info><comment>[%elapsed%/%estimated%][%memory%]</comment> %message%');
- $progress->setOverwrite(false);
+ $reparser->disable_save();
}
else
{
- $this->io->newLine(2);
- $progress->setFormat(
- " %current:s%/%max:s% %bar% %percent:3s%%\n" .
- " %message% %elapsed:6s%/%estimated:-6s% %memory:6s%\n");
- $progress->setBarWidth(60);
+ $reparser->enable_save();
}
- $progress->setMessage($this->user->lang('CLI_REPARSER_REPARSE_REPARSING_START', str_replace('text_reparser.', '', $name)));
+ // Start at range-max if specified or at the highest ID otherwise
+ $max = $this->get_option($name, 'range-max');
+ $min = $this->get_option($name, 'range-min');
+ $size = $this->get_option($name, 'range-size');
- if (!defined('PHP_WINDOWS_VERSION_BUILD'))
+ if ($max < $min)
{
- $progress->setEmptyBarCharacter('░'); // light shade character \u2591
- $progress->setProgressCharacter('');
- $progress->setBarCharacter('▓'); // dark shade character \u2593
+ return;
}
+ $this->io->section($this->user->lang('CLI_REPARSER_REPARSE_REPARSING', preg_replace('(^text_reparser\\.)', '', $name), $min, $max));
+
+ $progress = $this->create_progress_bar($max);
+ $progress->setMessage($this->user->lang('CLI_REPARSER_REPARSE_REPARSING_START', preg_replace('(^text_reparser\\.)', '', $name)));
$progress->start();
// Start from $max and decrement $current by $size until we reach $min
@@ -189,14 +266,40 @@ class reparse extends \phpbb\console\command\command
$start = max($min, $current + 1 - $size);
$end = max($min, $current);
- $progress->setMessage($this->user->lang('CLI_REPARSER_REPARSE_REPARSING', str_replace('text_reparser.', '', $name), $start, $end));
+ $progress->setMessage($this->user->lang('CLI_REPARSER_REPARSE_REPARSING', preg_replace('(^text_reparser\\.)', '', $name), $start, $end));
$reparser->reparse_range($start, $end);
$current = $start - 1;
$progress->setProgress($max + 1 - $start);
+
+ $this->update_resume_data($name, $current);
}
$progress->finish();
$this->io->newLine(2);
}
+
+ /**
+ * Save the resume data to the database
+ */
+ protected function save_resume_data()
+ {
+ $this->config_text->set('reparser_resume', serialize($this->resume_data));
+ }
+
+ /**
+ * Save the resume data to the database
+ *
+ * @param string $name Reparser name
+ * @param string $current Current ID
+ */
+ protected function update_resume_data($name, $current)
+ {
+ $this->resume_data[$name] = array(
+ 'range-min' => $this->get_option($name, 'range-min'),
+ 'range-max' => $current,
+ 'range-size' => $this->get_option($name, 'range-size'),
+ );
+ $this->save_resume_data();
+ }
}
diff --git a/phpBB/phpbb/db/migration/data/v310/notifications_board.php b/phpBB/phpbb/db/migration/data/v310/notifications_board.php
new file mode 100644
index 0000000000..525d94e984
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v310/notifications_board.php
@@ -0,0 +1,73 @@
+<?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\v310;
+
+class notifications_board extends \phpbb\db\migration\migration
+{
+ static public function depends_on()
+ {
+ return array('\phpbb\db\migration\data\v310\notifications');
+ }
+
+ public function update_data()
+ {
+ return array(
+ array('config.add', array('allow_board_notifications', 1)),
+ array('custom', array(array($this, 'update_user_subscriptions'))),
+ array('custom', array(array($this, 'update_module'))),
+ );
+ }
+
+ public function update_module()
+ {
+ $sql = 'UPDATE ' . MODULES_TABLE . "
+ SET auth = 'cfg_allow_board_notifications'
+ WHERE module_basename = 'ucp_notifications'
+ AND module_mode = 'notification_list'";
+ $this->sql_query($sql);
+ }
+
+ public function update_user_subscriptions()
+ {
+ $sql = 'UPDATE ' . USER_NOTIFICATIONS_TABLE . "
+ SET method = 'notification.method.board'
+ WHERE method = ''";
+ $this->sql_query($sql);
+ }
+
+ public function revert_data()
+ {
+ return array(
+ array('custom', array(array($this, 'revert_user_subscriptions'))),
+ array('custom', array(array($this, 'revert_module'))),
+ );
+ }
+
+ public function revert_user_subscriptions()
+ {
+ $sql = 'UPDATE ' . USER_NOTIFICATIONS_TABLE . "
+ SET method = ''
+ WHERE method = 'notification.method.board'";
+ $this->sql_query($sql);
+ }
+
+ public function revert_module()
+ {
+ $sql = 'UPDATE ' . MODULES_TABLE . "
+ SET auth = ''
+ WHERE module_basename = 'ucp_notifications'
+ AND module_mode = 'notification_list'";
+ $this->sql_query($sql);
+ }
+}
diff --git a/phpBB/phpbb/db/migration/data/v320/announce_global_permission.php b/phpBB/phpbb/db/migration/data/v320/announce_global_permission.php
new file mode 100644
index 0000000000..fe30a1c1b8
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v320/announce_global_permission.php
@@ -0,0 +1,41 @@
+<?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\v320;
+
+class announce_global_permission extends \phpbb\db\migration\migration
+{
+ public function effectively_installed()
+ {
+ $sql = 'SELECT auth_option_id
+ FROM ' . ACL_OPTIONS_TABLE . "
+ WHERE auth_option = 'f_announce_global'";
+ $result = $this->db->sql_query($sql);
+ $auth_option_id = $this->db->sql_fetchfield('auth_option_id');
+ $this->db->sql_freeresult($result);
+
+ return $auth_option_id !== false;
+ }
+
+ static public function depends_on()
+ {
+ return array('\phpbb\db\migration\data\v310\rc2');
+ }
+
+ public function update_data()
+ {
+ return array(
+ array('permission.add', array('f_announce_global', false, 'f_announce')),
+ );
+ }
+}
diff --git a/phpBB/phpbb/filesystem/filesystem_interface.php b/phpBB/phpbb/filesystem/filesystem_interface.php
index 21ad8252f8..1093be2499 100644
--- a/phpBB/phpbb/filesystem/filesystem_interface.php
+++ b/phpBB/phpbb/filesystem/filesystem_interface.php
@@ -64,7 +64,7 @@ interface filesystem_interface
* or the user can specify octal values (or any integer if it makes sense). All directories will have
* an execution bit appended, if the user group (owner, group or other) has any bit specified.
*
- * @param string|array|\Traversable $file The file/directory to be chmodded
+ * @param string|array|\Traversable $files The file/directory to be chmodded
* @param int $perms Permissions to set
* @param bool $recursive If the permissions should be changed recursively
* @param bool $force_chmod_link Try to apply permissions to symlinks as well
diff --git a/phpBB/phpbb/help/manager.php b/phpBB/phpbb/help/manager.php
index d6991c0733..39f52d343b 100644
--- a/phpBB/phpbb/help/manager.php
+++ b/phpBB/phpbb/help/manager.php
@@ -49,6 +49,7 @@ class manager
*
* @param string $block_name Name or language key with the name of the block
* @param bool $switch_column Switch the column of the menu
+ * @param array $questions Array of frequently asked questions
*/
public function add_block($block_name, $switch_column = false, $questions = array())
{
diff --git a/phpBB/phpbb/notification/manager.php b/phpBB/phpbb/notification/manager.php
index 38d7a13165..04259382ba 100644
--- a/phpBB/phpbb/notification/manager.php
+++ b/phpBB/phpbb/notification/manager.php
@@ -26,7 +26,7 @@ class manager
/** @var array */
protected $subscription_types;
- /** @var array */
+ /** @var method\method_interface[] */
protected $notification_methods;
/** @var ContainerInterface */
@@ -35,9 +35,6 @@ class manager
/** @var \phpbb\user_loader */
protected $user_loader;
- /** @var \phpbb\config\config */
- protected $config;
-
/** @var \phpbb\event\dispatcher_interface */
protected $phpbb_dispatcher;
@@ -51,18 +48,9 @@ class manager
protected $user;
/** @var string */
- protected $phpbb_root_path;
-
- /** @var string */
- protected $php_ext;
-
- /** @var string */
protected $notification_types_table;
/** @var string */
- protected $notifications_table;
-
- /** @var string */
protected $user_notifications_table;
/**
@@ -72,43 +60,35 @@ class manager
* @param array $notification_methods
* @param ContainerInterface $phpbb_container
* @param \phpbb\user_loader $user_loader
- * @param \phpbb\config\config $config
* @param \phpbb\event\dispatcher_interface $phpbb_dispatcher
* @param \phpbb\db\driver\driver_interface $db
* @param \phpbb\cache\service $cache
* @param \phpbb\user $user
- * @param string $phpbb_root_path
- * @param string $php_ext
* @param string $notification_types_table
- * @param string $notifications_table
* @param string $user_notifications_table
*
* @return \phpbb\notification\manager
*/
- public function __construct($notification_types, $notification_methods, ContainerInterface $phpbb_container, \phpbb\user_loader $user_loader, \phpbb\config\config $config, \phpbb\event\dispatcher_interface $phpbb_dispatcher, \phpbb\db\driver\driver_interface $db, \phpbb\cache\service $cache, $user, $phpbb_root_path, $php_ext, $notification_types_table, $notifications_table, $user_notifications_table)
+ public function __construct($notification_types, $notification_methods, ContainerInterface $phpbb_container, \phpbb\user_loader $user_loader, \phpbb\event\dispatcher_interface $phpbb_dispatcher, \phpbb\db\driver\driver_interface $db, \phpbb\cache\service $cache, \phpbb\user $user, $notification_types_table, $user_notifications_table)
{
$this->notification_types = $notification_types;
$this->notification_methods = $notification_methods;
$this->phpbb_container = $phpbb_container;
$this->user_loader = $user_loader;
- $this->config = $config;
$this->phpbb_dispatcher = $phpbb_dispatcher;
$this->db = $db;
$this->cache = $cache;
$this->user = $user;
- $this->phpbb_root_path = $phpbb_root_path;
- $this->php_ext = $php_ext;
-
$this->notification_types_table = $notification_types_table;
- $this->notifications_table = $notifications_table;
$this->user_notifications_table = $user_notifications_table;
}
/**
- * Load the user's notifications
+ * Load the user's notifications for a given method
*
+ * @param string $method_name
* @param array $options Optional options to control what notifications are loaded
* notification_id Notification id to load (or array of notification ids)
* user_id User id to load notifications for (Default: $user->data['user_id'])
@@ -123,27 +103,21 @@ class manager
* 'notifications' array of notification type objects
* 'unread_count' number of unread notifications the user has if count_unread is true in the options
* 'total_count' number of notifications the user has if count_total is true in the options
+ * @throws \phpbb\notification\exception when the method doesn't refer to a class extending \phpbb\notification\method\method_interface
*/
- public function load_notifications(array $options = array())
+ public function load_notifications($method_name, array $options = array())
{
- // Merge default options
- $options = array_merge(array(
- 'notification_id' => false,
- 'user_id' => $this->user->data['user_id'],
- 'order_by' => 'notification_time',
- 'order_dir' => 'DESC',
- 'limit' => 0,
- 'start' => 0,
- 'all_unread' => false,
- 'count_unread' => false,
- 'count_total' => false,
- ), $options);
-
- // If all_unread, count_unread must be true
- $options['count_unread'] = ($options['all_unread']) ? true : $options['count_unread'];
+ $method = $this->get_method_class($method_name);
- // Anonymous users and bots never receive notifications
- if ($options['user_id'] == $this->user->data['user_id'] && ($this->user->data['user_id'] == ANONYMOUS || $this->user->data['user_type'] == USER_IGNORE))
+ if (! $method instanceof \phpbb\notification\method\method_interface)
+ {
+ throw new \phpbb\notification\exception($this->user->lang('NOTIFICATION_METHOD_INVALID', $method_name));
+ }
+ else if ($method->is_available())
+ {
+ return $method->load_notifications($options);
+ }
+ else
{
return array(
'notifications' => array(),
@@ -151,172 +125,110 @@ class manager
'total_count' => 0,
);
}
+ }
- $notifications = $user_ids = array();
- $load_special = array();
- $total_count = $unread_count = 0;
+ /**
+ * Mark notifications read or unread for all available methods
+ *
+ * @param bool|string|array $notification_type_name Type identifier or array of item types (only acceptable if the $data is identical for the specified types). False to mark read for all item types
+ * @param bool|int|array $item_id Item id or array of item ids. False to mark read for all item ids
+ * @param bool|int|array $user_id User id or array of user ids. False to mark read for all user ids
+ * @param bool|int $time Time at which to mark all notifications prior to as read. False to mark all as read. (Default: False)
+ *
+ * @deprecated since 3.2
+ */
+ public function mark_notifications_read($notification_type_name, $item_id, $user_id, $time = false)
+ {
+ $this->mark_notifications($notification_type_name, $item_id, $user_id, $time);
+ }
- if ($options['count_unread'])
+ /**
+ * Mark notifications read or unread for all available methods
+ *
+ * @param bool|string|array $notification_type_name Type identifier or array of item types (only acceptable if the $data is identical for the specified types). False to mark read for all item types
+ * @param bool|int|array $item_id Item id or array of item ids. False to mark read for all item ids
+ * @param bool|int|array $user_id User id or array of user ids. False to mark read for all user ids
+ * @param bool|int $time Time at which to mark all notifications prior to as read. False to mark all as read. (Default: False)
+ * @param bool $mark_read Define if the notification as to be set to True or False. (Default: True)
+ */
+ public function mark_notifications($notification_type_name, $item_id, $user_id, $time = false, $mark_read = true)
+ {
+ if (is_array($notification_type_name))
{
- // Get the total number of unread notifications
- $sql = 'SELECT COUNT(n.notification_id) AS unread_count
- FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt
- WHERE n.user_id = ' . (int) $options['user_id'] . '
- AND n.notification_read = 0
- AND nt.notification_type_id = n.notification_type_id
- AND nt.notification_type_enabled = 1';
- $result = $this->db->sql_query($sql);
- $unread_count = (int) $this->db->sql_fetchfield('unread_count');
- $this->db->sql_freeresult($result);
+ $notification_type_id = $this->get_notification_type_ids($notification_type_name);
}
-
- if ($options['count_total'])
+ else if ($notification_type_name !== false)
{
- // Get the total number of notifications
- $sql = 'SELECT COUNT(n.notification_id) AS total_count
- FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt
- WHERE n.user_id = ' . (int) $options['user_id'] . '
- AND nt.notification_type_id = n.notification_type_id
- AND nt.notification_type_enabled = 1';
- $result = $this->db->sql_query($sql);
- $total_count = (int) $this->db->sql_fetchfield('total_count');
- $this->db->sql_freeresult($result);
+ $notification_type_id = $this->get_notification_type_id($notification_type_name);
}
-
- if (!$options['count_total'] || $total_count)
+ else
{
- $rowset = array();
-
- // Get the main notifications
- $sql = 'SELECT n.*, nt.notification_type_name
- FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt
- WHERE n.user_id = ' . (int) $options['user_id'] .
- (($options['notification_id']) ? ((is_array($options['notification_id'])) ? ' AND ' . $this->db->sql_in_set('n.notification_id', $options['notification_id']) : ' AND n.notification_id = ' . (int) $options['notification_id']) : '') . '
- AND nt.notification_type_id = n.notification_type_id
- AND nt.notification_type_enabled = 1
- ORDER BY n.' . $this->db->sql_escape($options['order_by']) . ' ' . $this->db->sql_escape($options['order_dir']);
- $result = $this->db->sql_query_limit($sql, $options['limit'], $options['start']);
-
- while ($row = $this->db->sql_fetchrow($result))
- {
- $rowset[$row['notification_id']] = $row;
- }
- $this->db->sql_freeresult($result);
-
- // Get all unread notifications
- if ($unread_count && $options['all_unread'] && !empty($rowset))
- {
- $sql = 'SELECT n.*, nt.notification_type_name
- FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt
- WHERE n.user_id = ' . (int) $options['user_id'] . '
- AND n.notification_read = 0
- AND ' . $this->db->sql_in_set('n.notification_id', array_keys($rowset), true) . '
- AND nt.notification_type_id = n.notification_type_id
- AND nt.notification_type_enabled = 1
- ORDER BY n.' . $this->db->sql_escape($options['order_by']) . ' ' . $this->db->sql_escape($options['order_dir']);
- $result = $this->db->sql_query_limit($sql, $options['limit'], $options['start']);
-
- while ($row = $this->db->sql_fetchrow($result))
- {
- $rowset[$row['notification_id']] = $row;
- }
- $this->db->sql_freeresult($result);
- }
-
- foreach ($rowset as $row)
- {
- $notification = $this->get_item_type_class($row['notification_type_name'], $row);
-
- // Array of user_ids to query all at once
- $user_ids = array_merge($user_ids, $notification->users_to_query());
-
- // Some notification types also require querying additional tables themselves
- if (!isset($load_special[$row['notification_type_name']]))
- {
- $load_special[$row['notification_type_name']] = array();
- }
- $load_special[$row['notification_type_name']] = array_merge($load_special[$row['notification_type_name']], $notification->get_load_special());
-
- $notifications[$row['notification_id']] = $notification;
- }
-
- $this->user_loader->load_users($user_ids);
-
- // Allow each type to load its own special items
- foreach ($load_special as $item_type => $data)
- {
- $item_class = $this->get_item_type_class($item_type);
-
- $item_class->load_special($data, $notifications);
- }
+ $notification_type_id = false;
}
- return array(
- 'notifications' => $notifications,
- 'unread_count' => $unread_count,
- 'total_count' => $total_count,
- );
+ foreach ($this->get_available_subscription_methods() as $method)
+ {
+ $method->mark_notifications($notification_type_id, $item_id, $user_id, $time, $mark_read);
+ }
}
/**
- * Mark notifications read
- *
- * @param bool|string|array $notification_type_name Type identifier or array of item types (only acceptable if the $data is identical for the specified types). False to mark read for all item types
- * @param bool|int|array $item_id Item id or array of item ids. False to mark read for all item ids
- * @param bool|int|array $user_id User id or array of user ids. False to mark read for all user ids
- * @param bool|int $time Time at which to mark all notifications prior to as read. False to mark all as read. (Default: False)
- */
- public function mark_notifications_read($notification_type_name, $item_id, $user_id, $time = false)
+ * Mark notifications read or unread from a parent identifier for all available methods
+ *
+ * @param string|array $notification_type_name Type identifier or array of item types (only acceptable if the $data is identical for the specified types)
+ * @param bool|int|array $item_parent_id Item parent id or array of item parent ids. False to mark read for all item parent ids
+ * @param bool|int|array $user_id User id or array of user ids. False to mark read for all user ids
+ * @param bool|int $time Time at which to mark all notifications prior to as read. False to mark all as read. (Default: False)
+ *
+ * @deprecated since 3.2
+ */
+ public function mark_notifications_read_by_parent($notification_type_name, $item_parent_id, $user_id, $time = false)
{
- $time = ($time !== false) ? $time : time();
-
- $sql = 'UPDATE ' . $this->notifications_table . "
- SET notification_read = 1
- WHERE notification_time <= " . (int) $time .
- (($notification_type_name !== false) ? ' AND ' .
- (is_array($notification_type_name) ? $this->db->sql_in_set('notification_type_id', $this->get_notification_type_ids($notification_type_name)) : 'notification_type_id = ' . $this->get_notification_type_id($notification_type_name)) : '') .
- (($user_id !== false) ? ' AND ' . (is_array($user_id) ? $this->db->sql_in_set('user_id', $user_id) : 'user_id = ' . (int) $user_id) : '') .
- (($item_id !== false) ? ' AND ' . (is_array($item_id) ? $this->db->sql_in_set('item_id', $item_id) : 'item_id = ' . (int) $item_id) : '');
- $this->db->sql_query($sql);
+ $this->mark_notifications_by_parent($notification_type_name, $item_parent_id, $user_id, $time);
}
/**
- * Mark notifications read from a parent identifier
+ * Mark notifications read or unread from a parent identifier for all available methods
*
* @param string|array $notification_type_name Type identifier or array of item types (only acceptable if the $data is identical for the specified types)
* @param bool|int|array $item_parent_id Item parent id or array of item parent ids. False to mark read for all item parent ids
* @param bool|int|array $user_id User id or array of user ids. False to mark read for all user ids
* @param bool|int $time Time at which to mark all notifications prior to as read. False to mark all as read. (Default: False)
+ * @param bool $mark_read Define if the notification as to be set to True or False. (Default: True)
*/
- public function mark_notifications_read_by_parent($notification_type_name, $item_parent_id, $user_id, $time = false)
+ public function mark_notifications_by_parent($notification_type_name, $item_parent_id, $user_id, $time = false, $mark_read = true)
{
- $time = ($time !== false) ? $time : time();
-
- $sql = 'UPDATE ' . $this->notifications_table . "
- SET notification_read = 1
- WHERE notification_time <= " . (int) $time .
- (($notification_type_name !== false) ? ' AND ' .
- (is_array($notification_type_name) ? $this->db->sql_in_set('notification_type_id', $this->get_notification_type_ids($notification_type_name)) : 'notification_type_id = ' . $this->get_notification_type_id($notification_type_name)) : '') .
- (($item_parent_id !== false) ? ' AND ' . (is_array($item_parent_id) ? $this->db->sql_in_set('item_parent_id', $item_parent_id, false, true) : 'item_parent_id = ' . (int) $item_parent_id) : '') .
- (($user_id !== false) ? ' AND ' . (is_array($user_id) ? $this->db->sql_in_set('user_id', $user_id) : 'user_id = ' . (int) $user_id) : '');
- $this->db->sql_query($sql);
+ if (is_array($notification_type_name))
+ {
+ $notification_type_id = $this->get_notification_type_ids($notification_type_name);
+ }
+ else
+ {
+ $notification_type_id = $this->get_notification_type_id($notification_type_name);
+ }
+
+ foreach ($this->get_available_subscription_methods() as $method)
+ {
+ $method->mark_notifications_by_parent($notification_type_id, $item_parent_id, $user_id, $time, $mark_read);
+ }
}
/**
- * Mark notifications read
+ * Mark notifications read or unread for a given method
*
+ * @param string $method_name
* @param int|array $notification_id Notification id or array of notification ids.
* @param bool|int $time Time at which to mark all notifications prior to as read. False to mark all as read. (Default: False)
+ * @param bool $mark_read Define if the notification as to be set to True or False. (Default: True)
*/
- public function mark_notifications_read_by_id($notification_id, $time = false)
+ public function mark_notifications_by_id($method_name, $notification_id, $time = false, $mark_read = true)
{
- $time = ($time !== false) ? $time : time();
+ $method = $this->get_method_class($method_name);
- $sql = 'UPDATE ' . $this->notifications_table . "
- SET notification_read = 1
- WHERE notification_time <= " . (int) $time . '
- AND ' . ((is_array($notification_id)) ? $this->db->sql_in_set('notification_id', $notification_id) : 'notification_id = ' . (int) $notification_id);
- $this->db->sql_query($sql);
+ if ($method instanceof \phpbb\notification\method\method_interface && $method->is_available())
+ {
+ $method->mark_notifications_by_id($notification_id, $time, $mark_read);
+ }
}
/**
@@ -411,18 +323,15 @@ class manager
// Make sure not to send new notifications to users who've already been notified about this item
// This may happen when an item was added, but now new users are able to see the item
- $sql = 'SELECT n.user_id
- FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt
- WHERE n.notification_type_id = ' . (int) $notification_type_id . '
- AND n.item_id = ' . (int) $item_id . '
- AND nt.notification_type_id = n.notification_type_id
- AND nt.notification_type_enabled = 1';
- $result = $this->db->sql_query($sql);
- while ($row = $this->db->sql_fetchrow($result))
+ // We remove each user which was already notified by at least one method.
+ foreach ($this->get_subscription_methods_instances() as $method)
{
- unset($notify_users[$row['user_id']]);
+ $notified_users = $method->get_notified_users($notification_type_id, array('item_id' => $item_id));
+ foreach ($notified_users as $user => $notifications)
+ {
+ unset($notify_users[$user]);
+ }
}
- $this->db->sql_freeresult($result);
if (!sizeof($notify_users))
{
@@ -434,8 +343,6 @@ class manager
$pre_create_data = $notification->pre_create_insert_array($data, $notify_users);
unset($notification);
- $insert_buffer = new \phpbb\db\sql_insert_buffer($this->db, $this->notifications_table);
-
// Go through each user so we can insert a row in the DB and then notify them by their desired means
foreach ($notify_users as $user => $methods)
{
@@ -443,8 +350,8 @@ class manager
$notification->user_id = (int) $user;
- // Insert notification row using buffer.
- $insert_buffer->insert($notification->create_insert_array($data, $pre_create_data));
+ // Generate the insert_array
+ $notification->create_insert_array($data, $pre_create_data);
// Users are needed to send notifications
$user_ids = array_merge($user_ids, $notification->users_to_query());
@@ -452,20 +359,15 @@ class manager
foreach ($methods as $method)
{
// setup the notification methods and add the notification to the queue
- if ($method) // blank means we just insert it as a notification, but do not notify them by any other means
+ if (!isset($notification_methods[$method]))
{
- if (!isset($notification_methods[$method]))
- {
- $notification_methods[$method] = $this->get_method_class($method);
- }
-
- $notification_methods[$method]->add_to_queue($notification);
+ $notification_methods[$method] = $this->get_method_class($method);
}
+
+ $notification_methods[$method]->add_to_queue($notification);
}
}
- $insert_buffer->flush();
-
// We need to load all of the users to send notifications
$this->user_loader->load_users($user_ids);
@@ -477,12 +379,13 @@ class manager
}
/**
- * Update a notification
+ * Update notification
*
* @param string|array $notification_type_name Type identifier or array of item types (only acceptable if the $data is identical for the specified types)
* @param array $data Data specific for this type that will be updated
+ * @param array $options
*/
- public function update_notifications($notification_type_name, $data)
+ public function update_notifications($notification_type_name, array $data, array $options = array())
{
if (is_array($notification_type_name))
{
@@ -494,27 +397,27 @@ class manager
return;
}
- $notification = $this->get_item_type_class($notification_type_name);
+ $this->update_notification($this->get_item_type_class($notification_type_name), $data, $options);
+ }
- // Allow the notifications class to over-ride the update_notifications functionality
- if (method_exists($notification, 'update_notifications'))
+ /**
+ * Update a notification
+ *
+ * @param \phpbb\notification\type\type_interface $notification The notification
+ * @param array $data Data specific for this type that will be updated
+ * @param array $options
+ */
+ public function update_notification(\phpbb\notification\type\type_interface $notification, array $data, array $options = array())
+ {
+ if (empty($options))
{
- // Return False to over-ride the rest of the update
- if ($notification->update_notifications($data) === false)
- {
- return;
- }
+ $options['item_id'] = $notification->get_item_id($data);
}
- $notification_type_id = $this->get_notification_type_id($notification_type_name);
- $item_id = $notification->get_item_id($data);
- $update_array = $notification->create_update_array($data);
-
- $sql = 'UPDATE ' . $this->notifications_table . '
- SET ' . $this->db->sql_build_array('UPDATE', $update_array) . '
- WHERE notification_type_id = ' . (int) $notification_type_id . '
- AND item_id = ' . (int) $item_id;
- $this->db->sql_query($sql);
+ foreach ($this->get_available_subscription_methods() as $method)
+ {
+ $method->update_notification($notification, $data, $options);
+ }
}
/**
@@ -523,14 +426,15 @@ class manager
* @param string|array $notification_type_name Type identifier or array of item types (only acceptable if the $item_id is identical for the specified types)
* @param int|array $item_id Identifier within the type (or array of ids)
* @param mixed $parent_id Parent identifier within the type (or array of ids), used in combination with item_id if specified (Default: false; not checked)
+ * @param mixed $user_id User id (Default: false; not checked)
*/
- public function delete_notifications($notification_type_name, $item_id, $parent_id = false)
+ public function delete_notifications($notification_type_name, $item_id, $parent_id = false, $user_id = false)
{
if (is_array($notification_type_name))
{
foreach ($notification_type_name as $type)
{
- $this->delete_notifications($type, $item_id, $parent_id);
+ $this->delete_notifications($type, $item_id, $parent_id, $user_id);
}
return;
@@ -538,11 +442,10 @@ class manager
$notification_type_id = $this->get_notification_type_id($notification_type_name);
- $sql = 'DELETE FROM ' . $this->notifications_table . '
- WHERE notification_type_id = ' . (int) $notification_type_id . '
- AND ' . (is_array($item_id) ? $this->db->sql_in_set('item_id', $item_id) : 'item_id = ' . (int) $item_id) .
- (($parent_id !== false) ? ' AND ' . ((is_array($parent_id) ? $this->db->sql_in_set('item_parent_id', $parent_id) : 'item_parent_id = ' . (int) $parent_id)) : '');
- $this->db->sql_query($sql);
+ foreach ($this->get_available_subscription_methods() as $method)
+ {
+ $method->delete_notifications($notification_type_id, $item_id, $parent_id, $user_id);
+ }
}
/**
@@ -593,16 +496,53 @@ class manager
{
$subscription_methods = array();
+ foreach ($this->get_available_subscription_methods() as $method_name => $method)
+ {
+ $subscription_methods[$method_name] = array(
+ 'id' => $method->get_type(),
+ 'lang' => str_replace('.', '_', strtoupper($method->get_type())),
+ );
+ }
+
+ return $subscription_methods;
+ }
+
+ /**
+ * Get all of the subscription methods
+ *
+ * @return array Array of method's instances
+ */
+ private function get_subscription_methods_instances()
+ {
+ $subscription_methods = array();
+
foreach ($this->notification_methods as $method_name => $data)
{
$method = $this->get_method_class($method_name);
- if ($method instanceof \phpbb\notification\method\method_interface && $method->is_available())
+ if ($method instanceof \phpbb\notification\method\method_interface)
+ {
+ $subscription_methods[$method_name] = $method;
+ }
+ }
+
+ return $subscription_methods;
+ }
+
+ /**
+ * Get all of the available subscription methods
+ *
+ * @return array Array of method's instances
+ */
+ private function get_available_subscription_methods()
+ {
+ $subscription_methods = array();
+
+ foreach ($this->get_subscription_methods_instances() as $method_name => $method)
+ {
+ if ($method->is_available())
{
- $subscription_methods[$method_name] = array(
- 'id' => $method->get_type(),
- 'lang' => str_replace('.', '_', strtoupper($method->get_type())),
- );
+ $subscription_methods[$method_name] = $method;
}
}
@@ -646,7 +586,7 @@ class manager
*/
public function get_global_subscriptions($user_id = false)
{
- $user_id = ($user_id === false) ? $this->user->data['user_id'] : $user_id;
+ $user_id = $user_id ?: $this->user->data['user_id'];
$subscriptions = array();
@@ -656,11 +596,9 @@ class manager
{
foreach ($types as $id => $type)
{
-
if (empty($user_notifications[$id]))
{
- // No rows at all, default to ''
- $subscriptions[$id] = array('');
+ $subscriptions[$id] = $this->get_default_methods();
}
else
{
@@ -690,15 +628,20 @@ class manager
*
* @param string $item_type Type identifier of the subscription
* @param int $item_id The id of the item
- * @param string $method The method of the notification e.g. '', 'email', or 'jabber'
+ * @param string $method The method of the notification e.g. 'board', 'email', or 'jabber'
+ * (if null a subscription will be added for all the defaults methods)
* @param bool|int $user_id The user_id to add the subscription for (bool false for current user)
*/
- public function add_subscription($item_type, $item_id = 0, $method = '', $user_id = false)
+ public function add_subscription($item_type, $item_id = 0, $method = null, $user_id = false)
{
- if ($method !== '')
+ if ($method === null)
{
- // Make sure to subscribe them to the base subscription
- $this->add_subscription($item_type, $item_id, '', $user_id);
+ foreach ($this->get_default_methods() as $method_name)
+ {
+ $this->add_subscription($item_type, $item_id, $method_name, $user_id);
+ }
+
+ return;
}
$user_id = ($user_id === false) ? $this->user->data['user_id'] : $user_id;
@@ -742,33 +685,23 @@ class manager
*
* @param string $item_type Type identifier of the subscription
* @param int $item_id The id of the item
- * @param string $method The method of the notification e.g. '', 'email', or 'jabber'
+ * @param string $method The method of the notification e.g. 'board', 'email', or 'jabber'
* @param bool|int $user_id The user_id to add the subscription for (bool false for current user)
*/
- public function delete_subscription($item_type, $item_id = 0, $method = '', $user_id = false)
+ public function delete_subscription($item_type, $item_id = 0, $method = null, $user_id = false)
{
- $user_id = ($user_id === false) ? $this->user->data['user_id'] : $user_id;
-
- // If no method, make sure that no other notification methods for this item are selected before deleting
- if ($method === '')
+ if ($method === null)
{
- $sql = 'SELECT COUNT(*) as num_notifications
- FROM ' . $this->user_notifications_table . "
- WHERE item_type = '" . $this->db->sql_escape($item_type) . "'
- AND item_id = " . (int) $item_id . '
- AND user_id = ' .(int) $user_id . "
- AND method <> ''
- AND notify = 1";
- $this->db->sql_query($sql);
- $num_notifications = $this->db->sql_fetchfield('num_notifications');
- $this->db->sql_freeresult();
-
- if ($num_notifications)
+ foreach ($this->get_default_methods() as $method_name)
{
- return;
+ $this->delete_subscription($item_type, $item_id, $method_name, $user_id);
}
+
+ return;
}
+ $user_id = $user_id ?: $this->user->data['user_id'];
+
$sql = 'UPDATE ' . $this->user_notifications_table . "
SET notify = 0
WHERE item_type = '" . $this->db->sql_escape($item_type) . "'
@@ -828,15 +761,11 @@ class manager
{
$notification_type_id = $this->get_notification_type_id($notification_type_name);
- $sql = 'DELETE FROM ' . $this->notifications_table . '
- WHERE notification_type_id = ' . (int) $notification_type_id;
- $this->db->sql_query($sql);
-
- $sql = 'DELETE FROM ' . $this->notification_types_table . '
- WHERE notification_type_id = ' . (int) $notification_type_id;
- $this->db->sql_query($sql);
+ foreach ($this->get_available_subscription_methods() as $method)
+ {
+ $method->purge_notifications($notification_type_id);
+ }
- $this->cache->destroy('notification_type_ids');
}
catch (\phpbb\notification\exception $e)
{
@@ -869,17 +798,37 @@ class manager
*/
public function prune_notifications($timestamp, $only_read = true)
{
- $sql = 'DELETE FROM ' . $this->notifications_table . '
- WHERE notification_time < ' . (int) $timestamp .
- (($only_read) ? ' AND notification_read = 1' : '');
- $this->db->sql_query($sql);
+ foreach ($this->get_available_subscription_methods() as $method)
+ {
+ $method->prune_notifications($timestamp, $only_read);
+ }
+ }
+
+ /**
+ * Helper to get the list of methods enabled by default
+ *
+ * @return method\method_interface[]
+ */
+ public function get_default_methods()
+ {
+ $default_methods = array();
+
+ foreach ($this->notification_methods as $method)
+ {
+ if ($method->is_enabled_by_default() && $method->is_available())
+ {
+ $default_methods[] = $method->get_type();
+ }
+ }
- $this->config->set('read_notification_last_gc', time(), false);
+ return $default_methods;
}
/**
- * Helper to get the notifications item type class and set it up
- */
+ * Helper to get the notifications item type class and set it up
+ *
+ * @return type\type_interface
+ */
public function get_item_type_class($notification_type_name, $data = array())
{
$item = $this->load_object($notification_type_name);
@@ -890,16 +839,20 @@ class manager
}
/**
- * Helper to get the notifications method class and set it up
- */
+ * Helper to get the notifications method class and set it up
+ *
+ * @return method\method_interface
+ */
public function get_method_class($method_name)
{
return $this->load_object($method_name);
}
/**
- * Helper to load objects (notification types/methods)
- */
+ * Helper to load objects (notification types/methods)
+ *
+ * @return method\method_interface|type\type_interface
+ */
protected function load_object($object_name)
{
$object = $this->phpbb_container->get($object_name);
@@ -977,4 +930,24 @@ class manager
return $notification_type_ids;
}
+
+ /**
+ * Find the users which are already notified
+ *
+ * @param bool|string|array $notification_type_name Type identifier or array of item types (only acceptable if the $data is identical for the specified types). False to retrieve all item types
+ * @param array $options
+ * @return array The list of the notified users
+ */
+ public function get_notified_users($notification_type_name, array $options)
+ {
+ $notification_type_id = $this->get_notification_type_id($notification_type_name);
+
+ $notified_users = array();
+ foreach ($this->get_available_subscription_methods() as $method)
+ {
+ $notified_users = $notified_users + $method->get_notified_users($notification_type_id, $options);
+ }
+
+ return $notified_users;
+ }
}
diff --git a/phpBB/phpbb/notification/method/base.php b/phpBB/phpbb/notification/method/base.php
index 6ee1d2984a..4a183ca508 100644
--- a/phpBB/phpbb/notification/method/base.php
+++ b/phpBB/phpbb/notification/method/base.php
@@ -21,36 +21,6 @@ abstract class base implements \phpbb\notification\method\method_interface
/** @var \phpbb\notification\manager */
protected $notification_manager;
- /** @var \phpbb\user_loader */
- protected $user_loader;
-
- /** @var \phpbb\db\driver\driver_interface */
- protected $db;
-
- /** @var \phpbb\cache\driver\driver_interface */
- protected $cache;
-
- /** @var \phpbb\template\template */
- protected $template;
-
- /** @var \phpbb\extension\manager */
- protected $extension_manager;
-
- /** @var \phpbb\user */
- protected $user;
-
- /** @var \phpbb\auth\auth */
- protected $auth;
-
- /** @var \phpbb\config\config */
- protected $config;
-
- /** @var string */
- protected $phpbb_root_path;
-
- /** @var string */
- protected $php_ext;
-
/**
* Queue of messages to be sent
*
@@ -59,38 +29,43 @@ abstract class base implements \phpbb\notification\method\method_interface
protected $queue = array();
/**
- * Notification Method Base Constructor
+ * Set notification manager (required)
*
- * @param \phpbb\user_loader $user_loader
- * @param \phpbb\db\driver\driver_interface $db
- * @param \phpbb\cache\driver\driver_interface $cache
- * @param \phpbb\user $user
- * @param \phpbb\auth\auth $auth
- * @param \phpbb\config\config $config
- * @param string $phpbb_root_path
- * @param string $php_ext
- * @return \phpbb\notification\method\base
+ * @param \phpbb\notification\manager $notification_manager
*/
- public function __construct(\phpbb\user_loader $user_loader, \phpbb\db\driver\driver_interface $db, \phpbb\cache\driver\driver_interface $cache, $user, \phpbb\auth\auth $auth, \phpbb\config\config $config, $phpbb_root_path, $php_ext)
+ public function set_notification_manager(\phpbb\notification\manager $notification_manager)
{
- $this->user_loader = $user_loader;
- $this->db = $db;
- $this->cache = $cache;
- $this->user = $user;
- $this->auth = $auth;
- $this->config = $config;
- $this->phpbb_root_path = $phpbb_root_path;
- $this->php_ext = $php_ext;
+ $this->notification_manager = $notification_manager;
}
/**
- * Set notification manager (required)
+ * Is the method enable by default?
*
- * @param \phpbb\notification\manager $notification_manager
+ * @return bool
*/
- public function set_notification_manager(\phpbb\notification\manager $notification_manager)
+ public function is_enabled_by_default()
{
- $this->notification_manager = $notification_manager;
+ return false;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_notified_users($notification_type_id, array $options)
+ {
+ return array();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function load_notifications(array $options = array())
+ {
+ return array(
+ 'notifications' => array(),
+ 'unread_count' => 0,
+ 'total_count' => 0,
+ );
}
/**
@@ -104,6 +79,55 @@ abstract class base implements \phpbb\notification\method\method_interface
}
/**
+ * {@inheritdoc}
+ */
+ public function update_notification($notification, array $data, array $options)
+ {
+ }
+
+ /**
+ * {@inheritdoc
+ */
+ public function mark_notifications($notification_type_id, $item_id, $user_id, $time = false, $mark_read = true)
+ {
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function mark_notifications_by_parent($notification_type_id, $item_parent_id, $user_id, $time = false, $mark_read = true)
+ {
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function mark_notifications_by_id($notification_id, $time = false, $mark_read = true)
+ {
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function delete_notifications($notification_type_id, $item_id, $parent_id = false, $user_id = false)
+ {
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function prune_notifications($timestamp, $only_read = true)
+ {
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function purge_notifications($notification_type_id)
+ {
+ }
+
+ /**
* Empty the queue
*/
protected function empty_queue()
diff --git a/phpBB/phpbb/notification/method/board.php b/phpBB/phpbb/notification/method/board.php
new file mode 100644
index 0000000000..c45f3a8caa
--- /dev/null
+++ b/phpBB/phpbb/notification/method/board.php
@@ -0,0 +1,398 @@
+<?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\notification\method;
+
+/**
+* In Board notification method class
+* This class handles in board notifications. This method is enabled by default.
+*
+* @package notifications
+*/
+class board extends \phpbb\notification\method\base
+{
+ /** @var \phpbb\user_loader */
+ protected $user_loader;
+
+ /** @var \phpbb\db\driver\driver_interface */
+ protected $db;
+
+ /** @var \phpbb\cache\driver\driver_interface */
+ protected $cache;
+
+ /** @var \phpbb\user */
+ protected $user;
+
+ /** @var \phpbb\config\config */
+ protected $config;
+
+ /** @var string */
+ protected $notification_types_table;
+
+ /** @var string */
+ protected $notifications_table;
+
+ /**
+ * Notification Method Board Constructor
+ *
+ * @param \phpbb\user_loader $user_loader
+ * @param \phpbb\db\driver\driver_interface $db
+ * @param \phpbb\cache\driver\driver_interface $cache
+ * @param \phpbb\user $user
+ * @param \phpbb\config\config $config
+ * @param string $notification_types_table
+ * @param string $notifications_table
+ */
+ public function __construct(\phpbb\user_loader $user_loader, \phpbb\db\driver\driver_interface $db, \phpbb\cache\driver\driver_interface $cache, \phpbb\user $user, \phpbb\config\config $config, $notification_types_table, $notifications_table)
+ {
+ $this->user_loader = $user_loader;
+ $this->db = $db;
+ $this->cache = $cache;
+ $this->user = $user;
+ $this->config = $config;
+ $this->notification_types_table = $notification_types_table;
+ $this->notifications_table = $notifications_table;
+
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function add_to_queue(\phpbb\notification\type\type_interface $notification)
+ {
+ $this->queue[] = $notification;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_type()
+ {
+ return 'notification.method.board';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function is_available()
+ {
+ return $this->config['allow_board_notifications'];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function is_enabled_by_default()
+ {
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_notified_users($notification_type_id, array $options)
+ {
+ $notified_users = array();
+ $sql = 'SELECT n.*
+ FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt
+ WHERE n.notification_type_id = ' . (int) $notification_type_id .
+ (isset($options['item_id']) ? ' AND n.item_id = ' . (int) $options['item_id'] : '') .
+ (isset($options['item_parent_id']) ? ' AND n.item_parent_id = ' . (int) $options['item_parent_id'] : '') .
+ (isset($options['user_id']) ? ' AND n.user_id = ' . (int) $options['user_id'] : '') .
+ (isset($options['read']) ? ' AND n.notification_read = ' . (int) $options['read'] : '') .'
+ AND nt.notification_type_id = n.notification_type_id
+ AND nt.notification_type_enabled = 1';
+ $result = $this->db->sql_query($sql);
+ while ($row = $this->db->sql_fetchrow($result))
+ {
+ $notified_users[$row['user_id']] = $row;
+ }
+ $this->db->sql_freeresult($result);
+
+ return $notified_users;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function load_notifications(array $options = array())
+ {
+ // Merge default options
+ $options = array_merge(array(
+ 'notification_id' => false,
+ 'user_id' => $this->user->data['user_id'],
+ 'order_by' => 'notification_time',
+ 'order_dir' => 'DESC',
+ 'limit' => 0,
+ 'start' => 0,
+ 'all_unread' => false,
+ 'count_unread' => false,
+ 'count_total' => false,
+ ), $options);
+
+ // If all_unread, count_unread must be true
+ $options['count_unread'] = ($options['all_unread']) ? true : $options['count_unread'];
+
+ // Anonymous users and bots never receive notifications
+ if ($options['user_id'] == $this->user->data['user_id'] && ($this->user->data['user_id'] == ANONYMOUS || $this->user->data['user_type'] == USER_IGNORE))
+ {
+ return array(
+ 'notifications' => array(),
+ 'unread_count' => 0,
+ 'total_count' => 0,
+ );
+ }
+
+ $notifications = $user_ids = array();
+ $load_special = array();
+ $total_count = $unread_count = 0;
+
+ if ($options['count_unread'])
+ {
+ // Get the total number of unread notifications
+ $sql = 'SELECT COUNT(n.notification_id) AS unread_count
+ FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt
+ WHERE n.user_id = ' . (int) $options['user_id'] . '
+ AND n.notification_read = 0
+ AND nt.notification_type_id = n.notification_type_id
+ AND nt.notification_type_enabled = 1';
+ $result = $this->db->sql_query($sql);
+ $unread_count = (int) $this->db->sql_fetchfield('unread_count');
+ $this->db->sql_freeresult($result);
+ }
+
+ if ($options['count_total'])
+ {
+ // Get the total number of notifications
+ $sql = 'SELECT COUNT(n.notification_id) AS total_count
+ FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt
+ WHERE n.user_id = ' . (int) $options['user_id'] . '
+ AND nt.notification_type_id = n.notification_type_id
+ AND nt.notification_type_enabled = 1';
+ $result = $this->db->sql_query($sql);
+ $total_count = (int) $this->db->sql_fetchfield('total_count');
+ $this->db->sql_freeresult($result);
+ }
+
+ if (!$options['count_total'] || $total_count)
+ {
+ $rowset = array();
+
+ // Get the main notifications
+ $sql = 'SELECT n.*, nt.notification_type_name
+ FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt
+ WHERE n.user_id = ' . (int) $options['user_id'] .
+ (($options['notification_id']) ? ((is_array($options['notification_id'])) ? ' AND ' . $this->db->sql_in_set('n.notification_id', $options['notification_id']) : ' AND n.notification_id = ' . (int) $options['notification_id']) : '') . '
+ AND nt.notification_type_id = n.notification_type_id
+ AND nt.notification_type_enabled = 1
+ ORDER BY n.' . $this->db->sql_escape($options['order_by']) . ' ' . $this->db->sql_escape($options['order_dir']);
+ $result = $this->db->sql_query_limit($sql, $options['limit'], $options['start']);
+
+ while ($row = $this->db->sql_fetchrow($result))
+ {
+ $rowset[$row['notification_id']] = $row;
+ }
+ $this->db->sql_freeresult($result);
+
+ // Get all unread notifications
+ if ($unread_count && $options['all_unread'] && !empty($rowset))
+ {
+ $sql = 'SELECT n.*, nt.notification_type_name
+ FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt
+ WHERE n.user_id = ' . (int) $options['user_id'] . '
+ AND n.notification_read = 0
+ AND ' . $this->db->sql_in_set('n.notification_id', array_keys($rowset), true) . '
+ AND nt.notification_type_id = n.notification_type_id
+ AND nt.notification_type_enabled = 1
+ ORDER BY n.' . $this->db->sql_escape($options['order_by']) . ' ' . $this->db->sql_escape($options['order_dir']);
+ $result = $this->db->sql_query_limit($sql, $options['limit'], $options['start']);
+
+ while ($row = $this->db->sql_fetchrow($result))
+ {
+ $rowset[$row['notification_id']] = $row;
+ }
+ $this->db->sql_freeresult($result);
+ }
+
+ foreach ($rowset as $row)
+ {
+ $notification = $this->notification_manager->get_item_type_class($row['notification_type_name'], $row);
+
+ // Array of user_ids to query all at once
+ $user_ids = array_merge($user_ids, $notification->users_to_query());
+
+ // Some notification types also require querying additional tables themselves
+ if (!isset($load_special[$row['notification_type_name']]))
+ {
+ $load_special[$row['notification_type_name']] = array();
+ }
+ $load_special[$row['notification_type_name']] = array_merge($load_special[$row['notification_type_name']], $notification->get_load_special());
+
+ $notifications[$row['notification_id']] = $notification;
+ }
+
+ $this->user_loader->load_users($user_ids);
+
+ // Allow each type to load its own special items
+ foreach ($load_special as $item_type => $data)
+ {
+ $item_class = $this->notification_manager->get_item_type_class($item_type);
+
+ $item_class->load_special($data, $notifications);
+ }
+ }
+
+ return array(
+ 'notifications' => $notifications,
+ 'unread_count' => $unread_count,
+ 'total_count' => $total_count,
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function notify()
+ {
+ $insert_buffer = new \phpbb\db\sql_insert_buffer($this->db, $this->notifications_table);
+
+ foreach ($this->queue as $notification)
+ {
+ $data = $notification->get_insert_array();
+ $insert_buffer->insert($data);
+ }
+
+ $insert_buffer->flush();
+
+ // We're done, empty the queue
+ $this->empty_queue();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function update_notification($notification, array $data, array $options)
+ {
+ // Allow the notifications class to over-ride the update_notifications functionality
+ if (method_exists($notification, 'update_notifications'))
+ {
+ // Return False to over-ride the rest of the update
+ if ($notification->update_notifications($data) === false)
+ {
+ return;
+ }
+ }
+
+ $notification_type_id = $this->notification_manager->get_notification_type_id($notification->get_type());
+ $update_array = $notification->create_update_array($data);
+
+ $sql = 'UPDATE ' . $this->notifications_table . '
+ SET ' . $this->db->sql_build_array('UPDATE', $update_array) . '
+ WHERE notification_type_id = ' . (int) $notification_type_id .
+ (isset($options['item_id']) ? ' AND item_id = ' . (int) $options['item_id'] : '') .
+ (isset($options['item_parent_id']) ? ' AND item_parent_id = ' . (int) $options['item_parent_id'] : '') .
+ (isset($options['user_id']) ? ' AND user_id = ' . (int) $options['user_id'] : '') .
+ (isset($options['read']) ? ' AND notification_read = ' . (int) $options['read'] : '');
+ $this->db->sql_query($sql);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function mark_notifications($notification_type_id, $item_id, $user_id, $time = false, $mark_read = true)
+ {
+ $time = ($time !== false) ? $time : time();
+
+ $sql = 'UPDATE ' . $this->notifications_table . '
+ SET notification_read = ' . ($mark_read ? 1 : 0) . '
+ WHERE notification_time <= ' . (int) $time .
+ (($notification_type_id !== false) ? ' AND ' .
+ (is_array($notification_type_id) ? $this->db->sql_in_set('notification_type_id', $notification_type_id) : 'notification_type_id = ' . $notification_type_id) : '') .
+ (($user_id !== false) ? ' AND ' . (is_array($user_id) ? $this->db->sql_in_set('user_id', $user_id) : 'user_id = ' . (int) $user_id) : '') .
+ (($item_id !== false) ? ' AND ' . (is_array($item_id) ? $this->db->sql_in_set('item_id', $item_id) : 'item_id = ' . (int) $item_id) : '');
+ $this->db->sql_query($sql);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function mark_notifications_by_parent($notification_type_id, $item_parent_id, $user_id, $time = false, $mark_read = true)
+ {
+ $time = ($time !== false) ? $time : time();
+
+ $sql = 'UPDATE ' . $this->notifications_table . '
+ SET notification_read = ' . ($mark_read ? 1 : 0) . '
+ WHERE notification_time <= ' . (int) $time .
+ (($notification_type_id !== false) ? ' AND ' .
+ (is_array($notification_type_id) ? $this->db->sql_in_set('notification_type_id', $notification_type_id) : 'notification_type_id = ' . $notification_type_id) : '') .
+ (($item_parent_id !== false) ? ' AND ' . (is_array($item_parent_id) ? $this->db->sql_in_set('item_parent_id', $item_parent_id, false, true) : 'item_parent_id = ' . (int) $item_parent_id) : '') .
+ (($user_id !== false) ? ' AND ' . (is_array($user_id) ? $this->db->sql_in_set('user_id', $user_id) : 'user_id = ' . (int) $user_id) : '');
+ $this->db->sql_query($sql);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function mark_notifications_by_id($notification_id, $time = false, $mark_read = true)
+ {
+ $time = ($time !== false) ? $time : time();
+
+ $sql = 'UPDATE ' . $this->notifications_table . '
+ SET notification_read = ' . ($mark_read ? 1 : 0) . '
+ WHERE notification_time <= ' . (int) $time . '
+ AND ' . ((is_array($notification_id)) ? $this->db->sql_in_set('notification_id', $notification_id) : 'notification_id = ' . (int) $notification_id);
+ $this->db->sql_query($sql);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function delete_notifications($notification_type_id, $item_id, $parent_id = false, $user_id = false)
+ {
+ $sql = 'DELETE FROM ' . $this->notifications_table . '
+ WHERE notification_type_id = ' . (int) $notification_type_id . '
+ AND ' . (is_array($item_id) ? $this->db->sql_in_set('item_id', $item_id) : 'item_id = ' . (int) $item_id) .
+ (($parent_id !== false) ? ' AND ' . ((is_array($parent_id) ? $this->db->sql_in_set('item_parent_id', $parent_id) : 'item_parent_id = ' . (int) $parent_id)) : '') .
+ (($user_id !== false) ? ' AND ' . ((is_array($user_id) ? $this->db->sql_in_set('user_id', $user_id) : 'user_id = ' . (int) $user_id)) : '');
+ $this->db->sql_query($sql);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function prune_notifications($timestamp, $only_read = true)
+ {
+ $sql = 'DELETE FROM ' . $this->notifications_table . '
+ WHERE notification_time < ' . (int) $timestamp .
+ (($only_read) ? ' AND notification_read = 1' : '');
+ $this->db->sql_query($sql);
+
+ $this->config->set('read_notification_last_gc', time(), false);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function purge_notifications($notification_type_id)
+ {
+ $sql = 'DELETE FROM ' . $this->notifications_table . '
+ WHERE notification_type_id = ' . (int) $notification_type_id;
+ $this->db->sql_query($sql);
+
+ $sql = 'DELETE FROM ' . $this->notification_types_table . '
+ WHERE notification_type_id = ' . (int) $notification_type_id;
+ $this->db->sql_query($sql);
+
+ $this->cache->destroy('notification_type_ids');
+ }
+}
diff --git a/phpBB/phpbb/notification/method/email.php b/phpBB/phpbb/notification/method/email.php
index a4b93bc85c..21a6559012 100644
--- a/phpBB/phpbb/notification/method/email.php
+++ b/phpBB/phpbb/notification/method/email.php
@@ -20,6 +20,29 @@ namespace phpbb\notification\method;
class email extends \phpbb\notification\method\messenger_base
{
+ /** @var \phpbb\user */
+ protected $user;
+
+ /** @var \phpbb\config\config */
+ protected $config;
+
+ /**
+ * Notification Method email Constructor
+ *
+ * @param \phpbb\user_loader $user_loader
+ * @param \phpbb\user $user
+ * @param \phpbb\config\config $config
+ * @param string $phpbb_root_path
+ * @param string $php_ext
+ */
+ public function __construct(\phpbb\user_loader $user_loader, \phpbb\user $user, \phpbb\config\config $config, $phpbb_root_path, $php_ext)
+ {
+ parent::__construct($user_loader, $phpbb_root_path, $php_ext);
+
+ $this->user = $user;
+ $this->config = $config;
+ }
+
/**
* Get notification method name
*
diff --git a/phpBB/phpbb/notification/method/jabber.php b/phpBB/phpbb/notification/method/jabber.php
index 09f186e3ca..509c6b432c 100644
--- a/phpBB/phpbb/notification/method/jabber.php
+++ b/phpBB/phpbb/notification/method/jabber.php
@@ -20,6 +20,29 @@ namespace phpbb\notification\method;
class jabber extends \phpbb\notification\method\messenger_base
{
+ /** @var \phpbb\user */
+ protected $user;
+
+ /** @var \phpbb\config\config */
+ protected $config;
+
+ /**
+ * Notification Method jabber Constructor
+ *
+ * @param \phpbb\user_loader $user_loader
+ * @param \phpbb\user $user
+ * @param \phpbb\config\config $config
+ * @param string $phpbb_root_path
+ * @param string $php_ext
+ */
+ public function __construct(\phpbb\user_loader $user_loader, \phpbb\user $user, \phpbb\config\config $config, $phpbb_root_path, $php_ext)
+ {
+ parent::__construct($user_loader, $phpbb_root_path, $php_ext);
+
+ $this->user = $user;
+ $this->config = $config;
+ }
+
/**
* Get notification method name
*
@@ -61,6 +84,6 @@ class jabber extends \phpbb\notification\method\messenger_base
return;
}
- return $this->notify_using_messenger(NOTIFY_IM, 'short/');
+ $this->notify_using_messenger(NOTIFY_IM, 'short/');
}
}
diff --git a/phpBB/phpbb/notification/method/messenger_base.php b/phpBB/phpbb/notification/method/messenger_base.php
index bde4573117..74a1811155 100644
--- a/phpBB/phpbb/notification/method/messenger_base.php
+++ b/phpBB/phpbb/notification/method/messenger_base.php
@@ -19,6 +19,29 @@ namespace phpbb\notification\method;
*/
abstract class messenger_base extends \phpbb\notification\method\base
{
+ /** @var \phpbb\user_loader */
+ protected $user_loader;
+
+ /** @var string */
+ protected $phpbb_root_path;
+
+ /** @var string */
+ protected $php_ext;
+
+ /**
+ * Notification Method Board Constructor
+ *
+ * @param \phpbb\user_loader $user_loader
+ * @param string $phpbb_root_path
+ * @param string $php_ext
+ */
+ public function __construct(\phpbb\user_loader $user_loader, $phpbb_root_path, $php_ext)
+ {
+ $this->user_loader = $user_loader;
+ $this->phpbb_root_path = $phpbb_root_path;
+ $this->php_ext = $php_ext;
+ }
+
/**
* Notify using phpBB messenger
*
@@ -57,7 +80,6 @@ abstract class messenger_base extends \phpbb\notification\method\base
include($this->phpbb_root_path . 'includes/functions_messenger.' . $this->php_ext);
}
$messenger = new \messenger();
- $board_url = generate_board_url();
// Time to go through the queue and send emails
foreach ($this->queue as $notification)
diff --git a/phpBB/phpbb/notification/method/method_interface.php b/phpBB/phpbb/notification/method/method_interface.php
index 76b0de179c..c2e4940485 100644
--- a/phpBB/phpbb/notification/method/method_interface.php
+++ b/phpBB/phpbb/notification/method/method_interface.php
@@ -26,12 +26,48 @@ interface method_interface
public function get_type();
/**
+ * Is the method enable by default?
+ *
+ * @return bool
+ */
+ public function is_enabled_by_default();
+
+ /**
* Is this method available for the user?
* This is checked on the notifications options
*/
public function is_available();
/**
+ * Return the list of the users already notified
+ *
+ * @param int $notification_type_id Type of the notification
+ * @param array $options
+ * @return array User
+ */
+ public function get_notified_users($notification_type_id, array $options);
+
+ /**
+ * Load the user's notifications
+ *
+ * @param array $options Optional options to control what notifications are loaded
+ * notification_id Notification id to load (or array of notification ids)
+ * user_id User id to load notifications for (Default: $user->data['user_id'])
+ * order_by Order by (Default: notification_time)
+ * order_dir Order direction (Default: DESC)
+ * limit Number of notifications to load (Default: 5)
+ * start Notifications offset (Default: 0)
+ * all_unread Load all unread notifications? If set to true, count_unread is set to true (Default: false)
+ * count_unread Count all unread notifications? (Default: false)
+ * count_total Count all notifications? (Default: false)
+ * @return array Array of information based on the request with keys:
+ * 'notifications' array of notification type objects
+ * 'unread_count' number of unread notifications the user has if count_unread is true in the options
+ * 'total_count' number of notifications the user has if count_total is true in the options
+ */
+ public function load_notifications(array $options = array());
+
+ /**
* Add a notification to the queue
*
* @param \phpbb\notification\type\type_interface $notification
@@ -42,4 +78,72 @@ interface method_interface
* Parse the queue and notify the users
*/
public function notify();
+
+ /**
+ * Update a notification
+ *
+ * @param \phpbb\notification\type\type_interface $notification Notification to update
+ * @param array $data Data specific for this type that will be updated
+ * @param array $options
+ */
+ public function update_notification($notification, array $data, array $options);
+
+ /**
+ * Mark notifications read or unread
+ *
+ * @param bool|string $notification_type_id Type identifier of item types. False to mark read for all item types
+ * @param bool|int|array $item_id Item id or array of item ids. False to mark read for all item ids
+ * @param bool|int|array $user_id User id or array of user ids. False to mark read for all user ids
+ * @param bool|int $time Time at which to mark all notifications prior to as read. False to mark all as read. (Default: False)
+ * @param bool $mark_read Define if the notification as to be set to True or False. (Default: True)
+ */
+ public function mark_notifications($notification_type_id, $item_id, $user_id, $time = false, $mark_read = true);
+
+ /**
+ * Mark notifications read or unread from a parent identifier
+ *
+ * @param string $notification_type_id Type identifier of item types
+ * @param bool|int|array $item_parent_id Item parent id or array of item parent ids. False to mark read for all item parent ids
+ * @param bool|int|array $user_id User id or array of user ids. False to mark read for all user ids
+ * @param bool|int $time Time at which to mark all notifications prior to as read. False to mark all as read. (Default: False)
+ * @param bool $mark_read Define if the notification as to be set to True or False. (Default: True)
+ */
+ public function mark_notifications_by_parent($notification_type_id, $item_parent_id, $user_id, $time = false, $mark_read = true);
+
+ /**
+ * Mark notifications read or unread
+ *
+ * @param int $notification_id Notification id of notification ids.
+ * @param bool|int $time Time at which to mark all notifications prior to as read. False to mark all as read. (Default: False)
+ * @param bool $mark_read Define if the notification as to be set to True or False. (Default: True)
+ */
+ public function mark_notifications_by_id($notification_id, $time = false, $mark_read = true);
+
+ /**
+ * Delete a notification
+ *
+ * @param string $notification_type_id Type identifier of item types
+ * @param int|array $item_id Identifier within the type (or array of ids)
+ * @param mixed $parent_id Parent identifier within the type (or array of ids), used in combination with item_id if specified (Default: false; not checked)
+ * @param mixed $user_id User id (Default: false; not checked)
+ */
+ public function delete_notifications($notification_type_id, $item_id, $parent_id = false, $user_id = false);
+
+ /**
+ * Delete all notifications older than a certain time
+ *
+ * @param int $timestamp Unix timestamp to delete all notifications that were created before
+ * @param bool $only_read True (default) to only prune read notifications
+ */
+ public function prune_notifications($timestamp, $only_read = true);
+
+ /**
+ * Purge all notifications of a certain type
+ *
+ * This should be called when an extension which has notification types
+ * is purged so that all those notifications are removed
+ *
+ * @param string $notification_type_id Type identifier of the subscription
+ */
+ public function purge_notifications($notification_type_id);
}
diff --git a/phpBB/phpbb/notification/type/admin_activate_user.php b/phpBB/phpbb/notification/type/admin_activate_user.php
index 0e2924e29c..b191fa62ae 100644
--- a/phpBB/phpbb/notification/type/admin_activate_user.php
+++ b/phpBB/phpbb/notification/type/admin_activate_user.php
@@ -41,6 +41,22 @@ class admin_activate_user extends \phpbb\notification\type\base
'group' => 'NOTIFICATION_GROUP_ADMINISTRATION',
);
+ /** @var \phpbb\user_loader */
+ protected $user_loader;
+
+ /** @var \phpbb\config\config */
+ protected $config;
+
+ public function set_config(\phpbb\config\config $config)
+ {
+ $this->config = $config;
+ }
+
+ public function set_user_loader(\phpbb\user_loader $user_loader)
+ {
+ $this->user_loader = $user_loader;
+ }
+
/**
* {@inheritdoc}
*/
@@ -164,6 +180,6 @@ class admin_activate_user extends \phpbb\notification\type\base
$this->set_data('user_actkey', $user['user_actkey']);
$this->notification_time = $user['user_regdate'];
- return parent::create_insert_array($user, $pre_create_data);
+ parent::create_insert_array($user, $pre_create_data);
}
}
diff --git a/phpBB/phpbb/notification/type/approve_post.php b/phpBB/phpbb/notification/type/approve_post.php
index e6c38b2ede..9666647bd8 100644
--- a/phpBB/phpbb/notification/type/approve_post.php
+++ b/phpBB/phpbb/notification/type/approve_post.php
@@ -79,7 +79,7 @@ class approve_post extends \phpbb\notification\type\post
), $options);
$users = array();
- $users[$post['poster_id']] = array('');
+ $users[$post['poster_id']] = $this->notification_manager->get_default_methods();
return $this->get_authorised_recipients(array_keys($users), $post['forum_id'], array_merge($options, array(
'item_type' => self::$notification_option['id'],
@@ -107,21 +107,24 @@ class approve_post extends \phpbb\notification\type\post
}
/**
- * Function for preparing the data for insertion in an SQL query
- * (The service handles insertion)
- *
- * @param array $post Data from submit_post
- * @param array $pre_create_data Data from pre_create_insert_array()
- *
- * @return array Array of data ready to be inserted into the database
+ * {@inheritdoc}
*/
public function create_insert_array($post, $pre_create_data = array())
{
$this->set_data('post_subject', $post['post_subject']);
- $data = parent::create_insert_array($post, $pre_create_data);
+ parent::create_insert_array($post, $pre_create_data);
+
+ $this->notification_time = time();
+ }
- $this->notification_time = $data['notification_time'] = time();
+ /**
+ * {@inheritdoc}
+ */
+ public function get_insert_array()
+ {
+ $data = parent::get_insert_array();
+ $data['notification_time'] = $this->notification_time;
return $data;
}
diff --git a/phpBB/phpbb/notification/type/approve_topic.php b/phpBB/phpbb/notification/type/approve_topic.php
index 5f5b96f335..e9f4c32852 100644
--- a/phpBB/phpbb/notification/type/approve_topic.php
+++ b/phpBB/phpbb/notification/type/approve_topic.php
@@ -79,7 +79,7 @@ class approve_topic extends \phpbb\notification\type\topic
), $options);
$users = array();
- $users[$post['poster_id']] = array('');
+ $users[$post['poster_id']] = $this->notification_manager->get_default_methods();
return $this->get_authorised_recipients(array_keys($users), $post['forum_id'], array_merge($options, array(
'item_type' => self::$notification_option['id'],
@@ -107,19 +107,23 @@ class approve_topic extends \phpbb\notification\type\topic
}
/**
- * Function for preparing the data for insertion in an SQL query
- * (The service handles insertion)
- *
- * @param array $post Data from submit_post
- * @param array $pre_create_data Data from pre_create_insert_array()
- *
- * @return array Array of data ready to be inserted into the database
+ * {@inheritdoc}
*/
public function create_insert_array($post, $pre_create_data = array())
{
- $data = parent::create_insert_array($post, $pre_create_data);
- $this->notification_time = $data['notification_time'] = time();
+ parent::create_insert_array($post, $pre_create_data);
+
+ $this->notification_time = time();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_insert_array()
+ {
+ $data = parent::get_insert_array();
+ $data['notification_time'] = $this->notification_time;
return $data;
}
diff --git a/phpBB/phpbb/notification/type/base.php b/phpBB/phpbb/notification/type/base.php
index 1cf0498138..06f7f9c615 100644
--- a/phpBB/phpbb/notification/type/base.php
+++ b/phpBB/phpbb/notification/type/base.php
@@ -21,27 +21,15 @@ abstract class base implements \phpbb\notification\type\type_interface
/** @var \phpbb\notification\manager */
protected $notification_manager;
- /** @var \phpbb\user_loader */
- protected $user_loader;
-
/** @var \phpbb\db\driver\driver_interface */
protected $db;
- /** @var \phpbb\cache\driver\driver_interface */
- protected $cache;
-
- /** @var \phpbb\template\template */
- protected $template;
-
/** @var \phpbb\user */
protected $user;
/** @var \phpbb\auth\auth */
protected $auth;
- /** @var \phpbb\config\config */
- protected $config;
-
/** @var string */
protected $phpbb_root_path;
@@ -49,12 +37,6 @@ abstract class base implements \phpbb\notification\type\type_interface
protected $php_ext;
/** @var string */
- protected $notification_types_table;
-
- /** @var string */
- protected $notifications_table;
-
- /** @var string */
protected $user_notifications_table;
/**
@@ -91,33 +73,23 @@ abstract class base implements \phpbb\notification\type\type_interface
/**
* Notification Type Base Constructor
*
- * @param \phpbb\user_loader $user_loader
* @param \phpbb\db\driver\driver_interface $db
- * @param \phpbb\cache\driver\driver_interface $cache
* @param \phpbb\user $user
* @param \phpbb\auth\auth $auth
- * @param \phpbb\config\config $config
* @param string $phpbb_root_path
* @param string $php_ext
- * @param string $notification_types_table
- * @param string $notifications_table
* @param string $user_notifications_table
* @return \phpbb\notification\type\base
*/
- public function __construct(\phpbb\user_loader $user_loader, \phpbb\db\driver\driver_interface $db, \phpbb\cache\driver\driver_interface $cache, $user, \phpbb\auth\auth $auth, \phpbb\config\config $config, $phpbb_root_path, $php_ext, $notification_types_table, $notifications_table, $user_notifications_table)
+ public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\user $user, \phpbb\auth\auth $auth, $phpbb_root_path, $php_ext, $user_notifications_table)
{
- $this->user_loader = $user_loader;
$this->db = $db;
- $this->cache = $cache;
$this->user = $user;
$this->auth = $auth;
- $this->config = $config;
$this->phpbb_root_path = $phpbb_root_path;
$this->php_ext = $php_ext;
- $this->notification_types_table = $notification_types_table;
- $this->notifications_table = $notifications_table;
$this->user_notifications_table = $user_notifications_table;
}
@@ -207,12 +179,7 @@ abstract class base implements \phpbb\notification\type\type_interface
}
/**
- * Function for preparing the data for insertion in an SQL query
- * (The service handles insertion)
- *
- * @param array $type_data Data unique to this notification type
- * @param array $pre_create_data Data from pre_create_insert_array()
- * @return array Array of data ready to be inserted into the database
+ * {@inheritdoc}
*/
public function create_insert_array($type_data, $pre_create_data = array())
{
@@ -227,7 +194,13 @@ abstract class base implements \phpbb\notification\type\type_interface
'notification_data' => array(),
), $this->data);
+ }
+ /**
+ * {@inheritdoc}
+ */
+ public function get_insert_array()
+ {
$data = $this->data;
$data['notification_data'] = serialize($data['notification_data']);
@@ -244,7 +217,8 @@ abstract class base implements \phpbb\notification\type\type_interface
*/
public function create_update_array($type_data)
{
- $data = $this->create_insert_array($type_data);
+ $this->create_insert_array($type_data);
+ $data = $this->get_insert_array();
// Unset data unique to each row
unset(
@@ -497,8 +471,8 @@ abstract class base implements \phpbb\notification\type\type_interface
{
if (!in_array($user_id, $resulting_user_ids) && !isset($options['ignore_users'][$user_id]))
{
- // No rows at all for this user, default to ''
- $rowset[$user_id] = array('');
+ // No rows at all for this user, use the default methods
+ $rowset[$user_id] = $this->notification_manager->get_default_methods();
}
}
@@ -516,22 +490,21 @@ abstract class base implements \phpbb\notification\type\type_interface
{
$this->notification_read = (bool) !$unread;
- $where = array(
- 'notification_type_id = ' . (int) $this->notification_type_id,
- 'item_id = ' . (int) $this->item_id,
- 'user_id = ' . (int) $this->user_id,
- );
- $where = implode(' AND ', $where);
-
if ($return)
{
+ $where = array(
+ 'notification_type_id = ' . (int) $this->notification_type_id,
+ 'item_id = ' . (int) $this->item_id,
+ 'user_id = ' . (int) $this->user_id,
+ );
+
+ $where = implode(' AND ', $where);
return $where;
}
-
- $sql = 'UPDATE ' . $this->notifications_table . '
- SET notification_read = ' . (int) $this->notification_read . '
- WHERE ' . $where;
- $this->db->sql_query($sql);
+ else
+ {
+ $this->notification_manager->mark_notifications($this->get_type(), (int) $this->item_id, (int) $this->user_id, $this->notification_read);
+ }
}
/**
diff --git a/phpBB/phpbb/notification/type/bookmark.php b/phpBB/phpbb/notification/type/bookmark.php
index e6a695e875..5b3fc3a1f2 100644
--- a/phpBB/phpbb/notification/type/bookmark.php
+++ b/phpBB/phpbb/notification/type/bookmark.php
@@ -91,31 +91,27 @@ class bookmark extends \phpbb\notification\type\post
}
// Try to find the users who already have been notified about replies and have not read the topic since and just update their notifications
- $update_notifications = array();
- $sql = 'SELECT n.*
- FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt
- WHERE n.notification_type_id = ' . (int) $this->notification_type_id . '
- AND n.item_parent_id = ' . (int) self::get_item_parent_id($post) . '
- AND n.notification_read = 0
- AND nt.notification_type_id = n.notification_type_id
- AND nt.notification_type_enabled = 1';
- $result = $this->db->sql_query($sql);
- while ($row = $this->db->sql_fetchrow($result))
+ $notified_users = $this->notification_manager->get_notified_users($this->get_type(), array(
+ 'item_parent_id' => self::get_item_parent_id($post),
+ 'read' => 0,
+ ));
+
+ foreach ($notified_users as $user => $notification_data)
{
- // Do not create a new notification
- unset($notify_users[$row['user_id']]);
+ unset($notify_users[$user]);
- $notification = $this->notification_manager->get_item_type_class($this->get_type(), $row);
+ /** @var bookmark $notification */
+ $notification = $this->notification_manager->get_item_type_class($this->get_type(), $notification_data);
$update_responders = $notification->add_responders($post);
if (!empty($update_responders))
{
- $sql = 'UPDATE ' . $this->notifications_table . '
- SET ' . $this->db->sql_build_array('UPDATE', $update_responders) . '
- WHERE notification_id = ' . $row['notification_id'];
- $this->db->sql_query($sql);
+ $this->notification_manager->update_notification($notification, $update_responders, array(
+ 'item_parent_id' => self::get_item_parent_id($post),
+ 'read' => 0,
+ 'user_id' => $user,
+ ));
}
}
- $this->db->sql_freeresult($result);
return $notify_users;
}
diff --git a/phpBB/phpbb/notification/type/disapprove_post.php b/phpBB/phpbb/notification/type/disapprove_post.php
index 7021cdc837..21338bddb7 100644
--- a/phpBB/phpbb/notification/type/disapprove_post.php
+++ b/phpBB/phpbb/notification/type/disapprove_post.php
@@ -125,21 +125,24 @@ class disapprove_post extends \phpbb\notification\type\approve_post
}
/**
- * Function for preparing the data for insertion in an SQL query
- * (The service handles insertion)
- *
- * @param array $post Data from submit_post
- * @param array $pre_create_data Data from pre_create_insert_array()
- *
- * @return array Array of data ready to be inserted into the database
+ * {@inheritdoc}
*/
public function create_insert_array($post, $pre_create_data = array())
{
$this->set_data('disapprove_reason', $post['disapprove_reason']);
- $data = parent::create_insert_array($post);
+ parent::create_insert_array($post, $pre_create_data);
+
+ $this->notification_time = time();
+ }
- $this->notification_time = $data['notification_time'] = time();
+ /**
+ * {@inheritdoc}
+ */
+ public function get_insert_array()
+ {
+ $data = parent::get_insert_array();
+ $data['notification_time'] = $this->notification_time;
return $data;
}
diff --git a/phpBB/phpbb/notification/type/disapprove_topic.php b/phpBB/phpbb/notification/type/disapprove_topic.php
index 419cc5b2a6..30a23a83fe 100644
--- a/phpBB/phpbb/notification/type/disapprove_topic.php
+++ b/phpBB/phpbb/notification/type/disapprove_topic.php
@@ -125,21 +125,24 @@ class disapprove_topic extends \phpbb\notification\type\approve_topic
}
/**
- * Function for preparing the data for insertion in an SQL query
- * (The service handles insertion)
- *
- * @param array $post Data from submit_post
- * @param array $pre_create_data Data from pre_create_insert_array()
- *
- * @return array Array of data ready to be inserted into the database
+ * {@inheritdoc}
*/
public function create_insert_array($post, $pre_create_data = array())
{
$this->set_data('disapprove_reason', $post['disapprove_reason']);
- $data = parent::create_insert_array($post, $pre_create_data);
+ parent::create_insert_array($post, $pre_create_data);
+
+ $this->notification_time = time();
+ }
- $this->notification_time = $data['notification_time'] = time();
+ /**
+ * {@inheritdoc}
+ */
+ public function get_insert_array()
+ {
+ $data = parent::get_insert_array();
+ $data['notification_time'] = $this->notification_time;
return $data;
}
diff --git a/phpBB/phpbb/notification/type/group_request.php b/phpBB/phpbb/notification/type/group_request.php
index 2d7925c1b4..8a0027bfec 100644
--- a/phpBB/phpbb/notification/type/group_request.php
+++ b/phpBB/phpbb/notification/type/group_request.php
@@ -30,6 +30,14 @@ class group_request extends \phpbb\notification\type\base
'lang' => 'NOTIFICATION_TYPE_GROUP_REQUEST',
);
+ /** @var \phpbb\user_loader */
+ protected $user_loader;
+
+ public function set_user_loader(\phpbb\user_loader $user_loader)
+ {
+ $this->user_loader = $user_loader;
+ }
+
/**
* {@inheritdoc}
*/
@@ -156,6 +164,6 @@ class group_request extends \phpbb\notification\type\base
{
$this->set_data('group_name', $group['group_name']);
- return parent::create_insert_array($group, $pre_create_data);
+ parent::create_insert_array($group, $pre_create_data);
}
}
diff --git a/phpBB/phpbb/notification/type/group_request_approved.php b/phpBB/phpbb/notification/type/group_request_approved.php
index f282cdd158..dc353f3380 100644
--- a/phpBB/phpbb/notification/type/group_request_approved.php
+++ b/phpBB/phpbb/notification/type/group_request_approved.php
@@ -58,7 +58,7 @@ class group_request_approved extends \phpbb\notification\type\base
foreach ($group['user_ids'] as $user_id)
{
- $users[$user_id] = array('');
+ $users[$user_id] = $this->notification_manager->get_default_methods();
}
return $users;
@@ -87,7 +87,7 @@ class group_request_approved extends \phpbb\notification\type\base
{
$this->set_data('group_name', $group['group_name']);
- return parent::create_insert_array($group, $pre_create_data);
+ parent::create_insert_array($group, $pre_create_data);
}
/**
diff --git a/phpBB/phpbb/notification/type/pm.php b/phpBB/phpbb/notification/type/pm.php
index 5d4f7fe0c6..2de2dcfa0b 100644
--- a/phpBB/phpbb/notification/type/pm.php
+++ b/phpBB/phpbb/notification/type/pm.php
@@ -40,6 +40,22 @@ class pm extends \phpbb\notification\type\base
'lang' => 'NOTIFICATION_TYPE_PM',
);
+ /** @var \phpbb\user_loader */
+ protected $user_loader;
+
+ /** @var \phpbb\config\config */
+ protected $config;
+
+ public function set_config(\phpbb\config\config $config)
+ {
+ $this->config = $config;
+ }
+
+ public function set_user_loader(\phpbb\user_loader $user_loader)
+ {
+ $this->user_loader = $user_loader;
+ }
+
/**
* Is available
*/
@@ -176,13 +192,7 @@ class pm extends \phpbb\notification\type\base
}
/**
- * Function for preparing the data for insertion in an SQL query
- * (The service handles insertion)
- *
- * @param array $pm Data from submit_post
- * @param array $pre_create_data Data from pre_create_insert_array()
- *
- * @return array Array of data ready to be inserted into the database
+ * {@inheritdoc}
*/
public function create_insert_array($pm, $pre_create_data = array())
{
@@ -190,6 +200,6 @@ class pm extends \phpbb\notification\type\base
$this->set_data('message_subject', $pm['message_subject']);
- return parent::create_insert_array($pm, $pre_create_data);
+ parent::create_insert_array($pm, $pre_create_data);
}
}
diff --git a/phpBB/phpbb/notification/type/post.php b/phpBB/phpbb/notification/type/post.php
index f6b3136a21..f3dd6d531a 100644
--- a/phpBB/phpbb/notification/type/post.php
+++ b/phpBB/phpbb/notification/type/post.php
@@ -55,6 +55,22 @@ class post extends \phpbb\notification\type\base
'group' => 'NOTIFICATION_GROUP_POSTING',
);
+ /** @var \phpbb\user_loader */
+ protected $user_loader;
+
+ /** @var \phpbb\config\config */
+ protected $config;
+
+ public function set_config(\phpbb\config\config $config)
+ {
+ $this->config = $config;
+ }
+
+ public function set_user_loader(\phpbb\user_loader $user_loader)
+ {
+ $this->user_loader = $user_loader;
+ }
+
/**
* Is available
*/
@@ -131,31 +147,27 @@ class post extends \phpbb\notification\type\base
}
// Try to find the users who already have been notified about replies and have not read the topic since and just update their notifications
- $update_notifications = array();
- $sql = 'SELECT n.*
- FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt
- WHERE n.notification_type_id = ' . (int) $this->notification_type_id . '
- AND n.item_parent_id = ' . (int) self::get_item_parent_id($post) . '
- AND n.notification_read = 0
- AND nt.notification_type_id = n.notification_type_id
- AND nt.notification_type_enabled = 1';
- $result = $this->db->sql_query($sql);
- while ($row = $this->db->sql_fetchrow($result))
+ $notified_users = $this->notification_manager->get_notified_users($this->get_type(), array(
+ 'item_parent_id' => self::get_item_parent_id($post),
+ 'read' => 0,
+ ));
+
+ foreach ($notified_users as $user => $notification_data)
{
- // Do not create a new notification
- unset($notify_users[$row['user_id']]);
+ unset($notify_users[$user]);
- $notification = $this->notification_manager->get_item_type_class($this->get_type(), $row);
+ /** @var post $notification */
+ $notification = $this->notification_manager->get_item_type_class($this->get_type(), $notification_data);
$update_responders = $notification->add_responders($post);
if (!empty($update_responders))
{
- $sql = 'UPDATE ' . $this->notifications_table . '
- SET ' . $this->db->sql_build_array('UPDATE', $update_responders) . '
- WHERE notification_id = ' . $row['notification_id'];
- $this->db->sql_query($sql);
+ $this->notification_manager->update_notification($notification, $update_responders, array(
+ 'item_parent_id' => self::get_item_parent_id($post),
+ 'read' => 0,
+ 'user_id' => $user,
+ ));
}
}
- $this->db->sql_freeresult($result);
return $notify_users;
}
@@ -363,13 +375,7 @@ class post extends \phpbb\notification\type\base
}
/**
- * Function for preparing the data for insertion in an SQL query
- * (The service handles insertion)
- *
- * @param array $post Data from submit_post
- * @param array $pre_create_data Data from pre_create_insert_array()
- *
- * @return array Array of data ready to be inserted into the database
+ * {@inheritdoc}
*/
public function create_insert_array($post, $pre_create_data = array())
{
@@ -394,7 +400,7 @@ class post extends \phpbb\notification\type\base
$this->notification_read = true;
}
- return parent::create_insert_array($post, $pre_create_data);
+ parent::create_insert_array($post, $pre_create_data);
}
/**
diff --git a/phpBB/phpbb/notification/type/post_in_queue.php b/phpBB/phpbb/notification/type/post_in_queue.php
index e500ad33bc..8b21d77cdd 100644
--- a/phpBB/phpbb/notification/type/post_in_queue.php
+++ b/phpBB/phpbb/notification/type/post_in_queue.php
@@ -131,19 +131,22 @@ class post_in_queue extends \phpbb\notification\type\post
}
/**
- * Function for preparing the data for insertion in an SQL query
- * (The service handles insertion)
- *
- * @param array $post Data from submit_post
- * @param array $pre_create_data Data from pre_create_insert_array()
- *
- * @return array Array of data ready to be inserted into the database
+ * {@inheritdoc}
*/
public function create_insert_array($post, $pre_create_data = array())
{
- $data = parent::create_insert_array($post, $pre_create_data);
+ parent::create_insert_array($post, $pre_create_data);
+
+ $this->notification_time = time();
+ }
- $this->notification_time = $data['notification_time'] = time();
+ /**
+ * {@inheritdoc}
+ */
+ public function get_insert_array()
+ {
+ $data = parent::get_insert_array();
+ $data['notification_time'] = $this->notification_time;
return $data;
}
diff --git a/phpBB/phpbb/notification/type/quote.php b/phpBB/phpbb/notification/type/quote.php
index 51edfec6f7..57f77bba83 100644
--- a/phpBB/phpbb/notification/type/quote.php
+++ b/phpBB/phpbb/notification/type/quote.php
@@ -109,22 +109,12 @@ class quote extends \phpbb\notification\type\post
*/
public function update_notifications($post)
{
- $old_notifications = array();
- $sql = 'SELECT n.user_id
- FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt
- WHERE n.notification_type_id = ' . (int) $this->notification_type_id . '
- AND n.item_id = ' . self::get_item_id($post) . '
- AND nt.notification_type_id = n.notification_type_id
- AND nt.notification_type_enabled = 1';
- $result = $this->db->sql_query($sql);
- while ($row = $this->db->sql_fetchrow($result))
- {
- $old_notifications[] = $row['user_id'];
- }
- $this->db->sql_freeresult($result);
+ $old_notifications = $this->notification_manager->get_notified_users($this->get_type(), array(
+ 'item_id' => self::get_item_id($post),
+ ));
// Find the new users to notify
- $notifications = $this->find_users_for_notification($post);
+ $notifications = array_keys($this->find_users_for_notification($post));
// Find the notifications we must delete
$remove_notifications = array_diff($old_notifications, array_keys($notifications));
@@ -142,11 +132,7 @@ class quote extends \phpbb\notification\type\post
// Remove the necessary notifications
if (!empty($remove_notifications))
{
- $sql = 'DELETE FROM ' . $this->notifications_table . '
- WHERE notification_type_id = ' . (int) $this->notification_type_id . '
- AND item_id = ' . self::get_item_id($post) . '
- AND ' . $this->db->sql_in_set('user_id', $remove_notifications);
- $this->db->sql_query($sql);
+ $this->notification_manager->delete_notifications($this->get_type(), self::get_item_id($post), false, $remove_notifications);
}
// return true to continue with the update code in the notifications service (this will update the rest of the notifications)
diff --git a/phpBB/phpbb/notification/type/report_pm.php b/phpBB/phpbb/notification/type/report_pm.php
index e7d385f59f..0f7dce0a68 100644
--- a/phpBB/phpbb/notification/type/report_pm.php
+++ b/phpBB/phpbb/notification/type/report_pm.php
@@ -141,6 +141,8 @@ class report_pm extends \phpbb\notification\type\pm
*/
public function get_email_template_variables()
{
+ $user_data = $this->user_loader->get_username($this->get_data('reporter_id'), 'no_profile');
+
return array(
'AUTHOR_NAME' => htmlspecialchars_decode($user_data['username']),
'SUBJECT' => htmlspecialchars_decode(censor_text($this->get_data('message_subject'))),
@@ -237,13 +239,7 @@ class report_pm extends \phpbb\notification\type\pm
}
/**
- * Function for preparing the data for insertion in an SQL query
- * (The service handles insertion)
- *
- * @param array $post Data from submit_post
- * @param array $pre_create_data Data from pre_create_insert_array()
- *
- * @return array Array of data ready to be inserted into the database
+ * {@inheritdoc}
*/
public function create_insert_array($post, $pre_create_data = array())
{
@@ -252,6 +248,6 @@ class report_pm extends \phpbb\notification\type\pm
$this->set_data('reason_description', $post['reason_description']);
$this->set_data('report_text', $post['report_text']);
- return parent::create_insert_array($post, $pre_create_data);
+ parent::create_insert_array($post, $pre_create_data);
}
}
diff --git a/phpBB/phpbb/notification/type/report_pm_closed.php b/phpBB/phpbb/notification/type/report_pm_closed.php
index 1c99db60c3..f793c7df9a 100644
--- a/phpBB/phpbb/notification/type/report_pm_closed.php
+++ b/phpBB/phpbb/notification/type/report_pm_closed.php
@@ -64,7 +64,7 @@ class report_pm_closed extends \phpbb\notification\type\pm
return array();
}
- return array($pm['reporter'] => array(''));
+ return array($pm['reporter'] => $this->notification_manager->get_default_methods());
}
/**
@@ -144,21 +144,24 @@ class report_pm_closed extends \phpbb\notification\type\pm
}
/**
- * Function for preparing the data for insertion in an SQL query
- * (The service handles insertion)
- *
- * @param array $pm PM Data
- * @param array $pre_create_data Data from pre_create_insert_array()
- *
- * @return array Array of data ready to be inserted into the database
+ * {@inheritdoc}
*/
public function create_insert_array($pm, $pre_create_data = array())
{
$this->set_data('closer_id', $pm['closer_id']);
- $data = parent::create_insert_array($pm, $pre_create_data);
+ parent::create_insert_array($pm, $pre_create_data);
+
+ $this->notification_time = time();
+ }
- $this->notification_time = $data['notification_time'] = time();
+ /**
+ * {@inheritdoc}
+ */
+ public function get_insert_array()
+ {
+ $data = parent::get_insert_array();
+ $data['notification_time'] = $this->notification_time;
return $data;
}
diff --git a/phpBB/phpbb/notification/type/report_post.php b/phpBB/phpbb/notification/type/report_post.php
index 8289a04cf1..6eefd53832 100644
--- a/phpBB/phpbb/notification/type/report_post.php
+++ b/phpBB/phpbb/notification/type/report_post.php
@@ -210,13 +210,7 @@ class report_post extends \phpbb\notification\type\post_in_queue
}
/**
- * Function for preparing the data for insertion in an SQL query
- * (The service handles insertion)
- *
- * @param array $post Data from submit_post
- * @param array $pre_create_data Data from pre_create_insert_array()
- *
- * @return array Array of data ready to be inserted into the database
+ * {@inheritdoc}
*/
public function create_insert_array($post, $pre_create_data = array())
{
@@ -225,6 +219,6 @@ class report_post extends \phpbb\notification\type\post_in_queue
$this->set_data('reason_description', $post['reason_description']);
$this->set_data('report_text', $post['report_text']);
- return parent::create_insert_array($post, $pre_create_data);
+ parent::create_insert_array($post, $pre_create_data);
}
}
diff --git a/phpBB/phpbb/notification/type/report_post_closed.php b/phpBB/phpbb/notification/type/report_post_closed.php
index 3f4378628b..6327011f2d 100644
--- a/phpBB/phpbb/notification/type/report_post_closed.php
+++ b/phpBB/phpbb/notification/type/report_post_closed.php
@@ -71,7 +71,7 @@ class report_post_closed extends \phpbb\notification\type\post
return array();
}
- return array($post['reporter'] => array(''));
+ return array($post['reporter'] => $this->notification_manager->get_default_methods());
}
/**
@@ -151,21 +151,24 @@ class report_post_closed extends \phpbb\notification\type\post
}
/**
- * Function for preparing the data for insertion in an SQL query
- * (The service handles insertion)
- *
- * @param array $post Data from submit_post
- * @param array $pre_create_data Data from pre_create_insert_array()
- *
- * @return array Array of data ready to be inserted into the database
+ * {@inheritdoc}
*/
public function create_insert_array($post, $pre_create_data = array())
{
$this->set_data('closer_id', $post['closer_id']);
- $data = parent::create_insert_array($post, $pre_create_data);
+ parent::create_insert_array($post, $pre_create_data);
+
+ $this->notification_time = time();
+ }
- $this->notification_time = $data['notification_time'] = time();
+ /**
+ * {@inheritdoc}
+ */
+ public function get_insert_array()
+ {
+ $data = parent::get_insert_array();
+ $data['notification_time'] = $this->notification_time;
return $data;
}
diff --git a/phpBB/phpbb/notification/type/topic.php b/phpBB/phpbb/notification/type/topic.php
index f0681b9eb8..4812e8b5af 100644
--- a/phpBB/phpbb/notification/type/topic.php
+++ b/phpBB/phpbb/notification/type/topic.php
@@ -55,6 +55,22 @@ class topic extends \phpbb\notification\type\base
'group' => 'NOTIFICATION_GROUP_POSTING',
);
+ /** @var \phpbb\user_loader */
+ protected $user_loader;
+
+ /** @var \phpbb\config\config */
+ protected $config;
+
+ public function set_config(\phpbb\config\config $config)
+ {
+ $this->config = $config;
+ }
+
+ public function set_user_loader(\phpbb\user_loader $user_loader)
+ {
+ $this->user_loader = $user_loader;
+ }
+
/**
* Is available
*/
@@ -263,13 +279,7 @@ class topic extends \phpbb\notification\type\base
}
/**
- * Function for preparing the data for insertion in an SQL query
- * (The service handles insertion)
- *
- * @param array $post Data from submit_post
- * @param array $pre_create_data Data from pre_create_insert_array()
- *
- * @return array Array of data ready to be inserted into the database
+ * {@inheritdoc}
*/
public function create_insert_array($post, $pre_create_data = array())
{
@@ -290,6 +300,6 @@ class topic extends \phpbb\notification\type\base
$this->notification_read = true;
}
- return parent::create_insert_array($post, $pre_create_data);
+ parent::create_insert_array($post, $pre_create_data);
}
}
diff --git a/phpBB/phpbb/notification/type/topic_in_queue.php b/phpBB/phpbb/notification/type/topic_in_queue.php
index cfdf748d38..ad2961525e 100644
--- a/phpBB/phpbb/notification/type/topic_in_queue.php
+++ b/phpBB/phpbb/notification/type/topic_in_queue.php
@@ -123,19 +123,22 @@ class topic_in_queue extends \phpbb\notification\type\topic
}
/**
- * Function for preparing the data for insertion in an SQL query
- * (The service handles insertion)
- *
- * @param array $topic Data from submit_post
- * @param array $pre_create_data Data from pre_create_insert_array()
- *
- * @return array Array of data ready to be inserted into the database
+ * {@inheritdoc}
*/
public function create_insert_array($topic, $pre_create_data = array())
{
- $data = parent::create_insert_array($topic, $pre_create_data);
+ parent::create_insert_array($topic, $pre_create_data);
+
+ $this->notification_time = time();
+ }
- $this->notification_time = $data['notification_time'] = time();
+ /**
+ * {@inheritdoc}
+ */
+ public function get_insert_array()
+ {
+ $data = parent::get_insert_array();
+ $data['notification_time'] = $this->notification_time;
return $data;
}
diff --git a/phpBB/phpbb/notification/type/type_interface.php b/phpBB/phpbb/notification/type/type_interface.php
index 8844ce1a38..9b4446ac47 100644
--- a/phpBB/phpbb/notification/type/type_interface.php
+++ b/phpBB/phpbb/notification/type/type_interface.php
@@ -177,14 +177,18 @@ interface type_interface
/**
* Function for preparing the data for insertion in an SQL query
- * (The service handles insertion)
*
* @param array $type_data The type specific data
* @param array $pre_create_data Data from pre_create_insert_array()
+ */
+ public function create_insert_array($type_data, $pre_create_data);
+
+ /**
+ * Function for getting the data for insertion in an SQL query
*
* @return array Array of data ready to be inserted into the database
*/
- public function create_insert_array($type_data, $pre_create_data);
+ public function get_insert_array();
/**
* Function for preparing the data for update in an SQL query
diff --git a/phpBB/phpbb/permissions.php b/phpBB/phpbb/permissions.php
index 82f59b5c20..c462f72a73 100644
--- a/phpBB/phpbb/permissions.php
+++ b/phpBB/phpbb/permissions.php
@@ -251,6 +251,7 @@ class permissions
'f_post' => array('lang' => 'ACL_F_POST', 'cat' => 'post'),
'f_sticky' => array('lang' => 'ACL_F_STICKY', 'cat' => 'post'),
'f_announce' => array('lang' => 'ACL_F_ANNOUNCE', 'cat' => 'post'),
+ 'f_announce_global' => array('lang' => 'ACL_F_ANNOUNCE_GLOBAL', 'cat' => 'post'),
'f_reply' => array('lang' => 'ACL_F_REPLY', 'cat' => 'post'),
'f_edit' => array('lang' => 'ACL_F_EDIT', 'cat' => 'post'),
'f_delete' => array('lang' => 'ACL_F_DELETE', 'cat' => 'post'),
diff --git a/phpBB/phpbb/session.php b/phpBB/phpbb/session.php
index 91b657262c..120142e64c 100644
--- a/phpBB/phpbb/session.php
+++ b/phpBB/phpbb/session.php
@@ -527,7 +527,7 @@ class session
*/
function session_create($user_id = false, $set_admin = false, $persist_login = false, $viewonline = true)
{
- global $SID, $_SID, $db, $config, $cache, $phpbb_root_path, $phpEx, $phpbb_container;
+ global $SID, $_SID, $db, $config, $cache, $phpbb_root_path, $phpEx, $phpbb_container, $phpbb_dispatcher;
$this->data = array();
@@ -902,6 +902,19 @@ class session
$_SID = '';
}
+ $session_data = $sql_ary;
+ /**
+ * Event to send new session data to extension
+ * Read-only event
+ *
+ * @event core.session_create_after
+ * @var array session_data Associative array of session keys to be updated
+ * @since 3.1.6-RC1
+ */
+ $vars = array('session_data');
+ extract($phpbb_dispatcher->trigger_event('core.session_create_after', compact($vars)));
+ unset($session_data);
+
return true;
}
@@ -915,13 +928,30 @@ class session
*/
function session_kill($new_session = true)
{
- global $SID, $_SID, $db, $config, $phpbb_root_path, $phpEx, $phpbb_container;
+ global $SID, $_SID, $db, $config, $phpbb_root_path, $phpEx, $phpbb_container, $phpbb_dispatcher;
$sql = 'DELETE FROM ' . SESSIONS_TABLE . "
WHERE session_id = '" . $db->sql_escape($this->session_id) . "'
AND session_user_id = " . (int) $this->data['user_id'];
$db->sql_query($sql);
+ $user_id = (int) $this->data['user_id'];
+ $session_id = $this->session_id;
+ /**
+ * Event to send session kill information to extension
+ * Read-only event
+ *
+ * @event core.session_kill_after
+ * @var int user_id user_id of the session user.
+ * @var string session_id current user's session_id
+ * @var bool new_session should we create new session for user
+ * @since 3.1.6-RC1
+ */
+ $vars = array('user_id', 'session_id', 'new_session');
+ extract($phpbb_dispatcher->trigger_event('core.session_kill_after', compact($vars)));
+ unset($user_id);
+ unset($session_id);
+
// Allow connecting logout with external auth method logout
/* @var $provider_collection \phpbb\auth\provider_collection */
$provider_collection = $phpbb_container->get('auth.provider_collection');
@@ -990,7 +1020,7 @@ class session
*/
function session_gc()
{
- global $db, $config, $phpbb_root_path, $phpEx, $phpbb_container;
+ global $db, $config, $phpbb_root_path, $phpEx, $phpbb_container, $phpbb_dispatcher;
$batch_size = 10;
@@ -1059,6 +1089,14 @@ class session
$db->sql_query($sql);
}
+ /**
+ * Event to trigger extension on session_gc
+ *
+ * @event core.session_gc_after
+ * @since 3.1.6-RC1
+ */
+ $phpbb_dispatcher->dispatch('core.session_gc_after');
+
return;
}
@@ -1558,12 +1596,24 @@ class session
*/
public function update_session($session_data, $session_id = null)
{
- global $db;
+ global $db, $phpbb_dispatcher;
$session_id = ($session_id) ? $session_id : $this->session_id;
$sql = 'UPDATE ' . SESSIONS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $session_data) . "
WHERE session_id = '" . $db->sql_escape($session_id) . "'";
$db->sql_query($sql);
+
+ /**
+ * Event to send update session information to extension
+ * Read-only event
+ *
+ * @event core.update_session_after
+ * @var array session_data Associative array of session keys to be updated
+ * @var string session_id current user's session_id
+ * @since 3.1.6-RC1
+ */
+ $vars = array('session_data', 'session_id');
+ extract($phpbb_dispatcher->trigger_event('core.update_session_after', compact($vars)));
}
}
diff --git a/phpBB/phpbb/template/twig/node/includecss.php b/phpBB/phpbb/template/twig/node/includecss.php
index 2ce63402aa..2dac154036 100644
--- a/phpBB/phpbb/template/twig/node/includecss.php
+++ b/phpBB/phpbb/template/twig/node/includecss.php
@@ -31,7 +31,7 @@ class includecss extends \phpbb\template\twig\node\includeasset
$compiler
->raw("<link href=\"' . ")
->raw("\$asset_file . '\"")
- ->raw(' rel="stylesheet" type="text/css" media="screen, projection" />')
+ ->raw(' rel="stylesheet" type="text/css" media="screen" />')
;
}
}
diff --git a/phpBB/phpbb/textformatter/s9e/factory.php b/phpBB/phpbb/textformatter/s9e/factory.php
index 2f6498197f..2aab97b667 100644
--- a/phpBB/phpbb/textformatter/s9e/factory.php
+++ b/phpBB/phpbb/textformatter/s9e/factory.php
@@ -324,6 +324,11 @@ class factory implements \phpbb\textformatter\cache_interface
$configurator->registeredVars['max_img_height'] = 0;
$configurator->registeredVars['max_img_width'] = 0;
+ // Load the Emoji plugin and modify its tag's template to obey viewsmilies
+ $configurator->Emoji->setImageSize(18);
+ $tag = $configurator->Emoji->getTag();
+ $tag->template = '<xsl:choose><xsl:when test="$S_VIEWSMILIES">' . str_replace('class="emoji"', 'class="smilies"', $tag->template) . '</xsl:when><xsl:otherwise><xsl:value-of select="."/></xsl:otherwise></xsl:choose>';
+
/**
* Modify the s9e\TextFormatter configurator after the default settings are set
*
diff --git a/phpBB/phpbb/textformatter/s9e/utils.php b/phpBB/phpbb/textformatter/s9e/utils.php
index 40479b3423..b317fe4a8d 100644
--- a/phpBB/phpbb/textformatter/s9e/utils.php
+++ b/phpBB/phpbb/textformatter/s9e/utils.php
@@ -70,6 +70,12 @@ class utils implements \phpbb\textformatter\utils_interface
$quote .= '=' . $this->format_attribute_value($attributes['author']);
unset($attributes['author']);
}
+
+ if (isset($attributes['user_id']) && $attributes['user_id'] == ANONYMOUS)
+ {
+ unset($attributes['user_id']);
+ }
+
ksort($attributes);
foreach ($attributes as $name => $value)
{
diff --git a/phpBB/phpbb/user.php b/phpBB/phpbb/user.php
index c33070d6f4..fc125f5edc 100644
--- a/phpBB/phpbb/user.php
+++ b/phpBB/phpbb/user.php
@@ -54,8 +54,8 @@ class user extends \phpbb\session
/**
* Constructor to set the lang path
*
- * @param string $datetime_class Class name of datetime class
- * @param \phpbb\language\language $lang phpBB's Language loader
+ * @param \phpbb\language\language $lang phpBB's Language loader
+ * @param string $datetime_class Class name of datetime class
*/
function __construct(\phpbb\language\language $lang, $datetime_class)
{