diff options
author | Nathan Guse <nathaniel.guse@gmail.com> | 2013-09-13 09:15:23 -0500 |
---|---|---|
committer | Nathan Guse <nathaniel.guse@gmail.com> | 2013-09-13 09:15:23 -0500 |
commit | a194e6ce7afe373fcb89ab26b3d057f60d10fa3d (patch) | |
tree | 7d39cb8a17faf1733db8b5f2ee7d822c0b9080f8 | |
parent | baa73f6933e70f79482e0c4c978d3bfa53eed768 (diff) | |
parent | 16c6e439149cee19b84ab809e913eb41bc5f4fd9 (diff) | |
download | forums-a194e6ce7afe373fcb89ab26b3d057f60d10fa3d.tar forums-a194e6ce7afe373fcb89ab26b3d057f60d10fa3d.tar.gz forums-a194e6ce7afe373fcb89ab26b3d057f60d10fa3d.tar.bz2 forums-a194e6ce7afe373fcb89ab26b3d057f60d10fa3d.tar.xz forums-a194e6ce7afe373fcb89ab26b3d057f60d10fa3d.zip |
Merge branch 'develop' of github.com:phpbb/phpbb3 into ticket/11832
# By Nathan Guse (22) and others
# Via Nathan Guse (10) and others
* 'develop' of github.com:phpbb/phpbb3: (39 commits)
[ticket/11843] Added newlines and included numbers in the DEFINE vars test
[ticket/11843] Add checking DEFINE variables with underscores to template_test
[ticket/11843] The twig lexer fixes DEFINE variables with underscores again
[ticket/11727] Fix indentation
[ticket/11727] Fix indentation
[ticket/11745] Correct language, coding guidelines
[ticket/11828] Fix greedy operators in lexer
[ticket/11833] Prevent Twig errors from invalid template loops using BEGINELSE
[ticket/11833] Fix bad template loop
[ticket/11816] !$DOESNT_EXIST test
[ticket/9550] Add the core.viewtopic_post_rowset_data event to viewtopic.php
[ticket/11829] Use report_closed to determine status in MCP report_details
[ticket/11816] Test !$DEFINITION
[ticket/11822] Use namespace lookup order for asset loading
[ticket/11727] Template loader support for safe directories to load files from
[ticket/11816] Fix define/loop checks in IF statements containing parenthesis
[ticket/11373] Use inheritdoc
[ticket/11637] generate_text_for_display on search.php
[ticket/11744] Cast to int
[ticket/11744] Inheritdoc
...
35 files changed, 1178 insertions, 362 deletions
diff --git a/phpBB/config/notifications.yml b/phpBB/config/notifications.yml index 60aa63a854..fc687cbd19 100644 --- a/phpBB/config/notifications.yml +++ b/phpBB/config/notifications.yml @@ -103,6 +103,42 @@ services: tags: - { name: notification.type } + notification.type.group_request: + class: phpbb_notification_type_group_request + scope: prototype # scope MUST be prototype for this to work! + 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.type.group_request_approved: + class: phpbb_notification_type_group_request_approved + scope: prototype # scope MUST be prototype for this to work! + 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.type.pm: class: phpbb_notification_type_pm scope: prototype # scope MUST be prototype for this to work! diff --git a/phpBB/includes/acp/acp_board.php b/phpBB/includes/acp/acp_board.php index 449ce55e0f..62e8044765 100644 --- a/phpBB/includes/acp/acp_board.php +++ b/phpBB/includes/acp/acp_board.php @@ -328,6 +328,7 @@ class acp_board 'session_length' => array('lang' => 'SESSION_LENGTH', 'validate' => 'int:60:9999999999', 'type' => 'number:60:9999999999', 'explain' => true, 'append' => ' ' . $user->lang['SECONDS']), 'active_sessions' => array('lang' => 'LIMIT_SESSIONS', 'validate' => 'int:0:9999', 'type' => 'number:0:9999', 'explain' => true), 'load_online_time' => array('lang' => 'ONLINE_LENGTH', 'validate' => 'int:0:999', 'type' => 'number:0:999', 'explain' => true, 'append' => ' ' . $user->lang['MINUTES']), + 'read_notification_expire_days' => array('lang' => 'READ_NOTIFICATION_EXPIRE_DAYS', 'validate' => 'int:0', 'type' => 'number:0', 'explain' => true, 'append' => ' ' . $user->lang['DAYS']), 'legend2' => 'GENERAL_OPTIONS', 'load_notifications' => array('lang' => 'LOAD_NOTIFICATIONS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), diff --git a/phpBB/includes/functions_user.php b/phpBB/includes/functions_user.php index 1b598f7bf7..4fcce67801 100644 --- a/phpBB/includes/functions_user.php +++ b/phpBB/includes/functions_user.php @@ -2534,7 +2534,7 @@ function group_delete($group_id, $group_name = false) */ function group_user_add($group_id, $user_id_ary = false, $username_ary = false, $group_name = false, $default = false, $leader = 0, $pending = 0, $group_attributes = false) { - global $db, $auth; + global $db, $auth, $phpbb_container; // We need both username and user_id info $result = user_get_id_name($user_id_ary, $username_ary); @@ -2622,6 +2622,20 @@ function group_user_add($group_id, $user_id_ary = false, $username_ary = false, group_update_listings($group_id); + if ($pending) + { + $phpbb_notifications = $phpbb_container->get('notification_manager'); + + foreach ($add_id_ary as $user_id) + { + $phpbb_notifications->add_notifications('group_request', array( + 'group_id' => $group_id, + 'user_id' => $user_id, + 'group_name' => $group_name, + )); + } + } + // Return false - no error return false; } @@ -2635,7 +2649,7 @@ function group_user_add($group_id, $user_id_ary = false, $username_ary = false, */ function group_user_del($group_id, $user_id_ary = false, $username_ary = false, $group_name = false) { - global $db, $auth, $config, $phpbb_dispatcher; + global $db, $auth, $config, $phpbb_dispatcher, $phpbb_container; if ($config['coppa_enable']) { @@ -2769,6 +2783,10 @@ function group_user_del($group_id, $user_id_ary = false, $username_ary = false, group_update_listings($group_id); + $phpbb_notifications = $phpbb_container->get('notification_manager'); + + $phpbb_notifications->delete_notifications('group_request', $user_id_ary, $group_id); + // Return false - no error return false; } @@ -2858,7 +2876,7 @@ function remove_default_rank($group_id, $user_ids) */ function group_user_attributes($action, $group_id, $user_id_ary = false, $username_ary = false, $group_name = false, $group_attributes = false) { - global $db, $auth, $phpbb_root_path, $phpEx, $config; + global $db, $auth, $phpbb_root_path, $phpEx, $config, $phpbb_container; // We need both username and user_id info $result = user_get_id_name($user_id_ary, $username_ary); @@ -2911,11 +2929,10 @@ function group_user_attributes($action, $group_id, $user_id_ary = false, $userna AND ' . $db->sql_in_set('ug.user_id', $user_id_ary); $result = $db->sql_query($sql); - $user_id_ary = $email_users = array(); + $user_id_ary = array(); while ($row = $db->sql_fetchrow($result)) { $user_id_ary[] = $row['user_id']; - $email_users[] = $row; } $db->sql_freeresult($result); @@ -2930,26 +2947,14 @@ function group_user_attributes($action, $group_id, $user_id_ary = false, $userna AND " . $db->sql_in_set('user_id', $user_id_ary); $db->sql_query($sql); - // Send approved email to users... - include_once($phpbb_root_path . 'includes/functions_messenger.' . $phpEx); - $messenger = new messenger(); - - foreach ($email_users as $row) - { - $messenger->template('group_approved', $row['user_lang']); - - $messenger->set_addresses($row); - - $messenger->assign_vars(array( - 'USERNAME' => htmlspecialchars_decode($row['username']), - 'GROUP_NAME' => htmlspecialchars_decode($group_name), - 'U_GROUP' => generate_board_url() . "/ucp.$phpEx?i=groups&mode=membership") - ); - - $messenger->send($row['user_notify_type']); - } + $phpbb_notifications = $phpbb_container->get('notification_manager'); - $messenger->save_queue(); + $phpbb_notifications->add_notifications('group_request_approved', array( + 'user_ids' => $user_id_ary, + 'group_id' => $group_id, + 'group_name' => $group_name, + )); + $phpbb_notifications->delete_notifications('group_request', $user_id_ary, $group_id); $log = 'LOG_USERS_APPROVED'; break; diff --git a/phpBB/includes/mcp/mcp_pm_reports.php b/phpBB/includes/mcp/mcp_pm_reports.php index cb61b25174..f0452b37a5 100644 --- a/phpBB/includes/mcp/mcp_pm_reports.php +++ b/phpBB/includes/mcp/mcp_pm_reports.php @@ -161,6 +161,7 @@ class mcp_pm_reports 'S_CLOSE_ACTION' => append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=pm_reports&mode=pm_report_details&r=' . $report_id), 'S_CAN_VIEWIP' => $auth->acl_getf_global('m_info'), 'S_POST_REPORTED' => $pm_info['message_reported'], + 'S_REPORT_CLOSED' => $report['report_closed'], 'S_USER_NOTES' => true, 'U_MCP_REPORT' => append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=pm_reports&mode=pm_report_details&r=' . $report_id), diff --git a/phpBB/includes/mcp/mcp_reports.php b/phpBB/includes/mcp/mcp_reports.php index 3f48c58073..8db5bb9727 100644 --- a/phpBB/includes/mcp/mcp_reports.php +++ b/phpBB/includes/mcp/mcp_reports.php @@ -189,6 +189,7 @@ class mcp_reports 'S_POST_REPORTED' => $post_info['post_reported'], 'S_POST_UNAPPROVED' => ($post_info['post_visibility'] == ITEM_UNAPPROVED), 'S_POST_LOCKED' => $post_info['post_edit_locked'], + 'S_REPORT_CLOSED' => $report['report_closed'], 'S_USER_NOTES' => true, 'U_EDIT' => ($auth->acl_get('m_edit', $post_info['forum_id'])) ? append_sid("{$phpbb_root_path}posting.$phpEx", "mode=edit&f={$post_info['forum_id']}&p={$post_info['post_id']}") : '', diff --git a/phpBB/includes/ucp/ucp_groups.php b/phpBB/includes/ucp/ucp_groups.php index 8620e33e47..6f78136f11 100644 --- a/phpBB/includes/ucp/ucp_groups.php +++ b/phpBB/includes/ucp/ucp_groups.php @@ -197,37 +197,6 @@ class ucp_groups else { group_user_add($group_id, $user->data['user_id'], false, false, false, 0, 1); - - include_once($phpbb_root_path . 'includes/functions_messenger.' . $phpEx); - $messenger = new messenger(); - - $sql = 'SELECT u.username, u.username_clean, u.user_email, u.user_notify_type, u.user_jabber, u.user_lang - FROM ' . USER_GROUP_TABLE . ' ug, ' . USERS_TABLE . " u - WHERE ug.user_id = u.user_id - AND ug.group_leader = 1 - AND ug.group_id = $group_id"; - $result = $db->sql_query($sql); - - while ($row = $db->sql_fetchrow($result)) - { - $messenger->template('group_request', $row['user_lang']); - - $messenger->set_addresses($row); - - $messenger->assign_vars(array( - 'USERNAME' => htmlspecialchars_decode($row['username']), - 'GROUP_NAME' => htmlspecialchars_decode($group_row[$group_id]['group_name']), - 'REQUEST_USERNAME' => $user->data['username'], - - 'U_PENDING' => generate_board_url() . "/ucp.$phpEx?i=groups&mode=manage&action=list&g=$group_id", - 'U_GROUP' => generate_board_url() . "/memberlist.$phpEx?mode=group&g=$group_id") - ); - - $messenger->send($row['user_notify_type']); - } - $db->sql_freeresult($result); - - $messenger->save_queue(); } add_log('user', $user->data['user_id'], 'LOG_USER_GROUP_JOIN' . (($group_row[$group_id]['group_type'] == GROUP_FREE) ? '' : '_PENDING'), $group_row[$group_id]['group_name']); diff --git a/phpBB/language/en/acp/board.php b/phpBB/language/en/acp/board.php index 2ee96ab5da..6eabe99d80 100644 --- a/phpBB/language/en/acp/board.php +++ b/phpBB/language/en/acp/board.php @@ -367,6 +367,8 @@ $lang = array_merge($lang, array( 'LOAD_JQUERY_CDN_EXPLAIN' => 'If this setting is enabled, jQuery will be served from Google’s AJAX API CDN instead of the copy included with phpBB on your server. If the CDN fails, phpBB will attempt to fall back to the copy included with phpBB.', 'LOAD_USER_ACTIVITY' => 'Show user’s activity', 'LOAD_USER_ACTIVITY_EXPLAIN' => 'Displays active topic/forum in user profiles and user control panel. It is recommended to disable this on boards with more than one million posts.', + 'READ_NOTIFICATION_EXPIRE_DAYS' => 'Read Notification Expiration', + 'READ_NOTIFICATION_EXPIRE_DAYS_EXPLAIN' => 'Number of days that will elapse before a read notification will automatically be deleted. Set this value to 0 to make notifications permanent.', 'RECOMPILE_STYLES' => 'Recompile stale style components', 'RECOMPILE_STYLES_EXPLAIN' => 'Check for updated style components on filesystem and recompile.', 'YES_ANON_READ_MARKING' => 'Enable topic marking for guests', diff --git a/phpBB/language/en/common.php b/phpBB/language/en/common.php index 5c7df2c5fd..e5c0478d98 100644 --- a/phpBB/language/en/common.php +++ b/phpBB/language/en/common.php @@ -423,6 +423,8 @@ $lang = array_merge($lang, array( 2 => '<strong>%d</strong> Notifications', ), 'NOTIFICATION_BOOKMARK' => '%1$s replied to the topic "%2$s" you have bookmarked.', + 'NOTIFICATION_GROUP_REQUEST' => '%1$s is requesting to join the group %2$s.', + 'NOTIFICATION_GROUP_REQUEST_APPROVED' => 'Your request to join the group %1$s has been approved.', 'NOTIFICATION_PM' => '%1$s sent you a Private Message "%2$s".', 'NOTIFICATION_POST' => '%1$s replied to the topic "%2$s".', 'NOTIFICATION_POST_APPROVED' => 'Your post was approved "%2$s".', diff --git a/phpBB/language/en/email/group_approved.txt b/phpBB/language/en/email/group_approved.txt deleted file mode 100644 index 24afefcd07..0000000000 --- a/phpBB/language/en/email/group_approved.txt +++ /dev/null @@ -1,10 +0,0 @@ -Subject: Your request has been approved - -Congratulations, - -Your request to join the "{GROUP_NAME}" group on "{SITENAME}" has been approved. -Click on the following link to see your group membership. - -{U_GROUP} - -{EMAIL_SIG} diff --git a/phpBB/language/en/ucp.php b/phpBB/language/en/ucp.php index 03a14336b5..0222f92b1b 100644 --- a/phpBB/language/en/ucp.php +++ b/phpBB/language/en/ucp.php @@ -317,6 +317,7 @@ $lang = array_merge($lang, array( 'NOTIFICATION_METHOD_JABBER' => 'Jabber', 'NOTIFICATION_TYPE' => 'Notification type', 'NOTIFICATION_TYPE_BOOKMARK' => 'Someone replies to a topic you have bookmarked', + 'NOTIFICATION_TYPE_GROUP_REQUEST' => 'Someone requests to join a group you lead', 'NOTIFICATION_TYPE_IN_MODERATION_QUEUE' => 'A post or topic needs approval', 'NOTIFICATION_TYPE_MODERATION_QUEUE' => 'Your topics/posts are approved or disapproved by a moderator', 'NOTIFICATION_TYPE_PM' => 'Someone sends you a private message', diff --git a/phpBB/phpbb/cron/task/core/prune_notifications.php b/phpBB/phpbb/cron/task/core/prune_notifications.php new file mode 100644 index 0000000000..296c0ae64f --- /dev/null +++ b/phpBB/phpbb/cron/task/core/prune_notifications.php @@ -0,0 +1,65 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** +* Prune notifications cron task. +* +* @package phpBB3 +*/ +class phpbb_cron_task_core_prune_notifications extends phpbb_cron_task_base +{ + protected $config; + protected $notification_manager; + + /** + * Constructor. + * + * @param phpbb_config $config The config + * @param phpbb_notification_manager $notification_manager Notification manager + */ + public function __construct(phpbb_config $config, phpbb_notification_manager $notification_manager) + { + $this->config = $config; + $this->notification_manager = $notification_manager; + } + + /** + * {@inheritdoc} + */ + public function run() + { + // time minus expire days in seconds + $timestamp = time() - ($this->config['read_notification_expire_days'] * 60 * 60 * 24); + $this->notification_manager->prune_notifications($timestamp); + } + + /** + * {@inheritdoc} + */ + public function is_runnable() + { + return (bool) $this->config['read_notification_expire_days']; + } + + /** + * {@inheritdoc} + */ + public function should_run() + { + return $this->config['read_notification_last_gc'] < time() - $this->config['read_notification_gc']; + } +} diff --git a/phpBB/phpbb/db/migration/data/310/notifications_cron.php b/phpBB/phpbb/db/migration/data/310/notifications_cron.php new file mode 100644 index 0000000000..454628e50e --- /dev/null +++ b/phpBB/phpbb/db/migration/data/310/notifications_cron.php @@ -0,0 +1,25 @@ +<?php +/** +* +* @package migration +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +class phpbb_db_migration_data_310_notifications_cron extends phpbb_db_migration +{ + static public function depends_on() + { + return array('phpbb_db_migration_data_310_notifications'); + } + + public function update_data() + { + return array( + array('config.add', array('read_notification_expire_days', 30)), + array('config.add', array('read_notification_last_gc', 0)), // last run + array('config.add', array('read_notification_gc', (60 * 60 * 24))), // seconds between run; 1 day + ); + } +} diff --git a/phpBB/phpbb/log/null.php b/phpBB/phpbb/log/null.php new file mode 100644 index 0000000000..14b5f65eec --- /dev/null +++ b/phpBB/phpbb/log/null.php @@ -0,0 +1,78 @@ +<?php +/** +* +* @package phpbb_log +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** +* Null logger +* +* @package phpbb_log +*/ +class phpbb_log_null implements phpbb_log_interface +{ + /** + * {@inheritdoc} + */ + public function is_enabled($type = '') + { + return false; + } + + /** + * {@inheritdoc} + */ + public function disable($type = '') + { + } + + /** + * {@inheritdoc} + */ + public function enable($type = '') + { + } + + /** + * {@inheritdoc} + */ + public function add($mode, $user_id, $log_ip, $log_operation, $log_time = false, $additional_data = array()) + { + return false; + } + + /** + * {@inheritdoc} + */ + public function get_logs($mode, $count_logs = true, $limit = 0, $offset = 0, $forum_id = 0, $topic_id = 0, $user_id = 0, $log_time = 0, $sort_by = 'l.log_time DESC', $keywords = '') + { + return array(); + } + + /** + * {@inheritdoc} + */ + public function get_log_count() + { + return 0; + } + + /** + * {@inheritdoc} + */ + public function get_valid_offset() + { + return 0; + } +} diff --git a/phpBB/phpbb/notification/manager.php b/phpBB/phpbb/notification/manager.php index 97833710c0..a962a61e6e 100644 --- a/phpBB/phpbb/notification/manager.php +++ b/phpBB/phpbb/notification/manager.php @@ -59,7 +59,7 @@ class phpbb_notification_manager /** * Notification Constructor - * + * * @param array $notification_types * @param array $notification_methods * @param ContainerBuilder $phpbb_container @@ -490,15 +490,15 @@ class phpbb_notification_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 array $data Data specific for this type that will be updated + * @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) */ - public function delete_notifications($notification_type_name, $item_id) + public function delete_notifications($notification_type_name, $item_id, $parent_id = false) { if (is_array($notification_type_name)) { foreach ($notification_type_name as $type) { - $this->delete_notifications($type, $item_id); + $this->delete_notifications($type, $item_id, $parent_id); } return; @@ -508,7 +508,8 @@ class phpbb_notification_manager $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); + 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); } @@ -796,11 +797,13 @@ class phpbb_notification_manager * Delete all notifications older than a certain time * * @param int $timestamp Unix timestamp to delete all notifications that were created before + * @param bool $only_unread True (default) to only prune read notifications */ - public function prune_notifications($timestamp) + public function prune_notifications($timestamp, $only_read = true) { $sql = 'DELETE FROM ' . $this->notifications_table . ' - WHERE notification_time < ' . (int) $timestamp; + WHERE notification_time < ' . (int) $timestamp . + (($only_read) ? ' AND notification_read = 1' : ''); $this->db->sql_query($sql); } @@ -834,12 +837,12 @@ class phpbb_notification_manager protected function load_object($object_name) { $object = $this->phpbb_container->get($object_name); - + if (method_exists($object, 'set_notification_manager')) { $object->set_notification_manager($this); } - + return $object; } diff --git a/phpBB/phpbb/notification/type/group_request.php b/phpBB/phpbb/notification/type/group_request.php new file mode 100644 index 0000000000..1a3b5b6992 --- /dev/null +++ b/phpBB/phpbb/notification/type/group_request.php @@ -0,0 +1,163 @@ +<?php +/** +* +* @package notifications +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +class phpbb_notification_type_group_request extends phpbb_notification_type_base +{ + /** + * {@inheritdoc} + */ + public function get_type() + { + return 'group_request'; + } + + /** + * {@inheritdoc} + */ + public static $notification_option = array( + 'lang' => 'NOTIFICATION_TYPE_GROUP_REQUEST', + ); + + /** + * {@inheritdoc} + */ + public function is_available() + { + // Leader of any groups? + $sql = 'SELECT group_id + FROM ' . USER_GROUP_TABLE . ' + WHERE user_id = ' . (int) $this->user->data['user_id'] . ' + AND group_leader = 1'; + $result = $this->db->sql_query_limit($sql, 1); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + return (!empty($row)) ? true : false; + } + + /** + * {@inheritdoc} + */ + public static function get_item_id($group) + { + return (int) $group['user_id']; + } + + /** + * {@inheritdoc} + */ + public static function get_item_parent_id($group) + { + // Group id is the parent + return (int) $group['group_id']; + } + + /** + * {@inheritdoc} + */ + public function find_users_for_notification($group, $options = array()) + { + $options = array_merge(array( + 'ignore_users' => array(), + ), $options); + + $sql = 'SELECT user_id + FROM ' . USER_GROUP_TABLE . ' + WHERE group_leader = 1 + AND group_id = ' . (int) $group['group_id']; + $result = $this->db->sql_query($sql); + + $user_ids = array(); + while ($row = $this->db->sql_fetchrow($result)) + { + $user_ids[] = (int) $row['user_id']; + } + $this->db->sql_freeresult($result); + + $this->user_loader->load_users($user_ids); + + return $this->check_user_notification_options($user_ids, $options); + } + + /** + * {@inheritdoc} + */ + public function get_avatar() + { + return $this->user_loader->get_avatar($this->item_id); + } + + /** + * {@inheritdoc} + */ + public function get_title() + { + $username = $this->user_loader->get_username($this->item_id, 'no_profile'); + + return $this->user->lang('NOTIFICATION_GROUP_REQUEST', $username, $this->get_data('group_name')); + } + + /** + * {@inheritdoc} + */ + public function get_email_template() + { + return 'group_request'; + } + + /** + * {@inheritdoc} + */ + public function get_email_template_variables() + { + $user_data = $this->user_loader->get_user($this->item_id); + + return array( + 'GROUP_NAME' => htmlspecialchars_decode($this->get_data('group_name')), + 'REQUEST_USERNAME' => htmlspecialchars_decode($user_data['username']), + + 'U_PENDING' => generate_board_url() . "/ucp.{$this->php_ext}?i=groups&mode=manage&action=list&g={$this->item_parent_id}", + 'U_GROUP' => generate_board_url() . "/memberlist.{$this->php_ext}?mode=group&g={$this->item_parent_id}", + ); + } + + /** + * {@inheritdoc} + */ + public function get_url() + { + return append_sid($this->phpbb_root_path . 'ucp.' . $this->php_ext, "i=groups&mode=manage&action=list&g={$this->item_parent_id}"); + } + + /** + * {@inheritdoc} + */ + public function users_to_query() + { + return array($this->item_id); + } + + /** + * {@inheritdoc} + */ + public function create_insert_array($group, $pre_create_data = array()) + { + $this->set_data('group_name', $group['group_name']); + + return 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 new file mode 100644 index 0000000000..ce83329ff3 --- /dev/null +++ b/phpBB/phpbb/notification/type/group_request_approved.php @@ -0,0 +1,118 @@ +<?php +/** +* +* @package notifications +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +class phpbb_notification_type_group_request_approved extends phpbb_notification_type_base +{ + /** + * {@inheritdoc} + */ + public function get_type() + { + return 'group_request_approved'; + } + + /** + * {@inheritdoc} + */ + public function is_available() + { + return false; + } + + /** + * {@inheritdoc} + */ + public static function get_item_id($group) + { + return (int) $group['group_id']; + } + + /** + * {@inheritdoc} + */ + public static function get_item_parent_id($group) + { + return 0; + } + + /** + * {@inheritdoc} + */ + public function find_users_for_notification($group, $options = array()) + { + $users = array(); + + $group['user_ids'] = (!is_array($group['user_ids'])) ? array($group['user_ids']) : $group['user_ids']; + + foreach ($group['user_ids'] as $user_id) + { + $users[$user_id] = array(''); + } + + return $users; + } + + /** + * {@inheritdoc} + */ + public function get_title() + { + return $this->user->lang('NOTIFICATION_GROUP_REQUEST_APPROVED', $this->get_data('group_name')); + } + + /** + * {@inheritdoc} + */ + public function get_url() + { + return append_sid($this->phpbb_root_path . 'memberlist.' . $this->php_ext, "mode=group&g={$this->item_id}"); + } + + /** + * {@inheritdoc} + */ + public function create_insert_array($group, $pre_create_data = array()) + { + $this->set_data('group_name', $group['group_name']); + + return parent::create_insert_array($group, $pre_create_data); + } + + /** + * {@inheritdoc} + */ + public function users_to_query() + { + return array(); + } + + /** + * {@inheritdoc} + */ + public function get_email_template() + { + return false; + } + + /** + * {@inheritdoc} + */ + public function get_email_template_variables() + { + return array(); + } +} diff --git a/phpBB/phpbb/template/twig/environment.php b/phpBB/phpbb/template/twig/environment.php index b60cd72325..9a40dc2b15 100644 --- a/phpBB/phpbb/template/twig/environment.php +++ b/phpBB/phpbb/template/twig/environment.php @@ -137,4 +137,39 @@ class phpbb_template_twig_environment extends Twig_Environment return parent::loadTemplate($name, $index); } } + + /** + * Finds a template by name. + * + * @param string $name The template name + * @return string + */ + public function findTemplate($name) + { + if (strpos($name, '@') === false) + { + foreach ($this->getNamespaceLookUpOrder() as $namespace) + { + try + { + if ($namespace === '__main__') + { + return parent::getLoader()->getCacheKey($name); + } + + return parent::getLoader()->getCacheKey('@' . $namespace . '/' . $name); + } + catch (Twig_Error_Loader $e) + { + } + } + + // We were unable to load any templates + throw $e; + } + else + { + return parent::getLoader()->getCacheKey($name); + } + } } diff --git a/phpBB/phpbb/template/twig/lexer.php b/phpBB/phpbb/template/twig/lexer.php index 7ab569313c..16a693cd7c 100644 --- a/phpBB/phpbb/template/twig/lexer.php +++ b/phpBB/phpbb/template/twig/lexer.php @@ -75,7 +75,7 @@ class phpbb_template_twig_lexer extends Twig_Lexer // Fix tokens that may have inline variables (e.g. <!-- DEFINE $TEST = '{FOO}') $code = $this->fix_inline_variable_tokens(array( - 'DEFINE.+=', + 'DEFINE \$[a-zA-Z0-9_]+ =', 'INCLUDE', 'INCLUDEPHP', 'INCLUDEJS', @@ -161,6 +161,9 @@ class phpbb_template_twig_lexer extends Twig_Lexer $subset = trim(substr($matches[2], 1, -1)); // Remove parenthesis $body = $matches[3]; + // Replace <!-- BEGINELSE --> + $body = str_replace('<!-- BEGINELSE -->', '{% else %}', $body); + // Is the designer wanting to call another loop in a loop? // <!-- BEGIN loop --> // <!-- BEGIN !loop2 --> @@ -205,9 +208,6 @@ class phpbb_template_twig_lexer extends Twig_Lexer return "{% for {$name} in {$parent}{$name}{$subset} %}{$body}{% endfor %}"; }; - // Replace <!-- BEGINELSE --> correctly, only needs to be done once - $code = str_replace('<!-- BEGINELSE -->', '{% else %}', $code); - return preg_replace_callback('#<!-- BEGIN ([!a-zA-Z0-9_]+)(\([0-9,\-]+\))? -->(.+?)<!-- END \1 -->#s', $callback, $code); } @@ -229,18 +229,18 @@ class phpbb_template_twig_lexer extends Twig_Lexer { $inner = $matches[2]; // Replace $TEST with definition.TEST - $inner = preg_replace('#\s\$([a-zA-Z_0-9]+)#', ' definition.$1', $inner); + $inner = preg_replace('#(\s\(?!?)\$([a-zA-Z_0-9]+)#', '$1definition.$2', $inner); // Replace .foo with loops.foo|length - $inner = preg_replace('#\s\.([a-zA-Z_0-9]+)([^a-zA-Z_0-9\.])#', ' loops.$1|length$2', $inner); + $inner = preg_replace('#(\s\(?!?)\.([a-zA-Z_0-9]+)([^a-zA-Z_0-9\.])#', '$1loops.$2|length$3', $inner); // Replace .foo.bar with foo.bar|length - $inner = preg_replace('#\s\.([a-zA-Z_0-9\.]+)([^a-zA-Z_0-9\.])#', ' $1|length$2', $inner); + $inner = preg_replace('#(\s\(?!?)\.([a-zA-Z_0-9\.]+)([^a-zA-Z_0-9\.])#', '$1$2|length$3', $inner); return "<!-- {$matches[1]}IF{$inner}-->"; }; - return preg_replace_callback('#<!-- (ELSE)?IF((.*)[\s][\$|\.|!]([^\s]+)(.*))-->#', $callback, $code); + return preg_replace_callback('#<!-- (ELSE)?IF((.*?) \(?!?[\$|\.]([^\s]+)(.*?))-->#', $callback, $code); } /** @@ -264,10 +264,10 @@ class phpbb_template_twig_lexer extends Twig_Lexer */ // Replace <!-- DEFINE $NAME with {% DEFINE definition.NAME - $code = preg_replace('#<!-- DEFINE \$(.*)-->#', '{% DEFINE $1 %}', $code); + $code = preg_replace('#<!-- DEFINE \$(.*?) -->#', '{% DEFINE $1 %}', $code); // Changing UNDEFINE NAME to DEFINE NAME = null to save from creating an extra token parser/node - $code = preg_replace('#<!-- UNDEFINE \$(.*)-->#', '{% DEFINE $1= null %}', $code); + $code = preg_replace('#<!-- UNDEFINE \$(.*?)-->#', '{% DEFINE $1= null %}', $code); // Replace all of our variables, {$VARNAME}, with Twig style, {{ definition.VARNAME }} $code = preg_replace('#{\$([a-zA-Z0-9_\.]+)}#', '{{ definition.$1 }}', $code); diff --git a/phpBB/phpbb/template/twig/loader.php b/phpBB/phpbb/template/twig/loader.php new file mode 100644 index 0000000000..0829e519f7 --- /dev/null +++ b/phpBB/phpbb/template/twig/loader.php @@ -0,0 +1,150 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** +* Twig Template loader +* @package phpBB3 +*/ +class phpbb_template_twig_loader extends Twig_Loader_Filesystem +{ + protected $safe_directories = array(); + + /** + * Set safe directories + * + * @param array $directories Array of directories that are safe (empty to clear) + * @return Twig_Loader_Filesystem + */ + public function setSafeDirectories($directories = array()) + { + $this->safe_directories = array(); + + if (!empty($directories)) + { + foreach ($directories as $directory) + { + $this->addSafeDirectory($directory); + } + } + + return $this; + } + + /** + * Add safe directory + * + * @param string $directory Directory that should be added + * @return Twig_Loader_Filesystem + */ + public function addSafeDirectory($directory) + { + $directory = phpbb_realpath($directory); + + if ($directory !== false) + { + $this->safe_directories[] = $directory; + } + + return $this; + } + + /** + * Get current safe directories + * + * @return array + */ + public function getSafeDirectories() + { + return $this->safe_directories; + } + + /** + * Override for parent::validateName() + * + * This is done because we added support for safe directories, and when Twig + * findTemplate() is called, validateName() is called first, which would + * always throw an exception if the file is outside of the configured + * template directories. + */ + protected function validateName($name) + { + return; + } + + /** + * Find the template + * + * Override for Twig_Loader_Filesystem::findTemplate to add support + * for loading from safe directories. + */ + protected function findTemplate($name) + { + $name = (string) $name; + + // normalize name + $name = preg_replace('#/{2,}#', '/', strtr($name, '\\', '/')); + + // If this is in the cache we can skip the entire process below + // as it should have already been validated + if (isset($this->cache[$name])) { + return $this->cache[$name]; + } + + // First, find the template name. The override above of validateName + // causes the validateName process to be skipped for this call + $file = parent::findTemplate($name); + + try + { + // Try validating the name (which may throw an exception) + parent::validateName($name); + } + catch (Twig_Error_Loader $e) + { + if (strpos($e->getRawMessage(), 'Looks like you try to load a template outside configured directories') === 0) + { + // Ok, so outside of the configured template directories, we + // can now check if we're within a "safe" directory + + // Find the real path of the directory the file is in + $directory = phpbb_realpath(dirname($file)); + + if ($directory === false) + { + // Some sort of error finding the actual path, must throw the exception + throw $e; + } + + foreach ($this->safe_directories as $safe_directory) + { + if (strpos($directory, $safe_directory) === 0) + { + // The directory being loaded is below a directory + // that is "safe". We're good to load it! + return $file; + } + } + } + + // Not within any safe directories + throw $e; + } + + // No exception from validateName, safe to load. + return $file; + } +} diff --git a/phpBB/phpbb/template/twig/node/includeasset.php b/phpBB/phpbb/template/twig/node/includeasset.php index 1cab416c79..0808e2b10e 100644 --- a/phpBB/phpbb/template/twig/node/includeasset.php +++ b/phpBB/phpbb/template/twig/node/includeasset.php @@ -40,10 +40,10 @@ abstract class phpbb_template_twig_node_includeasset extends Twig_Node ->write("\$local_file = \$this->getEnvironment()->get_phpbb_root_path() . \$asset_path;\n") ->write("if (!file_exists(\$local_file)) {\n") ->indent() - ->write("\$local_file = \$this->getEnvironment()->getLoader()->getCacheKey(\$asset_path);\n") + ->write("\$local_file = \$this->getEnvironment()->findTemplate(\$asset_path);\n") ->write("\$asset->set_path(\$local_file, true);\n") ->outdent() - ->write("\$asset->add_assets_version({$config['assets_version']});\n") + ->write("\$asset->add_assets_version('{$config['assets_version']}');\n") ->write("\$asset_file = \$asset->get_url();\n") ->write("}\n") ->outdent() diff --git a/phpBB/phpbb/template/twig/twig.php b/phpBB/phpbb/template/twig/twig.php index 1ed89d3ccc..5746cc64a3 100644 --- a/phpBB/phpbb/template/twig/twig.php +++ b/phpBB/phpbb/template/twig/twig.php @@ -91,7 +91,7 @@ class phpbb_template_twig extends phpbb_template_base $this->cachepath = $phpbb_root_path . 'cache/twig/'; // Initiate the loader, __main__ namespace paths will be setup later in set_style_names() - $loader = new Twig_Loader_Filesystem(''); + $loader = new phpbb_template_twig_loader(''); $this->twig = new phpbb_template_twig_environment( $this->config, @@ -181,11 +181,15 @@ class phpbb_template_twig extends phpbb_template_base { foreach ($names as $name) { - $path = $this->phpbb_root_path . trim($directory, '/') . "/{$name}/template/"; + $path = $this->phpbb_root_path . trim($directory, '/') . "/{$name}/"; + $template_path = $path . 'template/'; - if (is_dir($path)) + if (is_dir($template_path)) { - $paths[] = $path; + // Add the base style directory as a safe directory + $this->twig->getLoader()->addSafeDirectory($path); + + $paths[] = $template_path; } } } @@ -233,11 +237,15 @@ class phpbb_template_twig extends phpbb_template_base foreach ($names as $style_name) { - $ext_style_path = $ext_path . 'styles/' . $style_name . '/template'; + $ext_style_path = $ext_path . 'styles/' . $style_name . '/'; + $ext_style_template_path = $ext_style_path . 'template/'; - if (is_dir($ext_style_path)) + if (is_dir($ext_style_template_path)) { - $paths[] = $ext_style_path; + // Add the base style directory as a safe directory + $this->twig->getLoader()->addSafeDirectory($ext_style_path); + + $paths[] = $ext_style_template_path; } } diff --git a/phpBB/search.php b/phpBB/search.php index 40c0b9a8ce..784e1f6398 100644 --- a/phpBB/search.php +++ b/phpBB/search.php @@ -964,14 +964,8 @@ if ($keywords || $author || $author_id || $search_id || $submit) } else { - // Second parse bbcode here - if ($row['bbcode_bitfield']) - { - $bbcode->bbcode_second_pass($row['post_text'], $row['bbcode_uid'], $row['bbcode_bitfield']); - } - - $row['post_text'] = bbcode_nl2br($row['post_text']); - $row['post_text'] = smiley_text($row['post_text']); + $parse_flags = ($row['bbcode_bitfield'] ? OPTION_FLAG_BBCODE : 0) | OPTION_FLAG_SMILIES; + $row['post_text'] = generate_text_for_display($row['post_text'], $row['bbcode_uid'], $row['bbcode_bitfield'], $parse_flags, false); if (!empty($attachments[$row['post_id']])) { diff --git a/phpBB/styles/prosilver/template/mcp_notes_user.html b/phpBB/styles/prosilver/template/mcp_notes_user.html index 1738e45045..eb954fd11d 100644 --- a/phpBB/styles/prosilver/template/mcp_notes_user.html +++ b/phpBB/styles/prosilver/template/mcp_notes_user.html @@ -88,7 +88,7 @@ <tr> <td class="bg1" colspan="<!-- IF S_CLEAR_ALLOWED -->5<!-- ELSE -->4<!-- ENDIF -->" align="center"><span class="gen">{L_NO_ENTRIES}</span></td> </tr> - <!-- END usernames --> + <!-- END usernotes --> </tbody> </table> diff --git a/phpBB/styles/prosilver/template/mcp_post.html b/phpBB/styles/prosilver/template/mcp_post.html index 7b2ace6792..a205164e60 100644 --- a/phpBB/styles/prosilver/template/mcp_post.html +++ b/phpBB/styles/prosilver/template/mcp_post.html @@ -13,7 +13,7 @@ <div class="postbody"> <h3>{L_REPORT_REASON}{L_COLON} {REPORT_REASON_TITLE}</h3> <p class="author">{L_REPORTED} {L_POST_BY_AUTHOR} {REPORTER_FULL} « {REPORT_DATE}</p> - <!-- IF not S_POST_REPORTED --> + <!-- IF S_REPORT_CLOSED --> <p class="post-notice reported">{L_REPORT_CLOSED}</p> <!-- ENDIF --> <div class="content"> @@ -31,7 +31,7 @@ <form method="post" id="mcp_report" action="{S_CLOSE_ACTION}"> <fieldset class="submit-buttons"> - <!-- IF S_POST_REPORTED --> + <!-- IF not S_REPORT_CLOSED --> <input class="button1" type="submit" value="{L_CLOSE_REPORT}" name="action[close]" /> <!-- ENDIF --> <input class="button2" type="submit" value="{L_DELETE_REPORT}" name="action[delete]" /> diff --git a/phpBB/styles/subsilver2/template/mcp_post.html b/phpBB/styles/subsilver2/template/mcp_post.html index a3ebb00d06..0f000ca931 100644 --- a/phpBB/styles/subsilver2/template/mcp_post.html +++ b/phpBB/styles/subsilver2/template/mcp_post.html @@ -28,7 +28,7 @@ </tr> <!-- ENDIF --> <tr> - <td class="cat" align="center" colspan="2"><!-- IF S_POST_REPORTED --><input class="btnmain" type="submit" value="{L_CLOSE_REPORT}" name="action[close]" /><!-- ELSE -->{L_REPORT_CLOSED}<!-- ENDIF --> <input class="btnlite" type="submit" value="{L_DELETE_REPORT}" name="action[delete]" /></td> + <td class="cat" align="center" colspan="2"><!-- IF not S_REPORT_CLOSED --><input class="btnmain" type="submit" value="{L_CLOSE_REPORT}" name="action[close]" /><!-- ELSE -->{L_REPORT_CLOSED}<!-- ENDIF --> <input class="btnlite" type="submit" value="{L_DELETE_REPORT}" name="action[delete]" /></td> </tr> </table> diff --git a/phpBB/viewtopic.php b/phpBB/viewtopic.php index bc54a249a9..af2056fdeb 100644 --- a/phpBB/viewtopic.php +++ b/phpBB/viewtopic.php @@ -1012,7 +1012,7 @@ while ($row = $db->sql_fetchrow($result)) } } - $rowset[$row['post_id']] = array( + $rowset_data = array( 'hide_post' => (($row['foe'] || $row['post_visibility'] == ITEM_DELETED) && ($view != 'show' || $post_id != $row['post_id'])) ? true : false, 'post_id' => $row['post_id'], @@ -1047,6 +1047,19 @@ while ($row = $db->sql_fetchrow($result)) 'foe' => $row['foe'], ); + /** + * Modify the post rowset containing data to be displayed with posts + * + * @event core.viewtopic_post_rowset_data + * @var array rowset_data Array with the rowset data for this post + * @var array row Array with original user and post data + * @since 3.1-A1 + */ + $vars = array('rowset_data', 'row'); + extract($phpbb_dispatcher->trigger_event('core.viewtopic_post_rowset_data', compact($vars))); + + $rowset[$row['post_id']] = $rowset_data; + // Define the global bbcode bitfield, will be used to load bbcodes $bbcode_bitfield = $bbcode_bitfield | base64_decode($row['bbcode_bitfield']); diff --git a/tests/notification/base.php b/tests/notification/base.php new file mode 100644 index 0000000000..8de162a1fb --- /dev/null +++ b/tests/notification/base.php @@ -0,0 +1,131 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +require_once dirname(__FILE__) . '/manager_helper.php'; + +abstract class phpbb_tests_notification_base extends phpbb_database_test_case +{ + protected $notifications, $db, $container, $user, $config, $auth, $cache; + + protected function get_notification_types() + { + return array( + 'test', + 'approve_post', + 'approve_topic', + 'bookmark', + 'disapprove_post', + 'disapprove_topic', + 'pm', + 'post', + 'post_in_queue', + 'quote', + 'report_pm', + 'report_pm_closed', + 'report_post', + 'report_post_closed', + 'topic', + 'topic_in_queue', + ); + } + + protected function setUp() + { + parent::setUp(); + + global $phpbb_root_path, $phpEx; + + include_once(__DIR__ . '/ext/test/notification/type/test.' . $phpEx); + + global $db, $config, $user, $auth, $cache, $phpbb_container; + + $db = $this->db = $this->new_dbal(); + $config = $this->config = new phpbb_config(array( + 'allow_privmsg' => true, + 'allow_bookmarks' => true, + 'allow_topic_notify' => true, + 'allow_forum_notify' => true, + )); + $user = $this->user = new phpbb_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 = $this->cache = new phpbb_cache_service( + new phpbb_cache_driver_null(), + $this->config, + $this->db, + $phpbb_root_path, + $phpEx + ); + + $phpbb_container = $this->container = new phpbb_mock_container_builder(); + + $this->notifications = new phpbb_notification_manager_helper( + array(), + array(), + $this->container, + $this->user_loader, + $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); + + $this->notifications->setDependencies($this->auth, $this->config); + + $types = array(); + foreach ($this->get_notification_types() as $type) + { + $class = $this->build_type('phpbb_notification_type_' . $type); + + $types[$type] = $class; + $this->container->set('notification.type.' . $type, $class); + } + + $this->notifications->set_var('notification_types', $types); + + $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'); + } + + protected function build_type($type) + { + global $phpbb_root_path, $phpEx; + + return 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'); + } + + protected function assert_notifications($expected, $options = array()) + { + $notifications = $this->notifications->load_notifications(array_merge(array( + 'count_unread' => true, + 'order_by' => 'notification_time', + 'order_dir' => 'ASC', + ), $options)); + + $this->assertEquals(sizeof($expected), $notifications['unread_count']); + + $i = 0; + foreach ($notifications['notifications'] as $notification) + { + foreach ($expected[$i] as $key => $value) + { + $this->assertEquals($value, $notification->$key, $i . ' ' . $key); + } + + $i++; + } + } +} diff --git a/tests/notification/fixtures/group_request.xml b/tests/notification/fixtures/group_request.xml new file mode 100644 index 0000000000..1eb73f1e15 --- /dev/null +++ b/tests/notification/fixtures/group_request.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<dataset> + <table name="phpbb_users"> + <column>user_id</column> + <column>username</column> + <column>username_clean</column> + <column>user_permissions</column> + <column>user_sig</column> + <column>user_occ</column> + <column>user_interests</column> + <row> + <value>2</value> + <value>2</value> + <value>2</value> + <value></value> + <value></value> + <value></value> + <value></value> + </row> + <row> + <value>3</value> + <value>3</value> + <value>3</value> + <value></value> + <value></value> + <value></value> + <value></value> + </row> + </table> +</dataset> diff --git a/tests/notification/group_request_test.php b/tests/notification/group_request_test.php new file mode 100644 index 0000000000..368e4ae973 --- /dev/null +++ b/tests/notification/group_request_test.php @@ -0,0 +1,109 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +require_once dirname(__FILE__) . '/base.php'; + +class phpbb_notification_group_request_test extends phpbb_tests_notification_base +{ + public function getDataSet() + { + return $this->createXMLDataSet(dirname(__FILE__) . '/fixtures/group_request.xml'); + } + + protected function get_notification_types() + { + return array_merge( + parent::get_notification_types(), + array( + 'group_request', + 'group_request_approved', + ) + ); + } + + public function test_notifications() + { + global $phpbb_root_path, $phpEx, $phpbb_dispatcher, $phpbb_log; + + include_once($phpbb_root_path . 'includes/utf/utf_tools.' . $phpEx); + include_once($phpbb_root_path . 'includes/functions_user.' . $phpEx); + include_once($phpbb_root_path . 'includes/functions_content.' . $phpEx); + + set_config(false, false, false, $this->config); + + $this->container->set('groupposition.legend', new phpbb_groupposition_legend( + $this->db, + $this->user + )); + $this->container->set('groupposition.teampage', new phpbb_groupposition_teampage( + $this->db, + $this->user, + $this->cache->get_driver() + )); + $phpbb_dispatcher = new phpbb_mock_event_dispatcher; + $phpbb_log = new phpbb_log_null(); + + // Now on to the actual test + + $group_id = false; + group_create($group_id, GROUP_OPEN, 'test', 'test group', array()); + + // Add user 2 as group leader + group_user_add($group_id, 2, false, false, false, true, false); + + // Add user 3 as pending + group_user_add($group_id, 3, false, false, false, false, true); + + $this->assert_notifications( + array( + // user 3 pending notification + array( + 'item_id' => 3, // user_id of requesting join + 'item_parent_id' => $group_id, + 'user_id' => 2, + 'notification_read' => 0, + 'notification_data' => array( + 'group_name' => 'test', + ), + ), + ), + array( + 'user_id' => 2, + ) + ); + + // Approve user 3 joining the group + group_user_attributes('approve', $group_id, array(3)); + + // user 3 pending notification should have been deleted + $this->assert_notifications( + array(), + array( + 'user_id' => 2, + ) + ); + + $this->assert_notifications( + array( + // user 3 approved notification + array( + 'item_id' => $group_id, // user_id of requesting join + 'user_id' => 3, + 'notification_read' => 0, + 'notification_data' => array( + 'group_name' => 'test', + ), + ), + ), + array( + 'user_id' => 3, + ) + ); + } +} diff --git a/tests/notification/notification_test.php b/tests/notification/notification_test.php index 8f7eb3b8a8..e1788e8670 100644 --- a/tests/notification/notification_test.php +++ b/tests/notification/notification_test.php @@ -7,9 +7,9 @@ * */ -require_once dirname(__FILE__) . '/manager_helper.php'; +require_once dirname(__FILE__) . '/base.php'; -class phpbb_notification_test extends phpbb_database_test_case +class phpbb_notification_test extends phpbb_tests_notification_base { protected $notifications, $db, $container, $user, $config, $auth, $cache; @@ -18,98 +18,17 @@ class phpbb_notification_test extends phpbb_database_test_case return $this->createXMLDataSet(dirname(__FILE__) . '/fixtures/notification.xml'); } - protected function setUp() - { - parent::setUp(); - - global $phpbb_root_path, $phpEx; - - include_once(__DIR__ . '/ext/test/notification/type/test.' . $phpEx); - - $this->db = $this->new_dbal(); - $this->config = new phpbb_config(array( - 'allow_privmsg' => true, - 'allow_bookmarks' => true, - 'allow_topic_notify' => true, - 'allow_forum_notify' => true, - )); - $this->user = new phpbb_user(); - $this->user_loader = new phpbb_user_loader($this->db, $phpbb_root_path, $phpEx, 'phpbb_users'); - $this->auth = new phpbb_mock_notifications_auth(); - $this->cache = new phpbb_cache_service( - new phpbb_cache_driver_null(), - $this->config, - $this->db, - $phpbb_root_path, - $phpEx - ); - - $this->container = new phpbb_mock_container_builder(); - - $this->notifications = new phpbb_notification_manager_helper( - array(), - array(), - $this->container, - $this->user_loader, - $this->db, - $this->cache, - $this->user, - $phpbb_root_path, - $phpEx, - 'phpbb_notification_types', - 'phpbb_notifications', - 'phpbb_user_notifications' - ); - - $this->notifications->setDependencies($this->auth, $this->config); - - $types = array(); - foreach (array( - 'test', - 'approve_post', - 'approve_topic', - 'bookmark', - 'disapprove_post', - 'disapprove_topic', - 'pm', - 'post', - 'post_in_queue', - 'quote', - 'report_pm', - 'report_pm_closed', - 'report_post', - 'report_post_closed', - 'topic', - 'topic_in_queue', - ) as $type) - { - $class = $this->build_type('phpbb_notification_type_' . $type); - - $types[$type] = $class; - $this->container->set('notification.type.' . $type, $class); - } - - $this->notifications->set_var('notification_types', $types); - } - - protected function build_type($type) - { - global $phpbb_root_path, $phpEx; - - return 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'); - } - public function test_get_notification_type_id() { // They should be inserted the first time - $this->assertEquals(1, $this->notifications->get_notification_type_id('post')); - $this->assertEquals(2, $this->notifications->get_notification_type_id('quote')); - $this->assertEquals(3, $this->notifications->get_notification_type_id('test')); + $post_type_id = $this->notifications->get_notification_type_id('post'); + $quote_type_id = $this->notifications->get_notification_type_id('quote'); + $test_type_id = $this->notifications->get_notification_type_id('test'); $this->assertEquals(array( - 'test' => 3, - 'quote' => 2, - 'post' => 1, + 'test' => $test_type_id, + 'quote' => $quote_type_id, + 'post' => $post_type_id, ), $this->notifications->get_notification_type_ids(array( 'test', @@ -117,11 +36,11 @@ class phpbb_notification_test extends phpbb_database_test_case 'post', ) )); - $this->assertEquals(2, $this->notifications->get_notification_type_id('quote')); + $this->assertEquals($quote_type_id, $this->notifications->get_notification_type_id('quote')); try { - $this->assertEquals(3, $this->notifications->get_notification_type_id('fail')); + $this->assertEquals(false, $this->notifications->get_notification_type_id('fail')); $this->fail('Non-existent type should throw an exception'); } @@ -241,88 +160,65 @@ class phpbb_notification_test extends phpbb_database_test_case 'post_time' => 1349413326, )); - $notifications = $this->notifications->load_notifications(array( - 'count_unread' => true, - )); - - $expected = array( - 1 => array( - 'notification_type_id' => 4, - 'item_id' => 1, - 'item_parent_id' => 1, - 'user_id' => 0, - 'notification_read' => 0, - 'notification_time' => 1349413321, - 'notification_data' => array(), - ), - 2 => array( - 'notification_type_id' => 4, - 'item_id' => 2, - 'item_parent_id' => 2, - 'user_id' => 0, - 'notification_read' => 0, - 'notification_time' => 1349413322, - 'notification_data' => array(), - ), - 3 => array( - 'notification_type_id' => 4, - 'item_id' => 3, - 'item_parent_id' => 2, - 'user_id' => 0, - 'notification_read' => 0, - 'notification_time' => 1349413323, - 'notification_data' => array(), - ), - 4 => array( - 'notification_type_id' => 3, - 'item_id' => 4, - 'item_parent_id' => 2, - 'user_id' => 0, - 'notification_read' => 0, - 'notification_time' => 1349413324, - 'notification_data' => array( - 'poster_id' => 2, - 'topic_title' => 'test-title', - 'post_subject' => 'Re: test-title', - 'post_username' => '', - 'forum_id' => 2, - 'forum_name' => 'Your first forum', + $this->assert_notifications( + array( + array( + 'item_id' => 1, + 'item_parent_id' => 1, + 'user_id' => 0, + 'notification_read' => 0, + 'notification_time' => 1349413321, + 'notification_data' => array(), ), - ), - 5 => array( - 'notification_type_id' => 2, - 'item_id' => 5, - 'item_parent_id' => 2, - 'user_id' => 0, - 'notification_read' => 0, - 'notification_time' => 1349413325, - 'notification_data' => array( - 'poster_id' => 2, - 'topic_title' => 'test-title', - 'post_subject' => 'Re: test-title', - 'post_username' => '', - 'forum_id' => 2, - 'forum_name' => 'Your first forum', + array( + 'item_id' => 2, + 'item_parent_id' => 2, + 'user_id' => 0, + 'notification_read' => 0, + 'notification_time' => 1349413322, + 'notification_data' => array(), ), - ), + array( + 'item_id' => 3, + 'item_parent_id' => 2, + 'user_id' => 0, + 'notification_read' => 0, + 'notification_time' => 1349413323, + 'notification_data' => array(), + ), + array( + 'item_id' => 4, + 'item_parent_id' => 2, + 'user_id' => 0, + 'notification_read' => 0, + 'notification_time' => 1349413324, + 'notification_data' => array( + 'poster_id' => 2, + 'topic_title' => 'test-title', + 'post_subject' => 'Re: test-title', + 'post_username' => '', + 'forum_id' => 2, + 'forum_name' => 'Your first forum', + ), + ), + array( + 'item_id' => 5, + 'item_parent_id' => 2, + 'user_id' => 0, + 'notification_read' => 0, + 'notification_time' => 1349413325, + 'notification_data' => array( + 'poster_id' => 2, + 'topic_title' => 'test-title', + 'post_subject' => 'Re: test-title', + 'post_username' => '', + 'forum_id' => 2, + 'forum_name' => 'Your first forum', + ), + ), + ) ); - $this->assertEquals(sizeof($expected), $notifications['unread_count']); - - $notifications = $notifications['notifications']; - - foreach ($expected as $notification_id => $notification_data) - { - //echo $notifications[$notification_id]; - - $this->assertEquals($notification_id, $notifications[$notification_id]->notification_id, 'notification_id'); - - foreach ($notification_data as $key => $value) - { - $this->assertEquals($value, $notifications[$notification_id]->$key, $key . ' ' . $notification_id); - } - } - // Now test updating ------------------------------- $this->notifications->update_notifications('test', array( @@ -347,86 +243,63 @@ class phpbb_notification_test extends phpbb_database_test_case 'forum_name' => 'Your second forum', // change forum_name )); - $notifications = $this->notifications->load_notifications(array( - 'count_unread' => true, - )); - - $expected = array( - 1 => array( - 'notification_type_id' => 4, - 'item_id' => 1, - 'item_parent_id' => 2, - 'user_id' => 0, - 'notification_read' => 0, - 'notification_time' => 1349413321, - 'notification_data' => array(), - ), - 2 => array( - 'notification_type_id' => 4, - 'item_id' => 2, - 'item_parent_id' => 2, - 'user_id' => 0, - 'notification_read' => 0, - 'notification_time' => 1349413322, - 'notification_data' => array(), - ), - 3 => array( - 'notification_type_id' => 4, - 'item_id' => 3, - 'item_parent_id' => 2, - 'user_id' => 0, - 'notification_read' => 0, - 'notification_time' => 1234, - 'notification_data' => array(), - ), - 4 => array( - 'notification_type_id' => 3, - 'item_id' => 4, - 'item_parent_id' => 2, - 'user_id' => 0, - 'notification_read' => 0, - 'notification_time' => 1349413324, - 'notification_data' => array( - 'poster_id' => 2, - 'topic_title' => 'test-title', - 'post_subject' => 'Re: test-title', - 'post_username' => '', - 'forum_id' => 2, - 'forum_name' => 'Your first forum', + $this->assert_notifications( + array( + array( + 'item_id' => 3, + 'item_parent_id' => 2, + 'user_id' => 0, + 'notification_read' => 0, + 'notification_time' => 1234, + 'notification_data' => array(), ), - ), - 5 => array( - 'notification_type_id' => 2, - 'item_id' => 5, - 'item_parent_id' => 2, - 'user_id' => 0, - 'notification_read' => 0, - 'notification_time' => 1349413325, - 'notification_data' => array( - 'poster_id' => 2, - 'topic_title' => 'test-title2', - 'post_subject' => 'Re: test-title2', - 'post_username' => '', - 'forum_id' => 3, - 'forum_name' => 'Your second forum', + array( + 'item_id' => 1, + 'item_parent_id' => 2, + 'user_id' => 0, + 'notification_read' => 0, + 'notification_time' => 1349413321, + 'notification_data' => array(), ), - ), + array( + 'item_id' => 2, + 'item_parent_id' => 2, + 'user_id' => 0, + 'notification_read' => 0, + 'notification_time' => 1349413322, + 'notification_data' => array(), + ), + array( + 'item_id' => 4, + 'item_parent_id' => 2, + 'user_id' => 0, + 'notification_read' => 0, + 'notification_time' => 1349413324, + 'notification_data' => array( + 'poster_id' => 2, + 'topic_title' => 'test-title', + 'post_subject' => 'Re: test-title', + 'post_username' => '', + 'forum_id' => 2, + 'forum_name' => 'Your first forum', + ), + ), + array( + 'item_id' => 5, + 'item_parent_id' => 2, + 'user_id' => 0, + 'notification_read' => 0, + 'notification_time' => 1349413325, + 'notification_data' => array( + 'poster_id' => 2, + 'topic_title' => 'test-title2', + 'post_subject' => 'Re: test-title2', + 'post_username' => '', + 'forum_id' => 3, + 'forum_name' => 'Your second forum', + ), + ), + ) ); - - $this->assertEquals(sizeof($expected), $notifications['unread_count']); - - $notifications = $notifications['notifications']; - - foreach ($expected as $notification_id => $notification_data) - { - //echo $notifications[$notification_id]; - - $this->assertEquals($notification_id, $notifications[$notification_id]->notification_id, 'notification_id'); - - foreach ($notification_data as $key => $value) - { - $this->assertEquals($value, $notifications[$notification_id]->$key, $key . ' ' . $notification_id); - } - } } } diff --git a/tests/template/template_test.php b/tests/template/template_test.php index f2e3903458..2cca20f4c2 100644 --- a/tests/template/template_test.php +++ b/tests/template/template_test.php @@ -158,7 +158,7 @@ class phpbb_template_template_test extends phpbb_template_template_test_case array(), array('test_loop' => array(array(), array(), array(), array(), array(), array(), array()), 'test' => array(array()), 'test.deep' => array(array()), 'test.deep.defines' => array(array())), array(), - "xyz\nabc\n\$VALUE == 'abc'abc\nbar\nbar\nabc\ntest!@#$%^&*()_-=+{}[]:;\",<.>/?\n[]", + "xyz\nabc\n\$VALUE == 'abc'\n(\$VALUE == 'abc')\n!\$DOESNT_EXIST\n(!\$DOESNT_EXIST)\nabc\nbar\nbar\nabc\ntest!@#$%^&*()_-=+{}[]:;\",<.>/?[]|foobar|", ), array( 'define_advanced.html', @@ -237,7 +237,7 @@ class phpbb_template_template_test extends phpbb_template_template_test_case array('VARIABLE' => 'variable.html'), array(), array(), - 'variable.html', + "variable.html\nvariable.html\nvariable.html", ), array( 'include_loop_define.html', diff --git a/tests/template/templates/define.html b/tests/template/templates/define.html index e6c8ef49c9..bc20c02ed1 100644 --- a/tests/template/templates/define.html +++ b/tests/template/templates/define.html @@ -7,6 +7,15 @@ $VALUE != 'abc' <!-- ELSEIF $VALUE == 'abc' --> $VALUE == 'abc' <!-- ENDIF --> +<!-- IF ($VALUE == 'abc') --> +($VALUE == 'abc') +<!-- ENDIF --> +<!-- IF !$DOESNT_EXIST --> +!$DOESNT_EXIST +<!-- ENDIF --> +<!-- IF (!$DOESNT_EXIST) --> +(!$DOESNT_EXIST) +<!-- ENDIF --> <!-- INCLUDE define_include.html --> {$INCLUDED_VALUE} {$VALUE} @@ -16,3 +25,4 @@ $VALUE == 'abc' {$VALUE} <!-- DEFINE $VALUE = '' --> [{$VALUE}] +<!-- DEFINE $TEST -->foobar<!-- ENDDEFINE -->|{$TEST}| diff --git a/tests/template/templates/include_define_variable.html b/tests/template/templates/include_define_variable.html index aff9b574c2..6052657c97 100644 --- a/tests/template/templates/include_define_variable.html +++ b/tests/template/templates/include_define_variable.html @@ -1,2 +1,8 @@ <!-- DEFINE $DEF = '{VARIABLE}' --> <!-- INCLUDE {$DEF} --> + +<!-- DEFINE $DEF_WITH_UNDERSCORES = '{VARIABLE}' --> +<!-- INCLUDE {$DEF_WITH_UNDERSCORES} --> + +<!-- DEFINE $DEF123 = '{VARIABLE}' --> +<!-- INCLUDE {$DEF123} --> diff --git a/tests/test_framework/phpbb_database_test_connection_manager.php b/tests/test_framework/phpbb_database_test_connection_manager.php index c93a777701..9d2cfebd29 100644 --- a/tests/test_framework/phpbb_database_test_connection_manager.php +++ b/tests/test_framework/phpbb_database_test_connection_manager.php @@ -138,7 +138,7 @@ class phpbb_database_test_connection_manager catch (PDOException $e) { $cleaned_dsn = str_replace($this->config['dbpasswd'], '*password*', $dsn); - throw new Exception("Unable do connect to $cleaned_dsn using PDO with error: {$e->getMessage()}"); + throw new Exception("Unable to connect to $cleaned_dsn using PDO with error: {$e->getMessage()}"); } $this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); diff --git a/tests/test_framework/phpbb_functional_test_case.php b/tests/test_framework/phpbb_functional_test_case.php index dedaf4cd68..579e225ed9 100644 --- a/tests/test_framework/phpbb_functional_test_case.php +++ b/tests/test_framework/phpbb_functional_test_case.php @@ -533,12 +533,9 @@ class phpbb_functional_test_case extends phpbb_test_case $cache = new phpbb_mock_null_cache; $cache_driver = new phpbb_cache_driver_null(); - $phpbb_container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface'); - $phpbb_container - ->expects($this->any()) - ->method('get') - ->with('cache.driver') - ->will($this->returnValue($cache_driver)); + $phpbb_container = new phpbb_mock_container_builder(); + $phpbb_container->set('cache.driver', $cache_driver); + $phpbb_container->set('notification_manager', new phpbb_mock_notification_manager()); if (!function_exists('utf_clean_string')) { |