/phpBB/phpbb/notification/type/post.php
PHP | 448 lines | 257 code | 61 blank | 130 comment | 28 complexity | 962109e1db8d43a192d1d8eeb76fe84e MD5 | raw file
Possible License(s): AGPL-1.0
- <?php
- /**
- *
- * This file is part of the phpBB Forum Software package.
- *
- * @copyright (c) phpBB Limited <https://www.phpbb.com>
- * @license GNU General Public License, version 2 (GPL-2.0)
- *
- * For full copyright and license information, please see
- * the docs/CREDITS.txt file.
- *
- */
- namespace phpbb\notification\type;
- /**
- * Post notifications class
- * This class handles notifications for replies to a topic
- */
- class post extends \phpbb\notification\type\base
- {
- /**
- * Get notification type name
- *
- * @return string
- */
- public function get_type()
- {
- return 'post';
- }
- /**
- * Language key used to output the text
- *
- * @var string
- */
- protected $language_key = 'NOTIFICATION_POST';
- /**
- * Inherit notification read status from post.
- *
- * @var bool
- */
- protected $inherit_read_status = true;
- /**
- * Notification option data (for outputting to the user)
- *
- * @var bool|array False if the service should use it's default data
- * Array of data (including keys 'id', 'lang', and 'group')
- */
- public static $notification_option = array(
- 'lang' => 'NOTIFICATION_TYPE_POST',
- 'group' => 'NOTIFICATION_GROUP_POSTING',
- );
- /**
- * Is available
- */
- public function is_available()
- {
- return $this->config['allow_topic_notify'];
- }
- /**
- * Get the id of the item
- *
- * @param array $post The data from the post
- */
- public static function get_item_id($post)
- {
- return (int) $post['post_id'];
- }
- /**
- * Get the id of the parent
- *
- * @param array $post The data from the post
- */
- public static function get_item_parent_id($post)
- {
- return (int) $post['topic_id'];
- }
- /**
- * Find the users who want to receive notifications
- *
- * @param array $post Data from
- *
- * @return array
- */
- public function find_users_for_notification($post, $options = array())
- {
- $options = array_merge(array(
- 'ignore_users' => array(),
- ), $options);
- $users = array();
- $sql = 'SELECT user_id
- FROM ' . TOPICS_WATCH_TABLE . '
- WHERE topic_id = ' . (int) $post['topic_id'] . '
- AND notify_status = ' . NOTIFY_YES . '
- AND user_id <> ' . (int) $post['poster_id'];
- $result = $this->db->sql_query($sql);
- while ($row = $this->db->sql_fetchrow($result))
- {
- $users[] = (int) $row['user_id'];
- }
- $this->db->sql_freeresult($result);
- $sql = 'SELECT user_id
- FROM ' . FORUMS_WATCH_TABLE . '
- WHERE forum_id = ' . (int) $post['forum_id'] . '
- AND notify_status = ' . NOTIFY_YES . '
- AND user_id <> ' . (int) $post['poster_id'];
- $result = $this->db->sql_query($sql);
- while ($row = $this->db->sql_fetchrow($result))
- {
- $users[] = (int) $row['user_id'];
- }
- $this->db->sql_freeresult($result);
- if (empty($users))
- {
- return array();
- }
- $users = array_unique($users);
- sort($users);
- $auth_read = $this->auth->acl_get_list($users, 'f_read', $post['forum_id']);
- if (empty($auth_read))
- {
- return array();
- }
- $notify_users = $this->check_user_notification_options($auth_read[$post['forum_id']]['f_read'], $options);
- // 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']]);
- $notification = $this->notification_manager->get_item_type_class($this->get_type(), $row);
- $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->db->sql_freeresult($result);
- return $notify_users;
- }
- /**
- * Get the user's avatar
- */
- public function get_avatar()
- {
- return $this->user_loader->get_avatar($this->get_data('poster_id'));
- }
- /**
- * Get the HTML formatted title of this notification
- *
- * @return string
- */
- public function get_title()
- {
- $responders = $this->get_data('responders');
- $usernames = array();
- if (!is_array($responders))
- {
- $responders = array();
- }
- $responders = array_merge(array(array(
- 'poster_id' => $this->get_data('poster_id'),
- 'username' => $this->get_data('post_username'),
- )), $responders);
- $responders_cnt = sizeof($responders);
- $responders = $this->trim_user_ary($responders);
- $trimmed_responders_cnt = $responders_cnt - sizeof($responders);
- foreach ($responders as $responder)
- {
- if ($responder['username'])
- {
- $usernames[] = $responder['username'];
- }
- else
- {
- $usernames[] = $this->user_loader->get_username($responder['poster_id'], 'no_profile');
- }
- }
- if ($trimmed_responders_cnt > 20)
- {
- $usernames[] = $this->user->lang('NOTIFICATION_MANY_OTHERS');
- }
- else if ($trimmed_responders_cnt)
- {
- $usernames[] = $this->user->lang('NOTIFICATION_X_OTHERS', $trimmed_responders_cnt);
- }
- return $this->user->lang(
- $this->language_key,
- phpbb_generate_string_list($usernames, $this->user),
- censor_text($this->get_data('topic_title')),
- $responders_cnt
- );
- }
- /**
- * Get email template
- *
- * @return string|bool
- */
- public function get_email_template()
- {
- return 'topic_notify';
- }
- /**
- * Get email template variables
- *
- * @return array
- */
- public function get_email_template_variables()
- {
- if ($this->get_data('post_username'))
- {
- $username = $this->get_data('post_username');
- }
- else
- {
- $username = $this->user_loader->get_username($this->get_data('poster_id'), 'username');
- }
- return array(
- 'AUTHOR_NAME' => htmlspecialchars_decode($username),
- 'POST_SUBJECT' => htmlspecialchars_decode(censor_text($this->get_data('post_subject'))),
- 'TOPIC_TITLE' => htmlspecialchars_decode(censor_text($this->get_data('topic_title'))),
- 'U_VIEW_POST' => generate_board_url() . "/viewtopic.{$this->php_ext}?p={$this->item_id}#p{$this->item_id}",
- 'U_NEWEST_POST' => generate_board_url() . "/viewtopic.{$this->php_ext}?f={$this->get_data('forum_id')}&t={$this->item_parent_id}&e=1&view=unread#unread",
- 'U_TOPIC' => generate_board_url() . "/viewtopic.{$this->php_ext}?f={$this->get_data('forum_id')}&t={$this->item_parent_id}",
- 'U_VIEW_TOPIC' => generate_board_url() . "/viewtopic.{$this->php_ext}?f={$this->get_data('forum_id')}&t={$this->item_parent_id}",
- 'U_FORUM' => generate_board_url() . "/viewforum.{$this->php_ext}?f={$this->get_data('forum_id')}",
- 'U_STOP_WATCHING_TOPIC' => generate_board_url() . "/viewtopic.{$this->php_ext}?uid={$this->user_id}&f={$this->get_data('forum_id')}&t={$this->item_parent_id}&unwatch=topic",
- );
- }
- /**
- * Get the url to this item
- *
- * @return string URL
- */
- public function get_url()
- {
- return append_sid($this->phpbb_root_path . 'viewtopic.' . $this->php_ext, "p={$this->item_id}#p{$this->item_id}");
- }
- /**
- * {inheritDoc}
- */
- public function get_redirect_url()
- {
- return append_sid($this->phpbb_root_path . 'viewtopic.' . $this->php_ext, "t={$this->item_parent_id}&view=unread#unread");
- }
- /**
- * Users needed to query before this notification can be displayed
- *
- * @return array Array of user_ids
- */
- public function users_to_query()
- {
- $responders = $this->get_data('responders');
- $users = array(
- $this->get_data('poster_id'),
- );
- if (is_array($responders))
- {
- foreach ($responders as $responder)
- {
- $users[] = $responder['poster_id'];
- }
- }
- return $this->trim_user_ary($users);
- }
- /**
- * Trim the user array passed down to 3 users if the array contains
- * more than 4 users.
- *
- * @param array $users Array of users
- * @return array Trimmed array of user_ids
- */
- public function trim_user_ary($users)
- {
- if (sizeof($users) > 4)
- {
- array_splice($users, 3);
- }
- return $users;
- }
- /**
- * Pre create insert array function
- * This allows you to perform certain actions, like run a query
- * and load data, before create_insert_array() is run. The data
- * returned from this function will be sent to create_insert_array().
- *
- * @param array $post Post data from submit_post
- * @param array $notify_users Notify users list
- * Formated from find_users_for_notification()
- * @return array Whatever you want to send to create_insert_array().
- */
- public function pre_create_insert_array($post, $notify_users)
- {
- if (!sizeof($notify_users) || !$this->inherit_read_status)
- {
- return array();
- }
- $tracking_data = array();
- $sql = 'SELECT user_id, mark_time FROM ' . TOPICS_TRACK_TABLE . '
- WHERE topic_id = ' . (int) $post['topic_id'] . '
- AND ' . $this->db->sql_in_set('user_id', array_keys($notify_users));
- $result = $this->db->sql_query($sql);
- while ($row = $this->db->sql_fetchrow($result))
- {
- $tracking_data[$row['user_id']] = $row['mark_time'];
- }
- return $tracking_data;
- }
- /**
- * 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
- */
- public function create_insert_array($post, $pre_create_data = array())
- {
- $this->set_data('poster_id', $post['poster_id']);
- $this->set_data('topic_title', $post['topic_title']);
- $this->set_data('post_subject', $post['post_subject']);
- $this->set_data('post_username', (($post['poster_id'] == ANONYMOUS) ? $post['post_username'] : ''));
- $this->set_data('forum_id', $post['forum_id']);
- $this->set_data('forum_name', $post['forum_name']);
- $this->notification_time = $post['post_time'];
- // Topics can be "read" before they are public (while awaiting approval).
- // Make sure that if the user has read the topic, it's marked as read in the notification
- if ($this->inherit_read_status && isset($pre_create_data[$this->user_id]) && $pre_create_data[$this->user_id] >= $this->notification_time)
- {
- $this->notification_read = true;
- }
- return parent::create_insert_array($post, $pre_create_data);
- }
- /**
- * Add responders to the notification
- *
- * @param mixed $post
- */
- public function add_responders($post)
- {
- // Do not add them as a responder if they were the original poster that created the notification
- if ($this->get_data('poster_id') == $post['poster_id'])
- {
- return array();
- }
- $responders = $this->get_data('responders');
- $responders = ($responders === null) ? array() : $responders;
- // Do not add more than 25 responders,
- // we trim the username list to "a, b, c and x others" anyway
- // so there is no use to add all of them anyway.
- if (sizeof($responders) > 25)
- {
- return array();
- }
- foreach ($responders as $responder)
- {
- // Do not add them as a responder multiple times
- if ($responder['poster_id'] == $post['poster_id'])
- {
- return array();
- }
- }
- $responders[] = array(
- 'poster_id' => $post['poster_id'],
- 'username' => (($post['poster_id'] == ANONYMOUS) ? $post['post_username'] : ''),
- );
- $this->set_data('responders', $responders);
- $serialized_data = serialize($this->get_data(false));
- // If the data is longer then 4000 characters, it would cause a SQL error.
- // We don't add the username to the list if this is the case.
- if (utf8_strlen($serialized_data) >= 4000)
- {
- return array();
- }
- return array('notification_data' => $serialized_data);
- }
- }