diff --git a/phpBB/config/default/container/services_notification.yml b/phpBB/config/default/container/services_notification.yml index c3bbcddfa6..c842656575 100644 --- a/phpBB/config/default/container/services_notification.yml +++ b/phpBB/config/default/container/services_notification.yml @@ -6,15 +6,11 @@ services: - @notification.method_collection - @service_container - @user_loader - - @config - @dispatcher - @dbal.conn - @cache - @user - - %core.root_path% - - %core.php_ext% - %tables.notification_types% - - %tables.notifications% - %tables.user_notifications% # ----- Notification's types ----- @@ -26,201 +22,108 @@ services: tags: - { name: service_collection, tag: notification.type } + notification.type.base: + abstract: true + arguments: + - @dbal.conn + - @user + - @auth + - %core.root_path% + - %core.php_ext% + - %tables.user_notifications% + + notification.type.admin_activate_user: + class: phpbb\notification\type\admin_activate_user + scope: prototype + parent: notification.type.base + calls: + - [set_user_loader, [@user_loader]] + - [set_config, [@config]] + tags: + - { name: notification.type } + notification.type.approve_post: class: phpbb\notification\type\approve_post scope: prototype - arguments: - - @user_loader - - @dbal.conn - - @cache.driver - - @user - - @auth - - @config - - %core.root_path% - - %core.php_ext% - - %tables.notification_types% - - %tables.notifications% - - %tables.user_notifications% + parent: notification.type.post tags: - { name: notification.type } notification.type.approve_topic: class: phpbb\notification\type\approve_topic scope: prototype - arguments: - - @user_loader - - @dbal.conn - - @cache.driver - - @user - - @auth - - @config - - %core.root_path% - - %core.php_ext% - - %tables.notification_types% - - %tables.notifications% - - %tables.user_notifications% + parent: notification.type.topic tags: - { name: notification.type } notification.type.bookmark: class: phpbb\notification\type\bookmark scope: prototype - arguments: - - @user_loader - - @dbal.conn - - @cache.driver - - @user - - @auth - - @config - - %core.root_path% - - %core.php_ext% - - %tables.notification_types% - - %tables.notifications% - - %tables.user_notifications% + parent: notification.type.post tags: - { name: notification.type } notification.type.disapprove_post: class: phpbb\notification\type\disapprove_post scope: prototype - arguments: - - @user_loader - - @dbal.conn - - @cache.driver - - @user - - @auth - - @config - - %core.root_path% - - %core.php_ext% - - %tables.notification_types% - - %tables.notifications% - - %tables.user_notifications% + parent: notification.type.post tags: - { name: notification.type } notification.type.disapprove_topic: class: phpbb\notification\type\disapprove_topic scope: prototype - arguments: - - @user_loader - - @dbal.conn - - @cache.driver - - @user - - @auth - - @config - - %core.root_path% - - %core.php_ext% - - %tables.notification_types% - - %tables.notifications% - - %tables.user_notifications% + parent: notification.type.topic tags: - { name: notification.type } notification.type.group_request: class: phpbb\notification\type\group_request scope: prototype - arguments: - - @user_loader - - @dbal.conn - - @cache.driver - - @user - - @auth - - @config - - %core.root_path% - - %core.php_ext% - - %tables.notification_types% - - %tables.notifications% - - %tables.user_notifications% + parent: notification.type.base + calls: + - [set_user_loader, [@user_loader]] tags: - { name: notification.type } notification.type.group_request_approved: class: phpbb\notification\type\group_request_approved scope: prototype - arguments: - - @user_loader - - @dbal.conn - - @cache.driver - - @user - - @auth - - @config - - %core.root_path% - - %core.php_ext% - - %tables.notification_types% - - %tables.notifications% - - %tables.user_notifications% + parent: notification.type.base tags: - { name: notification.type } notification.type.pm: class: phpbb\notification\type\pm scope: prototype - arguments: - - @user_loader - - @dbal.conn - - @cache.driver - - @user - - @auth - - @config - - %core.root_path% - - %core.php_ext% - - %tables.notification_types% - - %tables.notifications% - - %tables.user_notifications% + parent: notification.type.base + calls: + - [set_user_loader, [@user_loader]] + - [set_config, [@config]] tags: - { name: notification.type } notification.type.post: class: phpbb\notification\type\post scope: prototype - arguments: - - @user_loader - - @dbal.conn - - @cache.driver - - @user - - @auth - - @config - - %core.root_path% - - %core.php_ext% - - %tables.notification_types% - - %tables.notifications% - - %tables.user_notifications% + parent: notification.type.base + calls: + - [set_user_loader, [@user_loader]] + - [set_config, [@config]] tags: - { name: notification.type } notification.type.post_in_queue: class: phpbb\notification\type\post_in_queue scope: prototype - arguments: - - @user_loader - - @dbal.conn - - @cache.driver - - @user - - @auth - - @config - - %core.root_path% - - %core.php_ext% - - %tables.notification_types% - - %tables.notifications% - - %tables.user_notifications% + parent: notification.type.post tags: - { name: notification.type } notification.type.quote: class: phpbb\notification\type\quote scope: prototype - arguments: - - @user_loader - - @dbal.conn - - @cache.driver - - @user - - @auth - - @config - - %core.root_path% - - %core.php_ext% - - %tables.notification_types% - - %tables.notifications% - - %tables.user_notifications% + parent: notification.type.post calls: - [set_utils, [@text_formatter.utils]] tags: @@ -229,129 +132,48 @@ services: notification.type.report_pm: class: phpbb\notification\type\report_pm scope: prototype - arguments: - - @user_loader - - @dbal.conn - - @cache.driver - - @user - - @auth - - @config - - %core.root_path% - - %core.php_ext% - - %tables.notification_types% - - %tables.notifications% - - %tables.user_notifications% + parent: notification.type.pm tags: - { name: notification.type } notification.type.report_pm_closed: class: phpbb\notification\type\report_pm_closed scope: prototype - arguments: - - @user_loader - - @dbal.conn - - @cache.driver - - @user - - @auth - - @config - - %core.root_path% - - %core.php_ext% - - %tables.notification_types% - - %tables.notifications% - - %tables.user_notifications% + parent: notification.type.pm tags: - { name: notification.type } notification.type.report_post: class: phpbb\notification\type\report_post scope: prototype - arguments: - - @user_loader - - @dbal.conn - - @cache.driver - - @user - - @auth - - @config - - %core.root_path% - - %core.php_ext% - - %tables.notification_types% - - %tables.notifications% - - %tables.user_notifications% + parent: notification.type.post tags: - { name: notification.type } notification.type.report_post_closed: class: phpbb\notification\type\report_post_closed scope: prototype - arguments: - - @user_loader - - @dbal.conn - - @cache.driver - - @user - - @auth - - @config - - %core.root_path% - - %core.php_ext% - - %tables.notification_types% - - %tables.notifications% - - %tables.user_notifications% + parent: notification.type.post tags: - { name: notification.type } notification.type.topic: class: phpbb\notification\type\topic scope: prototype - arguments: - - @user_loader - - @dbal.conn - - @cache.driver - - @user - - @auth - - @config - - %core.root_path% - - %core.php_ext% - - %tables.notification_types% - - %tables.notifications% - - %tables.user_notifications% + parent: notification.type.base + calls: + - [set_user_loader, [@user_loader]] + - [set_config, [@config]] tags: - { name: notification.type } notification.type.topic_in_queue: class: phpbb\notification\type\topic_in_queue scope: prototype - arguments: - - @user_loader - - @dbal.conn - - @cache.driver - - @user - - @auth - - @config - - %core.root_path% - - %core.php_ext% - - %tables.notification_types% - - %tables.notifications% - - %tables.user_notifications% + parent: notification.type.topic tags: - { name: notification.type } - notification.type.admin_activate_user: - class: phpbb\notification\type\admin_activate_user - scope: prototype - arguments: - - @user_loader - - @dbal.conn - - @cache.driver - - @user - - @auth - - @config - - %core.root_path% - - %core.php_ext% - - %tables.notification_types% - - %tables.notifications% - - %tables.user_notifications% - tags: - - { name: notification.type } - # ----- Notification's methods ----- # Scope MUST be prototype for all the plugins to work. notification.method_collection: @@ -361,15 +183,26 @@ services: tags: - { name: service_collection, tag: notification.method } - notification.method.email: - class: phpbb\notification\method\email - scope: prototype + notification.method.board: + class: phpbb\notification\method\board + scope: prototype # scope MUST be prototype for this to work! arguments: - @user_loader - @dbal.conn - @cache.driver - @user - - @auth + - @config + - %tables.notification_types% + - %tables.notifications% + tags: + - { name: notification.method } + + notification.method.email: + class: phpbb\notification\method\email + scope: prototype + arguments: + - @user_loader + - @user - @config - %core.root_path% - %core.php_ext% @@ -381,10 +214,7 @@ services: scope: prototype arguments: - @user_loader - - @dbal.conn - - @cache.driver - @user - - @auth - @config - %core.root_path% - %core.php_ext% diff --git a/phpBB/includes/acp/acp_board.php b/phpBB/includes/acp/acp_board.php index 018eedda2a..6e636d2f7d 100644 --- a/phpBB/includes/acp/acp_board.php +++ b/phpBB/includes/acp/acp_board.php @@ -94,6 +94,7 @@ class acp_board 'allow_bbcode' => array('lang' => 'ALLOW_BBCODE', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'allow_smilies' => array('lang' => 'ALLOW_SMILIES', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'allow_sig' => array('lang' => 'ALLOW_SIG', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), + 'allow_board_notifications' => array('lang' => 'ALLOW_BOARD_NOTIFICATIONS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false), 'allow_nocensors' => array('lang' => 'ALLOW_NO_CENSORS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'allow_bookmarks' => array('lang' => 'ALLOW_BOOKMARKS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'allow_birthdays' => array('lang' => 'ALLOW_BIRTHDAYS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index d109fe0648..a987213337 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -624,7 +624,7 @@ function markread($mode, $forum_id = false, $topic_id = false, $post_time = 0, $ $phpbb_notifications = $phpbb_container->get('notification_manager'); // Mark all topic notifications read for this user - $phpbb_notifications->mark_notifications_read(array( + $phpbb_notifications->mark_notifications(array( 'notification.type.topic', 'notification.type.quote', 'notification.type.bookmark', @@ -694,7 +694,7 @@ function markread($mode, $forum_id = false, $topic_id = false, $post_time = 0, $ /* @var $phpbb_notifications \phpbb\notification\manager */ $phpbb_notifications = $phpbb_container->get('notification_manager'); - $phpbb_notifications->mark_notifications_read_by_parent(array( + $phpbb_notifications->mark_notifications_by_parent(array( 'notification.type.topic', 'notification.type.approve_topic', ), $forum_id, $user->data['user_id'], $post_time); @@ -711,7 +711,7 @@ function markread($mode, $forum_id = false, $topic_id = false, $post_time = 0, $ } $db->sql_freeresult($result); - $phpbb_notifications->mark_notifications_read_by_parent(array( + $phpbb_notifications->mark_notifications_by_parent(array( 'notification.type.quote', 'notification.type.bookmark', 'notification.type.post', @@ -818,12 +818,12 @@ function markread($mode, $forum_id = false, $topic_id = false, $post_time = 0, $ $phpbb_notifications = $phpbb_container->get('notification_manager'); // Mark post notifications read for this user in this topic - $phpbb_notifications->mark_notifications_read(array( + $phpbb_notifications->mark_notifications(array( 'notification.type.topic', 'notification.type.approve_topic', ), $topic_id, $user->data['user_id'], $post_time); - $phpbb_notifications->mark_notifications_read_by_parent(array( + $phpbb_notifications->mark_notifications_by_parent(array( 'notification.type.quote', 'notification.type.bookmark', 'notification.type.post', @@ -4254,12 +4254,12 @@ function page_header($page_title = '', $display_online_list = false, $item_id = // Output the notifications $notifications = false; - if ($config['load_notifications'] && $user->data['user_id'] != ANONYMOUS && $user->data['user_type'] != USER_IGNORE) + if ($config['load_notifications'] && $config['allow_board_notifications'] && $user->data['user_id'] != ANONYMOUS && $user->data['user_type'] != USER_IGNORE) { /* @var $phpbb_notifications \phpbb\notification\manager */ $phpbb_notifications = $phpbb_container->get('notification_manager'); - $notifications = $phpbb_notifications->load_notifications(array( + $notifications = $phpbb_notifications->load_notifications('notification.method.board', array( 'all_unread' => true, 'limit' => 5, )); @@ -4296,7 +4296,7 @@ function page_header($page_title = '', $display_online_list = false, $item_id = 'U_VIEW_ALL_NOTIFICATIONS' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=ucp_notifications'), 'U_MARK_ALL_NOTIFICATIONS' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=ucp_notifications&mode=notification_list&mark=all&token=' . $notification_mark_hash), 'U_NOTIFICATION_SETTINGS' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=ucp_notifications&mode=notification_options'), - 'S_NOTIFICATIONS_DISPLAY' => $config['load_notifications'], + 'S_NOTIFICATIONS_DISPLAY' => $config['load_notifications'] && $config['allow_board_notifications'], 'S_USER_NEW_PRIVMSG' => $user->data['user_new_privmsg'], 'S_USER_UNREAD_PRIVMSG' => $user->data['user_unread_privmsg'], diff --git a/phpBB/includes/functions_privmsgs.php b/phpBB/includes/functions_privmsgs.php index 26df5b9954..c8c2670986 100644 --- a/phpBB/includes/functions_privmsgs.php +++ b/phpBB/includes/functions_privmsgs.php @@ -884,7 +884,7 @@ function update_unread_status($unread, $msg_id, $user_id, $folder_id) /* @var $phpbb_notifications \phpbb\notification\manager */ $phpbb_notifications = $phpbb_container->get('notification_manager'); - $phpbb_notifications->mark_notifications_read('notification.type.pm', $msg_id, $user_id); + $phpbb_notifications->mark_notifications('notification.type.pm', $msg_id, $user_id); $sql = 'UPDATE ' . PRIVMSGS_TO_TABLE . " SET pm_unread = 0 diff --git a/phpBB/includes/mcp/mcp_pm_reports.php b/phpBB/includes/mcp/mcp_pm_reports.php index cc8e48dc91..6e1d594135 100644 --- a/phpBB/includes/mcp/mcp_pm_reports.php +++ b/phpBB/includes/mcp/mcp_pm_reports.php @@ -97,7 +97,7 @@ class mcp_pm_reports /* @var $phpbb_notifications \phpbb\notification\manager */ $phpbb_notifications = $phpbb_container->get('notification_manager'); - $phpbb_notifications->mark_notifications_read_by_parent('notification.type.report_pm', $report_id, $user->data['user_id']); + $phpbb_notifications->mark_notifications_by_parent('report_pm', $report_id, $user->data['user_id']); $pm_id = $report['pm_id']; $report_id = $report['report_id']; diff --git a/phpBB/includes/mcp/mcp_queue.php b/phpBB/includes/mcp/mcp_queue.php index 596364cefd..3488ea326d 100644 --- a/phpBB/includes/mcp/mcp_queue.php +++ b/phpBB/includes/mcp/mcp_queue.php @@ -166,7 +166,7 @@ class mcp_queue { $post_id = (int) $topic_info[$topic_id]['topic_first_post_id']; - $phpbb_notifications->mark_notifications_read('notification.type.topic_in_queue', $topic_id, $user->data['user_id']); + $phpbb_notifications->mark_notifications('topic_in_queue', $topic_id, $user->data['user_id']); } else { @@ -174,7 +174,7 @@ class mcp_queue } } - $phpbb_notifications->mark_notifications_read('notification.type.post_in_queue', $post_id, $user->data['user_id']); + $phpbb_notifications->mark_notifications('post_in_queue', $post_id, $user->data['user_id']); $post_info = phpbb_get_post_data(array($post_id), 'm_approve', true); @@ -738,7 +738,7 @@ class mcp_queue $phpbb_notifications->add_notifications(array('notification.type.quote'), $post_data); $phpbb_notifications->delete_notifications('notification.type.post_in_queue', $post_id); - $phpbb_notifications->mark_notifications_read(array( + $phpbb_notifications->mark_notifications(array( 'notification.type.quote', 'notification.type.bookmark', 'notification.type.post', @@ -974,8 +974,8 @@ class mcp_queue ), $topic_data); } - $phpbb_notifications->mark_notifications_read('notification.type.quote', $topic_data['post_id'], $user->data['user_id']); - $phpbb_notifications->mark_notifications_read('notification.type.topic', $topic_id, $user->data['user_id']); + $phpbb_notifications->mark_notifications('quote', $topic_data['post_id'], $user->data['user_id']); + $phpbb_notifications->mark_notifications('topic', $topic_id, $user->data['user_id']); if ($notify_poster) { diff --git a/phpBB/includes/mcp/mcp_reports.php b/phpBB/includes/mcp/mcp_reports.php index 30a2188b98..3970237058 100644 --- a/phpBB/includes/mcp/mcp_reports.php +++ b/phpBB/includes/mcp/mcp_reports.php @@ -142,7 +142,7 @@ class mcp_reports /* @var $phpbb_notifications \phpbb\notification\manager */ $phpbb_notifications = $phpbb_container->get('notification_manager'); - $phpbb_notifications->mark_notifications_read('notification.type.report_post', $post_id, $user->data['user_id']); + $phpbb_notifications->mark_notifications('report_post', $post_id, $user->data['user_id']); if (!$report_id && $report['report_closed']) { diff --git a/phpBB/includes/ucp/info/ucp_notifications.php b/phpBB/includes/ucp/info/ucp_notifications.php index 0f6a7a8d71..94e0467ccb 100644 --- a/phpBB/includes/ucp/info/ucp_notifications.php +++ b/phpBB/includes/ucp/info/ucp_notifications.php @@ -20,7 +20,7 @@ class ucp_notifications_info 'title' => 'UCP_NOTIFICATION_OPTIONS', 'modes' => array( 'notification_options' => array('title' => 'UCP_NOTIFICATION_OPTIONS', 'auth' => '', 'cat' => array('UCP_PREFS')), - 'notification_list' => array('title' => 'UCP_NOTIFICATION_LIST', 'auth' => '', 'cat' => array('UCP_MAIN')), + 'notification_list' => array('title' => 'UCP_NOTIFICATION_LIST', 'auth' => 'cfg_allow_board_notifications', 'cat' => array('UCP_MAIN')), ), ); } diff --git a/phpBB/includes/ucp/ucp_notifications.php b/phpBB/includes/ucp/ucp_notifications.php index 6d0d4f06a6..c291cc1ddf 100644 --- a/phpBB/includes/ucp/ucp_notifications.php +++ b/phpBB/includes/ucp/ucp_notifications.php @@ -70,15 +70,6 @@ class ucp_notifications $phpbb_notifications->delete_subscription($type, 0, $method_data['id']); } } - - if ($request->is_set_post(str_replace('.', '_', $type) . '_notification') && !isset($subscriptions[$type])) - { - $phpbb_notifications->add_subscription($type); - } - else if (!$request->is_set_post(str_replace('.', '_', $type) . '_notification') && isset($subscriptions[$type])) - { - $phpbb_notifications->delete_subscription($type); - } } } @@ -100,7 +91,7 @@ class ucp_notifications // Mark all items read if ($request->variable('mark', '') == 'all' && check_link_hash($request->variable('token', ''), 'mark_all_notifications_read')) { - $phpbb_notifications->mark_notifications_read(false, false, $user->data['user_id'], $form_time); + $phpbb_notifications->mark_notifications(false, false, $user->data['user_id'], $form_time); meta_refresh(3, $this->u_action); $message = $user->lang['NOTIFICATIONS_MARK_ALL_READ_SUCCESS']; @@ -131,11 +122,11 @@ class ucp_notifications if (!empty($mark_read)) { - $phpbb_notifications->mark_notifications_read_by_id($mark_read, $form_time); + $phpbb_notifications->mark_notifications_by_id($mark_read, $form_time); } } - $notifications = $phpbb_notifications->load_notifications(array( + $notifications = $phpbb_notifications->load_notifications('notification.method.board', array( 'start' => $start, 'limit' => $config['topics_per_page'], 'count_total' => true, @@ -196,8 +187,6 @@ class ucp_notifications 'NAME' => $user->lang($data['lang']), 'EXPLAIN' => (isset($user->lang[$data['lang'] . '_EXPLAIN'])) ? $user->lang($data['lang'] . '_EXPLAIN') : '', - - 'SUBSCRIBED' => (isset($subscriptions[$type])) ? true : false, )); foreach ($notification_methods as $method => $method_data) diff --git a/phpBB/index.php b/phpBB/index.php index 132cbd444f..dba961feb8 100644 --- a/phpBB/index.php +++ b/phpBB/index.php @@ -45,7 +45,7 @@ if (($mark_notification = $request->variable('mark_notification', 0))) /* @var $phpbb_notifications \phpbb\notification\manager */ $phpbb_notifications = $phpbb_container->get('notification_manager'); - $notification = $phpbb_notifications->load_notifications(array( + $notification = $phpbb_notifications->load_notifications('notification.method.board', array( 'notification_id' => $mark_notification, )); diff --git a/phpBB/install/schemas/schema_data.sql b/phpBB/install/schemas/schema_data.sql index 1f856f016c..c53c252e2f 100644 --- a/phpBB/install/schemas/schema_data.sql +++ b/phpBB/install/schemas/schema_data.sql @@ -107,6 +107,7 @@ INSERT INTO phpbb_config (config_name, config_value) VALUES ('email_max_chunk_si INSERT INTO phpbb_config (config_name, config_value) VALUES ('email_package_size', '20'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('enable_confirm', '1'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('enable_mod_rewrite', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_board_notifications', '1'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('enable_pm_icons', '1'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('enable_post_confirm', '1'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('feed_enable', '1'); @@ -813,9 +814,9 @@ INSERT INTO phpbb_profile_fields (field_name, field_type, field_ident, field_len INSERT INTO phpbb_profile_fields (field_name, field_type, field_ident, field_length, field_minlen, field_maxlen, field_novalue, field_default_value, field_validation, field_required, field_show_novalue, field_show_on_reg, field_show_on_pm, field_show_on_vt, field_show_on_ml, field_show_profile, field_hide, field_no_view, field_active, field_order, field_is_contact, field_contact_desc, field_contact_url) VALUES ('phpbb_googleplus', 'profilefields.type.googleplus', 'phpbb_googleplus', '20', '3', '255', '', '', '[\w]+', 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 13, 1, 'VIEW_GOOGLEPLUS_PROFILE', 'http://plus.google.com/%s'); # User Notification Options (for first user) -INSERT INTO phpbb_user_notifications (item_type, item_id, user_id, method) VALUES('notification.type.post', 0, 2, ''); +INSERT INTO phpbb_user_notifications (item_type, item_id, user_id, method) VALUES('notification.type.post', 0, 2, 'notification.method.board'); INSERT INTO phpbb_user_notifications (item_type, item_id, user_id, method) VALUES('notification.type.post', 0, 2, 'notification.method.email'); -INSERT INTO phpbb_user_notifications (item_type, item_id, user_id, method) VALUES('notification.type.topic', 0, 2, ''); +INSERT INTO phpbb_user_notifications (item_type, item_id, user_id, method) VALUES('notification.type.topic', 0, 2, 'notification.method.board'); INSERT INTO phpbb_user_notifications (item_type, item_id, user_id, method) VALUES('notification.type.topic', 0, 2, 'notification.method.email'); # POSTGRES COMMIT # diff --git a/phpBB/language/en/acp/board.php b/phpBB/language/en/acp/board.php index 8d6c1c141d..001775349a 100644 --- a/phpBB/language/en/acp/board.php +++ b/phpBB/language/en/acp/board.php @@ -99,6 +99,7 @@ $lang = array_merge($lang, array( 'ALLOW_TOPIC_NOTIFY' => 'Allow subscribing to topics', 'BOARD_PM' => 'Private messaging', 'BOARD_PM_EXPLAIN' => 'Enable private messaging for all users.', + 'ALLOW_BOARD_NOTIFICATIONS' => 'Allow board notifications', )); // Avatar Settings diff --git a/phpBB/language/en/common.php b/phpBB/language/en/common.php index 79d504a67d..cb99183dd8 100644 --- a/phpBB/language/en/common.php +++ b/phpBB/language/en/common.php @@ -447,6 +447,7 @@ $lang = array_merge($lang, array( 'NOTIFICATION_FORUM' => 'Forum: %1$s', 'NOTIFICATION_GROUP_REQUEST' => 'Group request from %1$s to join the group %2$s.', 'NOTIFICATION_GROUP_REQUEST_APPROVED' => 'Group request approved to join the group %1$s.', + 'NOTIFICATION_METHOD_INVALID' => 'The method "%s" does not refer to a valid notification method.', 'NOTIFICATION_PM' => 'Private Message from %1$s:', 'NOTIFICATION_POST' => array( 1 => 'Reply from %1$s in topic:', diff --git a/phpBB/language/en/ucp.php b/phpBB/language/en/ucp.php index 07751d1f7f..b346051108 100644 --- a/phpBB/language/en/ucp.php +++ b/phpBB/language/en/ucp.php @@ -327,6 +327,7 @@ $lang = array_merge($lang, array( 'NOTIFICATION_GROUP_MODERATION' => 'Moderation Notifications', 'NOTIFICATION_GROUP_ADMINISTRATION' => 'Administration Notifications', 'NOTIFICATION_GROUP_POSTING' => 'Posting Notifications', + 'NOTIFICATION_METHOD_BOARD' => 'Notifications', 'NOTIFICATION_METHOD_EMAIL' => 'Email', 'NOTIFICATION_METHOD_JABBER' => 'Jabber', 'NOTIFICATION_TYPE' => 'Notification type', 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 @@ + +* @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/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; @@ -50,18 +47,9 @@ class manager /** @var \phpbb\user */ 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); + $method = $this->get_method_class($method_name); - // 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)) + 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; - - 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->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); - } - } - - return array( - 'notifications' => $notifications, - 'unread_count' => $unread_count, - 'total_count' => $total_count, - ); } /** - * Mark notifications read + * 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); + } + + /** + * 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_read($notification_type_name, $item_id, $user_id, $time = false) + public function mark_notifications($notification_type_name, $item_id, $user_id, $time = false, $mark_read = true) { - $time = ($time !== false) ? $time : time(); + if (is_array($notification_type_name)) + { + $notification_type_id = $this->get_notification_type_ids($notification_type_name); + } + else if ($notification_type_name !== false) + { + $notification_type_id = $this->get_notification_type_id($notification_type_name); + } + else + { + $notification_type_id = false; + } - $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); + foreach ($this->get_available_subscription_methods() as $method) + { + $method->mark_notifications($notification_type_id, $item_id, $user_id, $time, $mark_read); + } } /** - * 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) + * + * @deprecated since 3.2 + */ + public function mark_notifications_read_by_parent($notification_type_name, $item_parent_id, $user_id, $time = false) + { + $this->mark_notifications_by_parent($notification_type_name, $item_parent_id, $user_id, $time); + } + + /** + * 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(); + 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); + } - $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); + 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] = array( - 'id' => $method->get_type(), - 'lang' => str_replace('.', '_', strtoupper($method->get_type())), - ); + $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] = $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); + foreach ($this->get_available_subscription_methods() as $method) + { + $method->purge_notifications($notification_type_id); + } - $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'); } 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); - - $this->config->set('read_notification_last_gc', time(), false); + foreach ($this->get_available_subscription_methods() as $method) + { + $method->prune_notifications($timestamp, $only_read); + } } /** - * Helper to get the notifications item type class and set it up - */ + * 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(); + } + } + + return $default_methods; + } + + /** + * 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 * @@ -58,31 +28,6 @@ abstract class base implements \phpbb\notification\method\method_interface */ protected $queue = array(); - /** - * Notification Method 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 - * @return \phpbb\notification\method\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) - { - $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; - } - /** * Set notification manager (required) * @@ -93,6 +38,36 @@ abstract class base implements \phpbb\notification\method\method_interface $this->notification_manager = $notification_manager; } + /** + * Is the method enable by default? + * + * @return bool + */ + public function is_enabled_by_default() + { + 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, + ); + } + /** * Add a notification to the queue * @@ -103,6 +78,55 @@ abstract class base implements \phpbb\notification\method\method_interface $this->queue[] = $notification; } + /** + * {@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 */ 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 @@ + +* @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 @@ -25,12 +25,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 * @@ -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 = $data['notification_time'] = time(); + $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/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,39 +21,21 @@ 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; @@ -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)) - { - // Do not create a new notification - unset($notify_users[$row['user_id']]); + $notified_users = $this->notification_manager->get_notified_users($this->get_type(), array( + 'item_parent_id' => self::get_item_parent_id($post), + 'read' => 0, + )); - $notification = $this->notification_manager->get_item_type_class($this->get_type(), $row); + foreach ($notified_users as $user => $notification_data) + { + unset($notify_users[$user]); + + /** @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 = $data['notification_time'] = time(); + $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/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 = $data['notification_time'] = time(); + $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/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)) - { - // Do not create a new notification - unset($notify_users[$row['user_id']]); + $notified_users = $this->notification_manager->get_notified_users($this->get_type(), array( + 'item_parent_id' => self::get_item_parent_id($post), + 'read' => 0, + )); - $notification = $this->notification_manager->get_item_type_class($this->get_type(), $row); + foreach ($notified_users as $user => $notification_data) + { + unset($notify_users[$user]); + + /** @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 = $data['notification_time'] = time(); + $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/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 = $data['notification_time'] = time(); + $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/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 = $data['notification_time'] = time(); + $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/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 = $data['notification_time'] = time(); + $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/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/styles/prosilver/template/ucp_notifications.html b/phpBB/styles/prosilver/template/ucp_notifications.html index 500bae0c47..1255d7a0d0 100644 --- a/phpBB/styles/prosilver/template/ucp_notifications.html +++ b/phpBB/styles/prosilver/template/ucp_notifications.html @@ -16,7 +16,6 @@ {notification_methods.NAME} - {L_NOTIFICATIONS} @@ -34,7 +33,6 @@ checked="checked" /> - checked="checked" /> diff --git a/tests/functional/notification_test.php b/tests/functional/notification_test.php index ec03f7a6a4..87c36dd4d1 100644 --- a/tests/functional/notification_test.php +++ b/tests/functional/notification_test.php @@ -11,6 +11,8 @@ * */ +require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; + /** * @group functional */ @@ -21,15 +23,15 @@ class phpbb_functional_notification_test extends phpbb_functional_test_case return array( // Rows inserted by phpBB/install/schemas/schema_data.sql // Also see PHPBB3-11460 - array('notification.type.post_notification', true), - array('notification.type.topic_notification', true), + array('notification.type.post_notification.method.board', true), + array('notification.type.topic_notification.method.board', true), array('notification.type.post_notification.method.email', true), array('notification.type.topic_notification.method.email', true), // Default behaviour for in-board notifications: // If user did not opt-out, in-board notifications are on. - array('notification.type.bookmark_notification', true), - array('notification.type.quote_notification', true), + array('notification.type.bookmark_notification.method.board', true), + array('notification.type.quote_notification.method.board', true), // Default behaviour for email notifications: // If user did not opt-in, email notifications are off. diff --git a/tests/mock/container_builder.php b/tests/mock/container_builder.php index 297e3a65e6..134589b0b8 100644 --- a/tests/mock/container_builder.php +++ b/tests/mock/container_builder.php @@ -52,7 +52,15 @@ class phpbb_mock_container_builder implements ContainerInterface { if ($this->has($id)) { - return $this->services[$id]; + $service = $this->services[$id]; + if (is_array($service) && is_callable($service[0])) + { + return call_user_func_array($service[0], $service[1]); + } + else + { + return $service; + } } throw new Exception('Could not find service: ' . $id); @@ -180,4 +188,9 @@ class phpbb_mock_container_builder implements ContainerInterface public function isScopeActive($name) { } + + public function isFrozen() + { + return false; + } } diff --git a/tests/mock/notification_manager.php b/tests/mock/notification_manager.php index 6a590bc0ca..952c0db489 100644 --- a/tests/mock/notification_manager.php +++ b/tests/mock/notification_manager.php @@ -32,19 +32,18 @@ class phpbb_mock_notification_manager ); } - public function mark_notifications_read() + public function mark_notifications() { } - public function mark_notifications_read_by_parent() + public function mark_notifications_by_parent() { } - public function mark_notifications_read_by_id() + public function mark_notifications_by_id() { } - public function add_notifications() { return array(); diff --git a/tests/mock/notification_type_post.php b/tests/mock/notification_type_post.php index 6d8f6dc504..fd2d1b63cd 100644 --- a/tests/mock/notification_type_post.php +++ b/tests/mock/notification_type_post.php @@ -21,7 +21,7 @@ if (!defined('IN_PHPBB')) class phpbb_mock_notification_type_post extends \phpbb\notification\type\post { - public function __construct($user_loader, $db, $cache, $user, $auth, $config, $phpbb_root_path, $php_ext, $notification_types_table, $notifications_table, $user_notifications_table) + public function __construct($user_loader, $db, $cache, $user, $auth, $config, $phpbb_root_path, $php_ext, $notification_types_table, $user_notifications_table) { $this->user_loader = $user_loader; $this->db = $db; @@ -34,7 +34,6 @@ class phpbb_mock_notification_type_post extends \phpbb\notification\type\post $this->php_ext = $php_ext; $this->notification_types_table = $notification_types_table; - $this->notifications_table = $notifications_table; - $this->user_notifications_table = $user_notifications_table; + $this->user_notifications_table = $user_notifications_table; } } diff --git a/tests/notification/base.php b/tests/notification/base.php index 45b0b6f179..1295f099f0 100644 --- a/tests/notification/base.php +++ b/tests/notification/base.php @@ -11,6 +11,10 @@ * */ +use Symfony\Component\Config\FileLocator; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; + require_once dirname(__FILE__) . '/manager_helper.php'; abstract class phpbb_tests_notification_base extends phpbb_database_test_case @@ -39,6 +43,13 @@ abstract class phpbb_tests_notification_base extends phpbb_database_test_case ); } + protected function get_notification_methods() + { + return array( + 'notification.method.board', + ); + } + protected function setUp() { parent::setUp(); @@ -55,6 +66,7 @@ abstract class phpbb_tests_notification_base extends phpbb_database_test_case 'allow_bookmarks' => true, 'allow_topic_notify' => true, 'allow_forum_notify' => true, + 'allow_board_notifications' => true, )); $lang_loader = new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx); $lang = new \phpbb\language\language($lang_loader); @@ -62,8 +74,9 @@ abstract class phpbb_tests_notification_base extends phpbb_database_test_case $this->user = $user; $this->user_loader = new \phpbb\user_loader($this->db, $phpbb_root_path, $phpEx, 'phpbb_users'); $auth = $this->auth = new phpbb_mock_notifications_auth(); + $cache_driver = new \phpbb\cache\driver\dummy(); $cache = $this->cache = new \phpbb\cache\service( - new \phpbb\cache\driver\dummy(), + $cache_driver, $this->config, $this->db, $phpbb_root_path, @@ -72,41 +85,62 @@ abstract class phpbb_tests_notification_base extends phpbb_database_test_case $this->phpbb_dispatcher = new phpbb_mock_event_dispatcher(); - $phpbb_container = $this->container = new phpbb_mock_container_builder(); + $phpbb_container = $this->container = new ContainerBuilder(); + $loader = new YamlFileLoader($phpbb_container, new FileLocator(__DIR__ . '/fixtures')); + $loader->load('services_notification.yml'); + $phpbb_container->set('user_loader', $this->user_loader); + $phpbb_container->set('user', $user); + $phpbb_container->set('config', $this->config); + $phpbb_container->set('dbal.conn', $this->db); + $phpbb_container->set('auth', $auth); + $phpbb_container->set('cache.driver', $cache_driver); + $phpbb_container->set('cache', $cache); + $phpbb_container->set('text_formatter.utils', new \phpbb\textformatter\s9e\utils()); + $phpbb_container->set('dispatcher', $this->phpbb_dispatcher); + $phpbb_container->setParameter('core.root_path', $phpbb_root_path); + $phpbb_container->setParameter('core.php_ext', $phpEx); + $phpbb_container->setParameter('tables.notifications', 'phpbb_notifications'); + $phpbb_container->setParameter('tables.user_notifications', 'phpbb_user_notifications'); + $phpbb_container->setParameter('tables.notification_types', 'phpbb_notification_types'); $this->notifications = new phpbb_notification_manager_helper( array(), array(), $this->container, $this->user_loader, - $this->config, $this->phpbb_dispatcher, $this->db, $this->cache, $this->user, - $phpbb_root_path, - $phpEx, 'phpbb_notification_types', - 'phpbb_notifications', 'phpbb_user_notifications' ); $phpbb_container->set('notification_manager', $this->notifications); + $phpbb_container->compile(); $this->notifications->setDependencies($this->auth, $this->config); $types = array(); foreach ($this->get_notification_types() as $type) { - $type_parts = explode('.', $type); - $class = $this->build_type('phpbb\notification\type\\' . array_pop($type_parts)); + $class = $this->build_type($type); $types[$type] = $class; - $this->container->set($type, $class); } $this->notifications->set_var('notification_types', $types); + $methods = array(); + foreach ($this->get_notification_methods() as $method) + { + $class = $this->container->get($method); + + $methods[$method] = $class; + } + + $this->notifications->set_var('notification_methods', $methods); + $this->db->sql_query('DELETE FROM phpbb_notification_types'); $this->db->sql_query('DELETE FROM phpbb_notifications'); $this->db->sql_query('DELETE FROM phpbb_user_notifications'); @@ -114,21 +148,14 @@ abstract class phpbb_tests_notification_base extends phpbb_database_test_case protected function build_type($type) { - global $phpbb_root_path, $phpEx; - - $instance = new $type($this->user_loader, $this->db, $this->cache->get_driver(), $this->user, $this->auth, $this->config, $phpbb_root_path, $phpEx, 'phpbb_notification_types', 'phpbb_notifications', 'phpbb_user_notifications'); - - if ($type === 'phpbb\\notification\\type\\quote') - { - $instance->set_utils(new \phpbb\textformatter\s9e\utils); - } + $instance = $this->container->get($type); return $instance; } protected function assert_notifications($expected, $options = array()) { - $notifications = $this->notifications->load_notifications(array_merge(array( + $notifications = $this->notifications->load_notifications('notification.method.board', array_merge(array( 'count_unread' => true, 'order_by' => 'notification_time', 'order_dir' => 'ASC', diff --git a/tests/notification/ext/test/notification/type/test.php b/tests/notification/ext/test/notification/type/test.php index b02a563f06..7f3b4a4ef1 100644 --- a/tests/notification/ext/test/notification/type/test.php +++ b/tests/notification/ext/test/notification/type/test.php @@ -47,12 +47,13 @@ class test extends \phpbb\notification\type\base { $this->notification_time = $post['post_time']; - return parent::create_insert_array($post, $pre_create_data); + parent::create_insert_array($post, $pre_create_data); } 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( diff --git a/tests/notification/fixtures/services_notification.yml b/tests/notification/fixtures/services_notification.yml new file mode 100644 index 0000000000..7eaa7e81ec --- /dev/null +++ b/tests/notification/fixtures/services_notification.yml @@ -0,0 +1,70 @@ +imports: + - { resource: ../../../phpBB/config/default/container/services_notification.yml } + +services: + notification_manager: + synthetic: true + + user_loader: + synthetic: true + + user: + synthetic: true + + config: + synthetic: true + + dbal.conn: + synthetic: true + + auth: + synthetic: true + + cache.driver: + synthetic: true + + path_helper: + synthetic: true + + groupposition.legend: + synthetic: true + + groupposition.teampage: + synthetic: true + + groupposition.teampage: + synthetic: true + + text_formatter.s9e.factory: + synthetic: true + + text_formatter.s9e.quote_helper: + synthetic: true + + text_formatter.parser: + synthetic: true + + text_formatter.s9e.parser: + synthetic: true + + text_formatter.renderer: + synthetic: true + + text_formatter.s9e.renderer: + synthetic: true + + text_formatter.utils: + synthetic: true + + text_formatter.s9e.utils: + synthetic: true + + text_formatter.data_access: + synthetic: true + + test: + class: phpbb\notification\type\test + scope: prototype + parent: notification.type.base + tags: + - { name: notification.type } diff --git a/tests/notification/fixtures/submit_post_notification.type.bookmark.xml b/tests/notification/fixtures/submit_post_notification.type.bookmark.xml index a1413e2cf8..7f069abc59 100644 --- a/tests/notification/fixtures/submit_post_notification.type.bookmark.xml +++ b/tests/notification/fixtures/submit_post_notification.type.bookmark.xml @@ -126,35 +126,35 @@ notification.type.bookmark 0 2 - + notification.method.board 1 notification.type.bookmark 0 3 - + notification.method.board 1 notification.type.bookmark 0 4 - + notification.method.board 1 notification.type.bookmark 0 5 - + notification.method.board 1 notification.type.bookmark 0 6 - + notification.method.board 0 diff --git a/tests/notification/fixtures/submit_post_notification.type.post.xml b/tests/notification/fixtures/submit_post_notification.type.post.xml index ed75787c70..a4bf9d3ee4 100644 --- a/tests/notification/fixtures/submit_post_notification.type.post.xml +++ b/tests/notification/fixtures/submit_post_notification.type.post.xml @@ -156,49 +156,49 @@ notification.type.post 0 2 - + notification.method.board 1 notification.type.post 0 3 - + notification.method.board 1 notification.type.post 0 4 - + notification.method.board 1 notification.type.post 0 5 - + notification.method.board 1 notification.type.post 0 6 - + notification.method.board 1 notification.type.post 0 7 - + notification.method.board 1 notification.type.post 0 8 - + notification.method.board 1 diff --git a/tests/notification/fixtures/submit_post_notification.type.post_in_queue.xml b/tests/notification/fixtures/submit_post_notification.type.post_in_queue.xml index 2dea8e34dd..0a955c48d2 100644 --- a/tests/notification/fixtures/submit_post_notification.type.post_in_queue.xml +++ b/tests/notification/fixtures/submit_post_notification.type.post_in_queue.xml @@ -110,49 +110,49 @@ notification.type.needs_approval 0 2 - + notification.method.board 1 notification.type.needs_approval 0 3 - + notification.method.board 1 notification.type.needs_approval 0 4 - + notification.method.board 1 notification.type.needs_approval 0 5 - + notification.method.board 1 notification.type.needs_approval 0 6 - + notification.method.board 1 notification.type.needs_approval 0 7 - + notification.method.board 0 notification.type.needs_approval 0 9 - + notification.method.board 1 diff --git a/tests/notification/fixtures/submit_post_notification.type.quote.xml b/tests/notification/fixtures/submit_post_notification.type.quote.xml index dd5bc620cd..c66830fbf5 100644 --- a/tests/notification/fixtures/submit_post_notification.type.quote.xml +++ b/tests/notification/fixtures/submit_post_notification.type.quote.xml @@ -98,35 +98,35 @@ notification.type.quote 0 2 - + notification.method.board 1 notification.type.quote 0 3 - + notification.method.board 1 notification.type.quote 0 4 - + notification.method.board 1 notification.type.quote 0 5 - + notification.method.board 1 notification.type.quote 0 6 - + notification.method.board 0 diff --git a/tests/notification/fixtures/submit_post_notification.type.topic.xml b/tests/notification/fixtures/submit_post_notification.type.topic.xml index 1ba8d05699..e0f6583f48 100644 --- a/tests/notification/fixtures/submit_post_notification.type.topic.xml +++ b/tests/notification/fixtures/submit_post_notification.type.topic.xml @@ -106,28 +106,28 @@ notification.type.topic 0 2 - + notification.method.board 1 notification.type.topic 0 6 - + notification.method.board 1 notification.type.topic 0 7 - + notification.method.board 1 notification.type.topic 0 8 - + notification.method.board 1 diff --git a/tests/notification/manager_helper.php b/tests/notification/manager_helper.php index 48bf5b177b..2e8699e1e0 100644 --- a/tests/notification/manager_helper.php +++ b/tests/notification/manager_helper.php @@ -37,40 +37,4 @@ class phpbb_notification_manager_helper extends \phpbb\notification\manager $this->auth = $auth; $this->config = $config; } - - /** - * Helper to get the notifications item type class and set it up - */ - public function get_item_type_class($item_type, $data = array()) - { - $item_parts = explode('.', $item_type); - $item_type = 'phpbb\notification\type\\' . array_pop($item_parts); - - $item = new $item_type($this->user_loader, $this->db, $this->cache->get_driver(), $this->user, $this->auth, $this->config, $this->phpbb_root_path, $this->php_ext, $this->notification_types_table, $this->notifications_table, $this->user_notifications_table); - - if ($item_type === 'phpbb\\notification\\type\\quote') - { - $item->set_utils(new \phpbb\textformatter\s9e\utils); - } - - $item->set_notification_manager($this); - - $item->set_initial_data($data); - - return $item; - } - - /** - * Helper to get the notifications method class and set it up - */ - public function get_method_class($method_name) - { - $method_name = 'phpbb\notification\method\\' . $method_name; - - $method = new $method_name($this->user_loader, $this->db, $this->cache->get_driver(), $this->user, $this->auth, $this->config, $this->phpbb_root_path, $this->php_ext, $this->notification_types_table, $this->notifications_table, $this->user_notifications_table); - - $method->set_notification_manager($this); - - return $method; - } } diff --git a/tests/notification/notification_test.php b/tests/notification/notification_test.php index 79fa5338c4..ec42aa193c 100644 --- a/tests/notification/notification_test.php +++ b/tests/notification/notification_test.php @@ -29,7 +29,7 @@ class phpbb_notification_test extends phpbb_tests_notification_base $quote_type_id = $this->notifications->get_notification_type_id('notification.type.quote'); $test_type_id = $this->notifications->get_notification_type_id('test'); - $this->assertEquals(array( + self::assertEquals(array( 'test' => $test_type_id, 'notification.type.quote' => $quote_type_id, 'notification.type.post' => $post_type_id, @@ -40,13 +40,13 @@ class phpbb_notification_test extends phpbb_tests_notification_base 'notification.type.post', ) )); - $this->assertEquals($quote_type_id, $this->notifications->get_notification_type_id('notification.type.quote')); + self::assertEquals($quote_type_id, $this->notifications->get_notification_type_id('notification.type.quote')); try { - $this->assertEquals(false, $this->notifications->get_notification_type_id('fail')); + self::assertEquals(false, $this->notifications->get_notification_type_id('fail')); - $this->fail('Non-existent type should throw an exception'); + self::fail('Non-existent type should throw an exception'); } catch (Exception $e) {} } @@ -55,15 +55,15 @@ class phpbb_notification_test extends phpbb_tests_notification_base { $subscription_types = $this->notifications->get_subscription_types(); - $this->assertArrayHasKey('NOTIFICATION_GROUP_MISCELLANEOUS', $subscription_types); - $this->assertArrayHasKey('NOTIFICATION_GROUP_POSTING', $subscription_types); + self::assertArrayHasKey('NOTIFICATION_GROUP_MISCELLANEOUS', $subscription_types); + self::assertArrayHasKey('NOTIFICATION_GROUP_POSTING', $subscription_types); - $this->assertArrayHasKey('notification.type.bookmark', $subscription_types['NOTIFICATION_GROUP_POSTING']); - $this->assertArrayHasKey('notification.type.post', $subscription_types['NOTIFICATION_GROUP_POSTING']); - $this->assertArrayHasKey('notification.type.quote', $subscription_types['NOTIFICATION_GROUP_POSTING']); - $this->assertArrayHasKey('notification.type.topic', $subscription_types['NOTIFICATION_GROUP_POSTING']); + self::assertArrayHasKey('notification.type.bookmark', $subscription_types['NOTIFICATION_GROUP_POSTING']); + self::assertArrayHasKey('notification.type.post', $subscription_types['NOTIFICATION_GROUP_POSTING']); + self::assertArrayHasKey('notification.type.quote', $subscription_types['NOTIFICATION_GROUP_POSTING']); + self::assertArrayHasKey('notification.type.topic', $subscription_types['NOTIFICATION_GROUP_POSTING']); - $this->assertArrayHasKey('notification.type.pm', $subscription_types['NOTIFICATION_GROUP_MISCELLANEOUS']); + self::assertArrayHasKey('notification.type.pm', $subscription_types['NOTIFICATION_GROUP_MISCELLANEOUS']); //get_subscription_types //get_subscription_methods @@ -72,33 +72,33 @@ class phpbb_notification_test extends phpbb_tests_notification_base public function test_subscriptions() { $expected_subscriptions = array( - 'notification.type.post' => array(''), - 'notification.type.topic' => array(''), - 'notification.type.quote' => array(''), - 'notification.type.bookmark' => array(''), - 'test' => array(''), - 'notification.type.pm' => array(''), + 'notification.type.post' => array('notification.method.board'), + 'notification.type.topic' => array('notification.method.board'), + 'notification.type.quote' => array('notification.method.board'), + 'notification.type.bookmark' => array('notification.method.board'), + 'test' => array('notification.method.board'), + 'notification.type.pm' => array('notification.method.board'), ); $subscriptions = $this->notifications->get_global_subscriptions(2); - foreach ($expected_subscriptions as $item_type => $methods) { + self::assertArrayHasKey($item_type, $subscriptions); $this->assert_array_content_equals($methods, $subscriptions[$item_type]); } foreach ($subscriptions as $item_type => $methods) { - $this->assert_array_content_equals($methods, $expected_subscriptions[$item_type]); + $this->assert_array_content_equals($methods, $expected_subscriptions[$item_type]); } - $this->notifications->delete_subscription('notification.type.post', 0, '', 2); + $this->notifications->delete_subscription('notification.type.post', 0, 'notification.method.board', 2); - $this->assertArrayNotHasKey('notification.type.post', $this->notifications->get_global_subscriptions(2)); + self::assertArrayNotHasKey('notification.type.post', $this->notifications->get_global_subscriptions(2)); - $this->notifications->add_subscription('notification.type.post', 0, '', 2); + $this->notifications->add_subscription('notification.type.post', 0, 'notification.method.board', 2); - $this->assertArrayHasKey('notification.type.post', $this->notifications->get_global_subscriptions(2)); + self::assertArrayHasKey('notification.type.post', $this->notifications->get_global_subscriptions(2)); } public function test_notifications() @@ -124,11 +124,11 @@ class phpbb_notification_test extends phpbb_tests_notification_base 'user_id' => 0, ))); - $this->assertEquals(array( + self::assertEquals(array( 'notifications' => array(), 'unread_count' => 0, 'total_count' => 0, - ), $this->notifications->load_notifications(array( + ), $this->notifications->load_notifications('notification.method.board', array( 'count_unread' => true, ))); diff --git a/tests/notification/submit_post_base.php b/tests/notification/submit_post_base.php index 04fb6658c3..72b25abf0a 100644 --- a/tests/notification/submit_post_base.php +++ b/tests/notification/submit_post_base.php @@ -11,6 +11,10 @@ * */ +use Symfony\Component\Config\FileLocator; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; + require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; require_once dirname(__FILE__) . '/../../phpBB/includes/functions_content.php'; require_once dirname(__FILE__) . '/../../phpBB/includes/functions_posting.php'; @@ -50,7 +54,7 @@ abstract class phpbb_notification_submit_post_base extends phpbb_database_test_c { parent::setUp(); - global $auth, $cache, $config, $db, $phpbb_container, $phpbb_dispatcher, $user, $request, $phpEx, $phpbb_root_path; + global $auth, $cache, $config, $db, $phpbb_container, $phpbb_dispatcher, $user, $request, $phpEx, $phpbb_root_path, $user_loader; // Database $this->db = $this->new_dbal(); @@ -69,10 +73,15 @@ abstract class phpbb_notification_submit_post_base extends phpbb_database_test_c ))); // Config - $config = new \phpbb\config\config(array('num_topics' => 1,'num_posts' => 1,)); + $config = new \phpbb\config\config(array( + 'num_topics' => 1, + 'num_posts' => 1, + 'allow_board_notifications' => true, + )); + $cache_driver = new \phpbb\cache\driver\dummy(); $cache = new \phpbb\cache\service( - new \phpbb\cache\driver\dummy(), + $cache_driver, $config, $db, $phpbb_root_path, @@ -99,39 +108,46 @@ abstract class phpbb_notification_submit_post_base extends phpbb_database_test_c $type_cast_helper = $this->getMock('\phpbb\request\type_cast_helper_interface'); $request = $this->getMock('\phpbb\request\request'); - // Container - $phpbb_container = new phpbb_mock_container_builder(); $phpbb_dispatcher = new phpbb_mock_event_dispatcher(); - $phpbb_container->set('content.visibility', new \phpbb\content_visibility($auth, $config, $phpbb_dispatcher, $db, $user, $phpbb_root_path, $phpEx, FORUMS_TABLE, POSTS_TABLE, TOPICS_TABLE, USERS_TABLE)); - $user_loader = new \phpbb\user_loader($db, $phpbb_root_path, $phpEx, USERS_TABLE); + // Container + $phpbb_container = new ContainerBuilder(); + $loader = new YamlFileLoader($phpbb_container, new FileLocator(__DIR__ . '/fixtures')); + $loader->load('services_notification.yml'); + $phpbb_container->set('user_loader', $user_loader); + $phpbb_container->set('user', $user); + $phpbb_container->set('config', $config); + $phpbb_container->set('dbal.conn', $db); + $phpbb_container->set('auth', $auth); + $phpbb_container->set('cache.driver', $cache_driver); + $phpbb_container->set('cache', $cache); + $phpbb_container->set('text_formatter.utils', new \phpbb\textformatter\s9e\utils()); + $phpbb_container->set('dispatcher', $phpbb_dispatcher); + $phpbb_container->setParameter('core.root_path', $phpbb_root_path); + $phpbb_container->setParameter('core.php_ext', $phpEx); + $phpbb_container->setParameter('tables.notifications', 'phpbb_notifications'); + $phpbb_container->setParameter('tables.user_notifications', 'phpbb_user_notifications'); + $phpbb_container->setParameter('tables.notification_types', 'phpbb_notification_types'); + $phpbb_container->set('content.visibility', new \phpbb\content_visibility($auth, $config, $phpbb_dispatcher, $db, $user, $phpbb_root_path, $phpEx, FORUMS_TABLE, POSTS_TABLE, TOPICS_TABLE, USERS_TABLE)); + $phpbb_container->compile(); + // Notification Types $notification_types = array('quote', 'bookmark', 'post', 'post_in_queue', 'topic', 'topic_in_queue', 'approve_topic', 'approve_post'); $notification_types_array = array(); foreach ($notification_types as $type) { - $class_name = '\phpbb\notification\type\\' . $type; - $class = new $class_name( - $user_loader, $db, $cache->get_driver(), $user, $auth, $config, - $phpbb_root_path, $phpEx, - NOTIFICATION_TYPES_TABLE, NOTIFICATIONS_TABLE, USER_NOTIFICATIONS_TABLE); - - if ($type === 'quote') - { - $class->set_utils(new \phpbb\textformatter\s9e\utils); - } - - $phpbb_container->set('notification.type.' . $type, $class); - + $class = $phpbb_container->get('notification.type.' . $type); $notification_types_array['notification.type.' . $type] = $class; } + // Methods Types + $notification_methods_array = array('notification.method.board' => $phpbb_container->get('notification.method.board')); + // Notification Manager - $phpbb_notifications = new \phpbb\notification\manager($notification_types_array, array(), - $phpbb_container, $user_loader, $config, $phpbb_dispatcher, $db, $cache, $user, - $phpbb_root_path, $phpEx, - NOTIFICATION_TYPES_TABLE, NOTIFICATIONS_TABLE, USER_NOTIFICATIONS_TABLE); + $phpbb_notifications = new \phpbb\notification\manager($notification_types_array, $notification_methods_array, + $phpbb_container, $user_loader, $phpbb_dispatcher, $db, $cache, $user, + NOTIFICATION_TYPES_TABLE, USER_NOTIFICATIONS_TABLE); $phpbb_container->set('notification_manager', $phpbb_notifications); } diff --git a/tests/notification/submit_post_type_quote_test.php b/tests/notification/submit_post_type_quote_test.php index 8ad6a62b09..3fab8c05ba 100644 --- a/tests/notification/submit_post_type_quote_test.php +++ b/tests/notification/submit_post_type_quote_test.php @@ -51,7 +51,8 @@ class phpbb_notification_submit_post_type_quote_test extends phpbb_notification_ */ public function submit_post_data() { - $parser = $this->get_test_case_helpers()->set_s9e_services()->get('text_formatter.parser'); + // The new mock container is needed because the data providers may be executed before phpunit call setUp() + $parser = $this->get_test_case_helpers()->set_s9e_services(new phpbb_mock_container_builder())->get('text_formatter.parser'); return array( /** diff --git a/tests/notification/user_list_trim_test.php b/tests/notification/user_list_trim_test.php index f7b4fcb215..d57fbf0485 100644 --- a/tests/notification/user_list_trim_test.php +++ b/tests/notification/user_list_trim_test.php @@ -61,7 +61,7 @@ class phpbb_notification_user_list_trim_test extends phpbb_database_test_case $user_loader->load_users(array(2, 3, 4, 5, 6)); $this->notification = new phpbb_mock_notification_type_post( - $user_loader, null, null, $user, null, null, $phpbb_root_path, $phpEx, null, null, null + $user_loader, null, null, $user, null, null, $phpbb_root_path, $phpEx, null, null ); } diff --git a/tests/test_framework/phpbb_test_case_helpers.php b/tests/test_framework/phpbb_test_case_helpers.php index 62a56ed693..70bd309653 100644 --- a/tests/test_framework/phpbb_test_case_helpers.php +++ b/tests/test_framework/phpbb_test_case_helpers.php @@ -426,24 +426,34 @@ class phpbb_test_case_helpers $cache_key_parser = $prefix . '_parser'; $cache_key_renderer = $prefix . '_renderer'; $container->set('cache.driver', $cache); - $container->setParameter('cache.dir', $cache_dir); + + if (!$container->isFrozen()) + { + $container->setParameter('cache.dir', $cache_dir); + } // Create a path_helper - if (!$container->has('path_helper')) + if (!$container->has('path_helper') || $container->getDefinition('path_helper')->isSynthetic()) { + $path_helper = new \phpbb\path_helper( + new \phpbb\symfony_request( + new phpbb_mock_request() + ), + new \phpbb\filesystem(), + $this->test_case->getMock('\phpbb\request\request'), + $phpbb_root_path, + $phpEx + ); + $container->set( 'path_helper', - new \phpbb\path_helper( - new \phpbb\symfony_request( - new phpbb_mock_request() - ), - new \phpbb\filesystem(), - $this->test_case->getMock('\phpbb\request\request'), - $phpbb_root_path, - $phpEx - ) + $path_helper ); } + else + { + $path_helper = $container->get('path_helper'); + } // Create an event dispatcher if ($container->has('dispatcher')) @@ -534,7 +544,7 @@ class phpbb_test_case_helpers // Calls configured in services.yml $renderer->configure_quote_helper($quote_helper); - $renderer->configure_smilies_path($config, $container->get('path_helper')); + $renderer->configure_smilies_path($config, $path_helper); $renderer->configure_user($user, $config, $auth); $container->set('text_formatter.renderer', $renderer);