Merge branch '3.2.x' into ticket/16153

This commit is contained in:
3D-I 2019-10-28 21:11:42 +01:00
commit d136a8a907
85 changed files with 880 additions and 240 deletions

View file

@ -4,7 +4,7 @@
<!-- a few settings for the build --> <!-- a few settings for the build -->
<property name="newversion" value="3.2.9-dev" /> <property name="newversion" value="3.2.9-dev" />
<property name="prevversion" value="3.2.7" /> <property name="prevversion" value="3.2.7" />
<property name="olderversions" value="3.1.0, 3.1.1, 3.1.2, 3.1.3, 3.1.4, 3.1.5, 3.1.6, 3.1.7, 3.1.7-pl1, 3.1.8, 3.1.9, 3.1.10, 3.1.11, 3.1.12, 3.2.0-a1, 3.2.0-a2, 3.2.0-b1, 3.2.0-b2, 3.2.0-RC1, 3.2.0-RC2, 3.2.0, 3.2.1, 3.2.2, 3.2.3, 3.2.4, 3.2.5, 3.2.6" /> <property name="olderversions" value="3.1.0, 3.1.1, 3.1.2, 3.1.3, 3.1.4, 3.1.5, 3.1.6, 3.1.7, 3.1.7-pl1, 3.1.8, 3.1.9, 3.1.10, 3.1.11, 3.1.12, 3.2.0-a1, 3.2.0-a2, 3.2.0-b1, 3.2.0-b2, 3.2.0-RC1, 3.2.0-RC2, 3.2.0, 3.2.1, 3.2.2, 3.2.3, 3.2.4, 3.2.5, 3.2.6, 3.2.8-RC1" />
<!-- no configuration should be needed beyond this point --> <!-- no configuration should be needed beyond this point -->
<property name="oldversions" value="${olderversions}, ${prevversion}" /> <property name="oldversions" value="${olderversions}, ${prevversion}" />

View file

@ -0,0 +1,127 @@
#!/usr/bin/env php
<?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.
*
*/
if (version_compare(PHP_VERSION, '7.0-dev', '<'))
{
die('generate_package_json.php requires at least PHP 7.0.');
}
define('IN_PHPBB', true);
include_once('../phpBB/includes/functions.php');
$json_data = new \stdClass();
$json_data->metadata = new stdClass();
$json_data->metadata->current_version_date = '';
$json_data->metadata->current_version = '';
$json_data->metadata->download_path = '';
$json_data->metadata->show_update_package = true;
$json_data->metadata->historic = false;
$json_data->package = [];
// Open build.xml
$build_xml = simplexml_load_file('build.xml');
$current_version = (string) $build_xml->xpath('/project/property[@name=\'newversion\']/@value')[0]->value;
$previous_version = (string) $build_xml->xpath('/project/property[@name=\'prevversion\']/@value')[0]->value;
$older_verions = explode(', ', (string) $build_xml->xpath('/project/property[@name=\'olderversions\']/@value')[0]->value);
// Clean and sort version info
$older_verions[] = $previous_version;
$older_verions = array_filter($older_verions, function($version) {
preg_match(get_preg_expression('semantic_version'), $version, $matches);
return empty($matches['prerelease']) || strpos($matches['prerelease'], 'pl') !== false;
});
usort($older_verions, function($version_a, $version_b)
{
return phpbb_version_compare($version_b, $version_a);
});
// Set metadata
$json_data->metadata->current_version = $current_version;
$json_data->metadata->current_version_date = date('Y-m-d');
$json_data->metadata->download_path = 'https://download.phpbb.com/pub/release/' . preg_replace('#([0-9]+\.[0-9]+)(\..+)#', '$1', $current_version) . '/' . $current_version . '/';
// Add package, patch files, and changed files
phpbb_add_package_file(
$json_data->package,
'phpBB ' . $current_version,
'phpBB-' . $current_version,
'full',
''
);
phpbb_add_package_file(
$json_data->package,
'phpBB ' . $current_version . ' Patch Files',
'phpBB-' . $current_version . '-patch',
'update',
'patch'
);
phpbb_add_package_file(
$json_data->package,
'phpBB ' . $current_version . ' Changed Files',
'phpBB-' . $current_version . '-files',
'update',
'files'
);
// Loop through packages and assign to packages array
foreach ($older_verions as $version)
{
phpbb_add_package_file(
$json_data->package,
'phpBB ' . $version . ' to ' . $current_version . ' Update Package',
'phpBB-' . $version . '_to_' . $current_version,
'update',
'update',
$version
);
}
echo(json_encode($json_data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . "\n");
function phpbb_add_package_file(array &$package_list, $name, $file_name, $type, $subtype, $from = '')
{
if (!file_exists(__DIR__ . '/new_version/release_files/' . $file_name . '.zip'))
{
trigger_error('File does not exist: ' . __DIR__ . '/new_version/release_files/' . $file_name . '.zip');
return;
}
$package_file = new stdClass();
$package_file->name = $name;
$package_file->filename = $file_name;
$package_file->type = $type;
if (!empty($subtype))
{
$package_file->subtype = $subtype;
}
if (!empty($from))
{
$package_file->from = $from;
}
$package_file->files = [];
foreach (['zip', 'tar.bz2'] as $extension)
{
$file_path = 'new_version/release_files/' . $file_name . '.' . $extension;
$filedata = new stdClass();
$filedata->filesize = filesize($file_path);
$filedata->checksum = trim(preg_replace('/(^\w+)(.+)/', '$1', file_get_contents($file_path . '.sha256')));
$filedata->filetype = $extension;
$package_file->files[] = $filedata;
}
$package_list[] = $package_file;
}

View file

@ -110,7 +110,7 @@
<!-- ELSEIF S_EXTENSION_GROUPS --> <!-- ELSEIF S_EXTENSION_GROUPS -->
<!-- IF S_EDIT_GROUP --> <!-- IF S_EDIT_GROUP -->
<script type="text/javascript" defer="defer"> <script>
// <![CDATA[ // <![CDATA[
function update_image(newimage) function update_image(newimage)
{ {

View file

@ -8,7 +8,7 @@
<p>{L_EXPLAIN}</p> <p>{L_EXPLAIN}</p>
<script type="text/javascript"> <script>
// <![CDATA[ // <![CDATA[
var ban_length = new Array(); var ban_length = new Array();

View file

@ -1,6 +1,6 @@
<!-- INCLUDE overall_header.html --> <!-- INCLUDE overall_header.html -->
<script type="text/javascript"> <script>
// <![CDATA[ // <![CDATA[
var form_name = 'acp_contact'; var form_name = 'acp_contact';

View file

@ -35,7 +35,7 @@
<p>{L_ACP_BACKUP_EXPLAIN}</p> <p>{L_ACP_BACKUP_EXPLAIN}</p>
<script type="text/javascript"> <script>
// <![CDATA[ // <![CDATA[
function selector(bool) function selector(bool)

View file

@ -4,7 +4,7 @@
<!-- IF S_EDIT_FORUM --> <!-- IF S_EDIT_FORUM -->
<script type="text/javascript"> <script>
// <![CDATA[ // <![CDATA[
/** /**
* Handle displaying/hiding several options based on the forum type * Handle displaying/hiding several options based on the forum type
@ -405,7 +405,7 @@
<!-- ELSEIF S_CONTINUE_SYNC --> <!-- ELSEIF S_CONTINUE_SYNC -->
<script type="text/javascript"> <script>
// <![CDATA[ // <![CDATA[
var close_waitscreen = 0; var close_waitscreen = 0;
// no scrollbars... // no scrollbars...
@ -421,7 +421,7 @@
<!-- ELSE --> <!-- ELSE -->
<script type="text/javascript"> <script>
// <![CDATA[ // <![CDATA[
/** /**
* Popup search progress bar * Popup search progress bar
@ -447,7 +447,7 @@
<!-- ENDIF --> <!-- ENDIF -->
<!-- IF S_RESYNCED --> <!-- IF S_RESYNCED -->
<script type="text/javascript"> <script>
// <![CDATA[ // <![CDATA[
var close_waitscreen = 1; var close_waitscreen = 1;
// ]]> // ]]>

View file

@ -36,10 +36,12 @@
<dl> <dl>
<dt><label for="group_type">{L_GROUP_TYPE}{L_COLON}</label><br /><span>{L_GROUP_TYPE_EXPLAIN}</span></dt> <dt><label for="group_type">{L_GROUP_TYPE}{L_COLON}</label><br /><span>{L_GROUP_TYPE_EXPLAIN}</span></dt>
<dd> <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" 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_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_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> <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> </dd>
</dl> </dl>
<!-- ELSE --> <!-- ELSE -->

View file

@ -4,7 +4,7 @@
<!-- IF S_EDIT --> <!-- IF S_EDIT -->
<script type="text/javascript" defer="defer"> <script>
// <![CDATA[ // <![CDATA[
<!-- IF S_ADD_CODE --> <!-- IF S_ADD_CODE -->

View file

@ -4,7 +4,7 @@
<!-- IF S_EDIT_MODULE --> <!-- IF S_EDIT_MODULE -->
<script type="text/javascript"> <script>
// <![CDATA[ // <![CDATA[
function display_options(value) function display_options(value)
{ {

View file

@ -4,7 +4,7 @@
<!-- IF S_EDIT --> <!-- IF S_EDIT -->
<script type="text/javascript"> <script>
// <![CDATA[ // <![CDATA[
var active_pmask = '0'; var active_pmask = '0';
var active_fmask = '0'; var active_fmask = '0';
@ -20,7 +20,7 @@
// ]]> // ]]>
</script> </script>
<script type="text/javascript" src="style/permissions.js"></script> <script src="style/permissions.js"></script>
<a href="{U_BACK}" style="float: {S_CONTENT_FLOW_END};">&laquo; {L_BACK}</a> <a href="{U_BACK}" style="float: {S_CONTENT_FLOW_END};">&laquo; {L_BACK}</a>

View file

@ -1,31 +1,10 @@
<script type="text/javascript"> <script>
// <![CDATA[ // <![CDATA[
// Define the bbCode tags // Define the bbCode tags
var bbcode = new Array(); 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 -->); 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> </script>
@ -65,7 +44,7 @@
</select> </select>
<!-- EVENT acp_posting_buttons_custom_tags_before --> <!-- EVENT acp_posting_buttons_custom_tags_before -->
<!-- BEGIN custom_tags --> <!-- 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 --> <!-- END custom_tags -->
</div> </div>
<!-- EVENT acp_posting_buttons_after --> <!-- EVENT acp_posting_buttons_after -->

View file

@ -6,7 +6,7 @@
<a href="{U_BACK}" style="float: {S_CONTENT_FLOW_END};">&laquo; {L_BACK}</a> <a href="{U_BACK}" style="float: {S_CONTENT_FLOW_END};">&laquo; {L_BACK}</a>
<script type="text/javascript"> <script>
// <![CDATA[ // <![CDATA[
function update_image(newimage) function update_image(newimage)
{ {

View file

@ -69,7 +69,7 @@
<!-- ELSEIF S_INDEX --> <!-- ELSEIF S_INDEX -->
<script type="text/javascript"> <script>
// <![CDATA[ // <![CDATA[
/** /**
* Popup search progress bar * Popup search progress bar

View file

@ -79,7 +79,7 @@
<!-- IF not S_USER_FOUNDER or S_FOUNDER --> <!-- IF not S_USER_FOUNDER or S_FOUNDER -->
<script type="text/javascript"> <script>
// <![CDATA[ // <![CDATA[
function display_reason(option) function display_reason(option)

View file

@ -1,4 +1,4 @@
<script type="text/javascript"> <script>
// <![CDATA[ // <![CDATA[
var default_dateformat = '{A_DEFAULT_DATEFORMAT}'; var default_dateformat = '{A_DEFAULT_DATEFORMAT}';
// ]]> // ]]>

View file

@ -1,4 +1,4 @@
<script type="text/javascript"> <script>
// <![CDATA[ // <![CDATA[
var form_name = 'user_signature'; var form_name = 'user_signature';

View file

@ -13,7 +13,7 @@
</div> </div>
</div> </div>
<script type="text/javascript"> <script>
<!-- <!--
installLang = { installLang = {
title: '{LA_TIMEOUT_DETECTED_TITLE}', title: '{LA_TIMEOUT_DETECTED_TITLE}',
@ -22,9 +22,9 @@ installLang = {
//--> //-->
</script> </script>
<script type="text/javascript" src="{T_JQUERY_LINK}"></script> <script src="{T_JQUERY_LINK}"></script>
<!-- IF S_ALLOW_CDN --><script type="text/javascript">window.jQuery || document.write('\x3Cscript src="{T_ASSETS_PATH}/javascript/jquery.min.js">\x3C/script>');</script><!-- ENDIF --> <!-- IF S_ALLOW_CDN --><script>window.jQuery || document.write('\x3Cscript src="{T_ASSETS_PATH}/javascript/jquery.min.js">\x3C/script>');</script><!-- ENDIF -->
<script type="text/javascript" src="{T_ASSETS_PATH}/javascript/core.js?assets_version={T_ASSETS_VERSION}"></script> <script src="{T_ASSETS_PATH}/javascript/core.js?assets_version={T_ASSETS_VERSION}"></script>
<!-- INCLUDEJS admin.js --> <!-- INCLUDEJS admin.js -->
{$SCRIPTS} {$SCRIPTS}

View file

@ -33,9 +33,9 @@
</div> </div>
</div> </div>
<script type="text/javascript" src="{T_JQUERY_LINK}"></script> <script src="{T_JQUERY_LINK}"></script>
<!-- IF S_ALLOW_CDN --><script type="text/javascript">window.jQuery || document.write('\x3Cscript src="{T_ASSETS_PATH}/javascript/jquery.min.js?assets_version={T_ASSETS_VERSION}">\x3C/script>');</script><!-- ENDIF --> <!-- IF S_ALLOW_CDN --><script>window.jQuery || document.write('\x3Cscript src="{T_ASSETS_PATH}/javascript/jquery.min.js?assets_version={T_ASSETS_VERSION}">\x3C/script>');</script><!-- ENDIF -->
<script type="text/javascript" src="{T_ASSETS_PATH}/javascript/core.js?assets_version={T_ASSETS_VERSION}"></script> <script src="{T_ASSETS_PATH}/javascript/core.js?assets_version={T_ASSETS_VERSION}"></script>
<!-- INCLUDEJS ajax.js --> <!-- INCLUDEJS ajax.js -->
<!-- INCLUDEJS admin.js --> <!-- INCLUDEJS admin.js -->

View file

@ -10,7 +10,7 @@
<link href="{T_FONT_AWESOME_LINK}" rel="stylesheet"> <link href="{T_FONT_AWESOME_LINK}" rel="stylesheet">
<link href="style/admin.css?assets_version={T_ASSETS_VERSION}" rel="stylesheet" type="text/css" media="screen" /> <link href="style/admin.css?assets_version={T_ASSETS_VERSION}" rel="stylesheet" type="text/css" media="screen" />
<script type="text/javascript"> <script>
// <![CDATA[ // <![CDATA[
var jump_page = '{LA_JUMP_PAGE}{L_COLON}'; var jump_page = '{LA_JUMP_PAGE}{L_COLON}';
var on_page = '{CURRENT_PAGE}'; var on_page = '{CURRENT_PAGE}';

View file

@ -1,5 +1,5 @@
<script type="text/javascript"> <script>
// <![CDATA[ // <![CDATA[
var active_pmask = '0'; var active_pmask = '0';
var active_fmask = '0'; var active_fmask = '0';
@ -9,12 +9,14 @@
var role_options = new Array(); var role_options = new Array();
var no_role_assigned = "{LA_NO_ROLE_ASSIGNED}";
<!-- IF S_ROLE_JS_ARRAY --> <!-- IF S_ROLE_JS_ARRAY -->
{S_ROLE_JS_ARRAY} {S_ROLE_JS_ARRAY}
<!-- ENDIF --> <!-- ENDIF -->
// ]]> // ]]>
</script> </script>
<script type="text/javascript" src="style/permissions.js"></script> <script src="style/permissions.js"></script>
<!-- BEGIN p_mask --> <!-- BEGIN p_mask -->
<div class="clearfix"></div> <div class="clearfix"></div>

View file

@ -279,6 +279,10 @@ function reset_role(id) {
} }
t.options[0].selected = true; 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';
} }
/** /**

View file

@ -1,6 +1,6 @@
<!-- INCLUDE simple_header.html --> <!-- INCLUDE simple_header.html -->
<script type="text/javascript"> <script>
// <![CDATA[ // <![CDATA[
/** /**
* Close previously opened popup * Close previously opened popup
@ -31,7 +31,7 @@
<p>{L_PROGRESS_EXPLAIN}</p> <p>{L_PROGRESS_EXPLAIN}</p>
</div> </div>
<script type="text/javascript"> <script>
// <![CDATA[ // <![CDATA[
close_popup(); close_popup();
// ]]> // ]]>

View file

@ -16,9 +16,9 @@
</div> </div>
<script type="text/javascript" src="{T_JQUERY_LINK}"></script> <script src="{T_JQUERY_LINK}"></script>
<!-- IF S_ALLOW_CDN --><script type="text/javascript">window.jQuery || document.write('\x3Cscript src="{T_ASSETS_PATH}/javascript/jquery.min.js?assets_version={T_ASSETS_VERSION}">\x3C/script>');</script><!-- ENDIF --> <!-- IF S_ALLOW_CDN --><script>window.jQuery || document.write('\x3Cscript src="{T_ASSETS_PATH}/javascript/jquery.min.js?assets_version={T_ASSETS_VERSION}">\x3C/script>');</script><!-- ENDIF -->
<script type="text/javascript" src="{T_ASSETS_PATH}/javascript/core.js?assets_version={T_ASSETS_VERSION}"></script> <script src="{T_ASSETS_PATH}/javascript/core.js?assets_version={T_ASSETS_VERSION}"></script>
<!-- EVENT acp_simple_footer_after --> <!-- EVENT acp_simple_footer_after -->
{$SCRIPTS} {$SCRIPTS}

View file

@ -9,7 +9,7 @@
<link href="style/admin.css?assets_version={T_ASSETS_VERSION}" rel="stylesheet" type="text/css" media="screen" /> <link href="style/admin.css?assets_version={T_ASSETS_VERSION}" rel="stylesheet" type="text/css" media="screen" />
<script type="text/javascript"> <script>
// <![CDATA[ // <![CDATA[
var jump_page = '{LA_JUMP_PAGE}{L_COLON}'; var jump_page = '{LA_JUMP_PAGE}{L_COLON}';
var on_page = '{CURRENT_PAGE}'; var on_page = '{CURRENT_PAGE}';

View file

@ -17,17 +17,10 @@ var is_ie = ((clientPC.indexOf('msie') !== -1) && (clientPC.indexOf('opera') ===
var is_win = ((clientPC.indexOf('win') !== -1) || (clientPC.indexOf('16bit') !== -1)); var is_win = ((clientPC.indexOf('win') !== -1) || (clientPC.indexOf('16bit') !== -1));
var baseHeight; 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 * Fix a bug involving the TextRange object. From
* http://www.frostjedi.com/terra/scripts/demo/caretBug.html * http://www.frostjedi.com/terra/scripts/demo/caretBug.html
*/ */
function initInsertions() { function initInsertions() {
var doc; var doc;
@ -104,8 +97,8 @@ function bbfontstyle(bbopen, bbclose) {
} }
// IE // IE
else if (document.selection) { else if (document.selection) {
var range = textarea.createTextRange(); var range = textarea.createTextRange();
range.move("character", new_pos); range.move("character", new_pos);
range.select(); range.select();
storeCaret(textarea); storeCaret(textarea);
} }

View file

@ -90,6 +90,12 @@ phpbb.plupload.getSerializedData = function() {
obj['attachment_data[' + i + '][' + key + ']'] = datum[key]; 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; return obj;
}; };
@ -264,6 +270,17 @@ phpbb.plupload.deleteFile = function(row, attachId) {
return; 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); phpbb.plupload.update(response, 'removal', index);
// Check if the user can upload files now if he had reached the max files limit. // Check if the user can upload files now if he had reached the max files limit.
phpbb.plupload.handleMaxFilesReached(); phpbb.plupload.handleMaxFilesReached();
@ -446,6 +463,44 @@ phpbb.plupload.fileError = function(file, error) {
phpbb.plupload.uploader = new plupload.Uploader(phpbb.plupload.config); phpbb.plupload.uploader = new plupload.Uploader(phpbb.plupload.config);
phpbb.plupload.initialize(); 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'); var $fileList = $('#file-list');
/** /**

View file

@ -50,6 +50,7 @@
<ol> <ol>
<li><a href="#changelog">Changelog</a> <li><a href="#changelog">Changelog</a>
<ul> <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="#v327">Changes since 3.2.7</a></li>
<li><a href="#v326">Changes since 3.2.6</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="#v326rc1">Changes since 3.2.6-RC1</a></li>
@ -139,6 +140,28 @@
<div class="inner"> <div class="inner">
<div class="content"> <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 &quot; Reason shown to the banned&quot; 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> <a name="v327"></a><h3>Changes since 3.2.7</h3>
<h4>Bug</h4> <h4>Bug</h4>
<ul> <ul>
@ -193,7 +216,6 @@
<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-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-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-16097">PHPBB3-16097</a>] - Add core.viewtopic_gen_sort_selects_before</li>
<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-16101">PHPBB3-16101</a>] - Add Referrer-Policy header</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-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-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-16106">PHPBB3-16106</a>] - Add core.mcp_main_before</li>
@ -212,6 +234,10 @@
<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-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> <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> </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> <a name="v326"></a><h3>Changes since 3.2.6</h3>
<h4>Bug</h4> <h4>Bug</h4>

View file

@ -1,7 +1,7 @@
/** /**
* *
* phpBB © Copyright phpBB Limited 2003-2016 * phpBB © Copyright phpBB Limited 2003-2019
* http://www.phpbb.com * https://www.phpbb.com
* *
* phpBB is free software. You can redistribute it and/or modify it * 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) * 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) Derky (Derk Ruitenbeek)
Elsensee (Oliver Schramm) Elsensee (Oliver Schramm)
Hanakin (Michael Miday) Hanakin (Michael Miday)
MichaelC (Michael Cullum)
Nicofuma (Tristan Darricau) Nicofuma (Tristan Darricau)
rubencm (Rubén Calvo) 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] igorw (Igor Wiedler) [08/2010 - 02/2013]
imkingdavid (David King) [11/2012 - 06/2014] imkingdavid (David King) [11/2012 - 06/2014]
kellanved (Henry Sudhof) [04/2007 - 03/2011] kellanved (Henry Sudhof) [04/2007 - 03/2011]
MichaelC (Michael Cullum) [11/2017 - 09/2019]
nickvergessen (Joas Schilling)[04/2010 - 12/2015] nickvergessen (Joas Schilling)[04/2010 - 12/2015]
Oleg (Oleg Pudeyev) [01/2011 - 05/2013] Oleg (Oleg Pudeyev) [01/2011 - 05/2013]
prototech (Cesar Gallegos) [01/2014 - 12/2016] prototech (Cesar Gallegos) [01/2014 - 12/2016]

View file

@ -172,6 +172,18 @@ acp_group_options_before
* Since: 3.1.0-b4 * Since: 3.1.0-b4
* Purpose: Add additional options to group settings (before GROUP_FOUNDER_MANAGE) * 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 acp_groups_find_username_append
=== ===
* Location: adm/style/acp_groups.html * Location: adm/style/acp_groups.html
@ -2634,6 +2646,13 @@ ucp_profile_profile_info_before
* Since: 3.1.4-RC1 * Since: 3.1.4-RC1
* Purpose: Add options in profile page fieldset - before jabber field. * Purpose: Add options in profile page fieldset - before jabber field.
ucp_profile_profile_info_birthday_label_append
===
* Locations:
+ styles/prosilver/template/ucp_profile_profile_info.html
* Since: 3.2.9-RC1
* Purpose: Add more text to birthday label, such as required asterisk
ucp_profile_register_details_after ucp_profile_register_details_after
=== ===
* Locations: * Locations:

View file

@ -33,7 +33,6 @@ class acp_bbcodes
// Set up general vars // Set up general vars
$action = $request->variable('action', ''); $action = $request->variable('action', '');
$bbcode_id = $request->variable('bbcode', 0); $bbcode_id = $request->variable('bbcode', 0);
$submit = $request->is_set_post('submit');
$this->tpl_name = 'acp_bbcodes'; $this->tpl_name = 'acp_bbcodes';
$this->page_title = 'ACP_BBCODES'; $this->page_title = 'ACP_BBCODES';
@ -41,11 +40,6 @@ class acp_bbcodes
add_form_key($form_key); 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 // Set up mode-specific vars
switch ($action) switch ($action)
{ {
@ -179,6 +173,12 @@ class acp_bbcodes
extract($phpbb_dispatcher->trigger_event('core.acp_bbcodes_modify_create', compact($vars))); extract($phpbb_dispatcher->trigger_event('core.acp_bbcodes_modify_create', compact($vars)));
$warn_text = preg_match('%<[^>]*\{text[\d]*\}[^>]*>%i', $bbcode_tpl); $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)) if (!$warn_text || confirm_box(true))
{ {
$data = $this->build_regexp($bbcode_match, $bbcode_tpl); $data = $this->build_regexp($bbcode_match, $bbcode_tpl);
@ -211,11 +211,6 @@ class acp_bbcodes
$test = $data['bbcode_tag']; $test = $data['bbcode_tag'];
} }
if (!preg_match('%\\[' . $test . '[^]]*].*?\\[/' . $test . ']%s', $bbcode_match))
{
trigger_error($user->lang['BBCODE_OPEN_ENDED_TAG'] . adm_back_link($this->u_action), E_USER_WARNING);
}
if (strlen($data['bbcode_tag']) > 16) if (strlen($data['bbcode_tag']) > 16)
{ {
trigger_error($user->lang['BBCODE_TAG_TOO_LONG'] . adm_back_link($this->u_action), E_USER_WARNING); trigger_error($user->lang['BBCODE_TAG_TOO_LONG'] . adm_back_link($this->u_action), E_USER_WARNING);

View file

@ -986,10 +986,20 @@ class acp_forums
$errors[] = $user->lang['FORUM_NAME_EMPTY']; $errors[] = $user->lang['FORUM_NAME_EMPTY'];
} }
// No Emojis /**
* Replace Emojis and other 4bit UTF-8 chars not allowed by MySql to UCR / NCR.
* Using their Numeric Character Reference's Hexadecimal notation.
*/
$forum_data_ary['forum_name'] = utf8_encode_ucr($forum_data_ary['forum_name']);
/**
* This should never happen again.
* Leaving the fallback here just in case there will be the need of it.
*/
if (preg_match_all('/[\x{10000}-\x{10FFFF}]/u', $forum_data_ary['forum_name'], $matches)) if (preg_match_all('/[\x{10000}-\x{10FFFF}]/u', $forum_data_ary['forum_name'], $matches))
{ {
$character_list = implode('<br>', $matches[0]); $character_list = implode('<br>', $matches[0]);
$errors[] = $user->lang('FORUM_NAME_EMOJI', $character_list); $errors[] = $user->lang('FORUM_NAME_EMOJI', $character_list);
} }
@ -1423,8 +1433,8 @@ class acp_forums
* This event may be triggered, when a forum is deleted * This event may be triggered, when a forum is deleted
* *
* @event core.acp_manage_forums_move_children * @event core.acp_manage_forums_move_children
* @var int from_id If of the current parent forum * @var int from_id Id of the current parent forum
* @var int to_id If of the new parent forum * @var int to_id Id of the new parent forum
* @var array errors Array of errors, should be strings and not * @var array errors Array of errors, should be strings and not
* language key. * language key.
* @since 3.1.0-a1 * @since 3.1.0-a1
@ -1529,8 +1539,8 @@ class acp_forums
* Event when we move content from one forum to another * Event when we move content from one forum to another
* *
* @event core.acp_manage_forums_move_content * @event core.acp_manage_forums_move_content
* @var int from_id If of the current parent forum * @var int from_id Id of the current parent forum
* @var int to_id If of the new parent forum * @var int to_id Id of the new parent forum
* @var bool sync Shall we sync the "to"-forum's data * @var bool sync Shall we sync the "to"-forum's data
* @var array errors Array of errors, should be strings and not * @var array errors Array of errors, should be strings and not
* language key. If this array is not empty, * language key. If this array is not empty,
@ -1576,6 +1586,19 @@ class acp_forums
$db->sql_query($sql); $db->sql_query($sql);
} }
/**
* Event when content has been moved from one forum to another
*
* @event core.acp_manage_forums_move_content_after
* @var int from_id Id of the current parent forum
* @var int to_id Id of the new parent forum
* @var bool sync Shall we sync the "to"-forum's data
*
* @since 3.2.9-RC1
*/
$vars = array('from_id', 'to_id', 'sync');
extract($phpbb_dispatcher->trigger_event('core.acp_manage_forums_move_content_after', compact($vars)));
if ($sync) if ($sync)
{ {
// Delete ghost topics that link back to the same forum then resync counters // Delete ghost topics that link back to the same forum then resync counters

View file

@ -537,6 +537,7 @@ class acp_prune
AND ug.user_id <> ' . ANONYMOUS . ' AND ug.user_id <> ' . ANONYMOUS . '
AND u.user_type <> ' . USER_FOUNDER . ' AND u.user_type <> ' . USER_FOUNDER . '
AND ug.user_pending = 0 AND ug.user_pending = 0
AND ug.group_leader = 0
AND u.user_id = ug.user_id AND u.user_id = ug.user_id
' . (!empty($user_ids) ? ' AND ' . $db->sql_in_set('ug.user_id', $user_ids) : ''); ' . (!empty($user_ids) ? ' AND ' . $db->sql_in_set('ug.user_id', $user_ids) : '');
$result = $db->sql_query($sql); $result = $db->sql_query($sql);

View file

@ -543,6 +543,20 @@ function move_topics($topic_ids, $forum_id, $auto_sync = true)
$topic_ids = array($topic_ids); $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 . ' $sql = 'DELETE FROM ' . TOPICS_TABLE . '
WHERE ' . $db->sql_in_set('topic_moved_id', $topic_ids) . ' WHERE ' . $db->sql_in_set('topic_moved_id', $topic_ids) . '
AND forum_id = ' . $forum_id; AND forum_id = ' . $forum_id;
@ -593,6 +607,22 @@ function move_topics($topic_ids, $forum_id, $auto_sync = true)
} }
unset($table_ary); 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) if ($auto_sync)
{ {
sync('forum', 'forum_id', $forum_ids, true, true); sync('forum', 'forum_id', $forum_ids, true, true);

View file

@ -70,7 +70,7 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod
$data = array( $data = array(
'NO_UNREAD_POSTS' => $user->lang['NO_UNREAD_POSTS'], 'NO_UNREAD_POSTS' => $user->lang['NO_UNREAD_POSTS'],
'UNREAD_POSTS' => $user->lang['UNREAD_POSTS'], 'UNREAD_POSTS' => $user->lang['UNREAD_POSTS'],
'U_MARK_FORUMS' => ($user->data['is_registered'] || $config['load_anon_lastread']) ? append_sid("{$phpbb_root_path}index.$phpEx", 'hash=' . generate_link_hash('global') . '&mark=forums&mark_time=' . time()) : '', 'U_MARK_FORUMS' => ($user->data['is_registered'] || $config['load_anon_lastread']) ? append_sid("{$phpbb_root_path}index.$phpEx", 'hash=' . generate_link_hash('global') . '&mark=forums&mark_time=' . time(), false) : '',
'MESSAGE_TITLE' => $user->lang['INFORMATION'], 'MESSAGE_TITLE' => $user->lang['INFORMATION'],
'MESSAGE_TEXT' => $user->lang['FORUMS_MARKED'] 'MESSAGE_TEXT' => $user->lang['FORUMS_MARKED']
); );
@ -355,7 +355,7 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod
$data = array( $data = array(
'NO_UNREAD_POSTS' => $user->lang['NO_UNREAD_POSTS'], 'NO_UNREAD_POSTS' => $user->lang['NO_UNREAD_POSTS'],
'UNREAD_POSTS' => $user->lang['UNREAD_POSTS'], 'UNREAD_POSTS' => $user->lang['UNREAD_POSTS'],
'U_MARK_FORUMS' => ($user->data['is_registered'] || $config['load_anon_lastread']) ? append_sid("{$phpbb_root_path}viewforum.$phpEx", 'hash=' . generate_link_hash('global') . '&f=' . $root_data['forum_id'] . '&mark=forums&mark_time=' . time()) : '', 'U_MARK_FORUMS' => ($user->data['is_registered'] || $config['load_anon_lastread']) ? append_sid("{$phpbb_root_path}viewforum.$phpEx", 'hash=' . generate_link_hash('global') . '&f=' . $root_data['forum_id'] . '&mark=forums&mark_time=' . time(), false) : '',
'MESSAGE_TITLE' => $user->lang['INFORMATION'], 'MESSAGE_TITLE' => $user->lang['INFORMATION'],
'MESSAGE_TEXT' => $user->lang['FORUMS_MARKED'] 'MESSAGE_TEXT' => $user->lang['FORUMS_MARKED']
); );
@ -548,11 +548,12 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod
$last_post_subject = $last_post_subject_truncated = ''; $last_post_subject = $last_post_subject_truncated = '';
} }
$last_post_time = $user->format_date($row['forum_last_post_time']); $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'] . '&amp;p=' . $row['forum_last_post_id']) . '#p' . $row['forum_last_post_id']; $last_post_url = append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'f=' . $row['forum_id_last_post'] . '&amp;p=' . $row['forum_last_post_id']) . '#p' . $row['forum_last_post_id'];
} }
else 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 // Output moderator listing ... if applicable
@ -623,6 +624,7 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod
'LAST_POST_SUBJECT' => $last_post_subject, 'LAST_POST_SUBJECT' => $last_post_subject,
'LAST_POST_SUBJECT_TRUNCATED' => $last_post_subject_truncated, 'LAST_POST_SUBJECT_TRUNCATED' => $last_post_subject_truncated,
'LAST_POST_TIME' => $last_post_time, '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' => 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_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']), 'LAST_POSTER_FULL' => get_username_string('full', $row['forum_last_poster_id'], $row['forum_last_poster_name'], $row['forum_last_poster_colour']),
@ -1118,7 +1120,6 @@ function display_custom_bbcodes()
'BBCODE_TAG' => $row['bbcode_tag'], 'BBCODE_TAG' => $row['bbcode_tag'],
'BBCODE_TAG_CLEAN' => str_replace('=', '-', $row['bbcode_tag']), 'BBCODE_TAG_CLEAN' => str_replace('=', '-', $row['bbcode_tag']),
'BBCODE_HELPLINE' => $row['bbcode_helpline'], 'BBCODE_HELPLINE' => $row['bbcode_helpline'],
'A_BBCODE_HELPLINE' => str_replace(array('&amp;', '&quot;', "'", '&lt;', '&gt;'), array('&', '"', "\'", '<', '>'), $row['bbcode_helpline']),
); );
/** /**

View file

@ -52,9 +52,29 @@ function generate_smilies($mode, $forum_id)
page_header($user->lang['SMILIES']); page_header($user->lang['SMILIES']);
$sql = 'SELECT COUNT(smiley_id) AS item_count $sql_ary = [
FROM ' . SMILIES_TABLE . ' 'SELECT' => 'COUNT(s.smiley_id) AS item_count',
GROUP BY smiley_url'; 'FROM' => [
SMILIES_TABLE => 's',
],
'GROUP_BY' => 's.smiley_url',
];
/**
* Modify SQL query that fetches the total number of smilies in window mode
*
* @event core.generate_smilies_count_sql_before
* @var int forum_id Forum where smilies are generated
* @var array sql_ary Array with the SQL query
* @since 3.2.9-RC1
*/
$vars = [
'forum_id',
'sql_ary',
];
extract($phpbb_dispatcher->trigger_event('core.generate_smilies_count_sql_before', compact($vars)));
$sql = $db->sql_build_query('SELECT', $sql_ary);
$result = $db->sql_query($sql, 3600); $result = $db->sql_query($sql, 3600);
$smiley_count = 0; $smiley_count = 0;
@ -114,6 +134,22 @@ function generate_smilies($mode, $forum_id)
} }
$db->sql_freeresult($result); $db->sql_freeresult($result);
/**
* Modify smilies before they are assigned to the template
*
* @event core.generate_smilies_modify_rowset
* @var string mode Smiley mode, either window or inline
* @var int forum_id Forum where smilies are generated
* @var array smilies Smiley rows fetched from the database
* @since 3.2.9-RC1
*/
$vars = [
'mode',
'forum_id',
'smilies',
];
extract($phpbb_dispatcher->trigger_event('core.generate_smilies_modify_rowset', compact($vars)));
if (count($smilies)) if (count($smilies))
{ {
$root_path = (defined('PHPBB_USE_BOARD_URL_PATH') && PHPBB_USE_BOARD_URL_PATH) ? generate_board_url() . '/' : $phpbb_path_helper->get_web_root_path(); $root_path = (defined('PHPBB_USE_BOARD_URL_PATH') && PHPBB_USE_BOARD_URL_PATH) ? generate_board_url() . '/' : $phpbb_path_helper->get_web_root_path();

View file

@ -1945,9 +1945,10 @@ function validate_user_email($email, $allowed_email = false)
return $validate_email; 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']) if (!$config['allow_emailreuse'])

View file

@ -1524,6 +1524,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 * Parse Attachments
*/ */

View file

@ -26,7 +26,7 @@ if (!defined('IN_PHPBB'))
function compose_pm($id, $mode, $action, $user_folders = array()) function compose_pm($id, $mode, $action, $user_folders = array())
{ {
global $template, $db, $auth, $user, $cache; 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; global $request, $phpbb_dispatcher, $phpbb_container;
// Damn php and globals - i know, this is horrible // 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))); extract($phpbb_dispatcher->trigger_event('core.ucp_pm_compose_modify_parse_before', compact($vars)));
// Parse Attachments - before checksum is calculated // 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)) if (count($message_parser->warn_msg) && !($remove_u || $remove_g || $add_to || $add_bcc))
{ {

View file

@ -418,24 +418,43 @@ function utf8_recode($string, $encoding)
} }
/** /**
* Replace all UTF-8 chars that are not in ASCII with their NCR * Replace some special UTF-8 chars that are not in ASCII with their UCR.
* * using their Numeric Character Reference's Hexadecimal notation.
* @param string $text UTF-8 string in NFC *
* @return string ASCII string using NCRs for non-ASCII chars * Doesn't interfere with Japanese or Cyrillic etc.
*/ * Unicode character visualization will depend on the character support
* of your web browser and the fonts installed on your system.
*
* @see https://en.wikibooks.org/wiki/Unicode/Character_reference/1F000-1FFFF
*
* @param string $text UTF-8 string in NFC
* @return string ASCII string using NCR for non-ASCII chars
*/
function utf8_encode_ucr($text)
{
return preg_replace_callback('/[\\xF0-\\xF4].../', 'utf8_encode_ncr_callback', $text);
}
/**
* Replace all UTF-8 chars that are not in ASCII with their NCR
* using their Numeric Character Reference's Hexadecimal notation.
*
* @param string $text UTF-8 string in NFC
* @return string ASCII string using NCRs for non-ASCII chars
*/
function utf8_encode_ncr($text) function utf8_encode_ncr($text)
{ {
return preg_replace_callback('#[\\xC2-\\xF4][\\x80-\\xBF]{1,3}#', 'utf8_encode_ncr_callback', $text); return preg_replace_callback('#[\\xC2-\\xF4][\\x80-\\xBF]{1,3}#', 'utf8_encode_ncr_callback', $text);
} }
/** /**
* Callback used in encode_ncr() * Callback used in utf8_encode_ncr() and utf8_encode_ucr()
* *
* Takes a UTF-8 char and replaces it with its NCR. Attention, $m is an array * Takes a UTF-8 char and replaces it with its NCR. Attention, $m is an array
* *
* @param array $m 0-based numerically indexed array passed by preg_replace_callback() * @param array $m 0-based numerically indexed array passed by preg_replace_callback()
* @return string A HTML NCR if the character is valid, or the original string otherwise * @return string A HTML NCR if the character is valid, or the original string otherwise
*/ */
function utf8_encode_ncr_callback($m) function utf8_encode_ncr_callback($m)
{ {
return '&#' . utf8_ord($m[0]) . ';'; return '&#' . utf8_ord($m[0]) . ';';

View file

@ -23,7 +23,7 @@ if (php_sapi_name() !== 'cli')
define('IN_PHPBB', true); define('IN_PHPBB', true);
define('IN_INSTALL', true); define('IN_INSTALL', true);
define('PHPBB_ENVIRONMENT', 'production'); define('PHPBB_ENVIRONMENT', 'production');
define('PHPBB_VERSION', '3.2.8-RC1'); define('PHPBB_VERSION', '3.2.8');
$phpbb_root_path = __DIR__ . '/../'; $phpbb_root_path = __DIR__ . '/../';
$phpEx = substr(strrchr(__FILE__, '.'), 1); $phpEx = substr(strrchr(__FILE__, '.'), 1);

View file

@ -56,7 +56,6 @@ $lang = array_merge($lang, array(
'BBCODE_INVALID_TAG_NAME' => 'The BBCode tag name that you selected already exists.', 'BBCODE_INVALID_TAG_NAME' => 'The BBCode tag name that you selected already exists.',
'BBCODE_INVALID' => 'Your BBCode is constructed in an invalid form.', 'BBCODE_INVALID' => 'Your BBCode is constructed in an invalid form.',
'BBCODE_OPEN_ENDED_TAG' => 'Your custom BBCode must contain both an opening and a closing tag.',
'BBCODE_TAG' => 'Tag', 'BBCODE_TAG' => 'Tag',
'BBCODE_TAG_TOO_LONG' => 'The tag name you selected is too long.', 'BBCODE_TAG_TOO_LONG' => 'The tag name you selected is too long.',
'BBCODE_TAG_DEF_TOO_LONG' => 'The tag definition that you have entered is too long, please shorten your tag definition.', 'BBCODE_TAG_DEF_TOO_LONG' => 'The tag definition that you have entered is too long, please shorten your tag definition.',
@ -78,13 +77,13 @@ $lang = array_merge($lang, array(
'TOO_MANY_BBCODES' => 'You cannot create any more BBCodes. Please remove one or more BBCodes then try again.', 'TOO_MANY_BBCODES' => 'You cannot create any more BBCodes. Please remove one or more BBCodes then try again.',
'tokens' => array( 'tokens' => array(
'TEXT' => 'Any text, including foreign characters, numbers, etc… You should not use this token in HTML tags. Instead try to use IDENTIFIER, INTTEXT or SIMPLETEXT.', 'TEXT' => 'Any text, including foreign characters, numbers, etc…',
'SIMPLETEXT' => 'Characters from the latin alphabet (A-Z), numbers, spaces, commas, dots, minus, plus, hyphen and underscore', 'SIMPLETEXT' => 'Characters from the latin alphabet (A-Z), numbers, spaces, commas, dots, minus, plus, hyphen and underscore',
'INTTEXT' => 'Unicode letter characters, numbers, spaces, commas, dots, minus, plus, hyphen, underscore and whitespaces.', 'INTTEXT' => 'Unicode letter characters, numbers, spaces, commas, dots, minus, plus, hyphen, underscore and whitespaces.',
'IDENTIFIER' => 'Characters from the latin alphabet (A-Z), numbers, hyphen and underscore', 'IDENTIFIER' => 'Characters from the latin alphabet (A-Z), numbers, hyphen and underscore',
'NUMBER' => 'Any series of digits', 'NUMBER' => 'Any series of digits',
'EMAIL' => 'A valid email address', 'EMAIL' => 'A valid email address',
'URL' => 'A valid URL using any protocol (http, ftp, etc… cannot be used for javascript exploits). If none is given, “http://” is prefixed to the string.', 'URL' => 'A valid URL using any allowed protocol (http, ftp, etc… cannot be used for javascript exploits). If none is given, “http://” is prefixed to the string.',
'LOCAL_URL' => 'A local URL. The URL must be relative to the topic page and cannot contain a server name or protocol, as links are prefixed with “%s”', 'LOCAL_URL' => 'A local URL. The URL must be relative to the topic page and cannot contain a server name or protocol, as links are prefixed with “%s”',
'RELATIVE_URL' => 'A relative URL. You can use this to match parts of a URL, but be careful: a full URL is a valid relative URL. When you want to use relative URLs of your board, use the LOCAL_URL token.', 'RELATIVE_URL' => 'A relative URL. You can use this to match parts of a URL, but be careful: a full URL is a valid relative URL. When you want to use relative URLs of your board, use the LOCAL_URL token.',
'COLOR' => 'A HTML colour, can be either in the numeric form <samp>#FF1234</samp> or a <a href="http://www.w3.org/TR/CSS21/syndata.html#value-def-color">CSS colour keyword</a> such as <samp>fuchsia</samp> or <samp>InactiveBorder</samp>', 'COLOR' => 'A HTML colour, can be either in the numeric form <samp>#FF1234</samp> or a <a href="http://www.w3.org/TR/CSS21/syndata.html#value-def-color">CSS colour keyword</a> such as <samp>fuchsia</samp> or <samp>InactiveBorder</samp>',

View file

@ -91,7 +91,7 @@ $lang = array_merge($lang, array(
'ATTACHED_IMAGE_NOT_IMAGE' => 'The image file you tried to attach is invalid.', 'ATTACHED_IMAGE_NOT_IMAGE' => 'The image file you tried to attach is invalid.',
'AUTHOR' => 'Author', 'AUTHOR' => 'Author',
'AUTH_NO_PROFILE_CREATED' => 'The creation of a user profile was unsuccessful.', 'AUTH_NO_PROFILE_CREATED' => 'The creation of a user profile was unsuccessful.',
'AUTH_PROVIDER_OAUTH_ERROR_ALREADY_LINKED' => 'The account is already linked with other user.', '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_ENTRY' => 'Invalid database entry.',
'AUTH_PROVIDER_OAUTH_ERROR_INVALID_SERVICE_TYPE' => 'Invalid service type provided to OAuth service handler.', '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', 'AUTH_PROVIDER_OAUTH_ERROR_SERVICE_NOT_CREATED' => 'OAuth service not created',
@ -519,7 +519,7 @@ $lang = array_merge($lang, array(
'NO_POSTS_TIME_FRAME' => 'No posts exist inside this topic for the selected time frame.', 'NO_POSTS_TIME_FRAME' => 'No posts exist inside this topic for the selected time frame.',
'NO_FEED_ENABLED' => 'Feeds are not available on this board.', 'NO_FEED_ENABLED' => 'Feeds are not available on this board.',
'NO_FEED' => 'The requested feed is not available.', 'NO_FEED' => 'The requested feed is not available.',
'NO_STYLE_DATA' => 'Could not get style data', 'NO_STYLE_DATA' => 'Could not get style data for user_style %s and set for user_id %s',
'NO_STYLE_CFG' => 'Could not get the style configuration file for: %s', '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_SUBJECT' => 'No subject specified', // Used for posts having no subject defined but displayed within management pages.
'NO_SUCH_SEARCH_MODULE' => 'The specified search backend doesnt exist.', 'NO_SUCH_SEARCH_MODULE' => 'The specified search backend doesnt exist.',

View file

@ -1675,7 +1675,7 @@ switch ($mode)
} }
// do we need to display contact fields as such // 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 * Modify list of users before member row is created

View file

@ -216,10 +216,15 @@ class oauth extends \phpbb\auth\provider\base
$this->service_providers[$service_name]->set_external_service_provider($service); $this->service_providers[$service_name]->set_external_service_provider($service);
$unique_id = $this->service_providers[$service_name]->perform_auth_login(); $unique_id = $this->service_providers[$service_name]->perform_auth_login();
// Check to see if this provider is already assosciated with an account /**
* Check to see if this provider is already associated with an account.
*
* Enforcing a data type to make data contains strings and not integers,
* so values are quoted in the SQL WHERE statement.
*/
$data = array( $data = array(
'provider' => $service_name_original, 'provider' => (string) $service_name_original,
'oauth_provider_id' => $unique_id 'oauth_provider_id' => (string) $unique_id
); );
$sql = 'SELECT user_id FROM ' . $this->auth_provider_oauth_token_account_assoc . ' $sql = 'SELECT user_id FROM ' . $this->auth_provider_oauth_token_account_assoc . '

View file

@ -68,6 +68,9 @@ class mysqli extends \phpbb\db\driver\mysql_base
if ($this->db_connect_id && $this->dbname != '') 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'"); @mysqli_query($this->db_connect_id, "SET NAMES 'utf8'");
// enforce strict mode on databases that support it // enforce strict mode on databases that support it

View file

@ -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')),
);
}
}

View file

@ -835,7 +835,7 @@ class filesystem implements filesystem_interface
$current_path = $resolved_path . '/' . $path_part; $current_path = $resolved_path . '/' . $path_part;
// Resolve symlinks // Resolve symlinks
if (is_link($current_path)) if (@is_link($current_path))
{ {
if (!function_exists('readlink')) if (!function_exists('readlink'))
{ {
@ -872,12 +872,12 @@ class filesystem implements filesystem_interface
$resolved_path = false; $resolved_path = false;
} }
else if (is_dir($current_path . '/')) else if (@is_dir($current_path . '/'))
{ {
$resolved[] = $path_part; $resolved[] = $path_part;
$resolved_path = $current_path; $resolved_path = $current_path;
} }
else if (is_file($current_path)) else if (@is_file($current_path))
{ {
$resolved[] = $path_part; $resolved[] = $path_part;
$resolved_path = $current_path; $resolved_path = $current_path;

View file

@ -136,7 +136,7 @@ abstract class form
{ {
if (!check_form_key('memberlist_email')) if (!check_form_key('memberlist_email'))
{ {
$this->errors[] = 'FORM_INVALID'; $this->errors[] = $this->user->lang('FORM_INVALID');
} }
if (!count($this->errors)) if (!count($this->errors))

View file

@ -216,38 +216,36 @@ class plupload
} }
/** /**
* Looks at the list of allowed extensions and generates a string * Looks at the list of allowed extensions and generates a string
* appropriate for use in configuring plupload with * appropriate for use in configuring plupload with
* *
* @param \phpbb\cache\service $cache * @param \phpbb\cache\service $cache Cache service object
* @param string $forum_id The ID of the forum * @param string $forum_id The forum identifier
* *
* @return string * @return string
*/ */
public function generate_filter_string(\phpbb\cache\service $cache, $forum_id) public function generate_filter_string(\phpbb\cache\service $cache, $forum_id)
{ {
$groups = [];
$filters = [];
$attach_extensions = $cache->obtain_attach_extensions($forum_id); $attach_extensions = $cache->obtain_attach_extensions($forum_id);
unset($attach_extensions['_allowed_']); unset($attach_extensions['_allowed_']);
$groups = array();
// Re-arrange the extension array to $groups[$group_name][] // Re-arrange the extension array to $groups[$group_name][]
foreach ($attach_extensions as $extension => $extension_info) foreach ($attach_extensions as $extension => $extension_info)
{ {
if (!isset($groups[$extension_info['group_name']])) $groups[$extension_info['group_name']]['extensions'][] = $extension;
{ $groups[$extension_info['group_name']]['max_file_size'] = (int) $extension_info['max_filesize'];
$groups[$extension_info['group_name']] = array();
}
$groups[$extension_info['group_name']][] = $extension;
} }
$filters = array(); foreach ($groups as $group => $group_info)
foreach ($groups as $group => $extensions)
{ {
$filters[] = sprintf( $filters[] = sprintf(
"{title: '%s', extensions: '%s'}", "{title: '%s', extensions: '%s', max_file_size: %s}",
addslashes(ucfirst(strtolower($group))), addslashes(ucfirst(strtolower($group))),
addslashes(implode(',', $extensions)) addslashes(implode(',', $group_info['extensions'])),
$group_info['max_file_size']
); );
} }
@ -276,22 +274,37 @@ class plupload
} }
/** /**
* Checks various php.ini values and the maximum file size to determine * Checks various php.ini values to determine the maximum chunk
* the maximum size chunks a file can be split up into for upload * size a file should be split into for upload.
* *
* @return int * The intention is to calculate a value which reflects whatever
*/ * the most restrictive limit is set to. And to then set the chunk
* size to half that value, to ensure any required transfer overhead
* and POST data remains well within the limit. Or, if all of the
* limits are set to unlimited, the chunk size will also be unlimited.
*
* @return int
*
* @access public
*/
public function get_chunk_size() public function get_chunk_size()
{ {
$max = min( $max = 0;
$limits = [
$this->php_ini->getBytes('memory_limit'),
$this->php_ini->getBytes('upload_max_filesize'), $this->php_ini->getBytes('upload_max_filesize'),
$this->php_ini->getBytes('post_max_size'), $this->php_ini->getBytes('post_max_size'),
max(1, $this->php_ini->getBytes('memory_limit')), ];
$this->config['max_filesize']
); foreach ($limits as $limit_type)
{
if ($limit_type > 0)
{
$max = ($max !== 0) ? min($limit_type, $max) : $limit_type;
}
}
// Use half of the maximum possible to leave plenty of room for other
// POST data.
return floor($max / 2); return floor($max / 2);
} }

View file

@ -1077,7 +1077,7 @@ class session
*/ */
function set_cookie($name, $cookiedata, $cookietime, $httponly = true) function set_cookie($name, $cookiedata, $cookietime, $httponly = true)
{ {
global $config; global $config, $phpbb_dispatcher;
// If headers are already set, we just return // If headers are already set, we just return
if (headers_sent()) if (headers_sent())
@ -1085,6 +1085,32 @@ class session
return; return;
} }
$disable_cookie = false;
/**
* Event to modify or disable setting cookies
*
* @event core.set_cookie
* @var bool disable_cookie Set to true to disable setting this cookie
* @var string name Name of the cookie
* @var string cookiedata The data to hold within the cookie
* @var int cookietime The expiration time as UNIX timestamp
* @var bool httponly Use HttpOnly?
* @since 3.2.9-RC1
*/
$vars = array(
'disable_cookie',
'name',
'cookiedata',
'cookietime',
'httponly',
);
extract($phpbb_dispatcher->trigger_event('core.set_cookie', compact($vars)));
if ($disable_cookie)
{
return;
}
$name_data = rawurlencode($config['cookie_name'] . '_' . $name) . '=' . rawurlencode($cookiedata); $name_data = rawurlencode($config['cookie_name'] . '_' . $name) . '=' . rawurlencode($cookiedata);
$expire = gmdate('D, d-M-Y H:i:s \\G\\M\\T', $cookietime); $expire = gmdate('D, d-M-Y H:i:s \\G\\M\\T', $cookietime);
$domain = (!$config['cookie_domain'] || $config['cookie_domain'] == '127.0.0.1' || strpos($config['cookie_domain'], '.') === false) ? '' : '; domain=' . $config['cookie_domain']; $domain = (!$config['cookie_domain'] || $config['cookie_domain'] == '127.0.0.1' || strpos($config['cookie_domain'], '.') === false) ? '' : '; domain=' . $config['cookie_domain'];

View file

@ -110,7 +110,7 @@ class factory implements \phpbb\textformatter\cache_interface
'i' => '<span style="font-style: italic"><xsl:apply-templates/></span>', 'i' => '<span style="font-style: italic"><xsl:apply-templates/></span>',
'u' => '<span style="text-decoration: underline"><xsl:apply-templates/></span>', 'u' => '<span style="text-decoration: underline"><xsl:apply-templates/></span>',
'img' => '<img src="{IMAGEURL}" class="postimage" alt="{L_IMAGE}"/>', '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>', 'color' => '<span style="color: {COLOR}"><xsl:apply-templates/></span>',
'email' => '<a> 'email' => '<a>
<xsl:attribute name="href"> <xsl:attribute name="href">

View file

@ -342,7 +342,7 @@ class parser implements \phpbb\textformatter\parser_interface
return false; return false;
} }
if ($size < 1) if ($size < 1 || !is_numeric($size))
{ {
return false; return false;
} }

View file

@ -281,9 +281,43 @@ class user extends \phpbb\session
$db->sql_freeresult($result); $db->sql_freeresult($result);
} }
// Fallback to board's default style
if (!$this->style) if (!$this->style)
{ {
trigger_error('NO_STYLE_DATA', E_USER_ERROR); // Verify default style exists in the database
$sql = 'SELECT style_id
FROM ' . STYLES_TABLE . '
WHERE style_id = ' . (int) $config['default_style'];
$result = $db->sql_query($sql);
$style_id = (int) $db->sql_fetchfield('style_id');
$db->sql_freeresult($result);
if ($style_id > 0)
{
$db->sql_transaction('begin');
// Update $user row
$sql = 'SELECT *
FROM ' . STYLES_TABLE . '
WHERE style_id = ' . (int) $config['default_style'];
$result = $db->sql_query($sql);
$this->style = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
// Update user style preference
$sql = 'UPDATE ' . USERS_TABLE . '
SET user_style = ' . (int) $style_id . '
WHERE user_id = ' . (int) $this->data['user_id'];
$db->sql_query($sql);
$db->sql_transaction('commit');
}
}
// This should never happen
if (!$this->style)
{
trigger_error($this->language->lang('NO_STYLE_DATA', $this->data['user_style'], $this->data['user_id']), E_USER_ERROR);
} }
// Now parse the cfg file and cache it // Now parse the cfg file and cache it

View file

@ -974,7 +974,10 @@ if ($submit || $preview || $refresh)
} }
// Parse Attachments - before checksum is calculated // 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 * This event allows you to modify message text before parsing

View file

@ -1093,9 +1093,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_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']), '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' => $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_SUBJECT' => $row['topic_last_post_subject'],
'LAST_POST_TIME' => $user->format_date($row['topic_last_post_time']), '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' => $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' => 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_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']), 'LAST_POST_AUTHOR_FULL' => get_username_string('full', $row['topic_last_poster_id'], $row['topic_last_poster_name'], $row['topic_last_poster_colour']),

View file

@ -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> <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> </a>
<!-- ENDIF --> <!-- ENDIF -->
<br />{forumrow.LAST_POST_TIME} <br /><time datetime="{forumrow.LAST_POST_TIME_RFC3339}">{forumrow.LAST_POST_TIME}</time>
<!-- ELSE --> <!-- ELSE -->
{% if forumrow.U_UNAPPROVED_TOPICS %} {% if forumrow.U_UNAPPROVED_TOPICS %}
{{ lang('TOPIC_UNAPPROVED_FORUM', forumrow.TOPICS) }} {{ lang('TOPIC_UNAPPROVED_FORUM', forumrow.TOPICS) }}

View file

@ -118,7 +118,7 @@
<!-- EVENT mcp_topic_postrow_post_details_before --> <!-- EVENT mcp_topic_postrow_post_details_before -->
<p class="author"> <p class="author">
<a href="#pr{postrow.POST_ID}" title="{postrow.MINI_POST}"> <a href="{postrow.U_MINI_POST}" 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> <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} {% 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 --> </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> </p>

View file

@ -28,8 +28,13 @@
<p> <p>
<!-- IF AVATAR_IMG -->{AVATAR_IMG}<!-- ENDIF --> <!-- IF AVATAR_IMG -->{AVATAR_IMG}<!-- ENDIF -->
{% EVENT memberlist_body_group_rank_before %} {% EVENT memberlist_body_group_rank_before %}
<!-- IF RANK_IMG -->{RANK_IMG}<!-- ENDIF --> {% if RANK_IMG %}{{ RANK_IMG }}{% endif %}
<!-- IF GROUP_RANK -->{GROUP_RANK}<!-- ENDIF --> {% if GROUP_RANK %}
{% if not RANK_IMG %}
{{ lang('GROUP_RANK') ~ lang('COLON') }}
{% endif %}
{{ GROUP_RANK }}
{% endif %}
{% EVENT memberlist_body_group_rank_after %} {% EVENT memberlist_body_group_rank_after %}
</p> </p>
<!-- ELSE --> <!-- ELSE -->
@ -120,7 +125,13 @@
<tr class="<!-- IF memberrow.S_ROW_COUNT is even -->bg1<!-- ELSE -->bg2<!-- ENDIF --><!-- IF memberrow.S_INACTIVE --> inactive<!-- ENDIF -->"> <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 />[&nbsp;<a href="#" onclick="insert_single_user('#results', '{memberrow.A_USERNAME}'); return false;">{L_SELECT}</a>&nbsp;]<!-- ENDIF --></td> <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 />[&nbsp;<a href="#" onclick="insert_single_user('#results', '{memberrow.A_USERNAME}'); return false;">{L_SELECT}</a>&nbsp;]<!-- 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="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 -->&nbsp;<!-- 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 -%}
&nbsp;
{%- endfor -%}
</td>
<td>{memberrow.JOINED}</td> <td>{memberrow.JOINED}</td>
<!-- IF S_VIEWONLINE --><td>{memberrow.LAST_ACTIVE}&nbsp;</td><!-- ENDIF --> <!-- IF S_VIEWONLINE --><td>{memberrow.LAST_ACTIVE}&nbsp;</td><!-- ENDIF -->
{% EVENT memberlist_body_memberrow_after %} {% EVENT memberlist_body_memberrow_after %}

View file

@ -160,7 +160,7 @@
</li> </li>
<!-- ENDIF --> <!-- ENDIF -->
<!-- EVENT navbar_header_user_profile_append --> <!-- EVENT navbar_header_user_profile_append -->
<!-- ELSE --> <!-- ELSE IF not S_IS_BOT -->
<li class="rightside" data-skip-responsive="true"> <li class="rightside" data-skip-responsive="true">
<a href="{U_LOGIN_LOGOUT}" title="{L_LOGIN_LOGOUT}" accesskey="x" role="menuitem"> <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> <i class="icon fa-power-off fa-fw" aria-hidden="true"></i><span>{L_LOGIN_LOGOUT}</span>
@ -183,14 +183,14 @@
<!-- EVENT overall_header_breadcrumbs_before --> <!-- EVENT overall_header_breadcrumbs_before -->
<li class="breadcrumbs" itemscope itemtype="http://schema.org/BreadcrumbList"> <li class="breadcrumbs" itemscope itemtype="http://schema.org/BreadcrumbList">
<!-- IF U_SITE_HOME --> <!-- IF U_SITE_HOME -->
<span class="crumb" {$MICRODATA}><a href="{U_SITE_HOME}" itemtype="https://schema.org/Thing" itemprop="item" data-navbar-reference="home"><i class="icon fa-home fa-fw" aria-hidden="true"></i><span itemprop="name">{L_SITE_HOME}</span></a><meta itemprop="position" content="{{ navlink_position }}{% set navlink_position = navlink_position + 1 %}" /></span> <span class="crumb" {$MICRODATA}><a href="{U_SITE_HOME}" itemtype="https://schema.org/Thing" itemscope itemprop="item" data-navbar-reference="home"><i class="icon fa-home fa-fw" aria-hidden="true"></i><span itemprop="name">{L_SITE_HOME}</span></a><meta itemprop="position" content="{{ navlink_position }}{% set navlink_position = navlink_position + 1 %}" /></span>
<!-- ENDIF --> <!-- ENDIF -->
<!-- EVENT overall_header_breadcrumb_prepend --> <!-- EVENT overall_header_breadcrumb_prepend -->
<span class="crumb" {$MICRODATA}><a href="{U_INDEX}" itemtype="https://schema.org/Thing" itemprop="item" accesskey="h" data-navbar-reference="index"><!-- IF not U_SITE_HOME --><i class="icon fa-home fa-fw"></i><!-- ENDIF --><span itemprop="name">{L_INDEX}</span></a><meta itemprop="position" content="{{ navlink_position }}{% set navlink_position = navlink_position + 1 %}" /></span> <span class="crumb" {$MICRODATA}><a href="{U_INDEX}" itemtype="https://schema.org/Thing" itemscope itemprop="item" accesskey="h" data-navbar-reference="index"><!-- IF not U_SITE_HOME --><i class="icon fa-home fa-fw"></i><!-- ENDIF --><span itemprop="name">{L_INDEX}</span></a><meta itemprop="position" content="{{ navlink_position }}{% set navlink_position = navlink_position + 1 %}" /></span>
<!-- BEGIN navlinks --> <!-- BEGIN navlinks -->
<!-- EVENT overall_header_navlink_prepend --> <!-- EVENT overall_header_navlink_prepend -->
<span class="crumb" {$MICRODATA}<!-- IF navlinks.MICRODATA --> {navlinks.MICRODATA}<!-- ENDIF -->><a href="{navlinks.U_VIEW_FORUM}" itemtype="https://schema.org/Thing" itemprop="item"><span itemprop="name">{navlinks.FORUM_NAME}</span></a><meta itemprop="position" content="{{ navlink_position }}{% set navlink_position = navlink_position + 1 %}" /></span> <span class="crumb" {$MICRODATA}<!-- IF navlinks.MICRODATA --> {navlinks.MICRODATA}<!-- ENDIF -->><a href="{navlinks.U_VIEW_FORUM}" itemtype="https://schema.org/Thing" itemscope itemprop="item"><span itemprop="name">{navlinks.FORUM_NAME}</span></a><meta itemprop="position" content="{{ navlink_position }}{% set navlink_position = navlink_position + 1 %}" /></span>
<!-- EVENT overall_header_navlink_append --> <!-- EVENT overall_header_navlink_append -->
<!-- END navlinks --> <!-- END navlinks -->
<!-- EVENT overall_header_breadcrumb_append --> <!-- EVENT overall_header_breadcrumb_append -->

View file

@ -17,7 +17,7 @@
</p> </p>
<!-- ENDIF --> <!-- ENDIF -->
<!-- EVENT overall_footer_copyright_append --> <!-- EVENT overall_footer_copyright_append -->
<p class="footer-row"> <p class="footer-row" role="menu">
<a class="footer-link" href="{{ U_PRIVACY }}" title="{{ lang('PRIVACY_LINK') }}" role="menuitem"> <a class="footer-link" href="{{ U_PRIVACY }}" title="{{ lang('PRIVACY_LINK') }}" role="menuitem">
<span class="footer-link-text">{{ lang('PRIVACY_LINK') }}</span> <span class="footer-link-text">{{ lang('PRIVACY_LINK') }}</span>
</a> </a>

View file

@ -45,7 +45,14 @@ phpbb.plupload = {
max_file_size: '{FILESIZE}b', max_file_size: '{FILESIZE}b',
chunk_size: '{CHUNK_SIZE}b', chunk_size: '{CHUNK_SIZE}b',
unique_names: true, unique_names: true,
filters: [{FILTERS}], filters: {
mime_types: [
{FILTERS}
],
mime_types_max_file_size: [
{FILTERS}
],
},
{S_RESIZE} {S_RESIZE}
headers: {'X-PHPBB-USING-PLUPLOAD': '1', 'X-Requested-With': 'XMLHttpRequest'}, headers: {'X-PHPBB-USING-PLUPLOAD': '1', 'X-Requested-With': 'XMLHttpRequest'},
file_data_name: 'fileupload', file_data_name: 'fileupload',
@ -57,6 +64,7 @@ phpbb.plupload = {
lang: { lang: {
ERROR: '{LA_ERROR}', ERROR: '{LA_ERROR}',
TOO_MANY_ATTACHMENTS: '{LA_TOO_MANY_ATTACHMENTS}', TOO_MANY_ATTACHMENTS: '{LA_TOO_MANY_ATTACHMENTS}',
FORM_INVALID: '{LA_FORM_INVALID}',
}, },
order: '{ATTACH_ORDER}', order: '{ATTACH_ORDER}',
maxFiles: {MAX_ATTACHMENTS}, maxFiles: {MAX_ATTACHMENTS},

View file

@ -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 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; 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() function change_palette()
{ {
phpbb.toggleDisplay('colour_palette'); phpbb.toggleDisplay('colour_palette');
@ -117,7 +96,7 @@
<!-- EVENT posting_editor_buttons_custom_tags_before --> <!-- EVENT posting_editor_buttons_custom_tags_before -->
<!-- BEGIN custom_tags --> <!-- 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} {custom_tags.BBCODE_TAG}
</button> </button>
<!-- END custom_tags --> <!-- END custom_tags -->

View file

@ -13,7 +13,7 @@
<!-- ENDIF --> <!-- ENDIF -->
<div class="postbody" id="ppr{post_review_row.POST_ID}"> <div class="postbody" id="ppr{post_review_row.POST_ID}">
<h3><a href="#ppr{post_review_row.POST_ID}">{post_review_row.POST_SUBJECT}</a></h3> <h3><a href="{post_review_row.U_MINI_POST}">{post_review_row.POST_SUBJECT}</a></h3>
<p class="author"> <p class="author">
<!-- IF S_IS_BOT --> <!-- IF S_IS_BOT -->
<span><i class="icon fa-file fa-fw icon-lightgray icon-md" aria-hidden="true"></i><span class="sr-only">{post_review_row.MINI_POST}</span></span> <span><i class="icon fa-file fa-fw icon-lightgray icon-md" aria-hidden="true"></i><span class="sr-only">{post_review_row.MINI_POST}</span></span>

View file

@ -24,7 +24,7 @@
<!-- ENDIF --> <!-- ENDIF -->
<div class="postbody" id="pr{topic_review_row.POST_ID}"> <div class="postbody" id="pr{topic_review_row.POST_ID}">
<h3><a href="#pr{topic_review_row.POST_ID}">{topic_review_row.POST_SUBJECT}</a></h3> <h3><a href="{topic_review_row.U_MINI_POST}">{topic_review_row.POST_SUBJECT}</a></h3>
<!-- IF (topic_review_row.POSTER_QUOTE and topic_review_row.DECODED_MESSAGE) or topic_review_row.U_MCP_DETAILS --> <!-- IF (topic_review_row.POSTER_QUOTE and topic_review_row.DECODED_MESSAGE) or topic_review_row.U_MCP_DETAILS -->
<ul class="post-buttons"> <ul class="post-buttons">

View file

@ -108,7 +108,7 @@
<!-- IF not S_IS_BOT --> <!-- IF not S_IS_BOT -->
<div class="responsive-show" style="display: none;"> <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 --> &laquo; <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 --> &laquo; <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> <br />{L_POSTED} {L_IN} <a href="{searchresults.U_VIEW_FORUM}">{searchresults.FORUM_TITLE}</a>
</div> </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 --> <!-- 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.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 --> <!-- IF searchresults.ATTACH_ICON_IMG --><i class="icon fa-paperclip fa-fw" aria-hidden="true"></i><!-- ENDIF -->
{% EVENT topiclist_row_topic_by_author_before %} {% 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 --> &raquo; {searchresults.FIRST_POST_TIME} &raquo; {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 --> &raquo; <time datetime="{searchresults.FIRST_POST_TIME_RFC3339}">{searchresults.FIRST_POST_TIME}</time> &raquo; {L_IN} <a href="{searchresults.U_VIEW_FORUM}">{searchresults.FORUM_TITLE}</a>
{% EVENT topiclist_row_topic_by_author_after %} {% EVENT topiclist_row_topic_by_author_after %}
</div> </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> <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> </a>
<!-- ENDIF --> <!-- ENDIF -->
<br />{searchresults.LAST_POST_TIME} <br /><time datetime="{searchresults.LAST_POST_TIME_RFC3339}">{searchresults.LAST_POST_TIME}</time>
</span> </span>
</dd> </dd>
</dl> </dl>

View file

@ -13,7 +13,7 @@
<!-- EVENT ucp_profile_profile_info_before --> <!-- EVENT ucp_profile_profile_info_before -->
<!-- IF S_BIRTHDAYS_ENABLED --> <!-- IF S_BIRTHDAYS_ENABLED -->
<dl> <dl>
<dt><label for="bday_day">{L_BIRTHDAY}{L_COLON}</label><br /><span>{L_BIRTHDAY_EXPLAIN}</span></dt> <dt><label for="bday_day">{L_BIRTHDAY}{L_COLON}{% EVENT ucp_profile_profile_info_birthday_label_append %}</label><br /><span>{L_BIRTHDAY_EXPLAIN}</span></dt>
<dd> <dd>
<label for="bday_day">{L_DAY}{L_COLON} <select name="bday_day" id="bday_day">{S_BIRTHDAY_DAY_OPTIONS}</select></label> <label for="bday_day">{L_DAY}{L_COLON} <select name="bday_day" id="bday_day">{S_BIRTHDAY_DAY_OPTIONS}</select></label>
<label for="bday_month">{L_MONTH}{L_COLON} <select name="bday_month" id="bday_month">{S_BIRTHDAY_MONTH_OPTIONS}</select></label> <label for="bday_month">{L_MONTH}{L_COLON} <select name="bday_month" id="bday_month">{S_BIRTHDAY_MONTH_OPTIONS}</select></label>

View file

@ -187,7 +187,7 @@
<!-- IF not S_IS_BOT --> <!-- IF not S_IS_BOT -->
<div class="responsive-show" style="display: none;"> <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 --> &laquo; <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 --> &laquo; <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 --> <!-- 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> </div>
<!-- IF topicrow.REPLIES --> <!-- 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.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 --> <!-- IF topicrow.ATTACH_ICON_IMG --><i class="icon fa-paperclip fa-fw" aria-hidden="true"></i><!-- ENDIF -->
{% EVENT topiclist_row_topic_by_author_before %} {% 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 --> &raquo; {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 --> &raquo; <time datetime="{topicrow.FIRST_POST_TIME_RFC3339}">{topicrow.FIRST_POST_TIME}</time>
{% EVENT topiclist_row_topic_by_author_after %} {% EVENT topiclist_row_topic_by_author_after %}
<!-- IF topicrow.S_POST_GLOBAL and FORUM_ID != topicrow.FORUM_ID --> &raquo; {L_IN} <a href="{topicrow.U_VIEW_FORUM}">{topicrow.FORUM_NAME}</a><!-- ENDIF --> <!-- IF topicrow.S_POST_GLOBAL and FORUM_ID != topicrow.FORUM_ID --> &raquo; {L_IN} <a href="{topicrow.U_VIEW_FORUM}">{topicrow.FORUM_NAME}</a><!-- ENDIF -->
</div> </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> <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> </a>
<!-- ENDIF --> <!-- ENDIF -->
<br />{topicrow.LAST_POST_TIME} <br /><time datetime="{topicrow.LAST_POST_TIME_RFC3339}">{topicrow.LAST_POST_TIME}</time>
</span> </span>
</dd> </dd>
</dl> </dl>

View file

@ -224,7 +224,7 @@
<div id="post_content{postrow.POST_ID}"<!-- IF postrow.S_POST_HIDDEN --> style="display: none;"<!-- ENDIF -->> <div id="post_content{postrow.POST_ID}"<!-- IF postrow.S_POST_HIDDEN --> style="display: none;"<!-- ENDIF -->>
<!-- EVENT viewtopic_body_post_subject_before --> <!-- EVENT viewtopic_body_post_subject_before -->
<h3 <!-- IF postrow.S_FIRST_ROW -->class="first"<!-- ENDIF -->><!-- IF postrow.POST_ICON_IMG --><img src="{T_ICONS_PATH}{postrow.POST_ICON_IMG}" width="{postrow.POST_ICON_IMG_WIDTH}" height="{postrow.POST_ICON_IMG_HEIGHT}" alt="{postrow.POST_ICON_IMG_ALT}" title="{postrow.POST_ICON_IMG_ALT}" /> <!-- ENDIF --><a href="#p{postrow.POST_ID}">{postrow.POST_SUBJECT}</a></h3> <h3 <!-- IF postrow.S_FIRST_ROW -->class="first"<!-- ENDIF -->><!-- IF postrow.POST_ICON_IMG --><img src="{T_ICONS_PATH}{postrow.POST_ICON_IMG}" width="{postrow.POST_ICON_IMG_WIDTH}" height="{postrow.POST_ICON_IMG_HEIGHT}" alt="{postrow.POST_ICON_IMG_ALT}" title="{postrow.POST_ICON_IMG_ALT}" /> <!-- ENDIF --><a href="{postrow.U_MINI_POST}">{postrow.POST_SUBJECT}</a></h3>
<!-- DEFINE $SHOW_POST_BUTTONS = (postrow.U_EDIT or postrow.U_DELETE or postrow.U_REPORT or postrow.U_WARN or postrow.U_INFO or postrow.U_QUOTE) --> <!-- DEFINE $SHOW_POST_BUTTONS = (postrow.U_EDIT or postrow.U_DELETE or postrow.U_REPORT or postrow.U_WARN or postrow.U_INFO or postrow.U_QUOTE) -->
<!-- EVENT viewtopic_body_post_buttons_list_before --> <!-- EVENT viewtopic_body_post_buttons_list_before -->
@ -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> <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> </a>
<!-- ENDIF --> <!-- ENDIF -->
<span class="responsive-hide">{L_POST_BY_AUTHOR} <strong>{postrow.POST_AUTHOR_FULL}</strong> &raquo; </span>{postrow.POST_DATE} <span class="responsive-hide">{L_POST_BY_AUTHOR} <strong>{postrow.POST_AUTHOR_FULL}</strong> &raquo; </span><time datetime="{postrow.POST_DATE_RFC3339}">{postrow.POST_DATE}</time>
</p> </p>
<!-- EVENT viewtopic_body_postrow_post_details_after --> <!-- EVENT viewtopic_body_postrow_post_details_after -->

View file

@ -222,7 +222,7 @@ if ($mark_read == 'topics')
$data = array( $data = array(
'NO_UNREAD_POSTS' => $user->lang['NO_UNREAD_POSTS'], 'NO_UNREAD_POSTS' => $user->lang['NO_UNREAD_POSTS'],
'UNREAD_POSTS' => $user->lang['UNREAD_POSTS'], 'UNREAD_POSTS' => $user->lang['UNREAD_POSTS'],
'U_MARK_TOPICS' => ($user->data['is_registered'] || $config['load_anon_lastread']) ? append_sid("{$phpbb_root_path}viewforum.$phpEx", 'hash=' . generate_link_hash('global') . "&f=$forum_id&mark=topics&mark_time=" . time()) : '', 'U_MARK_TOPICS' => ($user->data['is_registered'] || $config['load_anon_lastread']) ? append_sid("{$phpbb_root_path}viewforum.$phpEx", 'hash=' . generate_link_hash('global') . "&f=$forum_id&mark=topics&mark_time=" . time(), false) : '',
'MESSAGE_TITLE' => $user->lang['INFORMATION'], 'MESSAGE_TITLE' => $user->lang['INFORMATION'],
'MESSAGE_TEXT' => $user->lang['TOPICS_MARKED'] 'MESSAGE_TEXT' => $user->lang['TOPICS_MARKED']
); );
@ -933,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_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']), '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' => $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_SUBJECT' => censor_text($row['topic_last_post_subject']),
'LAST_POST_TIME' => $user->format_date($row['topic_last_post_time']), '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' => $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' => 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_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']), 'LAST_POST_AUTHOR_FULL' => get_username_string('full', $row['topic_last_poster_id'], $row['topic_last_poster_name'], $row['topic_last_poster_colour']),

View file

@ -2044,6 +2044,7 @@ for ($i = 0, $end = count($post_list); $i < $end; ++$i)
'CONTACT_USER' => $user_cache[$poster_id]['contact_user'], 'CONTACT_USER' => $user_cache[$poster_id]['contact_user'],
'POST_DATE' => $user->format_date($row['post_time'], false, ($view == 'print') ? true : false), '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'], 'POST_SUBJECT' => $row['post_subject'],
'MESSAGE' => $message, 'MESSAGE' => $message,
'SIGNATURE' => ($row['enable_sig']) ? $user_cache[$poster_id]['sig'] : '', '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; ($s_notify) ? $qr_hidden_fields['notify'] = 1 : true;
($topic_data['topic_status'] == ITEM_LOCKED) ? $qr_hidden_fields['lock_topic'] = 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, 'S_QUICK_REPLY' => true,
'U_QR_ACTION' => append_sid("{$phpbb_root_path}posting.$phpEx", "mode=reply&amp;f=$forum_id&amp;t=$topic_id"), 'U_QR_ACTION' => append_sid("{$phpbb_root_path}posting.$phpEx", "mode=reply&amp;f=$forum_id&amp;t=$topic_id"),
'QR_HIDDEN_FIELDS' => build_hidden_fields($qr_hidden_fields), 'QR_HIDDEN_FIELDS' => build_hidden_fields($qr_hidden_fields),
'SUBJECT' => 'Re: ' . censor_text($topic_data['topic_title']), '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 :( // now I have the urge to wash my hands :(

View file

@ -55,7 +55,7 @@ class phpbb_functional_download_test extends phpbb_functional_test_case
// Test creating a reply // Test creating a reply
$post2 = $this->create_post($this->data['forums']['Download #1'], $post['topic_id'], 'Re: Download Topic #1-#2', 'This is a test post posted by the testing framework.', array('upload_files' => 1)); $post2 = $this->create_post($this->data['forums']['Download #1'], $post['topic_id'], 'Re: Download Topic #1-#2', 'This is a test post posted by the testing framework.', array('upload_files' => 1));
$crawler = self::request('GET', "viewtopic.php?t={$post2['topic_id']}&sid={$this->sid}"); $crawler = self::request('GET', "viewtopic.php?p={$post2['post_id']}&sid={$this->sid}");
$this->assertContains('Re: Download Topic #1-#2', $crawler->filter('html')->text()); $this->assertContains('Re: Download Topic #1-#2', $crawler->filter('html')->text());
$this->data['posts']['Re: Download Topic #1-#2'] = (int) $post2['post_id']; $this->data['posts']['Re: Download Topic #1-#2'] = (int) $post2['post_id'];

View file

@ -337,7 +337,7 @@ class phpbb_functional_feed_test extends phpbb_functional_test_case
// Test creating a reply // Test creating a reply
$post2 = $this->create_post($this->data['forums']['Feeds #news'], $post['topic_id'], 'Re: Feeds #news - Topic #2', 'This is a test post posted by the testing framework.'); $post2 = $this->create_post($this->data['forums']['Feeds #news'], $post['topic_id'], 'Re: Feeds #news - Topic #2', 'This is a test post posted by the testing framework.');
$crawler = self::request('GET', "viewtopic.php?t={$post2['topic_id']}&sid={$this->sid}"); $crawler = self::request('GET', "viewtopic.php?p={$post2['post_id']}&sid={$this->sid}");
self::assertContains('Re: Feeds #news - Topic #2', $crawler->filter('html')->text()); self::assertContains('Re: Feeds #news - Topic #2', $crawler->filter('html')->text());
$this->data['posts']['Re: Feeds #news - Topic #2'] = (int) $post2['post_id']; $this->data['posts']['Re: Feeds #news - Topic #2'] = (int) $post2['post_id'];
@ -493,7 +493,7 @@ class phpbb_functional_feed_test extends phpbb_functional_test_case
// Test creating a reply // Test creating a reply
$post2 = $this->create_post($this->data['forums']['Feeds #1'], $post['topic_id'], 'Re: Feeds #1 - Topic #2', 'This is a test post posted by the testing framework.'); $post2 = $this->create_post($this->data['forums']['Feeds #1'], $post['topic_id'], 'Re: Feeds #1 - Topic #2', 'This is a test post posted by the testing framework.');
$crawler = self::request('GET', "viewtopic.php?t={$post2['topic_id']}&sid={$this->sid}"); $crawler = self::request('GET', "viewtopic.php?p={$post2['post_id']}&sid={$this->sid}");
self::assertContains('Re: Feeds #1 - Topic #2', $crawler->filter('html')->text()); self::assertContains('Re: Feeds #1 - Topic #2', $crawler->filter('html')->text());
$this->data['posts']['Re: Feeds #1 - Topic #2'] = (int) $post2['post_id']; $this->data['posts']['Re: Feeds #1 - Topic #2'] = (int) $post2['post_id'];
@ -1222,7 +1222,7 @@ class phpbb_functional_feed_test extends phpbb_functional_test_case
// Test creating a reply with 1 missing attachment // Test creating a reply with 1 missing attachment
$post2 = $this->create_post($this->data['forums']['Feeds #1'], $this->data['topics']['Feeds #1 - Topic #3'], 'Re: Feeds #1 - Topic #3-1', 'This is a test post posted by the testing framework. [attachment=0]Attachment #0[/attachment]'); $post2 = $this->create_post($this->data['forums']['Feeds #1'], $this->data['topics']['Feeds #1 - Topic #3'], 'Re: Feeds #1 - Topic #3-1', 'This is a test post posted by the testing framework. [attachment=0]Attachment #0[/attachment]');
$crawler = self::request('GET', "viewtopic.php?t={$post2['topic_id']}&sid={$this->sid}"); $crawler = self::request('GET', "viewtopic.php?p={$post2['post_id']}&sid={$this->sid}");
self::assertContains('Re: Feeds #1 - Topic #3-1', $crawler->filter('html')->text()); self::assertContains('Re: Feeds #1 - Topic #3-1', $crawler->filter('html')->text());
$this->data['posts']['Re: Feeds #1 - Topic #3-1'] = (int) $post2['post_id']; $this->data['posts']['Re: Feeds #1 - Topic #3-1'] = (int) $post2['post_id'];

View file

@ -46,6 +46,13 @@ class phpbb_functional_fileupload_form_test extends phpbb_functional_test_case
private function upload_file($filename, $mimetype) private function upload_file($filename, $mimetype)
{ {
$crawler = self::$client->request(
'GET',
'posting.php?mode=reply&f=2&t=1&sid=' . $this->sid
);
$file_form_data = array_merge(['add_file' => $this->lang('ADD_FILE')], $this->get_hidden_fields($crawler, 'posting.php?mode=reply&f=2&t=1&sid=' . $this->sid));
$file = array( $file = array(
'tmp_name' => $this->path . $filename, 'tmp_name' => $this->path . $filename,
'name' => $filename, 'name' => $filename,
@ -57,7 +64,7 @@ class phpbb_functional_fileupload_form_test extends phpbb_functional_test_case
$crawler = self::$client->request( $crawler = self::$client->request(
'POST', 'POST',
'posting.php?mode=reply&f=2&t=1&sid=' . $this->sid, 'posting.php?mode=reply&f=2&t=1&sid=' . $this->sid,
array('add_file' => $this->lang('ADD_FILE')), $file_form_data,
array('fileupload' => $file) array('fileupload' => $file)
); );

View file

@ -76,6 +76,10 @@ class phpbb_functional_plupload_test extends phpbb_functional_test_case
$chunk_size = ceil(filesize($this->path . 'valid.jpg') / self::CHUNKS); $chunk_size = ceil(filesize($this->path . 'valid.jpg') / self::CHUNKS);
$handle = fopen($this->path . 'valid.jpg', 'rb'); $handle = fopen($this->path . 'valid.jpg', 'rb');
$crawler = self::$client->request('POST', $url . '&sid=' . $this->sid);
$file_form_data = $this->get_hidden_fields($crawler, $url);
for ($i = 0; $i < self::CHUNKS; $i++) for ($i = 0; $i < self::CHUNKS; $i++)
{ {
$chunk = fread($handle, $chunk_size); $chunk = fread($handle, $chunk_size);
@ -94,13 +98,13 @@ class phpbb_functional_plupload_test extends phpbb_functional_test_case
$crawler = self::$client->request( $crawler = self::$client->request(
'POST', 'POST',
$url . '&sid=' . $this->sid, $url . '&sid=' . $this->sid,
array( array_merge(array(
'chunk' => $i, 'chunk' => $i,
'chunks' => self::CHUNKS, 'chunks' => self::CHUNKS,
'name' => md5('valid') . '.jpg', 'name' => md5('valid') . '.jpg',
'real_filename' => 'valid.jpg', 'real_filename' => 'valid.jpg',
'add_file' => $this->lang('ADD_FILE'), 'add_file' => $this->lang('ADD_FILE'),
), ), $file_form_data),
array('fileupload' => $file), array('fileupload' => $file),
array('X-PHPBB-USING-PLUPLOAD' => '1') array('X-PHPBB-USING-PLUPLOAD' => '1')
); );
@ -134,17 +138,19 @@ class phpbb_functional_plupload_test extends phpbb_functional_test_case
'error' => UPLOAD_ERR_OK, 'error' => UPLOAD_ERR_OK,
); );
$file_form_data = $this->get_hidden_fields(null, $url);
self::$client->setServerParameter('HTTP_X_PHPBB_USING_PLUPLOAD', '1'); self::$client->setServerParameter('HTTP_X_PHPBB_USING_PLUPLOAD', '1');
self::$client->request( self::$client->request(
'POST', 'POST',
$url . '&sid=' . $this->sid, $url . '&sid=' . $this->sid,
array( array_merge(array(
'chunk' => '0', 'chunk' => '0',
'chunks' => '1', 'chunks' => '1',
'name' => md5('valid') . '.jpg', 'name' => md5('valid') . '.jpg',
'real_filename' => 'valid.jpg', 'real_filename' => 'valid.jpg',
'add_file' => $this->lang('ADD_FILE'), 'add_file' => $this->lang('ADD_FILE'),
), ), $file_form_data),
array('fileupload' => $file) array('fileupload' => $file)
); );

View file

@ -29,7 +29,7 @@ class phpbb_functional_posting_test extends phpbb_functional_test_case
// Test creating a reply with bbcode // Test creating a reply with bbcode
$post2 = $this->create_post(2, $post['topic_id'], 'Re: Test Topic 1', 'This is a test [b]post[/b] posted by the testing framework.'); $post2 = $this->create_post(2, $post['topic_id'], 'Re: Test Topic 1', 'This is a test [b]post[/b] posted by the testing framework.');
$crawler = self::request('GET', "viewtopic.php?t={$post2['topic_id']}&sid={$this->sid}"); $crawler = self::request('GET', "viewtopic.php?p={$post2['post_id']}&sid={$this->sid}");
$this->assertContains('This is a test post posted by the testing framework.', $crawler->filter('html')->text()); $this->assertContains('This is a test post posted by the testing framework.', $crawler->filter('html')->text());
// Test quoting a message // Test quoting a message
@ -156,7 +156,7 @@ class phpbb_functional_posting_test extends phpbb_functional_test_case
{ {
$this->set_quote_depth($quote_depth); $this->set_quote_depth($quote_depth);
$post = $this->create_post(2, $topic['topic_id'], 'Re: Test Topic 1', $text); $post = $this->create_post(2, $topic['topic_id'], "Re: Test Topic 1#$quote_depth", $text);
$url = "viewtopic.php?p={$post['post_id']}&sid={$this->sid}"; $url = "viewtopic.php?p={$post['post_id']}&sid={$this->sid}";
$crawler = self::request('GET', $url); $crawler = self::request('GET', $url);

View file

@ -77,7 +77,7 @@ class phpbb_functional_prune_shadow_topic_test extends phpbb_functional_test_cas
// Test creating a reply // Test creating a reply
$post2 = $this->create_post($this->data['forums']['Prune Shadow'], $this->post['topic_id'], 'Re: Prune Shadow #1-#2', 'This is a test post posted by the testing framework.'); $post2 = $this->create_post($this->data['forums']['Prune Shadow'], $this->post['topic_id'], 'Re: Prune Shadow #1-#2', 'This is a test post posted by the testing framework.');
$crawler = self::request('GET', "viewtopic.php?t={$post2['topic_id']}&sid={$this->sid}"); $crawler = self::request('GET', "viewtopic.php?p={$post2['post_id']}&sid={$this->sid}");
$this->assertContains('Re: Prune Shadow #1-#2', $crawler->filter('html')->text()); $this->assertContains('Re: Prune Shadow #1-#2', $crawler->filter('html')->text());
$this->data['posts']['Re: Prune Shadow #1-#2'] = (int) $post2['post_id']; $this->data['posts']['Re: Prune Shadow #1-#2'] = (int) $post2['post_id'];

View file

@ -97,7 +97,7 @@ class phpbb_functional_visibility_softdelete_test extends phpbb_functional_test_
// Test creating a reply // Test creating a reply
$post2 = $this->create_post($this->data['forums']['Soft Delete #1'], $post['topic_id'], 'Re: Soft Delete Topic #1-#2', 'This is a test post posted by the testing framework.'); $post2 = $this->create_post($this->data['forums']['Soft Delete #1'], $post['topic_id'], 'Re: Soft Delete Topic #1-#2', 'This is a test post posted by the testing framework.');
$crawler = self::request('GET', "viewtopic.php?t={$post2['topic_id']}&sid={$this->sid}"); $crawler = self::request('GET', "viewtopic.php?p={$post2['post_id']}&sid={$this->sid}");
$this->assertContains('Re: Soft Delete Topic #1-#2', $crawler->filter('html')->text()); $this->assertContains('Re: Soft Delete Topic #1-#2', $crawler->filter('html')->text());
$this->data['posts']['Re: Soft Delete Topic #1-#2'] = (int) $post2['post_id']; $this->data['posts']['Re: Soft Delete Topic #1-#2'] = (int) $post2['post_id'];
@ -114,7 +114,7 @@ class phpbb_functional_visibility_softdelete_test extends phpbb_functional_test_
// Test creating another reply // Test creating another reply
$post3 = $this->create_post($this->data['forums']['Soft Delete #1'], $post['topic_id'], 'Re: Soft Delete Topic #1-#3', 'This is another test post posted by the testing framework.'); $post3 = $this->create_post($this->data['forums']['Soft Delete #1'], $post['topic_id'], 'Re: Soft Delete Topic #1-#3', 'This is another test post posted by the testing framework.');
$crawler = self::request('GET', "viewtopic.php?t={$post3['topic_id']}&sid={$this->sid}"); $crawler = self::request('GET', "viewtopic.php?p={$post3['post_id']}&sid={$this->sid}");
$this->assertContains('Re: Soft Delete Topic #1-#3', $crawler->filter('html')->text()); $this->assertContains('Re: Soft Delete Topic #1-#3', $crawler->filter('html')->text());
$this->data['posts']['Re: Soft Delete Topic #1-#3'] = (int) $post3['post_id']; $this->data['posts']['Re: Soft Delete Topic #1-#3'] = (int) $post3['post_id'];

View file

@ -1,5 +1,29 @@
<?xml version="1.0" encoding="UTF-8" ?> <?xml version="1.0" encoding="UTF-8" ?>
<dataset> <dataset>
<table name="phpbb_banlist">
<column>ban_id</column>
<column>ban_userid</column>
<column>ban_exclude</column>
<column>ban_end</column>
<column>ban_email</column>
<column>ban_give_reason</column>
<row>
<value>1</value>
<value>0</value>
<value>0</value>
<value>0</value>
<value>banned@example.com</value>
<value></value>
</row>
<row>
<value>2</value>
<value>0</value>
<value>0</value>
<value>0</value>
<value>banned2@example.com</value>
<value>just because</value>
</row>
</table>
<table name="phpbb_users"> <table name="phpbb_users">
<column>user_id</column> <column>user_id</column>
<column>username</column> <column>username</column>

View file

@ -28,10 +28,16 @@ class phpbb_functions_validate_user_email_test extends phpbb_database_test_case
protected function setUp() protected function setUp()
{ {
global $cache, $phpbb_dispatcher, $phpbb_root_path, $phpEx;
parent::setUp(); parent::setUp();
$cache = new \phpbb\cache\driver\file();
$cache->purge();
$this->db = $this->new_dbal(); $this->db = $this->new_dbal();
$this->user = new phpbb_mock_user; $phpbb_dispatcher = new phpbb_mock_event_dispatcher();
$language = new phpbb\language\language(new phpbb\language\language_file_loader($phpbb_root_path, $phpEx));
$this->user = new phpbb\user($language, '\phpbb\datetime');
$this->helper = new phpbb_functions_validate_data_helper($this); $this->helper = new phpbb_functions_validate_data_helper($this);
} }
@ -47,7 +53,6 @@ class phpbb_functions_validate_user_email_test extends phpbb_database_test_case
$config['email_check_mx'] = $check_mx; $config['email_check_mx'] = $check_mx;
$db = $this->db; $db = $this->db;
$user = $this->user; $user = $this->user;
$user->optionset('banned_users', array('banned@example.com'));
} }
public static function validate_user_email_data() public static function validate_user_email_data()
@ -58,7 +63,8 @@ class phpbb_functions_validate_user_email_test extends phpbb_database_test_case
array('valid_complex', array(), "'%$~test@example.com"), array('valid_complex', array(), "'%$~test@example.com"),
array('invalid', array('EMAIL_INVALID'), 'fööbar@example.com'), array('invalid', array('EMAIL_INVALID'), 'fööbar@example.com'),
array('taken', array('EMAIL_TAKEN'), 'admin@example.com'), array('taken', array('EMAIL_TAKEN'), 'admin@example.com'),
array('banned', array('EMAIL_BANNED'), 'banned@example.com'), array('banned', ['just because'], 'banned2@example.com'),
array('banned', ['EMAIL_BANNED'], 'banned@example.com')
); );
} }

View file

@ -54,4 +54,77 @@ class phpbb_plupload_test extends phpbb_test_case
$this->assertEquals($expected, $plupload->generate_resize_string()); $this->assertEquals($expected, $plupload->generate_resize_string());
} }
public function data_get_chunk_size()
{
return [
[[
'memory_limit' => -1,
'upload_max_filesize' => 0,
'post_max_size' => 0,
], 0],
[[
'memory_limit' => -1,
'upload_max_filesize' => 500,
'post_max_size' => 400,
], 200],
[[
'memory_limit' => 100,
'upload_max_filesize' => 0,
'post_max_size' => 300,
], 50],
[[
'memory_limit' => 300,
'upload_max_filesize' => 200,
'post_max_size' => 0,
], 100],
[[
'memory_limit' => 3000,
'upload_max_filesize' => 800,
'post_max_size' => 900,
], 400],
[[
'memory_limit' => 2000,
'upload_max_filesize' => 1000,
'post_max_size' => 600,
], 300],
[[
'memory_limit' => 1000,
'upload_max_filesize' => 2000,
'post_max_size' => 3000,
], 500],
];
}
/**
* @dataProvider data_get_chunk_size
*/
public function test_get_chunk_size($limits_ary, $expected)
{
global $phpbb_root_path, $phpEx;
$lang = new \phpbb\language\language(new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx));
$config = new \phpbb\config\config([]);
$ini_wrapper = $this->getMockBuilder('\bantu\IniGetWrapper\IniGetWrapper')
->setMethods(['getBytes'])
->getMock();
$ini_wrapper->method('getBytes')
->will($this->returnValueMap([
['memory_limit', $limits_ary['memory_limit']],
['upload_max_filesize', $limits_ary['upload_max_filesize']],
['post_max_size', $limits_ary['post_max_size']]
]));
$plupload = new \phpbb\plupload\plupload(
'',
$config,
new phpbb_mock_request,
new \phpbb\user($lang, '\phpbb\datetime'),
$ini_wrapper,
new \phpbb\mimetype\guesser(array(new \phpbb\mimetype\extension_guesser))
);
$this->assertEquals($expected, $plupload->get_chunk_size());
}
} }

View file

@ -1166,24 +1166,14 @@ class phpbb_functional_test_case extends phpbb_test_case
'error' => UPLOAD_ERR_OK, 'error' => UPLOAD_ERR_OK,
); );
$crawler = self::$client->request('POST', $posting_url, array('add_file' => $this->lang('ADD_FILE')), array('fileupload' => $file)); $file_form_data = array_merge(['add_file' => $this->lang('ADD_FILE')], $this->get_hidden_fields($crawler, $posting_url));
$crawler = self::$client->request('POST', $posting_url, $file_form_data, array('fileupload' => $file));
} }
unset($form_data['upload_files']); unset($form_data['upload_files']);
} }
$hidden_fields = array( $form_data = array_merge($form_data, $this->get_hidden_fields($crawler, $posting_url));
$crawler->filter('[type="hidden"]')->each(function ($node, $i) {
return array('name' => $node->attr('name'), 'value' => $node->attr('value'));
}),
);
foreach ($hidden_fields as $fields)
{
foreach($fields as $field)
{
$form_data[$field['name']] = $field['value'];
}
}
// I use a request because the form submission method does not allow you to send data that is not // I use a request because the form submission method does not allow you to send data that is not
// contained in one of the actual form fields that the browser sees (i.e. it ignores "hidden" inputs) // contained in one of the actual form fields that the browser sees (i.e. it ignores "hidden" inputs)
@ -1314,4 +1304,37 @@ class phpbb_functional_test_case extends phpbb_test_case
return self::request('GET', substr($link, strpos($link, 'mcp.'))); return self::request('GET', substr($link, strpos($link, 'mcp.')));
} }
/**
* Get hidden fields for URL
*
* @param Symfony\Component\DomCrawler\Crawler|null $crawler Crawler instance or null
* @param string $url Request URL
*
* @return array Hidden form fields array
*/
protected function get_hidden_fields($crawler, $url)
{
if (!$crawler)
{
$crawler = self::$client->request('GET', $url);
}
$hidden_fields = [
$crawler->filter('[type="hidden"]')->each(function ($node, $i) {
return ['name' => $node->attr('name'), 'value' => $node->attr('value')];
}),
];
$file_form_data = [];
foreach ($hidden_fields as $fields)
{
foreach($fields as $field)
{
$file_form_data[$field['name']] = $field['value'];
}
}
return $file_form_data;
}
} }

View file

@ -158,7 +158,26 @@ class phpbb_ui_test_case extends phpbb_test_case
public function visit($path) public function visit($path)
{ {
$this->getDriver()->get(self::$root_url . $path); // Retry three times on curl issues, e.g. timeout
$attempts = 0;
$retries = 3;
while (true)
{
$attempts++;
try
{
$this->getDriver()->get(self::$root_url . $path);
break;
}
catch (Facebook\WebDriver\Exception\WebDriverCurlException $exception)
{
if ($attempts >= $retries)
{
throw $exception;
}
}
}
} }
static protected function recreate_database($config) static protected function recreate_database($config)

View file

@ -70,7 +70,7 @@ class phpbb_textformatter_s9e_default_formatting_test extends phpbb_test_case
), ),
array( array(
'[size=75]smaller[/size]', '[size=75]smaller[/size]',
'<span style="font-size:75%;line-height:normal">smaller</span>' '<span style="font-size: 75%; line-height: normal">smaller</span>'
), ),
array( array(
'[quote]quoted[/quote]', '[quote]quoted[/quote]',

View file

@ -1 +1 @@
<span style="font-size:200%;line-height:normal"></span><div style="text-align:center"><span style="font-size:200%;line-height:normal">xxx</span></div> <span style="font-size: 200%; line-height: normal"></span><div style="text-align:center"><span style="font-size: 200%; line-height: normal">xxx</span></div>