diff options
40 files changed, 379 insertions, 72 deletions
diff --git a/phpBB/adm/index.php b/phpBB/adm/index.php index 7dc8e4b13d..d27f56f28b 100644 --- a/phpBB/adm/index.php +++ b/phpBB/adm/index.php @@ -41,6 +41,7 @@ if (!isset($user->data['session_admin']) || !$user->data['session_admin']) // check specific permissions but this is a catchall if (!$auth->acl_get('a_')) { + send_status_line(403, 'Forbidden'); trigger_error('NO_ADMIN'); } diff --git a/phpBB/config/default/container/services_files.yml b/phpBB/config/default/container/services_files.yml index cf51ebdab8..ba1fdb4c9a 100644 --- a/phpBB/config/default/container/services_files.yml +++ b/phpBB/config/default/container/services_files.yml @@ -37,7 +37,7 @@ services: - '@request' files.types.local: - class: phpbb\files\types\form + class: phpbb\files\types\local shared: false arguments: - '@files.factory' diff --git a/phpBB/config/installer/routing/installer.yml b/phpBB/config/installer/routing/installer.yml index 47e16aa454..66b8893ad9 100644 --- a/phpBB/config/installer/routing/installer.yml +++ b/phpBB/config/installer/routing/installer.yml @@ -43,7 +43,7 @@ phpbb_convert_intro: start_new: 0 phpbb_convert_settings: - path: /convert/settings/{convertor} + path: /convert/settings/{converter} defaults: _controller: phpbb.installer.controller.convert:settings requirements: diff --git a/phpBB/docs/events.md b/phpBB/docs/events.md index d5aa0c3aec..f2241228fe 100644 --- a/phpBB/docs/events.md +++ b/phpBB/docs/events.md @@ -835,6 +835,20 @@ mcp_topic_options_before * Since: 3.1.6-RC1 * Purpose: Add some options (field, checkbox, ...) before the subject field when split a subject +mcp_topic_postrow_post_details_after +=== +* Locations: + + styles/prosilver/template/mcp_topic.html +* Since: 3.1.10-RC1 +* Purpose: Add content after post details in topic moderation + +mcp_topic_postrow_post_details_before +=== +* Locations: + + styles/prosilver/template/mcp_topic.html +* Since: 3.1.10-RC1 +* Purpose: Add content before post details in topic moderation + mcp_topic_topic_title_after === * Locations: @@ -1449,6 +1463,20 @@ posting_preview_poll_after * Since: 3.1.7-RC1 * Purpose: Add content after the poll preview block +posting_topic_review_row_post_details_after +=== +* Locations: + + styles/prosilver/template/posting_topic_review.html +* Since: 3.1.10-RC1 +* Purpose: Add content after post details in topic review + +posting_topic_review_row_post_details_before +=== +* Locations: + + styles/prosilver/template/posting_topic_review.html +* Since: 3.1.10-RC1 +* Purpose: Add content before post details in topic review + posting_topic_title_after === * Locations: @@ -2057,6 +2085,13 @@ viewforum_body_topic_row_prepend * Since: 3.1.7-RC1 * Purpose: Add content at the end of the topic list item. +viewforum_body_topicrow_row_before +=== +* Locations: + + styles/prosilver/template/viewforum_body.html +* Since: 3.1.10-RC1 +* Purpose: Add content before list of topics. + viewforum_buttons_bottom_before === * Locations: diff --git a/phpBB/includes/acp/acp_groups.php b/phpBB/includes/acp/acp_groups.php index 6bd3e71c2e..305296d013 100644 --- a/phpBB/includes/acp/acp_groups.php +++ b/phpBB/includes/acp/acp_groups.php @@ -223,6 +223,7 @@ class acp_groups } else if ($action === 'delete' && $group_row['group_type'] == GROUP_SPECIAL) { + send_status_line(403, 'Forbidden'); trigger_error($user->lang['NO_AUTH_OPERATION'] . adm_back_link($this->u_action), E_USER_WARNING); } @@ -235,6 +236,7 @@ class acp_groups case 'delete': if (!$auth->acl_get('a_groupdel')) { + send_status_line(403, 'Forbidden'); trigger_error($user->lang['NO_AUTH_OPERATION'] . adm_back_link($this->u_action), E_USER_WARNING); } @@ -313,6 +315,7 @@ class acp_groups if ($action == 'add' && !$auth->acl_get('a_groupadd')) { + send_status_line(403, 'Forbidden'); trigger_error($user->lang['NO_AUTH_OPERATION'] . adm_back_link($this->u_action), E_USER_WARNING); } diff --git a/phpBB/includes/acp/acp_inactive.php b/phpBB/includes/acp/acp_inactive.php index 7ec43f45cc..ec256e93ef 100644 --- a/phpBB/includes/acp/acp_inactive.php +++ b/phpBB/includes/acp/acp_inactive.php @@ -164,6 +164,7 @@ class acp_inactive { if (!$auth->acl_get('a_userdel')) { + send_status_line(403, 'Forbidden'); trigger_error($user->lang['NO_AUTH_OPERATION'] . adm_back_link($this->u_action), E_USER_WARNING); } diff --git a/phpBB/includes/acp/acp_main.php b/phpBB/includes/acp/acp_main.php index f44bbbc88d..8697504c77 100644 --- a/phpBB/includes/acp/acp_main.php +++ b/phpBB/includes/acp/acp_main.php @@ -118,6 +118,7 @@ class acp_main case 'online': if (!$auth->acl_get('a_board')) { + send_status_line(403, 'Forbidden'); trigger_error($user->lang['NO_AUTH_OPERATION'] . adm_back_link($this->u_action), E_USER_WARNING); } @@ -134,6 +135,7 @@ class acp_main case 'stats': if (!$auth->acl_get('a_board')) { + send_status_line(403, 'Forbidden'); trigger_error($user->lang['NO_AUTH_OPERATION'] . adm_back_link($this->u_action), E_USER_WARNING); } @@ -189,6 +191,7 @@ class acp_main case 'user': if (!$auth->acl_get('a_board')) { + send_status_line(403, 'Forbidden'); trigger_error($user->lang['NO_AUTH_OPERATION'] . adm_back_link($this->u_action), E_USER_WARNING); } @@ -256,6 +259,7 @@ class acp_main case 'date': if (!$auth->acl_get('a_board')) { + send_status_line(403, 'Forbidden'); trigger_error($user->lang['NO_AUTH_OPERATION'] . adm_back_link($this->u_action), E_USER_WARNING); } @@ -372,6 +376,7 @@ class acp_main case 'purge_sessions': if ((int) $user->data['user_type'] !== USER_FOUNDER) { + send_status_line(403, 'Forbidden'); trigger_error($user->lang['NO_AUTH_OPERATION'] . adm_back_link($this->u_action), E_USER_WARNING); } diff --git a/phpBB/includes/acp/acp_permissions.php b/phpBB/includes/acp/acp_permissions.php index fdac7c4d00..df3e238bcc 100644 --- a/phpBB/includes/acp/acp_permissions.php +++ b/phpBB/includes/acp/acp_permissions.php @@ -315,6 +315,7 @@ class acp_permissions case 'apply_permissions': if (!isset($_POST['setting'])) { + send_status_line(403, 'Forbidden'); trigger_error($user->lang['NO_AUTH_SETTING_FOUND'] . adm_back_link($this->u_action), E_USER_WARNING); } if (!check_form_key($form_name)) @@ -328,6 +329,7 @@ class acp_permissions case 'apply_all_permissions': if (!isset($_POST['setting'])) { + send_status_line(403, 'Forbidden'); trigger_error($user->lang['NO_AUTH_SETTING_FOUND'] . adm_back_link($this->u_action), E_USER_WARNING); } if (!check_form_key($form_name)) @@ -687,6 +689,7 @@ class acp_permissions // Check the permission setting again if (!$auth->acl_get('a_' . str_replace('_', '', $permission_type) . 'auth') || !$auth->acl_get('a_auth' . $ug_type . 's')) { + send_status_line(403, 'Forbidden'); trigger_error($user->lang['NO_AUTH_OPERATION'] . adm_back_link($this->u_action), E_USER_WARNING); } @@ -772,6 +775,7 @@ class acp_permissions // Check the permission setting again if (!$auth->acl_get('a_' . str_replace('_', '', $permission_type) . 'auth') || !$auth->acl_get('a_auth' . $ug_type . 's')) { + send_status_line(403, 'Forbidden'); trigger_error($user->lang['NO_AUTH_OPERATION'] . adm_back_link($this->u_action), E_USER_WARNING); } @@ -884,6 +888,7 @@ class acp_permissions // Check the permission setting again if (!$auth->acl_get('a_' . str_replace('_', '', $permission_type) . 'auth') || !$auth->acl_get('a_auth' . $ug_type . 's')) { + send_status_line(403, 'Forbidden'); trigger_error($user->lang['NO_AUTH_OPERATION'] . adm_back_link($this->u_action), E_USER_WARNING); } diff --git a/phpBB/includes/acp/acp_users.php b/phpBB/includes/acp/acp_users.php index 5091fcae7e..a37396a713 100644 --- a/phpBB/includes/acp/acp_users.php +++ b/phpBB/includes/acp/acp_users.php @@ -205,6 +205,7 @@ class acp_users { if (!$auth->acl_get('a_userdel')) { + send_status_line(403, 'Forbidden'); trigger_error($user->lang['NO_AUTH_OPERATION'] . adm_back_link($this->u_action . '&u=' . $user_id), E_USER_WARNING); } diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index 588a717f0e..465964913c 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -2264,6 +2264,7 @@ function login_box($redirect = '', $l_explain = '', $l_success = '', $admin = fa { $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_ADMIN_AUTH_FAIL'); } + send_status_line(403, 'Forbidden'); trigger_error('NO_AUTH_ADMIN'); } @@ -2280,6 +2281,7 @@ function login_box($redirect = '', $l_explain = '', $l_success = '', $admin = fa { $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_ADMIN_AUTH_FAIL'); } + send_status_line(403, 'Forbidden'); trigger_error('NO_AUTH_ADMIN'); } @@ -2301,6 +2303,8 @@ function login_box($redirect = '', $l_explain = '', $l_success = '', $admin = fa { // We log the attempt to use a different username... $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_ADMIN_AUTH_FAIL'); + + send_status_line(403, 'Forbidden'); trigger_error('NO_AUTH_ADMIN_USER_DIFFER'); } diff --git a/phpBB/includes/functions_privmsgs.php b/phpBB/includes/functions_privmsgs.php index d92934e59e..69c3dad9e6 100644 --- a/phpBB/includes/functions_privmsgs.php +++ b/phpBB/includes/functions_privmsgs.php @@ -801,6 +801,7 @@ function move_pm($user_id, $message_limit, $move_msg_ids, $dest_folder, $cur_fol if (!$row) { + send_status_line(403, 'Forbidden'); trigger_error('NOT_AUTHORISED'); } @@ -965,6 +966,7 @@ function handle_mark_actions($user_id, $mark_action) if (!$auth->acl_get('u_pm_delete')) { + send_status_line(403, 'Forbidden'); trigger_error('NO_AUTH_DELETE_MESSAGE'); } diff --git a/phpBB/includes/mcp/mcp_forum.php b/phpBB/includes/mcp/mcp_forum.php index dc4d59cc46..e381210331 100644 --- a/phpBB/includes/mcp/mcp_forum.php +++ b/phpBB/includes/mcp/mcp_forum.php @@ -274,7 +274,7 @@ function mcp_forum_view($id, $mode, $action, $forum_info) 'TOPIC_ICON_IMG_WIDTH' => (!empty($icons[$row_ary['icon_id']])) ? $icons[$row_ary['icon_id']]['width'] : '', 'TOPIC_ICON_IMG_HEIGHT' => (!empty($icons[$row_ary['icon_id']])) ? $icons[$row_ary['icon_id']]['height'] : '', 'UNAPPROVED_IMG' => ($topic_unapproved || $posts_unapproved) ? $user->img('icon_topic_unapproved', ($topic_unapproved) ? 'TOPIC_UNAPPROVED' : 'POSTS_UNAPPROVED') : '', - 'DELETED_IMG' => ($topic_deleted) ? $user->img('icon_topic_deleted', 'POSTS_DELETED') : '', + 'DELETED_IMG' => ($topic_deleted) ? $user->img('icon_topic_deleted', 'TOPIC_DELETED') : '', 'TOPIC_AUTHOR' => get_username_string('username', $row_ary['topic_poster'], $row_ary['topic_first_poster_name'], $row_ary['topic_first_poster_colour']), 'TOPIC_AUTHOR_COLOUR' => get_username_string('colour', $row_ary['topic_poster'], $row_ary['topic_first_poster_name'], $row_ary['topic_first_poster_colour']), diff --git a/phpBB/includes/mcp/mcp_logs.php b/phpBB/includes/mcp/mcp_logs.php index fca0412321..c34c915a40 100644 --- a/phpBB/includes/mcp/mcp_logs.php +++ b/phpBB/includes/mcp/mcp_logs.php @@ -83,6 +83,7 @@ class mcp_logs if (!in_array($forum_id, $forum_list)) { + send_status_line(403, 'Forbidden'); trigger_error('NOT_AUTHORISED'); } @@ -101,6 +102,7 @@ class mcp_logs if (!in_array($forum_id, $forum_list)) { + send_status_line(403, 'Forbidden'); trigger_error('NOT_AUTHORISED'); } diff --git a/phpBB/includes/mcp/mcp_queue.php b/phpBB/includes/mcp/mcp_queue.php index 1ccced7a2f..9060cc1098 100644 --- a/phpBB/includes/mcp/mcp_queue.php +++ b/phpBB/includes/mcp/mcp_queue.php @@ -622,6 +622,7 @@ class mcp_queue if (!phpbb_check_ids($post_id_list, POSTS_TABLE, 'post_id', array('m_approve'))) { + send_status_line(403, 'Forbidden'); trigger_error('NOT_AUTHORISED'); } @@ -877,6 +878,7 @@ class mcp_queue if (!phpbb_check_ids($topic_id_list, TOPICS_TABLE, 'topic_id', array('m_approve'))) { + send_status_line(403, 'Forbidden'); trigger_error('NOT_AUTHORISED'); } @@ -1074,6 +1076,7 @@ class mcp_queue if (!phpbb_check_ids($post_id_list, POSTS_TABLE, 'post_id', array('m_approve'))) { + send_status_line(403, 'Forbidden'); trigger_error('NOT_AUTHORISED'); } diff --git a/phpBB/includes/mcp/mcp_reports.php b/phpBB/includes/mcp/mcp_reports.php index 3809ea2616..1462acf110 100644 --- a/phpBB/includes/mcp/mcp_reports.php +++ b/phpBB/includes/mcp/mcp_reports.php @@ -542,6 +542,7 @@ function close_report($report_id_list, $mode, $action, $pm = false) { if (!$auth->acl_getf_global('m_report')) { + send_status_line(403, 'Forbidden'); trigger_error('NOT_AUTHORISED'); } } @@ -549,6 +550,7 @@ function close_report($report_id_list, $mode, $action, $pm = false) { if (!phpbb_check_ids($post_id_list, POSTS_TABLE, 'post_id', array('m_report'))) { + send_status_line(403, 'Forbidden'); trigger_error('NOT_AUTHORISED'); } } diff --git a/phpBB/includes/ucp/ucp_activate.php b/phpBB/includes/ucp/ucp_activate.php index 00044340df..1e54c18dc1 100644 --- a/phpBB/includes/ucp/ucp_activate.php +++ b/phpBB/includes/ucp/ucp_activate.php @@ -67,6 +67,7 @@ class ucp_activate { login_box('', $user->lang['NO_AUTH_OPERATION']); } + send_status_line(403, 'Forbidden'); trigger_error('NO_AUTH_OPERATION'); } diff --git a/phpBB/includes/ucp/ucp_groups.php b/phpBB/includes/ucp/ucp_groups.php index faffbe5bdc..352b7d1ec3 100644 --- a/phpBB/includes/ucp/ucp_groups.php +++ b/phpBB/includes/ucp/ucp_groups.php @@ -87,6 +87,7 @@ class ucp_groups if (!$auth->acl_get('u_chggrp')) { + send_status_line(403, 'Forbidden'); trigger_error($user->lang['NOT_AUTHORISED'] . $return_page); } diff --git a/phpBB/includes/ucp/ucp_pm.php b/phpBB/includes/ucp/ucp_pm.php index 33dff97fe6..d145d66f59 100644 --- a/phpBB/includes/ucp/ucp_pm.php +++ b/phpBB/includes/ucp/ucp_pm.php @@ -166,6 +166,7 @@ class ucp_pm if (!$auth->acl_get('u_readpm')) { + send_status_line(403, 'Forbidden'); trigger_error('NO_AUTH_READ_MESSAGE'); } diff --git a/phpBB/includes/ucp/ucp_pm_compose.php b/phpBB/includes/ucp/ucp_pm_compose.php index ad9a99204f..b61a9fab9f 100644 --- a/phpBB/includes/ucp/ucp_pm_compose.php +++ b/phpBB/includes/ucp/ucp_pm_compose.php @@ -171,6 +171,7 @@ function compose_pm($id, $mode, $action, $user_folders = array()) case 'post': if (!$auth->acl_get('u_sendpm')) { + send_status_line(403, 'Forbidden'); trigger_error('NO_AUTH_SEND_MESSAGE'); } break; @@ -186,6 +187,7 @@ function compose_pm($id, $mode, $action, $user_folders = array()) if (!$auth->acl_get('u_sendpm')) { + send_status_line(403, 'Forbidden'); trigger_error('NO_AUTH_SEND_MESSAGE'); } @@ -226,6 +228,7 @@ function compose_pm($id, $mode, $action, $user_folders = array()) case 'delete': if (!$auth->acl_get('u_pm_delete')) { + send_status_line(403, 'Forbidden'); trigger_error('NO_AUTH_DELETE_MESSAGE'); } @@ -251,11 +254,13 @@ function compose_pm($id, $mode, $action, $user_folders = array()) if ($action == 'forward' && (!$config['forward_pm'] || !$auth->acl_get('u_pm_forward'))) { + send_status_line(403, 'Forbidden'); trigger_error('NO_AUTH_FORWARD_MESSAGE'); } if ($action == 'edit' && !$auth->acl_get('u_pm_edit')) { + send_status_line(403, 'Forbidden'); trigger_error('NO_AUTH_EDIT_MESSAGE'); } @@ -321,6 +326,7 @@ function compose_pm($id, $mode, $action, $user_folders = array()) { if (($post['forum_id'] && !$auth->acl_get('f_read', $post['forum_id'])) || (!$post['forum_id'] && !$auth->acl_getf_global('f_read'))) { + send_status_line(403, 'Forbidden'); trigger_error('NOT_AUTHORISED'); } @@ -456,6 +462,7 @@ function compose_pm($id, $mode, $action, $user_folders = array()) if (($to_group_id || isset($address_list['g'])) && (!$config['allow_mass_pm'] || !$auth->acl_get('u_masspm_group'))) { + send_status_line(403, 'Forbidden'); trigger_error('NO_AUTH_GROUP_MESSAGE'); } diff --git a/phpBB/includes/ucp/ucp_pm_viewmessage.php b/phpBB/includes/ucp/ucp_pm_viewmessage.php index 2457ea9a2e..48d14a133c 100644 --- a/phpBB/includes/ucp/ucp_pm_viewmessage.php +++ b/phpBB/includes/ucp/ucp_pm_viewmessage.php @@ -41,6 +41,7 @@ function view_message($id, $mode, $folder_id, $msg_id, $folder, $message_row) $message = $user->lang['NO_AUTH_READ_REMOVED_MESSAGE']; $message .= '<br /><br />' . sprintf($user->lang['RETURN_FOLDER'], '<a href="' . $meta_info . '">', '</a>'); + send_status_line(403, 'Forbidden'); trigger_error($message); } diff --git a/phpBB/includes/ucp/ucp_profile.php b/phpBB/includes/ucp/ucp_profile.php index a9f8e10eef..a86c4f2672 100644 --- a/phpBB/includes/ucp/ucp_profile.php +++ b/phpBB/includes/ucp/ucp_profile.php @@ -279,6 +279,7 @@ class ucp_profile // Do not display profile information panel if not authed to do so if (!$auth->acl_get('u_chgprofileinfo')) { + send_status_line(403, 'Forbidden'); trigger_error('NO_AUTH_PROFILEINFO'); } @@ -464,6 +465,7 @@ class ucp_profile if (!$auth->acl_get('u_sig')) { + send_status_line(403, 'Forbidden'); trigger_error('NO_AUTH_SIGNATURE'); } diff --git a/phpBB/includes/ucp/ucp_remind.php b/phpBB/includes/ucp/ucp_remind.php index 0a46674fb1..a44f077693 100644 --- a/phpBB/includes/ucp/ucp_remind.php +++ b/phpBB/includes/ucp/ucp_remind.php @@ -79,6 +79,7 @@ class ucp_remind if (!$auth2->acl_get('u_chgpasswd')) { + send_status_line(403, 'Forbidden'); trigger_error('NO_AUTH_PASSWORD_REMINDER'); } diff --git a/phpBB/language/en/migrator.php b/phpBB/language/en/migrator.php index 78364319a1..8a82d40be5 100644 --- a/phpBB/language/en/migrator.php +++ b/phpBB/language/en/migrator.php @@ -69,9 +69,12 @@ $lang = array_merge($lang, array( 'MIGRATION_INVALID_DATA_UNDEFINED_METHOD' => 'A migration is invalid. An undefined migration tool method was encountered.', 'MODULE_ERROR' => 'An error occurred while creating a module: %s', + 'MODULE_EXISTS' => 'A module already exists: %s', + 'MODULE_EXIST_MULTIPLE' => 'Several modules with the given parent module langname already exist: %s. Try using before/after keys to clarify the module placement.', 'MODULE_INFO_FILE_NOT_EXIST' => 'A required module info file is missing: %2$s', 'MODULE_NOT_EXIST' => 'A required module does not exist: %s', + 'PARENT_MODULE_FIND_ERROR' => 'Unable to determine the parent module identifier: %s', 'PERMISSION_NOT_EXIST' => 'The permission setting "%s" unexpectedly does not exist.', 'ROLE_NOT_EXIST' => 'The permission role "%s" unexpectedly does not exist.', diff --git a/phpBB/mcp.php b/phpBB/mcp.php index a5fa09ba2b..a5464f4a73 100644 --- a/phpBB/mcp.php +++ b/phpBB/mcp.php @@ -127,6 +127,7 @@ if (!$auth->acl_getf_global('m_')) if (!$allow_user) { + send_status_line(403, 'Forbidden'); trigger_error('NOT_AUTHORISED'); } } @@ -134,6 +135,7 @@ if (!$auth->acl_getf_global('m_')) // if the user cannot read the forum he tries to access then we won't allow mcp access either if ($forum_id && !$auth->acl_get('f_read', $forum_id)) { + send_status_line(403, 'Forbidden'); trigger_error('NOT_AUTHORISED'); } diff --git a/phpBB/memberlist.php b/phpBB/memberlist.php index bfa28d8d11..e816e06488 100644 --- a/phpBB/memberlist.php +++ b/phpBB/memberlist.php @@ -75,6 +75,7 @@ switch ($mode) { if ($user->data['user_id'] != ANONYMOUS) { + send_status_line(403, 'Forbidden'); trigger_error('NO_VIEW_USERS'); } @@ -372,6 +373,7 @@ switch ($mode) if (!$auth->acl_get('u_sendim')) { + send_status_line(403, 'Forbidden'); trigger_error('NOT_AUTHORISED'); } diff --git a/phpBB/phpbb/db/migration/tool/module.php b/phpBB/phpbb/db/migration/tool/module.php index 90ed63e2e6..a7dffbb7f2 100644 --- a/phpBB/phpbb/db/migration/tool/module.php +++ b/phpBB/phpbb/db/migration/tool/module.php @@ -41,6 +41,9 @@ class module implements \phpbb\db\migration\tool\tool_interface /** @var string */ protected $modules_table; + /** @var array */ + protected $module_categories = array(); + /** * Constructor * @@ -94,30 +97,8 @@ class module implements \phpbb\db\migration\tool\tool_interface $parent_sql = ''; if ($parent !== false) { - // Allows '' to be sent as 0 - $parent = $parent ?: 0; - - if (!is_numeric($parent)) - { - $sql = 'SELECT module_id - FROM ' . $this->modules_table . " - WHERE module_langname = '" . $this->db->sql_escape($parent) . "' - AND module_class = '" . $this->db->sql_escape($class) . "'"; - $result = $this->db->sql_query($sql); - $module_id = $this->db->sql_fetchfield('module_id'); - $this->db->sql_freeresult($result); - - if (!$module_id) - { - return false; - } - - $parent_sql = 'AND parent_id = ' . (int) $module_id; - } - else - { - $parent_sql = 'AND parent_id = ' . (int) $parent; - } + $parent = $this->get_parent_module_id($parent, $module); + $parent_sql = 'AND parent_id = ' . (int) $parent; } $sql = 'SELECT module_id @@ -180,15 +161,14 @@ class module implements \phpbb\db\migration\tool\tool_interface { global $user, $phpbb_log; - // Allows '' to be sent as 0 - $parent = $parent ?: 0; - // allow sending the name as a string in $data to create a category if (!is_array($data)) { $data = array('module_langname' => $data); } + $parent = $data['parent_id'] = $this->get_parent_module_id($parent, $data); + if (!isset($data['module_langname'])) { // The "automatic" way @@ -218,31 +198,14 @@ class module implements \phpbb\db\migration\tool\tool_interface } // The "manual" way - if (!is_numeric($parent)) - { - $sql = 'SELECT module_id - FROM ' . $this->modules_table . " - WHERE module_langname = '" . $this->db->sql_escape($parent) . "' - AND module_class = '" . $this->db->sql_escape($class) . "'"; - $result = $this->db->sql_query($sql); - $module_id = $this->db->sql_fetchfield('module_id'); - $this->db->sql_freeresult($result); - - if (!$module_id) - { - throw new \phpbb\db\migration\exception('MODULE_NOT_EXIST', $parent); - } - - $parent = $data['parent_id'] = $module_id; - } - else if (!$this->exists($class, false, $parent)) + if (!$this->exists($class, false, $parent)) { throw new \phpbb\db\migration\exception('MODULE_NOT_EXIST', $parent); } if ($this->exists($class, $parent, $data['module_langname'])) { - return; + throw new \phpbb\db\migration\exception('MODULE_EXISTS', $module_id); } $module_data = array( @@ -374,26 +337,8 @@ class module implements \phpbb\db\migration\tool\tool_interface $parent_sql = ''; if ($parent !== false) { - // Allows '' to be sent as 0 - $parent = ($parent) ?: 0; - - if (!is_numeric($parent)) - { - $sql = 'SELECT module_id - FROM ' . $this->modules_table . " - WHERE module_langname = '" . $this->db->sql_escape($parent) . "' - AND module_class = '" . $this->db->sql_escape($class) . "'"; - $result = $this->db->sql_query($sql); - $module_id = $this->db->sql_fetchfield('module_id'); - $this->db->sql_freeresult($result); - - // we know it exists from the module_exists check - $parent_sql = 'AND parent_id = ' . (int) $module_id; - } - else - { - $parent_sql = 'AND parent_id = ' . (int) $parent; - } + $parent = $this->get_parent_module_id($parent, $module); + $parent_sql = 'AND parent_id = ' . (int) $parent; } $module_ids = array(); @@ -475,4 +420,110 @@ class module implements \phpbb\db\migration\tool\tool_interface return array_pop($module); } + + /** + * Get the list of installed module categories + * key - module_id + * value - module_langname + * + * @return null + */ + protected function get_categories_list() + { + // Select the top level categories + // and 2nd level [sub]categories which exist for ACP only + $sql = 'SELECT m2.module_id, m2.module_langname + FROM ' . $this->modules_table . ' m1, ' . $this->modules_table . " m2 + WHERE m1.parent_id = 0 + AND (m1.module_id = m2.module_id + OR m2.module_class = 'acp' AND m2.parent_id = m1.module_id) + ORDER BY m1.module_id, m2.module_id ASC"; + + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + $this->module_categories[(int) $row['module_id']] = $row['module_langname']; + } + $this->db->sql_freeresult($result); + } + + /** + * Get parent module id + * + * @param string|int $parent_id The parent module_id|module_langname + * @param int|string|array $data The module_id, module_langname for existance checking or module data array for adding + * @return int The parent module_id + * @throws \phpbb\db\migration\exception + */ + public function get_parent_module_id($parent_id, $data = '') + { + // Allow '' to be sent as 0 + $parent_id = $parent_id ?: 0; + + // If automatic adding is in action, convert array back to string to simplify things + if (is_array($data) && sizeof($data) == 1) + { + $data = $data['module_langname']; + } + + if (!is_numeric($parent_id)) + { + // Refresh the $module_categories array + $this->get_categories_list(); + + // Search for the parent module_langname + $ids = array_keys($this->module_categories, $parent_id); + + switch (sizeof($ids)) + { + // No parent with the given module_langname exist + case 0: + throw new \phpbb\db\migration\exception('MODULE_NOT_EXIST', $parent_id); + break; + + // Return the module id + case 1: + $parent_id = (int) $ids[0]; + break; + + // Several modules with the given module_langname were found + // Try to determine the parent_id by the neighbour module parent + default: + if (is_array($data) && (isset($data['before']) || isset($data['after']))) + { + $neighbour_module_langname = isset($data['before']) ? $data['before'] : $data['after']; + $sql = 'SELECT parent_id + FROM ' . $this->modules_table . " + WHERE module_langname = '" . $this->db->sql_escape($neighbour_module_langname) . "' + AND " . $this->db->sql_in_set('parent_id', $ids); + $result = $this->db->sql_query($sql); + $parent_id = (int) $this->db->sql_fetchfield('parent_id'); + if (!$parent_id) + { + throw new \phpbb\db\migration\exception('PARENT_MODULE_FIND_ERROR', $data['parent_id']); + } + } + else if (!empty($data) && !is_array($data)) + { + // The module_langname is set, checking for the module existance + // As more than 1 parents were found already, there's no way for null parent_id here + $sql = 'SELECT m2.module_id as module_parent_id + FROM ' . $this->modules_table . ' m1, ' . $this->modules_table . " m2 + WHERE " . ((is_numeric($data)) ? 'm1.module_id = ' . (int) $data : "m1.module_langname = '" . $this->db->sql_escape($data)) . "' + AND m2.module_id = m1.parent_id + AND " . $this->db->sql_in_set('m2.module_id', $ids); + $result = $this->db->sql_query($sql); + $parent_id = (int) $this->db->sql_fetchfield('module_parent_id'); + } + else + { + //Unable to get the parent module id, throwing an exception + throw new \phpbb\db\migration\exception('MODULE_EXIST_MULTIPLE', $parent_id); + } + break; + } + } + + return $parent_id; + } } diff --git a/phpBB/phpbb/feed/forum.php b/phpBB/phpbb/feed/forum.php index 6701c4d9e7..f522e91169 100644 --- a/phpBB/phpbb/feed/forum.php +++ b/phpBB/phpbb/feed/forum.php @@ -74,6 +74,14 @@ class forum extends post_base // Make sure we can read this forum if (!$this->auth->acl_get('f_read', $this->forum_id)) { + if ($this->user->data['user_id'] != ANONYMOUS) + { + send_status_line(403, 'Forbidden'); + } + else + { + send_status_line(401, 'Unauthorized'); + } throw new unauthorized_forum_exception($this->forum_id); } @@ -84,6 +92,14 @@ class forum extends post_base if (isset($forum_ids_passworded[$this->forum_id])) { + if ($this->user->data['user_id'] != ANONYMOUS) + { + send_status_line(403, 'Forbidden'); + } + else + { + send_status_line(401, 'Unauthorized'); + } throw new unauthorized_forum_exception($this->forum_id); } diff --git a/phpBB/phpbb/feed/topic.php b/phpBB/phpbb/feed/topic.php index f029c2b00e..e5f2c41468 100644 --- a/phpBB/phpbb/feed/topic.php +++ b/phpBB/phpbb/feed/topic.php @@ -66,6 +66,14 @@ class topic extends post_base // Make sure topic is either approved or user authed if ($this->topic_data['topic_visibility'] != ITEM_APPROVED && !$this->auth->acl_get('m_approve', $this->forum_id)) { + if ($this->user->data['user_id'] != ANONYMOUS) + { + send_status_line(403, 'Forbidden'); + } + else + { + send_status_line(401, 'Unauthorized'); + } throw new unauthorized_topic_exception($this->topic_id); } @@ -78,6 +86,14 @@ class topic extends post_base // Make sure we can read this forum if (!$this->auth->acl_get('f_read', $this->forum_id)) { + if ($this->user->data['user_id'] != ANONYMOUS) + { + send_status_line(403, 'Forbidden'); + } + else + { + send_status_line(401, 'Unauthorized'); + } throw new unauthorized_forum_exception($this->forum_id); } @@ -88,6 +104,14 @@ class topic extends post_base if (isset($forum_ids_passworded[$this->forum_id])) { + if ($this->user->data['user_id'] != ANONYMOUS) + { + send_status_line(403, 'Forbidden'); + } + else + { + send_status_line(401, 'Unauthorized'); + } throw new unauthorized_forum_exception($this->forum_id); } diff --git a/phpBB/phpbb/message/topic_form.php b/phpBB/phpbb/message/topic_form.php index 174643bb81..dbb883c142 100644 --- a/phpBB/phpbb/message/topic_form.php +++ b/phpBB/phpbb/message/topic_form.php @@ -71,6 +71,14 @@ class topic_form extends form if (!$this->auth->acl_get('f_read', $this->topic_row['forum_id'])) { + if ($this->user->data['user_id'] != ANONYMOUS) + { + send_status_line(403, 'Forbidden'); + } + else + { + send_status_line(401, 'Unauthorized'); + } return 'SORRY_AUTH_READ'; } diff --git a/phpBB/phpbb/session.php b/phpBB/phpbb/session.php index 12031bda03..518cee4705 100644 --- a/phpBB/phpbb/session.php +++ b/phpBB/phpbb/session.php @@ -1602,7 +1602,7 @@ class session $this->data = array_merge($this->data, $sql_ary); - if ($this->data['user_id'] != ANONYMOUS && !empty($config['new_member_post_limit']) && $this->data['user_new'] && $config['new_member_post_limit'] <= $this->data['user_posts']) + if ($this->data['user_id'] != ANONYMOUS && isset($config['new_member_post_limit']) && $this->data['user_new'] && $config['new_member_post_limit'] <= $this->data['user_posts']) { $this->leave_newly_registered(); } diff --git a/phpBB/search.php b/phpBB/search.php index 3d8c05fed9..2d8a0ad7c7 100644 --- a/phpBB/search.php +++ b/phpBB/search.php @@ -129,6 +129,26 @@ $phpbb_content_visibility = $phpbb_container->get('content.visibility'); /* @var $pagination \phpbb\pagination */ $pagination = $phpbb_container->get('pagination'); +/** +* This event allows you to alter the above parameters, such as keywords and submit +* +* @event core.search_modify_submit_parameters +* @var string keywords The search keywords +* @var string author Specifies the author match, when ANONYMOUS is also a search-match +* @var int author_id ID of the author to search by +* @var string search_id Predefined search type name +* @var bool submit Whether or not the form has been submitted +* @since 3.1.10-RC1 +*/ +$vars = array( + 'keywords', + 'author', + 'author_id', + 'search_id', + 'submit', +); +extract($phpbb_dispatcher->trigger_event('core.search_modify_submit_parameters', compact($vars))); + if ($keywords || $author || $author_id || $search_id || $submit) { // clear arrays diff --git a/phpBB/styles/prosilver/template/mcp_topic.html b/phpBB/styles/prosilver/template/mcp_topic.html index 32e5f0236c..c3050a8891 100644 --- a/phpBB/styles/prosilver/template/mcp_topic.html +++ b/phpBB/styles/prosilver/template/mcp_topic.html @@ -112,11 +112,15 @@ </ul> <h3><a href="{postrow.U_POST_DETAILS}">{postrow.POST_SUBJECT}</a></h3> + + <!-- EVENT mcp_topic_postrow_post_details_before --> <p class="author"> <a href="#pr{postrow.POST_ID}" title="{postrow.MINI_POST}"> <i class="icon fa-file fa-fw icon-lightgray icon-tiny" aria-hidden="true"></i><span class="sr-only">{postrow.MINI_POST}</span> </a> {L_POSTED} {postrow.POST_DATE} {L_POST_BY_AUTHOR} <strong>{postrow.POST_AUTHOR_FULL}</strong><!-- IF postrow.U_MCP_DETAILS --> [ <a href="{postrow.U_MCP_DETAILS}">{L_POST_DETAILS}</a> ]<!-- ENDIF --> </p> + <!-- EVENT mcp_topic_postrow_post_details_after --> + <!-- IF postrow.S_POST_UNAPPROVED --> <p class="post-notice unapproved"> <a href="{postrow.U_MCP_APPROVE}"><i class="icon fa-exclamation fa-fw icon-red" aria-hidden="true"></i><strong>{L_POST_UNAPPROVED}</strong></a> diff --git a/phpBB/styles/prosilver/template/posting_topic_review.html b/phpBB/styles/prosilver/template/posting_topic_review.html index dae0095105..3d7856d27a 100644 --- a/phpBB/styles/prosilver/template/posting_topic_review.html +++ b/phpBB/styles/prosilver/template/posting_topic_review.html @@ -43,6 +43,7 @@ </ul> <!-- ENDIF --> + <!-- EVENT posting_topic_review_row_post_details_before --> <p class="author"> <!-- IF S_IS_BOT --> <span><i class="icon fa-file fa-fw icon-lightgray icon-md" aria-hidden="true"></i><span class="sr-only">{topic_review_row.MINI_POST}</span></span> @@ -53,6 +54,8 @@ <!-- ENDIF --> {L_POST_BY_AUTHOR} <strong>{topic_review_row.POST_AUTHOR_FULL}</strong> » {topic_review_row.POST_DATE} </p> + <!-- EVENT posting_topic_review_row_post_details_after --> + <div class="content">{topic_review_row.MESSAGE}</div> <!-- IF topic_review_row.S_HAS_ATTACHMENTS --> diff --git a/phpBB/styles/prosilver/template/viewforum_body.html b/phpBB/styles/prosilver/template/viewforum_body.html index 026c0b35cc..9824989687 100644 --- a/phpBB/styles/prosilver/template/viewforum_body.html +++ b/phpBB/styles/prosilver/template/viewforum_body.html @@ -126,6 +126,8 @@ <!-- ENDIF --> +<!-- EVENT viewforum_body_topic_row_before --> + <!-- BEGIN topicrow --> <!-- IF not topicrow.S_TOPIC_TYPE_SWITCH and not topicrow.S_FIRST_ROW --> @@ -150,7 +152,7 @@ <ul class="topiclist topics"> <!-- ENDIF --> - <!-- EVENT viewforum_body_topic_row_before --> + <!-- EVENT viewforum_body_topicrow_row_before --> <li class="row<!-- IF topicrow.S_ROW_COUNT is even --> bg1<!-- ELSE --> bg2<!-- ENDIF --><!-- IF topicrow.S_POST_GLOBAL --> global-announce<!-- ENDIF --><!-- IF topicrow.S_POST_ANNOUNCE --> announce<!-- ENDIF --><!-- IF topicrow.S_POST_STICKY --> sticky<!-- ENDIF --><!-- IF topicrow.S_TOPIC_REPORTED --> reported<!-- ENDIF -->"> <!-- EVENT viewforum_body_topic_row_prepend --> <dl class="row-item {topicrow.TOPIC_IMG_STYLE}"> diff --git a/phpBB/styles/prosilver/theme/bidi.css b/phpBB/styles/prosilver/theme/bidi.css index a6d4bef6f4..f09493ab3b 100644 --- a/phpBB/styles/prosilver/theme/bidi.css +++ b/phpBB/styles/prosilver/theme/bidi.css @@ -922,6 +922,7 @@ li.breadcrumbs span:first-child > a { .rtl .search-header .button-search-end { border: 0; + border-radius: 4px 0 0 4px; } .rtl .search-header { diff --git a/phpBB/viewforum.php b/phpBB/viewforum.php index 812df396fa..cdffe69155 100644 --- a/phpBB/viewforum.php +++ b/phpBB/viewforum.php @@ -91,6 +91,7 @@ if (!$auth->acl_gets('f_list', 'f_read', $forum_id) || ($forum_data['forum_type' { if ($user->data['user_id'] != ANONYMOUS) { + send_status_line(403, 'Forbidden'); trigger_error('SORRY_AUTH_READ'); } diff --git a/phpBB/viewonline.php b/phpBB/viewonline.php index e8698d9916..3f35ac541e 100644 --- a/phpBB/viewonline.php +++ b/phpBB/viewonline.php @@ -37,6 +37,7 @@ if (!$auth->acl_gets('u_viewprofile', 'a_user', 'a_useradd', 'a_userdel')) { if ($user->data['user_id'] != ANONYMOUS) { + send_status_line(403, 'Forbidden'); trigger_error('NO_VIEW_USERS'); } diff --git a/phpBB/viewtopic.php b/phpBB/viewtopic.php index ded0f9aacc..4325fafb43 100644 --- a/phpBB/viewtopic.php +++ b/phpBB/viewtopic.php @@ -376,6 +376,7 @@ if (!$overrides_f_read_check && !$auth->acl_get('f_read', $forum_id)) { if ($user->data['user_id'] != ANONYMOUS) { + send_status_line(403, 'Forbidden'); trigger_error('SORRY_AUTH_READ'); } diff --git a/tests/dbal/fixtures/migrator_module.xml b/tests/dbal/fixtures/migrator_module.xml index 32afe7e6f3..e172d7a145 100644 --- a/tests/dbal/fixtures/migrator_module.xml +++ b/tests/dbal/fixtures/migrator_module.xml @@ -20,7 +20,7 @@ <value>acp</value> <value>0</value> <value>1</value> - <value>4</value> + <value>6</value> <value>ACP_CAT</value> <value></value> <value></value> @@ -38,5 +38,57 @@ <value>test</value> <value></value> </row> + <row> + <value>3</value> + <value>1</value> + <value>1</value> + <value></value> + <value>acp</value> + <value>1</value> + <value>4</value> + <value>5</value> + <value>ACP_FORUM_BASED_PERMISSIONS</value> + <value></value> + <value></value> + </row> + <row> + <value>4</value> + <value>1</value> + <value>1</value> + <value></value> + <value>acp</value> + <value>0</value> + <value>7</value> + <value>12</value> + <value>ACP_CAT_FORUMS</value> + <value></value> + <value></value> + </row> + <row> + <value>5</value> + <value>1</value> + <value>1</value> + <value></value> + <value>acp</value> + <value>4</value> + <value>8</value> + <value>11</value> + <value>ACP_FORUM_BASED_PERMISSIONS</value> + <value></value> + <value></value> + </row> + <row> + <value>6</value> + <value>1</value> + <value>1</value> + <value></value> + <value>acp</value> + <value>5</value> + <value>9</value> + <value>10</value> + <value>ACP_FORUM_BASED_PERMISSIONS_CHILD_1</value> + <value></value> + <value></value> + </row> </table> </dataset> diff --git a/tests/dbal/migrator_tool_module_test.php b/tests/dbal/migrator_tool_module_test.php index c2252c8d10..1744b7e92d 100644 --- a/tests/dbal/migrator_tool_module_test.php +++ b/tests/dbal/migrator_tool_module_test.php @@ -121,6 +121,44 @@ class phpbb_dbal_migrator_tool_module_test extends phpbb_database_test_case $this->fail($e); } $this->assertEquals(true, $this->tool->exists('acp', 'ACP_NEW_CAT', 'ACP_NEW_MODULE')); + + // Test adding module when plural parent module_langname exists + // PHPBB3-14703 + // Adding fail + try + { + $this->tool->add('acp', 'ACP_FORUM_BASED_PERMISSIONS', array( + 'module_basename' => 'acp_new_permissions_module', + 'module_langname' => 'ACP_NEW_PERMISSIONS_MODULE', + 'module_mode' => 'test', + 'module_auth' => '', + )); + $this->fail('Exception not thrown'); + } + catch (Exception $e) + { + $this->assertEquals('phpbb\db\migration\exception', get_class($e)); + $this->assertEquals('MODULE_EXIST_MULTIPLE', $e->getMessage()); + } + + // Test adding module when plural parent module_langname exists + // PHPBB3-14703 + // Adding success + try + { + $this->tool->add('acp', 'ACP_FORUM_BASED_PERMISSIONS', array( + 'module_basename' => 'acp_new_permissions_module', + 'module_langname' => 'ACP_NEW_PERMISSIONS_MODULE', + 'module_mode' => 'test', + 'module_auth' => '', + 'after' => 'ACP_FORUM_BASED_PERMISSIONS_CHILD_1', + )); + } + catch (Exception $e) + { + $this->fail($e); + } + $this->assertEquals(true, $this->tool->exists('acp', 'ACP_FORUM_BASED_PERMISSIONS', 'ACP_NEW_PERMISSIONS_MODULE')); } public function test_remove() |