diff options
Diffstat (limited to 'phpBB')
72 files changed, 969 insertions, 263 deletions
diff --git a/phpBB/adm/style/acp_database.html b/phpBB/adm/style/acp_database.html index ed0f4dd453..cc0b57b411 100644 --- a/phpBB/adm/style/acp_database.html +++ b/phpBB/adm/style/acp_database.html @@ -68,12 +68,6 @@ <!-- END methods --></dd> </dl> <dl> - <dt><label for="where">{L_ACTION}{L_COLON}</label></dt> - <dd> - <label><input id="where" type="radio" class="radio" name="where" value="store" checked="checked" /> {L_STORE_LOCAL}</label> - </dd> - </dl> - <dl> <dt><label for="table">{L_TABLE_SELECT}{L_COLON}</label></dt> <dd><select id="table" name="table[]" size="10" multiple="multiple"> <!-- BEGIN tables --> diff --git a/phpBB/adm/style/acp_groups.html b/phpBB/adm/style/acp_groups.html index 8eec3b63c6..8651b63b7f 100644 --- a/phpBB/adm/style/acp_groups.html +++ b/phpBB/adm/style/acp_groups.html @@ -36,10 +36,12 @@ <dl> <dt><label for="group_type">{L_GROUP_TYPE}{L_COLON}</label><br /><span>{L_GROUP_TYPE_EXPLAIN}</span></dt> <dd> + {% EVENT acp_group_types_prepend %} <label><input name="group_type" type="radio" class="radio" id="group_type" value="{GROUP_TYPE_FREE}"{GROUP_FREE} /> {L_GROUP_OPEN}</label> <label><input name="group_type" type="radio" class="radio" value="{GROUP_TYPE_OPEN}"{GROUP_OPEN} /> {L_GROUP_REQUEST}</label> <label><input name="group_type" type="radio" class="radio" value="{GROUP_TYPE_CLOSED}"{GROUP_CLOSED} /> {L_GROUP_CLOSED}</label> <label><input name="group_type" type="radio" class="radio" value="{GROUP_TYPE_HIDDEN}"{GROUP_HIDDEN} /> {L_GROUP_HIDDEN}</label> + {% EVENT acp_group_types_append %} </dd> </dl> <!-- ELSE --> diff --git a/phpBB/adm/style/acp_posting_buttons.html b/phpBB/adm/style/acp_posting_buttons.html index c3c42f8e82..36fc285537 100644 --- a/phpBB/adm/style/acp_posting_buttons.html +++ b/phpBB/adm/style/acp_posting_buttons.html @@ -5,27 +5,6 @@ var bbcode = new Array(); var bbtags = new Array('[b]','[/b]','[i]','[/i]','[u]','[/u]','[quote]','[/quote]','[code]','[/code]','[list]','[/list]','[list=]','[/list]','[img]','[/img]','[url]','[/url]','[flash=]', '[/flash]','[size=]','[/size]'<!-- BEGIN custom_tags -->, {custom_tags.BBCODE_NAME}<!-- END custom_tags -->); - // Helpline messages - var help_line = { - b: '{LA_BBCODE_B_HELP}', - i: '{LA_BBCODE_I_HELP}', - u: '{LA_BBCODE_U_HELP}', - q: '{LA_BBCODE_Q_HELP}', - c: '{LA_BBCODE_C_HELP}', - l: '{LA_BBCODE_L_HELP}', - o: '{LA_BBCODE_O_HELP}', - p: '{LA_BBCODE_P_HELP}', - w: '{LA_BBCODE_W_HELP}', - a: '{LA_BBCODE_A_HELP}', - s: '{LA_BBCODE_S_HELP}', - f: '{LA_BBCODE_F_HELP}', - y: '{LA_BBCODE_Y_HELP}', - d: '{LA_BBCODE_D_HELP}' - <!-- BEGIN custom_tags --> - ,cb_{custom_tags.BBCODE_ID}{L_COLON} '{custom_tags.A_BBCODE_HELPLINE}' - <!-- END custom_tags --> - } - // ]]> </script> @@ -65,7 +44,7 @@ </select> <!-- EVENT acp_posting_buttons_custom_tags_before --> <!-- BEGIN custom_tags --> - <input type="button" class="button2" name="addbbcode{custom_tags.BBCODE_ID}" value="{custom_tags.BBCODE_TAG}" onclick="bbstyle({custom_tags.BBCODE_ID})" title="{custom_tags.BBCODE_HELPLINE}" /> + <input type="button" class="button2" name="addbbcode{custom_tags.BBCODE_ID}" value="{custom_tags.BBCODE_TAG}" onclick="bbstyle({custom_tags.BBCODE_ID})" title="{{ custom_tags.BBCODE_HELPLINE|e('html_attr') }}" /> <!-- END custom_tags --> </div> <!-- EVENT acp_posting_buttons_after --> diff --git a/phpBB/adm/style/acp_styles.html b/phpBB/adm/style/acp_styles.html index b9c3925eca..c09294beaf 100644 --- a/phpBB/adm/style/acp_styles.html +++ b/phpBB/adm/style/acp_styles.html @@ -146,7 +146,9 @@ {styles_list.EXTRA} <td class="{$ROW_CLASS} mark" width="20"> <!-- IF styles_list.STYLE_ID --> - <input class="checkbox" type="checkbox" name="ids[]" value="{styles_list.STYLE_ID}" /> + {% if styles_list.STYLE_NAME !== 'prosilver' %} + <input class="checkbox" type="checkbox" name="ids[]" value="{styles_list.STYLE_ID}" /> + {% endif %} <!-- ELSE --> <!-- IF styles_list.COMMENT != '' --> diff --git a/phpBB/adm/style/captcha_recaptcha.html b/phpBB/adm/style/captcha_recaptcha.html index 3f61c76cb1..563bd98835 100644 --- a/phpBB/adm/style/captcha_recaptcha.html +++ b/phpBB/adm/style/captcha_recaptcha.html @@ -5,8 +5,9 @@ <div>{L_RECAPTCHA_NOSCRIPT}</div> </noscript> + {L_RECAPTCHA_INVISIBLE} <script src="{RECAPTCHA_SERVER}.js?hl={LA_RECAPTCHA_LANG}" async defer></script> - <div class="g-recaptcha" data-sitekey="{RECAPTCHA_PUBKEY}"></div> + <div class="g-recaptcha" data-sitekey="{RECAPTCHA_PUBKEY}" data-size="invisible"></div> </dd> </dl> <!-- ELSE --> diff --git a/phpBB/adm/style/installer_footer.html b/phpBB/adm/style/installer_footer.html index fefa8f6d3f..54e6951a12 100644 --- a/phpBB/adm/style/installer_footer.html +++ b/phpBB/adm/style/installer_footer.html @@ -6,7 +6,9 @@ <div id="page-footer"> <div class="copyright"> - Powered by <a href="https://www.phpbb.com/">phpBB</a>® Forum Software © phpBB Limited + {% if S_COPYRIGHT_HTML %} + {{ CREDIT_LINE }} + {% endif %} </div> </div> </div> diff --git a/phpBB/adm/style/permission_mask.html b/phpBB/adm/style/permission_mask.html index c556664b8c..23294d60df 100644 --- a/phpBB/adm/style/permission_mask.html +++ b/phpBB/adm/style/permission_mask.html @@ -9,6 +9,8 @@ var role_options = new Array(); + var no_role_assigned = "{LA_NO_ROLE_ASSIGNED}"; + <!-- IF S_ROLE_JS_ARRAY --> {S_ROLE_JS_ARRAY} <!-- ENDIF --> diff --git a/phpBB/adm/style/permissions.js b/phpBB/adm/style/permissions.js index 9178adab50..af8e21ad51 100644 --- a/phpBB/adm/style/permissions.js +++ b/phpBB/adm/style/permissions.js @@ -279,6 +279,10 @@ function reset_role(id) { } t.options[0].selected = true; + + var parent = t.parentNode; + parent.querySelector('span.dropdown-trigger').innerText = no_role_assigned; + parent.querySelector('input[data-name^=role]').value = '0'; } /** diff --git a/phpBB/assets/javascript/core.js b/phpBB/assets/javascript/core.js index 2ce20a3b1a..bb38441622 100644 --- a/phpBB/assets/javascript/core.js +++ b/phpBB/assets/javascript/core.js @@ -1650,6 +1650,50 @@ phpbb.lazyLoadAvatars = function loadAvatars() { }); }; +var recaptchaForm = $('.g-recaptcha').parents('form'); +var submitButton = null; +var programaticallySubmitted = false; + +phpbb.recaptchaOnLoad = function () { + // Listen to submit buttons in order to know which one was pressed + $('input[type="submit"]').each(function () { + $(this).on('click', function () { + submitButton = this; + }); + }); + + recaptchaForm.on('submit', function (e) { + if (!programaticallySubmitted) { + grecaptcha.execute(); + e.preventDefault(); + } + }); +} + +phpbb.recaptchaOnSubmit = function () { + programaticallySubmitted = true; + // If concrete button was clicked (e.g. preview instead of submit), + // let's trigger the same action + if (submitButton) { + submitButton.click(); + } else { + // Rename input[name="submit"] so that we can submit the form + if (typeof recaptchaForm.submit !== 'function') { + recaptchaForm.submit.name = 'submit_btn'; + } + recaptchaForm.submit(); + } +} + +// reCAPTCHA doesn't accept callback functions nested inside objects +// so we need to make this helper functions here +window.phpbbRecaptchaOnLoad = function() { + phpbb.recaptchaOnLoad(); +} +window.phpbbRecaptchaOnSubmit = function() { + phpbb.recaptchaOnSubmit(); +} + $(window).on('load', phpbb.lazyLoadAvatars); /** diff --git a/phpBB/assets/javascript/editor.js b/phpBB/assets/javascript/editor.js index 23244f5a40..24cbc09f58 100644 --- a/phpBB/assets/javascript/editor.js +++ b/phpBB/assets/javascript/editor.js @@ -18,16 +18,9 @@ var is_win = ((clientPC.indexOf('win') !== -1) || (clientPC.indexOf('16bit') !== var baseHeight; /** -* Shows the help messages in the helpline window -*/ -function helpline(help) { - document.forms[form_name].helpbox.value = help_line[help]; -} - -/** * Fix a bug involving the TextRange object. From * http://www.frostjedi.com/terra/scripts/demo/caretBug.html -*/ +*/ function initInsertions() { var doc; @@ -104,8 +97,8 @@ function bbfontstyle(bbopen, bbclose) { } // IE else if (document.selection) { - var range = textarea.createTextRange(); - range.move("character", new_pos); + var range = textarea.createTextRange(); + range.move("character", new_pos); range.select(); storeCaret(textarea); } diff --git a/phpBB/assets/javascript/plupload.js b/phpBB/assets/javascript/plupload.js index 495d756c79..8c52aae819 100644 --- a/phpBB/assets/javascript/plupload.js +++ b/phpBB/assets/javascript/plupload.js @@ -21,7 +21,9 @@ phpbb.plupload.initialize = function() { // Only execute if Plupload initialized successfully. phpbb.plupload.uploader.bind('Init', function() { phpbb.plupload.form = $(phpbb.plupload.config.form_hook)[0]; - phpbb.plupload.rowTpl = $('#attach-row-tpl')[0].outerHTML; + let $attachRowTemplate = $('#attach-row-tpl'); + $attachRowTemplate.removeClass('attach-row-tpl'); + phpbb.plupload.rowTpl = $attachRowTemplate[0].outerHTML; // Hide the basic upload panel and remove the attach row template. $('#attach-row-tpl, #attach-panel-basic').remove(); @@ -88,6 +90,12 @@ phpbb.plupload.getSerializedData = function() { obj['attachment_data[' + i + '][' + key + ']'] = datum[key]; } } + + // Insert form data + var $pluploadForm = $(phpbb.plupload.config.form_hook).first(); + obj.creation_time = $pluploadForm.find('input[type=hidden][name="creation_time"]').val(); + obj.form_token = $pluploadForm.find('input[type=hidden][name="form_token"]').val(); + return obj; }; @@ -262,6 +270,17 @@ phpbb.plupload.deleteFile = function(row, attachId) { return; } + + // Handle errors while deleting file + if (typeof response.error !== 'undefined') { + phpbb.alert(phpbb.plupload.lang.ERROR, response.error.message); + + // We will have to assume that the deletion failed. So leave the file status as uploaded. + row.find('.file-status').toggleClass('file-uploaded'); + + return; + } + phpbb.plupload.update(response, 'removal', index); // Check if the user can upload files now if he had reached the max files limit. phpbb.plupload.handleMaxFilesReached(); @@ -444,6 +463,44 @@ phpbb.plupload.fileError = function(file, error) { phpbb.plupload.uploader = new plupload.Uploader(phpbb.plupload.config); phpbb.plupload.initialize(); +/** + * Add a file filter to check for max file sizes per mime type. + */ +plupload.addFileFilter('mime_types_max_file_size', function(types, file, callback) { + if (file.size !== 'undefined') { + $(types).each(function(i, type) { + let extensions = [], + extsArray = type.extensions.split(','); + + $(extsArray).each(function(i, extension) { + /^\s*\*\s*$/.test(extension) ? extensions.push("\\.*") : extensions.push("\\." + extension.replace(new RegExp("[" + "/^$.*+?|()[]{}\\".replace(/./g, "\\$&") + "]", "g"), "\\$&")); + }); + + let regex = new RegExp("(" + extensions.join("|") + ")$", "i"); + + if (regex.test(file.name)) { + if (type.max_file_size !== 'undefined' && type.max_file_size) { + if (file.size > type.max_file_size) { + phpbb.plupload.uploader.trigger('Error', { + code: plupload.FILE_SIZE_ERROR, + message: plupload.translate('File size error.'), + file: file + }); + + callback(false); + } else { + callback(true); + } + } else { + callback(true); + } + + return false; + } + }); + } +}); + var $fileList = $('#file-list'); /** diff --git a/phpBB/config/default/container/services_twig.yml b/phpBB/config/default/container/services_twig.yml index ce76a6a5ea..6f70155295 100644 --- a/phpBB/config/default/container/services_twig.yml +++ b/phpBB/config/default/container/services_twig.yml @@ -43,6 +43,18 @@ services: tags: - { name: twig.extension } + template.twig.extensions.avatar: + class: phpbb\template\twig\extension\avatar + tags: + - { name: twig.extension } + + template.twig.extensions.config: + class: phpbb\template\twig\extension\config + arguments: + - '@config' + tags: + - { name: twig.extension } + template.twig.extensions.routing: class: phpbb\template\twig\extension\routing arguments: @@ -50,6 +62,11 @@ services: tags: - { name: twig.extension } + template.twig.extensions.username: + class: phpbb\template\twig\extension\username + tags: + - { name: twig.extension } + template.twig.extensions.debug: class: Twig_Extension_Debug diff --git a/phpBB/docs/CHANGELOG.html b/phpBB/docs/CHANGELOG.html index b1d45e7995..0c9b56d1bf 100644 --- a/phpBB/docs/CHANGELOG.html +++ b/phpBB/docs/CHANGELOG.html @@ -50,6 +50,8 @@ <ol> <li><a href="#changelog">Changelog</a> <ul> + <li><a href="#v328rc1">Changes since 3.2.8-RC1</a></li> + <li><a href="#v327">Changes since 3.2.7</a></li> <li><a href="#v326">Changes since 3.2.6</a></li> <li><a href="#v326rc1">Changes since 3.2.6-RC1</a></li> <li><a href="#v325">Changes since 3.2.5</a></li> @@ -138,6 +140,105 @@ <div class="inner"> <div class="content"> + <a name="v328rc1"></a><h3>Changes since 3.2.8-RC1</h3> + <h4>Bug</h4> + <ul> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15467">PHPBB3-15467</a>] - Permission settings do not take affect when set using All YES/NO/NEVER</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16123">PHPBB3-16123</a>] - PHP error (Array to string conversion) on new user registration if email address is banned and " Reason shown to the banned" is empty</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16136">PHPBB3-16136</a>] - Missing word in 'AUTH_PROVIDER_OAUTH_ERROR_ALREADY_LINKED' </li> + </ul> + <h4>Improvement</h4> + <ul> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16134">PHPBB3-16134</a>] - Exclude group leaders on group member purge</li> + </ul> + <h4>Security Issue</h4> + <ul> + <li>[SECURITY-243] - CSS injection via BBCode tag</li> + <li>[SECURITY-244] - Missing form token check when handling attachments</li> + <li>[SECURITY-246] - Missing form token check when managing BBCodes</li> + </ul> + <h4>Hardening</h4> + <ul> + <li>[SECURITY-247] - Disable MySQLi local infile to prevent local file inclusion</li> + </ul> + + <a name="v327"></a><h3>Changes since 3.2.7</h3> + <h4>Bug</h4> + <ul> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13175">PHPBB3-13175</a>] - External accounts can be linked to more than one local account</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14459">PHPBB3-14459</a>] - Check language input for group</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15211">PHPBB3-15211</a>] - Emoji characters in forum name causing SQL errors</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15885">PHPBB3-15885</a>] - Group rank not displaying on memberlist_body</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15897">PHPBB3-15897</a>] - Unicode Characters in Attachment Comment Causes mySQL Error </li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15932">PHPBB3-15932</a>] - Users can delete their attachments in the UCP, even if the post is locked</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15961">PHPBB3-15961</a>] - SMTP support for TLS is forcing use of deprecated TLS 1.0</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15974">PHPBB3-15974</a>] - The link "Back to previous page" can redirect to another page, not the previous one</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15976">PHPBB3-15976</a>] - Changing account settings without changing password resets user_passchg</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15982">PHPBB3-15982</a>] - Q&A captcha plug-in still throws PHP 7.2.x countable warning</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16003">PHPBB3-16003</a>] - Post count not updated when deleting only post in topic</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16021">PHPBB3-16021</a>] - Recognize number of Template Event instances in events.md file</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16040">PHPBB3-16040</a>] - Topic Icon with space in filename isn't displayed by viewforum_body.html</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16048">PHPBB3-16048</a>] - Unable to restore any backup from ACP</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16050">PHPBB3-16050</a>] - PHP warning in MCP banning tab on PHP 7.2+</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16053">PHPBB3-16053</a>] - BBCodes using {TEXT} in HTML tags no longer work</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16054">PHPBB3-16054</a>] - Style templates no longer able to login "from any page."</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16055">PHPBB3-16055</a>] - Unable to login using Oauth via Forums, topics or posts</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16061">PHPBB3-16061</a>] - Migrator never drops unique indexes</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16063">PHPBB3-16063</a>] - board_dst config value is not removed from config table after conversion</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16066">PHPBB3-16066</a>] - Banned or suspended user receives "The submitted form was invalid. Try submitting again."</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16071">PHPBB3-16071</a>] - Undefined index for custom attachments groups</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16073">PHPBB3-16073</a>] - Fix warning in ACP version check</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16074">PHPBB3-16074</a>] - Twemoji -fe0f sequence not rendering</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16075">PHPBB3-16075</a>] - PM filter “sent to my default usergroup” triggers array to string conversion warning</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16080">PHPBB3-16080</a>] - Warnings When a Style exists on database but not on FTP</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16093">PHPBB3-16093</a>] - Attach row template always gets displayed with JS disabled</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16096">PHPBB3-16096</a>] - MySQL full text search always uses MyISAM limits</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16124">PHPBB3-16124</a>] - Incorrect users search by last visit time in memberlist.php</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16126">PHPBB3-16126</a>] - AppVeyor builds fail due to chocolatey being unable to install PHP</li> + </ul> + <h4>Improvement</h4> + <ul> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15745">PHPBB3-15745</a>] - Hardcoded lang in credit line</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15886">PHPBB3-15886</a>] - Group helper functions</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15946">PHPBB3-15946</a>] - Add event - core.posting_modify_row_data</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15967">PHPBB3-15967</a>] - Unambiguous wording in user activation request email to Admin/Moderator</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15984">PHPBB3-15984</a>] - Use of 'Cache-Control: public' for serving files</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16000">PHPBB3-16000</a>] - Provide link to PHP Date Function in both ACP and UCP</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16013">PHPBB3-16013</a>] - Do not prevent username changes in ACP</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16019">PHPBB3-16019</a>] - Deny prosilver's uninstallation</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16024">PHPBB3-16024</a>] - Add core.topic_review_modify_sql_ary</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16025">PHPBB3-16025</a>] - Add 2 template events *_author_username_{append/prepend}</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16047">PHPBB3-16047</a>] - ACP Private Messages: Wording could be better</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16058">PHPBB3-16058</a>] - Remove sudo required from travis config</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16065">PHPBB3-16065</a>] - Undefined index: user_ip in oauth.php</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16068">PHPBB3-16068</a>] - Incorrect docblock parameter types</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16070">PHPBB3-16070</a>] - Remove support for WebSTAR and Xitami</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16078">PHPBB3-16078</a>] - Use chrome webdriver for UI tests</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16089">PHPBB3-16089</a>] - Add core.confirm_box_ajax_before</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16097">PHPBB3-16097</a>] - Add core.viewtopic_gen_sort_selects_before</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16102">PHPBB3-16102</a>] - Add core.posting_modify_post_subject</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16103">PHPBB3-16103</a>] - Add core.pm_modify_message_subject</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16106">PHPBB3-16106</a>] - Add core.mcp_main_before</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16107">PHPBB3-16107</a>] - Add mcp_move_destination_forum_before|after</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16108">PHPBB3-16108</a>] - Add topiclist_row_topic_by_author_before|after</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16109">PHPBB3-16109</a>] - Custom Profile Field visibility is incorrectly explained</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16111">PHPBB3-16111</a>] - Add core.message_history_modify_sql_ary</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16113">PHPBB3-16113</a>] - Add core.mcp_topic_modify_sql_ary</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16114">PHPBB3-16114</a>] - Add 2 mcp_topic_post_author_full_{append/prepend}</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16127">PHPBB3-16127</a>] - Add UI for Mass email $max_chunk_size</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16129">PHPBB3-16129</a>] - The attachment's ALT tag is supposed to describe the image, not the file.</li> + </ul> + <h4>Task</h4> + <ul> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16067">PHPBB3-16067</a>] - Define trusty build environment for travis builds</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16112">PHPBB3-16112</a>] - Update composer dependencies to latest</li> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16119">PHPBB3-16119</a>] - The text input for poll question has a too high maxlength attribute</li> + </ul> + <h4>Hardening</h4> + <ul> + <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16101">PHPBB3-16101</a>] - Add Referrer-Policy header</li> + </ul> + <a name="v326"></a><h3>Changes since 3.2.6</h3> <h4>Bug</h4> <ul> diff --git a/phpBB/docs/CREDITS.txt b/phpBB/docs/CREDITS.txt index 337c9cf536..64f5588bac 100644 --- a/phpBB/docs/CREDITS.txt +++ b/phpBB/docs/CREDITS.txt @@ -1,7 +1,7 @@ /** * -* phpBB © Copyright phpBB Limited 2003-2016 -* http://www.phpbb.com +* phpBB © Copyright phpBB Limited 2003-2019 +* https://www.phpbb.com * * phpBB is free software. You can redistribute it and/or modify it * under the terms of the GNU General Public License, version 2 (GPL-2.0) @@ -27,7 +27,6 @@ phpBB Developers: bantu (Andreas Fischer) Derky (Derk Ruitenbeek) Elsensee (Oliver Schramm) Hanakin (Michael Miday) - MichaelC (Michael Cullum) Nicofuma (Tristan Darricau) rubencm (Rubén Calvo) @@ -63,6 +62,7 @@ phpBB Developers: A_Jelly_Doughnut (Josh Woody) [01/2010 - 11/2010] igorw (Igor Wiedler) [08/2010 - 02/2013] imkingdavid (David King) [11/2012 - 06/2014] kellanved (Henry Sudhof) [04/2007 - 03/2011] + MichaelC (Michael Cullum) [11/2017 - 09/2019] nickvergessen (Joas Schilling)[04/2010 - 12/2015] Oleg (Oleg Pudeyev) [01/2011 - 05/2013] prototech (Cesar Gallegos) [01/2014 - 12/2016] diff --git a/phpBB/docs/events.md b/phpBB/docs/events.md index afe4bd7781..4be1725090 100644 --- a/phpBB/docs/events.md +++ b/phpBB/docs/events.md @@ -172,6 +172,18 @@ acp_group_options_before * Since: 3.1.0-b4 * Purpose: Add additional options to group settings (before GROUP_FOUNDER_MANAGE) +acp_group_types_append +=== +* Location: adm/style/acp_groups.html +* Since: 3.2.9-RC1 +* Purpose: Add additional group type options to group settings (append the list) + +acp_group_types_prepend +=== +* Location: adm/style/acp_groups.html +* Since: 3.2.9-RC1 +* Purpose: Add additional group type options to group settings (prepend the list) + acp_groups_find_username_append === * Location: adm/style/acp_groups.html @@ -1051,6 +1063,20 @@ mcp_topic_options_before * Since: 3.1.6-RC1 * Purpose: Add some options (field, checkbox, ...) before the subject field when split a subject +mcp_topic_post_author_full_append +=== +* Locations: + + styles/prosilver/template/mcp_topic.html +* Since: 3.2.8-RC1 +* Purpose: Append information to message author username for post details in topic moderation + +mcp_topic_post_author_full_prepend +=== +* Locations: + + styles/prosilver/template/mcp_topic.html +* Since: 3.2.8-RC1 +* Purpose: Prepend information to message author username for post details in topic moderation + mcp_topic_postrow_attachments_after === * Locations: diff --git a/phpBB/includes/acp/acp_bbcodes.php b/phpBB/includes/acp/acp_bbcodes.php index b59f9e3a39..5360ab0f7b 100644 --- a/phpBB/includes/acp/acp_bbcodes.php +++ b/phpBB/includes/acp/acp_bbcodes.php @@ -33,7 +33,6 @@ class acp_bbcodes // Set up general vars $action = $request->variable('action', ''); $bbcode_id = $request->variable('bbcode', 0); - $submit = $request->is_set_post('submit'); $this->tpl_name = 'acp_bbcodes'; $this->page_title = 'ACP_BBCODES'; @@ -41,11 +40,6 @@ class acp_bbcodes add_form_key($form_key); - if ($submit && !check_form_key($form_key)) - { - trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING); - } - // Set up mode-specific vars switch ($action) { @@ -179,6 +173,12 @@ class acp_bbcodes extract($phpbb_dispatcher->trigger_event('core.acp_bbcodes_modify_create', compact($vars))); $warn_text = preg_match('%<[^>]*\{text[\d]*\}[^>]*>%i', $bbcode_tpl); + + if (!$warn_text && !check_form_key($form_key)) + { + trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING); + } + if (!$warn_text || confirm_box(true)) { $data = $this->build_regexp($bbcode_match, $bbcode_tpl); diff --git a/phpBB/includes/acp/acp_board.php b/phpBB/includes/acp/acp_board.php index 083bd5adac..7cbd0903bd 100644 --- a/phpBB/includes/acp/acp_board.php +++ b/phpBB/includes/acp/acp_board.php @@ -441,6 +441,7 @@ class acp_board 'email_enable' => array('lang' => 'ENABLE_EMAIL', 'validate' => 'bool', 'type' => 'radio:enabled_disabled', 'explain' => true), 'board_email_form' => array('lang' => 'BOARD_EMAIL_FORM', 'validate' => 'bool', 'type' => 'radio:enabled_disabled', 'explain' => true), 'email_package_size' => array('lang' => 'EMAIL_PACKAGE_SIZE', 'validate' => 'int:0', 'type' => 'number:0:99999', 'explain' => true), + 'email_max_chunk_size' => array('lang' => 'EMAIL_MAX_CHUNK_SIZE', 'validate' => 'int:1:99999', 'type' => 'number:1:99999', 'explain' => true), 'board_contact' => array('lang' => 'CONTACT_EMAIL', 'validate' => 'email', 'type' => 'email:25:100', 'explain' => true), 'board_contact_name' => array('lang' => 'CONTACT_EMAIL_NAME', 'validate' => 'string', 'type' => 'text:25:50', 'explain' => true), 'board_email' => array('lang' => 'ADMIN_EMAIL', 'validate' => 'email', 'type' => 'email:25:100', 'explain' => true), diff --git a/phpBB/includes/acp/acp_database.php b/phpBB/includes/acp/acp_database.php index c33c2e4d6f..677fce7217 100644 --- a/phpBB/includes/acp/acp_database.php +++ b/phpBB/includes/acp/acp_database.php @@ -58,7 +58,6 @@ class acp_database $type = $request->variable('type', ''); $table = array_intersect($this->db_tools->sql_list_tables(), $request->variable('table', array(''))); $format = $request->variable('method', ''); - $where = $request->variable('where', ''); if (!count($table)) { @@ -70,12 +69,9 @@ class acp_database trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING); } - $store = $structure = $schema_data = false; - - if ($where == 'store') - { - $store = true; - } + $store = true; + $structure = false; + $schema_data = false; if ($type == 'full' || $type == 'structure') { diff --git a/phpBB/includes/acp/acp_extensions.php b/phpBB/includes/acp/acp_extensions.php index 2929de3c4f..6ac70ce3a8 100644 --- a/phpBB/includes/acp/acp_extensions.php +++ b/phpBB/includes/acp/acp_extensions.php @@ -172,10 +172,8 @@ class acp_extensions } $extension = $this->ext_manager->get_extension($ext_name); - if (!$extension->is_enableable()) - { - trigger_error($this->user->lang['EXTENSION_NOT_ENABLEABLE'] . adm_back_link($this->u_action), E_USER_WARNING); - } + + $this->check_is_enableable($extension); if ($this->ext_manager->is_enabled($ext_name)) { @@ -209,10 +207,8 @@ class acp_extensions } $extension = $this->ext_manager->get_extension($ext_name); - if (!$extension->is_enableable()) - { - trigger_error($this->user->lang['EXTENSION_NOT_ENABLEABLE'] . adm_back_link($this->u_action), E_USER_WARNING); - } + + $this->check_is_enableable($extension); try { @@ -727,4 +723,28 @@ class acp_extensions )); } } + + /** + * Checks whether the extension can be enabled. Triggers error if not. + * Error message can be set by the extension. + * + * @param \phpbb\extension\extension_interface $extension Extension to check + */ + protected function check_is_enableable(\phpbb\extension\extension_interface $extension) + { + $message = $extension->is_enableable(); + if ($message !== true) + { + if (empty($message)) + { + $message = $this->user->lang('EXTENSION_NOT_ENABLEABLE'); + } + else if (is_array($message)) + { + $message = implode('<br>', $message); + } + + trigger_error($message . adm_back_link($this->u_action), E_USER_WARNING); + } + } } diff --git a/phpBB/includes/acp/acp_prune.php b/phpBB/includes/acp/acp_prune.php index 3eee4f7922..c5f7789de8 100644 --- a/phpBB/includes/acp/acp_prune.php +++ b/phpBB/includes/acp/acp_prune.php @@ -537,6 +537,7 @@ class acp_prune AND ug.user_id <> ' . ANONYMOUS . ' AND u.user_type <> ' . USER_FOUNDER . ' AND ug.user_pending = 0 + AND ug.group_leader = 0 AND u.user_id = ug.user_id ' . (!empty($user_ids) ? ' AND ' . $db->sql_in_set('ug.user_id', $user_ids) : ''); $result = $db->sql_query($sql); diff --git a/phpBB/includes/acp/acp_styles.php b/phpBB/includes/acp/acp_styles.php index 1bf5a3c6a8..87c8d88f52 100644 --- a/phpBB/includes/acp/acp_styles.php +++ b/phpBB/includes/acp/acp_styles.php @@ -259,6 +259,19 @@ class acp_styles // Get list of styles to uninstall $ids = $this->request_vars('id', 0, true); + // Don't remove prosilver, you can still deactivate it. + $sql = 'SELECT style_id + FROM ' . STYLES_TABLE . " + WHERE style_name = '" . $this->db->sql_escape('prosilver') . "'"; + $result = $this->db->sql_query($sql); + $prosilver_id = (int) $this->db->sql_fetchfield('style_id'); + $this->db->sql_freeresult($result); + + if ($prosilver_id && in_array($prosilver_id, $ids)) + { + trigger_error($this->user->lang('UNINSTALL_PROSILVER') . adm_back_link($this->u_action), E_USER_WARNING); + } + // Check if confirmation box was submitted if (confirm_box(true)) { @@ -998,11 +1011,14 @@ class acp_styles 'L_ACTION' => $this->user->lang['EXPORT'] ); */ - // Uninstall - $actions[] = array( - 'U_ACTION' => $this->u_action . '&action=uninstall&hash=' . generate_link_hash('uninstall') . '&id=' . $style['style_id'], - 'L_ACTION' => $this->user->lang['STYLE_UNINSTALL'] - ); + if ($style['style_name'] !== 'prosilver') + { + // Uninstall + $actions[] = array( + 'U_ACTION' => $this->u_action . '&action=uninstall&hash=' . generate_link_hash('uninstall') . '&id=' . $style['style_id'], + 'L_ACTION' => $this->user->lang['STYLE_UNINSTALL'] + ); + } // Preview $actions[] = array( @@ -1123,7 +1139,14 @@ class acp_styles */ protected function read_style_cfg($dir) { + // This should never happen, we give them a red warning because of its relevance. + if (!file_exists($this->styles_path . $dir . '/style.cfg')) + { + trigger_error($this->user->lang('NO_STYLE_CFG', $dir), E_USER_WARNING); + } + static $required = array('name', 'phpbb_version', 'copyright'); + $cfg = parse_cfg_file($this->styles_path . $dir . '/style.cfg'); // Check if it is a valid file diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index e8f8b0ff46..e1f6fa3d1b 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -2514,9 +2514,6 @@ function login_box($redirect = '', $l_explain = '', $l_success = '', $admin = fa )); } - // Add form token for login box - add_form_key($form_name, '_LOGIN'); - $s_hidden_fields = build_hidden_fields($s_hidden_fields); /** @var \phpbb\controller\helper $controller_helper */ @@ -2654,9 +2651,6 @@ function login_forum_box($forum_data) page_header($user->lang['LOGIN']); - // Add form token for login box - add_form_key('login', '_LOGIN'); - $template->assign_vars(array( 'FORUM_NAME' => isset($forum_data['forum_name']) ? $forum_data['forum_name'] : '', 'S_LOGIN_ACTION' => build_url(array('f')), @@ -4432,6 +4426,10 @@ function page_header($page_title = '', $display_online_list = false, $item_id = $notification_mark_hash = generate_link_hash('mark_all_notifications_read'); $s_login_redirect = build_hidden_fields(array('redirect' => $phpbb_path_helper->remove_web_root_path(build_url()))); + + // Add form token for login box, in case page is presenting a login form. + add_form_key('login', '_LOGIN'); + /** * Workaround for missing template variable in pre phpBB 3.2.6 styles. * @deprecated 3.2.7 (To be removed: 3.3.0-a1) diff --git a/phpBB/includes/functions_admin.php b/phpBB/includes/functions_admin.php index 1f3fe1c8e8..ce5f0812aa 100644 --- a/phpBB/includes/functions_admin.php +++ b/phpBB/includes/functions_admin.php @@ -543,6 +543,20 @@ function move_topics($topic_ids, $forum_id, $auto_sync = true) $topic_ids = array($topic_ids); } + /** + * Perform additional actions before topics move + * + * @event core.move_topics_before + * @var array topic_ids Array of the moved topic ids + * @var string forum_id The forum id from where the topics are moved + * @since 3.2.9-RC1 + */ + $vars = array( + 'topic_ids', + 'forum_id', + ); + extract($phpbb_dispatcher->trigger_event('core.move_topics_before', compact($vars))); + $sql = 'DELETE FROM ' . TOPICS_TABLE . ' WHERE ' . $db->sql_in_set('topic_moved_id', $topic_ids) . ' AND forum_id = ' . $forum_id; @@ -593,6 +607,22 @@ function move_topics($topic_ids, $forum_id, $auto_sync = true) } unset($table_ary); + /** + * Perform additional actions after topics move + * + * @event core.move_topics_after + * @var array topic_ids Array of the moved topic ids + * @var string forum_id The forum id from where the topics were moved + * @var array forum_ids Array of the forums where the topics were moved (includes also forum_id) + * @since 3.2.9-RC1 + */ + $vars = array( + 'topic_ids', + 'forum_id', + 'forum_ids', + ); + extract($phpbb_dispatcher->trigger_event('core.move_topics_after', compact($vars))); + if ($auto_sync) { sync('forum', 'forum_id', $forum_ids, true, true); diff --git a/phpBB/includes/functions_display.php b/phpBB/includes/functions_display.php index 7fa32ce217..2d9aaba6e8 100644 --- a/phpBB/includes/functions_display.php +++ b/phpBB/includes/functions_display.php @@ -547,11 +547,12 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod $last_post_subject = $last_post_subject_truncated = ''; } $last_post_time = $user->format_date($row['forum_last_post_time']); + $last_post_time_rfc3339 = gmdate(DATE_RFC3339, $row['forum_last_post_time']); $last_post_url = append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'f=' . $row['forum_id_last_post'] . '&p=' . $row['forum_last_post_id']) . '#p' . $row['forum_last_post_id']; } else { - $last_post_subject = $last_post_time = $last_post_url = $last_post_subject_truncated = ''; + $last_post_subject = $last_post_time = $last_post_time_rfc3339 = $last_post_url = $last_post_subject_truncated = ''; } // Output moderator listing ... if applicable @@ -622,6 +623,7 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod 'LAST_POST_SUBJECT' => $last_post_subject, 'LAST_POST_SUBJECT_TRUNCATED' => $last_post_subject_truncated, 'LAST_POST_TIME' => $last_post_time, + 'LAST_POST_TIME_RFC3339'=> $last_post_time_rfc3339, 'LAST_POSTER' => get_username_string('username', $row['forum_last_poster_id'], $row['forum_last_poster_name'], $row['forum_last_poster_colour']), 'LAST_POSTER_COLOUR' => get_username_string('colour', $row['forum_last_poster_id'], $row['forum_last_poster_name'], $row['forum_last_poster_colour']), 'LAST_POSTER_FULL' => get_username_string('full', $row['forum_last_poster_id'], $row['forum_last_poster_name'], $row['forum_last_poster_colour']), @@ -1117,7 +1119,6 @@ function display_custom_bbcodes() 'BBCODE_TAG' => $row['bbcode_tag'], 'BBCODE_TAG_CLEAN' => str_replace('=', '-', $row['bbcode_tag']), 'BBCODE_HELPLINE' => $row['bbcode_helpline'], - 'A_BBCODE_HELPLINE' => str_replace(array('&', '"', "'", '<', '>'), array('&', '"', "\'", '<', '>'), $row['bbcode_helpline']), ); /** diff --git a/phpBB/includes/functions_posting.php b/phpBB/includes/functions_posting.php index cf511ec247..d150845952 100644 --- a/phpBB/includes/functions_posting.php +++ b/phpBB/includes/functions_posting.php @@ -2045,6 +2045,11 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll_ary, &$data continue; } + if (preg_match('/[\x{10000}-\x{10FFFF}]/u', $attach_row['attach_comment'])) + { + trigger_error('ATTACH_COMMENT_NO_EMOJIS'); + } + if (!$attach_row['is_orphan']) { // update entry in db if attachment already stored in db and filespace diff --git a/phpBB/includes/functions_privmsgs.php b/phpBB/includes/functions_privmsgs.php index baadf5bdee..f07512d623 100644 --- a/phpBB/includes/functions_privmsgs.php +++ b/phpBB/includes/functions_privmsgs.php @@ -1985,9 +1985,7 @@ function message_history($msg_id, $user_id, $message_row, $folder, $in_post_mode $recipients = array_unique($recipients); // Get History Messages (could be newer) - $sql = 'SELECT t.*, p.*, u.* - FROM ' . PRIVMSGS_TABLE . ' p, ' . PRIVMSGS_TO_TABLE . ' t, ' . USERS_TABLE . ' u - WHERE t.msg_id = p.msg_id + $sql_where = 't.msg_id = p.msg_id AND p.author_id = u.user_id AND t.folder_id NOT IN (' . PRIVMSGS_NO_BOX . ', ' . PRIVMSGS_HOLD_BOX . ') AND ' . $db->sql_in_set('t.author_id', $recipients, false, true) . " @@ -1998,13 +1996,37 @@ function message_history($msg_id, $user_id, $message_row, $folder, $in_post_mode if (!$message_row['root_level']) { - $sql .= " AND (p.root_level = $msg_id OR (p.root_level = 0 AND p.msg_id = $msg_id))"; + $sql_where .= " AND (p.root_level = $msg_id OR (p.root_level = 0 AND p.msg_id = $msg_id))"; } else { - $sql .= " AND (p.root_level = " . $message_row['root_level'] . ' OR p.msg_id = ' . $message_row['root_level'] . ')'; + $sql_where .= " AND (p.root_level = " . $message_row['root_level'] . ' OR p.msg_id = ' . $message_row['root_level'] . ')'; } - $sql .= ' ORDER BY p.message_time DESC'; + + $sql_ary = array( + 'SELECT' => 't.*, p.*, u.*', + 'FROM' => array( + PRIVMSGS_TABLE => 'p', + PRIVMSGS_TO_TABLE => 't', + USERS_TABLE => 'u' + ), + 'LEFT_JOIN' => array(), + 'WHERE' => $sql_where, + 'ORDER_BY' => 'p.message_time DESC', + ); + + /** + * Event to modify the SQL query before the message history in private message is queried + * + * @event core.message_history_modify_sql_ary + * @var array sql_ary The SQL array to get the data of the message history in private message + * @since 3.2.8-RC1 + */ + $vars = array('sql_ary'); + extract($phpbb_dispatcher->trigger_event('core.message_history_modify_sql_ary', compact($vars))); + + $sql = $db->sql_build_query('SELECT', $sql_ary); + unset($sql_ary); $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); diff --git a/phpBB/includes/functions_user.php b/phpBB/includes/functions_user.php index 3bf4aa16b7..e0b6a9d0c6 100644 --- a/phpBB/includes/functions_user.php +++ b/phpBB/includes/functions_user.php @@ -1945,9 +1945,10 @@ function validate_user_email($email, $allowed_email = false) return $validate_email; } - if (($ban = $user->check_ban(false, false, $email, true)) !== false) + $ban = $user->check_ban(false, false, $email, true); + if (!empty($ban)) { - return ($ban === true) ? 'EMAIL_BANNED' : (!empty($ban['ban_give_reason']) ? $ban['ban_give_reason'] : $ban); + return !empty($ban['ban_give_reason']) ? $ban['ban_give_reason'] : 'EMAIL_BANNED'; } if (!$config['allow_emailreuse']) diff --git a/phpBB/includes/mcp/mcp_topic.php b/phpBB/includes/mcp/mcp_topic.php index 68a65aafdd..83ad56f3e4 100644 --- a/phpBB/includes/mcp/mcp_topic.php +++ b/phpBB/includes/mcp/mcp_topic.php @@ -142,14 +142,36 @@ function mcp_topic_view($id, $mode, $action) } $start = $pagination->validate_start($start, $posts_per_page, $total); - $sql = 'SELECT u.username, u.username_clean, u.user_colour, p.* - FROM ' . POSTS_TABLE . ' p, ' . USERS_TABLE . ' u - WHERE ' . (($action == 'reports') ? 'p.post_reported = 1 AND ' : '') . ' + $sql_where = (($action == 'reports') ? 'p.post_reported = 1 AND ' : '') . ' p.topic_id = ' . $topic_id . ' AND ' . $phpbb_content_visibility->get_visibility_sql('post', $topic_info['forum_id'], 'p.') . ' AND p.poster_id = u.user_id ' . - $limit_time_sql . ' - ORDER BY ' . $sort_order_sql; + $limit_time_sql; + + $sql_ary = array( + 'SELECT' => 'u.username, u.username_clean, u.user_colour, p.*', + 'FROM' => array( + POSTS_TABLE => 'p', + USERS_TABLE => 'u' + ), + 'LEFT_JOIN' => array(), + 'WHERE' => $sql_where, + 'ORDER_BY' => $sort_order_sql, + ); + + /** + * Event to modify the SQL query before the MCP topic review posts is queried + * + * @event core.mcp_topic_modify_sql_ary + * @var array sql_ary The SQL array to get the data of the MCP topic review posts + * @since 3.2.8-RC1 + */ + $vars = array('sql_ary'); + extract($phpbb_dispatcher->trigger_event('core.mcp_topic_modify_sql_ary', compact($vars))); + + $sql = $db->sql_build_query('SELECT', $sql_ary); + unset($sql_ary); + $result = $db->sql_query_limit($sql, $posts_per_page, $start); $rowset = $post_id_list = array(); diff --git a/phpBB/includes/message_parser.php b/phpBB/includes/message_parser.php index 0b79cca864..e1c28223dc 100644 --- a/phpBB/includes/message_parser.php +++ b/phpBB/includes/message_parser.php @@ -1525,6 +1525,35 @@ class parse_message extends bbcode_firstpass } /** + * Check attachment form token depending on submit type + * + * @param \phpbb\language\language $language Language + * @param \phpbb\request\request_interface $request Request + * @param string $form_name Form name for checking form key + * + * @return bool True if form token is not needed or valid, false if needed and invalid + */ + function check_attachment_form_token(\phpbb\language\language $language, \phpbb\request\request_interface $request, $form_name) + { + $add_file = $request->is_set_post('add_file'); + $delete_file = $request->is_set_post('delete_file'); + + if (($add_file || $delete_file) && !check_form_key($form_name)) + { + $this->warn_msg[] = $language->lang('FORM_INVALID'); + + if ($request->is_ajax() && $this->plupload) + { + $this->plupload->emit_error(-400, 'FORM_INVALID'); + } + + return false; + } + + return true; + } + + /** * Parse Attachments */ function parse_attachments($form_name, $mode, $forum_id, $submit, $preview, $refresh, $is_message = false) diff --git a/phpBB/includes/ucp/ucp_pm_compose.php b/phpBB/includes/ucp/ucp_pm_compose.php index cb45112b01..06baa279a5 100644 --- a/phpBB/includes/ucp/ucp_pm_compose.php +++ b/phpBB/includes/ucp/ucp_pm_compose.php @@ -26,7 +26,7 @@ if (!defined('IN_PHPBB')) function compose_pm($id, $mode, $action, $user_folders = array()) { global $template, $db, $auth, $user, $cache; - global $phpbb_root_path, $phpEx, $config; + global $phpbb_root_path, $phpEx, $config, $language; global $request, $phpbb_dispatcher, $phpbb_container; // Damn php and globals - i know, this is horrible @@ -799,7 +799,10 @@ function compose_pm($id, $mode, $action, $user_folders = array()) extract($phpbb_dispatcher->trigger_event('core.ucp_pm_compose_modify_parse_before', compact($vars))); // Parse Attachments - before checksum is calculated - $message_parser->parse_attachments('fileupload', $action, 0, $submit, $preview, $refresh, true); + if ($message_parser->check_attachment_form_token($language, $request, 'ucp_pm_compose')) + { + $message_parser->parse_attachments('fileupload', $action, 0, $submit, $preview, $refresh, true); + } if (count($message_parser->warn_msg) && !($remove_u || $remove_g || $add_to || $add_bcc)) { diff --git a/phpBB/index.php b/phpBB/index.php index 5eee7723a9..5622bc37c7 100644 --- a/phpBB/index.php +++ b/phpBB/index.php @@ -211,9 +211,6 @@ if ($show_birthdays) $template->assign_block_vars_array('birthdays', $birthdays); } -// Add form token for login box -add_form_key('login', '_LOGIN'); - // Assign index specific vars $template->assign_vars(array( 'TOTAL_POSTS' => $user->lang('TOTAL_POSTS_COUNT', (int) $config['num_posts']), @@ -224,11 +221,6 @@ $template->assign_vars(array( 'LEGEND' => $legend, 'BIRTHDAY_LIST' => (empty($birthday_list)) ? '' : implode($user->lang['COMMA_SEPARATOR'], $birthday_list), - 'FORUM_IMG' => $user->img('forum_read', 'NO_UNREAD_POSTS'), - 'FORUM_UNREAD_IMG' => $user->img('forum_unread', 'UNREAD_POSTS'), - 'FORUM_LOCKED_IMG' => $user->img('forum_read_locked', 'NO_UNREAD_POSTS_LOCKED'), - 'FORUM_UNREAD_LOCKED_IMG' => $user->img('forum_unread_locked', 'UNREAD_POSTS_LOCKED'), - 'S_LOGIN_ACTION' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=login'), 'U_SEND_PASSWORD' => ($config['email_enable']) ? append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=sendpassword') : '', 'S_DISPLAY_BIRTHDAY_LIST' => $show_birthdays, diff --git a/phpBB/language/en/acp/board.php b/phpBB/language/en/acp/board.php index 10e76cc483..fdc02d9ae8 100644 --- a/phpBB/language/en/acp/board.php +++ b/phpBB/language/en/acp/board.php @@ -568,6 +568,8 @@ $lang = array_merge($lang, array( 'EMAIL_FORCE_SENDER_EXPLAIN' => 'This will set the <samp>Return-Path</samp> to the from email address instead of using the local user and hostname of the server. This setting does not apply when using SMTP.<br><em><strong>Warning:</strong> Requires the user that the webserver runs as to be added as trusted user to the sendmail configuration.</em>', 'EMAIL_PACKAGE_SIZE' => 'Email package size', 'EMAIL_PACKAGE_SIZE_EXPLAIN' => 'This is the number of maximum emails sent out in one package. This setting is applied to the internal message queue; set this value to 0 if you have problems with non-delivered notification emails.', + 'EMAIL_MAX_CHUNK_SIZE' => 'Maximum allowed email recipients', + 'EMAIL_MAX_CHUNK_SIZE_EXPLAIN' => 'If necessary, set this to not exceed the maximum number of recipients that your email server will allow in one email message.', 'EMAIL_SIG' => 'Email signature', 'EMAIL_SIG_EXPLAIN' => 'This text will be attached to all emails the board sends.', 'ENABLE_EMAIL' => 'Enable board-wide emails', diff --git a/phpBB/language/en/acp/profile.php b/phpBB/language/en/acp/profile.php index 41cbd9cb93..87c950581e 100644 --- a/phpBB/language/en/acp/profile.php +++ b/phpBB/language/en/acp/profile.php @@ -111,7 +111,7 @@ $lang = array_merge($lang, array( 'FIRST_OPTION' => 'First option', 'HIDE_PROFILE_FIELD' => 'Hide profile field', - 'HIDE_PROFILE_FIELD_EXPLAIN' => 'Hide the profile field from all other users except the user, administrators and moderators who are still able to see this field. If the Display in user control panel option is disabled, the user will not be able to see or change this field and the field can only be changed by administrators.', + 'HIDE_PROFILE_FIELD_EXPLAIN' => 'Hide the profile field from all users except administrators and moderators, who are still able to see this field. If the Display in user control panel option is disabled, the user will not be able to see or change this field and the field can only be changed by administrators.', 'INVALID_CHARS_FIELD_IDENT' => 'Field identification can only contain lowercase a-z and _', 'INVALID_FIELD_IDENT_LEN' => 'Field identification can only be 17 characters long', diff --git a/phpBB/language/en/acp/styles.php b/phpBB/language/en/acp/styles.php index ab85d9d2f5..44be3c11cd 100644 --- a/phpBB/language/en/acp/styles.php +++ b/phpBB/language/en/acp/styles.php @@ -21,7 +21,7 @@ if (!defined('IN_PHPBB')) if (empty($lang) || !is_array($lang)) { - $lang = array(); + $lang = []; } // DEVELOPERS PLEASE NOTE @@ -36,55 +36,56 @@ if (empty($lang) || !is_array($lang)) // equally where a string contains only two placeholders which are used to wrap text // in a url you again do not need to specify an order e.g., 'Click %sHERE%s' is fine -$lang = array_merge($lang, array( - 'ACP_STYLES_EXPLAIN' => 'Here you can manage the available styles on your board. You may alter existing styles, delete, deactivate, reactivate, install new ones. You can also see what a style will look like using the preview function. Also listed is the total user count for each style, note that overriding user styles will not be reflected here.', +$lang = array_merge($lang, [ + 'ACP_STYLES_EXPLAIN' => 'Here you can manage the styles available on your board.<br>Please note you cannot uninstall the “<strong>prosilver</strong>” style as it is phpBB’s default and primary parent style.', - 'CANNOT_BE_INSTALLED' => 'Cannot be installed', - 'CONFIRM_UNINSTALL_STYLES' => 'Are you sure you wish to uninstall selected styles?', - 'COPYRIGHT' => 'Copyright', + 'CANNOT_BE_INSTALLED' => 'Cannot be installed', + 'CONFIRM_UNINSTALL_STYLES' => 'Are you sure you wish to uninstall selected styles?', + 'COPYRIGHT' => 'Copyright', - 'DEACTIVATE_DEFAULT' => 'You cannot deactivate the default style.', - 'DELETE_FROM_FS' => 'Delete from filesystem', - 'DELETE_STYLE_FILES_FAILED' => 'Error deleting files for style "%s".', - 'DELETE_STYLE_FILES_SUCCESS' => 'Files for style "%s" have been deleted.', - 'DETAILS' => 'Details', + 'DEACTIVATE_DEFAULT' => 'You cannot deactivate the default style.', + 'DELETE_FROM_FS' => 'Delete from filesystem', + 'DELETE_STYLE_FILES_FAILED' => 'Error deleting files for style "%s".', + 'DELETE_STYLE_FILES_SUCCESS' => 'Files for style "%s" have been deleted.', + 'DETAILS' => 'Details', - 'INHERITING_FROM' => 'Inherits from', - 'INSTALL_STYLE' => 'Install style', - 'INSTALL_STYLES' => 'Install styles', - 'INSTALL_STYLES_EXPLAIN' => 'Here you can install new styles.<br />If you cannot find a specific style in list below, check to make sure style is already installed. If it is not installed, check if it was uploaded correctly.', - 'INVALID_STYLE_ID' => 'Invalid style ID.', + 'INHERITING_FROM' => 'Inherits from', + 'INSTALL_STYLE' => 'Install style', + 'INSTALL_STYLES' => 'Install styles', + 'INSTALL_STYLES_EXPLAIN' => 'Here you can install new styles.<br>If you cannot find a specific style in list below, check to make sure style is already installed. If it is not installed, check if it was uploaded correctly.', + 'INVALID_STYLE_ID' => 'Invalid style ID.', - 'NO_MATCHING_STYLES_FOUND' => 'No styles match your query.', - 'NO_UNINSTALLED_STYLE' => 'No uninstalled styles detected.', + 'NO_MATCHING_STYLES_FOUND' => 'No styles match your query.', + 'NO_UNINSTALLED_STYLE' => 'No uninstalled styles detected.', - 'PURGED_CACHE' => 'Cache was purged.', + 'PURGED_CACHE' => 'Cache was purged.', - 'REQUIRES_STYLE' => 'This style requires the style "%s" to be installed.', + 'REQUIRES_STYLE' => 'This style requires the style "%s" to be installed.', - 'STYLE_ACTIVATE' => 'Activate', - 'STYLE_ACTIVE' => 'Active', - 'STYLE_DEACTIVATE' => 'Deactivate', - 'STYLE_DEFAULT' => 'Make default style', - 'STYLE_DEFAULT_CHANGE_INACTIVE' => 'You must activate style before making it default style.', - 'STYLE_ERR_INVALID_PARENT' => 'Invalid parent style.', - 'STYLE_ERR_NAME_EXIST' => 'A style with that name already exists.', - 'STYLE_ERR_STYLE_NAME' => 'You must supply a name for this style.', - 'STYLE_INSTALLED' => 'Style "%s" has been installed.', + 'STYLE_ACTIVATE' => 'Activate', + 'STYLE_ACTIVE' => 'Active', + 'STYLE_DEACTIVATE' => 'Deactivate', + 'STYLE_DEFAULT' => 'Make default style', + 'STYLE_DEFAULT_CHANGE_INACTIVE' => 'You must activate style before making it default style.', + 'STYLE_ERR_INVALID_PARENT' => 'Invalid parent style.', + 'STYLE_ERR_NAME_EXIST' => 'A style with that name already exists.', + 'STYLE_ERR_STYLE_NAME' => 'You must supply a name for this style.', + 'STYLE_INSTALLED' => 'Style "%s" has been installed.', 'STYLE_INSTALLED_RETURN_INSTALLED_STYLES' => 'Return to installed styles list', 'STYLE_INSTALLED_RETURN_UNINSTALLED_STYLES' => 'Install more styles', - 'STYLE_NAME' => 'Style name', - 'STYLE_NAME_RESERVED' => 'Style "%s" can not be installed, because the name is reserved.', - 'STYLE_NOT_INSTALLED' => 'Style "%s" was not installed.', - 'STYLE_PATH' => 'Style path', - 'STYLE_UNINSTALL' => 'Uninstall', - 'STYLE_UNINSTALL_DEPENDENT' => 'Style "%s" cannot be uninstalled because it has one or more child styles.', - 'STYLE_UNINSTALLED' => 'Style "%s" uninstalled successfully.', - 'STYLE_PHPBB_VERSION' => 'phpBB Version', - 'STYLE_USED_BY' => 'Used by (including robots)', - 'STYLE_VERSION' => 'Style version', + 'STYLE_NAME' => 'Style name', + 'STYLE_NAME_RESERVED' => 'Style "%s" can not be installed, because the name is reserved.', + 'STYLE_NOT_INSTALLED' => 'Style "%s" was not installed.', + 'STYLE_PATH' => 'Style path', + 'STYLE_UNINSTALL' => 'Uninstall', + 'STYLE_UNINSTALL_DEPENDENT' => 'Style "%s" cannot be uninstalled because it has one or more child styles.', + 'STYLE_UNINSTALLED' => 'Style "%s" uninstalled successfully.', + 'STYLE_PHPBB_VERSION' => 'phpBB Version', + 'STYLE_USED_BY' => 'Used by (including robots)', + 'STYLE_VERSION' => 'Style version', - 'UNINSTALL_DEFAULT' => 'You cannot uninstall the default style.', + 'UNINSTALL_PROSILVER' => 'You cannot uninstall the style “prosilver”.', + 'UNINSTALL_DEFAULT' => 'You cannot uninstall the default style.', - 'BROWSE_STYLES_DATABASE' => 'Browse styles database', -)); + 'BROWSE_STYLES_DATABASE' => 'Browse styles database', +]); diff --git a/phpBB/language/en/captcha_recaptcha.php b/phpBB/language/en/captcha_recaptcha.php index dde2a4ba08..68546ae73c 100644 --- a/phpBB/language/en/captcha_recaptcha.php +++ b/phpBB/language/en/captcha_recaptcha.php @@ -43,10 +43,10 @@ $lang = array_merge($lang, array( 'RECAPTCHA_INCORRECT' => 'The solution you provided was incorrect', 'RECAPTCHA_NOSCRIPT' => 'Please enable JavaScript in your browser to load the challenge.', - 'RECAPTCHA_PUBLIC' => 'Public reCaptcha key', - 'RECAPTCHA_PUBLIC_EXPLAIN' => 'Your public reCaptcha key. Keys can be obtained on <a href="http://www.google.com/recaptcha">www.google.com/recaptcha</a>.', - 'RECAPTCHA_PRIVATE' => 'Private reCaptcha key', - 'RECAPTCHA_PRIVATE_EXPLAIN' => 'Your private reCaptcha key. Keys can be obtained on <a href="http://www.google.com/recaptcha">www.google.com/recaptcha</a>.', + 'RECAPTCHA_PUBLIC' => 'Site key', + 'RECAPTCHA_PUBLIC_EXPLAIN' => 'Your site reCAPTCHA key. Keys can be obtained on <a href="http://www.google.com/recaptcha">www.google.com/recaptcha</a>. Please, use reCAPTCHA v2 > Invisible reCAPTCHA badge type.', + 'RECAPTCHA_PRIVATE' => 'Secret key', + 'RECAPTCHA_PRIVATE_EXPLAIN' => 'Your secret reCAPTCHA key. Keys can be obtained on <a href="http://www.google.com/recaptcha">www.google.com/recaptcha</a>. Please, use reCAPTCHA v2 > Invisible reCAPTCHA badge type.', - 'RECAPTCHA_EXPLAIN' => 'In an effort to prevent automatic submissions, we require that you complete the following challenge.', + 'RECAPTCHA_INVISIBLE' => 'This CAPTCHA is actually invisible. To verify that it works, a small icon should appear in right bottom corner of this page.', )); diff --git a/phpBB/language/en/common.php b/phpBB/language/en/common.php index 8a2767e564..5f47fbe6ed 100644 --- a/phpBB/language/en/common.php +++ b/phpBB/language/en/common.php @@ -91,6 +91,7 @@ $lang = array_merge($lang, array( 'ATTACHED_IMAGE_NOT_IMAGE' => 'The image file you tried to attach is invalid.', 'AUTHOR' => 'Author', 'AUTH_NO_PROFILE_CREATED' => 'The creation of a user profile was unsuccessful.', + 'AUTH_PROVIDER_OAUTH_ERROR_ALREADY_LINKED' => 'This external service is already associated with another board account.', 'AUTH_PROVIDER_OAUTH_ERROR_INVALID_ENTRY' => 'Invalid database entry.', 'AUTH_PROVIDER_OAUTH_ERROR_INVALID_SERVICE_TYPE' => 'Invalid service type provided to OAuth service handler.', 'AUTH_PROVIDER_OAUTH_ERROR_SERVICE_NOT_CREATED' => 'OAuth service not created', @@ -391,7 +392,7 @@ $lang = array_merge($lang, array( 'LOGIN_CHECK_PM' => 'Log in to check your private messages.', 'LOGIN_CONFIRMATION' => 'Confirmation of login', 'LOGIN_CONFIRM_EXPLAIN' => 'To prevent brute forcing accounts the board requires you to enter a confirmation code after a maximum amount of failed logins. The code is displayed in the image you should see below. If you are visually impaired or cannot otherwise read this code please contact the %sBoard Administrator%s.', // unused - 'LOGIN_ERROR_ATTEMPTS' => 'You exceeded the maximum allowed number of login attempts. In addition to your username and password you now also have to solve the CAPTCHA below.', + 'LOGIN_ERROR_ATTEMPTS' => 'You exceeded the maximum allowed number of login attempts. In addition to your username and password you now also have to pass the CAPTCHA test.', 'LOGIN_ERROR_EXTERNAL_AUTH_APACHE' => 'You have not been authenticated by Apache.', 'LOGIN_ERROR_OAUTH_SERVICE_DOES_NOT_EXIST' => 'A non-existant OAuth service has been requested.', 'LOGIN_ERROR_PASSWORD' => 'You have specified an incorrect password. Please check your password and try again. If you continue to have problems please contact the %sBoard Administrator%s.', @@ -530,6 +531,7 @@ $lang = array_merge($lang, array( 'NO_FEED_ENABLED' => 'Feeds are not available on this board.', 'NO_FEED' => 'The requested feed is not available.', 'NO_STYLE_DATA' => 'Could not get style data', + 'NO_STYLE_CFG' => 'Could not get the style configuration file for: %s', 'NO_SUBJECT' => 'No subject specified', // Used for posts having no subject defined but displayed within management pages. 'NO_SUCH_SEARCH_MODULE' => 'The specified search backend doesn’t exist.', 'NO_SUPPORTED_AUTH_METHODS' => 'No supported authentication methods.', diff --git a/phpBB/language/en/posting.php b/phpBB/language/en/posting.php index 9157f407dd..639b8d8370 100644 --- a/phpBB/language/en/posting.php +++ b/phpBB/language/en/posting.php @@ -43,6 +43,7 @@ $lang = array_merge($lang, array( 'ADD_POLL' => 'Poll creation', 'ADD_POLL_EXPLAIN' => 'If you do not want to add a poll to your topic leave the fields blank.', 'ALREADY_DELETED' => 'Sorry but this message is already deleted.', + 'ATTACH_COMMENT_NO_EMOJIS' => 'The attachment comment contains forbidden characters (Emoji).', 'ATTACH_DISK_FULL' => 'There is not enough free disk space to post this attachment.', 'ATTACH_QUOTA_REACHED' => 'Sorry, the board attachment quota has been reached.', 'ATTACH_SIG' => 'Attach a signature (signatures can be altered via the UCP)', diff --git a/phpBB/memberlist.php b/phpBB/memberlist.php index 770d484d94..43b58969a5 100644 --- a/phpBB/memberlist.php +++ b/phpBB/memberlist.php @@ -1132,7 +1132,18 @@ switch ($mode) if ($active_time !== false) { - $sql_where .= " AND u.user_lastvisit " . $find_key_match[$active_select] . ' ' . $active_time; + if ($active_select === 'lt' && (int) $active[0] == 0 && (int) $active[1] == 0 && (int) $active[2] == 0) + { + $sql_where .= ' AND u.user_lastvisit = 0'; + } + else if ($active_select === 'gt') + { + $sql_where .= ' AND u.user_lastvisit ' . $find_key_match[$active_select] . ' ' . $active_time; + } + else + { + $sql_where .= ' AND (u.user_lastvisit > 0 AND u.user_lastvisit < ' . $active_time . ')'; + } } } @@ -1728,7 +1739,7 @@ switch ($mode) } // do we need to display contact fields as such - $use_contact_fields = false; + $use_contact_fields = true; /** * Modify list of users before member row is created diff --git a/phpBB/phpbb/auth/provider/oauth/oauth.php b/phpBB/phpbb/auth/provider/oauth/oauth.php index 1a3083d42e..0d94acfbca 100644 --- a/phpBB/phpbb/auth/provider/oauth/oauth.php +++ b/phpBB/phpbb/auth/provider/oauth/oauth.php @@ -634,6 +634,21 @@ class oauth extends \phpbb\auth\provider\base */ protected function link_account_perform_link(array $data) { + // Check if the external account is already associated with other user + $sql = 'SELECT user_id + FROM ' . $this->auth_provider_oauth_token_account_assoc . " + WHERE provider = '" . $this->db->sql_escape($data['provider']) . "' + AND oauth_provider_id = '" . $this->db->sql_escape($data['oauth_provider_id']) . "'"; + $result = $this->db->sql_query($sql); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + if ($row) + { + trigger_error('AUTH_PROVIDER_OAUTH_ERROR_ALREADY_LINKED'); + } + + // Link account $sql = 'INSERT INTO ' . $this->auth_provider_oauth_token_account_assoc . ' ' . $this->db->sql_build_array('INSERT', $data); $this->db->sql_query($sql); diff --git a/phpBB/phpbb/console/command/extension/enable.php b/phpBB/phpbb/console/command/extension/enable.php index a6f5b10e86..f007009aa0 100644 --- a/phpBB/phpbb/console/command/extension/enable.php +++ b/phpBB/phpbb/console/command/extension/enable.php @@ -69,7 +69,10 @@ class enable extends command } else { - $io->error($this->user->lang('CLI_EXTENSION_ENABLE_FAILURE', $name)); + $enableable = $this->manager->get_extension($name)->is_enableable(); + $message = !empty($enableable) ? $enableable : $this->user->lang('CLI_EXTENSION_ENABLE_FAILURE'); + $message = is_array($message) ? implode(PHP_EOL, $message) : $message; + $io->error($message, $name); return 1; } } diff --git a/phpBB/phpbb/db/driver/mysqli.php b/phpBB/phpbb/db/driver/mysqli.php index df8b88c315..0c1c063262 100644 --- a/phpBB/phpbb/db/driver/mysqli.php +++ b/phpBB/phpbb/db/driver/mysqli.php @@ -68,6 +68,9 @@ class mysqli extends \phpbb\db\driver\mysql_base if ($this->db_connect_id && $this->dbname != '') { + // Disable loading local files on client side + @mysqli_options($this->db_connect_id, MYSQLI_OPT_LOCAL_INFILE, false); + @mysqli_query($this->db_connect_id, "SET NAMES 'utf8'"); // enforce strict mode on databases that support it diff --git a/phpBB/phpbb/db/migration/data/v32x/v328.php b/phpBB/phpbb/db/migration/data/v32x/v328.php new file mode 100644 index 0000000000..28ff2c7033 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v32x/v328.php @@ -0,0 +1,36 @@ +<?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\v32x; + +class v328 extends \phpbb\db\migration\migration +{ + public function effectively_installed() + { + return phpbb_version_compare($this->config['version'], '3.2.8', '>='); + } + + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v32x\v328rc1', + ); + } + + public function update_data() + { + return array( + array('config.update', array('version', '3.2.8')), + ); + } +} diff --git a/phpBB/phpbb/db/migration/data/v32x/v328rc1.php b/phpBB/phpbb/db/migration/data/v32x/v328rc1.php new file mode 100644 index 0000000000..fa43cf33a7 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v32x/v328rc1.php @@ -0,0 +1,37 @@ +<?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\v32x; + +class v328rc1 extends \phpbb\db\migration\migration +{ + public function effectively_installed() + { + return phpbb_version_compare($this->config['version'], '3.2.8-RC1', '>='); + } + + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v32x\timezone_p3', + '\phpbb\db\migration\data\v32x\v327', + ); + } + + public function update_data() + { + return array( + array('config.update', array('version', '3.2.8-RC1')), + ); + } +} diff --git a/phpBB/phpbb/extension/extension_interface.php b/phpBB/phpbb/extension/extension_interface.php index 6a6b6adb8f..46072d420c 100644 --- a/phpBB/phpbb/extension/extension_interface.php +++ b/phpBB/phpbb/extension/extension_interface.php @@ -22,7 +22,8 @@ interface extension_interface /** * Indicate whether or not the extension can be enabled. * - * @return bool + * @return bool|array True if extension is enableable, array of reasons + * if not, false for generic reason. */ public function is_enableable(); diff --git a/phpBB/phpbb/filesystem/filesystem.php b/phpBB/phpbb/filesystem/filesystem.php index 943bce3910..9acead0876 100644 --- a/phpBB/phpbb/filesystem/filesystem.php +++ b/phpBB/phpbb/filesystem/filesystem.php @@ -835,7 +835,7 @@ class filesystem implements filesystem_interface $current_path = $resolved_path . '/' . $path_part; // Resolve symlinks - if (is_link($current_path)) + if (@is_link($current_path)) { if (!function_exists('readlink')) { @@ -872,12 +872,12 @@ class filesystem implements filesystem_interface $resolved_path = false; } - else if (is_dir($current_path . '/')) + else if (@is_dir($current_path . '/')) { $resolved[] = $path_part; $resolved_path = $current_path; } - else if (is_file($current_path)) + else if (@is_file($current_path)) { $resolved[] = $path_part; $resolved_path = $current_path; diff --git a/phpBB/phpbb/message/form.php b/phpBB/phpbb/message/form.php index 63bada91ff..6573a04f8b 100644 --- a/phpBB/phpbb/message/form.php +++ b/phpBB/phpbb/message/form.php @@ -136,7 +136,7 @@ abstract class form { if (!check_form_key('memberlist_email')) { - $this->errors[] = 'FORM_INVALID'; + $this->errors[] = $this->user->lang('FORM_INVALID'); } if (!count($this->errors)) diff --git a/phpBB/phpbb/notification/type/approve_post.php b/phpBB/phpbb/notification/type/approve_post.php index 1e8afec3f9..139b5fabb9 100644 --- a/phpBB/phpbb/notification/type/approve_post.php +++ b/phpBB/phpbb/notification/type/approve_post.php @@ -78,10 +78,7 @@ class approve_post extends \phpbb\notification\type\post 'ignore_users' => array(), ), $options); - $users = array(); - $users[$post['poster_id']] = $this->notification_manager->get_default_methods(); - - return $this->get_authorised_recipients(array_keys($users), $post['forum_id'], array_merge($options, array( + return $this->get_authorised_recipients(array($post['poster_id']), $post['forum_id'], array_merge($options, array( '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 f0bbf3f6b0..0c343646ee 100644 --- a/phpBB/phpbb/notification/type/approve_topic.php +++ b/phpBB/phpbb/notification/type/approve_topic.php @@ -78,10 +78,7 @@ class approve_topic extends \phpbb\notification\type\topic 'ignore_users' => array(), ), $options); - $users = array(); - $users[$post['poster_id']] = $this->notification_manager->get_default_methods(); - - return $this->get_authorised_recipients(array_keys($users), $post['forum_id'], array_merge($options, array( + return $this->get_authorised_recipients(array($post['poster_id']), $post['forum_id'], array_merge($options, array( 'item_type' => static::$notification_option['id'], ))); } diff --git a/phpBB/phpbb/plupload/plupload.php b/phpBB/phpbb/plupload/plupload.php index eb698fb35d..9ad12b1082 100644 --- a/phpBB/phpbb/plupload/plupload.php +++ b/phpBB/phpbb/plupload/plupload.php @@ -216,38 +216,36 @@ class plupload } /** - * Looks at the list of allowed extensions and generates a string - * appropriate for use in configuring plupload with - * - * @param \phpbb\cache\service $cache - * @param string $forum_id The ID of the forum - * - * @return string - */ + * Looks at the list of allowed extensions and generates a string + * appropriate for use in configuring plupload with + * + * @param \phpbb\cache\service $cache Cache service object + * @param string $forum_id The forum identifier + * + * @return string + */ public function generate_filter_string(\phpbb\cache\service $cache, $forum_id) { + $groups = []; + $filters = []; + $attach_extensions = $cache->obtain_attach_extensions($forum_id); unset($attach_extensions['_allowed_']); - $groups = array(); // Re-arrange the extension array to $groups[$group_name][] foreach ($attach_extensions as $extension => $extension_info) { - if (!isset($groups[$extension_info['group_name']])) - { - $groups[$extension_info['group_name']] = array(); - } - - $groups[$extension_info['group_name']][] = $extension; + $groups[$extension_info['group_name']]['extensions'][] = $extension; + $groups[$extension_info['group_name']]['max_file_size'] = (int) $extension_info['max_filesize']; } - $filters = array(); - foreach ($groups as $group => $extensions) + foreach ($groups as $group => $group_info) { $filters[] = sprintf( - "{title: '%s', extensions: '%s'}", + "{title: '%s', extensions: '%s', max_file_size: %s}", addslashes(ucfirst(strtolower($group))), - addslashes(implode(',', $extensions)) + addslashes(implode(',', $group_info['extensions'])), + $group_info['max_file_size'] ); } diff --git a/phpBB/phpbb/template/twig/extension.php b/phpBB/phpbb/template/twig/extension.php index c5b3db1aaf..1131a7f3aa 100644 --- a/phpBB/phpbb/template/twig/extension.php +++ b/phpBB/phpbb/template/twig/extension.php @@ -30,7 +30,6 @@ class extension extends \Twig_Extension * @param \phpbb\template\context $context * @param \phpbb\template\twig\environment $environment * @param \phpbb\language\language $language - * @return \phpbb\template\twig\extension */ public function __construct(\phpbb\template\context $context, \phpbb\template\twig\environment $environment, $language) { @@ -91,6 +90,7 @@ class extension extends \Twig_Extension return array( new \Twig_SimpleFunction('lang', array($this, 'lang')), new \Twig_SimpleFunction('lang_defined', array($this, 'lang_defined')), + new \Twig_SimpleFunction('get_class', 'get_class'), ); } @@ -190,10 +190,10 @@ class extension extends \Twig_Extension } /** - * Check if a language variable exists - * - * @return bool - */ + * Check if a language variable exists + * + * @return bool + */ public function lang_defined($key) { return call_user_func_array([$this->language, 'is_set'], [$key]); diff --git a/phpBB/phpbb/template/twig/extension/avatar.php b/phpBB/phpbb/template/twig/extension/avatar.php new file mode 100644 index 0000000000..7a17fd4b42 --- /dev/null +++ b/phpBB/phpbb/template/twig/extension/avatar.php @@ -0,0 +1,80 @@ +<?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\template\twig\extension; + +class avatar extends \Twig_Extension +{ + /** + * Get the name of this extension + * + * @return string + */ + public function getName() + { + return 'avatar'; + } + + /** + * Returns a list of global functions to add to the existing list. + * + * @return array An array of global functions + */ + public function getFunctions() + { + return array( + new \Twig_SimpleFunction('avatar', array($this, 'get_avatar')), + ); + } + + /** + * Get avatar for placing into templates. + * + * How to use in a template: + * - {{ avatar('mode', row, alt, ignore_config, lazy) }} + * + * The mode and row (group_row or user_row) are required. + * The other fields (alt|ignore_config|lazy) are optional. + * + * @uses \phpbb_get_group_avatar() + * @uses \phpbb_get_user_avatar() + * + * @return string The avatar HTML for the specified mode + */ + public function get_avatar() + { + $args = func_get_args(); + + $mode = (string) $args[0]; + $row = (array) $args[1]; + $alt = isset($args[2]) ? (string) $args[2] : false; + $ignore_config = isset($args[3]) ? (bool) $args[3] : false; + $lazy = isset($args[4]) ? (bool) $args[4] : false; + + // To prevent having to redefine alt attribute ('USER_AVATAR'|'GROUP_AVATAR'), we check if an alternative has been provided + switch ($mode) + { + case 'group': + return $alt ? phpbb_get_group_avatar($row, $alt, $ignore_config, $lazy) : phpbb_get_group_avatar($row); + break; + + case 'user': + return $alt ? phpbb_get_user_avatar($row, $alt, $ignore_config, $lazy) : phpbb_get_user_avatar($row); + break; + + default: + return ''; + break; + } + } +} diff --git a/phpBB/phpbb/template/twig/extension/config.php b/phpBB/phpbb/template/twig/extension/config.php new file mode 100644 index 0000000000..cbf6e505c5 --- /dev/null +++ b/phpBB/phpbb/template/twig/extension/config.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\template\twig\extension; + +class config extends \Twig_Extension +{ + /** @var \phpbb\config\config */ + protected $config; + + /** + * Constructor. + * + * @param \phpbb\config\config $config Configuration object + */ + public function __construct(\phpbb\config\config $config) + { + $this->config = $config; + } + + /** + * Get the name of this extension + * + * @return string + */ + public function getName() + { + return 'config'; + } + + /** + * Returns a list of global functions to add to the existing list. + * + * @return array An array of global functions + */ + public function getFunctions() + { + return array( + new \Twig_SimpleFunction('config', array($this, 'get_config')), + ); + } + + /** + * Retrieves a configuration value for use in templates. + * + * @return string The configuration value + */ + public function get_config() + { + $args = func_get_args(); + + return $this->config->offsetGet($args[0]); + } +} diff --git a/phpBB/phpbb/template/twig/extension/username.php b/phpBB/phpbb/template/twig/extension/username.php new file mode 100644 index 0000000000..ef149693a0 --- /dev/null +++ b/phpBB/phpbb/template/twig/extension/username.php @@ -0,0 +1,84 @@ +<?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\template\twig\extension; + +class username extends \Twig_Extension +{ + /** + * Get the name of this extension + * + * @return string + */ + public function getName() + { + return 'username'; + } + + /** + * Returns a list of global functions to add to the existing list. + * + * @return array An array of global functions + */ + public function getFunctions() + { + return array( + new \Twig_SimpleFunction('username', array($this, 'get_username')), + ); + } + + /** + * Get username details for placing into templates. + * + * How to use in a template: + * - {{ username('mode', user_id, username, user_colour, guest_username, custom_profile_url) }} + * - {{ username('mode', user_row, guest_username, custom_profile_url) }} + * It's possible to provide the user identifier, name and colour separately, + * or provide the entire user row at once as an array. + * + * The mode, user_id and username are required (separately or through a user row). + * The other fields (user_colour|guest_username|custom_profile_url) are optional. + * + * @uses \get_username_string() + * + * @return string A string based on what is wanted depending on $mode + */ + public function get_username() + { + $args = func_get_args(); + + $mode = $args[0]; + $user = $args[1]; + + // If the entire user row is provided + if (is_array($user)) + { + $user_id = isset($user['user_id']) ? $user['user_id'] : ''; + $username = isset($user['username']) ? $user['username'] : ''; + $user_colour = isset($user['user_colour']) ? $user['user_colour'] : ''; + $guest_username = isset($args[2]) ? $args[2] : false; + $custom_profile_url = isset($args[3]) ? $args[3] : false; + } + else + { + // Options are provided separately + $user_id = $user; + $username = $args[2]; + $user_colour = isset($args[3]) ? $args[3] : ''; + $guest_username = isset($args[4]) ? $args[4] : false; + $custom_profile_url = isset($args[5]) ? $args[5] : false; + } + + return get_username_string($mode, $user_id, $username, $user_colour, $guest_username, $custom_profile_url); + } +} diff --git a/phpBB/phpbb/textformatter/s9e/factory.php b/phpBB/phpbb/textformatter/s9e/factory.php index 6191b9a315..dca1c78d40 100644 --- a/phpBB/phpbb/textformatter/s9e/factory.php +++ b/phpBB/phpbb/textformatter/s9e/factory.php @@ -110,7 +110,7 @@ class factory implements \phpbb\textformatter\cache_interface 'i' => '<span style="font-style: italic"><xsl:apply-templates/></span>', 'u' => '<span style="text-decoration: underline"><xsl:apply-templates/></span>', 'img' => '<img src="{IMAGEURL}" class="postimage" alt="{L_IMAGE}"/>', - 'size' => '<span style="font-size: {FONTSIZE}%; line-height: normal"><xsl:apply-templates/></span>', + 'size' => '<span><xsl:attribute name="style"><xsl:text>font-size: </xsl:text><xsl:value-of select="substring(@size, 1, 4)"/><xsl:text>%; line-height: normal</xsl:text></xsl:attribute><xsl:apply-templates/></span>', 'color' => '<span style="color: {COLOR}"><xsl:apply-templates/></span>', 'email' => '<a> <xsl:attribute name="href"> diff --git a/phpBB/phpbb/textformatter/s9e/parser.php b/phpBB/phpbb/textformatter/s9e/parser.php index 3698dca224..a36fc63141 100644 --- a/phpBB/phpbb/textformatter/s9e/parser.php +++ b/phpBB/phpbb/textformatter/s9e/parser.php @@ -342,7 +342,7 @@ class parser implements \phpbb\textformatter\parser_interface return false; } - if ($size < 1) + if ($size < 1 || !is_numeric($size)) { return false; } diff --git a/phpBB/posting.php b/phpBB/posting.php index e4ba0303cc..20f6ddf8e5 100644 --- a/phpBB/posting.php +++ b/phpBB/posting.php @@ -974,7 +974,10 @@ if ($submit || $preview || $refresh) } // Parse Attachments - before checksum is calculated - $message_parser->parse_attachments('fileupload', $mode, $forum_id, $submit, $preview, $refresh); + if ($message_parser->check_attachment_form_token($language, $request, 'posting')) + { + $message_parser->parse_attachments('fileupload', $mode, $forum_id, $submit, $preview, $refresh); + } /** * This event allows you to modify message text before parsing diff --git a/phpBB/search.php b/phpBB/search.php index 4f4a14109b..8dde46f999 100644 --- a/phpBB/search.php +++ b/phpBB/search.php @@ -1103,9 +1103,12 @@ if ($keywords || $author || $author_id || $search_id || $submit) 'TOPIC_AUTHOR_COLOUR' => get_username_string('colour', $row['topic_poster'], $row['topic_first_poster_name'], $row['topic_first_poster_colour']), 'TOPIC_AUTHOR_FULL' => get_username_string('full', $row['topic_poster'], $row['topic_first_poster_name'], $row['topic_first_poster_colour']), 'FIRST_POST_TIME' => $user->format_date($row['topic_time']), + 'FIRST_POST_TIME_RFC3339' => gmdate(DATE_RFC3339, $row['topic_time']), 'LAST_POST_SUBJECT' => $row['topic_last_post_subject'], 'LAST_POST_TIME' => $user->format_date($row['topic_last_post_time']), + 'LAST_POST_TIME_RFC3339' => gmdate(DATE_RFC3339, $row['topic_last_post_time']), 'LAST_VIEW_TIME' => $user->format_date($row['topic_last_view_time']), + 'LAST_VIEW_TIME_RFC3339' => gmdate(DATE_RFC3339, $row['topic_last_view_time']), 'LAST_POST_AUTHOR' => get_username_string('username', $row['topic_last_poster_id'], $row['topic_last_poster_name'], $row['topic_last_poster_colour']), 'LAST_POST_AUTHOR_COLOUR' => get_username_string('colour', $row['topic_last_poster_id'], $row['topic_last_poster_name'], $row['topic_last_poster_colour']), 'LAST_POST_AUTHOR_FULL' => get_username_string('full', $row['topic_last_poster_id'], $row['topic_last_poster_name'], $row['topic_last_poster_colour']), diff --git a/phpBB/styles/prosilver/template/attachment.html b/phpBB/styles/prosilver/template/attachment.html index 49c49f52a0..45b9dc2145 100644 --- a/phpBB/styles/prosilver/template/attachment.html +++ b/phpBB/styles/prosilver/template/attachment.html @@ -8,14 +8,14 @@ <!-- IF _file.S_THUMBNAIL --> <dl class="thumbnail"> - <dt><a href="{_file.U_DOWNLOAD_LINK}"><img src="{_file.THUMB_IMAGE}" class="postimage" alt="{_file.DOWNLOAD_NAME}" title="{_file.DOWNLOAD_NAME} ({_file.FILESIZE} {_file.SIZE_LANG}) {_file.L_DOWNLOAD_COUNT}" /></a></dt> + <dt><a href="{_file.U_DOWNLOAD_LINK}"><img src="{_file.THUMB_IMAGE}" class="postimage" alt="{% if _file.COMMENT %}{{ _file.COMMENT|e('html') }}{% else %}{{ _file.DOWNLOAD_NAME }}{% endif %}" title="{_file.DOWNLOAD_NAME} ({_file.FILESIZE} {_file.SIZE_LANG}) {_file.L_DOWNLOAD_COUNT}" /></a></dt> <!-- IF _file.COMMENT --><dd> {_file.COMMENT}</dd><!-- ENDIF --> </dl> <!-- ENDIF --> <!-- IF _file.S_IMAGE --> <dl class="file"> - <dt class="attach-image"><img src="{_file.U_INLINE_LINK}" class="postimage" alt="{_file.DOWNLOAD_NAME}" onclick="viewableArea(this);" /></dt> + <dt class="attach-image"><img src="{_file.U_INLINE_LINK}" class="postimage" alt="{% if _file.COMMENT %}{{ _file.COMMENT|e('html') }}{% else %}{{ _file.DOWNLOAD_NAME }}{% endif %}" onclick="viewableArea(this);" /></dt> <!-- IF _file.COMMENT --><dd><em>{_file.COMMENT}</em></dd><!-- ENDIF --> <dd>{_file.DOWNLOAD_NAME} ({_file.FILESIZE} {_file.SIZE_LANG}) {_file.L_DOWNLOAD_COUNT}</dd> </dl> diff --git a/phpBB/styles/prosilver/template/captcha_recaptcha.html b/phpBB/styles/prosilver/template/captcha_recaptcha.html index a123f543a8..8fc7faa50f 100644 --- a/phpBB/styles/prosilver/template/captcha_recaptcha.html +++ b/phpBB/styles/prosilver/template/captcha_recaptcha.html @@ -1,30 +1,9 @@ -<!-- IF S_TYPE == 1 --> -<div class="panel captcha-panel"> - <div class="inner"> - - <h3 class="captcha-title">{L_CONFIRMATION}</h3> - <p>{L_CONFIRM_EXPLAIN}</p> - - <fieldset class="fields2"> -<!-- ENDIF --> - <!-- IF S_RECAPTCHA_AVAILABLE --> - <dl> - <dt><label>{L_CONFIRM_CODE}{L_COLON}</label><br /><span>{L_RECAPTCHA_EXPLAIN}</span></dt> - <dd class="captcha"> - <noscript> - <div>{L_RECAPTCHA_NOSCRIPT}</div> - </noscript> - <script src="{RECAPTCHA_SERVER}.js?hl={LA_RECAPTCHA_LANG}" async defer></script> - <div class="g-recaptcha" data-sitekey="{RECAPTCHA_PUBKEY}" data-tabindex="<!-- IF $CAPTCHA_TAB_INDEX -->{$CAPTCHA_TAB_INDEX}<!-- ELSE -->10<!-- ENDIF -->"></div> - </dd> - </dl> + <noscript> + <div>{L_RECAPTCHA_NOSCRIPT}</div> + </noscript> + {% INCLUDEJS RECAPTCHA_SERVER ~ '.js?onload=phpbbRecaptchaOnLoad&hl=' ~ lang('RECAPTCHA_LANG') %} + <div class="g-recaptcha" data-sitekey="{RECAPTCHA_PUBKEY}" data-callback="phpbbRecaptchaOnSubmit" data-size="invisible" data-tabindex="<!-- IF $CAPTCHA_TAB_INDEX -->{$CAPTCHA_TAB_INDEX}<!-- ELSE -->10<!-- ENDIF -->"></div> <!-- ELSE --> {L_RECAPTCHA_NOT_AVAILABLE} <!-- ENDIF --> - -<!-- IF S_TYPE == 1 --> - </fieldset> - </div> -</div> -<!-- ENDIF --> diff --git a/phpBB/styles/prosilver/template/forumlist_body.html b/phpBB/styles/prosilver/template/forumlist_body.html index 8250a1fd07..4932860f8c 100644 --- a/phpBB/styles/prosilver/template/forumlist_body.html +++ b/phpBB/styles/prosilver/template/forumlist_body.html @@ -101,7 +101,7 @@ <i class="icon fa-external-link-square fa-fw icon-lightgray icon-md" aria-hidden="true"></i><span class="sr-only">{L_VIEW_LATEST_POST}</span> </a> <!-- ENDIF --> - <br />{forumrow.LAST_POST_TIME} + <br /><time datetime="{forumrow.LAST_POST_TIME_RFC3339}">{forumrow.LAST_POST_TIME}</time> <!-- ELSE --> {% if forumrow.U_UNAPPROVED_TOPICS %} {{ lang('TOPIC_UNAPPROVED_FORUM', forumrow.TOPICS) }} diff --git a/phpBB/styles/prosilver/template/mcp_topic.html b/phpBB/styles/prosilver/template/mcp_topic.html index b56ed188c1..090e24041e 100644 --- a/phpBB/styles/prosilver/template/mcp_topic.html +++ b/phpBB/styles/prosilver/template/mcp_topic.html @@ -120,7 +120,7 @@ <p class="author"> <a href="#pr{postrow.POST_ID}" title="{postrow.MINI_POST}"> <i class="icon fa-file fa-fw icon-lightgray icon-tiny" aria-hidden="true"></i><span class="sr-only">{postrow.MINI_POST}</span> - </a> {L_POSTED} {postrow.POST_DATE} {L_POST_BY_AUTHOR} <strong>{postrow.POST_AUTHOR_FULL}</strong><!-- IF postrow.U_MCP_DETAILS --> [ <a href="{postrow.U_MCP_DETAILS}">{L_POST_DETAILS}</a> ]<!-- ENDIF --> + </a> {L_POSTED} {postrow.POST_DATE} {L_POST_BY_AUTHOR} {% EVENT mcp_topic_post_author_full_prepend %}<strong>{postrow.POST_AUTHOR_FULL}</strong>{% EVENT mcp_topic_post_author_full_append %}<!-- IF postrow.U_MCP_DETAILS --> [ <a href="{postrow.U_MCP_DETAILS}">{L_POST_DETAILS}</a> ]<!-- ENDIF --> </p> <!-- EVENT mcp_topic_postrow_post_details_after --> diff --git a/phpBB/styles/prosilver/template/memberlist_body.html b/phpBB/styles/prosilver/template/memberlist_body.html index 5f03ad99cc..745f9a58a8 100644 --- a/phpBB/styles/prosilver/template/memberlist_body.html +++ b/phpBB/styles/prosilver/template/memberlist_body.html @@ -120,7 +120,13 @@ <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 class="info"> + {%- for field in memberrow.custom_fields -%} + <div>{% if field.S_PROFILE_CONTACT %}<a href="{{ field.PROFILE_FIELD_CONTACT }}">{% endif %}{{ field.PROFILE_FIELD_VALUE }}{% if field.S_PROFILE_CONTACT %}</a>{% endif %}</div> + {%- else -%} + + {%- endfor -%} + </td> <td>{memberrow.JOINED}</td> <!-- IF S_VIEWONLINE --><td>{memberrow.LAST_ACTIVE} </td><!-- ENDIF --> {% EVENT memberlist_body_memberrow_after %} diff --git a/phpBB/styles/prosilver/template/navbar_header.html b/phpBB/styles/prosilver/template/navbar_header.html index 9584aaf415..ecb67012a4 100644 --- a/phpBB/styles/prosilver/template/navbar_header.html +++ b/phpBB/styles/prosilver/template/navbar_header.html @@ -160,7 +160,7 @@ </li> <!-- ENDIF --> <!-- EVENT navbar_header_user_profile_append --> - <!-- ELSE --> + <!-- ELSE IF not S_IS_BOT --> <li class="rightside" data-skip-responsive="true"> <a href="{U_LOGIN_LOGOUT}" title="{L_LOGIN_LOGOUT}" accesskey="x" role="menuitem"> <i class="icon fa-power-off fa-fw" aria-hidden="true"></i><span>{L_LOGIN_LOGOUT}</span> diff --git a/phpBB/styles/prosilver/template/plupload.html b/phpBB/styles/prosilver/template/plupload.html index 1eb84372e8..9425b7d769 100644 --- a/phpBB/styles/prosilver/template/plupload.html +++ b/phpBB/styles/prosilver/template/plupload.html @@ -45,7 +45,14 @@ phpbb.plupload = { max_file_size: '{FILESIZE}b', chunk_size: '{CHUNK_SIZE}b', unique_names: true, - filters: [{FILTERS}], + filters: { + mime_types: [ + {FILTERS} + ], + mime_types_max_file_size: [ + {FILTERS} + ], + }, {S_RESIZE} headers: {'X-PHPBB-USING-PLUPLOAD': '1', 'X-Requested-With': 'XMLHttpRequest'}, file_data_name: 'fileupload', @@ -57,6 +64,7 @@ phpbb.plupload = { lang: { ERROR: '{LA_ERROR}', TOO_MANY_ATTACHMENTS: '{LA_TOO_MANY_ATTACHMENTS}', + FORM_INVALID: '{LA_FORM_INVALID}', }, order: '{ATTACH_ORDER}', maxFiles: {MAX_ATTACHMENTS}, diff --git a/phpBB/styles/prosilver/template/posting_buttons.html b/phpBB/styles/prosilver/template/posting_buttons.html index fb395fb291..1564b5f522 100644 --- a/phpBB/styles/prosilver/template/posting_buttons.html +++ b/phpBB/styles/prosilver/template/posting_buttons.html @@ -10,27 +10,6 @@ var bbtags = new Array('[b]','[/b]','[i]','[/i]','[u]','[/u]','[quote]','[/quote]','[code]','[/code]','[list]','[/list]','[list=]','[/list]','[img]','[/img]','[url]','[/url]','[flash=]', '[/flash]','[size=]','[/size]'<!-- BEGIN custom_tags -->, {custom_tags.BBCODE_NAME}<!-- END custom_tags -->); var imageTag = false; - // Helpline messages - var help_line = { - b: '{LA_BBCODE_B_HELP}', - i: '{LA_BBCODE_I_HELP}', - u: '{LA_BBCODE_U_HELP}', - q: '{LA_BBCODE_Q_HELP}', - c: '{LA_BBCODE_C_HELP}', - l: '{LA_BBCODE_L_HELP}', - o: '{LA_BBCODE_O_HELP}', - p: '{LA_BBCODE_P_HELP}', - w: '{LA_BBCODE_W_HELP}', - a: '{LA_BBCODE_A_HELP}', - s: '{LA_BBCODE_S_HELP}', - f: '{LA_BBCODE_F_HELP}', - y: '{LA_BBCODE_Y_HELP}', - d: '{LA_BBCODE_D_HELP}' - <!-- BEGIN custom_tags --> - ,cb_{custom_tags.BBCODE_ID}: '{custom_tags.A_BBCODE_HELPLINE}' - <!-- END custom_tags --> - } - function change_palette() { phpbb.toggleDisplay('colour_palette'); @@ -117,7 +96,7 @@ <!-- EVENT posting_editor_buttons_custom_tags_before --> <!-- BEGIN custom_tags --> - <button type="button" class="button button-secondary bbcode-{custom_tags.BBCODE_TAG_CLEAN}" name="addbbcode{custom_tags.BBCODE_ID}" value="{custom_tags.BBCODE_TAG}" onclick="bbstyle({custom_tags.BBCODE_ID})" title="{custom_tags.BBCODE_HELPLINE}"> + <button type="button" class="button button-secondary bbcode-{custom_tags.BBCODE_TAG_CLEAN}" name="addbbcode{custom_tags.BBCODE_ID}" value="{custom_tags.BBCODE_TAG}" onclick="bbstyle({custom_tags.BBCODE_ID})" title="{{ custom_tags.BBCODE_HELPLINE|e('html_attr') }}"> {custom_tags.BBCODE_TAG} </button> <!-- END custom_tags --> diff --git a/phpBB/styles/prosilver/template/search_results.html b/phpBB/styles/prosilver/template/search_results.html index 391afa4d7f..9ee13a4224 100644 --- a/phpBB/styles/prosilver/template/search_results.html +++ b/phpBB/styles/prosilver/template/search_results.html @@ -108,7 +108,7 @@ <!-- IF not S_IS_BOT --> <div class="responsive-show" style="display: none;"> - {L_LAST_POST} {L_POST_BY_AUTHOR} <!-- EVENT search_results_last_post_author_username_prepend -->{searchresults.LAST_POST_AUTHOR_FULL}<!-- EVENT search_results_last_post_author_username_append --> « <a href="{searchresults.U_LAST_POST}" title="{L_GOTO_LAST_POST}">{searchresults.LAST_POST_TIME}</a> + {L_LAST_POST} {L_POST_BY_AUTHOR} <!-- EVENT search_results_last_post_author_username_prepend -->{searchresults.LAST_POST_AUTHOR_FULL}<!-- EVENT search_results_last_post_author_username_append --> « <a href="{searchresults.U_LAST_POST}" title="{L_GOTO_LAST_POST}"><time datetime="{searchresults.LAST_POST_TIME_RFC3339}">{searchresults.LAST_POST_TIME}</time></a> <br />{L_POSTED} {L_IN} <a href="{searchresults.U_VIEW_FORUM}">{searchresults.FORUM_TITLE}</a> </div> <!-- IF searchresults.TOPIC_REPLIES --><span class="responsive-show left-box" style="display: none;">{L_REPLIES}{L_COLON} <strong>{searchresults.TOPIC_REPLIES}</strong></span><!-- ENDIF --> @@ -118,7 +118,7 @@ <!-- IF searchresults.S_HAS_POLL --><i class="icon fa-bar-chart fa-fw" aria-hidden="true"></i><!-- ENDIF --> <!-- IF searchresults.ATTACH_ICON_IMG --><i class="icon fa-paperclip fa-fw" aria-hidden="true"></i><!-- ENDIF --> {% EVENT topiclist_row_topic_by_author_before %} - {L_POST_BY_AUTHOR} <!-- EVENT search_results_topic_author_username_prepend -->{searchresults.TOPIC_AUTHOR_FULL}<!-- EVENT search_results_topic_author_username_append --> » {searchresults.FIRST_POST_TIME} » {L_IN} <a href="{searchresults.U_VIEW_FORUM}">{searchresults.FORUM_TITLE}</a> + {L_POST_BY_AUTHOR} <!-- EVENT search_results_topic_author_username_prepend -->{searchresults.TOPIC_AUTHOR_FULL}<!-- EVENT search_results_topic_author_username_append --> » <time datetime="{searchresults.FIRST_POST_TIME_RFC3339}">{searchresults.FIRST_POST_TIME}</time> » {L_IN} <a href="{searchresults.U_VIEW_FORUM}">{searchresults.FORUM_TITLE}</a> {% EVENT topiclist_row_topic_by_author_after %} </div> @@ -150,7 +150,7 @@ <i class="icon fa-external-link-square fa-fw icon-lightgray icon-md" aria-hidden="true"></i><span class="sr-only">{VIEW_LATEST_POST}</span> </a> <!-- ENDIF --> - <br />{searchresults.LAST_POST_TIME} + <br /><time datetime="{searchresults.LAST_POST_TIME_RFC3339}">{searchresults.LAST_POST_TIME}</time> </span> </dd> </dl> diff --git a/phpBB/styles/prosilver/template/ucp_pm_viewmessage_print.html b/phpBB/styles/prosilver/template/ucp_pm_viewmessage_print.html index 7a8849258a..41ff5b898a 100644 --- a/phpBB/styles/prosilver/template/ucp_pm_viewmessage_print.html +++ b/phpBB/styles/prosilver/template/ucp_pm_viewmessage_print.html @@ -42,7 +42,14 @@ <div id="page-footer" class="page-footer"> <div class="page-number">{S_TIMEZONE}<br />{PAGE_NUMBER}</div> - <div class="copyright">Powered by phpBB® Forum Software © phpBB Limited<br />https://www.phpbb.com/</div> + <div class="copyright"> + <p>{{ CREDIT_LINE }} + </p> + {% if TRANSLATION_INFO %} + <p>{{ TRANSLATION_INFO }} + </p> + {% endif %} + </div> </div> </div> diff --git a/phpBB/styles/prosilver/template/viewforum_body.html b/phpBB/styles/prosilver/template/viewforum_body.html index 1827738019..40beb784d7 100644 --- a/phpBB/styles/prosilver/template/viewforum_body.html +++ b/phpBB/styles/prosilver/template/viewforum_body.html @@ -187,7 +187,7 @@ <!-- IF not S_IS_BOT --> <div class="responsive-show" style="display: none;"> - {L_LAST_POST} {L_POST_BY_AUTHOR} <!-- EVENT viewforum_body_last_post_author_username_prepend -->{topicrow.LAST_POST_AUTHOR_FULL}<!-- EVENT viewforum_body_last_post_author_username_append --> « <a href="{topicrow.U_LAST_POST}" title="{L_GOTO_LAST_POST}">{topicrow.LAST_POST_TIME}</a> + {L_LAST_POST} {L_POST_BY_AUTHOR} <!-- EVENT viewforum_body_last_post_author_username_prepend -->{topicrow.LAST_POST_AUTHOR_FULL}<!-- EVENT viewforum_body_last_post_author_username_append --> « <a href="{topicrow.U_LAST_POST}" title="{L_GOTO_LAST_POST}"><time datetime="{topicrow.LAST_POST_TIME_RFC3339}">{topicrow.LAST_POST_TIME}</time></a> <!-- IF topicrow.S_POST_GLOBAL and FORUM_ID != topicrow.FORUM_ID --><br />{L_POSTED} {L_IN} <a href="{topicrow.U_VIEW_FORUM}">{topicrow.FORUM_NAME}</a><!-- ENDIF --> </div> <!-- IF topicrow.REPLIES --> @@ -199,7 +199,7 @@ <!-- IF topicrow.S_HAS_POLL --><i class="icon fa-bar-chart fa-fw" aria-hidden="true"></i><!-- ENDIF --> <!-- IF topicrow.ATTACH_ICON_IMG --><i class="icon fa-paperclip fa-fw" aria-hidden="true"></i><!-- ENDIF --> {% EVENT topiclist_row_topic_by_author_before %} - {L_POST_BY_AUTHOR} <!-- EVENT viewforum_body_topic_author_username_prepend -->{topicrow.TOPIC_AUTHOR_FULL}<!-- EVENT viewforum_body_topic_author_username_append --> » {topicrow.FIRST_POST_TIME} + {L_POST_BY_AUTHOR} <!-- EVENT viewforum_body_topic_author_username_prepend -->{topicrow.TOPIC_AUTHOR_FULL}<!-- EVENT viewforum_body_topic_author_username_append --> » <time datetime="{topicrow.FIRST_POST_TIME_RFC3339}">{topicrow.FIRST_POST_TIME}</time> {% EVENT topiclist_row_topic_by_author_after %} <!-- IF topicrow.S_POST_GLOBAL and FORUM_ID != topicrow.FORUM_ID --> » {L_IN} <a href="{topicrow.U_VIEW_FORUM}">{topicrow.FORUM_NAME}</a><!-- ENDIF --> </div> @@ -232,7 +232,7 @@ <i class="icon fa-external-link-square fa-fw icon-lightgray icon-md" aria-hidden="true"></i><span class="sr-only">{VIEW_LATEST_POST}</span> </a> <!-- ENDIF --> - <br />{topicrow.LAST_POST_TIME} + <br /><time datetime="{topicrow.LAST_POST_TIME_RFC3339}">{topicrow.LAST_POST_TIME}</time> </span> </dd> </dl> diff --git a/phpBB/styles/prosilver/template/viewtopic_body.html b/phpBB/styles/prosilver/template/viewtopic_body.html index 8d7e26f099..f77b99dc29 100644 --- a/phpBB/styles/prosilver/template/viewtopic_body.html +++ b/phpBB/styles/prosilver/template/viewtopic_body.html @@ -289,7 +289,7 @@ <i class="icon fa-file fa-fw <!-- IF postrow.S_UNREAD_POST -->icon-red<!-- ELSE -->icon-lightgray<!-- ENDIF --> icon-md" aria-hidden="true"></i><span class="sr-only">{postrow.MINI_POST}</span> </a> <!-- ENDIF --> - <span class="responsive-hide">{L_POST_BY_AUTHOR} <strong>{postrow.POST_AUTHOR_FULL}</strong> » </span>{postrow.POST_DATE} + <span class="responsive-hide">{L_POST_BY_AUTHOR} <strong>{postrow.POST_AUTHOR_FULL}</strong> » </span><time datetime="{postrow.POST_DATE_RFC3339}">{postrow.POST_DATE}</time> </p> <!-- EVENT viewtopic_body_postrow_post_details_after --> diff --git a/phpBB/styles/prosilver/template/viewtopic_print.html b/phpBB/styles/prosilver/template/viewtopic_print.html index b504949053..658062f9fd 100644 --- a/phpBB/styles/prosilver/template/viewtopic_print.html +++ b/phpBB/styles/prosilver/template/viewtopic_print.html @@ -38,7 +38,14 @@ <div id="page-footer" class="page-footer"> <div class="page-number">{S_TIMEZONE}<br />{PAGE_NUMBER}</div> - <div class="copyright">Powered by phpBB® Forum Software © phpBB Limited<br />https://www.phpbb.com/</div> + <div class="copyright"> + <p>{{ CREDIT_LINE }} + </p> + {% if TRANSLATION_INFO %} + <p>{{ TRANSLATION_INFO }} + </p> + {% endif %} + </div> </div> </div> diff --git a/phpBB/viewforum.php b/phpBB/viewforum.php index 5525a0d462..0a5484cdf2 100644 --- a/phpBB/viewforum.php +++ b/phpBB/viewforum.php @@ -198,9 +198,6 @@ if (!($forum_data['forum_type'] == FORUM_POST || (($forum_data['forum_flags'] & // We also make this circumstance available to the template in case we want to display a notice. ;) if (!$auth->acl_gets('f_read', 'f_list_topics', $forum_id)) { - // Add form token for login box - add_form_key('login', '_LOGIN'); - $template->assign_vars(array( 'S_NO_READ_ACCESS' => true, )); @@ -936,9 +933,12 @@ if (count($topic_list)) 'TOPIC_AUTHOR_COLOUR' => get_username_string('colour', $row['topic_poster'], $row['topic_first_poster_name'], $row['topic_first_poster_colour']), 'TOPIC_AUTHOR_FULL' => get_username_string('full', $row['topic_poster'], $row['topic_first_poster_name'], $row['topic_first_poster_colour']), 'FIRST_POST_TIME' => $user->format_date($row['topic_time']), + 'FIRST_POST_TIME_RFC3339' => gmdate(DATE_RFC3339, $row['topic_time']), 'LAST_POST_SUBJECT' => censor_text($row['topic_last_post_subject']), 'LAST_POST_TIME' => $user->format_date($row['topic_last_post_time']), + 'LAST_POST_TIME_RFC3339' => gmdate(DATE_RFC3339, $row['topic_last_post_time']), 'LAST_VIEW_TIME' => $user->format_date($row['topic_last_view_time']), + 'LAST_VIEW_TIME_RFC3339' => gmdate(DATE_RFC3339, $row['topic_last_view_time']), 'LAST_POST_AUTHOR' => get_username_string('username', $row['topic_last_poster_id'], $row['topic_last_poster_name'], $row['topic_last_poster_colour']), 'LAST_POST_AUTHOR_COLOUR' => get_username_string('colour', $row['topic_last_poster_id'], $row['topic_last_poster_name'], $row['topic_last_poster_colour']), 'LAST_POST_AUTHOR_FULL' => get_username_string('full', $row['topic_last_poster_id'], $row['topic_last_poster_name'], $row['topic_last_poster_colour']), diff --git a/phpBB/viewtopic.php b/phpBB/viewtopic.php index 0c2be8c52e..4e502538c8 100644 --- a/phpBB/viewtopic.php +++ b/phpBB/viewtopic.php @@ -2044,6 +2044,7 @@ for ($i = 0, $end = count($post_list); $i < $end; ++$i) 'CONTACT_USER' => $user_cache[$poster_id]['contact_user'], 'POST_DATE' => $user->format_date($row['post_time'], false, ($view == 'print') ? true : false), + 'POST_DATE_RFC3339' => gmdate(DATE_RFC3339, $row['post_time']), 'POST_SUBJECT' => $row['post_subject'], 'MESSAGE' => $message, 'SIGNATURE' => ($row['enable_sig']) ? $user_cache[$poster_id]['sig'] : '', @@ -2359,12 +2360,25 @@ if ($s_can_vote || $s_quick_reply) ($s_notify) ? $qr_hidden_fields['notify'] = 1 : true; ($topic_data['topic_status'] == ITEM_LOCKED) ? $qr_hidden_fields['lock_topic'] = 1 : true; - $template->assign_vars(array( + $tpl_ary = [ 'S_QUICK_REPLY' => true, 'U_QR_ACTION' => append_sid("{$phpbb_root_path}posting.$phpEx", "mode=reply&f=$forum_id&t=$topic_id"), 'QR_HIDDEN_FIELDS' => build_hidden_fields($qr_hidden_fields), 'SUBJECT' => 'Re: ' . censor_text($topic_data['topic_title']), - )); + ]; + + /** + * Event after the quick-reply has been setup + * + * @event core.viewtopic_modify_quick_reply_template_vars + * @var array tpl_ary Array with template data + * @var array topic_data Array with topic data + * @since 3.2.9-RC1 + */ + $vars = ['tpl_ary', 'topic_data']; + extract($phpbb_dispatcher->trigger_event('core.viewtopic_modify_quick_reply_template_vars', compact($vars))); + + $template->assign_vars($tpl_ary); } } // now I have the urge to wash my hands :( |