diff options
author | Maat <maat-pub@mageia.biz> | 2020-05-08 18:29:30 +0200 |
---|---|---|
committer | Maat <maat-pub@mageia.biz> | 2020-05-08 21:36:04 +0200 |
commit | 36bc1870f21fac04736a1049c1d5b8e127d729f4 (patch) | |
tree | 9d102331eeaf1ef3cd23e656320d7c08e65757ed /phpBB/phpbb/notification/type/base.php | |
parent | 8875d385d0579b451dac4d9bda465172b4f69ee0 (diff) | |
parent | 149375253685b3a38996f63015a74b7a0f53aa14 (diff) | |
download | forums-36bc1870f21fac04736a1049c1d5b8e127d729f4.tar forums-36bc1870f21fac04736a1049c1d5b8e127d729f4.tar.gz forums-36bc1870f21fac04736a1049c1d5b8e127d729f4.tar.bz2 forums-36bc1870f21fac04736a1049c1d5b8e127d729f4.tar.xz forums-36bc1870f21fac04736a1049c1d5b8e127d729f4.zip |
Merge remote-tracking branch 'upstream/prep-release-3.1.11'
Diffstat (limited to 'phpBB/phpbb/notification/type/base.php')
-rw-r--r-- | phpBB/phpbb/notification/type/base.php | 569 |
1 files changed, 569 insertions, 0 deletions
diff --git a/phpBB/phpbb/notification/type/base.php b/phpBB/phpbb/notification/type/base.php new file mode 100644 index 0000000000..4ead06071e --- /dev/null +++ b/phpBB/phpbb/notification/type/base.php @@ -0,0 +1,569 @@ +<?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\type; + +/** +* Base notifications class +*/ +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; + + /** @var string */ + protected $php_ext; + + /** @var string */ + protected $notification_types_table; + + /** @var string */ + protected $notifications_table; + + /** @var string */ + protected $user_notifications_table; + + /** + * Notification option data (for outputting to the user) + * + * @var bool|array False if the service should use its default data + * Array of data (including keys 'id', 'lang', and 'group') + */ + public static $notification_option = false; + + /** + * The notification_type_id, set upon creation of the class + * This is the notification_type_id from the notification_types table + * + * @var int + */ + protected $notification_type_id; + + /** + * Indentification data + * notification_type_id - ID of the item type (auto generated, from notification types table) + * item_id - ID of the item (e.g. post_id, msg_id) + * item_parent_id - Parent item id (ex: for topic => forum_id, for post => topic_id, etc) + * user_id + * notification_read + * notification_time + * notification_data (special serialized field that each notification type can use to store stuff) + * + * @var array $data Notification row from the database + * This must be private, all interaction should use __get(), __set(), get_data(), set_data() + */ + private $data = array(); + + /** + * 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) + { + $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; + } + + /** + * Set notification manager (required) + * + * @param \phpbb\notification\manager $notification_manager + */ + public function set_notification_manager(\phpbb\notification\manager $notification_manager) + { + $this->notification_manager = $notification_manager; + + $this->notification_type_id = $this->notification_manager->get_notification_type_id($this->get_type()); + } + + /** + * Set initial data from the database + * + * @param array $data Row directly from the database + */ + public function set_initial_data($data = array()) + { + // The row from the database (unless this is a new notification we're going to add) + $this->data = $data; + $this->data['notification_data'] = (isset($this->data['notification_data'])) ? unserialize($this->data['notification_data']) : array(); + } + + /** + * Magic method to get data from this notification + * + * @param mixed $name + * @return mixed + */ + public function __get($name) + { + return (!isset($this->data[$name])) ? null : $this->data[$name]; + } + + + /** + * Magic method to set data on this notification + * + * @param mixed $name + * @param mixed $value + * + * @return null + */ + public function __set($name, $value) + { + $this->data[$name] = $value; + } + + + /** + * Magic method to get a string of this notification + * + * Primarily for testing + * + * @return mixed + */ + public function __toString() + { + return (!empty($this->data)) ? var_export($this->data, true) : $this->get_type(); + } + + /** + * Get special data (only important for the classes that extend this) + * + * @param string $name Name of the variable to get + * @return mixed + */ + protected function get_data($name) + { + return ($name === false) ? $this->data['notification_data'] : ((isset($this->data['notification_data'][$name])) ? $this->data['notification_data'][$name] : null); + } + + /** + * Set special data (only important for the classes that extend this) + * + * @param string $name Name of the variable to set + * @param mixed $value Value to set to the variable + * @return mixed + */ + protected function set_data($name, $value) + { + $this->data['notification_data'][$name] = $value; + } + + /** + * 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 + */ + public function create_insert_array($type_data, $pre_create_data = array()) + { + // Defaults + $this->data = array_merge(array( + 'item_id' => static::get_item_id($type_data), + 'notification_type_id' => $this->notification_type_id, + 'item_parent_id' => static::get_item_parent_id($type_data), + + 'notification_time' => time(), + 'notification_read' => false, + + 'notification_data' => array(), + ), $this->data); + + $data = $this->data; + + $data['notification_data'] = serialize($data['notification_data']); + + return $data; + } + + /** + * Function for preparing the data for update in an SQL query + * (The service handles insertion) + * + * @param array $type_data Data unique to this notification type + * @return array Array of data ready to be updated in the database + */ + public function create_update_array($type_data) + { + $data = $this->create_insert_array($type_data); + + // Unset data unique to each row + unset( + $data['notification_time'], // Also unsetting time, since it always tries to change the time to current (if you actually need to change the time, over-ride this function) + $data['notification_id'], + $data['notification_read'], + $data['user_id'] + ); + + return $data; + } + + /** + * Mark this item read + * + * @param bool $return True to return a string containing the SQL code to update this item, False to execute it (Default: False) + * @return string|null If $return is False, nothing will be returned, else the sql code to update this item + */ + public function mark_read($return = false) + { + return $this->mark(false, $return); + } + + /** + * Mark this item unread + * + * @param bool $return True to return a string containing the SQL code to update this item, False to execute it (Default: False) + * @return string|null If $return is False, nothing will be returned, else the sql code to update this item + */ + public function mark_unread($return = false) + { + return $this->mark(true, $return); + } + + /** + * {inheritDoc} + */ + public function get_redirect_url() + { + return $this->get_url(); + } + + /** + * Prepare to output the notification to the template + * + * @return array Template variables + */ + public function prepare_for_display() + { + $mark_hash = generate_link_hash('mark_notification_read'); + + if ($this->get_url()) + { + $u_mark_read = append_sid($this->phpbb_root_path . 'index.' . $this->php_ext, 'mark_notification=' . $this->notification_id . '&hash=' . $mark_hash); + } + else + { + $redirect = (($this->user->page['page_dir']) ? $this->user->page['page_dir'] . '/' : '') . $this->user->page['page_name'] . (($this->user->page['query_string']) ? '?' . $this->user->page['query_string'] : ''); + + $u_mark_read = append_sid($this->phpbb_root_path . 'index.' . $this->php_ext, 'mark_notification=' . $this->notification_id . '&hash=' . $mark_hash . '&redirect=' . urlencode($redirect)); + } + + return array( + 'NOTIFICATION_ID' => $this->notification_id, + 'STYLING' => $this->get_style_class(), + 'AVATAR' => $this->get_avatar(), + 'FORMATTED_TITLE' => $this->get_title(), + 'REFERENCE' => $this->get_reference(), + 'FORUM' => $this->get_forum(), + 'REASON' => $this->get_reason(), + 'URL' => $this->get_url(), + 'TIME' => $this->user->format_date($this->notification_time), + 'UNREAD' => !$this->notification_read, + 'U_MARK_READ' => (!$this->notification_read) ? $u_mark_read : '', + ); + } + + /** + * -------------- Fall back functions ------------------- + */ + + /** + * URL to unsubscribe to this notification (fall back) + * + * @param string|bool $method Method name to unsubscribe from (email|jabber|etc), False to unsubscribe from all notifications for this item + */ + public function get_unsubscribe_url($method = false) + { + return false; + } + + /** + * Get the CSS style class of the notification (fall back) + * + * @return string + */ + public function get_style_class() + { + return ''; + } + + /** + * Get the user's avatar (fall back) + * + * @return string + */ + public function get_avatar() + { + return ''; + } + + /** + * Get the reference of the notifcation (fall back) + * + * @return string + */ + public function get_reference() + { + return ''; + } + + /** + * Get the forum of the notification reference (fall back) + * + * @return string + */ + public function get_forum() + { + return ''; + } + + /** + * Get the reason for the notifcation (fall back) + * + * @return string + */ + public function get_reason() + { + return ''; + } + + /** + * Get the special items to load (fall back) + * + * @return array + */ + public function get_load_special() + { + return array(); + } + + /** + * Load the special items (fall back) + */ + public function load_special($data, $notifications) + { + return; + } + + /** + * Is available (fall back) + * + * @return bool + */ + public function is_available() + { + return true; + } + + /** + * Pre create insert array function (fall back) + * + * @return array + */ + public function pre_create_insert_array($type_data, $notify_users) + { + return array(); + } + + /** + * -------------- Helper functions ------------------- + */ + + /** + * Find the users who want to receive notifications (helper) + * + * @param array $user_ids User IDs to check if they want to receive notifications + * (Bool False to check all users besides anonymous and bots (USER_IGNORE)) + * + * @return array + */ + protected function check_user_notification_options($user_ids = false, $options = array()) + { + $options = array_merge(array( + 'ignore_users' => array(), + 'item_type' => $this->get_type(), + 'item_id' => 0, // Global by default + ), $options); + + if ($user_ids === false) + { + $user_ids = array(); + + $sql = 'SELECT user_id + FROM ' . USERS_TABLE . ' + WHERE user_id <> ' . ANONYMOUS . ' + AND user_type <> ' . USER_IGNORE; + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + $user_ids[] = $row['user_id']; + } + $this->db->sql_freeresult($result); + } + + if (empty($user_ids)) + { + return array(); + } + + $rowset = $resulting_user_ids = array(); + + $sql = 'SELECT user_id, method, notify + FROM ' . $this->user_notifications_table . ' + WHERE ' . $this->db->sql_in_set('user_id', $user_ids) . " + AND item_type = '" . $this->db->sql_escape($options['item_type']) . "' + AND item_id = " . (int) $options['item_id']; + $result = $this->db->sql_query($sql); + + while ($row = $this->db->sql_fetchrow($result)) + { + $resulting_user_ids[] = $row['user_id']; + + if (!$row['notify'] || (isset($options['ignore_users'][$row['user_id']]) && in_array($row['method'], $options['ignore_users'][$row['user_id']]))) + { + continue; + } + + if (!isset($rowset[$row['user_id']])) + { + $rowset[$row['user_id']] = array(); + } + + $rowset[$row['user_id']][] = $row['method']; + } + + $this->db->sql_freeresult($result); + + foreach ($user_ids as $user_id) + { + 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(''); + } + } + + return $rowset; + } + + /** + * Mark this item read/unread helper + * + * @param bool $unread Unread (True/False) (Default: False) + * @param bool $return True to return a string containing the SQL code to update this item, False to execute it (Default: False) + * @return string|null If $return is False, nothing will be returned, else the sql code to update this item + */ + protected function mark($unread = true, $return = false) + { + $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) + { + return $where; + } + + $sql = 'UPDATE ' . $this->notifications_table . ' + SET notification_read = ' . (int) $this->notification_read . ' + WHERE ' . $where; + $this->db->sql_query($sql); + } + + /** + * Get a list of users that are authorised to receive notifications + * + * @param array $users Array of users that have subscribed to a notification + * @param int $forum_id Forum ID of the forum + * @param array $options Array of notification options + * @param bool $sort Whether the users array should be sorted. Default: false + * @return array Array of users that are authorised recipients + */ + protected function get_authorised_recipients($users, $forum_id, $options, $sort = false) + { + if (empty($users)) + { + return array(); + } + + $users = array_unique($users); + + if ($sort) + { + sort($users); + } + + $auth_read = $this->auth->acl_get_list($users, 'f_read', $forum_id); + + if (empty($auth_read)) + { + return array(); + } + + return $this->check_user_notification_options($auth_read[$forum_id]['f_read'], $options); + } +} |