diff options
86 files changed, 1136 insertions, 199 deletions
diff --git a/.travis.yml b/.travis.yml index 2542898324..14cf3e6d6c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -50,4 +50,3 @@ script: - sh -c "if [ '$SLOWTESTS' != '1' ]; then phpBB/vendor/bin/phpunit --configuration travis/phpunit-$DB-travis.xml; fi" - sh -c "if [ '$SLOWTESTS' = '1' ]; then phpBB/vendor/bin/phpunit --configuration travis/phpunit-$DB-travis.xml --group slow; fi" - sh -c "if [ '$TRAVIS_PHP_VERSION' = '5.3.3' -a '$DB' = 'mysqli' -a '$TRAVIS_PULL_REQUEST' != 'false' ]; then git-tools/commit-msg-hook-range.sh origin/$TRAVIS_BRANCH..FETCH_HEAD; fi" - diff --git a/phpBB/adm/style/acp_avatar_options_local.html b/phpBB/adm/style/acp_avatar_options_local.html index 8adafa1d99..bee3c57ea0 100644 --- a/phpBB/adm/style/acp_avatar_options_local.html +++ b/phpBB/adm/style/acp_avatar_options_local.html @@ -12,7 +12,7 @@ <!-- BEGIN avatar_local_col --> <li> <label for="av-{avatar_local_row.S_ROW_COUNT}-{avatar_local_row.avatar_local_col.S_ROW_COUNT}"><img src="{avatar_local_row.avatar_local_col.AVATAR_IMAGE}" alt="" /><br /> - <input type="radio" name="avatar_local_file" id="av-{avatar_local_row.S_ROW_COUNT}-{avatar_local_row.avatar_local_col.S_ROW_COUNT}" value="{avatar_local_row.avatar_local_col.AVATAR_FILE}" /></label> + <input type="radio" name="avatar_local_file" id="av-{avatar_local_row.S_ROW_COUNT}-{avatar_local_row.avatar_local_col.S_ROW_COUNT}" value="{avatar_local_row.avatar_local_col.AVATAR_FILE}"<!-- IF avatar_local_row.avatar_local_col.CHECKED -->checked="checked"<!-- ENDIF --> /></label> </li> <!-- END avatar_local_col --> <!-- END avatar_local_row --> diff --git a/phpBB/adm/style/acp_captcha.html b/phpBB/adm/style/acp_captcha.html index f4866653c3..0efbbac51e 100644 --- a/phpBB/adm/style/acp_captcha.html +++ b/phpBB/adm/style/acp_captcha.html @@ -8,6 +8,13 @@ <p>{L_ACP_VC_EXT_GET_MORE}</p> +<!-- IF ERROR_MSG --> +<div class="errorbox"> + <h3>{L_WARNING}</h3> + <p>{ERROR_MSG}</p> +</div> +<!-- ENDIF --> + <form id="acp_captcha" method="post" action="{U_ACTION}"> <fieldset> diff --git a/phpBB/adm/style/acp_ext_list.html b/phpBB/adm/style/acp_ext_list.html index fa261ed289..8feb12a423 100644 --- a/phpBB/adm/style/acp_ext_list.html +++ b/phpBB/adm/style/acp_ext_list.html @@ -47,7 +47,7 @@ <td class="row3" colspan="4"><strong>{L_EXTENSIONS_ENABLED}</strong></td> </tr> <!-- BEGIN enabled --> - <tr class="ext_enabled"> + <tr class="ext_enabled row-highlight"> <td><strong title="{enabled.NAME}">{enabled.META_DISPLAY_NAME}</strong></td> <td style="text-align: center;"> <!-- IF enabled.S_VERSIONCHECK --> @@ -72,7 +72,7 @@ <td class="row3" colspan="4"><strong>{L_EXTENSIONS_DISABLED}</strong></td> </tr> <!-- BEGIN disabled --> - <tr class="ext_disabled"> + <tr class="ext_disabled row-highlight"> <td><strong title="{disabled.NAME}">{disabled.META_DISPLAY_NAME}</strong></td> <td style="text-align: center;"> <!-- IF disabled.S_VERSIONCHECK --> diff --git a/phpBB/adm/style/acp_inactive.html b/phpBB/adm/style/acp_inactive.html index 409ea46de5..2aa3051f53 100644 --- a/phpBB/adm/style/acp_inactive.html +++ b/phpBB/adm/style/acp_inactive.html @@ -18,6 +18,7 @@ <thead> <tr> <th>{L_USERNAME}</th> + <th>{L_EMAIL}</th> <th>{L_JOINED}</th> <th>{L_INACTIVE_DATE}</th> <th>{L_LAST_VISIT}</th> @@ -32,6 +33,7 @@ {inactive.USERNAME_FULL} <!-- IF inactive.POSTS --><br />{L_POSTS}{L_COLON} <strong>{inactive.POSTS}</strong> [<a href="{inactive.U_SEARCH_USER}">{L_SEARCH_USER_POSTS}</a>]<!-- ENDIF --> </td> + <td style="vertical-align: top;">{inactive.USER_EMAIL}</td> <td style="vertical-align: top;">{inactive.JOINED}</td> <td style="vertical-align: top;">{inactive.INACTIVE_DATE}</td> <td style="vertical-align: top;">{inactive.LAST_VISIT}</td> diff --git a/phpBB/adm/style/acp_main.html b/phpBB/adm/style/acp_main.html index 065dd7ac4f..6e51e1fc70 100644 --- a/phpBB/adm/style/acp_main.html +++ b/phpBB/adm/style/acp_main.html @@ -141,19 +141,24 @@ <td>{L_GZIP_COMPRESSION}{L_COLON} </td> <td><strong>{GZIP_COMPRESSION}</strong></td> </tr> + <!-- IF S_TOTAL_ORPHAN or S_VERSIONCHECK --> <tr> + <!-- IF S_VERSIONCHECK --> <td>{L_BOARD_VERSION}{L_COLON} </td> <td> <strong><a href="{U_VERSIONCHECK}" <!-- IF S_VERSION_UP_TO_DATE -->style="color: #228822;"<!-- ELSE -->style="color: #BC2A4D;"<!-- ENDIF --> title="{L_MORE_INFORMATION}">{BOARD_VERSION}</a></strong> [ <a href="{U_VERSIONCHECK_FORCE}">{L_VERSIONCHECK_FORCE_UPDATE}</a> ] </td> + <!-- ENDIF --> <!-- IF S_TOTAL_ORPHAN --> <td>{L_NUMBER_ORPHAN}{L_COLON} </td> <td><strong>{TOTAL_ORPHAN}</strong></td> - <!-- ELSE --> + <!-- ENDIF --> + <!-- IF not S_TOTAL_ORPHAN or not S_VERSIONCHECK --> <td> </td> <td> </td> <!-- ENDIF --> </tr> + <!-- ENDIF --> </tbody> </table> diff --git a/phpBB/adm/style/acp_profile.html b/phpBB/adm/style/acp_profile.html index 3ce2d9471d..07718846cc 100644 --- a/phpBB/adm/style/acp_profile.html +++ b/phpBB/adm/style/acp_profile.html @@ -17,7 +17,7 @@ </div> <!-- ENDIF --> - <form id="add_profile_field" method="post" action="{U_ACTION}"> + <form id="add_profile_field" method="post" action="{U_ACTION}"{S_FORM_ENCTYPE}> <!-- IF S_STEP_ONE --> diff --git a/phpBB/adm/style/acp_styles.html b/phpBB/adm/style/acp_styles.html index 92ceaebc08..a36d15fe73 100644 --- a/phpBB/adm/style/acp_styles.html +++ b/phpBB/adm/style/acp_styles.html @@ -87,6 +87,7 @@ <!-- ENDIF --> <!-- IF .styles_list --> + <!-- EVENT acp_styles_list_before --> <table class="table1 styles"> <thead> <tr> @@ -99,7 +100,7 @@ </thead> <!-- BEGIN styles_list --> <tbody id="styles-list-{styles_list.S_ROW_COUNT}"> - <tr<!-- IF styles_list.STYLE_ID and not styles_list.STYLE_ACTIVE --> class="row-inactive"<!-- ENDIF -->> + <tr class="row-highlight<!-- IF styles_list.STYLE_ID and not styles_list.STYLE_ACTIVE --> row-inactive<!-- ENDIF -->"> <!-- IF styles_list.LEVEL is odd --> <!-- IF $ROW_CLASS == 'row1a' --><!-- DEFINE $ROW_CLASS = 'row1b' --><!-- ELSE --><!-- DEFINE $ROW_CLASS = 'row1a' --><!-- ENDIF --> <!-- ELSE --> diff --git a/phpBB/adm/style/acp_users_profile.html b/phpBB/adm/style/acp_users_profile.html index 573534fc95..9296638ff6 100644 --- a/phpBB/adm/style/acp_users_profile.html +++ b/phpBB/adm/style/acp_users_profile.html @@ -1,4 +1,4 @@ - <form id="user_profile" method="post" action="{U_ACTION}"> + <form id="user_profile" method="post" action="{U_ACTION}"{S_FORM_ENCTYPE}> <fieldset> <legend>{L_USER_PROFILE}</legend> diff --git a/phpBB/adm/style/admin.css b/phpBB/adm/style/admin.css index 396b21e3eb..0c00e5339e 100644 --- a/phpBB/adm/style/admin.css +++ b/phpBB/adm/style/admin.css @@ -859,6 +859,8 @@ table.zebra-table tbody tr:nth-child(even) { .row2a { background-color: #E7EEF4; } .row2b { background-color: #E3EBF2; } +tr.row-highlight:hover td { background-color: #DBDFE2; } + .spacer { background-color: #DBDFE2; height: 1px; diff --git a/phpBB/docs/INSTALL.html b/phpBB/docs/INSTALL.html index 132367dd0a..033bb1a80b 100644 --- a/phpBB/docs/INSTALL.html +++ b/phpBB/docs/INSTALL.html @@ -265,7 +265,7 @@ <p>If you are currently using a stable release of phpBB, updating to this version is straightforward. You would have downloaded one of four packages and your choice determines what you need to do. <strong>Note</strong>: Before updating, we heavily recommend you do a <em>full backup of your database and existing phpBB files</em>! If you are unsure how to achieve this please ask your hosting provider for advice.</p> -<p><strong>Please make sure you update your phpBB source files too, even if you run the <code>database_update.php</code> file.</strong></p> +<p><strong>Please make sure you update your phpBB source files too, even if you run the <code>database_update.php</code> file.</strong> If you have shell access to your server, you may wish to update via the command line interface. From your board's root, execute the following command: <code>php bin/phpbbcli.php --safe-mode db:migrate</code>.</p> <a name="update_full"></a><h3>4.i. Full package</h3> @@ -273,7 +273,7 @@ <p>First, you should make a copy of your existing <code>config.php</code> file; keep it in a safe place! Next, delete all the existing phpBB files, you may want to leave your <code>files/</code> and <code>images/</code> directories in place. You can leave alternative styles in place too. With this complete, you can upload the new phpBB files (see <a href="#install">New installation</a> for details if necessary). Once complete, copy back your saved <code>config.php</code>, replacing the new one. Another method is to just <strong>replace</strong> the existing files with the files from the full package - though make sure you do <strong>not</strong> overwrite your config.php file.</p> - <p>You should now run <code>install/database_update.php</code> which, depending on your previous version, will make a number of database changes. You may receive <em>FAILURES</em> during this procedure. They should not be a cause for concern unless you see an actual <em>ERROR</em>, in which case the script will stop (in this case you should seek help via our forums or bug tracker).</p> + <p>You should now run <code>install/database_update.php</code> which, depending on your previous version, will make a number of database changes. You may receive <em>FAILURES</em> during this procedure. They should not be a cause for concern unless you see an actual <em>ERROR</em>, in which case the script will stop (in this case you should seek help via our forums or bug tracker). If you have shell access to your server, you may wish to update via the command line interface. From your board's root, execute the following command: <code>php bin/phpbbcli.php --safe-mode db:migrate</code>.</p> <p>Once <code>install/database_update.php</code> has completed, you may proceed to the Administration Control Panel and then remove the install directory as advised.</p> @@ -285,7 +285,7 @@ <p>The directory structure has been preserved, enabling you (if you wish) to simply upload the uncompressed contents of the archive to the appropriate location on your server, i.e. simply overwrite the existing files with the new versions. Do not forget that if you have installed any modifications (MODs) these files will overwrite the originals, possibly destroying them in the process. You will need to re-add MODs to any affected file before uploading.</p> - <p>As for the other update procedures, you should run <code>install/database_update.php</code> after you have finished updating the files. This will update your database schema and increment the version number.</p> + <p>As for the other update procedures, you should run <code>install/database_update.php</code> after you have finished updating the files. This will update your database schema and increment the version number. If you have shell access to your server, you may wish to update via the command line interface. From your board's root, execute the following command: <code>php bin/phpbbcli.php --safe-mode db:migrate</code>.</p> <a name="update_patch"></a><h3>4.iii. Patch file</h3> @@ -297,13 +297,13 @@ <p>If you do get failures, you should look at using the <a href="#update_files">Changed Files</a> package to replace the files which failed to patch. Please note that you will need to manually re-add any MODs to these particular files. Alternatively, if you know how, you can examine the .rej files to determine what failed where and make manual adjustments to the relevant source.</p> - <p>You should, of course, delete the patch file (or files) after use. As for the other update procedures, you should run <code>install/database_update.php</code> after you have finished updating the files. This will update your database schema and data (if appropriate) and increment the version number.</p> + <p>You should, of course, delete the patch file (or files) after use. As for the other update procedures, you should run <code>install/database_update.php</code> after you have finished updating the files. This will update your database schema and data (if appropriate) and increment the version number. If you have shell access to your server, you may wish to update via the command line interface. From your board's root, execute the following command: <code>php bin/phpbbcli.php --safe-mode db:migrate</code>.</p> <a name="update_auto"></a><h3>4.iv. Automatic update package</h3> <p>This update method is the recommended method for updating. This package detects changed files automatically and merges in changes if needed.</p> - <p>The automatic update package will update the board from a given version to the latest version. A number of automatic update files are available, and you should choose the one that corresponds to the version of the board that you are currently running. For example, if your current version is <strong>3.0.13</strong>, you need the <code>phpBB-3.0.13_to_3.0.14.zip/tar.bz2</code> file.</p> + <p>The automatic update package will update the board from a given version to the latest version. A number of automatic update files are available, and you should choose the one that corresponds to the version of the board that you are currently running. For example, if your current version is <strong>3.1.5</strong>, you need the <code>phpBB-3.1.5_to_3.1.6.zip/tar.bz2</code> file.</p> <p>To perform the update, either follow the instructions from the <strong>Administration Control Panel->System</strong> Tab - this should point out that you are running an outdated version and will guide you through the update - or follow the instructions listed below.</p> diff --git a/phpBB/docs/events.md b/phpBB/docs/events.md index 00d3650e4d..385d3bf0e9 100644 --- a/phpBB/docs/events.md +++ b/phpBB/docs/events.md @@ -422,6 +422,13 @@ acp_ranks_list_header_before * Purpose: Add content after the last header-column (but before the action column) in the ranks list in the ACP +acp_styles_list_before +=== +* Locations: + + adm/style/acp_styles.html +* Since: 3.1.7-RC1 +* Purpose: Add content before list of styles + acp_users_profile_before === * Locations: @@ -1535,6 +1542,14 @@ quickreply_editor_message_before * Since: 3.1.0-a4 * Purpose: Add content before the quick reply textbox +quickreply_editor_subject_before +=== +* Locations: + + styles/prosilver/template/quickreply_editor.html + + styles/subsilver2/template/quickreply_editor.html +* Since: 3.1.7-RC1 +* Purpose: Add content before the quick reply subject textbox + search_body_form_before === * Locations: @@ -2014,6 +2029,38 @@ ucp_friend_list_after * Since: 3.1.0-a4 * Purpose: Add optional elements after list of friends in UCP +viewforum_body_topic_row_after +=== +* Locations: + + styles/prosilver/template/viewforum_body.html + + styles/subsilver2/template/viewforum_body.html +* Since: 3.1.7-RC1 +* Purpose: Add content after the topic list item. + +viewforum_body_topic_row_append +=== +* Locations: + + styles/prosilver/template/viewforum_body.html + + styles/subsilver2/template/viewforum_body.html +* Since: 3.1.7-RC1 +* Purpose: Add content at the start of the topic list item. + +viewforum_body_topic_row_before +=== +* Locations: + + styles/prosilver/template/viewforum_body.html + + styles/subsilver2/template/viewforum_body.html +* Since: 3.1.7-RC1 +* Purpose: Add content before the topic list item. + +viewforum_body_topic_row_prepend +=== +* Locations: + + styles/prosilver/template/viewforum_body.html + + styles/subsilver2/template/viewforum_body.html +* Since: 3.1.7-RC1 +* Purpose: Add content at the end of the topic list item. + viewforum_buttons_bottom_before === * Locations: diff --git a/phpBB/download/file.php b/phpBB/download/file.php index 3e7965899f..56ea273d5c 100644 --- a/phpBB/download/file.php +++ b/phpBB/download/file.php @@ -258,17 +258,18 @@ else * @var array attachment Array with attachment data * @var int display_cat Attachment category * @var int download_mode File extension specific download mode - * @var array extension Array with file extensions data + * @var array extensions Array with file extensions data * @var string mode Download mode * @var bool thumbnail Flag indicating if the file is a thumbnail * @since 3.1.6-RC1 + * @change 3.1.7-RC1 Fixing wrong name of a variable (replacing "extension" by "extensions") */ $vars = array( 'attach_id', 'attachment', 'display_cat', 'download_mode', - 'extension', + 'extensions', 'mode', 'thumbnail', ); diff --git a/phpBB/includes/acp/acp_attachments.php b/phpBB/includes/acp/acp_attachments.php index 67fba1094d..4956aab241 100644 --- a/phpBB/includes/acp/acp_attachments.php +++ b/phpBB/includes/acp/acp_attachments.php @@ -106,7 +106,10 @@ class acp_attachments { case 'attach': - include_once($phpbb_root_path . 'includes/functions_posting.' . $phpEx); + if (!function_exists('get_supported_image_types')) + { + include($phpbb_root_path . 'includes/functions_posting.' . $phpEx); + } $sql = 'SELECT group_name, cat_id FROM ' . EXTENSION_GROUPS_TABLE . ' diff --git a/phpBB/includes/acp/acp_ban.php b/phpBB/includes/acp/acp_ban.php index b555f46a94..286bc92813 100644 --- a/phpBB/includes/acp/acp_ban.php +++ b/phpBB/includes/acp/acp_ban.php @@ -28,7 +28,10 @@ class acp_ban global $user, $template, $request, $phpbb_dispatcher; global $phpbb_root_path, $phpEx; - include($phpbb_root_path . 'includes/functions_user.' . $phpEx); + if (!function_exists('user_ban')) + { + include($phpbb_root_path . 'includes/functions_user.' . $phpEx); + } $bansubmit = $request->is_set_post('bansubmit'); $unbansubmit = $request->is_set_post('unbansubmit'); diff --git a/phpBB/includes/acp/acp_bots.php b/phpBB/includes/acp/acp_bots.php index 1ea320e674..2188b90729 100644 --- a/phpBB/includes/acp/acp_bots.php +++ b/phpBB/includes/acp/acp_bots.php @@ -141,7 +141,11 @@ class acp_bots case 'edit': case 'add': - include_once($phpbb_root_path . 'includes/functions_user.' . $phpEx); + + if (!function_exists('user_update_name')) + { + include($phpbb_root_path . 'includes/functions_user.' . $phpEx); + } $bot_row = array( 'bot_name' => utf8_normalize_nfc(request_var('bot_name', '', true)), diff --git a/phpBB/includes/acp/acp_captcha.php b/phpBB/includes/acp/acp_captcha.php index fa8d8fb6a9..92d5e1dda6 100644 --- a/phpBB/includes/acp/acp_captcha.php +++ b/phpBB/includes/acp/acp_captcha.php @@ -25,7 +25,7 @@ class acp_captcha function main($id, $mode) { - global $db, $user, $auth, $template; + global $request, $user, $auth, $template; global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx, $phpbb_container; $user->add_lang('acp/board'); @@ -52,11 +52,36 @@ class acp_captcha else { $config_vars = array( - 'enable_confirm' => array('tpl' => 'REG_ENABLE', 'default' => false), - 'enable_post_confirm' => array('tpl' => 'POST_ENABLE', 'default' => false), - 'confirm_refresh' => array('tpl' => 'CONFIRM_REFRESH', 'default' => false), - 'max_reg_attempts' => array('tpl' => 'REG_LIMIT', 'default' => 0), - 'max_login_attempts' => array('tpl' => 'MAX_LOGIN_ATTEMPTS', 'default' => 0), + 'enable_confirm' => array( + 'tpl' => 'REG_ENABLE', + 'default' => false, + 'validate' => 'bool', + 'lang' => 'VISUAL_CONFIRM_REG', + ), + 'enable_post_confirm' => array( + 'tpl' => 'POST_ENABLE', + 'default' => false, + 'validate' => 'bool', + 'lang' => 'VISUAL_CONFIRM_POST', + ), + 'confirm_refresh' => array( + 'tpl' => 'CONFIRM_REFRESH', + 'default' => false, + 'validate' => 'bool', + 'lang' => 'VISUAL_CONFIRM_REFRESH', + ), + 'max_reg_attempts' => array( + 'tpl' => 'REG_LIMIT', + 'default' => 0, + 'validate' => 'int:0:99999', + 'lang' => 'REG_LIMIT', + ), + 'max_login_attempts' => array( + 'tpl' => 'MAX_LOGIN_ATTEMPTS', + 'default' => 0, + 'validate' => 'int:0:99999', + 'lang' => 'MAX_LOGIN_ATTEMPTS', + ), ); $this->tpl_name = 'acp_captcha'; @@ -65,12 +90,31 @@ class acp_captcha add_form_key($form_key); $submit = request_var('main_submit', false); + $error = $cfg_array = array(); - if ($submit && check_form_key($form_key)) + if ($submit) { foreach ($config_vars as $config_var => $options) { - set_config($config_var, request_var($config_var, $options['default'])); + $cfg_array[$config_var] = $request->variable($config_var, $options['default']); + } + validate_config_vars($config_vars, $cfg_array, $error); + + if (!check_form_key($form_key)) + { + $error[] = $user->lang['FORM_INVALID']; + } + if ($error) + { + $submit = false; + } + } + + if ($submit) + { + foreach ($cfg_array as $key => $value) + { + $config->set($key, $value); } if ($selected !== $config['captcha_plugin']) @@ -94,10 +138,6 @@ class acp_captcha } trigger_error($user->lang['CONFIG_UPDATED'] . adm_back_link($this->u_action)); } - else if ($submit) - { - trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING); - } else { $captcha_select = ''; @@ -124,6 +164,7 @@ class acp_captcha 'CAPTCHA_PREVIEW_TPL' => $demo_captcha->get_demo_template($id), 'S_CAPTCHA_HAS_CONFIG' => $demo_captcha->has_config(), 'CAPTCHA_SELECT' => $captcha_select, + 'ERROR_MSG' => implode('<br />', $error), 'U_ACTION' => $this->u_action, )); diff --git a/phpBB/includes/acp/acp_disallow.php b/phpBB/includes/acp/acp_disallow.php index 4c8f3cc65b..5b12013708 100644 --- a/phpBB/includes/acp/acp_disallow.php +++ b/phpBB/includes/acp/acp_disallow.php @@ -26,9 +26,7 @@ class acp_disallow function main($id, $mode) { global $db, $user, $auth, $template, $cache; - global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx; - - include($phpbb_root_path . 'includes/functions_user.' . $phpEx); + global $config, $phpbb_admin_path; $user->add_lang('acp/posting'); diff --git a/phpBB/includes/acp/acp_email.php b/phpBB/includes/acp/acp_email.php index fda9d50779..917d02318e 100644 --- a/phpBB/includes/acp/acp_email.php +++ b/phpBB/includes/acp/acp_email.php @@ -189,8 +189,15 @@ class acp_email $db->sql_freeresult($result); // Send the messages - include_once($phpbb_root_path . 'includes/functions_messenger.' . $phpEx); - include_once($phpbb_root_path . 'includes/functions_user.' . $phpEx); + if (!class_exists('messenger')) + { + include($phpbb_root_path . 'includes/functions_messenger.' . $phpEx); + } + + if (!function_exists('get_group_name')) + { + include($phpbb_root_path . 'includes/functions_user.' . $phpEx); + } $messenger = new messenger($use_queue); $errored = false; diff --git a/phpBB/includes/acp/acp_groups.php b/phpBB/includes/acp/acp_groups.php index edfada1bf1..befbcdf24a 100644 --- a/phpBB/includes/acp/acp_groups.php +++ b/phpBB/includes/acp/acp_groups.php @@ -42,7 +42,10 @@ class acp_groups return; } - include($phpbb_root_path . 'includes/functions_user.' . $phpEx); + if (!function_exists('group_user_attributes')) + { + include($phpbb_root_path . 'includes/functions_user.' . $phpEx); + } // Check and set some common vars $action = (isset($_POST['add'])) ? 'add' : ((isset($_POST['addusers'])) ? 'addusers' : request_var('action', '')); @@ -295,7 +298,10 @@ class acp_groups case 'edit': case 'add': - include($phpbb_root_path . 'includes/functions_display.' . $phpEx); + if (!function_exists('display_forums')) + { + include($phpbb_root_path . 'includes/functions_display.' . $phpEx); + } $data = $submit_ary = array(); diff --git a/phpBB/includes/acp/acp_inactive.php b/phpBB/includes/acp/acp_inactive.php index e96c42de05..76c7a1b277 100644 --- a/phpBB/includes/acp/acp_inactive.php +++ b/phpBB/includes/acp/acp_inactive.php @@ -34,7 +34,10 @@ class acp_inactive global $config, $db, $user, $auth, $template, $phpbb_container; global $phpbb_root_path, $phpbb_admin_path, $phpEx, $table_prefix; - include($phpbb_root_path . 'includes/functions_user.' . $phpEx); + if (!function_exists('user_active_flip')) + { + include($phpbb_root_path . 'includes/functions_user.' . $phpEx); + } $user->add_lang('memberlist'); @@ -109,7 +112,10 @@ class acp_inactive if ($config['require_activation'] == USER_ACTIVATION_ADMIN && !empty($inactive_users)) { - include_once($phpbb_root_path . 'includes/functions_messenger.' . $phpEx); + if (!class_exists('messenger')) + { + include($phpbb_root_path . 'includes/functions_messenger.' . $phpEx); + } $messenger = new messenger(false); @@ -196,7 +202,10 @@ class acp_inactive if ($row = $db->sql_fetchrow($result)) { // Send the messages - include_once($phpbb_root_path . 'includes/functions_messenger.' . $phpEx); + if (!class_exists('messenger')) + { + include($phpbb_root_path . 'includes/functions_messenger.' . $phpEx); + } $messenger = new messenger(); $usernames = $user_ids = array(); @@ -271,9 +280,10 @@ class acp_inactive 'REMINDED_EXPLAIN' => $user->lang('USER_LAST_REMINDED', (int) $row['user_reminded'], $user->format_date($row['user_reminded_time'])), - 'USERNAME_FULL' => get_username_string('full', $row['user_id'], $row['username'], $row['user_colour'], false, append_sid("{$phpbb_admin_path}index.$phpEx", 'i=users&mode=overview')), + 'USERNAME_FULL' => get_username_string('full', $row['user_id'], $row['username'], $row['user_colour'], false, append_sid("{$phpbb_admin_path}index.$phpEx", 'i=users&mode=overview&redirect=acp_inactive')), 'USERNAME' => get_username_string('username', $row['user_id'], $row['username'], $row['user_colour']), 'USER_COLOR' => get_username_string('colour', $row['user_id'], $row['username'], $row['user_colour']), + 'USER_EMAIL' => $row['user_email'], 'U_USER_ADMIN' => append_sid("{$phpbb_admin_path}index.$phpEx", "i=users&mode=overview&u={$row['user_id']}"), 'U_SEARCH_USER' => ($auth->acl_get('u_search')) ? append_sid("{$phpbb_root_path}search.$phpEx", "author_id={$row['user_id']}&sr=posts") : '', diff --git a/phpBB/includes/acp/acp_jabber.php b/phpBB/includes/acp/acp_jabber.php index 284543acd3..a482b41e1d 100644 --- a/phpBB/includes/acp/acp_jabber.php +++ b/phpBB/includes/acp/acp_jabber.php @@ -34,7 +34,10 @@ class acp_jabber $user->add_lang('acp/board'); - include_once($phpbb_root_path . 'includes/functions_jabber.' . $phpEx); + if (!class_exists('jabber')) + { + include($phpbb_root_path . 'includes/functions_jabber.' . $phpEx); + } $action = request_var('action', ''); $submit = (isset($_POST['submit'])) ? true : false; diff --git a/phpBB/includes/acp/acp_language.php b/phpBB/includes/acp/acp_language.php index 60e338ae7c..3888a411f0 100644 --- a/phpBB/includes/acp/acp_language.php +++ b/phpBB/includes/acp/acp_language.php @@ -34,7 +34,10 @@ class acp_language global $config, $db, $user, $template; global $phpbb_root_path, $phpEx, $request; - include_once($phpbb_root_path . 'includes/functions_user.' . $phpEx); + if (!function_exists('validate_language_iso_name')) + { + include($phpbb_root_path . 'includes/functions_user.' . $phpEx); + } // Check and set some common vars $action = (isset($_POST['update_details'])) ? 'update_details' : ''; diff --git a/phpBB/includes/acp/acp_main.php b/phpBB/includes/acp/acp_main.php index f6d728ffed..afa0f1ea61 100644 --- a/phpBB/includes/acp/acp_main.php +++ b/phpBB/includes/acp/acp_main.php @@ -429,20 +429,28 @@ class acp_main )); } - $version_helper = $phpbb_container->get('version_helper'); - try + if ($auth->acl_get('a_board')) { - $recheck = $request->variable('versioncheck_force', false); - $updates_available = $version_helper->get_suggested_updates($recheck); + $version_helper = $phpbb_container->get('version_helper'); + try + { + $recheck = $request->variable('versioncheck_force', false); + $updates_available = $version_helper->get_suggested_updates($recheck); - $template->assign_var('S_VERSION_UP_TO_DATE', empty($updates_available)); + $template->assign_var('S_VERSION_UP_TO_DATE', empty($updates_available)); + } + catch (\RuntimeException $e) + { + $template->assign_vars(array( + 'S_VERSIONCHECK_FAIL' => true, + 'VERSIONCHECK_FAIL_REASON' => ($e->getMessage() !== $user->lang('VERSIONCHECK_FAIL')) ? $e->getMessage() : '', + )); + } } - catch (\RuntimeException $e) + else { - $template->assign_vars(array( - 'S_VERSIONCHECK_FAIL' => true, - 'VERSIONCHECK_FAIL_REASON' => ($e->getMessage() !== $user->lang('VERSIONCHECK_FAIL')) ? $e->getMessage() : '', - )); + // We set this template var to true, to not display an outdated version notice. + $template->assign_var('S_VERSION_UP_TO_DATE', true); } /** @@ -553,6 +561,7 @@ class acp_main 'U_VERSIONCHECK' => append_sid("{$phpbb_admin_path}index.$phpEx", 'i=update&mode=version_check'), 'U_VERSIONCHECK_FORCE' => append_sid("{$phpbb_admin_path}index.$phpEx", 'versioncheck_force=1'), + 'S_VERSIONCHECK' => ($auth->acl_get('a_board')) ? true : false, 'S_ACTION_OPTIONS' => ($auth->acl_get('a_board')) ? true : false, 'S_FOUNDER' => ($user->data['user_type'] == USER_FOUNDER) ? true : false, ) diff --git a/phpBB/includes/acp/acp_permission_roles.php b/phpBB/includes/acp/acp_permission_roles.php index cd3616208d..be4ab4676a 100644 --- a/phpBB/includes/acp/acp_permission_roles.php +++ b/phpBB/includes/acp/acp_permission_roles.php @@ -30,8 +30,15 @@ class acp_permission_roles global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx; global $request; - include_once($phpbb_root_path . 'includes/functions_user.' . $phpEx); - include_once($phpbb_root_path . 'includes/acp/auth.' . $phpEx); + if (!function_exists('user_get_id_name')) + { + include($phpbb_root_path . 'includes/functions_user.' . $phpEx); + } + + if (!class_exists('auth_admin')) + { + include($phpbb_root_path . 'includes/acp/auth.' . $phpEx); + } $this->auth_admin = new auth_admin(); diff --git a/phpBB/includes/acp/acp_permissions.php b/phpBB/includes/acp/acp_permissions.php index cb408e304f..660afb4e93 100644 --- a/phpBB/includes/acp/acp_permissions.php +++ b/phpBB/includes/acp/acp_permissions.php @@ -30,8 +30,15 @@ class acp_permissions global $db, $user, $auth, $template, $cache, $phpbb_container; global $config, $phpbb_root_path, $phpbb_admin_path, $phpEx; - include_once($phpbb_root_path . 'includes/functions_user.' . $phpEx); - include_once($phpbb_root_path . 'includes/acp/auth.' . $phpEx); + if (!function_exists('user_get_id_name')) + { + include($phpbb_root_path . 'includes/functions_user.' . $phpEx); + } + + if (!class_exists('auth_admin')) + { + include($phpbb_root_path . 'includes/acp/auth.' . $phpEx); + } $this->permissions = $phpbb_container->get('acl.permissions'); diff --git a/phpBB/includes/acp/acp_profile.php b/phpBB/includes/acp/acp_profile.php index 43668b8ad5..8c7691538c 100644 --- a/phpBB/includes/acp/acp_profile.php +++ b/phpBB/includes/acp/acp_profile.php @@ -33,8 +33,15 @@ class acp_profile global $phpbb_root_path, $phpbb_admin_path, $phpEx, $table_prefix; global $request, $phpbb_container, $phpbb_dispatcher; - include($phpbb_root_path . 'includes/functions_posting.' . $phpEx); - include($phpbb_root_path . 'includes/functions_user.' . $phpEx); + if (!function_exists('generate_smilies')) + { + include($phpbb_root_path . 'includes/functions_posting.' . $phpEx); + } + + if (!function_exists('user_get_id_name')) + { + include($phpbb_root_path . 'includes/functions_user.' . $phpEx); + } $user->add_lang(array('ucp', 'acp/profile')); $this->tpl_name = 'acp_profile'; @@ -537,13 +544,14 @@ class acp_profile } } - $step = (isset($_REQUEST['next'])) ? $step + 1 : ((isset($_REQUEST['prev'])) ? $step - 1 : $step); - if (sizeof($error)) { - $step--; $submit = false; } + else + { + $step = (isset($_REQUEST['next'])) ? $step + 1 : ((isset($_REQUEST['prev'])) ? $step - 1 : $step); + } // Build up the specific hidden fields foreach ($exclude as $num => $key_ary) @@ -561,7 +569,7 @@ class acp_profile $var = $profile_field->prepare_hidden_fields($step, $key, $action, $field_data); if ($var !== null) { - $_new_key_ary[$key] = $profile_field->prepare_hidden_fields($step, $key, $action, $field_data); + $_new_key_ary[$key] = $var; } } $cp->vars = $field_data; @@ -571,11 +579,7 @@ class acp_profile if (!sizeof($error)) { - if ($step == 3 && (sizeof($this->lang_defs['iso']) == 1 || $save)) - { - $this->save_profile_field($cp, $field_type, $action); - } - else if ($action == 'edit' && $save) + if (($step == 3 && (sizeof($this->lang_defs['iso']) == 1 || $save)) || ($action == 'edit' && $save)) { $this->save_profile_field($cp, $field_type, $action); } diff --git a/phpBB/includes/acp/acp_prune.php b/phpBB/includes/acp/acp_prune.php index e17399e3d9..98d9caabdd 100644 --- a/phpBB/includes/acp/acp_prune.php +++ b/phpBB/includes/acp/acp_prune.php @@ -28,7 +28,11 @@ class acp_prune global $user, $phpEx, $phpbb_admin_path, $phpbb_root_path; $user->add_lang('acp/prune'); - include_once($phpbb_root_path . 'includes/functions_user.' . $phpEx); + + if (!function_exists('user_active_flip')) + { + include($phpbb_root_path . 'includes/functions_user.' . $phpEx); + } switch ($mode) { diff --git a/phpBB/includes/acp/acp_send_statistics.php b/phpBB/includes/acp/acp_send_statistics.php index d178be2fb0..7c9e9cf78e 100644 --- a/phpBB/includes/acp/acp_send_statistics.php +++ b/phpBB/includes/acp/acp_send_statistics.php @@ -27,7 +27,10 @@ class acp_send_statistics { global $config, $template, $phpbb_admin_path, $phpbb_root_path, $phpEx; - include($phpbb_root_path . 'includes/questionnaire/questionnaire.' . $phpEx); + if (!class_exists('phpbb_questionnaire_data_collector')) + { + include($phpbb_root_path . 'includes/questionnaire/questionnaire.' . $phpEx); + } $collect_url = "https://www.phpbb.com/stats/receive_stats.php"; diff --git a/phpBB/includes/acp/acp_styles.php b/phpBB/includes/acp/acp_styles.php index a36a6c1ecd..5181b87ecb 100644 --- a/phpBB/includes/acp/acp_styles.php +++ b/phpBB/includes/acp/acp_styles.php @@ -56,9 +56,12 @@ class acp_styles /** @var string */ protected $php_ext; + /** @var \phpbb\event\dispatcher_interface */ + protected $dispatcher; + public function main($id, $mode) { - global $db, $user, $phpbb_admin_path, $phpbb_root_path, $phpEx, $template, $request, $cache, $auth, $config; + global $db, $user, $phpbb_admin_path, $phpbb_root_path, $phpEx, $template, $request, $cache, $auth, $config, $phpbb_dispatcher; $this->db = $db; $this->user = $user; @@ -69,6 +72,7 @@ class acp_styles $this->config = $config; $this->phpbb_root_path = $phpbb_root_path; $this->php_ext = $phpEx; + $this->dispatcher = $phpbb_dispatcher; $this->default_style = $config['default_style']; $this->styles_path = $this->phpbb_root_path . $this->styles_path_absolute . '/'; @@ -118,6 +122,18 @@ class acp_styles ) ); + /** + * Run code before ACP styles action execution + * + * @event core.acp_styles_action_before + * @var int id Module ID + * @var string mode Active module + * @var string action Module that should be run + * @since 3.1.7-RC1 + */ + $vars = array('id', 'mode', 'action'); + extract($this->dispatcher->trigger_event('core.acp_styles_action_before', compact($vars))); + // Execute actions switch ($action) { diff --git a/phpBB/includes/acp/acp_users.php b/phpBB/includes/acp/acp_users.php index 8c17fb6311..4d0bbf5721 100644 --- a/phpBB/includes/acp/acp_users.php +++ b/phpBB/includes/acp/acp_users.php @@ -44,6 +44,11 @@ class acp_users $user_id = request_var('u', 0); $action = request_var('action', ''); + // Get referer to redirect user to the appropriate page after delete action + $redirect = request_var('redirect', ''); + $redirect_tag = "redirect=$redirect"; + $redirect_url = append_sid("{$phpbb_admin_path}index.$phpEx", "i=$redirect"); + $submit = (isset($_POST['update']) && !isset($_POST['cancel'])) ? true : false; $form_name = 'acp_users'; @@ -52,7 +57,10 @@ class acp_users // Whois (special case) if ($action == 'whois') { - include($phpbb_root_path . 'includes/functions_user.' . $phpEx); + if (!function_exists('user_get_id_name')) + { + include($phpbb_root_path . 'includes/functions_user.' . $phpEx); + } $this->page_title = 'WHOIS'; $this->tpl_name = 'simple_body'; @@ -146,9 +154,9 @@ class acp_users } $template->assign_vars(array( - 'U_BACK' => $this->u_action, + 'U_BACK' => (empty($redirect)) ? $this->u_action : $redirect_url, 'U_MODE_SELECT' => append_sid("{$phpbb_admin_path}index.$phpEx", "i=$id&u=$user_id"), - 'U_ACTION' => $this->u_action . '&u=' . $user_id, + 'U_ACTION' => $this->u_action . '&u=' . $user_id . ((empty($redirect)) ? '' : '&' . $redirect_tag), 'S_FORM_OPTIONS' => $s_form_options, 'MANAGED_USERNAME' => $user_row['username']) ); @@ -165,7 +173,10 @@ class acp_users { case 'overview': - include($phpbb_root_path . 'includes/functions_user.' . $phpEx); + if (!function_exists('user_get_id_name')) + { + include($phpbb_root_path . 'includes/functions_user.' . $phpEx); + } $user->add_lang('acp/ban'); @@ -221,19 +232,30 @@ class acp_users user_delete($delete_type, $user_id, $user_row['username']); add_log('admin', 'LOG_USER_DELETED', $user_row['username']); - trigger_error($user->lang['USER_DELETED'] . adm_back_link($this->u_action)); + trigger_error($user->lang['USER_DELETED'] . adm_back_link( + (empty($redirect)) ? $this->u_action : $redirect_url + ) + ); } else { - confirm_box(false, $user->lang['CONFIRM_OPERATION'], build_hidden_fields(array( + $delete_confirm_hidden_fields = array( 'u' => $user_id, 'i' => $id, 'mode' => $mode, 'action' => $action, 'update' => true, 'delete' => 1, - 'delete_type' => $delete_type)) + 'delete_type' => $delete_type, ); + + // Checks if the redirection page is specified + if (!empty($redirect)) + { + $delete_confirm_hidden_fields['redirect'] = $redirect; + } + + confirm_box(false, $user->lang['CONFIRM_OPERATION'], build_hidden_fields($delete_confirm_hidden_fields)); } } else @@ -338,7 +360,10 @@ class acp_users if ($config['email_enable']) { - include_once($phpbb_root_path . 'includes/functions_messenger.' . $phpEx); + if (!class_exists('messenger')) + { + include($phpbb_root_path . 'includes/functions_messenger.' . $phpEx); + } $server_url = generate_board_url(); @@ -421,7 +446,10 @@ class acp_users $phpbb_notifications = $phpbb_container->get('notification_manager'); $phpbb_notifications->delete_notifications('notification.type.admin_activate_user', $user_row['user_id']); - include_once($phpbb_root_path . 'includes/functions_messenger.' . $phpEx); + if (!class_exists('messenger')) + { + include($phpbb_root_path . 'includes/functions_messenger.' . $phpEx); + } $messenger = new messenger(false); @@ -1345,7 +1373,10 @@ class acp_users case 'profile': - include($phpbb_root_path . 'includes/functions_user.' . $phpEx); + if (!function_exists('user_get_id_name')) + { + include($phpbb_root_path . 'includes/functions_user.' . $phpEx); + } $cp = $phpbb_container->get('profilefields.manager'); @@ -1504,7 +1535,10 @@ class acp_users case 'prefs': - include($phpbb_root_path . 'includes/functions_user.' . $phpEx); + if (!function_exists('user_get_id_name')) + { + include($phpbb_root_path . 'includes/functions_user.' . $phpEx); + } $data = array( 'dateformat' => utf8_normalize_nfc(request_var('dateformat', $user_row['user_dateformat'], true)), @@ -1774,8 +1808,6 @@ class acp_users case 'avatar': - include($phpbb_root_path . 'includes/functions_display.' . $phpEx); - $avatars_enabled = false; if ($config['allow_avatar']) @@ -1930,8 +1962,15 @@ class acp_users case 'sig': - include_once($phpbb_root_path . 'includes/functions_posting.' . $phpEx); - include_once($phpbb_root_path . 'includes/functions_display.' . $phpEx); + if (!function_exists('generate_smilies')) + { + include($phpbb_root_path . 'includes/functions_posting.' . $phpEx); + } + + if (!function_exists('display_custom_bbcodes')) + { + include($phpbb_root_path . 'includes/functions_display.' . $phpEx); + } $enable_bbcode = ($config['allow_sig_bbcode']) ? (bool) $this->optionget($user_row, 'sig_bbcode') : false; $enable_smilies = ($config['allow_sig_smilies']) ? (bool) $this->optionget($user_row, 'sig_smilies') : false; @@ -1942,7 +1981,10 @@ class acp_users if ($submit || $preview) { - include_once($phpbb_root_path . 'includes/message_parser.' . $phpEx); + if (!class_exists('messenger')) + { + include($phpbb_root_path . 'includes/message_parser.' . $phpEx); + } $enable_bbcode = ($config['allow_sig_bbcode']) ? ((request_var('disable_bbcode', false)) ? false : true) : false; $enable_smilies = ($config['allow_sig_smilies']) ? ((request_var('disable_smilies', false)) ? false : true) : false; @@ -2183,7 +2225,10 @@ class acp_users case 'groups': - include($phpbb_root_path . 'includes/functions_user.' . $phpEx); + if (!function_exists('group_user_attributes')) + { + include($phpbb_root_path . 'includes/functions_user.' . $phpEx); + } $user->add_lang(array('groups', 'acp/groups')); $group_id = request_var('g', 0); @@ -2399,7 +2444,10 @@ class acp_users case 'perm': - include_once($phpbb_root_path . 'includes/acp/auth.' . $phpEx); + if (!class_exists('auth_admin')) + { + include($phpbb_root_path . 'includes/acp/auth.' . $phpEx); + } $auth_admin = new auth_admin(); diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index 80d6e22bb7..2d94bd14a7 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -4264,10 +4264,14 @@ function obtain_users_online_string($online_users, $item_id = 0, $item = 'forum' if (sizeof($online_users['online_users'])) { - $sql = 'SELECT username, username_clean, user_id, user_type, user_allow_viewonline, user_colour - FROM ' . USERS_TABLE . ' - WHERE ' . $db->sql_in_set('user_id', $online_users['online_users']) . ' - ORDER BY username_clean ASC'; + $sql_ary = array( + 'SELECT' => 'u.username, u.username_clean, u.user_id, u.user_type, u.user_allow_viewonline, u.user_colour', + 'FROM' => array( + USERS_TABLE => 'u', + ), + 'WHERE' => $db->sql_in_set('u.user_id', $online_users['online_users']), + 'ORDER_BY' => 'u.username_clean ASC', + ); /** * Modify SQL query to obtain online users data @@ -4279,13 +4283,14 @@ function obtain_users_online_string($online_users, $item_id = 0, $item = 'forum' * @var string item Restrict online users to a certain * session item, e.g. forum for * session_forum_id - * @var string sql SQL query to obtain users online data + * @var string sql_ary SQL query to obtain users online data * @since 3.1.4-RC1 + * @changed 3.1.7-RC1 Change sql query into array and adjust var accordingly. Allows extension authors the ability to adjust the sql_ary. */ - $vars = array('online_users', 'item_id', 'item', 'sql'); + $vars = array('online_users', 'item_id', 'item', 'sql_ary'); extract($phpbb_dispatcher->trigger_event('core.obtain_users_online_string_sql', compact($vars))); - $result = $db->sql_query($sql); + $result = $db->sql_query($db->sql_build_query('SELECT', $sql_ary)); $rowset = $db->sql_fetchrowset($result); $db->sql_freeresult($result); @@ -4299,7 +4304,7 @@ function obtain_users_online_string($online_users, $item_id = 0, $item = 'forum' $row['username'] = '<em>' . $row['username'] . '</em>'; } - if (!isset($online_users['hidden_users'][$row['user_id']]) || $auth->acl_get('u_viewonline')) + if (!isset($online_users['hidden_users'][$row['user_id']]) || $auth->acl_get('u_viewonline') || $row['user_id'] === $user->data['user_id']) { $user_online_link[$row['user_id']] = get_username_string(($row['user_type'] <> USER_IGNORE) ? 'full' : 'no_profile', $row['user_id'], $row['username'], $row['user_colour']); } diff --git a/phpBB/includes/functions_admin.php b/phpBB/includes/functions_admin.php index afd3dce730..33cf55cc0b 100644 --- a/phpBB/includes/functions_admin.php +++ b/phpBB/includes/functions_admin.php @@ -576,7 +576,7 @@ function move_topics($topic_ids, $forum_id, $auto_sync = true) */ function move_posts($post_ids, $topic_id, $auto_sync = true) { - global $db; + global $db, $phpbb_dispatcher; if (!is_array($post_ids)) { @@ -610,6 +610,28 @@ function move_posts($post_ids, $topic_id, $auto_sync = true) trigger_error('NO_TOPIC'); } + /** + * Perform additional actions before moving posts + * + * @event core.move_posts_before + * @var array post_ids Array of post ids to move + * @var string topic_id The topic id the posts are moved to + * @var bool auto_sync Whether or not to perform auto sync + * @var array forum_ids Array of the forum ids the posts are moved from + * @var array topic_ids Array of the topic ids the posts are moved from + * @var array forum_row Array with the forum id of the topic the posts are moved to + * @since 3.1.7-RC1 + */ + $vars = array( + 'post_ids', + 'topic_id', + 'auto_sync', + 'forum_ids', + 'topic_ids', + 'forum_row', + ); + extract($phpbb_dispatcher->trigger_event('core.move_posts_before', compact($vars))); + $sql = 'UPDATE ' . POSTS_TABLE . ' SET forum_id = ' . (int) $forum_row['forum_id'] . ", topic_id = $topic_id WHERE " . $db->sql_in_set('post_id', $post_ids); @@ -620,6 +642,28 @@ function move_posts($post_ids, $topic_id, $auto_sync = true) WHERE " . $db->sql_in_set('post_msg_id', $post_ids); $db->sql_query($sql); + /** + * Perform additional actions after moving posts + * + * @event core.move_posts_after + * @var array post_ids Array of the moved post ids + * @var string topic_id The topic id the posts are moved to + * @var bool auto_sync Whether or not to perform auto sync + * @var array forum_ids Array of the forum ids the posts are moved from + * @var array topic_ids Array of the topic ids the posts are moved from + * @var array forum_row Array with the forum id of the topic the posts are moved to + * @since 3.1.7-RC1 + */ + $vars = array( + 'post_ids', + 'topic_id', + 'auto_sync', + 'forum_ids', + 'topic_ids', + 'forum_row', + ); + extract($phpbb_dispatcher->trigger_event('core.move_posts_after', compact($vars))); + if ($auto_sync) { $forum_ids[] = (int) $forum_row['forum_id']; @@ -785,6 +829,7 @@ function delete_posts($where_type, $where_ids, $auto_sync = true, $posted_sync = 'notification.type.quote', 'notification.type.approve_post', 'notification.type.post_in_queue', + 'notification.type.report_post', ); /** @@ -886,6 +931,32 @@ function delete_posts($where_type, $where_ids, $auto_sync = true, $posted_sync = $table_ary = array(POSTS_TABLE, REPORTS_TABLE); + /** + * Perform additional actions during post(s) deletion before running the queries + * + * @event core.delete_posts_in_transaction_before + * @var array post_ids Array with deleted posts' ids + * @var array poster_ids Array with deleted posts' author ids + * @var array topic_ids Array with deleted posts' topic ids + * @var array forum_ids Array with deleted posts' forum ids + * @var string where_type Variable containing posts deletion mode + * @var mixed where_ids Array or comma separated list of post ids to delete + * @var array delete_notifications_types Array with notifications types to delete + * @var array table_ary Array with table names to delete data from + * @since 3.1.7-RC1 + */ + $vars = array( + 'post_ids', + 'poster_ids', + 'topic_ids', + 'forum_ids', + 'where_type', + 'where_ids', + 'delete_notifications_types', + 'table_ary', + ); + extract($phpbb_dispatcher->trigger_event('core.delete_posts_in_transaction_before', compact($vars))); + foreach ($table_ary as $table) { $sql = "DELETE FROM $table @@ -1042,7 +1113,7 @@ function delete_posts($where_type, $where_ids, $auto_sync = true, $posted_sync = */ function delete_attachments($mode, $ids, $resync = true) { - global $db, $config; + global $db, $config, $phpbb_dispatcher; // 0 is as bad as an empty array if (empty($ids)) @@ -1087,6 +1158,24 @@ function delete_attachments($mode, $ids, $resync = true) $post_ids = $message_ids = $topic_ids = $physical = array(); + /** + * Perform additional actions before collecting data for attachment(s) deletion + * + * @event core.delete_attachments_collect_data_before + * @var string mode Variable containing attachments deletion mode, can be: post|message|topic|attach|user + * @var mixed ids Array or comma separated list of ids corresponding to the mode + * @var bool resync Flag indicating if posts/messages/topics should be synchronized + * @var string sql_id The field name to collect/delete data for depending on the mode + * @since 3.1.7-RC1 + */ + $vars = array( + 'mode', + 'ids', + 'resync', + 'sql_id', + ); + extract($phpbb_dispatcher->trigger_event('core.delete_attachments_collect_data_before', compact($vars))); + // Collect post and topic ids for later use if we need to touch remaining entries (if resync is enabled) $sql = 'SELECT post_msg_id, topic_id, in_message, physical_filename, thumbnail, filesize, is_orphan FROM ' . ATTACHMENTS_TABLE . ' @@ -1116,6 +1205,32 @@ function delete_attachments($mode, $ids, $resync = true) } $db->sql_freeresult($result); + /** + * Perform additional actions before attachment(s) deletion + * + * @event core.delete_attachments_before + * @var string mode Variable containing attachments deletion mode, can be: post|message|topic|attach|user + * @var mixed ids Array or comma separated list of ids corresponding to the mode + * @var bool resync Flag indicating if posts/messages/topics should be synchronized + * @var string sql_id The field name to collect/delete data for depending on the mode + * @var array post_ids Array with post ids for deleted attachment(s) + * @var array topic_ids Array with topic ids for deleted attachment(s) + * @var array message_ids Array with private message ids for deleted attachment(s) + * @var array physical Array with deleted attachment(s) physical file(s) data + * @since 3.1.7-RC1 + */ + $vars = array( + 'mode', + 'ids', + 'resync', + 'sql_id', + 'post_ids', + 'topic_ids', + 'message_ids', + 'physical', + ); + extract($phpbb_dispatcher->trigger_event('core.delete_attachments_before', compact($vars))); + // Delete attachments $sql = 'DELETE FROM ' . ATTACHMENTS_TABLE . ' WHERE ' . $db->sql_in_set($sql_id, $ids); @@ -1125,6 +1240,34 @@ function delete_attachments($mode, $ids, $resync = true) $db->sql_query($sql); $num_deleted = $db->sql_affectedrows(); + /** + * Perform additional actions after attachment(s) deletion from the database + * + * @event core.delete_attachments_from_database_after + * @var string mode Variable containing attachments deletion mode, can be: post|message|topic|attach|user + * @var mixed ids Array or comma separated list of ids corresponding to the mode + * @var bool resync Flag indicating if posts/messages/topics should be synchronized + * @var string sql_id The field name to collect/delete data for depending on the mode + * @var array post_ids Array with post ids for deleted attachment(s) + * @var array topic_ids Array with topic ids for deleted attachment(s) + * @var array message_ids Array with private message ids for deleted attachment(s) + * @var array physical Array with deleted attachment(s) physical file(s) data + * @var int num_deleted The number of deleted attachment(s) from the database + * @since 3.1.7-RC1 + */ + $vars = array( + 'mode', + 'ids', + 'resync', + 'sql_id', + 'post_ids', + 'topic_ids', + 'message_ids', + 'physical', + 'num_deleted', + ); + extract($phpbb_dispatcher->trigger_event('core.delete_attachments_from_database_after', compact($vars))); + if (!$num_deleted) { return 0; @@ -1147,6 +1290,38 @@ function delete_attachments($mode, $ids, $resync = true) } } + /** + * Perform additional actions after attachment(s) deletion from the filesystem + * + * @event core.delete_attachments_from_filesystem_after + * @var string mode Variable containing attachments deletion mode, can be: post|message|topic|attach|user + * @var mixed ids Array or comma separated list of ids corresponding to the mode + * @var bool resync Flag indicating if posts/messages/topics should be synchronized + * @var string sql_id The field name to collect/delete data for depending on the mode + * @var array post_ids Array with post ids for deleted attachment(s) + * @var array topic_ids Array with topic ids for deleted attachment(s) + * @var array message_ids Array with private message ids for deleted attachment(s) + * @var array physical Array with deleted attachment(s) physical file(s) data + * @var int num_deleted The number of deleted attachment(s) from the database + * @var int space_removed The size of deleted files(s) from the filesystem + * @var int files_removed The number of deleted file(s) from the filesystem + * @since 3.1.7-RC1 + */ + $vars = array( + 'mode', + 'ids', + 'resync', + 'sql_id', + 'post_ids', + 'topic_ids', + 'message_ids', + 'physical', + 'num_deleted', + 'space_removed', + 'files_removed', + ); + extract($phpbb_dispatcher->trigger_event('core.delete_attachments_from_filesystem_after', compact($vars))); + if ($space_removed || $files_removed) { set_config_count('upload_dir_size', $space_removed * (-1), true); diff --git a/phpBB/includes/functions_user.php b/phpBB/includes/functions_user.php index c46653db9e..fe370750d9 100644 --- a/phpBB/includes/functions_user.php +++ b/phpBB/includes/functions_user.php @@ -2933,6 +2933,19 @@ function group_user_del($group_id, $user_id_ary = false, $username_ary = false, // Clear permissions cache of relevant users $auth->acl_clear_prefetch($user_id_ary); + /** + * Event after users are removed from a group + * + * @event core.group_delete_user_after + * @var int group_id ID of the group from which users are deleted + * @var string group_name Name of the group + * @var array user_id_ary IDs of the users which are removed + * @var array username_ary names of the users which are removed + * @since 3.1.7-RC1 + */ + $vars = array('group_id', 'group_name', 'user_id_ary', 'username_ary'); + extract($phpbb_dispatcher->trigger_event('core.group_delete_user_after', compact($vars))); + if (!$group_name) { $group_name = get_group_name($group_id); diff --git a/phpBB/includes/mcp/info/mcp_pm_reports.php b/phpBB/includes/mcp/info/mcp_pm_reports.php index 8670b71084..c80f3b86a3 100644 --- a/phpBB/includes/mcp/info/mcp_pm_reports.php +++ b/phpBB/includes/mcp/info/mcp_pm_reports.php @@ -20,9 +20,9 @@ class mcp_pm_reports_info 'title' => 'MCP_PM_REPORTS', 'version' => '1.0.0', 'modes' => array( - 'pm_reports' => array('title' => 'MCP_PM_REPORTS_OPEN', 'auth' => 'aclf_m_report', 'cat' => array('MCP_REPORTS')), - 'pm_reports_closed' => array('title' => 'MCP_PM_REPORTS_CLOSED', 'auth' => 'aclf_m_report', 'cat' => array('MCP_REPORTS')), - 'pm_report_details' => array('title' => 'MCP_PM_REPORT_DETAILS', 'auth' => 'aclf_m_report', 'cat' => array('MCP_REPORTS')), + 'pm_reports' => array('title' => 'MCP_PM_REPORTS_OPEN', 'auth' => 'acl_m_pm_report', 'cat' => array('MCP_REPORTS')), + 'pm_reports_closed' => array('title' => 'MCP_PM_REPORTS_CLOSED', 'auth' => 'acl_m_pm_report', 'cat' => array('MCP_REPORTS')), + 'pm_report_details' => array('title' => 'MCP_PM_REPORT_DETAILS', 'auth' => 'acl_m_pm_report', 'cat' => array('MCP_REPORTS')), ), ); } diff --git a/phpBB/includes/mcp/mcp_front.php b/phpBB/includes/mcp/mcp_front.php index 629b6fd275..cdf1abd8ff 100644 --- a/phpBB/includes/mcp/mcp_front.php +++ b/phpBB/includes/mcp/mcp_front.php @@ -274,7 +274,7 @@ function mcp_front_view($id, $mode, $action) } // Latest 5 reported PMs - if ($module->loaded('pm_reports') && $auth->acl_getf_global('m_report')) + if ($module->loaded('pm_reports') && $auth->acl_get('m_pm_report')) { $template->assign_var('S_SHOW_PM_REPORTS', true); $user->add_lang(array('ucp')); diff --git a/phpBB/includes/mcp/mcp_queue.php b/phpBB/includes/mcp/mcp_queue.php index 5fde63ecb4..3567e545f0 100644 --- a/phpBB/includes/mcp/mcp_queue.php +++ b/phpBB/includes/mcp/mcp_queue.php @@ -72,6 +72,7 @@ class mcp_queue case 'delete': $post_id_list = $request->variable('post_id_list', array(0)); $topic_id_list = $request->variable('topic_id_list', array(0)); + $delete_reason = $request->variable('delete_reason', '', true); if (!empty($post_id_list)) { @@ -80,7 +81,7 @@ class mcp_queue global $phpbb_root_path, $phpEx; include($phpbb_root_path . 'includes/mcp/mcp_main.' . $phpEx); } - mcp_delete_post($post_id_list, false, '', $action); + mcp_delete_post($post_id_list, false, $delete_reason, $action); } else if (!empty($topic_id_list)) { @@ -89,7 +90,7 @@ class mcp_queue global $phpbb_root_path, $phpEx; include($phpbb_root_path . 'includes/mcp/mcp_main.' . $phpEx); } - mcp_delete_topic($topic_id_list, false, '', $action); + mcp_delete_topic($topic_id_list, false, $delete_reason, $action); } else { @@ -283,6 +284,7 @@ class mcp_queue $template->assign_vars(array( 'S_MCP_QUEUE' => true, 'U_APPROVE_ACTION' => append_sid("{$phpbb_root_path}mcp.$phpEx", "i=queue&p=$post_id&f=$forum_id"), + 'S_CAN_DELETE_POST' => $auth->acl_get('m_delete', $post_info['forum_id']), 'S_CAN_VIEWIP' => $auth->acl_get('m_info', $post_info['forum_id']), 'S_POST_REPORTED' => $post_info['post_reported'], 'S_POST_UNAPPROVED' => $post_info['post_visibility'] == ITEM_UNAPPROVED || $post_info['post_visibility'] == ITEM_REAPPROVE, @@ -1130,6 +1132,11 @@ class mcp_queue // Build a list of posts to be disapproved and get the related topics real replies count foreach ($post_info as $post_id => $post_data) { + if ($mode === 'unapproved_topics' && $post_data['post_visibility'] == ITEM_APPROVED) + { + continue; + } + $post_disapprove_list[$post_id] = $post_data['topic_id']; if (!isset($topic_posts_unapproved[$post_data['topic_id']])) { @@ -1139,6 +1146,12 @@ class mcp_queue $topic_posts_unapproved[$post_data['topic_id']]++; } + // Do not try to disapprove if no posts are selected + if (empty($post_disapprove_list)) + { + trigger_error('NO_POST_SELECTED'); + } + // Now we build the log array foreach ($post_disapprove_list as $post_id => $topic_id) { @@ -1240,7 +1253,7 @@ class mcp_queue continue; } - $post_data['disapprove_reason'] = ''; + $post_data['disapprove_reason'] = $disapprove_reason; if (isset($disapprove_reason_lang)) { // Okay we need to get the reason from the posters language diff --git a/phpBB/includes/ucp/ucp_pm.php b/phpBB/includes/ucp/ucp_pm.php index 425a56cf6c..f026cd3eb3 100644 --- a/phpBB/includes/ucp/ucp_pm.php +++ b/phpBB/includes/ucp/ucp_pm.php @@ -92,7 +92,7 @@ class ucp_pm $user_folders = get_folder($user->data['user_id']); - if (!$auth->acl_get('u_sendpm')) + if ($action != 'delete' && !$auth->acl_get('u_sendpm')) { // trigger_error('NO_AUTH_SEND_MESSAGE'); $template->assign_vars(array( diff --git a/phpBB/includes/ucp/ucp_profile.php b/phpBB/includes/ucp/ucp_profile.php index 8d8d42e742..be0833254b 100644 --- a/phpBB/includes/ucp/ucp_profile.php +++ b/phpBB/includes/ucp/ucp_profile.php @@ -183,37 +183,12 @@ class ucp_profile if ($config['require_activation'] == USER_ACTIVATION_ADMIN) { - // Grab an array of user_id's with a_user permissions ... these users can activate a user - $admin_ary = $auth->acl_get_list(false, 'a_user', false); - $admin_ary = (!empty($admin_ary[0]['a_user'])) ? $admin_ary[0]['a_user'] : array(); - - // Also include founders - $where_sql = ' WHERE user_type = ' . USER_FOUNDER; - - if (sizeof($admin_ary)) - { - $where_sql .= ' OR ' . $db->sql_in_set('user_id', $admin_ary); - } - - $sql = 'SELECT user_id, username, user_email, user_lang, user_jabber, user_notify_type - FROM ' . USERS_TABLE . ' ' . - $where_sql; - $result = $db->sql_query($sql); - - while ($row = $db->sql_fetchrow($result)) - { - $messenger->template('admin_activate', $row['user_lang']); - $messenger->set_addresses($row); - - $messenger->assign_vars(array( - 'USERNAME' => htmlspecialchars_decode($data['username']), - 'U_USER_DETAILS' => "$server_url/memberlist.$phpEx?mode=viewprofile&u={$user->data['user_id']}", - 'U_ACTIVATE' => "$server_url/ucp.$phpEx?mode=activate&u={$user->data['user_id']}&k=$user_actkey") - ); - - $messenger->send($row['user_notify_type']); - } - $db->sql_freeresult($result); + $notifications_manager = $phpbb_container->get('notification_manager'); + $notifications_manager->add_notifications('notification.type.admin_activate_user', array( + 'user_id' => $user->data['user_id'], + 'user_actkey' => $user_actkey, + 'user_regdate' => time(), // Notification time + )); } user_active_flip('deactivate', $user->data['user_id'], INACTIVE_PROFILE); diff --git a/phpBB/install/schemas/schema_data.sql b/phpBB/install/schemas/schema_data.sql index 9af2bc13f7..1b6766e1b1 100644 --- a/phpBB/install/schemas/schema_data.sql +++ b/phpBB/install/schemas/schema_data.sql @@ -355,6 +355,7 @@ INSERT INTO phpbb_acl_options (auth_option, is_local, is_global) VALUES ('m_soft # -- Global moderator auth option (not a local option) INSERT INTO phpbb_acl_options (auth_option, is_local, is_global) VALUES ('m_ban', 0, 1); +INSERT INTO phpbb_acl_options (auth_option, is_local, is_global) VALUES ('m_pm_report', 0, 1); INSERT INTO phpbb_acl_options (auth_option, is_local, is_global) VALUES ('m_warn', 0, 1); # -- Admin related auth options @@ -542,7 +543,7 @@ INSERT INTO phpbb_acl_roles_data (role_id, auth_option_id, auth_setting) SELECT INSERT INTO phpbb_acl_roles_data (role_id, auth_option_id, auth_setting) SELECT 11, auth_option_id, 1 FROM phpbb_acl_options WHERE auth_option LIKE 'm_%' AND auth_option NOT IN ('m_ban', 'm_chgposter'); # Simple Moderator (m_) -INSERT INTO phpbb_acl_roles_data (role_id, auth_option_id, auth_setting) SELECT 12, auth_option_id, 1 FROM phpbb_acl_options WHERE auth_option LIKE 'm_%' AND auth_option IN ('m_', 'm_delete', 'm_softdelete', 'm_edit', 'm_info', 'm_report'); +INSERT INTO phpbb_acl_roles_data (role_id, auth_option_id, auth_setting) SELECT 12, auth_option_id, 1 FROM phpbb_acl_options WHERE auth_option LIKE 'm_%' AND auth_option IN ('m_', 'm_delete', 'm_softdelete', 'm_edit', 'm_info', 'm_report', 'm_pm_report'); # Queue Moderator (m_) INSERT INTO phpbb_acl_roles_data (role_id, auth_option_id, auth_setting) SELECT 13, auth_option_id, 1 FROM phpbb_acl_options WHERE auth_option LIKE 'm_%' AND auth_option IN ('m_', 'm_approve', 'm_edit'); diff --git a/phpBB/language/en/acp/permissions_phpbb.php b/phpBB/language/en/acp/permissions_phpbb.php index b9aeed8fcb..2e80e61adc 100644 --- a/phpBB/language/en/acp/permissions_phpbb.php +++ b/phpBB/language/en/acp/permissions_phpbb.php @@ -155,9 +155,10 @@ $lang = array_merge($lang, array( 'ACL_M_SPLIT' => 'Can split topics', 'ACL_M_MERGE' => 'Can merge topics', - 'ACL_M_INFO' => 'Can view post details', - 'ACL_M_WARN' => 'Can issue warnings<br /><em>This setting is only assigned globally. It is not forum based.</em>', // This moderator setting is only global (and not local) - 'ACL_M_BAN' => 'Can manage bans<br /><em>This setting is only assigned globally. It is not forum based.</em>', // This moderator setting is only global (and not local) + 'ACL_M_INFO' => 'Can view post details', + 'ACL_M_WARN' => 'Can issue warnings<br /><em>This setting is only assigned globally. It is not forum based.</em>', // This moderator setting is only global (and not local) + 'ACL_M_PM_REPORT' => 'Can close and delete reports of private messages<br /><em>This setting is only assigned globally. It is not forum based.</em>', // This moderator setting is only global (and not local) + 'ACL_M_BAN' => 'Can manage bans<br /><em>This setting is only assigned globally. It is not forum based.</em>', // This moderator setting is only global (and not local) )); // Admin Permissions diff --git a/phpBB/language/en/common.php b/phpBB/language/en/common.php index 79d504a67d..47e04d9360 100644 --- a/phpBB/language/en/common.php +++ b/phpBB/language/en/common.php @@ -329,6 +329,7 @@ $lang = array_merge($lang, array( 'IMAGE_FILETYPE_INVALID' => 'Image file type %d for mimetype %s not supported.', 'IMAGE_FILETYPE_MISMATCH' => 'Image file type mismatch: expected extension %1$s but extension %2$s given.', 'IN' => 'in', + 'INACTIVE' => 'Inactive', 'INDEX' => 'Index page', 'INFORMATION' => 'Information', 'INSECURE_REDIRECT' => 'Tried to redirect to potentially insecure url.', @@ -467,7 +468,7 @@ $lang = array_merge($lang, array( 'NOTIFICATION_TOPIC_DISAPPROVED' => '<strong>Topic disapproved</strong>:', 'NOTIFICATION_TOPIC_IN_QUEUE' => '<strong>Topic approval</strong> request by %1$s:', 'NOTIFICATION_TYPE_NOT_EXIST' => 'The notification type "%s" is missing from the file system.', - 'NOTIFICATION_ADMIN_ACTIVATE_USER' => '<strong>Activation required</strong> for newly registered user: “%1$s”', + 'NOTIFICATION_ADMIN_ACTIVATE_USER' => '<strong>Activation required</strong> for deactivated or newly registered user: “%1$s”', // Used in conjuction with NOTIFICATION_BOOKMARK and NOTIFICATION_POST. 'NOTIFICATION_MANY_OTHERS' => 'others', 'NOTIFICATION_X_OTHERS' => array( diff --git a/phpBB/language/en/ucp.php b/phpBB/language/en/ucp.php index 07751d1f7f..1faa623b44 100644 --- a/phpBB/language/en/ucp.php +++ b/phpBB/language/en/ucp.php @@ -339,7 +339,7 @@ $lang = array_merge($lang, array( 'NOTIFICATION_TYPE_QUOTE' => 'Someone quotes you in a post', 'NOTIFICATION_TYPE_REPORT' => 'Someone reports a post', 'NOTIFICATION_TYPE_TOPIC' => 'Someone creates a topic in a forum to which you are subscribed', - 'NOTIFICATION_TYPE_ADMIN_ACTIVATE_USER' => 'Newly registered user requiring activation', + 'NOTIFICATION_TYPE_ADMIN_ACTIVATE_USER' => 'User requiring activation', 'NOTIFY_METHOD' => 'Notification method', 'NOTIFY_METHOD_BOTH' => 'Both', diff --git a/phpBB/memberlist.php b/phpBB/memberlist.php index e64dab635b..364a3cd523 100644 --- a/phpBB/memberlist.php +++ b/phpBB/memberlist.php @@ -151,7 +151,7 @@ switch ($mode) $db->sql_freeresult($result); $sql_ary = array( - 'SELECT' => 'u.user_id, u.group_id as default_group, u.username, u.username_clean, u.user_colour, u.user_rank, u.user_posts, u.user_allow_pm, g.group_id', + 'SELECT' => 'u.user_id, u.group_id as default_group, u.username, u.username_clean, u.user_colour, u.user_type, u.user_rank, u.user_posts, u.user_allow_pm, g.group_id', 'FROM' => array( USER_GROUP_TABLE => 'ug', @@ -314,6 +314,8 @@ switch ($mode) 'RANK_IMG' => $user_rank_data['img'], 'RANK_IMG_SRC' => $user_rank_data['img_src'], + 'S_INACTIVE' => $row['user_type'] == USER_INACTIVE, + 'U_PM' => ($config['allow_privmsg'] && $auth->acl_get('u_sendpm') && ($row['user_allow_pm'] || $auth->acl_gets('a_', 'm_') || $auth->acl_getf_global('m_'))) ? append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&mode=compose&u=' . $row['user_id']) : '', 'USERNAME_FULL' => get_username_string('full', $row['user_id'], $row['username'], $row['user_colour']), @@ -1025,6 +1027,23 @@ switch ($mode) FROM ' . POSTS_TABLE . ' WHERE poster_ip ' . ((strpos($ips, '%') !== false) ? 'LIKE' : 'IN') . " ($ips) AND " . $db->sql_in_set('forum_id', $ip_forums); + + /** + * Modify sql query for members search by ip address / hostname + * + * @event core.memberlist_modify_ip_search_sql_query + * @var string ipdomain The host name + * @var string ips IP address list for the given host name + * @var string sql The SQL query for searching members by IP address + * @since 3.1.7-RC1 + */ + $vars = array( + 'ipdomain', + 'ips', + 'sql', + ); + extract($phpbb_dispatcher->trigger_event('core.memberlist_modify_ip_search_sql_query', compact($vars))); + $result = $db->sql_query($sql); if ($row = $db->sql_fetchrow($result)) @@ -1165,6 +1184,32 @@ switch ($mode) $order_by .= ', u.user_posts DESC'; } + /** + * Modify sql query data for members search + * + * @event core.memberlist_modify_sql_query_data + * @var string order_by SQL ORDER BY clause condition + * @var string sort_dir The sorting direction + * @var string sort_key The sorting key + * @var array sort_key_sql Arraty with the sorting conditions data + * @var string sql_from SQL FROM clause condition + * @var string sql_select SQL SELECT fields list + * @var string sql_where SQL WHERE clause condition + * @var string sql_where_data SQL WHERE clause additional conditions data + * @since 3.1.7-RC1 + */ + $vars = array( + 'order_by', + 'sort_dir', + 'sort_key', + 'sort_key_sql', + 'sql_from', + 'sql_select', + 'sql_where', + 'sql_where_data', + ); + extract($phpbb_dispatcher->trigger_event('core.memberlist_modify_sql_query_data', compact($vars))); + // Count the users ... if ($sql_where) { @@ -1345,13 +1390,19 @@ switch ($mode) ); } + $user_types = array(USER_NORMAL, USER_FOUNDER); + if ($auth->acl_get('a_user')) + { + $user_types[] = USER_INACTIVE; + } + $start = $pagination->validate_start($start, $config['topics_per_page'], $config['num_users']); // Get us some users :D $sql = "SELECT u.user_id FROM " . USERS_TABLE . " u $sql_from - WHERE u.user_type IN (" . USER_NORMAL . ', ' . USER_FOUNDER . ") + WHERE " . $db->sql_in_set('u.user_type', $user_types) . " $sql_where ORDER BY $order_by"; $result = $db->sql_query_limit($sql, $config['topics_per_page'], $start); @@ -1448,6 +1499,20 @@ switch ($mode) usort($user_list, 'phpbb_sort_last_active'); } + // do we need to display contact fields as such + $use_contact_fields = false; + + /** + * Modify list of users before member row is created + * + * @event core.memberlist_memberrow_before + * @var array user_list Array containing list of users + * @var bool use_contact_fields Should we display contact fields as such? + * @since 3.1.7-RC1 + */ + $vars = array('user_list', 'use_contact_fields'); + extract($phpbb_dispatcher->trigger_event('core.memberlist_memberrow_before', compact($vars))); + for ($i = 0, $end = sizeof($user_list); $i < $end; ++$i) { $user_id = $user_list[$i]; @@ -1458,7 +1523,7 @@ switch ($mode) $cp_row = array(); if ($config['load_cpf_memberlist']) { - $cp_row = (isset($profile_fields_cache[$user_id])) ? $cp->generate_profile_fields_template_data($profile_fields_cache[$user_id], false) : array(); + $cp_row = (isset($profile_fields_cache[$user_id])) ? $cp->generate_profile_fields_template_data($profile_fields_cache[$user_id], $use_contact_fields) : array(); } $memberrow = array_merge(phpbb_show_profile($row, false, false, false), array( @@ -1466,6 +1531,7 @@ switch ($mode) 'S_CUSTOM_PROFILE' => (isset($cp_row['row']) && sizeof($cp_row['row'])) ? true : false, 'S_GROUP_LEADER' => $is_leader, + 'S_INACTIVE' => $row['user_type'] == USER_INACTIVE, 'U_VIEW_PROFILE' => get_username_string('profile', $user_id, $row['username']), )); diff --git a/phpBB/phpbb/auth/auth.php b/phpBB/phpbb/auth/auth.php index b59f0e60ec..b7634e04ce 100644 --- a/phpBB/phpbb/auth/auth.php +++ b/phpBB/phpbb/auth/auth.php @@ -928,6 +928,7 @@ class auth function login($username, $password, $autologin = false, $viewonline = 1, $admin = 0) { global $db, $user, $phpbb_root_path, $phpEx, $phpbb_container; + global $phpbb_dispatcher; $provider_collection = $phpbb_container->get('auth.provider_collection'); @@ -982,6 +983,24 @@ class auth redirect($url); } + /** + * Event is triggered after checking for valid username and password, and before the actual session creation. + * + * @event core.auth_login_session_create_before + * @var array login Variable containing login array + * @var bool admin Boolean variable whether user is logging into the ACP + * @var string username Username of user to log in + * @var bool autologin Boolean variable signaling whether login is triggered via auto login + * @since 3.1.7-RC1 + */ + $vars = array( + 'login', + 'admin', + 'username', + 'autologin', + ); + extract($phpbb_dispatcher->trigger_event('core.auth_login_session_create_before', compact($vars))); + // If login succeeded, we will log the user in... else we pass the login array through... if ($login['status'] == LOGIN_SUCCESS) { diff --git a/phpBB/phpbb/avatar/driver/gravatar.php b/phpBB/phpbb/avatar/driver/gravatar.php index 2082e0fd02..bb4977c30c 100644 --- a/phpBB/phpbb/avatar/driver/gravatar.php +++ b/phpBB/phpbb/avatar/driver/gravatar.php @@ -172,6 +172,8 @@ class gravatar extends \phpbb\avatar\driver\driver */ protected function get_gravatar_url($row) { + global $phpbb_dispatcher; + $url = self::GRAVATAR_URL; $url .= md5(strtolower(trim($row['avatar']))); @@ -180,6 +182,17 @@ class gravatar extends \phpbb\avatar\driver\driver $url .= '?s=' . max($row['avatar_width'], $row['avatar_height']); } + /** + * Modify gravatar url + * + * @event core.get_gravatar_url_after + * @var string row User data or group data + * @var string url Gravatar URL + * @since 3.1.7-RC1 + */ + $vars = array('row', 'url'); + extract($phpbb_dispatcher->trigger_event('core.get_gravatar_url_after', compact($vars))); + return $url; } } diff --git a/phpBB/phpbb/avatar/driver/local.php b/phpBB/phpbb/avatar/driver/local.php index 36087f8ba0..75c384f31e 100644 --- a/phpBB/phpbb/avatar/driver/local.php +++ b/phpBB/phpbb/avatar/driver/local.php @@ -84,11 +84,13 @@ class local extends \phpbb\avatar\driver\driver 'AVATAR_IMAGE' => $this->phpbb_root_path . $this->config['avatar_gallery_path'] . '/' . $img['file'], 'AVATAR_NAME' => $img['name'], 'AVATAR_FILE' => $img['filename'], + 'CHECKED' => $img['file'] === $row['avatar'], )); $template->assign_block_vars('avatar_local_row.avatar_local_option', array( 'AVATAR_FILE' => $img['filename'], - 'S_OPTIONS_AVATAR' => $img['filename'] + 'S_OPTIONS_AVATAR' => $img['filename'], + 'CHECKED' => $img['file'] === $row['avatar'], )); $col_count = ($col_count + 1) % $table_cols; @@ -182,7 +184,7 @@ class local extends \phpbb\avatar\driver\driver } $cat = ($path == $file_path) ? $user->lang['NO_AVATAR_CATEGORY'] : str_replace("$path/", '', $file_path); $avatar_list[$cat][$image] = array( - 'file' => ($cat != $user->lang['NO_AVATAR_CATEGORY']) ? rawurlencode($cat) . '/' . rawurlencode($image) : rawurlencode($image), + 'file' => ($cat != $user->lang['NO_AVATAR_CATEGORY']) ? str_replace('%2F', '/', rawurlencode($cat)) . '/' . rawurlencode($image) : rawurlencode($image), 'filename' => rawurlencode($image), 'name' => ucfirst(str_replace('_', ' ', preg_replace('#^(.*)\..*$#', '\1', $image))), 'width' => $dims[0], diff --git a/phpBB/phpbb/db/migration/data/v31x/m_pm_report.php b/phpBB/phpbb/db/migration/data/v31x/m_pm_report.php new file mode 100644 index 0000000000..9b5710c639 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v31x/m_pm_report.php @@ -0,0 +1,64 @@ +<?php +/** +* +* This file is part of the phpBB Forum Software package. +* +* @copyright (c) phpBB Limited <https://www.phpbb.com> +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\db\migration\data\v31x; + +class m_pm_report extends \phpbb\db\migration\migration +{ + static public function depends_on() + { + return array('\phpbb\db\migration\data\v31x\v316rc1'); + } + + public function update_data() + { + return array( + array('permission.add', array('m_pm_report', true, 'm_report')), + array('custom', array( + array($this, 'update_module_auth'), + ), + ), + ); + } + + public function revert_data() + { + return array( + array('permission.remove', array('m_pm_report')), + array('custom', array( + array($this, 'revert_module_auth'), + ), + ), + ); + } + + public function update_module_auth() + { + $sql = 'UPDATE ' . MODULES_TABLE . " + SET module_auth = 'acl_m_pm_report' + WHERE module_class = 'mcp' + AND module_basename = 'mcp_pm_reports' + AND module_auth = 'aclf_m_report'"; + $this->db->sql_query($sql); + } + + public function revert_module_auth() + { + $sql = 'UPDATE ' . MODULES_TABLE . " + SET module_auth = 'aclf_m_report' + WHERE module_class = 'mcp' + AND module_basename = 'mcp_pm_reports' + AND module_auth = 'acl_m_pm_report'"; + $this->db->sql_query($sql); + } +} diff --git a/phpBB/phpbb/notification/type/approve_post.php b/phpBB/phpbb/notification/type/approve_post.php index a9e635b41a..5760c12166 100644 --- a/phpBB/phpbb/notification/type/approve_post.php +++ b/phpBB/phpbb/notification/type/approve_post.php @@ -82,7 +82,7 @@ class approve_post extends \phpbb\notification\type\post $users[$post['poster_id']] = array(''); return $this->get_authorised_recipients(array_keys($users), $post['forum_id'], array_merge($options, array( - 'item_type' => self::$notification_option['id'], + 'item_type' => static::$notification_option['id'], ))); } diff --git a/phpBB/phpbb/notification/type/approve_topic.php b/phpBB/phpbb/notification/type/approve_topic.php index 2f4678359c..26e51bf9cd 100644 --- a/phpBB/phpbb/notification/type/approve_topic.php +++ b/phpBB/phpbb/notification/type/approve_topic.php @@ -82,7 +82,7 @@ class approve_topic extends \phpbb\notification\type\topic $users[$post['poster_id']] = array(''); return $this->get_authorised_recipients(array_keys($users), $post['forum_id'], array_merge($options, array( - 'item_type' => self::$notification_option['id'], + 'item_type' => static::$notification_option['id'], ))); } diff --git a/phpBB/phpbb/notification/type/bookmark.php b/phpBB/phpbb/notification/type/bookmark.php index 4f2d34cb60..1626add22c 100644 --- a/phpBB/phpbb/notification/type/bookmark.php +++ b/phpBB/phpbb/notification/type/bookmark.php @@ -95,7 +95,7 @@ class bookmark extends \phpbb\notification\type\post $sql = 'SELECT n.* FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt WHERE n.notification_type_id = ' . (int) $this->notification_type_id . ' - AND n.item_parent_id = ' . (int) self::get_item_parent_id($post) . ' + AND n.item_parent_id = ' . (int) static::get_item_parent_id($post) . ' AND n.notification_read = 0 AND nt.notification_type_id = n.notification_type_id AND nt.notification_type_enabled = 1'; diff --git a/phpBB/phpbb/notification/type/post.php b/phpBB/phpbb/notification/type/post.php index e25fdcd808..2969da550d 100644 --- a/phpBB/phpbb/notification/type/post.php +++ b/phpBB/phpbb/notification/type/post.php @@ -135,7 +135,7 @@ class post extends \phpbb\notification\type\base $sql = 'SELECT n.* FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt WHERE n.notification_type_id = ' . (int) $this->notification_type_id . ' - AND n.item_parent_id = ' . (int) self::get_item_parent_id($post) . ' + AND n.item_parent_id = ' . (int) static::get_item_parent_id($post) . ' AND n.notification_read = 0 AND nt.notification_type_id = n.notification_type_id AND nt.notification_type_enabled = 1'; diff --git a/phpBB/phpbb/notification/type/post_in_queue.php b/phpBB/phpbb/notification/type/post_in_queue.php index 315b8b0243..5832c99cd2 100644 --- a/phpBB/phpbb/notification/type/post_in_queue.php +++ b/phpBB/phpbb/notification/type/post_in_queue.php @@ -108,7 +108,7 @@ class post_in_queue extends \phpbb\notification\type\post } return $this->check_user_notification_options($auth_read[$post['forum_id']]['f_read'], array_merge($options, array( - 'item_type' => self::$notification_option['id'], + 'item_type' => static::$notification_option['id'], ))); } diff --git a/phpBB/phpbb/notification/type/quote.php b/phpBB/phpbb/notification/type/quote.php index 508ca92fa0..2732cb84e4 100644 --- a/phpBB/phpbb/notification/type/quote.php +++ b/phpBB/phpbb/notification/type/quote.php @@ -78,7 +78,7 @@ class quote extends \phpbb\notification\type\post ), $options); $usernames = false; - preg_match_all(self::$regular_expression_match, $post['post_text'], $usernames); + preg_match_all(static::$regular_expression_match, $post['post_text'], $usernames); if (empty($usernames[1])) { @@ -116,7 +116,7 @@ class quote extends \phpbb\notification\type\post $sql = 'SELECT n.user_id FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt WHERE n.notification_type_id = ' . (int) $this->notification_type_id . ' - AND n.item_id = ' . self::get_item_id($post) . ' + AND n.item_id = ' . static::get_item_id($post) . ' AND nt.notification_type_id = n.notification_type_id AND nt.notification_type_enabled = 1'; $result = $this->db->sql_query($sql); @@ -147,7 +147,7 @@ class quote extends \phpbb\notification\type\post { $sql = 'DELETE FROM ' . $this->notifications_table . ' WHERE notification_type_id = ' . (int) $this->notification_type_id . ' - AND item_id = ' . self::get_item_id($post) . ' + AND item_id = ' . static::get_item_id($post) . ' AND ' . $this->db->sql_in_set('user_id', $remove_notifications); $this->db->sql_query($sql); } diff --git a/phpBB/phpbb/notification/type/report_pm.php b/phpBB/phpbb/notification/type/report_pm.php index 749cfe0b8e..785e5f243d 100644 --- a/phpBB/phpbb/notification/type/report_pm.php +++ b/phpBB/phpbb/notification/type/report_pm.php @@ -120,7 +120,7 @@ class report_pm extends \phpbb\notification\type\pm } return $this->check_user_notification_options($auth_approve[$post['forum_id']][$this->permission], array_merge($options, array( - 'item_type' => self::$notification_option['id'], + 'item_type' => static::$notification_option['id'], ))); } diff --git a/phpBB/phpbb/notification/type/topic_in_queue.php b/phpBB/phpbb/notification/type/topic_in_queue.php index 4c60c6b858..6e57b9ac0c 100644 --- a/phpBB/phpbb/notification/type/topic_in_queue.php +++ b/phpBB/phpbb/notification/type/topic_in_queue.php @@ -108,7 +108,7 @@ class topic_in_queue extends \phpbb\notification\type\topic } return $this->check_user_notification_options($auth_read[$topic['forum_id']]['f_read'], array_merge($options, array( - 'item_type' => self::$notification_option['id'], + 'item_type' => static::$notification_option['id'], ))); } diff --git a/phpBB/phpbb/passwords/driver/salted_md5.php b/phpBB/phpbb/passwords/driver/salted_md5.php index 81ac010785..38d6d9cd2c 100644 --- a/phpBB/phpbb/passwords/driver/salted_md5.php +++ b/phpBB/phpbb/passwords/driver/salted_md5.php @@ -75,7 +75,7 @@ class salted_md5 extends base // happen if pre-determined settings are // directly passed to the driver. The manager // will not do this. Same as the old hashing - // implementatio in phpBB 3.0 + // implementation in phpBB 3.0 return md5($password); } } diff --git a/phpBB/phpbb/permissions.php b/phpBB/phpbb/permissions.php index 42bbe443d1..e75476f59b 100644 --- a/phpBB/phpbb/permissions.php +++ b/phpBB/phpbb/permissions.php @@ -307,8 +307,9 @@ class permissions 'm_split' => array('lang' => 'ACL_M_SPLIT', 'cat' => 'topic_actions'), 'm_merge' => array('lang' => 'ACL_M_MERGE', 'cat' => 'topic_actions'), - 'm_warn' => array('lang' => 'ACL_M_WARN', 'cat' => 'misc'), - 'm_ban' => array('lang' => 'ACL_M_BAN', 'cat' => 'misc'), + 'm_warn' => array('lang' => 'ACL_M_WARN', 'cat' => 'misc'), + 'm_pm_report' => array('lang' => 'ACL_M_PM_REPORT', 'cat' => 'misc'), + 'm_ban' => array('lang' => 'ACL_M_BAN', 'cat' => 'misc'), // Admin Permissions 'a_board' => array('lang' => 'ACL_A_BOARD', 'cat' => 'settings'), diff --git a/phpBB/phpbb/plupload/plupload.php b/phpBB/phpbb/plupload/plupload.php index ca78167ec0..7f6267ed32 100644 --- a/phpBB/phpbb/plupload/plupload.php +++ b/phpBB/phpbb/plupload/plupload.php @@ -125,7 +125,7 @@ class plupload // Need to modify some of the $_FILES values to reflect the new file return array( 'tmp_name' => $file_path, - 'name' => $this->request->variable('real_filename', ''), + 'name' => $this->request->variable('real_filename', '', true), 'size' => filesize($file_path), 'type' => $this->mimetype_guesser->guess($file_path, $file_name), ); diff --git a/phpBB/phpbb/search/fulltext_mysql.php b/phpBB/phpbb/search/fulltext_mysql.php index bad2003000..3ddbd85b36 100644 --- a/phpBB/phpbb/search/fulltext_mysql.php +++ b/phpBB/phpbb/search/fulltext_mysql.php @@ -379,7 +379,7 @@ class fulltext_mysql extends \phpbb\search\base } // generate a search_key from all the options to identify the results - $search_key = md5(implode('#', array( + $search_key_array = array( implode(', ', $this->split_words), $type, $fields, @@ -390,7 +390,39 @@ class fulltext_mysql extends \phpbb\search\base implode(',', $ex_fid_ary), $post_visibility, implode(',', $author_ary) - ))); + ); + + /** + * Allow changing the search_key for cached results + * + * @event core.search_mysql_by_keyword_modify_search_key + * @var array search_key_array Array with search parameters to generate the search_key + * @var string type Searching type ('posts', 'topics') + * @var string fields Searching fields ('titleonly', 'msgonly', 'firstpost', 'all') + * @var string terms Searching terms ('all', 'any') + * @var int sort_days Time, in days, of the oldest possible post to list + * @var string sort_key The sort type used from the possible sort types + * @var int topic_id Limit the search to this topic_id only + * @var array ex_fid_ary Which forums not to search on + * @var string post_visibility Post visibility data + * @var array author_ary Array of user_id containing the users to filter the results to + * @since 3.1.7-RC1 + */ + $vars = array( + 'search_key_array', + 'type', + 'fields', + 'terms', + 'sort_days', + 'sort_key', + 'topic_id', + 'ex_fid_ary', + 'post_visibility', + 'author_ary', + ); + extract($this->phpbb_dispatcher->trigger_event('core.search_mysql_by_keyword_modify_search_key', compact($vars))); + + $search_key = md5(implode('#', $search_key_array)); if ($start < 0) { @@ -610,7 +642,7 @@ class fulltext_mysql extends \phpbb\search\base } // generate a search_key from all the options to identify the results - $search_key = md5(implode('#', array( + $search_key_array = array( '', $type, ($firstpost_only) ? 'firstpost' : '', @@ -623,7 +655,39 @@ class fulltext_mysql extends \phpbb\search\base $post_visibility, implode(',', $author_ary), $author_name, - ))); + ); + + /** + * Allow changing the search_key for cached results + * + * @event core.search_mysql_by_author_modify_search_key + * @var array search_key_array Array with search parameters to generate the search_key + * @var string type Searching type ('posts', 'topics') + * @var boolean firstpost_only Flag indicating if only topic starting posts are considered + * @var int sort_days Time, in days, of the oldest possible post to list + * @var string sort_key The sort type used from the possible sort types + * @var int topic_id Limit the search to this topic_id only + * @var array ex_fid_ary Which forums not to search on + * @var string post_visibility Post visibility data + * @var array author_ary Array of user_id containing the users to filter the results to + * @var string author_name The username to search on + * @since 3.1.7-RC1 + */ + $vars = array( + 'search_key_array', + 'type', + 'firstpost_only', + 'sort_days', + 'sort_key', + 'topic_id', + 'ex_fid_ary', + 'post_visibility', + 'author_ary', + 'author_name', + ); + extract($this->phpbb_dispatcher->trigger_event('core.search_mysql_by_author_modify_search_key', compact($vars))); + + $search_key = md5(implode('#', $search_key_array)); if ($start < 0) { diff --git a/phpBB/phpbb/search/fulltext_native.php b/phpBB/phpbb/search/fulltext_native.php index 02337cbf98..a02f889415 100644 --- a/phpBB/phpbb/search/fulltext_native.php +++ b/phpBB/phpbb/search/fulltext_native.php @@ -57,7 +57,7 @@ class fulltext_native extends \phpbb\search\base protected $must_not_contain_ids = array(); /** - * Post ids of posts containing atleast one word that needs to be excluded + * Post ids of posts containing at least one word that needs to be excluded * @var array */ protected $must_exclude_one_ids = array(); @@ -530,7 +530,7 @@ class fulltext_native extends \phpbb\search\base sort($must_exclude_one_ids); // generate a search_key from all the options to identify the results - $search_key = md5(implode('#', array( + $search_key_array = array( serialize($must_contain_ids), serialize($must_not_contain_ids), serialize($must_exclude_one_ids), @@ -544,7 +544,45 @@ class fulltext_native extends \phpbb\search\base $post_visibility, implode(',', $author_ary), $author_name, - ))); + ); + + /** + * Allow changing the search_key for cached results + * + * @event core.search_native_by_keyword_modify_search_key + * @var array search_key_array Array with search parameters to generate the search_key + * @var array must_contain_ids Array with post ids of posts containing words that are to be included + * @var array must_not_contain_ids Array with post ids of posts containing words that should not be included + * @var array must_exclude_one_ids Array with post ids of posts containing at least one word that needs to be excluded + * @var string type Searching type ('posts', 'topics') + * @var string fields Searching fields ('titleonly', 'msgonly', 'firstpost', 'all') + * @var string terms Searching terms ('all', 'any') + * @var int sort_days Time, in days, of the oldest possible post to list + * @var string sort_key The sort type used from the possible sort types + * @var int topic_id Limit the search to this topic_id only + * @var array ex_fid_ary Which forums not to search on + * @var string post_visibility Post visibility data + * @var array author_ary Array of user_id containing the users to filter the results to + * @since 3.1.7-RC1 + */ + $vars = array( + 'search_key_array', + 'must_contain_ids', + 'must_not_contain_ids', + 'must_exclude_one_ids', + 'type', + 'fields', + 'terms', + 'sort_days', + 'sort_key', + 'topic_id', + 'ex_fid_ary', + 'post_visibility', + 'author_ary', + ); + extract($this->phpbb_dispatcher->trigger_event('core.search_native_by_keyword_modify_search_key', compact($vars))); + + $search_key = md5(implode('#', $search_key_array)); // try reading the results from cache $total_results = 0; @@ -980,7 +1018,7 @@ class fulltext_native extends \phpbb\search\base } // generate a search_key from all the options to identify the results - $search_key = md5(implode('#', array( + $search_key_array = array( '', $type, ($firstpost_only) ? 'firstpost' : '', @@ -993,7 +1031,39 @@ class fulltext_native extends \phpbb\search\base $post_visibility, implode(',', $author_ary), $author_name, - ))); + ); + + /** + * Allow changing the search_key for cached results + * + * @event core.search_native_by_author_modify_search_key + * @var array search_key_array Array with search parameters to generate the search_key + * @var string type Searching type ('posts', 'topics') + * @var boolean firstpost_only Flag indicating if only topic starting posts are considered + * @var int sort_days Time, in days, of the oldest possible post to list + * @var string sort_key The sort type used from the possible sort types + * @var int topic_id Limit the search to this topic_id only + * @var array ex_fid_ary Which forums not to search on + * @var string post_visibility Post visibility data + * @var array author_ary Array of user_id containing the users to filter the results to + * @var string author_name The username to search on + * @since 3.1.7-RC1 + */ + $vars = array( + 'search_key_array', + 'type', + 'firstpost_only', + 'sort_days', + 'sort_key', + 'topic_id', + 'ex_fid_ary', + 'post_visibility', + 'author_ary', + 'author_name', + ); + extract($this->phpbb_dispatcher->trigger_event('core.search_native_by_author_modify_search_key', compact($vars))); + + $search_key = md5(implode('#', $search_key_array)); // try reading the results from cache $total_results = 0; diff --git a/phpBB/phpbb/search/fulltext_postgres.php b/phpBB/phpbb/search/fulltext_postgres.php index d17b26be8f..c2186b0df3 100644 --- a/phpBB/phpbb/search/fulltext_postgres.php +++ b/phpBB/phpbb/search/fulltext_postgres.php @@ -341,7 +341,7 @@ class fulltext_postgres extends \phpbb\search\base } // generate a search_key from all the options to identify the results - $search_key = md5(implode('#', array( + $search_key_array = array( implode(', ', $this->split_words), $type, $fields, @@ -352,7 +352,39 @@ class fulltext_postgres extends \phpbb\search\base implode(',', $ex_fid_ary), $post_visibility, implode(',', $author_ary) - ))); + ); + + /** + * Allow changing the search_key for cached results + * + * @event core.search_postgres_by_keyword_modify_search_key + * @var array search_key_array Array with search parameters to generate the search_key + * @var string type Searching type ('posts', 'topics') + * @var string fields Searching fields ('titleonly', 'msgonly', 'firstpost', 'all') + * @var string terms Searching terms ('all', 'any') + * @var int sort_days Time, in days, of the oldest possible post to list + * @var string sort_key The sort type used from the possible sort types + * @var int topic_id Limit the search to this topic_id only + * @var array ex_fid_ary Which forums not to search on + * @var string post_visibility Post visibility data + * @var array author_ary Array of user_id containing the users to filter the results to + * @since 3.1.7-RC1 + */ + $vars = array( + 'search_key_array', + 'type', + 'fields', + 'terms', + 'sort_days', + 'sort_key', + 'topic_id', + 'ex_fid_ary', + 'post_visibility', + 'author_ary', + ); + extract($this->phpbb_dispatcher->trigger_event('core.search_postgres_by_keyword_modify_search_key', compact($vars))); + + $search_key = md5(implode('#', $search_key_array)); if ($start < 0) { @@ -585,7 +617,7 @@ class fulltext_postgres extends \phpbb\search\base } // generate a search_key from all the options to identify the results - $search_key = md5(implode('#', array( + $search_key_array = array( '', $type, ($firstpost_only) ? 'firstpost' : '', @@ -598,7 +630,39 @@ class fulltext_postgres extends \phpbb\search\base $post_visibility, implode(',', $author_ary), $author_name, - ))); + ); + + /** + * Allow changing the search_key for cached results + * + * @event core.search_postgres_by_author_modify_search_key + * @var array search_key_array Array with search parameters to generate the search_key + * @var string type Searching type ('posts', 'topics') + * @var boolean firstpost_only Flag indicating if only topic starting posts are considered + * @var int sort_days Time, in days, of the oldest possible post to list + * @var string sort_key The sort type used from the possible sort types + * @var int topic_id Limit the search to this topic_id only + * @var array ex_fid_ary Which forums not to search on + * @var string post_visibility Post visibility data + * @var array author_ary Array of user_id containing the users to filter the results to + * @var string author_name The username to search on + * @since 3.1.7-RC1 + */ + $vars = array( + 'search_key_array', + 'type', + 'firstpost_only', + 'sort_days', + 'sort_key', + 'topic_id', + 'ex_fid_ary', + 'post_visibility', + 'author_ary', + 'author_name', + ); + extract($this->phpbb_dispatcher->trigger_event('core.search_postgres_by_author_modify_search_key', compact($vars))); + + $search_key = md5(implode('#', $search_key_array)); if ($start < 0) { diff --git a/phpBB/phpbb/search/fulltext_sphinx.php b/phpBB/phpbb/search/fulltext_sphinx.php index cd7add72f0..612ef8f1f3 100644 --- a/phpBB/phpbb/search/fulltext_sphinx.php +++ b/phpBB/phpbb/search/fulltext_sphinx.php @@ -358,6 +358,23 @@ class fulltext_sphinx $non_unique = array('sql_query_pre' => true, 'sql_attr_uint' => true, 'sql_attr_timestamp' => true, 'sql_attr_str2ordinal' => true, 'sql_attr_bool' => true); $delete = array('sql_group_column' => true, 'sql_date_column' => true, 'sql_str2ordinal_column' => true); + + /** + * Allow adding/changing the Sphinx configuration data + * + * @event core.search_sphinx_modify_config_data + * @var array config_data Array with the Sphinx configuration data + * @var array non_unique Array with the Sphinx non-unique variables to delete + * @var array delete Array with the Sphinx variables to delete + * @since 3.1.7-RC1 + */ + $vars = array( + 'config_data', + 'non_unique', + 'delete', + ); + extract($this->phpbb_dispatcher->trigger_event('core.search_sphinx_modify_config_data', compact($vars))); + foreach ($config_data as $section_name => $section_data) { $section = $config_object->get_section_by_name($section_name); @@ -531,6 +548,41 @@ class fulltext_sphinx $this->sphinx->SetFilter('topic_id', array($topic_id)); } + /** + * Allow modifying the Sphinx search options + * + * @event core.search_sphinx_keywords_modify_options + * @var string type Searching type ('posts', 'topics') + * @var string fields Searching fields ('titleonly', 'msgonly', 'firstpost', 'all') + * @var string terms Searching terms ('all', 'any') + * @var int sort_days Time, in days, of the oldest possible post to list + * @var string sort_key The sort type used from the possible sort types + * @var int topic_id Limit the search to this topic_id only + * @var array ex_fid_ary Which forums not to search on + * @var string post_visibility Post visibility data + * @var array author_ary Array of user_id containing the users to filter the results to + * @var string author_name The username to search on + * @var object sphinx The Sphinx searchd client object + * @since 3.1.7-RC1 + */ + $sphinx = $this->sphinx; + $vars = array( + 'type', + 'fields', + 'terms', + 'sort_days', + 'sort_key', + 'topic_id', + 'ex_fid_ary', + 'post_visibility', + 'author_ary', + 'author_name', + 'sphinx', + ); + extract($this->phpbb_dispatcher->trigger_event('core.search_sphinx_keywords_modify_options', compact($vars))); + $this->sphinx = $sphinx; + unset($sphinx); + $search_query_prefix = ''; switch ($fields) diff --git a/phpBB/posting.php b/phpBB/posting.php index 2bd3a1a1d2..5fcd427b2b 100644 --- a/phpBB/posting.php +++ b/phpBB/posting.php @@ -1027,7 +1027,8 @@ if ($submit || $preview || $refresh) $message_parser->bbcode_bitfield = $post_data['bbcode_bitfield']; } - if ($mode != 'edit' && !$preview && !$refresh && $config['flood_interval'] && !$auth->acl_get('f_ignoreflood', $forum_id)) + $ignore_flood = $auth->acl_get('u_ignoreflood') ? true : $auth->acl_get('f_ignoreflood', $forum_id); + if ($mode != 'edit' && !$preview && !$refresh && $config['flood_interval'] && !$ignore_flood) { // Flood check $last_post_time = 0; diff --git a/phpBB/search.php b/phpBB/search.php index d8f0bd1426..7469daa49c 100644 --- a/phpBB/search.php +++ b/phpBB/search.php @@ -427,6 +427,8 @@ if ($keywords || $author || $author_id || $search_id || $submit) gen_sort_selects($limit_days, $sort_by_text, $sort_days, $sort_key, $sort_dir, $s_limit_days, $s_sort_key, $s_sort_dir, $u_sort_param); $s_sort_key = $s_sort_dir = $u_sort_param = $s_limit_days = ''; + + $template->assign_var('U_MARK_ALL_READ', ($user->data['is_registered'] || $config['load_anon_lastread']) ? append_sid("{$phpbb_root_path}index.$phpEx", 'hash=' . generate_link_hash('global') . '&mark=forums&mark_time=' . time()) : ''); break; case 'newposts': @@ -483,6 +485,24 @@ if ($keywords || $author || $author_id || $search_id || $submit) } } + /** + * Event to modify data after pre-made searches + * + * @event core.search_modify_param_after + * @var string l_search_title The title of the search page + * @var string search_id Predefined search type name + * @var string show_results Display topics or posts + * @var string sql SQL query corresponding to the pre-made search id + * @since 3.1.7-RC1 + */ + $vars = array( + 'l_search_title', + 'search_id', + 'show_results', + 'sql', + ); + extract($phpbb_dispatcher->trigger_event('core.search_modify_param_after', compact($vars))); + // show_results should not change after this $per_page = ($show_results == 'posts') ? $config['posts_per_page'] : $config['topics_per_page']; $total_match_count = 0; @@ -594,6 +614,20 @@ if ($keywords || $author || $author_id || $search_id || $submit) $u_search .= ($search_fields != 'all') ? '&sf=' . $search_fields : ''; $u_search .= ($return_chars != 300) ? '&ch=' . $return_chars : ''; + /** + * Event to add or modify search URL parameters + * + * @event core.search_modify_url_parameters + * @var string u_search Search URL parameters string + * @var string search_id Predefined search type name + * @since 3.1.7-RC1 + */ + $vars = array( + 'u_search', + 'search_id', + ); + extract($phpbb_dispatcher->trigger_event('core.search_modify_url_parameters', compact($vars))); + if ($sql_where) { if ($show_results == 'posts') @@ -704,6 +738,8 @@ if ($keywords || $author || $author_id || $search_id || $submit) $tracking_topics = ($tracking_topics) ? tracking_unserialize($tracking_topics) : array(); } + $sql_order_by = $sort_by_sql[$sort_key] . ' ' . (($sort_dir == 'd') ? 'DESC' : 'ASC'); + /** * Event to modify the SQL query before the topic data is retrieved * @@ -712,16 +748,30 @@ if ($keywords || $author || $author_id || $search_id || $submit) * @var string sql_from The SQL FROM string used by search to get topic data * @var string sql_where The SQL WHERE string used by search to get topic data * @var int total_match_count The total number of search matches + * @var array sort_by_sql Array of SQL sorting instructions + * @var string sort_dir The sorting direction + * @var string sort_key The sorting key + * @var string sql_order_by The SQL ORDER BY string used by search to get topic data * @since 3.1.0-a1 * @changed 3.1.0-RC5 Added total_match_count + * @changed 3.1.7-RC1 Added sort_by_sql, sort_dir, sort_key, sql_order_by */ - $vars = array('sql_select', 'sql_from', 'sql_where', 'total_match_count'); + $vars = array( + 'sql_select', + 'sql_from', + 'sql_where', + 'total_match_count', + 'sort_by_sql', + 'sort_dir', + 'sort_key', + 'sql_order_by', + ); extract($phpbb_dispatcher->trigger_event('core.search_get_topic_data', compact($vars))); $sql = "SELECT $sql_select FROM $sql_from - WHERE $sql_where"; - $sql .= ' ORDER BY ' . $sort_by_sql[$sort_key] . ' ' . (($sort_dir == 'd') ? 'DESC' : 'ASC'); + WHERE $sql_where + ORDER BY $sql_order_by"; } $result = $db->sql_query($sql); $result_topic_id = 0; diff --git a/phpBB/styles/prosilver/template/ajax.js b/phpBB/styles/prosilver/template/ajax.js index 76c605dd19..e3780f024a 100644 --- a/phpBB/styles/prosilver/template/ajax.js +++ b/phpBB/styles/prosilver/template/ajax.js @@ -242,7 +242,14 @@ phpbb.addAjaxCallback('vote_poll', function(res) { var mostVoted = (res.vote_counts[optionId] === mostVotes); var percent = (!res.total_votes) ? 0 : Math.round((res.vote_counts[optionId] / res.total_votes) * 100); var percentRel = (mostVotes === 0) ? 0 : Math.round((res.vote_counts[optionId] / mostVotes) * 100); - + var altText; + + altText = $this.attr('data-alt-text'); + if (voted) { + $this.attr('title', $.trim(altText)); + } else { + $this.attr('title', ''); + }; $this.toggleClass('voted', voted); $this.toggleClass('most-votes', mostVoted); diff --git a/phpBB/styles/prosilver/template/forum_fn.js b/phpBB/styles/prosilver/template/forum_fn.js index 8e5b257ba4..99f3108fad 100644 --- a/phpBB/styles/prosilver/template/forum_fn.js +++ b/phpBB/styles/prosilver/template/forum_fn.js @@ -159,7 +159,10 @@ function selectCode(a) { try { s.setBaseAndExtent(e, 0, e, l); } catch (error) { - s.setBaseAndExtent(e, 0, e, 1); + r = document.createRange(); + r.selectNodeContents(e); + s.removeAllRanges(); + s.addRange(r); } } // Firefox and Opera diff --git a/phpBB/styles/prosilver/template/mcp_post.html b/phpBB/styles/prosilver/template/mcp_post.html index 81d1be795e..e5777d206a 100644 --- a/phpBB/styles/prosilver/template/mcp_post.html +++ b/phpBB/styles/prosilver/template/mcp_post.html @@ -91,9 +91,9 @@ <form method="post" id="mcp_approve" action="{U_APPROVE_ACTION}"> <p class="post-notice deleted"> - <input class="button2" type="submit" value="{L_DELETE}" name="action[disapprove]" /> + <!-- IF S_CAN_DELETE_POST --><input class="button2" type="submit" value="{L_DELETE}" name="action[delete]" /> <!-- ENDIF --> <input class="button1" type="submit" value="{L_RESTORE}" name="action[restore]" /> - <!-- IF not S_FIRST_POST --><input type="hidden" name="mode" value="unapproved_posts" /><!-- ENDIF --> + <!-- IF not S_FIRST_POST --><input type="hidden" name="mode" value="deleted_posts" /><!-- ENDIF --> <input type="hidden" name="post_id_list[]" value="{POST_ID}" /> {S_FORM_TOKEN} </p> diff --git a/phpBB/styles/prosilver/template/memberlist_body.html b/phpBB/styles/prosilver/template/memberlist_body.html index 414569019e..e0215848d0 100644 --- a/phpBB/styles/prosilver/template/memberlist_body.html +++ b/phpBB/styles/prosilver/template/memberlist_body.html @@ -101,8 +101,8 @@ <!-- ENDIF --> <!-- ENDIF --> - <tr class="<!-- IF memberrow.S_ROW_COUNT is even -->bg1<!-- ELSE -->bg2<!-- ENDIF -->"> - <td><span class="rank-img"><!-- EVENT memberlist_body_rank_prepend --><!-- IF memberrow.RANK_IMG -->{memberrow.RANK_IMG}<!-- ELSE -->{memberrow.RANK_TITLE}<!-- ENDIF --><!-- EVENT memberlist_body_rank_append --></span><!-- IF S_IN_SEARCH_POPUP and not S_SELECT_SINGLE --><input type="checkbox" name="user" value="{memberrow.USERNAME}" /> <!-- ENDIF --><!-- EVENT memberlist_body_username_prepend -->{memberrow.USERNAME_FULL}<!-- EVENT memberlist_body_username_append --><!-- IF S_IN_SEARCH_POPUP --><br />[ <a href="#" onclick="insert_single_user('#results', '{memberrow.A_USERNAME}'); return false;">{L_SELECT}</a> ]<!-- ENDIF --></td> + <tr class="<!-- IF memberrow.S_ROW_COUNT is even -->bg1<!-- ELSE -->bg2<!-- ENDIF --><!-- IF memberrow.S_INACTIVE --> inactive<!-- ENDIF -->"> + <td><span class="rank-img"><!-- EVENT memberlist_body_rank_prepend --><!-- IF memberrow.RANK_IMG -->{memberrow.RANK_IMG}<!-- ELSE -->{memberrow.RANK_TITLE}<!-- ENDIF --><!-- EVENT memberlist_body_rank_append --></span><!-- IF S_IN_SEARCH_POPUP and not S_SELECT_SINGLE --><input type="checkbox" name="user" value="{memberrow.USERNAME}" /> <!-- ENDIF --><!-- EVENT memberlist_body_username_prepend -->{memberrow.USERNAME_FULL}<!-- IF memberrow.S_INACTIVE --> ({L_INACTIVE})<!-- ENDIF --><!-- EVENT memberlist_body_username_append --><!-- IF S_IN_SEARCH_POPUP --><br />[ <a href="#" onclick="insert_single_user('#results', '{memberrow.A_USERNAME}'); return false;">{L_SELECT}</a> ]<!-- ENDIF --></td> <td class="posts"><!-- IF memberrow.POSTS and S_DISPLAY_SEARCH --><a href="{memberrow.U_SEARCH_USER}" title="{L_SEARCH_USER_POSTS}">{memberrow.POSTS}</a><!-- ELSE -->{memberrow.POSTS}<!-- ENDIF --></td> <td class="info"><!-- BEGIN custom_fields --><div>{memberrow.custom_fields.PROFILE_FIELD_VALUE}</div><!-- BEGINELSE --> <!-- END custom_fields --></td> <td>{memberrow.JOINED}</td> diff --git a/phpBB/styles/prosilver/template/memberlist_team.html b/phpBB/styles/prosilver/template/memberlist_team.html index fd2ba564d3..b7f2d66d94 100644 --- a/phpBB/styles/prosilver/template/memberlist_team.html +++ b/phpBB/styles/prosilver/template/memberlist_team.html @@ -8,7 +8,7 @@ <div class="forumbg forumbg-table"> <div class="inner"> - <table class="table1"> + <table class="table1" id="team"> <thead> <tr> <th class="name" data-dfn="{L_RANK}{L_COMMA_SEPARATOR}{L_USERNAME}"><span class="rank-img">{L_RANK} </span><!-- IF group.U_GROUP --><a href="{group.U_GROUP}">{group.GROUP_NAME}</a><!-- ELSE -->{group.GROUP_NAME}<!-- ENDIF --></th> @@ -18,8 +18,8 @@ </thead> <tbody> <!-- BEGIN user --> - <tr class="<!-- IF group.user.S_ROW_COUNT is even -->bg1<!-- ELSE -->bg2<!-- ENDIF -->"> - <td><!-- IF group.user.RANK_IMG --><span class="rank-img">{group.user.RANK_IMG}</span><!-- ELSE --><span class="rank-img">{group.user.RANK_TITLE}</span><!-- ENDIF -->{group.user.USERNAME_FULL}</td> + <tr class="<!-- IF group.user.S_ROW_COUNT is even -->bg1<!-- ELSE -->bg2<!-- ENDIF --><!-- IF group.user.S_INACTIVE --> inactive<!-- ENDIF -->"> + <td><!-- IF group.user.RANK_IMG --><span class="rank-img">{group.user.RANK_IMG}</span><!-- ELSE --><span class="rank-img">{group.user.RANK_TITLE}</span><!-- ENDIF -->{group.user.USERNAME_FULL}<!-- IF group.user.S_INACTIVE --> ({L_INACTIVE})<!-- ENDIF --></td> <td class="info"><!-- IF group.user.U_GROUP --> <a<!-- IF group.user.GROUP_COLOR --> style="font-weight: bold; color: #{group.user.GROUP_COLOR}"<!-- ENDIF --> href="{group.user.U_GROUP}">{group.user.GROUP_NAME}</a> <!-- ELSE --> diff --git a/phpBB/styles/prosilver/template/quickreply_editor.html b/phpBB/styles/prosilver/template/quickreply_editor.html index 6a8846626e..ca8ccc0a6b 100644 --- a/phpBB/styles/prosilver/template/quickreply_editor.html +++ b/phpBB/styles/prosilver/template/quickreply_editor.html @@ -4,6 +4,7 @@ <div class="inner"> <h2 class="quickreply-title">{L_QUICKREPLY}</h2> <fieldset class="fields1"> + <!-- EVENT quickreply_editor_subject_before --> <dl style="clear: left;"> <dt><label for="subject">{L_SUBJECT}{L_COLON}</label></dt> <dd><input type="text" name="subject" id="subject" size="45" maxlength="124" tabindex="2" value="{SUBJECT}" class="inputbox autowidth" /></dd> diff --git a/phpBB/styles/prosilver/template/search_results.html b/phpBB/styles/prosilver/template/search_results.html index f76afe3767..57d80bd804 100644 --- a/phpBB/styles/prosilver/template/search_results.html +++ b/phpBB/styles/prosilver/template/search_results.html @@ -33,6 +33,7 @@ <!-- EVENT search_results_searchbox_after --> <div class="pagination"> + <!-- IF U_MARK_ALL_READ --><a href="{U_MARK_ALL_READ}" class="mark-read" accesskey="m">{L_MARK_ALL_READ}</a> •<!-- ENDIF --> {SEARCH_MATCHES} <!-- IF .pagination --> <!-- INCLUDE pagination.html --> diff --git a/phpBB/styles/prosilver/template/ucp_avatar_options_local.html b/phpBB/styles/prosilver/template/ucp_avatar_options_local.html index 2a0f403782..80c7f28ca3 100644 --- a/phpBB/styles/prosilver/template/ucp_avatar_options_local.html +++ b/phpBB/styles/prosilver/template/ucp_avatar_options_local.html @@ -10,7 +10,8 @@ <!-- BEGIN avatar_local_row --> <!-- BEGIN avatar_local_col --> <label for="av-{avatar_local_row.S_ROW_COUNT}-{avatar_local_row.avatar_local_col.S_ROW_COUNT}"><img src="{avatar_local_row.avatar_local_col.AVATAR_IMAGE}" alt="" /><br /> - <input type="radio" name="avatar_local_file" id="av-{avatar_local_row.S_ROW_COUNT}-{avatar_local_row.avatar_local_col.S_ROW_COUNT}" value="{avatar_local_row.avatar_local_col.AVATAR_FILE}" /></label> + <input type="radio" name="avatar_local_file" id="av-{avatar_local_row.S_ROW_COUNT}-{avatar_local_row.avatar_local_col.S_ROW_COUNT}" + value="{avatar_local_row.avatar_local_col.AVATAR_FILE}"<!-- IF avatar_local_row.avatar_local_col.CHECKED --> checked="checked"<!-- ENDIF --> /></label> <!-- END avatar_local_col --> <!-- END avatar_local_row --> </div> diff --git a/phpBB/styles/prosilver/template/ucp_register.html b/phpBB/styles/prosilver/template/ucp_register.html index fafd0cce00..655c0fc48c 100644 --- a/phpBB/styles/prosilver/template/ucp_register.html +++ b/phpBB/styles/prosilver/template/ucp_register.html @@ -14,7 +14,7 @@ // ]]> </script> -<form method="post" action="{S_UCP_ACTION}" id="register"> +<form id="register" method="post" action="{S_UCP_ACTION}"{S_FORM_ENCTYPE}> <div class="panel"> <div class="inner"> diff --git a/phpBB/styles/prosilver/template/viewforum_body.html b/phpBB/styles/prosilver/template/viewforum_body.html index 2679a2cd29..087cf668cf 100644 --- a/phpBB/styles/prosilver/template/viewforum_body.html +++ b/phpBB/styles/prosilver/template/viewforum_body.html @@ -145,7 +145,9 @@ <ul class="topiclist topics"> <!-- ENDIF --> + <!-- EVENT viewforum_body_topic_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="icon {topicrow.TOPIC_IMG_STYLE}"> <dt<!-- IF topicrow.TOPIC_ICON_IMG and S_TOPIC_ICONS --> style="background-image: url({T_ICONS_PATH}{topicrow.TOPIC_ICON_IMG}); background-repeat: no-repeat;"<!-- ENDIF --> title="{topicrow.TOPIC_FOLDER_IMG_ALT}"> <!-- IF topicrow.S_UNREAD_TOPIC and not S_IS_BOT --><a href="{topicrow.U_NEWEST_POST}" class="icon-link"></a><!-- ENDIF --> @@ -195,7 +197,9 @@ <!-- IF not S_IS_BOT --><a href="{topicrow.U_LAST_POST}" title="{L_GOTO_LAST_POST}">{LAST_POST_IMG}</a> <!-- ENDIF --><br />{topicrow.LAST_POST_TIME}</span> </dd> </dl> + <!-- EVENT viewforum_body_topic_row_append --> </li> + <!-- EVENT viewforum_body_topic_row_after --> <!-- IF topicrow.S_LAST_ROW --> </ul> diff --git a/phpBB/styles/prosilver/template/viewtopic_body.html b/phpBB/styles/prosilver/template/viewtopic_body.html index b7506608d9..07215708a9 100644 --- a/phpBB/styles/prosilver/template/viewtopic_body.html +++ b/phpBB/styles/prosilver/template/viewtopic_body.html @@ -84,7 +84,7 @@ <fieldset class="polls"> <!-- BEGIN poll_option --> <!-- EVENT viewtopic_body_poll_option_before --> - <dl class="<!-- IF poll_option.POLL_OPTION_VOTED -->voted<!-- ENDIF --><!-- IF poll_option.POLL_OPTION_MOST_VOTES --> most-votes<!-- ENDIF -->"<!-- IF poll_option.POLL_OPTION_VOTED --> title="{L_POLL_VOTED_OPTION}"<!-- ENDIF --> data-poll-option-id="{poll_option.POLL_OPTION_ID}"> + <dl class="<!-- IF poll_option.POLL_OPTION_VOTED -->voted<!-- ENDIF --><!-- IF poll_option.POLL_OPTION_MOST_VOTES --> most-votes<!-- ENDIF -->"<!-- IF poll_option.POLL_OPTION_VOTED --> title="{L_POLL_VOTED_OPTION}"<!-- ENDIF --> data-alt-text="{L_POLL_VOTED_OPTION}" data-poll-option-id="{poll_option.POLL_OPTION_ID}"> <dt><!-- IF S_CAN_VOTE --><label for="vote_{poll_option.POLL_OPTION_ID}">{poll_option.POLL_OPTION_CAPTION}</label><!-- ELSE -->{poll_option.POLL_OPTION_CAPTION}<!-- ENDIF --></dt> <!-- IF S_CAN_VOTE --><dd style="width: auto;" class="poll_option_select"><!-- IF S_IS_MULTI_CHOICE --><input type="checkbox" name="vote_id[]" id="vote_{poll_option.POLL_OPTION_ID}" value="{poll_option.POLL_OPTION_ID}"<!-- IF poll_option.POLL_OPTION_VOTED --> checked="checked"<!-- ENDIF --> /><!-- ELSE --><input type="radio" name="vote_id[]" id="vote_{poll_option.POLL_OPTION_ID}" value="{poll_option.POLL_OPTION_ID}"<!-- IF poll_option.POLL_OPTION_VOTED --> checked="checked"<!-- ENDIF --> /><!-- ENDIF --></dd><!-- ENDIF --> <dd class="resultbar<!-- IF not S_DISPLAY_RESULTS --> hidden<!-- ENDIF -->"><div class="<!-- IF poll_option.POLL_OPTION_PCT < 20 -->pollbar1<!-- ELSEIF poll_option.POLL_OPTION_PCT < 40 -->pollbar2<!-- ELSEIF poll_option.POLL_OPTION_PCT < 60 -->pollbar3<!-- ELSEIF poll_option.POLL_OPTION_PCT < 80 -->pollbar4<!-- ELSE -->pollbar5<!-- ENDIF -->" style="width:{poll_option.POLL_OPTION_PERCENT_REL};">{poll_option.POLL_OPTION_RESULT}</div></dd> @@ -278,7 +278,9 @@ <form method="post" class="mcp_approve" action="{postrow.U_APPROVE_ACTION}"> <p class="post-notice deleted"> <strong>{L_POST_DELETED_ACTION}</strong> - <input class="button2" type="submit" value="{L_DELETE}" name="action[disapprove]" /> + <!-- IF postrow.S_DELETE_PERMANENT --> + <input class="button2" type="submit" value="{L_DELETE}" name="action[delete]" /> + <!-- ENDIF --> <input class="button1" type="submit" value="{L_RESTORE}" name="action[restore]" /> <input type="hidden" name="post_id_list[]" value="{postrow.POST_ID}" /> {S_FORM_TOKEN} diff --git a/phpBB/styles/prosilver/theme/content.css b/phpBB/styles/prosilver/theme/content.css index 380b285b83..92a7db81d9 100644 --- a/phpBB/styles/prosilver/theme/content.css +++ b/phpBB/styles/prosilver/theme/content.css @@ -672,7 +672,7 @@ fieldset.polls dd div { text-align: right; font-family: Arial, Helvetica, sans-serif; font-weight: bold; - padding: 0 2px; + padding: 2px 2px 0 2px; overflow: visible; min-width: 8px; } @@ -842,3 +842,7 @@ table.fixed-width-table { background: rgba(0, 0, 0, .3); border-radius: 3px; } + +#memberlist tr.inactive, #team tr.inactive { + font-style: italic; +} diff --git a/phpBB/styles/prosilver/theme/plupload.css b/phpBB/styles/prosilver/theme/plupload.css index 7d4092c3fe..b17cca5f25 100644 --- a/phpBB/styles/prosilver/theme/plupload.css +++ b/phpBB/styles/prosilver/theme/plupload.css @@ -15,6 +15,11 @@ width: 30%; } +.attach-comment .inputbox { + resize: vertical; + width: 100%; +} + .attach-filesize { width: 15%; } diff --git a/phpBB/styles/subsilver2/template/memberlist_body.html b/phpBB/styles/subsilver2/template/memberlist_body.html index 79b78f32a4..9044896bca 100644 --- a/phpBB/styles/subsilver2/template/memberlist_body.html +++ b/phpBB/styles/subsilver2/template/memberlist_body.html @@ -64,7 +64,7 @@ <!-- IF memberrow.S_ROW_COUNT is even --><tr class="row2"><!-- ELSE --> <tr class="row1"><!-- ENDIF --> <td class="gen" align="center"> {memberrow.ROW_NUMBER} </td> - <td class="genmed" align="{S_CONTENT_FLOW_BEGIN}"><!-- EVENT memberlist_body_username_prepend -->{memberrow.USERNAME_FULL}<!-- EVENT memberlist_body_username_append --><!-- IF S_SELECT_SINGLE --> [ <a href="#" onclick="insert_single('{memberrow.A_USERNAME}'); return false;">{L_SELECT}</a> ]<!-- ENDIF --></td> + <td class="genmed" align="{S_CONTENT_FLOW_BEGIN}"><!-- EVENT memberlist_body_username_prepend -->{memberrow.USERNAME_FULL}<!-- IF memberrow.S_INACTIVE --> <em>({L_INACTIVE})</em><!-- ENDIF --><!-- EVENT memberlist_body_username_append --><!-- IF S_SELECT_SINGLE --> [ <a href="#" onclick="insert_single('{memberrow.A_USERNAME}'); return false;">{L_SELECT}</a> ]<!-- ENDIF --></td> <td class="genmed" align="center" nowrap="nowrap"> {memberrow.JOINED} </td> <td class="gen" align="center">{memberrow.POSTS}</td> <td class="gen" align="center"><!-- EVENT memberlist_body_rank_prepend --><!-- IF memberrow.RANK_IMG -->{memberrow.RANK_IMG}<!-- ELSE -->{memberrow.RANK_TITLE}<!-- ENDIF --><!-- EVENT memberlist_body_rank_append --></td> diff --git a/phpBB/styles/subsilver2/template/memberlist_team.html b/phpBB/styles/subsilver2/template/memberlist_team.html index a4f38aafc4..18995b6e50 100644 --- a/phpBB/styles/subsilver2/template/memberlist_team.html +++ b/phpBB/styles/subsilver2/template/memberlist_team.html @@ -17,7 +17,7 @@ <!-- BEGIN user --> <!-- IF group.user.S_ROW_COUNT is even --><tr class="row2"><!-- ELSE --><tr class="row1"><!-- ENDIF --> - <td class="gen" align="center"><strong>{group.user.USERNAME_FULL}</strong></td> + <td class="gen" align="center"><strong>{group.user.USERNAME_FULL}</strong><!-- IF group.user.S_INACTIVE --> <em>({L_INACTIVE})</em><!-- ENDIF --></td> <!-- IF S_DISPLAY_MODERATOR_FORUMS --><td class="gensmall" align="center"><!-- IF group.user.FORUM_OPTIONS --><select style="width: 100%;">{group.user.FORUMS}</select><!-- ELSEIF group.user.FORUMS -->{group.user.FORUMS}<!-- ELSE -->-<!-- ENDIF --></td><!-- ENDIF --> <td class="gensmall" align="center" nowrap="nowrap"> <!-- IF group.user.U_GROUP --> diff --git a/phpBB/styles/subsilver2/template/quickreply_editor.html b/phpBB/styles/subsilver2/template/quickreply_editor.html index 5afc723f48..a7614e841f 100644 --- a/phpBB/styles/subsilver2/template/quickreply_editor.html +++ b/phpBB/styles/subsilver2/template/quickreply_editor.html @@ -4,6 +4,7 @@ <tr> <th align="center" colspan="2">{L_QUICKREPLY}</th> </tr> + <!-- EVENT quickreply_editor_subject_before --> <tr> <td class="row1" width="22%"><b class="genmed">{L_SUBJECT}{L_COLON}</b></td> <td class="row2" width="78%"><input class="post" style="width:450px" type="text" name="subject" size="45" maxlength="124" tabindex="2" value="{SUBJECT}" /></td> diff --git a/phpBB/styles/subsilver2/template/ucp_avatar_options_local.html b/phpBB/styles/subsilver2/template/ucp_avatar_options_local.html index 919cf49e44..921126ba22 100644 --- a/phpBB/styles/subsilver2/template/ucp_avatar_options_local.html +++ b/phpBB/styles/subsilver2/template/ucp_avatar_options_local.html @@ -19,7 +19,11 @@ </tr> <tr> <!-- BEGIN avatar_local_option --> - <td class="row2" align="center"><input type="radio" class="radio" name="avatar_local_file" id="av-{avatar_local_row.S_ROW_COUNT}-{avatar_local_row.avatar_local_col.S_ROW_COUNT}" value="{avatar_local_row.avatar_local_option.S_OPTIONS_AVATAR}" /></td> + <td class="row2" align="center"><input type="radio" class="radio" name="avatar_local_file" + id="av-{avatar_local_row.S_ROW_COUNT}-{avatar_local_row.avatar_local_col.S_ROW_COUNT}" + value="{avatar_local_row.avatar_local_option.S_OPTIONS_AVATAR}" + <!-- IF avatar_local_row.avatar_local_option.CHECKED --> checked="checked"<!-- ENDIF --> /> + </td> <!-- END avatar_local_option --> </tr> <!-- BEGINELSE --> diff --git a/phpBB/styles/subsilver2/template/viewforum_body.html b/phpBB/styles/subsilver2/template/viewforum_body.html index 83b01b9f6d..ff16b62fd3 100644 --- a/phpBB/styles/subsilver2/template/viewforum_body.html +++ b/phpBB/styles/subsilver2/template/viewforum_body.html @@ -34,7 +34,9 @@ <!-- BEGIN topicrow --> + <!-- EVENT viewforum_body_topic_row_before --> <tr> + <!-- EVENT viewforum_body_topic_row_prepend --> <td class="row1" width="25" align="center">{topicrow.TOPIC_FOLDER_IMG}</td> <!-- IF S_TOPIC_ICONS --> <td class="row1" width="25" align="center"><!-- IF topicrow.TOPIC_ICON_IMG --><img src="{T_ICONS_PATH}{topicrow.TOPIC_ICON_IMG}" width="{topicrow.TOPIC_ICON_IMG_WIDTH}" height="{topicrow.TOPIC_ICON_IMG_HEIGHT}" alt="" title="" /><!-- ENDIF --></td> @@ -75,7 +77,9 @@ <!-- IF not S_IS_BOT --><a href="{topicrow.U_LAST_POST}" class="imageset">{LAST_POST_IMG}</a><!-- ENDIF --> </p> </td> + <!-- EVENT viewforum_body_topic_row_append --> </tr> + <!-- EVENT viewforum_body_topic_row_after --> <!-- BEGINELSE --> diff --git a/phpBB/viewonline.php b/phpBB/viewonline.php index 583e297682..87848f4485 100644 --- a/phpBB/viewonline.php +++ b/phpBB/viewonline.php @@ -187,7 +187,7 @@ while ($row = $db->sql_fetchrow($result)) if (!$row['session_viewonline']) { - $view_online = ($auth->acl_get('u_viewonline')) ? true : false; + $view_online = ($auth->acl_get('u_viewonline') || $row['user_id'] === $user->data['user_id']) ? true : false; $logged_hidden_online++; $username_full = '<em>' . $username_full . '</em>'; diff --git a/phpBB/viewtopic.php b/phpBB/viewtopic.php index 26524283e1..4220eabe06 100644 --- a/phpBB/viewtopic.php +++ b/phpBB/viewtopic.php @@ -1826,6 +1826,12 @@ for ($i = 0, $end = sizeof($post_list); $i < $end; ++$i) (!$s_cannot_delete && !$s_cannot_delete_lastpost && !$s_cannot_delete_time && !$s_cannot_delete_locked) )); + $softdelete_allowed = ($auth->acl_get('m_softdelete', $forum_id) || + ($auth->acl_get('f_softdelete', $forum_id) && $user->data['user_id'] == $poster_id)) && ($row['post_visibility'] != ITEM_DELETED); + + $permanent_delete_allowed = ($auth->acl_get('m_delete', $forum_id) || + ($auth->acl_get('f_delete', $forum_id) && $user->data['user_id'] == $poster_id)); + // Can this user receive a Private Message? $can_receive_pm = ( // They must be a "normal" user @@ -1888,7 +1894,7 @@ for ($i = 0, $end = sizeof($post_list); $i < $end; ++$i) 'U_EDIT' => ($edit_allowed) ? append_sid("{$phpbb_root_path}posting.$phpEx", "mode=edit&f=$forum_id&p={$row['post_id']}") : '', 'U_QUOTE' => ($quote_allowed) ? append_sid("{$phpbb_root_path}posting.$phpEx", "mode=quote&f=$forum_id&p={$row['post_id']}") : '', 'U_INFO' => ($auth->acl_get('m_info', $forum_id)) ? append_sid("{$phpbb_root_path}mcp.$phpEx", "i=main&mode=post_details&f=$forum_id&p=" . $row['post_id'], true, $user->session_id) : '', - 'U_DELETE' => ($delete_allowed) ? append_sid("{$phpbb_root_path}posting.$phpEx", "mode=delete&f=$forum_id&p={$row['post_id']}") : '', + 'U_DELETE' => ($delete_allowed) ? append_sid("{$phpbb_root_path}posting.$phpEx", 'mode=' . (($softdelete_allowed) ? 'soft_delete' : 'delete') . "&f=$forum_id&p={$row['post_id']}") : '', 'U_SEARCH' => $user_cache[$poster_id]['search'], 'U_PM' => $u_pm, @@ -1927,6 +1933,7 @@ for ($i = 0, $end = sizeof($post_list); $i < $end; ++$i) 'L_IGNORE_POST' => ($row['foe']) ? sprintf($user->lang['POST_BY_FOE'], get_username_string('full', $poster_id, $row['username'], $row['user_colour'], $row['post_username'])) : '', 'S_POST_HIDDEN' => $row['hide_post'], 'L_POST_DISPLAY' => ($row['hide_post']) ? $user->lang('POST_DISPLAY', '<a class="display_post" data-post-id="' . $row['post_id'] . '" href="' . $viewtopic_url . "&p={$row['post_id']}&view=show#p{$row['post_id']}" . '">', '</a>') : '', + 'S_DELETE_PERMANENT' => $permanent_delete_allowed, ); $user_poster_data = $user_cache[$poster_id]; diff --git a/travis/setup-php-extensions.sh b/travis/setup-php-extensions.sh index c0defe44ef..d9544858b7 100755 --- a/travis/setup-php-extensions.sh +++ b/travis/setup-php-extensions.sh @@ -48,6 +48,9 @@ then echo 'Enabling APC PHP extension' register_php_extension 'apc' "$php_ini_file" echo 'apc.enable_cli=1' >> "$php_ini_file" +else + echo 'Disabling Opcache' + echo 'opcache.enable=0' >> "$php_ini_file" fi # redis |