Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
Total | |
0.00% |
0 / 1 |
|
53.57% |
15 / 28 |
CRAP | |
64.06% |
82 / 128 |
base | |
0.00% |
0 / 1 |
|
53.57% |
15 / 28 |
195.40 | |
64.06% |
82 / 128 |
__construct | |
100.00% |
1 / 1 |
1 | |
100.00% |
8 / 8 |
|||
set_notification_manager | |
100.00% |
1 / 1 |
1 | |
100.00% |
3 / 3 |
|||
set_initial_data | |
100.00% |
1 / 1 |
2 | |
100.00% |
3 / 3 |
|||
__get | |
100.00% |
1 / 1 |
2 | |
100.00% |
1 / 1 |
|||
__set | |
100.00% |
1 / 1 |
1 | |
100.00% |
2 / 2 |
|||
__toString | |
0.00% |
0 / 1 |
6.00 | |
0.00% |
0 / 1 |
|||
get_data | |
100.00% |
1 / 1 |
3 | |
100.00% |
1 / 1 |
|||
set_data | |
100.00% |
1 / 1 |
1 | |
100.00% |
2 / 2 |
|||
create_insert_array | |
100.00% |
1 / 1 |
1 | |
100.00% |
7 / 7 |
|||
get_insert_array | |
100.00% |
1 / 1 |
1 | |
100.00% |
3 / 3 |
|||
create_update_array | |
100.00% |
1 / 1 |
1 | |
100.00% |
7 / 7 |
|||
mark_read | |
0.00% |
0 / 1 |
2.00 | |
0.00% |
0 / 1 |
|||
mark_unread | |
0.00% |
0 / 1 |
2.00 | |
0.00% |
0 / 1 |
|||
get_redirect_url | |
0.00% |
0 / 1 |
2.00 | |
0.00% |
0 / 1 |
|||
prepare_for_display | |
0.00% |
0 / 1 |
30.00 | |
0.00% |
0 / 16 |
|||
get_unsubscribe_url | |
0.00% |
0 / 1 |
2.00 | |
0.00% |
0 / 1 |
|||
get_style_class | |
0.00% |
0 / 1 |
2.00 | |
0.00% |
0 / 1 |
|||
get_avatar | |
0.00% |
0 / 1 |
2.00 | |
0.00% |
0 / 1 |
|||
get_reference | |
0.00% |
0 / 1 |
2.00 | |
0.00% |
0 / 1 |
|||
get_forum | |
0.00% |
0 / 1 |
2.00 | |
0.00% |
0 / 1 |
|||
get_reason | |
0.00% |
0 / 1 |
2.00 | |
0.00% |
0 / 1 |
|||
get_load_special | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
load_special | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
is_available | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
pre_create_insert_array | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
check_user_notification_options | |
0.00% |
0 / 1 |
18.77 | |
74.42% |
32 / 43 |
|||
mark | |
0.00% |
0 / 1 |
6.00 | |
0.00% |
0 / 9 |
|||
get_authorised_recipients | |
100.00% |
1 / 1 |
4 | |
100.00% |
9 / 9 |
<?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\db\driver\driver_interface */ | |
protected $db; | |
/** @var \phpbb\language\language */ | |
protected $language; | |
/** @var \phpbb\user */ | |
protected $user; | |
/** @var \phpbb\auth\auth */ | |
protected $auth; | |
/** @var string */ | |
protected $phpbb_root_path; | |
/** @var string */ | |
protected $php_ext; | |
/** @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') | |
*/ | |
static public $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; | |
/** | |
* Identification 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\db\driver\driver_interface $db | |
* @param \phpbb\language\language $language | |
* @param \phpbb\user $user | |
* @param \phpbb\auth\auth $auth | |
* @param string $phpbb_root_path | |
* @param string $php_ext | |
* @param string $user_notifications_table | |
*/ | |
public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\language\language $language, \phpbb\user $user, \phpbb\auth\auth $auth, $phpbb_root_path, $php_ext, $user_notifications_table) | |
{ | |
$this->db = $db; | |
$this->language = $language; | |
$this->user = $user; | |
$this->auth = $auth; | |
$this->phpbb_root_path = $phpbb_root_path; | |
$this->php_ext = $php_ext; | |
$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; | |
} | |
/** | |
* {@inheritdoc} | |
*/ | |
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); | |
} | |
/** | |
* {@inheritdoc} | |
*/ | |
public function get_insert_array() | |
{ | |
$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) | |
{ | |
$this->create_insert_array($type_data); | |
$data = $this->get_insert_array(); | |
// 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 | |
* @return false | |
*/ | |
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 notification (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 notification (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) | |
* | |
* @param array $data | |
* @param array $notifications | |
*/ | |
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) | |
* | |
* @param array $type_data | |
* @param array $notify_users | |
* @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|bool $user_ids User IDs to check if they want to receive notifications | |
* (Bool False to check all users besides anonymous and bots (USER_IGNORE)) | |
* @param array $options | |
* @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 = $output = 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)) | |
{ | |
if (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']] = $row['notify']; | |
if (!isset($output[$row['user_id']])) | |
{ | |
$output[$row['user_id']] = array(); | |
} | |
if ($row['notify']) | |
{ | |
$output[$row['user_id']][] = $row['method']; | |
} | |
} | |
$this->db->sql_freeresult($result); | |
$default_methods = $this->notification_manager->get_default_methods(); | |
foreach ($user_ids as $user_id) | |
{ | |
if (isset($options['ignore_users'][$user_id])) | |
{ | |
continue; | |
} | |
if (!array_key_exists($user_id, $rowset)) | |
{ | |
// No rows at all for this user, use the default methods | |
$output[$user_id] = $default_methods; | |
} | |
else | |
{ | |
foreach ($default_methods as $default_method) | |
{ | |
if (!array_key_exists($default_method, $rowset[$user_id])) | |
{ | |
// No user preference for this type recorded, but it should be enabled by default. | |
$output[$user_id][] = $default_method; | |
} | |
} | |
} | |
} | |
return $output; | |
} | |
/** | |
* 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; | |
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; | |
} | |
else | |
{ | |
$this->notification_manager->mark_notifications($this->get_type(), (int) $this->item_id, (int) $this->user_id, false, $this->notification_read); | |
} | |
return null; | |
} | |
/** | |
* 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); | |
} | |
} |