diff options
103 files changed, 3139 insertions, 1301 deletions
| diff --git a/build/build.xml b/build/build.xml index 56fe802824..8ac7c1758c 100644 --- a/build/build.xml +++ b/build/build.xml @@ -2,9 +2,9 @@  <project name="phpBB" description="The phpBB forum software" default="all" basedir="../">  	<!-- a few settings for the build --> -	<property name="newversion" value="3.1.0-RC4-dev" /> -	<property name="prevversion" value="3.1.0-RC3" /> -	<property name="olderversions" value="3.0.12, 3.1.0-a1, 3.1.0-a2, 3.1.0-a3, 3.1.0-b1, 3.1.0-b2, 3.1.0-b3, 3.1.0-b4, 3.1.0-RC1, 3.1.0-RC2" /> +	<property name="newversion" value="3.1.0-RC5-dev" /> +	<property name="prevversion" value="3.1.0-RC4" /> +	<property name="olderversions" value="3.0.12, 3.1.0-a1, 3.1.0-a2, 3.1.0-a3, 3.1.0-b1, 3.1.0-b2, 3.1.0-b3, 3.1.0-b4, 3.1.0-RC1, 3.1.0-RC2, 3.1.0-RC3" />  	<!-- no configuration should be needed beyond this point -->  	<property name="oldversions" value="${olderversions}, ${prevversion}" /> diff --git a/phpBB/adm/style/acp_attachments.html b/phpBB/adm/style/acp_attachments.html index 59b10f597e..da8a0096ea 100644 --- a/phpBB/adm/style/acp_attachments.html +++ b/phpBB/adm/style/acp_attachments.html @@ -284,8 +284,6 @@  	</fieldset>  	</form> -	<br /> -  	<form id="change_ext" method="post" action="{U_ACTION}">  	<fieldset class="tabulated"> diff --git a/phpBB/adm/style/acp_captcha.html b/phpBB/adm/style/acp_captcha.html index df4c675209..f4866653c3 100644 --- a/phpBB/adm/style/acp_captcha.html +++ b/phpBB/adm/style/acp_captcha.html @@ -6,6 +6,7 @@  <p>{L_ACP_VC_SETTINGS_EXPLAIN}</p> +<p>{L_ACP_VC_EXT_GET_MORE}</p>  <form id="acp_captcha" method="post" action="{U_ACTION}"> diff --git a/phpBB/adm/style/acp_inactive.html b/phpBB/adm/style/acp_inactive.html index 1cdc1abe6b..409ea46de5 100644 --- a/phpBB/adm/style/acp_inactive.html +++ b/phpBB/adm/style/acp_inactive.html @@ -2,14 +2,12 @@  <a id="maincontent"></a> -<h2>{L_INACTIVE_USERS}</h2> +<h1>{L_INACTIVE_USERS}</h1>  <p>{L_INACTIVE_USERS_EXPLAIN}</p>  <form id="inactive" method="post" action="{U_ACTION}"> -<div class="clearfix"></div> -  <!-- IF .pagination -->  <div class="pagination">  	<!-- INCLUDE pagination.html --> diff --git a/phpBB/adm/style/acp_logs.html b/phpBB/adm/style/acp_logs.html index ec2065f906..76ea801de0 100644 --- a/phpBB/adm/style/acp_logs.html +++ b/phpBB/adm/style/acp_logs.html @@ -8,7 +8,7 @@  <form id="list" method="post" action="{U_ACTION}"> -<fieldset class="display-options" style="float: left"> +<fieldset class="display-options search-box">  	{L_SEARCH_KEYWORDS}{L_COLON} <input type="text" name="keywords" value="{S_KEYWORDS}" /> <input type="submit" class="button2" name="filter" value="{L_SEARCH}" />  </fieldset> @@ -18,9 +18,6 @@  </div>  <!-- ENDIF --> -<div class="clearfix"> </div> -<div><br style="clear: both;" /></div> -  <!-- IF .log -->  	<table class="table1 zebra-table fixed-width-table">  	<thead> diff --git a/phpBB/adm/style/acp_main.html b/phpBB/adm/style/acp_main.html index 9a9b3ff2b9..065dd7ac4f 100644 --- a/phpBB/adm/style/acp_main.html +++ b/phpBB/adm/style/acp_main.html @@ -243,9 +243,6 @@  		<!-- END log -->  		</tbody>  		</table> - -		<br /> -  	<!-- ENDIF -->  	<!-- IF S_INACTIVE_USERS --> @@ -287,7 +284,6 @@  		<!-- END inactive -->  		</tbody>  		</table> -  	<!-- ENDIF -->  <!-- ENDIF --> diff --git a/phpBB/adm/style/admin.css b/phpBB/adm/style/admin.css index b8f55e66c5..b03cb0ba24 100644 --- a/phpBB/adm/style/admin.css +++ b/phpBB/adm/style/admin.css @@ -109,6 +109,14 @@ hr {  	text-align: center;  } +.search-box { +	float: left; +} + +.rtl .search-box { +	float: right; +} +  .small {  	font-size: 0.85em;  } @@ -154,6 +162,10 @@ a:active {  	font-weight: bold;  } +a#maincontent, a#acl, a#assigned_to { +	display: block; +} +  /* List items */  ul, ol {  	list-style-position: inside; @@ -174,7 +186,6 @@ li {  }  #page-header { -	clear: both;  	text-align: right;  	background: url("../images/phpbb_logo.png") top left no-repeat;  	height: 54px; @@ -203,14 +214,9 @@ li {  }  #page-body { -	clear: both;  	min-width: 650px;  } -#page-footer { -	clear: both; -} -  .copyright {  	font-size: 0.75em;  	text-align: center; @@ -335,12 +341,6 @@ li {  	padding: 0;  } -#tabs > ul:after { -	content: ''; -	display: block; -	clear: both; -} -  #tabs .tab {  	display: inline-block;  	float: left; @@ -475,7 +475,6 @@ li {  /* Main Panel  ---------------------------------------- */  #acp { -	clear: both;  	position: relative;  	top: -2px;  	margin: 0 0 2px; @@ -723,6 +722,7 @@ td {  .table1 {  	border-collapse: separate;  	border-spacing: 1px; +	clear: both;  }  dt#color_palette_placeholder table { @@ -862,10 +862,10 @@ table.zebra-table tbody tr:nth-child(even) {  }  /* Deactivated row */ -.row-inactive {  -	color: #999;  +.row-inactive { +	color: #999;  } -.row-inactive a, .row-inactive strong {  +.row-inactive a, .row-inactive strong {  	color: #888;  }  .row-inactive a:hover { @@ -1132,6 +1132,11 @@ input.langvalue, textarea.langvalue {  	width: 90%;  } +input[type="number"] { +	width: 60px; +	-moz-padding-end: 0; +} +  optgroup, select {  	background-color: #FAFAFA;  	border: 1px solid #666666; @@ -1226,8 +1231,8 @@ fieldset.quick legend {  fieldset.tabulated {  	background: none;  	margin: 0; +	margin-top: 5px;  	padding: 0; -	padding-top: 5px;  	border: 0;  } @@ -1464,7 +1469,7 @@ input:focus, textarea:focus {  {  	select, dd select, dd input {  		max-width: 240px; -	}	 +	}  }  /* Submit button fieldset or paragraph @@ -1676,12 +1681,12 @@ input.button1:focus, input.button2:focus {  	height: 1%; /* IE tweak (holly hack) */  	width: auto;  	text-align: right; -	margin-top: 5px; +	margin: 5px 0;  }  .top-pagination {  	float: right; -	margin: 15px 0 2px 0; +	margin: 15px 0 5px 0;  }  .rtl .pagination { @@ -1776,6 +1781,7 @@ li.pagination ul {  	margin: 10px 0;  	color: #FFFFFF;  	text-align: center; +	clear: both;  }  .success { @@ -1877,17 +1883,7 @@ li.pagination ul {  	vertical-align: middle;  } -/* Nice method for clearing floated blocks without having to insert any extra markup -	From http://www.positioniseverything.net/easyclearing.html -.clearfix:after, #tabs:after, .row:after, #content:after, fieldset dl:after, #page-body:after { -	content: "."; -	display: block; -	height: 0; -	clear: both; -	visibility: hidden; -}*/ - -.clearfix, .row, #content, fieldset dl, #page-body { +.row, fieldset dl {  	overflow: hidden;  } @@ -2470,3 +2466,20 @@ fieldset.permissions .padding {  	.responsive-show-inline { display: inline !important; }  	.responsive-show-inline-block { display: inline-block !important; }  } + +.clearfix { +	overflow: hidden; +} + +.pagination:after, +#page-header:after, +#page-body:after, +#tabs:after, +#tabs > ul:after, +#tabs li:after, +#acp:after, +#content:after { +	content: ''; +	clear: both; +	display: block; +} diff --git a/phpBB/adm/style/ajax.js b/phpBB/adm/style/ajax.js index 959580d6c2..4ad6b6afa5 100644 --- a/phpBB/adm/style/ajax.js +++ b/phpBB/adm/style/ajax.js @@ -1,6 +1,8 @@ +/* global phpbb */ +  (function($) {  // Avoid conflicts with other libraries -"use strict"; +'use strict';  /**   * The following callbacks are for reording items. row_down @@ -13,11 +15,10 @@ phpbb.addAjaxCallback('row_down', function(res) {  		return;  	} -	var el = $(this), -		tr = el.parents('tr'), -		trSwap = tr.next(); +	var $firstTr = $(this).parents('tr'), +		$secondTr = $firstTr.next(); -	tr.insertAfter(trSwap); +	$firstTr.insertAfter($secondTr);  });  phpbb.addAjaxCallback('row_up', function(res) { @@ -25,11 +26,10 @@ phpbb.addAjaxCallback('row_up', function(res) {  		return;  	} -	var el = $(this), -		tr = el.parents('tr'), -		trSwap = tr.prev(); +	var $secondTr = $(this).parents('tr'), +		$firstTr = $secondTr.prev(); -	tr.insertBefore(trSwap); +	$secondTr.insertBefore($firstTr);  });  /** @@ -38,10 +38,10 @@ phpbb.addAjaxCallback('row_up', function(res) {   * in the href with "deactivate", and vice versa.   */  phpbb.addAjaxCallback('activate_deactivate', function(res) { -	var el = $(this), -		newHref = el.attr('href'); +	var $this = $(this), +		newHref = $this.attr('href'); -	el.text(res.text); +	$this.text(res.text);  	if (newHref.indexOf('deactivate') !== -1) {  		newHref = newHref.replace('deactivate', 'activate'); @@ -49,7 +49,7 @@ phpbb.addAjaxCallback('activate_deactivate', function(res) {  		newHref = newHref.replace('activate', 'deactivate');  	} -	el.attr('href', newHref); +	$this.attr('href', newHref);  });  /** @@ -66,11 +66,10 @@ phpbb.addAjaxCallback('row_delete', function(res) {  $('[data-ajax]').each(function() {  	var $this = $(this), -		ajax = $this.attr('data-ajax'), -		fn; +		ajax = $this.attr('data-ajax');  	if (ajax !== 'false') { -		fn = (ajax !== 'true') ? ajax : null; +		var fn = (ajax !== 'true') ? ajax : null;  		phpbb.ajaxify({  			selector: this,  			refresh: $this.attr('data-refresh') !== undefined, @@ -82,7 +81,7 @@ $('[data-ajax]').each(function() {  /**  * Automatically resize textarea  */ -$(document).ready(function() { +$(function() {  	phpbb.resizeTextArea($('textarea:not(.no-auto-resize)'), {minHeight: 75});  }); diff --git a/phpBB/assets/javascript/core.js b/phpBB/assets/javascript/core.js index 388f31698f..b5187991f9 100644 --- a/phpBB/assets/javascript/core.js +++ b/phpBB/assets/javascript/core.js @@ -3,7 +3,7 @@ phpbb.alertTime = 100;  (function($) {  // Avoid conflicts with other libraries -"use strict"; +'use strict';  // define a couple constants for keydown functions.  var keymap = { @@ -12,8 +12,8 @@ var keymap = {  	ESC: 27  }; -var dark = $('#darkenwrapper'); -var loadingIndicator = $('#loading_indicator'); +var $dark = $('#darkenwrapper'); +var $loadingIndicator = $('#loading_indicator');  var phpbbAlertTimer = null;  phpbb.isTouch = (window && typeof window.ontouchstart !== 'undefined'); @@ -24,18 +24,20 @@ phpbb.isTouch = (window && typeof window.ontouchstart !== 'undefined');   * @returns object Returns loadingIndicator.   */  phpbb.loadingIndicator = function() { -	if (!loadingIndicator.is(':visible')) { -		loadingIndicator.fadeIn(phpbb.alertTime); +	if (!$loadingIndicator.is(':visible')) { +		$loadingIndicator.fadeIn(phpbb.alertTime);  		// Wait fifteen seconds and display an error if nothing has been returned by then.  		phpbb.clearLoadingTimeout();  		phpbbAlertTimer = setTimeout(function() { -			if (loadingIndicator.is(':visible')) { -				phpbb.alert($('#phpbb_alert').attr('data-l-err'), $('#phpbb_alert').attr('data-l-timeout-processing-req')); +			var $alert = $('#phpbb_alert'); + +			if ($loadingIndicator.is(':visible')) { +				phpbb.alert($alert.attr('data-l-err'), $alert.attr('data-l-timeout-processing-req'));  			}  		}, 15000);  	} -	return loadingIndicator; +	return $loadingIndicator;  };  /** @@ -73,60 +75,77 @@ phpbb.closeDarkenWrapper = function(delay) {   * @returns object Returns the div created.   */  phpbb.alert = function(title, msg, fadedark) { -	var div = $('#phpbb_alert'); -	div.find('.alert_title').html(title); -	div.find('.alert_text').html(msg); +	var $alert = $('#phpbb_alert'); +	$alert.find('.alert_title').html(title); +	$alert.find('.alert_text').html(msg); + +	$(document).on('keydown.phpbb.alert', function(e) { +		if (e.keyCode === keymap.ENTER || e.keyCode === keymap.ESC) { +			phpbb.alert.close($alert, true); +			e.preventDefault(); +			e.stopPropagation(); +		} +	}); +	phpbb.alert.open($alert); + +	return $alert; +}; + +/** +* Handler for opening an alert box. +* +* @param jQuery $alert			jQuery object. +*/ +phpbb.alert.open = function($alert) { +	if (!$dark.is(':visible')) { +		$dark.fadeIn(phpbb.alertTime); +	} -	if (!dark.is(':visible')) { -		dark.fadeIn(phpbb.alertTime); +	if ($loadingIndicator.is(':visible')) { +		$loadingIndicator.fadeOut(phpbb.alertTime, function() { +			$dark.append($alert); +			$alert.fadeIn(phpbb.alertTime); +		}); +	} else if ($dark.is(':visible')) { +		$dark.append($alert); +		$alert.fadeIn(phpbb.alertTime); +	} else { +		$dark.append($alert); +		$alert.show(); +		$dark.fadeIn(phpbb.alertTime);  	} -	div.bind('click', function(e) { +	$alert.on('click', function(e) {  		e.stopPropagation();  	}); -	dark.one('click', function(e) { -		var fade; - -		div.find('.alert_close').unbind('click'); -		fade = (typeof fadedark !== 'undefined' && !fadedark) ? div : dark; -		fade.fadeOut(phpbb.alertTime, function() { -			div.hide(); -		}); +	$dark.one('click', function(e) { +		phpbb.alert.close($alert, true);  		e.preventDefault();  		e.stopPropagation();  	}); -	$(document).keydown(function(e) { -		if ((e.keyCode === keymap.ENTER || e.keyCode === keymap.ESC) && dark.is(':visible')) { -			dark.trigger('click'); - -			e.preventDefault(); -			e.stopPropagation(); -		} +	$alert.find('.alert_close').one('click', function(e) { +		phpbb.alert.close($alert, true); +		e.preventDefault();  	}); +}; -	div.find('.alert_close').one('click', function(e) { -		dark.trigger('click'); +/** +* Handler for closing an alert box. +* +* @param jQuery $alert			jQuery object. +* @param bool fadedark			Whether to remove dark background. +*/ +phpbb.alert.close = function($alert, fadedark) { +	var $fade = (fadedark) ? $dark : $alert; -		e.preventDefault(); +	$fade.fadeOut(phpbb.alertTime, function() { +		$alert.hide();  	}); -	if (loadingIndicator.is(':visible')) { -		loadingIndicator.fadeOut(phpbb.alertTime, function() { -			dark.append(div); -			div.fadeIn(phpbb.alertTime); -		}); -	} else if (dark.is(':visible')) { -		dark.append(div); -		div.fadeIn(phpbb.alertTime); -	} else { -		dark.append(div); -		div.show(); -		dark.fadeIn(phpbb.alertTime); -	} - -	return div; +	$alert.find('.alert_close').off('click'); +	$(document).off('keydown.phpbb.alert');  };  /** @@ -143,81 +162,36 @@ phpbb.alert = function(title, msg, fadedark) {   * @returns object Returns the div created.   */  phpbb.confirm = function(msg, callback, fadedark) { -	var div = $('#phpbb_confirm'); -	div.find('.alert_text').html(msg); - -	if (!dark.is(':visible')) { -		dark.fadeIn(phpbb.alertTime); -	} - -	div.bind('click', function(e) { -		e.stopPropagation(); -	}); +	var $confirmDiv = $('#phpbb_confirm'); +	$confirmDiv.find('.alert_text').html(msg); +	fadedark = fadedark || true; -	var clickHandler = function(e) { -		var res = this.name === 'confirm'; -		var fade = (typeof fadedark !== 'undefined' && !fadedark && res) ? div : dark; -		fade.fadeOut(phpbb.alertTime, function() { -			div.hide(); -		}); -		div.find('input[type="button"]').unbind('click', clickHandler); -		callback(res); +	$(document).on('keydown.phpbb.alert', function(e) { +		if (e.keyCode === keymap.ENTER || e.keyCode === keymap.ESC) { +			var name = (e.keyCode === keymap.ENTER) ? 'confirm' : 'cancel'; -		if (e) { +			$('input[name="' + name + '"]').trigger('click');  			e.preventDefault();  			e.stopPropagation();  		} -	}; -	div.find('input[type="button"]').one('click', clickHandler); - -	dark.one('click', function(e) { -		div.find('.alert_close').unbind('click'); -		dark.fadeOut(phpbb.alertTime, function() { -			div.hide(); -		}); -		callback(false); - -		e.preventDefault(); -		e.stopPropagation();  	}); -	$(document).bind('keydown', function(e) { -		if (e.keyCode === keymap.ENTER) { -			$('input[name="confirm"]').trigger('click'); -			e.preventDefault(); -			e.stopPropagation(); -		} else if (e.keyCode === keymap.ESC) { -			$('input[name="cancel"]').trigger('click'); -			e.preventDefault(); -			e.stopPropagation(); -		} -	}); +	$confirmDiv.find('input[type="button"]').one('click.phpbb.confirmbox', function(e) { +		var confirmed = this.name === 'confirm'; -	div.find('.alert_close').one('click', function(e) { -		var fade = (typeof fadedark !== 'undefined' && fadedark) ? div : dark; -		fade.fadeOut(phpbb.alertTime, function() { -			div.hide(); -		}); -		callback(false); +		if (confirmed) { +			callback(true); +		} +		$confirmDiv.find('input[type="button"]').off('click.phpbb.confirmbox'); +		phpbb.alert.close($confirmDiv, fadedark || !confirmed);  		e.preventDefault(); +		e.stopPropagation();  	}); -	if (loadingIndicator.is(':visible')) { -		loadingIndicator.fadeOut(phpbb.alertTime, function() { -			dark.append(div); -			div.fadeIn(phpbb.alertTime); -		}); -	} else if (dark.is(':visible')) { -		dark.append(div); -		div.fadeIn(phpbb.alertTime); -	} else { -		dark.append(div); -		div.show(); -		dark.fadeIn(phpbb.alertTime); -	} +	phpbb.alert.open($confirmDiv); -	return div; +	return $confirmDiv;  };  /** @@ -257,12 +231,12 @@ phpbb.parseQuerystring = function(string) {   *     that was returned and (if it is a form) the form action.   */  phpbb.ajaxify = function(options) { -	var elements = $(options.selector), +	var $elements = $(options.selector),  		refresh = options.refresh,  		callback = options.callback,  		overlay = (typeof options.overlay !== 'undefined') ? options.overlay : true, -		isForm = elements.is('form'), -		isText = elements.is('input[type="text"], textarea'), +		isForm = $elements.is('form'), +		isText = $elements.is('input[type="text"], textarea'),  		eventName;  	if (isForm) { @@ -273,7 +247,7 @@ phpbb.ajaxify = function(options) {  		eventName = 'click';  	} -	elements.bind(eventName, function(event) { +	$elements.on(eventName, function(event) {  		var action, method, data, submit, that = this, $this = $(this);  		if ($this.find('input[type="submit"][data-clicked]').attr('data-ajax') === 'false') { @@ -293,11 +267,12 @@ phpbb.ajaxify = function(options) {  				errorText = errorThrown;  			}  			else { -				errorText = dark.attr('data-ajax-error-text-' + textStatus); -				if (typeof errorText !== 'string' || !errorText.length)  -					errorText = dark.attr('data-ajax-error-text'); +				errorText = $dark.attr('data-ajax-error-text-' + textStatus); +				if (typeof errorText !== 'string' || !errorText.length) { +					errorText = $dark.attr('data-ajax-error-text'); +				}  			} -			phpbb.alert(dark.attr('data-ajax-error-title'), errorText); +			phpbb.alert($dark.attr('data-ajax-error-title'), errorText);  		}  		/** @@ -322,7 +297,7 @@ phpbb.ajaxify = function(options) {  				if (typeof res.MESSAGE_TITLE !== 'undefined') {  					alert = phpbb.alert(res.MESSAGE_TITLE, res.MESSAGE_TEXT);  				} else { -					dark.fadeOut(phpbb.alertTime); +					$dark.fadeOut(phpbb.alertTime);  				}  				if (typeof phpbb.ajaxCallbacks[callback] === 'function') { @@ -345,7 +320,7 @@ phpbb.ajaxify = function(options) {  						// Hide the alert even if we refresh the page, in case the user  						// presses the back button. -						dark.fadeOut(phpbb.alertTime, function() { +						$dark.fadeOut(phpbb.alertTime, function() {  							if (typeof alert !== 'undefined') {  								alert.hide();  							} @@ -355,17 +330,19 @@ phpbb.ajaxify = function(options) {  			} else {  				// If confirmation is required, display a dialog to the user.  				phpbb.confirm(res.MESSAGE_BODY, function(del) { -					if (del) { -						phpbb.loadingIndicator(); -						data =  $('<form>' + res.S_HIDDEN_FIELDS + '</form>').serialize(); -						$.ajax({ -							url: res.S_CONFIRM_ACTION, -							type: 'POST', -							data: data + '&confirm=' + res.YES_VALUE + '&' + $('#phpbb_confirm form').serialize(), -							success: returnHandler, -							error: errorHandler -						}); +					if (!del) { +						return;  					} + +					phpbb.loadingIndicator(); +					data =  $('<form>' + res.S_HIDDEN_FIELDS + '</form>').serialize(); +					$.ajax({ +						url: res.S_CONFIRM_ACTION, +						type: 'POST', +						data: data + '&confirm=' + res.YES_VALUE + '&' + $('form', '#phpbb_confirm').serialize(), +						success: returnHandler, +						error: errorHandler +					});  				}, false);  			}  		} @@ -373,7 +350,7 @@ phpbb.ajaxify = function(options) {  		// If the element is a form, POST must be used and some extra data must  		// be taken from the form.  		var runFilter = (typeof options.filter === 'function'); -		var data = {}; +		data = {};  		if (isForm) {  			action = $this.attr('action').replace('&', '&'); @@ -388,7 +365,7 @@ phpbb.ajaxify = function(options) {  				});  			}  		} else if (isText) { -			var name = ($this.attr('data-name') !== undefined) ? $this.attr('data-name') : this['name']; +			var name = $this.attr('data-name') || this.name;  			action = $this.attr('data-url').replace('&', '&');  			data[name] = this.value;  			method = 'POST'; @@ -399,7 +376,8 @@ phpbb.ajaxify = function(options) {  		}  		var sendRequest = function() { -			if (overlay && (typeof $this.attr('data-overlay') === 'undefined' || $this.attr('data-overlay') === 'true')) { +			var dataOverlay = $this.attr('data-overlay'); +			if (overlay && (typeof dataOverlay === 'undefined' || dataOverlay === 'true')) {  				phpbb.loadingIndicator();  			} @@ -411,7 +389,7 @@ phpbb.ajaxify = function(options) {  				error: errorHandler  			});  			request.always(function() { -				loadingIndicator.fadeOut(phpbb.alertTime); +				$loadingIndicator.fadeOut(phpbb.alertTime);  			});  		}; @@ -426,7 +404,7 @@ phpbb.ajaxify = function(options) {  	});  	if (isForm) { -		elements.find('input:submit').click(function () { +		$elements.find('input:submit').click(function () {  			var $this = $(this);  			$this.siblings('[data-clicked]').removeAttr('data-clicked'); @@ -437,7 +415,13 @@ phpbb.ajaxify = function(options) {  	return this;  }; -phpbb.search = {cache: {data: []}, tpl: [], container: []}; +phpbb.search = { +	cache: { +		data: [] +	}, +	tpl: [], +	container: [] +};  /**   * Get cached search data.  @@ -478,7 +462,7 @@ phpbb.search.cache.set = function(id, key, value) {   * @return undefined   */  phpbb.search.cache.setResults = function(id, keyword, value) { -	this.data[id]['results'][keyword] = value; +	this.data[id].results[keyword] = value;  };  /** @@ -495,16 +479,16 @@ phpbb.search.cleanKeyword = function(keyword) {   * Get clean version of search keyword. If textarea supports several keywords   * (one per line), it fetches the current keyword based on the caret position.   * - * @param jQuery el			Search input|textarea. + * @param jQuery $input		Search input|textarea.   * @param string keyword	Input|textarea value.   * @param bool multiline	Whether textarea supports multiple search keywords.   *   * @return string Clean string.   */ -phpbb.search.getKeyword = function(el, keyword, multiline) { +phpbb.search.getKeyword = function($input, keyword, multiline) {  	if (multiline) { -		var line = phpbb.search.getKeywordLine(el); -		keyword = keyword.split("\n").splice(line, 1); +		var line = phpbb.search.getKeywordLine($input); +		keyword = keyword.split('\n').splice(line, 1);  	}  	return phpbb.search.cleanKeyword(keyword);  }; @@ -513,46 +497,48 @@ phpbb.search.getKeyword = function(el, keyword, multiline) {   * Get the textarea line number on which the keyword resides - for textareas   * that support multiple keywords (one per line).    * - * @param jQuery el	Search textarea. + * @param jQuery $textarea	Search textarea.   * @return int   */ -phpbb.search.getKeywordLine = function (el) { -	return el.val().substr(0, el.get(0).selectionStart).split("\n").length - 1; +phpbb.search.getKeywordLine = function ($textarea) { +	var selectionStart = $textarea.get(0).selectionStart; +	return $textarea.val().substr(0, selectionStart).split('\n').length - 1;  };  /**   * Set the value on the input|textarea. If textarea supports multiple   * keywords, only the active keyword is replaced.   * - * @param jQuery el			Search input|textarea. + * @param jQuery $input		Search input|textarea.   * @param string value		Value to set.   * @param bool multiline	Whether textarea supports multiple search keywords.	   *   * @return undefined   */ -phpbb.search.setValue = function(el, value, multiline) { +phpbb.search.setValue = function($input, value, multiline) {  	if (multiline) { -		var line = phpbb.search.getKeywordLine(el), -			lines = el.val().split("\n"); +		var line = phpbb.search.getKeywordLine($input), +			lines = $input.val().split('\n');  		lines[line] = value; -		value = lines.join("\n"); +		value = lines.join('\n');  	} -	el.val(value); +	$input.val(value);  };  /**   * Sets the onclick event to set the value on the input|textarea to the selected search result.    * - * @param jQuery el		Search input|textarea. + * @param jQuery $input		Search input|textarea.   * @param object value		Result object. - * @param object container	jQuery object for the search container. + * @param jQuery $row		Result element. + * @param jQuery $container	jQuery object for the search container.   *   * @return undefined   */ -phpbb.search.setValueOnClick = function(el, value, row, container) { -	row.click(function() { -		phpbb.search.setValue(el, value.result, el.attr('data-multiline')); -		container.hide(); +phpbb.search.setValueOnClick = function($input, value, $row, $container) { +	$row.click(function() { +		phpbb.search.setValue($input, value.result, $input.attr('data-multiline')); +		$container.hide();  	});  }; @@ -569,39 +555,39 @@ phpbb.search.setValueOnClick = function(el, value, row, container) {   * @return bool Returns false.   */  phpbb.search.filter = function(data, event, sendRequest) { -	var el = $(this), -		dataName = (el.attr('data-name') !== undefined) ? el.attr('data-name') : el.attr('name'), -		minLength = parseInt(el.attr('data-min-length')), -		searchID = el.attr('data-results'), -		keyword = phpbb.search.getKeyword(el, data[dataName], el.attr('data-multiline')), +	var $this = $(this), +		dataName = ($this.attr('data-name') !== undefined) ? $this.attr('data-name') : $this.attr('name'), +		minLength = parseInt($this.attr('data-min-length')), +		searchID = $this.attr('data-results'), +		keyword = phpbb.search.getKeyword($this, data[dataName], $this.attr('data-multiline')),  		cache = phpbb.search.cache.get(searchID),  		proceed = true;  	data[dataName] = keyword; -	if (cache['timeout']) { -		clearTimeout(cache['timeout']); +	if (cache.timeout) { +		clearTimeout(cache.timeout);  	}  	var timeout = setTimeout(function() {  		// Check min length and existence of cache.  		if (minLength > keyword.length) {  			proceed = false; -		} else if (cache['last_search']) { +		} else if (cache.lastSearch) {  			// Has the keyword actually changed? -			if (cache['last_search'] === keyword) { +			if (cache.lastSearch === keyword) {  				proceed = false;  			} else {  				// Do we already have results for this? -				if (cache['results'][keyword]) { -					var response = {keyword: keyword, results: cache['results'][keyword]}; -					phpbb.search.handleResponse(response, el, true); +				if (cache.results[keyword]) { +					var response = {keyword: keyword, results: cache.results[keyword]}; +					phpbb.search.handleResponse(response, $this, true);  					proceed = false;  				}  				// If the previous search didn't yield results and the string only had characters added to it,  				// then we won't bother sending a request. -				if (keyword.indexOf(cache['last_search']) === 0 && cache['results'][cache['last_search']].length === 0) { -					phpbb.search.cache.set(searchID, 'last_search', keyword); +				if (keyword.indexOf(cache.lastSearch) === 0 && cache.results[cache.lastSearch].length === 0) { +					phpbb.search.cache.set(searchID, 'lastSearch', keyword);  					phpbb.search.cache.setResults(searchID, keyword, []);  					proceed = false;  				}		 @@ -621,22 +607,22 @@ phpbb.search.filter = function(data, event, sendRequest) {   * Handle search result response.    *   * @param object res		Data received from server. - * @param jQuery el			Search input|textarea. + * @param jQuery $input		Search input|textarea.   * @param bool fromCache	Whether the results are from the cache.   * @param function callback	Optional callback to run when assigning each search result.   *   * @return undefined   */ -phpbb.search.handleResponse = function(res, el, fromCache, callback) { +phpbb.search.handleResponse = function(res, $input, fromCache, callback) {  	if (typeof res !== 'object') {  		return;  	} -	var searchID = el.attr('data-results'), -		container = $(searchID); +	var searchID = $input.attr('data-results'), +		$container = $(searchID); -	if (this.cache.get(searchID)['callback']) { -		callback = this.cache.get(searchID)['callback']; +	if (this.cache.get(searchID).callback) { +		callback = this.cache.get(searchID).callback;  	} else if (typeof callback === 'function') {  		this.cache.set(searchID, 'callback', callback);  	} @@ -645,35 +631,35 @@ phpbb.search.handleResponse = function(res, el, fromCache, callback) {  		this.cache.setResults(searchID, res.keyword, res.results);  	} -	this.cache.set(searchID, 'last_search', res.keyword); -	this.showResults(res.results, el, container, callback); +	this.cache.set(searchID, 'lastSearch', res.keyword); +	this.showResults(res.results, $input, $container, callback);  };  /**   * Show search results.   *   * @param array results		Search results. - * @param jQuery el			Search input|textarea. - * @param jQuery container	Search results container element. + * @param jQuery $input		Search input|textarea. + * @param jQuery $container	Search results container element.   * @param function callback	Optional callback to run when assigning each search result.   *   * @return undefined   */ -phpbb.search.showResults = function(results, el, container, callback) { -	var resultContainer = $('.search-results', container); -	this.clearResults(resultContainer); +phpbb.search.showResults = function(results, $input, $container, callback) { +	var $resultContainer = $('.search-results', $container); +	this.clearResults($resultContainer);  	if (!results.length) { -		container.hide(); +		$container.hide();  		return;  	} -	var searchID = container.attr('id'), +	var searchID = $container.attr('id'),  		tpl,  		row;  	if (!this.tpl[searchID]) { -		tpl = $('.search-result-tpl', container); +		tpl = $('.search-result-tpl', $container);  		this.tpl[searchID] = tpl.clone().removeClass('search-result-tpl');  		tpl.remove();  	} @@ -684,27 +670,27 @@ phpbb.search.showResults = function(results, el, container, callback) {  		row.find('.search-result').html(item.display);  		if (typeof callback === 'function') { -			callback.call(this, el, item, row, container); +			callback.call(this, $input, item, row, $container);  		} -		row.appendTo(resultContainer).show(); +		row.appendTo($resultContainer).show();  	}); -	container.show(); +	$container.show();  };  /**   * Clear search results.   * - * @param jQuery container	Search results container. + * @param jQuery $container	Search results container.   * @return undefined   */ -phpbb.search.clearResults = function(container) { -	container.children(':not(.search-result-tpl)').remove(); +phpbb.search.clearResults = function($container) { +	$container.children(':not(.search-result-tpl)').remove();  }; -$('#phpbb').click(function(e) { -	var target = $(e.target); +$('#phpbb').click(function() { +	var $this = $(this); -	if (!target.is('.live-search') && !target.parents().is('.live-search')) { +	if (!$this.is('.live-search') && !$this.parents().is('.live-search')) {  		$('.live-search').hide();  	}  }); @@ -718,10 +704,7 @@ phpbb.history = {};  * @return bool Returns true if the method is supported.  */  phpbb.history.isSupported = function(fn) { -	if (typeof history === 'undefined' || typeof history[fn] === 'undefined') { -		return false; -	} -	return true; +	return !(typeof history === 'undefined' || typeof history[fn] === 'undefined');  };  /** @@ -783,36 +766,47 @@ phpbb.history.pushUrl = function(url, title, obj) {  * @param	bool	keepSelection		Shall we keep the value selected, or shall the user be forced to repick one.  */  phpbb.timezoneSwitchDate = function(keepSelection) { -	if ($('#timezone_copy').length === 0) { +	var $timezoneCopy = $('#timezone_copy'); +	var $timezone = $('#timezone'); +	var $tzDate = $('#tz_date'); +	var $tzSelectDateSuggest = $('#tz_select_date_suggest'); + +	if ($timezoneCopy.length === 0) {  		// We make a backup of the original dropdown, so we can remove optgroups  		// instead of setting display to none, because IE and chrome will not  		// hide options inside of optgroups and selects via css -		$('#timezone').clone().attr('id', 'timezone_copy').css('display', 'none').attr('name', 'tz_copy').insertAfter('#timezone'); +		$timezone.clone() +			.attr('id', 'timezone_copy') +			.css('display', 'none') +			.attr('name', 'tz_copy') +			.insertAfter('#timezone');  	} else {  		// Copy the content of our backup, so we can remove all unneeded options -		$('#timezone').replaceWith($('#timezone_copy').clone().attr('id', 'timezone').css('display', 'block').attr('name', 'tz')); +		$timezone.html($timezoneCopy.html());  	} -	if ($('#tz_date').val() !== '') { -		$('#timezone > optgroup').remove(":not([label='" + $('#tz_date').val() + "'])"); +	if ($tzDate.val() !== '') { +		$timezone.children('optgroup').remove(':not([label="' + $('#tz_date').val() + '"])');  	} -	if ($('#tz_date').val() === $('#tz_select_date_suggest').attr('data-suggested-tz')) { -		$('#tz_select_date_suggest').css('display', 'none'); +	if ($tzDate.val() === $tzSelectDateSuggest.attr('data-suggested-tz')) { +		$tzSelectDateSuggest.css('display', 'none');  	} else { -		$('#tz_select_date_suggest').css('display', 'inline'); +		$tzSelectDateSuggest.css('display', 'inline');  	} +	 +	var $tzOptions = $timezone.children('optgroup[label="' + $tzDate.val() + '"]').children('option'); -	if ($("#timezone > optgroup[label='" + $('#tz_date').val() + "'] > option").size() === 1) { +	if ($tzOptions.length === 1) {  		// If there is only one timezone for the selected date, we just select that automatically. -		$("#timezone > optgroup[label='" + $('#tz_date').val() + "'] > option:first").prop('selected', true); +		$tzOptions.prop('selected', true);  		keepSelection = true;  	}  	if (typeof keepSelection !== 'undefined' && !keepSelection) { -		var timezoneOptions = $('#timezone > optgroup option'); -		if (timezoneOptions.filter(':selected').length <= 0) { -			timezoneOptions.filter(':first').prop('selected', true); +		var $timezoneOptions = $timezone.find('optgroup option'); +		if ($timezoneOptions.filter(':selected').length <= 0) { +			$timezoneOptions.filter(':first').prop('selected', true);  		}  	}  }; @@ -832,7 +826,6 @@ phpbb.timezoneEnableDateSelection = function() {  phpbb.timezonePreselectSelect = function(forceSelector) {  	// The offset returned here is in minutes and negated. -	// http://www.w3schools.com/jsref/jsref_getTimezoneOffset.asp  	var offset = (new Date()).getTimezoneOffset();  	var sign = '-'; @@ -858,9 +851,11 @@ phpbb.timezonePreselectSelect = function(forceSelector) {  	var prefix = 'GMT' + sign + hours + ':' + minutes;  	var prefixLength = prefix.length; -	var selectorOptions = $('#tz_date > option'); +	var selectorOptions = $('option', '#tz_date');  	var i; +	var $tzSelectDateSuggest = $('#tz_select_date_suggest'); +  	for (i = 0; i < selectorOptions.length; ++i) {  		var option = selectorOptions[i]; @@ -869,16 +864,18 @@ phpbb.timezonePreselectSelect = function(forceSelector) {  				// We do not select the option for the user, but notify him,  				// that we would suggest a different setting.  				phpbb.timezoneSwitchDate(true); -				$('#tz_select_date_suggest').css('display', 'inline'); +				$tzSelectDateSuggest.css('display', 'inline');  			} else {  				option.selected = true;  				phpbb.timezoneSwitchDate(!forceSelector); -				$('#tz_select_date_suggest').css('display', 'none'); +				$tzSelectDateSuggest.css('display', 'none');  			} -			$('#tz_select_date_suggest').attr('title', $('#tz_select_date_suggest').attr('data-l-suggestion').replace("%s", option.innerHTML)); -			$('#tz_select_date_suggest').attr('value', $('#tz_select_date_suggest').attr('data-l-suggestion').replace("%s", option.innerHTML.substring(0, 9))); -			$('#tz_select_date_suggest').attr('data-suggested-tz', option.innerHTML); +			var suggestion = $tzSelectDateSuggest.attr('data-l-suggestion'); + +			$tzSelectDateSuggest.attr('title', suggestion.replace('%s', option.innerHTML)); +			$tzSelectDateSuggest.attr('value', suggestion.replace('%s', option.innerHTML.substring(0, 9))); +			$tzSelectDateSuggest.attr('data-suggested-tz', option.innerHTML);  			// Found the suggestion, there cannot be more, so return from here.  			return; @@ -916,22 +913,22 @@ phpbb.addAjaxCallback('member_search', function(res) {   * current text so that the process can be repeated.   */  phpbb.addAjaxCallback('alt_text', function() { -	var el, +	var $anchor,  		updateAll = $(this).data('update-all'),  		altText;  	if (updateAll !== undefined && updateAll.length) { -		el = $(updateAll); +		$anchor = $(updateAll);  	} else { -		el = $(this); +		$anchor = $(this);  	} -	el.each(function() { -		var el = $(this); -		altText = el.attr('data-alt-text'); -		el.attr('data-alt-text', el.text()); -		el.attr('title', $.trim(altText)); -		el.text(altText); +	$anchor.each(function() { +		var $this = $(this); +		altText = $this.attr('data-alt-text'); +		$this.attr('data-alt-text', $this.text()); +		$this.attr('title', $.trim(altText)); +		$this.text(altText);  	});  }); @@ -945,36 +942,36 @@ phpbb.addAjaxCallback('alt_text', function() {   * and changes the link itself.   */  phpbb.addAjaxCallback('toggle_link', function() { -	var el, +	var $anchor,  		updateAll = $(this).data('update-all') ,  		toggleText,  		toggleUrl,  		toggleClass;  	if (updateAll !== undefined && updateAll.length) { -		el = $(updateAll); +		$anchor = $(updateAll);  	} else { -		el = $(this); +		$anchor = $(this);  	} -	el.each(function() { -		var el = $(this); +	$anchor.each(function() { +		var $this = $(this);  		// Toggle link text -		toggleText = el.attr('data-toggle-text'); -		el.attr('data-toggle-text', el.text()); -		el.attr('title', $.trim(toggleText)); -		el.text(toggleText); +		toggleText = $this.attr('data-toggle-text'); +		$this.attr('data-toggle-text', $this.text()); +		$this.attr('title', $.trim(toggleText)); +		$this.text(toggleText);  		// Toggle link url -		toggleUrl = el.attr('data-toggle-url'); -		el.attr('data-toggle-url', el.attr('href')); -		el.attr('href', toggleUrl); +		toggleUrl = $this.attr('data-toggle-url'); +		$this.attr('data-toggle-url', $this.attr('href')); +		$this.attr('href', toggleUrl);  		// Toggle class of link parent -		toggleClass = el.attr('data-toggle-class'); -		el.attr('data-toggle-class', el.parent().attr('class')); -		el.parent().attr('class', toggleClass); +		toggleClass = $this.attr('data-toggle-class'); +		$this.attr('data-toggle-class', $this.parent().attr('class')); +		$this.parent().attr('class', toggleClass);  	});  }); @@ -984,7 +981,7 @@ phpbb.addAjaxCallback('toggle_link', function() {  * This function automatically resizes textarea elements when user  * types text.  * -* @param {jQuery} items jQuery object(s) to resize +* @param {jQuery} $items jQuery object(s) to resize  * @param {object} options Optional parameter that adjusts default  * 	configuration. See configuration variable  * @@ -1000,25 +997,26 @@ phpbb.addAjaxCallback('toggle_link', function() {  *			this points to DOM object  *			item is a jQuery object, same as this  */ -phpbb.resizeTextArea = function(items, options) { +phpbb.resizeTextArea = function($items, options) {  	// Configuration  	var configuration = {  		minWindowHeight: 500,  		minHeight: 200,  		maxHeight: 500,  		heightDiff: 200, -		resizeCallback: function(item) { }, -		resetCallback: function(item) { } +		resizeCallback: function() {}, +		resetCallback: function() {}  	}; -	if (phpbb.isTouch) return; +	if (phpbb.isTouch) { +		return; +	}  	if (arguments.length > 1) {  		configuration = $.extend(configuration, options);  	} -	function resetAutoResize(item)  -	{ +	function resetAutoResize(item) {  		var $item = $(item);  		if ($item.hasClass('auto-resized')) {  			$(item).css({height: '', resize: ''}).removeClass('auto-resized'); @@ -1026,10 +1024,8 @@ phpbb.resizeTextArea = function(items, options) {  		}  	} -	function autoResize(item)  -	{ -		function setHeight(height) -		{ +	function autoResize(item) { +		function setHeight(height) {  			height += parseInt($item.css('height')) - $item.height();  			$item.css({height: height + 'px', resize: 'none'}).addClass('auto-resized');  			configuration.resizeCallback.call(item, $item); @@ -1042,7 +1038,10 @@ phpbb.resizeTextArea = function(items, options) {  			return;  		} -		var maxHeight = Math.min(Math.max(windowHeight - configuration.heightDiff, configuration.minHeight), configuration.maxHeight), +		var maxHeight = Math.min( +				Math.max(windowHeight - configuration.heightDiff, configuration.minHeight), +				configuration.maxHeight +			),  			$item = $(item),  			height = parseInt($item.height()),  			scrollHeight = (item.scrollHeight) ? item.scrollHeight : 0; @@ -1059,14 +1058,14 @@ phpbb.resizeTextArea = function(items, options) {  		}  	} -	items.bind('focus change keyup', function() { +	$items.on('focus change keyup', function() {  		$(this).each(function() {  			autoResize(this);  		});  	}).change();  	$(window).resize(function() { -		items.each(function() { +		$items.each(function() {  			if ($(this).hasClass('auto-resized')) {  				autoResize(this);  			} @@ -1104,7 +1103,9 @@ phpbb.inBBCodeTag = function(textarea, startTags, endTags) {  			lastStart = Math.max(lastStart, index);  		}  	} -	if (lastStart == -1) return false; +	if (lastStart === -1) { +		return false; +	}  	if (start > 0) {  		for (i = 0; i < endTags.length; i++) { @@ -1114,7 +1115,7 @@ phpbb.inBBCodeTag = function(textarea, startTags, endTags) {  	}  	return (lastEnd < lastStart); -} +};  /** @@ -1158,7 +1159,7 @@ phpbb.applyCodeEditor = function(textarea) {  	function getLastLine(stripCodeStart) {  		var start = textarea.selectionStart,  			value = textarea.value, -			index = value.lastIndexOf("\n", start - 1); +			index = value.lastIndexOf('\n', start - 1);  		value = value.substring(index + 1, start); @@ -1201,28 +1202,27 @@ phpbb.applyCodeEditor = function(textarea) {  		var key = event.keyCode || event.which;  		// intercept tabs -		if (key == keymap.TAB	&& +		if (key === keymap.TAB	&&  			!event.ctrlKey		&&  			!event.shiftKey		&&  			!event.altKey		&&  			!event.metaKey) {  			if (inTag()) { -				appendText("\t"); +				appendText('\t');  				event.preventDefault();  				return;  			}  		}  		// intercept new line characters -		if (key == keymap.ENTER) { +		if (key === keymap.ENTER) {  			if (inTag()) {  				var lastLine = getLastLine(true),  					code = '' + /^\s*/g.exec(lastLine);  				if (code.length > 0) { -					appendText("\n" + code); +					appendText('\n' + code);  					event.preventDefault(); -					return;  				}  			}  		} @@ -1247,43 +1247,41 @@ phpbb.toggleDropdown = function() {  	var $this = $(this),  		options = $this.data('dropdown-options'),  		parent = options.parent, -		visible = parent.hasClass('dropdown-visible'); +		visible = parent.hasClass('dropdown-visible'), +		direction;  	if (!visible) {  		// Hide other dropdown menus  		$(phpbb.dropdownHandles).each(phpbb.toggleDropdown);  		// Figure out direction of dropdown -		var direction = options.direction, -			verticalDirection = options.verticalDirection, +		direction = options.direction; +		var verticalDirection = options.verticalDirection,  			offset = $this.offset(); -		if (direction == 'auto') { +		if (direction === 'auto') {  			if (($(window).width() - $this.outerWidth(true)) / 2 > offset.left) {  				direction = 'right'; -			} -			else { +			} else {  				direction = 'left';  			}  		} -		parent.toggleClass(options.leftClass, direction == 'left').toggleClass(options.rightClass, direction == 'right'); +		parent.toggleClass(options.leftClass, direction === 'left') +			.toggleClass(options.rightClass, direction === 'right'); -		if (verticalDirection == 'auto') { +		if (verticalDirection === 'auto') {  			var height = $(window).height(),  				top = offset.top - $(window).scrollTop(); -			if (top < height * 0.7) { -				verticalDirection = 'down'; -			} -			else { -				verticalDirection = 'up'; -			} +			verticalDirection = (top < height * 0.7) ? 'down' : 'up';  		} -		parent.toggleClass(options.upClass, verticalDirection == 'up').toggleClass(options.downClass, verticalDirection == 'down'); +		parent.toggleClass(options.upClass, verticalDirection === 'up') +			.toggleClass(options.downClass, verticalDirection === 'down');  	}  	options.dropdown.toggle(); -	parent.toggleClass(options.visibleClass, !visible).toggleClass('dropdown-visible', !visible); +	parent.toggleClass(options.visibleClass, !visible) +		.toggleClass('dropdown-visible', !visible);  	// Check dimensions when showing dropdown  	// !visible because variable shows state of dropdown before it was toggled @@ -1304,8 +1302,7 @@ phpbb.toggleDropdown = function() {  			if (offset < 2) {  				$this.css('left', (2 - offset) + 'px'); -			} -			else if ((offset + width + 2) > windowWidth) { +			} else if ((offset + width + 2) > windowWidth) {  				$this.css('margin-left', (windowWidth - offset - width - 2) + 'px');  			} @@ -1315,7 +1312,7 @@ phpbb.toggleDropdown = function() {  		});  		var freeSpace = parent.offset().left - 4; -		if (direction == 'left') { +		if (direction === 'left') {  			options.dropdown.css('margin-left', '-' + freeSpace + 'px');  			// Try to position the notification dropdown correctly in RTL-responsive mode @@ -1342,8 +1339,7 @@ phpbb.toggleDropdown = function() {  			var e = arguments[0];  			e.preventDefault();  			e.stopPropagation(); -		} -		catch (error) { } +		} catch (error) { }  	}  	return false;  }; @@ -1354,7 +1350,7 @@ phpbb.toggleDropdown = function() {  phpbb.toggleSubmenu = function(e) {  	$(this).siblings('.dropdown-submenu').toggle();  	e.preventDefault(); -} +};  /**  * Register dropdown menu @@ -1364,8 +1360,7 @@ phpbb.toggleSubmenu = function(e) {  * @param {jQuery} dropdown Dropdown menu.  * @param {Object} options List of options. Optional.  */ -phpbb.registerDropdown = function(toggle, dropdown, options) -{ +phpbb.registerDropdown = function(toggle, dropdown, options) {  	var ops = {  			parent: toggle.parent(), // Parent item to add classes to  			direction: 'auto', // Direction of dropdown menu. Possible values: auto, left, right @@ -1411,8 +1406,8 @@ phpbb.colorPalette = function(dir, width, height) {  	numberList[3] = 'BF';  	numberList[4] = 'FF'; -	var table_class = (dir == 'h') ? 'horizontal-palette' : 'vertical-palette'; -	html += '<table class="not-responsive colour-palette ' + table_class + '" style="width: auto;">'; +	var tableClass = (dir == 'h') ? 'horizontal-palette' : 'vertical-palette'; +	html += '<table class="not-responsive colour-palette ' + tableClass + '" style="width: auto;">';  	for (r = 0; r < 5; r++) {  		if (dir == 'h') { @@ -1442,7 +1437,7 @@ phpbb.colorPalette = function(dir, width, height) {  	}  	html += '</table>';  	return html; -} +};  /**  * Register a color palette. @@ -1492,12 +1487,14 @@ phpbb.toggleDisplay = function(id, action, type) {  		type = 'block';  	} -	var display = $('#' + id).css('display'); +	var $element = $('#' + id); + +	var display = $element.css('display');  	if (!action) {  		action = (display === '' || display === type) ? -1 : 1;  	} -	$('#' + id).css('display', ((action === 1) ? type : 'none')); -} +	$element.css('display', ((action === 1) ? type : 'none')); +};  /**  * Toggle additional settings based on the selected @@ -1508,9 +1505,9 @@ phpbb.toggleDisplay = function(id, action, type) {  */  phpbb.toggleSelectSettings = function(el) {  	el.children().each(function() { -		var option = $(this), -			setting = $(option.data('toggle-setting')); -		setting.toggle(option.is(':selected')); +		var $this = $(this), +			$setting = $($this.data('toggle-setting')); +		$setting.toggle($this.is(':selected'));  	});  }; @@ -1536,49 +1533,61 @@ phpbb.getFunctionByName = function (functionName) {  * Register page dropdowns.  */  phpbb.registerPageDropdowns = function() { -	$('body').find('.dropdown-container').each(function() { +	var $body = $('body'); + +	$body.find('.dropdown-container').each(function() {  		var $this = $(this), -			trigger = $this.find('.dropdown-trigger:first'), -			contents = $this.find('.dropdown'), +			$trigger = $this.find('.dropdown-trigger:first'), +			$contents = $this.find('.dropdown'),  			options = {  				direction: 'auto',  				verticalDirection: 'auto'  			},  			data; -		if (!trigger.length) { +		if (!$trigger.length) {  			data = $this.attr('data-dropdown-trigger'); -			trigger = data ? $this.children(data) : $this.children('a:first'); +			$trigger = data ? $this.children(data) : $this.children('a:first');  		} -		if (!contents.length) { +		if (!$contents.length) {  			data = $this.attr('data-dropdown-contents'); -			contents = data ? $this.children(data) : $this.children('div:first'); +			$contents = data ? $this.children(data) : $this.children('div:first');  		} -		if (!trigger.length || !contents.length) return; +		if (!$trigger.length || !$contents.length) { +			return; +		} -		if ($this.hasClass('dropdown-up')) options.verticalDirection = 'up'; -		if ($this.hasClass('dropdown-down')) options.verticalDirection = 'down'; -		if ($this.hasClass('dropdown-left')) options.direction = 'left'; -		if ($this.hasClass('dropdown-right')) options.direction = 'right'; +		if ($this.hasClass('dropdown-up')) { +			options.verticalDirection = 'up'; +		} +		if ($this.hasClass('dropdown-down')) { +			options.verticalDirection = 'down'; +		} +		if ($this.hasClass('dropdown-left')) { +			options.direction = 'left'; +		} +		if ($this.hasClass('dropdown-right')) { +			options.direction = 'right'; +		} -		phpbb.registerDropdown(trigger, contents, options); +		phpbb.registerDropdown($trigger, $contents, options);  	});  	// Hide active dropdowns when click event happens outside -	$('body').click(function(e) { -		var parents = $(e.target).parents(); -		if (!parents.is(phpbb.dropdownVisibleContainers)) { +	$body.click(function(e) { +		var $parents = $(e.target).parents(); +		if (!$parents.is(phpbb.dropdownVisibleContainers)) {  			$(phpbb.dropdownHandles).each(phpbb.toggleDropdown);  		}  	}); -} +};  /**  * Apply code editor to all textarea elements with data-bbcode attribute  */ -$(document).ready(function() { +$(function() {  	$('textarea[data-bbcode]').each(function() {  		phpbb.applyCodeEditor(this);  	}); @@ -1595,12 +1604,12 @@ $(document).ready(function() {  	// Hide settings that are not selected via select element.  	$('select[data-togglable-settings]').each(function() { -		var select = $(this); +		var $this = $(this); -		select.change(function() { -			phpbb.toggleSelectSettings(select); +		$this.change(function() { +			phpbb.toggleSelectSettings($this);  		}); -		phpbb.toggleSelectSettings(select); +		phpbb.toggleSelectSettings($this);  	});  }); diff --git a/phpBB/assets/javascript/editor.js b/phpBB/assets/javascript/editor.js index dfc7dab525..5fd4f7eae3 100644 --- a/phpBB/assets/javascript/editor.js +++ b/phpBB/assets/javascript/editor.js @@ -266,10 +266,6 @@ function mozWrap(txtarea, open, close) {  	var selEnd = txtarea.selectionEnd;  	var scrollTop = txtarea.scrollTop; -	if (selEnd === 1 || selEnd === 2) { -		selEnd = selLength; -	} -  	var s1 = (txtarea.value).substring(0,selStart);  	var s2 = (txtarea.value).substring(selStart, selEnd);  	var s3 = (txtarea.value).substring(selEnd, selLength); diff --git a/phpBB/config/parameters.yml b/phpBB/config/parameters.yml index 5bf2c678ee..b076ea3ecb 100644 --- a/phpBB/config/parameters.yml +++ b/phpBB/config/parameters.yml @@ -1,2 +1,3 @@  parameters: +    core.disable_super_globals: true      datetime.class: \phpbb\datetime diff --git a/phpBB/config/services.yml b/phpBB/config/services.yml index a588046245..cca655263f 100644 --- a/phpBB/config/services.yml +++ b/phpBB/config/services.yml @@ -100,6 +100,7 @@ services:              - @controller.provider              - @ext.manager              - @symfony_request +            - @filesystem              - %core.root_path%              - %core.php_ext% @@ -157,21 +158,6 @@ services:          arguments:              - @dbal.conn -    event.subscriber_loader: -        class: phpbb\event\extension_subscriber_loader -        arguments: -            - @dispatcher -            - @event.listener_collection -        calls: -            - [load, []] - -    event.listener_collection: -        class: phpbb\di\service_collection -        arguments: -            - @service_container -        tags: -            - { name: service_collection, tag: event.listener } -      ext.manager:          class: phpbb\extension\manager          arguments: @@ -328,6 +314,9 @@ services:      request:          class: phpbb\request\request +        arguments: +            - null +            - %core.disable_super_globals%      symfony_request:          class: phpbb\symfony_request diff --git a/phpBB/docs/CHANGELOG.html b/phpBB/docs/CHANGELOG.html index d882d2e3f4..7b46129c6c 100644 --- a/phpBB/docs/CHANGELOG.html +++ b/phpBB/docs/CHANGELOG.html @@ -46,6 +46,7 @@  <ol>  	<li><a href="#changelog">Changelog</a>  	<ol style="list-style-type: lower-roman;"> +		<li><a href="#v310RC3">Changes since 3.1.0-RC3</a></li>  		<li><a href="#v310RC2">Changes since 3.1.0-RC2</a></li>  		<li><a href="#v310RC1">Changes since 3.1.0-RC1</a></li>  		<li><a href="#v310b4">Changes since 3.1.0-b4</a></li> @@ -96,7 +97,97 @@  		<div class="content"> -	<a name="v310RC2"></a><h3>1.i. Changes since 3.1.0-RC2</h3> +	<a name="v310RC3"></a><h3>1.i. Changes since 3.1.0-RC3</h3> + +	<h4>Bug</h4> +	<ul> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10472">PHPBB3-10472</a>] - ACP "add multiple smilies" page is unusable on 1024x768 resolution</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11909">PHPBB3-11909</a>] - phpbb/db/migrator::load_migrations is never called</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12258">PHPBB3-12258</a>] - Add attachment: error alert popup on "empty.png" does not show up</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12506">PHPBB3-12506</a>] - Long post titles bump the username down an extra row beneath the edit/quote/delete buttons</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12658">PHPBB3-12658</a>] - Add tests for config:* cli commands</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12661">PHPBB3-12661</a>] - Extensions templates not loaded from "all" by helper/render()</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12734">PHPBB3-12734</a>] - Custom profile manager should not suppress errors when inserting user rows</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12765">PHPBB3-12765</a>] - acp_profile.php should use db/tools</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12852">PHPBB3-12852</a>] - \phpbb\path_helper get_url_parts does not handle get variable with no value</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12856">PHPBB3-12856</a>] - plupload images are not integrated into style-path</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12862">PHPBB3-12862</a>] - Smiley and Whos Onlike pop-up boxes are making styling difficult</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12949">PHPBB3-12949</a>] - Undefined function mime_content_type()</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12966">PHPBB3-12966</a>] - Undefined sorting of posts with same post_time on postgres</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12975">PHPBB3-12975</a>] - Catchable fatal error after update to RC3</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12976">PHPBB3-12976</a>] - Pagination of UCP manage attachments page in prosilver does not support plural forms</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12983">PHPBB3-12983</a>] - UCP preferences, Display posts ordering by: input is not properly validated</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12984">PHPBB3-12984</a>] - Index page: blank line when no forum description shown</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12986">PHPBB3-12986</a>] - Wrong functions call order breaks detection of common words in search</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12990">PHPBB3-12990</a>] - The prefix for the notification's services is harcoded</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12996">PHPBB3-12996</a>] - tests/lock/flock_test.php should use microtime() instead of time()</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12998">PHPBB3-12998</a>] - Undefined  $lang in mcp_warn.php::add_warning()</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13004">PHPBB3-13004</a>] - Topic tools button is displayed even if dropdown is empty</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13008">PHPBB3-13008</a>] - Importing a resource in routing.yml breaks download/file.php and ACP</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13009">PHPBB3-13009</a>] - Cleanup Tweaks CSS, Remove outdated browser support</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13018">PHPBB3-13018</a>] - Key binding on AJAX popups are not unbound upon close/cancel</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13019">PHPBB3-13019</a>] - Don't display "Soft delete reason" dialog when moderator cannot soft-delete</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13022">PHPBB3-13022</a>] - "Return to advanced search" wrong assumption </li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13031">PHPBB3-13031</a>] - Impossible to properly upload image if no proper mimetype guessers enabled</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13035">PHPBB3-13035</a>] - Empty meta tags in header</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13040">PHPBB3-13040</a>] - W3C validator warning in overral_footer.html</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13042">PHPBB3-13042</a>] - Unused var in login_box()</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13044">PHPBB3-13044</a>] - Expires header violates RFC 2616</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13046">PHPBB3-13046</a>] - In download/avatar we don't load the vendors added by the extensions</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13050">PHPBB3-13050</a>] - Allow topic/forum subscription when email and jabber are off</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13051">PHPBB3-13051</a>] - Fix broken viewonline core event</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13052">PHPBB3-13052</a>] - Remove additional parameters from check_form_key()</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13057">PHPBB3-13057</a>] - Fatal error on previous page link after closing a report</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13065">PHPBB3-13065</a>] - Unknown column 'user_pass_convert' in 'field list' [code] - => 1054 </li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13068">PHPBB3-13068</a>] - Language correction in FIELD_IS_CONTACT_EXPLAIN</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13069">PHPBB3-13069</a>] - Timezone selector does not filter locations on change</li> +	</ul> +	<h4>Improvement</h4> +	<ul> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12416">PHPBB3-12416</a>] - WhoIs Pop Up Page Details</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12598">PHPBB3-12598</a>] - Improve action-bar search box styling</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12653">PHPBB3-12653</a>] - Caches the informations about the listeners to be able to not load them everytime</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12900">PHPBB3-12900</a>] - 3.1.0 avatar scaling</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12943">PHPBB3-12943</a>] - Add core.phpbb_generate_debug_output core event</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12961">PHPBB3-12961</a>] - Add link in anti-spam ACP page which links directly to captchas in titania</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12969">PHPBB3-12969</a>] - Add template event around the find username link on composing pm</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12982">PHPBB3-12982</a>] - JS in 3.1 is nasty</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12989">PHPBB3-12989</a>] - Remove unused "created_by.jpg" from prosilver</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12991">PHPBB3-12991</a>] - Have events after/before "add warning" field - user and post</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12994">PHPBB3-12994</a>] - Add core event to viewtopic.php before sending vars to template</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13003">PHPBB3-13003</a>] - Missing language keys in command "extension:show"</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13005">PHPBB3-13005</a>] - Add core event to display_forums() to modify category template data</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13006">PHPBB3-13006</a>] - Add variables to the 'core.modify_quickmod_actions' event</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13010">PHPBB3-13010</a>] - phpbb_get_avatar() incorrectly refers to \phpbb\avatar\driver\driver::clean_row()</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13020">PHPBB3-13020</a>] - Add var to core.viewforum_get_topic_data event to allow modifying forum template data</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13024">PHPBB3-13024</a>] - Template event viewtopic_body_postrow_post_content_footer</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13026">PHPBB3-13026</a>] - Add template vars array to core.viewonline_overwrite_location to allow modifying/adding template vars</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13034">PHPBB3-13034</a>] - Add ability to access extensions outside the phpBB root</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13036">PHPBB3-13036</a>] - Controller helper route method should be able to generate absolute URL's</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13038">PHPBB3-13038</a>] - Link user post tally to their posts</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13047">PHPBB3-13047</a>] - Add $post_list array to core.viewtopic_modify_page_title core event</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13056">PHPBB3-13056</a>] - Move the arguments of the request class to the DI</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13058">PHPBB3-13058</a>] - The "jump to page" input does not have a min attribute.</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13061">PHPBB3-13061</a>] - Use a compiler pass to replace the service event.subscriber_loader</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13062">PHPBB3-13062</a>] - Add viewforum.php core event to allow modifying sql query to select topic ids</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13066">PHPBB3-13066</a>] - Add common search results core event to modify search title</li> +	</ul> +	<h4>New Feature</h4> +	<ul> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12951">PHPBB3-12951</a>] - Add .editorconfig</li> +	</ul> +	<h4>Sub-task</h4> +	<ul> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12928">PHPBB3-12928</a>] - [Event] - core.mcp_reports_gather_query_before</li> +	</ul> +	<h4>Task</h4> +	<ul> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12999">PHPBB3-12999</a>] - Remove @author tag from the doc block</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13032">PHPBB3-13032</a>] - Update Symfony Components to 2.3.19</li> +	</ul> + + +	<a name="v310RC2"></a><h3>1.ii. Changes since 3.1.0-RC2</h3>  	<h4>Bug</h4>  	<ul> @@ -220,7 +311,7 @@  		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12948">PHPBB3-12948</a>] - Remove Travis CI "broken opcache on PHP 5.5.7 and 5.5.8" workaround.</li>  	</ul> -	<a name="v310RC1"></a><h3>1.ii. Changes since 3.1.0-RC1</h3> +	<a name="v310RC1"></a><h3>1.iii. Changes since 3.1.0-RC1</h3>  	<h4>Bug</h4>  	<ul> @@ -291,7 +382,7 @@  		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12829">PHPBB3-12829</a>] - Remove check for pgsql 8.3/8.2</li>  	</ul> -	<a name="v310b4"></a><h3>1.iii. Changes since 3.1.0-b4</h3> +	<a name="v310b4"></a><h3>1.iv. Changes since 3.1.0-b4</h3>  	<h4>Bug</h4>  	<ul> @@ -411,7 +502,7 @@  	</ul> -	<a name="v310b3"></a><h3>1.iv. Changes since 3.1.0-b3</h3> +	<a name="v310b3"></a><h3>1.v. Changes since 3.1.0-b3</h3>  	<h4>Bug</h4>  	<ul> @@ -518,7 +609,7 @@  	</ul> -	<a name="v310b2"></a><h3>1.v. Changes since 3.1.0-b2</h3> +	<a name="v310b2"></a><h3>1.vi. Changes since 3.1.0-b2</h3>  	<h4>Bug</h4>  	<ul> @@ -683,7 +774,7 @@  	</ul> -	<a name="v310b1"></a><h3>1.vi. Changes since 3.1.0-b1</h3> +	<a name="v310b1"></a><h3>1.vii. Changes since 3.1.0-b1</h3>  	<h4>Bug</h4>  	<ul> @@ -751,7 +842,7 @@  		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12302">PHPBB3-12302</a>] - Upgrade composer.phar to 1.0.0-alpha8</li>  	</ul> -	<a name="v310a3"></a><h3>1.vii. Changes since 3.1.0-a3</h3> +	<a name="v310a3"></a><h3>1.viii. Changes since 3.1.0-a3</h3>  	<h4>Bug</h4>  	<ul> @@ -898,7 +989,7 @@  	</ul> -	<a name="v310a2"></a><h3>1.viii. Changes since 3.1.0-a2</h3> +	<a name="v310a2"></a><h3>1.ix. Changes since 3.1.0-a2</h3>  <h4>Bug</h4>  <ul> @@ -1006,7 +1097,7 @@  <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12147">PHPBB3-12147</a>] - Remove Travis CI notification configuration</li>  </ul> -	<a name="v310a1"></a><h3>1.ix. Changes since 3.1.0-a1</h3> +	<a name="v310a1"></a><h3>1.x. Changes since 3.1.0-a1</h3>  <h4>Bug</h4>  <ul> @@ -1082,7 +1173,7 @@  <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11998">PHPBB3-11998</a>] - Add console / command line client environment </li>  </ul> -	<a name="v30x"></a><h3>1.x. Changes since 3.0.x</h3> +	<a name="v30x"></a><h3>1.xi. Changes since 3.0.x</h3>  <h4>Bug</h4>  <ul> @@ -1763,7 +1854,7 @@  <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11913">PHPBB3-11913</a>] - Apply reorganisation of download.phpbb.com to build_announcement.php</li>  </ul> -	<a name="v3011"></a><h3>1.xi. Changes since 3.0.11</h3> +	<a name="v3011"></a><h3>1.xii. Changes since 3.0.11</h3>  <h4>Bug</h4>  <ul> @@ -1918,7 +2009,7 @@  <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11753">PHPBB3-11753</a>] - Upgrade mysql_upgrader.php schema data.</li>  </ul> -	<a name="v3010"></a><h3>1.xii. Changes since 3.0.10</h3> +	<a name="v3010"></a><h3>1.xiii. Changes since 3.0.10</h3>  <h4>Bug</h4>  <ul> @@ -2043,7 +2134,7 @@  <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10909">PHPBB3-10909</a>] - Update Travis Test Configuration: Travis no longer supports PHP 5.3.2</li>  </ul> -	<a name="v309"></a><h3>1.xiii. Changes since 3.0.9</h3> +	<a name="v309"></a><h3>1.xiv. Changes since 3.0.9</h3>  <h4>Bug</h4>  <ul> @@ -2179,7 +2270,7 @@  <li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10480">PHPBB3-10480</a>] - Automate changelog building</li>  </ul> -	<a name="v308"></a><h3>1.xiv. Changes since 3.0.8</h3> +	<a name="v308"></a><h3>1.xv. Changes since 3.0.8</h3>  <h4>        Bug  </h4> @@ -2547,7 +2638,7 @@  </ul> -	<a name="v307-PL1"></a><h3>1.xv. Changes since 3.0.7-PL1</h3> +	<a name="v307-PL1"></a><h3>1.xvi. Changes since 3.0.7-PL1</h3>  <h4>        Security  </h4>  <ul> @@ -3005,13 +3096,13 @@  </ul> -	<a name="v307"></a><h3>1.xvi. Changes since 3.0.7</h3> +	<a name="v307"></a><h3>1.xvii. Changes since 3.0.7</h3>  	<ul>  		<li>[Sec] Do not expose forum content of forums with ACL entries but no actual permission in ATOM Feeds. (Bug #58595)</li>  	</ul> -	<a name="v306"></a><h3>1.xvii. Changes since 3.0.6</h3> +	<a name="v306"></a><h3>1.xviii. Changes since 3.0.6</h3>  	<ul>  		<li>[Fix] Allow ban reason and length to be selected and copied in ACP and subsilver2 MCP. (Bug #51095)</li> @@ -3115,7 +3206,7 @@  	</ul> -	<a name="v305"></a><h3>1.xviii. Changes since 3.0.5</h3> +	<a name="v305"></a><h3>1.xix. Changes since 3.0.5</h3>  	<ul>  		<li>[Fix] Allow whitespaces in avatar gallery names. (Bug #44955)</li> @@ -3337,7 +3428,7 @@  		<li>[Feature] Send anonymous statistical information to phpBB on installation and update (optional).</li>  	</ul> -	<a name="v304"></a><h3>1.xix. Changes since 3.0.4</h3> +	<a name="v304"></a><h3>1.xx. Changes since 3.0.4</h3>  	<ul>  		<li>[Fix] Delete user entry from ban list table upon user deletion (Bug #40015 - Patch by TerraFrost)</li> @@ -3426,7 +3517,7 @@  		<li>[Sec] Only use forum id supplied for posting if global announcement detected. (Reported by nickvergessen)</li>  	</ul> -	<a name="v303"></a><h3>1.xx. Changes since 3.0.3</h3> +	<a name="v303"></a><h3>1.xxi. Changes since 3.0.3</h3>  	<ul>  		<li>[Fix] Allow mixed-case template directories to be inherited (Bug #36725)</li> @@ -3458,7 +3549,7 @@  		<li>[Sec] Ask for forum password if post within passworded forum quoted in private message. (Reported by nickvergessen)</li>  	</ul> -	<a name="v302"></a><h3>1.xxi. Changes since 3.0.2</h3> +	<a name="v302"></a><h3>1.xxii. Changes since 3.0.2</h3>  	<ul>  		<li>[Fix] Correctly set topic starter if first post in topic removed (Bug #30575 - Patch by blueray2048)</li> @@ -3557,7 +3648,7 @@  		<li>[Sec Precaution] Stricter validation of the HTTP_HOST header (Thanks to Techie-Micheal et al for pointing out possible issues in derived code)</li>  	</ul> -	<a name="v301"></a><h3>1.xxii. Changes since 3.0.1</h3> +	<a name="v301"></a><h3>1.xxiii. Changes since 3.0.1</h3>  	<ul>  		<li>[Fix] Ability to set permissions on non-mysql dbms (Bug #24955)</li> @@ -3605,7 +3696,7 @@  		<li>[Sec] Only allow urls gone through redirect() being used within login_box(). (thanks nookieman)</li>  	</ul> -	<a name="v300"></a><h3>1.xxiii. Changes since 3.0.0</h3> +	<a name="v300"></a><h3>1.xxiv. Changes since 3.0.0</h3>  	<ul>  		<li>[Change] Validate birthdays (Bug #15004)</li> @@ -3676,7 +3767,7 @@  		<li>[Fix] Find and display colliding usernames correctly when converting from one database to another (Bug #23925)</li>  	</ul> -	<a name="v30rc8"></a><h3>1.xxiv. Changes since 3.0.RC8</h3> +	<a name="v30rc8"></a><h3>1.xxv. Changes since 3.0.RC8</h3>  	<ul>  		<li>[Fix] Cleaned usernames contain only single spaces, so "a_name" and "a__name" are treated as the same name (Bug #15634)</li> @@ -3685,7 +3776,7 @@  		<li>[Fix] Call garbage_collection() within database updater to correctly close connections (affects Oracle for example)</li>  	</ul> -	<a name="v30rc7"></a><h3>1.xxv. Changes since 3.0.RC7</h3> +	<a name="v30rc7"></a><h3>1.xxvi. Changes since 3.0.RC7</h3>  	<ul>  		<li>[Fix] Fixed MSSQL related bug in the update system</li> @@ -3720,7 +3811,7 @@  		<li>[Fix] No duplication of active topics (Bug #15474)</li>  	</ul> -	<a name="v30rc6"></a><h3>1.xxvi. Changes since 3.0.RC6</h3> +	<a name="v30rc6"></a><h3>1.xxvii. Changes since 3.0.RC6</h3>  	<ul>  		<li>[Fix] Submitting language changes using acp_language (Bug #14736)</li> @@ -3730,7 +3821,7 @@  		<li>[Fix] Able to request new password (Bug #14743)</li>  	</ul> -	<a name="v30rc5"></a><h3>1.xxvii. Changes since 3.0.RC5</h3> +	<a name="v30rc5"></a><h3>1.xxviii. Changes since 3.0.RC5</h3>  	<ul>  		<li>[Feature] Removing constant PHPBB_EMBEDDED in favor of using an exit_handler(); the constant was meant to achive this more or less.</li> @@ -3793,7 +3884,7 @@  		<li>[Sec] New password hashing mechanism for storing passwords (#i42)</li>  	</ul> -	<a name="v30rc4"></a><h3>1.xxviii. Changes since 3.0.RC4</h3> +	<a name="v30rc4"></a><h3>1.xxix. Changes since 3.0.RC4</h3>  	<ul>  		<li>[Fix] MySQL, PostgreSQL and SQLite related database fixes (Bug #13862)</li> @@ -3844,7 +3935,7 @@  		<li>[Fix] odbc_autocommit causing existing result sets to be dropped (Bug #14182)</li>  	</ul> -	<a name="v30rc3"></a><h3>1.xxix. Changes since 3.0.RC3</h3> +	<a name="v30rc3"></a><h3>1.xxx. Changes since 3.0.RC3</h3>  	<ul>  		<li>[Fix] Fixing some subsilver2 and prosilver style issues</li> @@ -3953,7 +4044,7 @@  	</ul> -	<a name="v30rc2"></a><h3>1.xxx. Changes since 3.0.RC2</h3> +	<a name="v30rc2"></a><h3>1.xxxi. Changes since 3.0.RC2</h3>  	<ul>  		<li>[Fix] Re-allow searching within the memberlist</li> @@ -3999,7 +4090,7 @@  	</ul> -	<a name="v30rc1"></a><h3>1.xxxi. Changes since 3.0.RC1</h3> +	<a name="v30rc1"></a><h3>1.xxxii. Changes since 3.0.RC1</h3>  	<ul>  		<li>[Fix] (X)HTML issues within the templates (Bug #11255, #11255)</li> diff --git a/phpBB/download/file.php b/phpBB/download/file.php index db657e95f0..77fb455bc1 100644 --- a/phpBB/download/file.php +++ b/phpBB/download/file.php @@ -83,7 +83,6 @@ if (isset($_GET['avatar']))  	// load extensions  	$phpbb_extension_manager = $phpbb_container->get('ext.manager'); -	$phpbb_subscriber_loader = $phpbb_container->get('event.subscriber_loader');  	// worst-case default  	$browser = strtolower($request->header('User-Agent', 'msie 6.0')); diff --git a/phpBB/feed.php b/phpBB/feed.php index 8971bae768..e0c0b01db6 100644 --- a/phpBB/feed.php +++ b/phpBB/feed.php @@ -164,8 +164,7 @@ if (defined('DEBUG') && request_var('explain', 0) && $auth->acl_get('a_'))  {  	header('Content-type: text/html; charset=UTF-8');  	header('Cache-Control: private, no-cache="set-cookie"'); -	header('Expires: 0'); -	header('Pragma: no-cache'); +	header('Expires: ' . gmdate('D, d M Y H:i:s', time()) . ' GMT');  	$mtime = explode(' ', microtime());  	$totaltime = $mtime[0] + $mtime[1] - $starttime; diff --git a/phpBB/includes/acp/acp_database.php b/phpBB/includes/acp/acp_database.php index 8f9c155ffc..0c52f82459 100644 --- a/phpBB/includes/acp/acp_database.php +++ b/phpBB/includes/acp/acp_database.php @@ -269,7 +269,7 @@ class acp_database  									break;  								} -								header('Pragma: no-cache'); +								header('Cache-Control: private, no-cache');  								header("Content-Type: $mimetype; name=\"$name\"");  								header("Content-disposition: attachment; filename=$name"); @@ -510,7 +510,7 @@ class base_extractor  		if ($download == true)  		{  			$name = $filename . $ext; -			header('Pragma: no-cache'); +			header('Cache-Control: private, no-cache');  			header("Content-Type: $mimetype; name=\"$name\"");  			header("Content-disposition: attachment; filename=$name"); diff --git a/phpBB/includes/acp/acp_icons.php b/phpBB/includes/acp/acp_icons.php index 028025b547..9265415dd1 100644 --- a/phpBB/includes/acp/acp_icons.php +++ b/phpBB/includes/acp/acp_icons.php @@ -737,7 +737,7 @@ class acp_icons  				{  					garbage_collection(); -					header('Pragma: public'); +					header('Cache-Control: public');  					// Send out the Headers  					header('Content-Type: text/x-delimtext; name="' . $mode . '.pak"'); diff --git a/phpBB/includes/compatibility_globals.php b/phpBB/includes/compatibility_globals.php index 2a60f7fb8e..54c9287c96 100644 --- a/phpBB/includes/compatibility_globals.php +++ b/phpBB/includes/compatibility_globals.php @@ -43,6 +43,5 @@ $phpbb_path_helper = $phpbb_container->get('path_helper');  // load extensions  $phpbb_extension_manager = $phpbb_container->get('ext.manager'); -$phpbb_subscriber_loader = $phpbb_container->get('event.subscriber_loader');  $template = $phpbb_container->get('template'); diff --git a/phpBB/includes/constants.php b/phpBB/includes/constants.php index 0eac2e9417..b72e4ab6d4 100644 --- a/phpBB/includes/constants.php +++ b/phpBB/includes/constants.php @@ -28,7 +28,7 @@ if (!defined('IN_PHPBB'))  */  // phpBB Version -define('PHPBB_VERSION', '3.1.0-RC4-dev'); +define('PHPBB_VERSION', '3.1.0-RC5-dev');  // QA-related  // define('PHPBB_QA', 1); diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index df613682a7..cf4e64451f 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -1989,6 +1989,9 @@ function tracking_unserialize($string, $max_depth = 3)  * @param mixed $params String or array of additional url parameters  * @param bool $is_amp Is url using & (true) or & (false)  * @param string $session_id Possibility to use a custom session id instead of the global one +* @param bool $is_route Is url generated by a route. +* +* @return string The corrected url.  *  * Examples:  * <code> @@ -1999,7 +2002,7 @@ function tracking_unserialize($string, $max_depth = 3)  * </code>  *  */ -function append_sid($url, $params = false, $is_amp = true, $session_id = false) +function append_sid($url, $params = false, $is_amp = true, $session_id = false, $is_route = false)  {  	global $_SID, $_EXTRA_URL, $phpbb_hook, $phpbb_path_helper;  	global $phpbb_dispatcher; @@ -2011,7 +2014,7 @@ function append_sid($url, $params = false, $is_amp = true, $session_id = false)  	}  	// Update the root path with the correct relative web path -	if ($phpbb_path_helper instanceof \phpbb\path_helper) +	if (!$is_route && $phpbb_path_helper instanceof \phpbb\path_helper)  	{  		$url = $phpbb_path_helper->update_web_root_path($url);  	} @@ -2037,9 +2040,10 @@ function append_sid($url, $params = false, $is_amp = true, $session_id = false)  	*											the global one (false)  	* @var	bool|string	append_sid_overwrite	Overwrite function (string  	*											URL) or not (false) +	* @var	bool	is_route					Is url generated by a route.  	* @since 3.1.0-a1  	*/ -	$vars = array('url', 'params', 'is_amp', 'session_id', 'append_sid_overwrite'); +	$vars = array('url', 'params', 'is_amp', 'session_id', 'append_sid_overwrite', 'is_route');  	extract($phpbb_dispatcher->trigger_event('core.append_sid', compact($vars)));  	if ($append_sid_overwrite) @@ -2576,15 +2580,17 @@ function add_form_key($form_name)  }  /** -* Check the form key. Required for all altering actions not secured by confirm_box -* @param string  $form_name The name of the form; has to match the name used in add_form_key, otherwise no restrictions apply -* @param int $timespan The maximum acceptable age for a submitted form in seconds. Defaults to the config setting. -* @param string $return_page The address for the return link -* @param bool $trigger If true, the function will triger an error when encountering an invalid form -*/ -function check_form_key($form_name, $timespan = false, $return_page = '', $trigger = false) + * Check the form key. Required for all altering actions not secured by confirm_box + * + * @param	string	$form_name	The name of the form; has to match the name used + *								in add_form_key, otherwise no restrictions apply + * @param	int		$timespan	The maximum acceptable age for a submitted form + *								in seconds. Defaults to the config setting. + * @return	bool	True, if the form key was valid, false otherwise + */ +function check_form_key($form_name, $timespan = false)  { -	global $config, $user; +	global $config, $request, $user;  	if ($timespan === false)  	{ @@ -2592,10 +2598,10 @@ function check_form_key($form_name, $timespan = false, $return_page = '', $trigg  		$timespan = ($config['form_token_lifetime'] == -1) ? -1 : max(30, $config['form_token_lifetime']);  	} -	if (isset($_POST['creation_time']) && isset($_POST['form_token'])) +	if ($request->is_set_post('creation_time') && $request->is_set_post('form_token'))  	{ -		$creation_time	= abs(request_var('creation_time', 0)); -		$token = request_var('form_token', ''); +		$creation_time	= abs($request->variable('creation_time', 0)); +		$token = $request->variable('form_token', '');  		$diff = time() - $creation_time; @@ -2612,11 +2618,6 @@ function check_form_key($form_name, $timespan = false, $return_page = '', $trigg  		}  	} -	if ($trigger) -	{ -		trigger_error($user->lang['FORM_INVALID'] . $return_page); -	} -  	return false;  } @@ -2832,8 +2833,6 @@ function login_box($redirect = '', $l_explain = '', $l_success = '', $admin = fa  		if ($result['status'] == LOGIN_SUCCESS)  		{  			$redirect = request_var('redirect', "{$phpbb_root_path}index.$phpEx"); -			$message = ($l_success) ? $l_success : $user->lang['LOGIN_REDIRECT']; -			$l_redirect = ($admin) ? $user->lang['PROCEED_TO_ACP'] : (($redirect === "{$phpbb_root_path}index.$phpEx" || $redirect === "index.$phpEx") ? $user->lang['RETURN_INDEX'] : $user->lang['RETURN_PAGE']);  			// append/replace SID (may change during the session for AOL users)  			$redirect = reapply_sid($redirect); @@ -3318,6 +3317,11 @@ function get_preg_expression($mode)  		case 'table_prefix':  			return '#^[a-zA-Z][a-zA-Z0-9_]*$#';  		break; + +		// Matches the predecing dot +		case 'path_remove_dot_trailing_slash': +			return '#^(?:(\.)?)+(?:(.+)?)+(?:([\\/\\\])$)#'; +		break;  	}  	return ''; @@ -5063,8 +5067,7 @@ function page_header($page_title = '', $display_online_list = false, $item_id =  		// application/xhtml+xml not used because of IE  		'Content-type' => 'text/html; charset=UTF-8',  		'Cache-Control' => 'private, no-cache="set-cookie"', -		'Expires' => '0', -		'Pragma' => 'no-cache', +		'Expires' => gmdate('D, d M Y H:i:s', time()) . ' GMT',  	);  	if (!empty($user->data['is_bot']))  	{ diff --git a/phpBB/includes/functions_acp.php b/phpBB/includes/functions_acp.php index d9dc11239c..e30c6da505 100644 --- a/phpBB/includes/functions_acp.php +++ b/phpBB/includes/functions_acp.php @@ -112,8 +112,7 @@ function adm_page_header($page_title)  		// application/xhtml+xml not used because of IE  		'Content-type' => 'text/html; charset=UTF-8',  		'Cache-Control' => 'private, no-cache="set-cookie"', -		'Expires' => '0', -		'Pragma' => 'no-cache', +		'Expires' => gmdate('D, d M Y H:i:s', time()) . ' GMT',  	);  	/** diff --git a/phpBB/includes/functions_compress.php b/phpBB/includes/functions_compress.php index 6ed69d6928..a7ee29dd91 100644 --- a/phpBB/includes/functions_compress.php +++ b/phpBB/includes/functions_compress.php @@ -509,7 +509,7 @@ class compress_zip extends compress  		$mimetype = 'application/zip'; -		header('Pragma: no-cache'); +		header('Cache-Control: private, no-cache');  		header("Content-Type: $mimetype; name=\"$download_name.zip\"");  		header("Content-disposition: attachment; filename=$download_name.zip"); @@ -757,7 +757,7 @@ class compress_tar extends compress  			break;  		} -		header('Pragma: no-cache'); +		header('Cache-Control: private, no-cache');  		header("Content-Type: $mimetype; name=\"$download_name$this->type\"");  		header("Content-disposition: attachment; filename=$download_name$this->type"); diff --git a/phpBB/includes/functions_display.php b/phpBB/includes/functions_display.php index 78137d075b..85d9496061 100644 --- a/phpBB/includes/functions_display.php +++ b/phpBB/includes/functions_display.php @@ -379,10 +379,10 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod  	$last_catless = true;  	foreach ($forum_rows as $row)  	{ -		// Empty category +		// Category  		if ($row['parent_id'] == $root_data['forum_id'] && $row['forum_type'] == FORUM_CAT)  		{ -			$template->assign_block_vars('forumrow', array( +			$cat_row = array(  				'S_IS_CAT'				=> true,  				'FORUM_ID'				=> $row['forum_id'],  				'FORUM_NAME'			=> $row['forum_name'], @@ -391,9 +391,33 @@ function display_forums($root_data = '', $display_moderators = true, $return_mod  				'FORUM_FOLDER_IMG_SRC'	=> '',  				'FORUM_IMAGE'			=> ($row['forum_image']) ? '<img src="' . $phpbb_root_path . $row['forum_image'] . '" alt="' . $user->lang['FORUM_CAT'] . '" />' : '',  				'FORUM_IMAGE_SRC'		=> ($row['forum_image']) ? $phpbb_root_path . $row['forum_image'] : '', -				'U_VIEWFORUM'			=> append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $row['forum_id'])) +				'U_VIEWFORUM'			=> append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $row['forum_id']),  			); +			/** +			* Modify the template data block of the 'category' +			* +			* This event is triggered once per 'category' +			* +			* @event core.display_forums_modify_category_template_vars +			* @var	array	cat_row			Template data of the 'category' +			* @var	bool	catless			The flag indicating whether the 'category' has a parent category +			* @var	bool	last_catless	The flag indicating whether the last forum had a parent category +			* @var	array	root_data		Array with the root forum data +			* @var	array	row				The data of the 'category' +			* @since 3.1.0-RC4 +			*/ +			$vars = array( +				'cat_row', +				'catless', +				'last_catless', +				'root_data', +				'row', +			); +			extract($phpbb_dispatcher->trigger_event('core.display_forums_modify_category_template_vars', compact($vars))); + +			$template->assign_block_vars('forumrow', $cat_row); +  			continue;  		} diff --git a/phpBB/includes/functions_download.php b/phpBB/includes/functions_download.php index 4ff3994f4c..704939b176 100644 --- a/phpBB/includes/functions_download.php +++ b/phpBB/includes/functions_download.php @@ -45,7 +45,7 @@ function send_avatar_to_browser($file, $browser)  	if ((@file_exists($file_path) && @is_readable($file_path)) && !headers_sent())  	{ -		header('Pragma: public'); +		header('Cache-Control: public');  		$image_data = @getimagesize($file_path);  		header('Content-Type: ' . image_type_to_mime_type($image_data[2])); @@ -56,17 +56,17 @@ function send_avatar_to_browser($file, $browser)  			if (strpos(strtolower($browser), 'msie 6.0') !== false)  			{ -				header('Expires: -1'); +				header('Expires: ' . gmdate('D, d M Y H:i:s', time()) . ' GMT');  			}  			else  			{ -				header('Expires: ' . gmdate('D, d M Y H:i:s \G\M\T', time() + 31536000)); +				header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 31536000) . ' GMT');  			}  		}  		else  		{  			header('Content-Disposition: inline; ' . header_filename($file)); -			header('Expires: ' . gmdate('D, d M Y H:i:s \G\M\T', time() + 31536000)); +			header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 31536000) . ' GMT');  		}  		$size = @filesize($file_path); @@ -175,7 +175,7 @@ function send_file_to_browser($attachment, $upload_dir, $category)  	}  	// Now the tricky part... let's dance -	header('Pragma: public'); +	header('Cache-Control: public');  	// Send out the Headers. Do not set Content-Disposition to inline please, it is a security measure for users using the Internet Explorer.  	header('Content-Type: ' . $attachment['mimetype']); @@ -197,7 +197,7 @@ function send_file_to_browser($attachment, $upload_dir, $category)  			header('Content-Disposition: attachment; ' . header_filename(htmlspecialchars_decode($attachment['real_filename'])));  			if (empty($user->browser) || (strpos(strtolower($user->browser), 'msie 6.0') !== false))  			{ -				header('expires: -1'); +				header('Expires: ' . gmdate('D, d M Y H:i:s', time()) . ' GMT');  			}  		}  		else @@ -420,8 +420,8 @@ function set_modified_headers($stamp, $browser)  		{  			send_status_line(304, 'Not Modified');  			// seems that we need those too ... browsers -			header('Pragma: public'); -			header('Expires: ' . gmdate('D, d M Y H:i:s \G\M\T', time() + 31536000)); +			header('Cache-Control: public'); +			header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 31536000) . ' GMT');  			return true;  		}  		else diff --git a/phpBB/includes/functions_posting.php b/phpBB/includes/functions_posting.php index 768011fa5b..1fdc7ee9ea 100644 --- a/phpBB/includes/functions_posting.php +++ b/phpBB/includes/functions_posting.php @@ -2538,7 +2538,7 @@ function phpbb_upload_popup($forum_style = 0)  /**  * Do the various checks required for removing posts as well as removing it  */ -function phpbb_handle_post_delete($forum_id, $topic_id, $post_id, &$post_data, $is_soft = false, $soft_delete_reason = '') +function phpbb_handle_post_delete($forum_id, $topic_id, $post_id, &$post_data, $is_soft = false, $delete_reason = '')  {  	global $user, $auth, $config, $request;  	global $phpbb_root_path, $phpEx; @@ -2571,19 +2571,19 @@ function phpbb_handle_post_delete($forum_id, $topic_id, $post_id, &$post_data, $  				'post_postcount'		=> $post_data['post_postcount'],  			); -			$next_post_id = delete_post($forum_id, $topic_id, $post_id, $data, $is_soft, $soft_delete_reason); +			$next_post_id = delete_post($forum_id, $topic_id, $post_id, $data, $is_soft, $delete_reason);  			$post_username = ($post_data['poster_id'] == ANONYMOUS && !empty($post_data['post_username'])) ? $post_data['post_username'] : $post_data['username'];  			if ($next_post_id === false)  			{ -				add_log('mod', $forum_id, $topic_id, (($is_soft) ? 'LOG_SOFTDELETE_TOPIC' : 'LOG_DELETE_TOPIC'), $post_data['topic_title'], $post_username, $soft_delete_reason); +				add_log('mod', $forum_id, $topic_id, (($is_soft) ? 'LOG_SOFTDELETE_TOPIC' : 'LOG_DELETE_TOPIC'), $post_data['topic_title'], $post_username, $delete_reason);  				$meta_info = append_sid("{$phpbb_root_path}viewforum.$phpEx", "f=$forum_id");  				$message = $user->lang['POST_DELETED'];  			}  			else  			{ -				add_log('mod', $forum_id, $topic_id, (($is_soft) ? 'LOG_SOFTDELETE_POST' : 'LOG_DELETE_POST'), $post_data['post_subject'], $post_username, $soft_delete_reason); +				add_log('mod', $forum_id, $topic_id, (($is_soft) ? 'LOG_SOFTDELETE_POST' : 'LOG_DELETE_POST'), $post_data['post_subject'], $post_username, $delete_reason);  				$meta_info = append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f=$forum_id&t=$topic_id&p=$next_post_id") . "#p$next_post_id";  				$message = $user->lang['POST_DELETED']; diff --git a/phpBB/includes/functions_privmsgs.php b/phpBB/includes/functions_privmsgs.php index 29cea477e4..ad142b1cca 100644 --- a/phpBB/includes/functions_privmsgs.php +++ b/phpBB/includes/functions_privmsgs.php @@ -1573,7 +1573,7 @@ function get_folder_status($folder_id, $folder)  		'cur'			=> $folder['num_messages'],  		'remaining'		=> ($user->data['message_limit']) ? $user->data['message_limit'] - $folder['num_messages'] : 0,  		'max'			=> $user->data['message_limit'], -		'percent'		=> ($user->data['message_limit']) ? (($user->data['message_limit'] > 0) ? round(($folder['num_messages'] / $user->data['message_limit']) * 100) : 100) : 0, +		'percent'		=> ($user->data['message_limit']) ? (($user->data['message_limit'] > 0) ? floor(($folder['num_messages'] / $user->data['message_limit']) * 100) : 100) : 0,  	);  	$return['message']	= $user->lang('FOLDER_STATUS_MSG', $user->lang('MESSAGES_COUNT', (int) $return['max']), $return['cur'], $return['percent']); diff --git a/phpBB/includes/functions_user.php b/phpBB/includes/functions_user.php index 38ae34c66c..e4479f07b0 100644 --- a/phpBB/includes/functions_user.php +++ b/phpBB/includes/functions_user.php @@ -363,12 +363,16 @@ function user_add($user_row, $cp_data = false)  }  /** -* Remove User -* @param $mode Either 'retain' or 'remove' -*/ + * Remove User + * + * @param string	$mode		Either 'retain' or 'remove' + * @param mixed		$user_ids	Either an array of integers or an integer + * @param bool		$retain_username + * @return bool + */  function user_delete($mode, $user_ids, $retain_username = true)  { -	global $cache, $config, $db, $user, $auth, $phpbb_dispatcher; +	global $cache, $config, $db, $user, $phpbb_dispatcher;  	global $phpbb_root_path, $phpEx;  	$db->sql_transaction('begin'); @@ -555,11 +559,6 @@ function user_delete($mode, $user_ids, $retain_username = true)  			WHERE ' . $db->sql_in_set('poster_id', $user_ids);  		$db->sql_query($sql); -		$sql = 'UPDATE ' . POSTS_TABLE . ' -			SET post_edit_user = ' . ANONYMOUS . ' -			WHERE ' . $db->sql_in_set('post_edit_user', $user_ids); -		$db->sql_query($sql); -  		$sql = 'UPDATE ' . USERS_TABLE . '  			SET user_posts = user_posts + ' . $added_guest_posts . '  			WHERE user_id = ' . ANONYMOUS; @@ -589,6 +588,30 @@ function user_delete($mode, $user_ids, $retain_username = true)  	$cache->destroy('sql', MODERATOR_CACHE_TABLE); +	// Change user_id to anonymous for posts edited by this user +	$sql = 'UPDATE ' . POSTS_TABLE . ' +		SET post_edit_user = ' . ANONYMOUS . ' +		WHERE ' . $db->sql_in_set('post_edit_user', $user_ids); +	$db->sql_query($sql); + +	// Change user_id to anonymous for pms edited by this user +	$sql = 'UPDATE ' . PRIVMSGS_TABLE . ' +		SET message_edit_user = ' . ANONYMOUS . ' +		WHERE ' . $db->sql_in_set('message_edit_user', $user_ids); +	$db->sql_query($sql); + +	// Change user_id to anonymous for posts deleted by this user +	$sql = 'UPDATE ' . POSTS_TABLE . ' +		SET post_delete_user = ' . ANONYMOUS . ' +		WHERE ' . $db->sql_in_set('post_delete_user', $user_ids); +	$db->sql_query($sql); + +	// Change user_id to anonymous for topics deleted by this user +	$sql = 'UPDATE ' . TOPICS_TABLE . ' +		SET topic_delete_user = ' . ANONYMOUS . ' +		WHERE ' . $db->sql_in_set('topic_delete_user', $user_ids); +	$db->sql_query($sql); +  	// Delete user log entries about this user  	$sql = 'DELETE FROM ' . LOG_TABLE . '  		WHERE ' . $db->sql_in_set('reportee_id', $user_ids); diff --git a/phpBB/includes/mcp/mcp_main.php b/phpBB/includes/mcp/mcp_main.php index f03bc034e4..74bf687fc8 100644 --- a/phpBB/includes/mcp/mcp_main.php +++ b/phpBB/includes/mcp/mcp_main.php @@ -161,9 +161,13 @@ class mcp_main  				* This event allows you to handle custom quickmod options  				*  				* @event core.modify_quickmod_actions +				* @var	string	action		Topic quick moderation action name +				* @var	bool	quickmod	Flag indicating whether MCP is in quick moderation mode  				* @since 3.1.0-a4 +				* @change 3.1.0-RC4 Added variables: action, quickmod  				*/ -				$phpbb_dispatcher->dispatch('core.modify_quickmod_actions'); +				$vars = array('action', 'quickmod'); +				extract($phpbb_dispatcher->trigger_event('core.modify_quickmod_actions', compact($vars)));  			break;  		} diff --git a/phpBB/includes/mcp/mcp_reports.php b/phpBB/includes/mcp/mcp_reports.php index 247b9d1651..804d48ea97 100644 --- a/phpBB/includes/mcp/mcp_reports.php +++ b/phpBB/includes/mcp/mcp_reports.php @@ -36,7 +36,7 @@ class mcp_reports  	function main($id, $mode)  	{  		global $auth, $db, $user, $template, $cache; -		global $config, $phpbb_root_path, $phpEx, $action, $phpbb_container; +		global $config, $phpbb_root_path, $phpEx, $action, $phpbb_container, $phpbb_dispatcher;  		include_once($phpbb_root_path . 'includes/functions_posting.' . $phpEx); diff --git a/phpBB/includes/ucp/ucp_attachments.php b/phpBB/includes/ucp/ucp_attachments.php index aab45339c5..42724209aa 100644 --- a/phpBB/includes/ucp/ucp_attachments.php +++ b/phpBB/includes/ucp/ucp_attachments.php @@ -182,6 +182,7 @@ class ucp_attachments  		$template->assign_vars(array(  			'TOTAL_ATTACHMENTS'		=> $num_attachments, +			'NUM_ATTACHMENTS'		=> $user->lang('NUM_ATTACHMENTS', $num_attachments),  			'L_TITLE'				=> $user->lang['UCP_ATTACHMENTS'], diff --git a/phpBB/includes/ucp/ucp_pm_options.php b/phpBB/includes/ucp/ucp_pm_options.php index 353bfdc7ec..d1fc9d2c62 100644 --- a/phpBB/includes/ucp/ucp_pm_options.php +++ b/phpBB/includes/ucp/ucp_pm_options.php @@ -32,7 +32,11 @@ function message_options($id, $mode, $global_privmsgs_rules, $global_rule_condit  	// Change "full folder" setting - what to do if folder is full  	if (isset($_POST['fullfolder']))  	{ -		check_form_key('ucp_pm_options', $config['form_token_lifetime'], $redirect_url); +		if (!check_form_key('ucp_pm_options')) +		{ +			trigger_error('FORM_INVALID'); +		} +  		$full_action = request_var('full_action', 0);  		$set_folder_id = 0; diff --git a/phpBB/includes/ucp/ucp_pm_viewfolder.php b/phpBB/includes/ucp/ucp_pm_viewfolder.php index 72921270f4..19acd9ecb9 100644 --- a/phpBB/includes/ucp/ucp_pm_viewfolder.php +++ b/phpBB/includes/ucp/ucp_pm_viewfolder.php @@ -383,7 +383,7 @@ function view_folder($id, $mode, $folder_id, $folder)  				break;  			} -			header('Pragma: no-cache'); +			header('Cache-Control: private, no-cache');  			header("Content-Type: $mimetype; name=\"data.$filetype\"");  			header("Content-disposition: attachment; filename=data.$filetype");  			echo $string; diff --git a/phpBB/install/convertors/convert_phpbb20.php b/phpBB/install/convertors/convert_phpbb20.php index de0cccd234..4ec408a670 100644 --- a/phpBB/install/convertors/convert_phpbb20.php +++ b/phpBB/install/convertors/convert_phpbb20.php @@ -38,7 +38,7 @@ $dbms = $phpbb_config_php_file->convert_30_dbms_to_31($dbms);  $convertor_data = array(  	'forum_name'	=> 'phpBB 2.0.x',  	'version'		=> '1.0.3', -	'phpbb_version'	=> '3.1.0-RC3', +	'phpbb_version'	=> '3.1.0-RC4',  	'author'		=> '<a href="https://www.phpbb.com/">phpBB Limited</a>',  	'dbms'			=> $dbms,  	'dbhost'		=> $dbhost, @@ -896,8 +896,7 @@ if (!$get_info)  				array('user_regdate',			'users.user_regdate',				''),  				array('username',				'users.username',					'phpbb_set_default_encoding'), // recode to utf8 with default lang  				array('username_clean',			'users.username',					array('function1' => 'phpbb_set_default_encoding', 'function2' => 'utf8_clean_string')), -				array('user_password',			'users.user_password',				'phpbb_hash'), -				array('user_pass_convert',		1,									''), +				array('user_password',			'users.user_password',				'phpbb_convert_password_hash'),  				array('user_posts',				'users.user_posts',					'intval'),  				array('user_email',				'users.user_email',					'strtolower'),  				array('user_email_hash',		'users.user_email',					'gen_email_hash'), diff --git a/phpBB/install/convertors/functions_phpbb20.php b/phpBB/install/convertors/functions_phpbb20.php index 01447a6232..817c007274 100644 --- a/phpBB/install/convertors/functions_phpbb20.php +++ b/phpBB/install/convertors/functions_phpbb20.php @@ -1969,3 +1969,13 @@ function phpbb_add_notification_options($user_notify_pm)  	$sql = $db->sql_multi_insert(USER_NOTIFICATIONS_TABLE, $rows);  } + +function phpbb_convert_password_hash($hash) +{ +	global $phpbb_container; + +	$manager = $phpbb_container->get('passwords.manager'); +	$hash = $manager->hash($hash, '$H$'); + +	return '$CP$' . $hash; +} diff --git a/phpBB/install/database_update.php b/phpBB/install/database_update.php index 6a91033dbb..8016ff349b 100644 --- a/phpBB/install/database_update.php +++ b/phpBB/install/database_update.php @@ -177,11 +177,13 @@ $migrator = $phpbb_container->get('migrator');  $migrator->create_migrations_table();  $phpbb_extension_manager = $phpbb_container->get('ext.manager'); -$finder = $phpbb_extension_manager->get_finder(); -$migrations = $finder +$migrations = $phpbb_extension_manager +	->get_finder()  	->core_path('phpbb/db/migration/data/') +	->extension_directory('/migrations')  	->get_classes(); +  $migrator->set_migrations($migrations);  // What is a safe limit of execution time? Half the max execution time should be safe. diff --git a/phpBB/install/index.php b/phpBB/install/index.php index 2e497da3db..5c16421499 100644 --- a/phpBB/install/index.php +++ b/phpBB/install/index.php @@ -445,8 +445,7 @@ class module  		header('Content-type: text/html; charset=UTF-8');  		header('Cache-Control: private, no-cache="set-cookie"'); -		header('Expires: 0'); -		header('Pragma: no-cache'); +		header('Expires: ' . gmdate('D, d M Y H:i:s', time()) . ' GMT');  		return;  	} diff --git a/phpBB/install/schemas/schema_data.sql b/phpBB/install/schemas/schema_data.sql index 90b1ac8f92..baabe90f2a 100644 --- a/phpBB/install/schemas/schema_data.sql +++ b/phpBB/install/schemas/schema_data.sql @@ -273,7 +273,7 @@ INSERT INTO phpbb_config (config_name, config_value) VALUES ('tpl_allow_php', '0  INSERT INTO phpbb_config (config_name, config_value) VALUES ('upload_icons_path', 'images/upload_icons');  INSERT INTO phpbb_config (config_name, config_value) VALUES ('upload_path', 'files');  INSERT INTO phpbb_config (config_name, config_value) VALUES ('use_system_cron', '0'); -INSERT INTO phpbb_config (config_name, config_value) VALUES ('version', '3.1.0-RC4-dev'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('version', '3.1.0-RC5-dev');  INSERT INTO phpbb_config (config_name, config_value) VALUES ('warnings_expire_days', '90');  INSERT INTO phpbb_config (config_name, config_value) VALUES ('warnings_gc', '14400'); diff --git a/phpBB/language/en/acp/board.php b/phpBB/language/en/acp/board.php index d451bdd515..24cfe4556b 100644 --- a/phpBB/language/en/acp/board.php +++ b/phpBB/language/en/acp/board.php @@ -298,6 +298,7 @@ $lang = array_merge($lang, array(  // Visual Confirmation Settings  $lang = array_merge($lang, array(  	'ACP_VC_SETTINGS_EXPLAIN'				=> 'Here you can select and configure plugins, which are designed to block automated form submissions by spambots. These plugins typically work by challenging the user with a <em>CAPTCHA</em>, a test which is designed to be difficult for computers to solve.', +	'ACP_VC_EXT_GET_MORE'					=> 'For additional (and possibly better) anti-spam plugins, visit the <a href="https://www.phpbb.com/go/anti-spam-ext"><strong>phpBB.com Extensions Database</strong></a>. For more information on preventing spam on your board, visit the <a href="https://www.phpbb.com/go/anti-spam"><strong>phpBB.com Knowledge Base</strong></a>.',  	'AVAILABLE_CAPTCHAS'					=> 'Available plugins',  	'CAPTCHA_UNAVAILABLE'					=> 'The plugin cannot be selected as its requirements are not met.',  	'CAPTCHA_GD'							=> 'GD image', diff --git a/phpBB/language/en/acp/profile.php b/phpBB/language/en/acp/profile.php index 6cb4a20eb0..5972f8a18e 100644 --- a/phpBB/language/en/acp/profile.php +++ b/phpBB/language/en/acp/profile.php @@ -99,7 +99,7 @@ $lang = array_merge($lang, array(  	'FIELD_IDENT_EXPLAIN'		=> 'The field identification is a name to identify the profile field within the database and the templates.',  	'FIELD_INT'					=> 'Numbers',  	'FIELD_IS_CONTACT'			=> 'Display field as a contact field', -	'FIELD_IS_CONTACT_EXPLAIN'	=> 'Contact fields are displayed with in the contact section of the user profile and are displayed differently in the mini profile next to posts and private messages.', +	'FIELD_IS_CONTACT_EXPLAIN'	=> 'Contact fields are displayed within the contact section of the user profile and are displayed differently in the mini profile next to posts and private messages.',  	'FIELD_LENGTH'				=> 'Length of input box',  	'FIELD_NOT_FOUND'			=> 'Profile field not found.',  	'FIELD_STRING'				=> 'Single text field', diff --git a/phpBB/language/en/common.php b/phpBB/language/en/common.php index c27086fd38..83e1f4eaa1 100644 --- a/phpBB/language/en/common.php +++ b/phpBB/language/en/common.php @@ -518,6 +518,10 @@ $lang = array_merge($lang, array(  	'NO_USER_SPECIFIED'			=> 'No username was specified.',  	// Nullar/Singular/Plural language entry. The key numbers define the number range in which a certain grammatical expression is valid. +	'NUM_ATTACHMENTS'		=> array( +		1	=> '%d attachment', +		2	=> '%d attachments', +	),  	'NUM_POSTS_IN_QUEUE'		=> array(  		0			=> 'No posts in queue',		// 0  		1			=> '1 post in queue',		// 1 diff --git a/phpBB/language/en/posting.php b/phpBB/language/en/posting.php index 2cd6ec59cc..924395ed44 100644 --- a/phpBB/language/en/posting.php +++ b/phpBB/language/en/posting.php @@ -93,7 +93,7 @@ $lang = array_merge($lang, array(  	'DELETE_POST_PERMANENTLY'	=> 'Permanently delete this post so it can not be recovered',  	'DELETE_POSTS_CONFIRM'		=> 'Are you sure you want to delete these posts?',  	'DELETE_POSTS_PERMANENTLY_CONFIRM'	=> 'Are you sure you want to <strong>permanently</strong> delete these posts?', -	'DELETE_REASON'				=> 'Soft delete reason', +	'DELETE_REASON'				=> 'Reason for deletion',  	'DELETE_REASON_EXPLAIN'		=> 'The specified reason for deletion will be visible to moderators.',  	'DELETE_POST_WARN'			=> 'Delete this post',  	'DELETE_TOPIC_CONFIRM'		=> 'Are you sure you want to delete this topic?', diff --git a/phpBB/language/en/search.php b/phpBB/language/en/search.php index 7d5b400f82..ec5dd99eb8 100644 --- a/phpBB/language/en/search.php +++ b/phpBB/language/en/search.php @@ -86,7 +86,7 @@ $lang = array_merge($lang, array(  	'RESULT_DAYS'			=> 'Limit results to previous',  	'RESULT_SORT'			=> 'Sort results by',  	'RETURN_FIRST'			=> 'Return first', -	'RETURN_TO_SEARCH_ADV'	=> 'Return to advanced search', +	'GO_TO_SEARCH_ADV'	=> 'Go to advanced search',  	'SEARCHED_FOR'				=> 'Search term used',  	'SEARCHED_TOPIC'			=> 'Searched topic', diff --git a/phpBB/phpbb/auth/provider/oauth/oauth.php b/phpBB/phpbb/auth/provider/oauth/oauth.php index 902c6ae84c..c0ce3f1fba 100644 --- a/phpBB/phpbb/auth/provider/oauth/oauth.php +++ b/phpBB/phpbb/auth/provider/oauth/oauth.php @@ -105,7 +105,7 @@ class oauth extends \phpbb\auth\provider\base  	protected $phpbb_root_path;  	/** -	* PHP extenstion +	* PHP file extension  	*  	* @var string  	*/ diff --git a/phpBB/phpbb/console/command/db/migrate.php b/phpBB/phpbb/console/command/db/migrate.php index c3caae5f70..86545c237d 100644 --- a/phpBB/phpbb/console/command/db/migrate.php +++ b/phpBB/phpbb/console/command/db/migrate.php @@ -119,6 +119,7 @@ class migrate extends \phpbb\console\command\command  			->core_path('phpbb/db/migration/data/')  			->extension_directory('/migrations')  			->get_classes(); +  		$this->migrator->set_migrations($migrations);  	} diff --git a/phpBB/phpbb/controller/helper.php b/phpBB/phpbb/controller/helper.php index dd89d0504a..fc19b855c0 100644 --- a/phpBB/phpbb/controller/helper.php +++ b/phpBB/phpbb/controller/helper.php @@ -15,6 +15,7 @@ namespace phpbb\controller;  use Symfony\Component\HttpFoundation\Response;  use Symfony\Component\Routing\Generator\UrlGenerator; +use Symfony\Component\Routing\Generator\UrlGeneratorInterface;  use Symfony\Component\Routing\RequestContext;  /** @@ -44,6 +45,11 @@ class helper  	protected $symfony_request;  	/** +	* @var \phpbb\filesystem The filesystem object +	*/ +	protected $filesystem; + +	/**  	* phpBB root path  	* @var string  	*/ @@ -64,15 +70,17 @@ class helper  	* @param \phpbb\controller\provider $provider Path provider  	* @param \phpbb\extension\manager $manager Extension manager object  	* @param \phpbb\symfony_request $symfony_request Symfony Request object +	* @param \phpbb\filesystem $filesystem The filesystem object  	* @param string $phpbb_root_path phpBB root path  	* @param string $php_ext PHP file extension  	*/ -	public function __construct(\phpbb\template\template $template, \phpbb\user $user, \phpbb\config\config $config, \phpbb\controller\provider $provider, \phpbb\extension\manager $manager, \phpbb\symfony_request $symfony_request, $phpbb_root_path, $php_ext) +	public function __construct(\phpbb\template\template $template, \phpbb\user $user, \phpbb\config\config $config, \phpbb\controller\provider $provider, \phpbb\extension\manager $manager, \phpbb\symfony_request $symfony_request, \phpbb\filesystem $filesystem, $phpbb_root_path, $php_ext)  	{  		$this->template = $template;  		$this->user = $user;  		$this->config = $config;  		$this->symfony_request = $symfony_request; +		$this->filesystem = $filesystem;  		$this->phpbb_root_path = $phpbb_root_path;  		$this->php_ext = $php_ext;  		$provider->find_routing_files($manager->get_finder()); @@ -108,10 +116,11 @@ class helper  	* @param string	$route		Name of the route to travel  	* @param array	$params		String or array of additional url parameters  	* @param bool	$is_amp		Is url using & (true) or & (false) -	* @param string|bool	$session_id	Possibility to use a custom session id instead of the global one +	* @param string|bool		$session_id	Possibility to use a custom session id instead of the global one +	* @param bool|string		$reference_type The type of reference to be generated (one of the constants)  	* @return string The URL already passed through append_sid()  	*/ -	public function route($route, array $params = array(), $is_amp = true, $session_id = false) +	public function route($route, array $params = array(), $is_amp = true, $session_id = false, $reference_type = UrlGeneratorInterface::ABSOLUTE_PATH)  	{  		$anchor = '';  		if (isset($params['#'])) @@ -119,27 +128,46 @@ class helper  			$anchor = '#' . $params['#'];  			unset($params['#']);  		} -		$url_generator = new UrlGenerator($this->route_collection, new RequestContext()); -		$route_url = $url_generator->generate($route, $params); -		if (strpos($route_url, '/') === 0) +		$context = new RequestContext(); +		$context->fromRequest($this->symfony_request); + +		$script_name = $this->symfony_request->getScriptName(); +		$page_name = substr($script_name, -1, 1) == '/' ? '' : utf8_basename($script_name); + +		$base_url = $context->getBaseUrl(); + +		// If enable_mod_rewrite is false we need to replace the current front-end by app.php, otherwise we need to remove it. +		$base_url = str_replace('/' . $page_name, empty($this->config['enable_mod_rewrite']) ? '/app.' . $this->php_ext : '', $base_url); + +		// We need to update the base url to move to the directory of the app.php file +		if (empty($this->config['enable_mod_rewrite'])) +		{ +			$base_url = str_replace('/app.' . $this->php_ext, '/' . $this->phpbb_root_path . 'app.' . $this->php_ext, $base_url); +		} +		else  		{ -			$route_url = substr($route_url, 1); +			$base_url .= preg_replace(get_preg_expression('path_remove_dot_trailing_slash'), '$2', $this->phpbb_root_path);  		} +		$base_url = $this->filesystem->clean_path($base_url); + +		$context->setBaseUrl($base_url); + +		$url_generator = new UrlGenerator($this->route_collection, $context); +		$route_url = $url_generator->generate($route, $params, $reference_type); +  		if ($is_amp)  		{  			$route_url = str_replace(array('&', '&'), array('&', '&'), $route_url);  		} -		// If enable_mod_rewrite is false, we need to include app.php -		$route_prefix = $this->phpbb_root_path; -		if (empty($this->config['enable_mod_rewrite'])) +		if ($reference_type === UrlGeneratorInterface::RELATIVE_PATH && empty($this->config['enable_mod_rewrite']))  		{ -			$route_prefix .= 'app.' . $this->php_ext . '/'; +			$route_url = 'app.' . $this->php_ext . '/' . $route_url;  		} -		return append_sid($route_prefix . $route_url . $anchor, false, $is_amp, $session_id); +		return append_sid($route_url . $anchor, false, $is_amp, $session_id, true);  	}  	/** diff --git a/phpBB/phpbb/db/migration/data/v310/rc4.php b/phpBB/phpbb/db/migration/data/v310/rc4.php new file mode 100644 index 0000000000..47de8291c1 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v310/rc4.php @@ -0,0 +1,32 @@ +<?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\v310; + +class rc4 extends \phpbb\db\migration\migration +{ +	static public function depends_on() +	{ +		return array( +			'\phpbb\db\migration\data\v310\rc3', +			'\phpbb\db\migration\data\v310\notifications_use_full_name', +		); +	} + +	public function update_data() +	{ +		return array( +			array('config.update', array('version', '3.1.0-RC4')), +		); +	} +} diff --git a/phpBB/phpbb/di/container_builder.php b/phpBB/phpbb/di/container_builder.php index 553b723cc8..638c13e86d 100644 --- a/phpBB/phpbb/di/container_builder.php +++ b/phpBB/phpbb/di/container_builder.php @@ -15,6 +15,7 @@ namespace phpbb\di;  use Symfony\Component\DependencyInjection\ContainerBuilder;  use Symfony\Component\DependencyInjection\Dumper\PhpDumper; +use Symfony\Component\HttpKernel\DependencyInjection\RegisterListenersPass;  class container_builder  { @@ -160,11 +161,13 @@ class container_builder  			if ($this->use_custom_pass)  			{ +				// Symfony Kernel Listeners  				$this->container->addCompilerPass(new \phpbb\di\pass\collection_pass()); +				$this->container->addCompilerPass(new RegisterListenersPass('dispatcher', 'event.listener_listener', 'event.listener'));  				if ($this->use_kernel_pass)  				{ -					$this->container->addCompilerPass(new \phpbb\di\pass\kernel_pass()); +					$this->container->addCompilerPass(new RegisterListenersPass('dispatcher'));  				}  			} diff --git a/phpBB/phpbb/event/extension_subscriber_loader.php b/phpBB/phpbb/event/extension_subscriber_loader.php deleted file mode 100644 index fc01961e9f..0000000000 --- a/phpBB/phpbb/event/extension_subscriber_loader.php +++ /dev/null @@ -1,39 +0,0 @@ -<?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\event; - -use Symfony\Component\EventDispatcher\EventDispatcherInterface; - -class extension_subscriber_loader -{ -	private $dispatcher; -	private $listener_collection; - -	public function __construct(EventDispatcherInterface $dispatcher, \phpbb\di\service_collection $listener_collection) -	{ -		$this->dispatcher = $dispatcher; -		$this->listener_collection = $listener_collection; -	} - -	public function load() -	{ -		if (!empty($this->listener_collection)) -		{ -			foreach ($this->listener_collection as $listener) -			{ -				$this->dispatcher->addSubscriber($listener); -			} -		} -	} -} diff --git a/phpBB/phpbb/extension/base.php b/phpBB/phpbb/extension/base.php index 288fb7d19c..5bb530bad4 100644 --- a/phpBB/phpbb/extension/base.php +++ b/phpBB/phpbb/extension/base.php @@ -35,6 +35,9 @@ class base implements \phpbb\extension\extension_interface  	/** @var string */  	protected $extension_path; +	/** @var string[] */ +	private $migrations = false; +  	/**  	* Constructor  	* @@ -122,17 +125,16 @@ class base implements \phpbb\extension\extension_interface  	*/  	protected function get_migration_file_list()  	{ -		static $migrations = false; - -		if ($migrations !== false) +		if ($this->migrations !== false)  		{ -			return $migrations; +			return $this->migrations;  		}  		// Only have the finder search in this extension path directory  		$migrations = $this->extension_finder  			->extension_directory('/migrations')  			->find_from_extension($this->extension_name, $this->extension_path); +  		$migrations = $this->extension_finder->get_classes_from_files($migrations);  		return $migrations; diff --git a/phpBB/phpbb/profilefields/manager.php b/phpBB/phpbb/profilefields/manager.php index 98802d2209..4ad3214ae4 100644 --- a/phpBB/phpbb/profilefields/manager.php +++ b/phpBB/phpbb/profilefields/manager.php @@ -245,12 +245,8 @@ class manager  			$cp_data = $this->build_insert_sql_array($cp_data);  			$cp_data['user_id'] = (int) $user_id; -			$this->db->sql_return_on_error(true); -  			$sql = 'INSERT INTO ' . $this->fields_data_table . ' ' . $this->db->sql_build_array('INSERT', $cp_data);  			$this->db->sql_query($sql); - -			$this->db->sql_return_on_error(false);  		}  	} @@ -328,7 +324,7 @@ class manager  		* Event to modify profile fields data retrieved from the database  		*  		* @event core.grab_profile_fields_data -		* @var	array	user_ids		Single user id or an array of ids  +		* @var	array	user_ids		Single user id or an array of ids  		* @var	array	field_data		Array with profile fields data  		* @since 3.1.0-b3  		*/ @@ -377,7 +373,7 @@ class manager  		* Event to modify data of the generated profile fields, before the template assignment loop  		*  		* @event core.generate_profile_fields_template_data_before -		* @var	array	profile_row		Array with users profile field data  +		* @var	array	profile_row		Array with users profile field data  		* @var	array	tpl_fields		Array with template data fields  		* @var	bool	use_contact_fields	Should we display contact fields as such?  		* @since 3.1.0-b3 @@ -445,7 +441,7 @@ class manager  		* Event to modify template data of the generated profile fields  		*  		* @event core.generate_profile_fields_template_data -		* @var	array	profile_row		Array with users profile field data  +		* @var	array	profile_row		Array with users profile field data  		* @var	array	tpl_fields		Array with template data fields  		* @var	bool	use_contact_fields	Should we display contact fields as such?  		* @since 3.1.0-b3 diff --git a/phpBB/phpbb/session.php b/phpBB/phpbb/session.php index 7d564742af..da8b848fa5 100644 --- a/phpBB/phpbb/session.php +++ b/phpBB/phpbb/session.php @@ -446,7 +446,8 @@ class session  						{  							$sql_ary = array('session_time' => $this->time_now); -							if ($this->update_session_page) +							// Do not update the session page for ajax requests, so the view online still works as intended +							if ($this->update_session_page && !$request->is_ajax())  							{  								$sql_ary['session_page'] = substr($this->page['page'], 0, 199);  								$sql_ary['session_forum_id'] = $this->page['forum']; diff --git a/phpBB/phpbb/template/base.php b/phpBB/phpbb/template/base.php index ab0e1f281d..9a40702ba8 100644 --- a/phpBB/phpbb/template/base.php +++ b/phpBB/phpbb/template/base.php @@ -142,11 +142,11 @@ abstract class base implements template  	{  		global $phpbb_hook; -		if (!empty($phpbb_hook) && $phpbb_hook->call_hook(array(__CLASS__, $method), $handle, $this)) +		if (!empty($phpbb_hook) && $phpbb_hook->call_hook(array('template', $method), $handle, $this))  		{ -			if ($phpbb_hook->hook_return(array(__CLASS__, $method))) +			if ($phpbb_hook->hook_return(array('template', $method)))  			{ -				$result = $phpbb_hook->hook_return_result(array(__CLASS__, $method)); +				$result = $phpbb_hook->hook_return_result(array('template', $method));  				return array($result);  			}  		} diff --git a/phpBB/posting.php b/phpBB/posting.php index 4c3d012ca5..18572a3a6c 100644 --- a/phpBB/posting.php +++ b/phpBB/posting.php @@ -436,9 +436,8 @@ if ($mode == 'delete' || $mode == 'soft_delete')  		trigger_error('NO_POST');  	} -	$allow_reason = $auth->acl_get('m_softdelete', $forum_id) || ($auth->acl_gets('m_delete', 'f_delete', $forum_id) && $auth->acl_gets('m_softdelete', 'f_softdelete', $forum_id)); -	$soft_delete_reason = ($mode == 'soft_delete' && $allow_reason) ? $request->variable('delete_reason', '', true) : ''; -	phpbb_handle_post_delete($forum_id, $topic_id, $post_id, $post_data, ($mode == 'soft_delete'), $soft_delete_reason); +	$delete_reason = $request->variable('delete_reason', '', true); +	phpbb_handle_post_delete($forum_id, $topic_id, $post_id, $post_data, ($mode == 'soft_delete'), $delete_reason);  	return;  } @@ -1258,9 +1257,8 @@ if ($submit || $preview || $refresh)  			// Handle delete mode...  			if ($request->is_set_post('delete') || $request->is_set_post('delete_permanent'))  			{ -				$allow_reason = $auth->acl_get('m_softdelete', $forum_id) || ($auth->acl_gets('m_delete', 'f_delete', $forum_id) && $auth->acl_gets('m_softdelete', 'f_softdelete', $forum_id)); -				$soft_delete_reason = (!$request->is_set_post('delete_permanent') && $allow_reason) ? $request->variable('delete_reason', '', true) : ''; -				phpbb_handle_post_delete($forum_id, $topic_id, $post_id, $post_data, !$request->is_set_post('delete_permanent'), $soft_delete_reason); +				$delete_reason = $request->variable('delete_reason', '', true); +				phpbb_handle_post_delete($forum_id, $topic_id, $post_id, $post_data, !$request->is_set_post('delete_permanent'), $delete_reason);  				return;  			} diff --git a/phpBB/search.php b/phpBB/search.php index 67f6f4dbb5..93f12f4310 100644 --- a/phpBB/search.php +++ b/phpBB/search.php @@ -1149,6 +1149,20 @@ if ($keywords || $author || $author_id || $search_id || $submit)  	}  	unset($rowset); +	/** +	* Modify the title and/or load data for the search results page +	* +	* @event core.search_results_modify_search_title +	* @var	int		author_id		ID of the author to search by +	* @var	string	l_search_title	The title of the search page +	* @var	string	search_id		Predefined search type name +	* @var	string	show_results	Search results output mode - topics or posts +	* @var	int		start			The starting id of the results +	* @since 3.1.0-RC4 +	*/ +	$vars = array('author_id', 'l_search_title', 'search_id', 'show_results', 'start'); +	extract($phpbb_dispatcher->trigger_event('core.search_results_modify_search_title', compact($vars))); +  	page_header(($l_search_title) ? $l_search_title : $user->lang['SEARCH']);  	$template->set_filenames(array( diff --git a/phpBB/styles/prosilver/style.cfg b/phpBB/styles/prosilver/style.cfg index aea59021d6..1c4315f937 100644 --- a/phpBB/styles/prosilver/style.cfg +++ b/phpBB/styles/prosilver/style.cfg @@ -21,8 +21,8 @@  # General Information about this style  name = prosilver  copyright = © phpBB Limited, 2007 -style_version = 3.1.0-RC3 -phpbb_version = 3.1.0-RC3 +style_version = 3.1.0-RC4 +phpbb_version = 3.1.0-RC4  # Defining a different template bitfield  # template_bitfield = lNg= diff --git a/phpBB/styles/prosilver/template/ajax.js b/phpBB/styles/prosilver/template/ajax.js index 63efe5f8ae..168efff4b4 100644 --- a/phpBB/styles/prosilver/template/ajax.js +++ b/phpBB/styles/prosilver/template/ajax.js @@ -1,6 +1,8 @@ +/* global phpbb */ +  (function($) {  // Avoid conflicts with other libraries -"use strict"; +'use strict';  // This callback will mark all forum icons read  phpbb.addAjaxCallback('mark_forums_read', function(res) { @@ -40,10 +42,10 @@ phpbb.addAjaxCallback('mark_forums_read', function(res) {  /**   * This callback will mark all topic icons read  * -* @param update_topic_links bool Wether "Mark topics read" links should be +* @param update_topic_links bool Whether "Mark topics read" links should be  *     updated. Defaults to true.  */ -phpbb.addAjaxCallback('mark_topics_read', function(res, update_topic_links) { +phpbb.addAjaxCallback('mark_topics_read', function(res, updateTopicLinks) {  	var readTitle = res.NO_UNREAD_POSTS;  	var unreadTitle = res.UNREAD_POSTS;  	var iconsArray = { @@ -53,12 +55,12 @@ phpbb.addAjaxCallback('mark_topics_read', function(res, update_topic_links) {  		'topic_unread': 'topic_read'  	};  	var iconsState = ['', '_hot', '_hot_mine', '_locked', '_locked_mine', '_mine']; -	var unreadClassSelectors = ''; +	var unreadClassSelectors;  	var classMap = {};  	var classNames = []; -	if (typeof update_topic_links === 'undefined') { -		update_topic_links = true; +	if (typeof updateTopicLinks === 'undefined') { +		updateTopicLinks = true;  	}  	$.each(iconsArray, function(unreadClass, readClass) { @@ -88,7 +90,7 @@ phpbb.addAjaxCallback('mark_topics_read', function(res, update_topic_links) {  	$('a').has('span.icon_topic_newest').remove();  	// Update mark topics read links -	if (update_topic_links) { +	if (updateTopicLinks) {  		$('[data-ajax="mark_topics_read"]').attr('href', res.U_MARK_TOPICS);  	} @@ -114,22 +116,22 @@ phpbb.addAjaxCallback('notification.mark_read', function(res) {  /**   * Mark notification popup rows as read.   * - * @param {jQuery} el jQuery object(s) to mark read. + * @param {jQuery} $popup jQuery object(s) to mark read.   * @param {int} unreadCount The new unread notifications count.   */ -phpbb.markNotifications = function(el, unreadCount) { +phpbb.markNotifications = function($popup, unreadCount) {  	// Remove the unread status. -	el.removeClass('bg2'); -	el.find('a.mark_read').remove(); +	$popup.removeClass('bg2'); +	$popup.find('a.mark_read').remove();  	// Update the notification link to the real URL. -	el.each(function() { +	$popup.each(function() {  		var link = $(this).find('a');  		link.attr('href', link.attr('data-real-url'));  	});  	// Update the unread count. -	$('#notification_list_button strong').html(unreadCount); +	$('strong', '#notification_list_button').html(unreadCount);  	// Remove the Mark all read link if there are no unread notifications.  	if (!unreadCount) {  		$('#mark_all_notifications').remove(); @@ -143,12 +145,12 @@ phpbb.markNotifications = function(el, unreadCount) {  // This callback finds the post from the delete link, and removes it.  phpbb.addAjaxCallback('post_delete', function() { -	var el = $(this), +	var $this = $(this),  		postId; -	if (el.attr('data-refresh') === undefined) { -		postId = el[0].href.split('&p=')[1]; -		var post = el.parents('#p' + postId).css('pointer-events', 'none'); +	if ($this.attr('data-refresh') === undefined) { +		postId = $this[0].href.split('&p=')[1]; +		var post = $this.parents('#p' + postId).css('pointer-events', 'none');  		if (post.hasClass('bg1') || post.hasClass('bg2')) {  			var posts1 = post.nextAll('.bg1');  			post.nextAll('.bg2').removeClass('bg2').addClass('bg1'); @@ -167,8 +169,7 @@ phpbb.addAjaxCallback('post_visibility', function(res) {  		$(this).remove();  	}); -	if (res.visible) -	{ +	if (res.visible) {  		// Remove the "Deleted by" message from the post on restoring.  		remove.parents('.post').find('.post_deleted_msg').css('pointer-events', 'none').fadeOut(function() {  			$(this).remove(); @@ -199,18 +200,18 @@ phpbb.addAjaxCallback('vote_poll', function(res) {  	if (typeof res.success !== 'undefined') {  		var poll = $('.topic_poll');  		var panel = poll.find('.panel'); -		var results_visible = poll.find('dl:first-child .resultbar').is(':visible'); -		var most_votes = 0; +		var resultsVisible = poll.find('dl:first-child .resultbar').is(':visible'); +		var mostVotes = 0;  		// Set min-height to prevent the page from jumping when the content changes -		var update_panel_height = function (height) { +		var updatePanelHeight = function (height) {  			var height = (typeof height === 'undefined') ? panel.find('.inner').outerHeight() : height;  			panel.css('min-height', height);  		}; -		update_panel_height(); +		updatePanelHeight();  		// Remove the View results link -		if (!results_visible) { +		if (!resultsVisible) {  			poll.find('.poll_view_results').hide(500);  		} @@ -226,8 +227,8 @@ phpbb.addAjaxCallback('vote_poll', function(res) {  		// Get the votes count of the highest poll option  		poll.find('[data-poll-option-id]').each(function() {  			var option = $(this); -			var option_id = option.attr('data-poll-option-id'); -			most_votes = (res.vote_counts[option_id] >= most_votes) ? res.vote_counts[option_id] : most_votes; +			var optionId = option.attr('data-poll-option-id'); +			mostVotes = (res.vote_counts[optionId] >= mostVotes) ? res.vote_counts[optionId] : mostVotes;  		});  		// Update the total votes count @@ -235,28 +236,30 @@ phpbb.addAjaxCallback('vote_poll', function(res) {  		// Update each option  		poll.find('[data-poll-option-id]').each(function() { -			var option = $(this); -			var option_id = option.attr('data-poll-option-id'); -			var voted = (typeof res.user_votes[option_id] !== 'undefined') ? true : false; -			var most_voted = (res.vote_counts[option_id] == most_votes) ? true : false; -			var percent = (!res.total_votes) ? 0 : Math.round((res.vote_counts[option_id] / res.total_votes) * 100); -			var percent_rel = (most_votes == 0) ? 0 : Math.round((res.vote_counts[option_id] / most_votes) * 100); +			var $this = $(this); +			var optionId = $this.attr('data-poll-option-id'); +			var voted = (typeof res.user_votes[optionId] !== 'undefined'); +			var mostVoted = (res.vote_counts[optionId] === mostVotes); +			var percent = (!res.total_votes) ? 0 : Math.round((res.vote_counts[optionId] / res.total_votes) * 100); +			var percentRel = (mostVotes === 0) ? 0 : Math.round((res.vote_counts[optionId] / mostVotes) * 100); -			option.toggleClass('voted', voted); -			option.toggleClass('most-votes', most_voted); +			$this.toggleClass('voted', voted); +			$this.toggleClass('most-votes', mostVoted);  			// Update the bars -			var bar = option.find('.resultbar div'); -			var bar_time_lapse = (res.can_vote) ? 500 : 1500; -			var new_bar_class = (percent == 100) ? 'pollbar5' : 'pollbar' + (Math.floor(percent / 20) + 1); +			var bar = $this.find('.resultbar div'); +			var barTimeLapse = (res.can_vote) ? 500 : 1500; +			var newBarClass = (percent === 100) ? 'pollbar5' : 'pollbar' + (Math.floor(percent / 20) + 1);  			setTimeout(function () { -				bar.animate({width: percent_rel + '%'}, 500).removeClass('pollbar1 pollbar2 pollbar3 pollbar4 pollbar5').addClass(new_bar_class); -				bar.html(res.vote_counts[option_id]); - -				var percent_txt = (!percent) ? res.NO_VOTES : percent + '%'; -				option.find('.poll_option_percent').html(percent_txt); -			}, bar_time_lapse); +				bar.animate({width: percentRel + '%'}, 500) +					.removeClass('pollbar1 pollbar2 pollbar3 pollbar4 pollbar5') +					.addClass(newBarClass) +					.html(res.vote_counts[optionId]); + +				var percentText = percent ? percent + '%' : res.NO_VOTES; +				$this.find('.poll_option_percent').html(percentText); +			}, barTimeLapse);  		});  		if (!res.can_vote) { @@ -264,30 +267,31 @@ phpbb.addAjaxCallback('vote_poll', function(res) {  		}  		// Display "Your vote has been cast." message. Disappears after 5 seconds. -		var confirmation_delay = (res.can_vote) ? 300 : 900; -		poll.find('.vote-submitted').delay(confirmation_delay).slideDown(200, function() { -			if (results_visible) { -				update_panel_height(); +		var confirmationDelay = (res.can_vote) ? 300 : 900; +		poll.find('.vote-submitted').delay(confirmationDelay).slideDown(200, function() { +			if (resultsVisible) { +				updatePanelHeight();  			}  			$(this).delay(5000).fadeOut(500, function() { -				resize_panel(300); +				resizePanel(300);  			});  		});  		// Remove the gap resulting from removing options  		setTimeout(function() { -			resize_panel(500); +			resizePanel(500);  		}, 1500); -		var resize_panel = function (time) { -			var panel_height = panel.height(); -			var inner_height = panel.find('.inner').outerHeight(); +		var resizePanel = function (time) { +			var panelHeight = panel.height(); +			var innerHeight = panel.find('.inner').outerHeight(); -			if (panel_height != inner_height) { -				panel.css({'min-height': '', 'height': panel_height}).animate({height: inner_height}, time, function () { -					panel.css({'min-height': inner_height, 'height': ''}); -				}); +			if (panelHeight != innerHeight) { +				panel.css({'min-height': '', 'height': panelHeight}) +					.animate({height: innerHeight}, time, function () { +						panel.css({'min-height': innerHeight, 'height': ''}); +					});  			}  		};  	} @@ -300,20 +304,19 @@ $('.poll_view_results a').click(function(e) {  	// Do not follow the link  	e.preventDefault(); -	var poll = $(this).parents('.topic_poll'); +	var $poll = $(this).parents('.topic_poll'); -	poll.find('.resultbar, .poll_option_percent, .poll_total_votes').show(500); -	poll.find('.poll_view_results').hide(500); +	$poll.find('.resultbar, .poll_option_percent, .poll_total_votes').show(500); +	$poll.find('.poll_view_results').hide(500);  });  $('[data-ajax]').each(function() { -	var $this = $(this), -		ajax = $this.attr('data-ajax'), -		filter = $this.attr('data-filter'), -		fn; +	var $this = $(this); +	var ajax = $this.attr('data-ajax'); +	var filter = $this.attr('data-filter');  	if (ajax !== 'false') { -		fn = (ajax !== 'true') ? ajax : null; +		var fn = (ajax !== 'true') ? ajax : null;  		filter = (filter !== undefined) ? phpbb.getFunctionByName(filter) : null;  		phpbb.ajaxify({ @@ -344,18 +347,10 @@ $('.display_post').click(function(e) {  	// Do not follow the link  	e.preventDefault(); -	var post_id = $(this).attr('data-post-id'); -	$('#post_content' + post_id).show(); -	$('#profile' + post_id).show(); -	$('#post_hidden' + post_id).hide(); -}); - -$('#delete_permanent').click(function () { -	if ($(this).prop('checked')) { -		$('#delete_reason').hide(); -	} else { -		$('#delete_reason').show(); -	} +	var postId = $(this).attr('data-post-id'); +	$('#post_content' + postId).show(); +	$('#profile' + postId).show(); +	$('#post_hidden' + postId).hide();  });  /** @@ -366,10 +361,13 @@ $('#delete_permanent').click(function () {  * appropriately changed based on the status of the search panel.  */  $('#member_search').click(function () { -	$('#memberlist_search').slideToggle('fast'); +	var $memberlistSearch = $('#memberlist_search'); + +	$memberlistSearch.slideToggle('fast');  	phpbb.ajaxCallbacks.alt_text.call(this); +  	// Focus on the username textbox if it's available and displayed -	if ($('#memberlist_search').is(':visible')) { +	if ($memberlistSearch.is(':visible')) {  		$('#username').focus();  	}  	return false; @@ -378,7 +376,7 @@ $('#member_search').click(function () {  /**  * Automatically resize textarea  */ -$(document).ready(function() { +$(function() {  	phpbb.resizeTextArea($('textarea:not(#message-box textarea, .no-auto-resize)'), {minHeight: 75, maxHeight: 250});  	phpbb.resizeTextArea($('#message-box textarea'));  }); diff --git a/phpBB/styles/prosilver/template/forum_fn.js b/phpBB/styles/prosilver/template/forum_fn.js index 4929e14ef7..1280ceb8ac 100644 --- a/phpBB/styles/prosilver/template/forum_fn.js +++ b/phpBB/styles/prosilver/template/forum_fn.js @@ -1,3 +1,5 @@ +/* global phpbb */ +  /**  * phpBB3 forum functions  */ @@ -6,6 +8,8 @@  * Find a member  */  function find_username(url) { +	'use strict'; +  	popup(url, 760, 570, '_usersearch');  	return false;  } @@ -14,6 +18,8 @@ function find_username(url) {  * Window popup  */  function popup(url, width, height, name) { +	'use strict'; +  	if (!name) {  		name = '_popup';  	} @@ -26,17 +32,18 @@ function popup(url, width, height, name) {  * Jump to page  */  function pageJump(item) { +	'use strict';  	var page = item.val(), -		per_page = item.attr('data-per-page'), -		base_url = item.attr('data-base-url'), -		start_name = item.attr('data-start-name'); +		perPage = item.attr('data-per-page'), +		baseUrl = item.attr('data-base-url'), +		startName = item.attr('data-start-name');  	if (page !== null && !isNaN(page) && page == Math.floor(page) && page > 0) { -		if (base_url.indexOf('?') === -1) { -			document.location.href = base_url + '?' + start_name + '=' + ((page - 1) * per_page); +		if (baseUrl.indexOf('?') === -1) { +			document.location.href = baseUrl + '?' + startName + '=' + ((page - 1) * perPage);  		} else { -			document.location.href = base_url.replace(/&/g, '&') + '&' + start_name + '=' + ((page - 1) * per_page); +			document.location.href = baseUrl.replace(/&/g, '&') + '&' + startName + '=' + ((page - 1) * perPage);  		}  	}  } @@ -46,9 +53,11 @@ function pageJump(item) {  * id = ID of parent container, name = name prefix, state = state [true/false]  */  function marklist(id, name, state) { +	'use strict'; +  	jQuery('#' + id + ' input[type=checkbox][name]').each(function() {  		var $this = jQuery(this); -		if ($this.attr('name').substr(0, name.length) == name) { +		if ($this.attr('name').substr(0, name.length) === name) {  			$this.prop('checked', state);  		}  	}); @@ -59,6 +68,8 @@ function marklist(id, name, state) {  * e = element  */  function viewableArea(e, itself) { +	'use strict'; +  	if (!e) {  		return;  	} @@ -86,18 +97,20 @@ function viewableArea(e, itself) {  /**  * Alternate display of subPanels  */ -jQuery(document).ready(function() { -	jQuery('.sub-panels').each(function() { +jQuery(function($) { +	'use strict'; -		var panels = [], -			childNodes = jQuery('a[data-subpanel]', this).each(function() { -				panels.push(this.getAttribute('data-subpanel')); +	$('.sub-panels').each(function() { + +		var $childNodes = $('a[data-subpanel]', this), +			panels = $childNodes.map(function () { +				return this.getAttribute('data-subpanel');  			}), -			show_panel = this.getAttribute('data-show-panel'); +			showPanel = this.getAttribute('data-show-panel');  		if (panels.length) { -			activateSubPanel(show_panel, panels); -			childNodes.click(function () { +			activateSubPanel(showPanel, panels); +			$childNodes.click(function () {  				activateSubPanel(this.getAttribute('data-subpanel'), panels);  				return false;  			}); @@ -109,60 +122,30 @@ jQuery(document).ready(function() {  * Activate specific subPanel  */  function activateSubPanel(p, panels) { -	var i; +	'use strict'; + +	var i, showPanel;  	if (typeof(p) === 'string') { -		show_panel = p; +		showPanel = p;  	} -	$('input[name="show_panel"]').val(show_panel); +	$('input[name="show_panel"]').val(showPanel); -	if (typeof(panels) === 'undefined') { -		panels = []; -		jQuery('.sub-panels a[data-subpanel]').each(function() { -			panels.push(this.getAttribute('data-subpanel')); +	if (typeof panels === 'undefined') { +		panels = jQuery('.sub-panels a[data-subpanel]').map(function() { +			return this.getAttribute('data-subpanel');  		});  	}  	for (i = 0; i < panels.length; i++) { -		jQuery('#' + panels[i]).css('display', panels[i] === show_panel ? 'block' : 'none'); -		jQuery('#' + panels[i] + '-tab').toggleClass('activetab', panels[i] === show_panel); -	} -} - -/** -* Call print preview -*/ -function printPage() { -	if (is_ie) { -		printPreview(); -	} else { -		window.print(); -	} -} - -/** -* Show/hide groups of blocks -* c = CSS style name -* e = checkbox element -* t = toggle dispay state (used to show 'grip-show' image in the profile block when hiding the profiles) -*/ -function displayBlocks(c, e, t) { -	var s = (e.checked === true) ?  1 : -1; - -	if (t) { -		s *= -1; -	} - -	var divs = document.getElementsByTagName("DIV"); - -	for (var d = 0; d < divs.length; d++) { -		if (divs[d].className.indexOf(c) === 0) { -			divs[d].style.display = (s === 1) ? 'none' : 'block'; -		} +		jQuery('#' + panels[i]).css('display', panels[i] === showPanel ? 'block' : 'none'); +		jQuery('#' + panels[i] + '-tab').toggleClass('activetab', panels[i] === showPanel);  	}  }  function selectCode(a) { +	'use strict'; +  	// Get ID of code block  	var e = a.parentNode.parentNode.getElementsByTagName('CODE')[0];  	var s, r; @@ -209,6 +192,8 @@ function selectCode(a) {  * from the displayed rectangle area  */  function play_qt_file(obj) { +	'use strict'; +  	var rectangle = obj.GetRectangle();  	var width, height; @@ -233,30 +218,32 @@ function play_qt_file(obj) {  	obj.Play();  } -var in_autocomplete = false; -var last_key_entered = ''; +var inAutocomplete = false; +var lastKeyEntered = '';  /**  * Check event key  */ -function phpbb_check_key(event) { +function phpbbCheckKey(event) { +	'use strict'; +  	// Keycode is array down or up?  	if (event.keyCode && (event.keyCode === 40 || event.keyCode === 38)) { -		in_autocomplete = true; +		inAutocomplete = true;  	}  	// Make sure we are not within an "autocompletion" field -	if (in_autocomplete) { +	if (inAutocomplete) {  		// If return pressed and key changed we reset the autocompletion -		if (!last_key_entered || last_key_entered === event.which) { -			in_autocompletion = false; +		if (!lastKeyEntered || lastKeyEntered === event.which) { +			inAutocomplete = false;  			return true;  		}  	}  	// Keycode is not return, then return. ;)  	if (event.which !== 13) { -		last_key_entered = event.which; +		lastKeyEntered = event.which;  		return true;  	} @@ -266,115 +253,106 @@ function phpbb_check_key(event) {  /**  * Apply onkeypress event for forcing default submit button on ENTER key press  */ -function apply_onkeypress_event() { -	jQuery('form input[type=text], form input[type=password]').on('keypress', function (e) { -		var default_button = jQuery(this).parents('form').find('input[type=submit].default-submit-action'); +jQuery(function($) { +	'use strict'; + +	$('form input[type=text], form input[type=password]').on('keypress', function (e) { +		var defaultButton = $(this).parents('form').find('input[type=submit].default-submit-action'); -		if (!default_button || default_button.length <= 0) { +		if (!defaultButton || defaultButton.length <= 0) {  			return true;  		} -		if (phpbb_check_key(e)) { +		if (phpbbCheckKey(e)) {  			return true;  		}  		if ((e.which && e.which === 13) || (e.keyCode && e.keyCode === 13)) { -			default_button.click(); +			defaultButton.click();  			return false;  		}  		return true;  	}); -} - -jQuery(document).ready(apply_onkeypress_event); +});  /**  * Functions for user search popup  */ -function insert_user(formId, value) +function insertUser(formId, value)  { -	var form = jQuery(formId), -		formName = form.attr('data-form-name'), -		fieldName = form.attr('data-field-name'), +	'use strict'; + +	var $form = jQuery(formId), +		formName = $form.attr('data-form-name'), +		fieldName = $form.attr('data-field-name'),  		item = opener.document.forms[formName][fieldName];  	if (item.value.length && item.type == 'textarea') { -		value = item.value + "\n" + value; +		value = item.value + '\n' + value;  	}  	item.value = value;  } -function insert_marked_users(formId, users) -{ -	if (typeof(users.length) == "undefined") -	{ -		if (users.checked) -		{ -			insert_user(formId, users.value); -		} -	} -	else if (users.length > 0) -	{ -		for (i = 0; i < users.length; i++) -		{ -			if (users[i].checked) -			{ -				insert_user(formId, users[i].value); -			} +function insert_marked_users(formId, users) { +	'use strict'; + +	for (var i = 0; i < users.length; i++) { +		if (users[i].checked) { +			insertUser(formId, users[i].value);  		}  	} -	self.close(); +	window.close();  } -function insert_single_user(formId, user) -{ -	insert_user(formId, user); -	self.close(); +function insert_single_user(formId, user) { +	'use strict'; + +	insertUser(formId, user); +	window.close();  }  /**  * Parse document block  */ -function parse_document(container)  -{ +function parseDocument($container) { +	'use strict'; +  	var test = document.createElement('div'),  		oldBrowser = (typeof test.style.borderRadius == 'undefined'); -	delete test; -  	/**  	* Reset avatar dimensions when changing URL or EMAIL  	*/ -	container.find('input[data-reset-on-edit]').bind('keyup', function() { +	$container.find('input[data-reset-on-edit]').on('keyup', function() {  		$(this.getAttribute('data-reset-on-edit')).val('');  	});  	/**  	* Pagination  	*/ -	container.find('.pagination .page-jump-form :button').click(function() { -		$input = $(this).siblings('input.inputbox'); +	$container.find('.pagination .page-jump-form :button').click(function() { +		var $input = $(this).siblings('input.inputbox');  		pageJump($input);  	}); -	container.find('.pagination .page-jump-form input.inputbox').on('keypress', function(event) { -		if (event.which == 13 || event.keyCode == 13) { +	$container.find('.pagination .page-jump-form input.inputbox').on('keypress', function(event) { +		if (event.which === 13 || event.keyCode === 13) {  			event.preventDefault();  			pageJump($(this));  		}  	}); -	container.find('.pagination .dropdown-trigger').click(function() { -		$dropdown_container = $(this).parent(); +	$container.find('.pagination .dropdown-trigger').click(function() { +		var $dropdownContainer = $(this).parent();  		// Wait a little bit to make sure the dropdown has activated  		setTimeout(function() {  -			if ($dropdown_container.hasClass('dropdown-visible')) { -				$dropdown_container.find('input.inputbox').focus(); +			if ($dropdownContainer.hasClass('dropdown-visible')) { +				$dropdownContainer.find('input.inputbox').focus();  			} -		},100); +		}, 100);  	});  	/** @@ -382,27 +360,29 @@ function parse_document(container)  	*/  	if (oldBrowser) {  		// Fix .linklist.bulletin lists -		container.find('ul.linklist.bulletin > li:first-child, ul.linklist.bulletin > li.rightside:last-child').addClass('no-bulletin'); +		$container.find('ul.linklist.bulletin > li:first-child, ul.linklist.bulletin > li.rightside:last-child').addClass('no-bulletin');  	}  	/**  	* Resize navigation block to keep all links on same line  	*/ -	container.find('.navlinks').each(function() { +	$container.find('.navlinks').each(function() {  		var $this = $(this), -			left = $this.children().not('.rightside'), -			right = $this.children('.rightside'); +			$left = $this.children().not('.rightside'), +			$right = $this.children('.rightside'); -		if (left.length !== 1 || !right.length) return; +		if ($left.length !== 1 || !$right.length) { +			return; +		}  		function resize() {  			var width = 0, -				diff = left.outerWidth(true) - left.width(); +				diff = $left.outerWidth(true) - $left.width(); -			right.each(function() { +			$right.each(function() {  				width += $(this).outerWidth(true);  			}); -			left.css('max-width', Math.floor($this.width() - width - diff) + 'px'); +			$left.css('max-width', Math.floor($this.width() - width - diff) + 'px');  		}  		resize(); @@ -412,11 +392,11 @@ function parse_document(container)  	/**  	* Makes breadcrumbs responsive  	*/ -	container.find('.breadcrumbs:not([data-skip-responsive])').each(function() { +	$container.find('.breadcrumbs:not([data-skip-responsive])').each(function() {  		var $this = $(this),  			$body = $('body'), -			links = $this.find('.crumb'), -			length = links.length, +			$links = $this.find('.crumb'), +			length = $links.length,  			classes = ['wrapped-max', 'wrapped-wide', 'wrapped-medium', 'wrapped-small', 'wrapped-tiny'],  			classesLength = classes.length,  			maxHeight = 0, @@ -429,14 +409,13 @@ function parse_document(container)  			$link.attr('title', $link.text());  		}); -		// Funciton that checks breadcrumbs +		// Function that checks breadcrumbs  		function check() {  			var height = $this.height(), -				width = $body.width(), -				link, i, j; +				width = $body.width(); -			maxHeight = parseInt($this.css('line-height')) | 0; -			links.each(function() { +			maxHeight = parseInt($this.css('line-height')); +			$links.each(function() {  				if ($(this).height() > 0) {  					maxHeight = Math.max(maxHeight, $(this).outerHeight(true));  				} @@ -444,7 +423,6 @@ function parse_document(container)  			if (height <= maxHeight) {  				if (!wrapped || lastWidth === false || lastWidth >= width) { -					lastWidth = width;  					return;  				}  			} @@ -452,7 +430,6 @@ function parse_document(container)  			if (wrapped) {  				$this.removeClass('wrapped').find('.crumb.wrapped').removeClass('wrapped ' + classes.join(' ')); -				wrapped = false;  				if ($this.height() <= maxHeight) {  					return;  				} @@ -464,9 +441,9 @@ function parse_document(container)  				return;  			} -			for (i = 0; i < classesLength; i ++) { -				for (j = length - 1; j >= 0; j --) { -					links.eq(j).addClass('wrapped ' + classes[i]); +			for (var i = 0; i < classesLength; i ++) { +				for (var j = length - 1; j >= 0; j --) { +					$links.eq(j).addClass('wrapped ' + classes[i]);  					if ($this.height() <= maxHeight) {  						return;  					} @@ -482,32 +459,29 @@ function parse_document(container)  	/**  	* Responsive link lists  	*/ -	container.find('.linklist:not(.navlinks, [data-skip-responsive]), .postbody .post-buttons:not([data-skip-responsive])').each(function() { +	$container.find('.linklist:not(.navlinks, [data-skip-responsive]), .postbody .post-buttons:not([data-skip-responsive])').each(function() {  		var $this = $(this),  			$body = $('body'),  			filterSkip = '.breadcrumbs, [data-skip-responsive]',  			filterLast = '.edit-icon, .quote-icon, [data-last-responsive]',  			persist = $this.attr('id') == 'nav-main', -			allLinks = $this.children(), -			links = allLinks.not(filterSkip), +			$allLinks = $this.children(), +			$links = $allLinks.not(filterSkip),  			html = '<li class="responsive-menu" style="display:none;"><a href="javascript:void(0);" class="responsive-menu-link"> </a><div class="dropdown" style="display:none;"><div class="pointer"><div class="pointer-inner" /></div><ul class="dropdown-contents" /></div></li>', -			filterLastList = links.filter(filterLast), +			$filterLastList = $links.filter(filterLast),  			slack = 1; // Vertical slack space (in pixels). Determines how sensitive the script is in determining whether a line-break has occured.   		if (!persist) { -			if (links.is('.rightside')) -			{ -				links.filter('.rightside:first').before(html); +			if ($links.is('.rightside')) { +				$links.filter('.rightside:first').before(html);  				$this.children('.responsive-menu').addClass('rightside'); -			} -			else -			{ +			} else {  				$this.append(html);  			}  		} -		var item = $this.children('.responsive-menu'), -			menu = item.find('.dropdown-contents'), +		var $item = $this.children('.responsive-menu'), +			$menu = $item.find('.dropdown-contents'),  			lastWidth = false,  			compact = false,  			responsive = false, @@ -521,29 +495,31 @@ function parse_document(container)  			// Unhide the quick-links menu if it has content  			if (persist) { -				item.addClass('hidden'); -				if (menu.find('li:not(.separator, .clone)').length || (responsive && menu.find('li.clone').length)) { -					item.removeClass('hidden'); +				$item.addClass('hidden'); +				if ($menu.find('li:not(.separator, .clone)').length || (responsive && $menu.find('li.clone').length)) { +					$item.removeClass('hidden');  				}  			}  			// Reset responsive and compact layout  			if (responsive) { -				responsive = false;  				$this.removeClass('responsive'); -				links.css('display', ''); -				if (!persist) item.css('display', 'none'); +				$links.css('display', ''); +				if (!persist) { +					$item.css('display', 'none'); +				}  			}  			if (compact) { -				compact = false;  				$this.removeClass('compact');  			}  			// Find tallest element  			var maxHeight = 0; -			allLinks.each(function() { -				if (!$(this).height()) return; +			$allLinks.each(function() { +				if (!$(this).height()) { +					return; +				}  				maxHeight = Math.max(maxHeight, $(this).outerHeight(true));  			}); @@ -557,12 +533,13 @@ function parse_document(container)  			}  			// Enable compact layout, find tallest element, compare to height of whole block -			compact = true;  			$this.addClass('compact');  			var compactMaxHeight = 0; -			allLinks.each(function() { -				if (!$(this).height()) return; +			$allLinks.each(function() { +				if (!$(this).height()) { +					return; +				}  				compactMaxHeight = Math.max(compactMaxHeight, $(this).outerHeight(true));  			}); @@ -571,51 +548,51 @@ function parse_document(container)  			}  			// Compact layout did not resize block enough, switch to responsive layout -			compact = false;  			$this.removeClass('compact');  			responsive = true;  			if (!copied) { -				var clone = links.clone(true); +				var clone = $links.clone(true);  				clone.filter('.rightside').each(function() { -					if (persist) $(this).addClass('clone'); -					menu.prepend(this); +					if (persist) { +						$(this).addClass('clone'); +					} +					$menu.prepend(this);  				});  				if (persist) { -					menu.prepend(clone.not('.rightside').addClass('clone')); +					$menu.prepend(clone.not('.rightside').addClass('clone'));  				} else { -					menu.prepend(clone.not('.rightside')); +					$menu.prepend(clone.not('.rightside'));  				} -				menu.find('li.leftside, li.rightside').removeClass('leftside rightside'); -				menu.find('.inputbox').parents('li:first').css('white-space', 'normal'); +				$menu.find('li.leftside, li.rightside').removeClass('leftside rightside'); +				$menu.find('.inputbox').parents('li:first').css('white-space', 'normal');  				if ($this.hasClass('post-buttons')) { -					$('.button', menu).removeClass('button icon-button'); -					$('.responsive-menu-link', item).addClass('button icon-button').prepend('<span></span>'); +					$('.button', $menu).removeClass('button icon-button'); +					$('.responsive-menu-link', $item).addClass('button icon-button').prepend('<span></span>');  				}  				copied = true; -			} -			else { -				menu.children().css('display', ''); +			} else { +				$menu.children().css('display', '');  			} -			item.css('display', ''); +			$item.css('display', '');  			$this.addClass('responsive');  			// Try to not hide filtered items -			if (filterLastList.length) { -				links.not(filterLast).css('display', 'none'); +			if ($filterLastList.length) { +				$links.not(filterLast).css('display', 'none');  				maxHeight = 0; -				filterLastList.each(function() { +				$filterLastList.each(function() {  					if (!$(this).height()) return;  					maxHeight = Math.max(maxHeight, $(this).outerHeight(true));  				});  				if ($this.height() <= (maxHeight + slack)) { -					menu.children().filter(filterLast).css('display', 'none'); +					$menu.children().filter(filterLast).css('display', 'none');  					return;  				}  			} @@ -624,10 +601,12 @@ function parse_document(container)  			compact = true;  			$this.addClass('compact'); -			links.css('display', 'none'); +			$links.css('display', 'none');  		} -		if (!persist) phpbb.registerDropdown(item.find('a.responsive-menu-link'), item.find('.dropdown')); +		if (!persist) { +			phpbb.registerDropdown($item.find('a.responsive-menu-link'), $item.find('.dropdown')); +		}  		check();  		$(window).resize(check); @@ -643,7 +622,7 @@ function parse_document(container)  	/**  	* Adjust topiclist lists with check boxes  	*/ -	container.find('ul.topiclist dd.mark').siblings('dt').children('.list-inner').addClass('with-mark'); +	$container.find('ul.topiclist dd.mark').siblings('dt').children('.list-inner').addClass('with-mark');  	/**  	* Appends contents of all extra columns to first column in @@ -652,31 +631,30 @@ function parse_document(container)  	* To add that functionality to .topiclist list simply add  	* responsive-show-all to list of classes  	*/ -	container.find('.topiclist.responsive-show-all > li > dl').each(function() { +	$container.find('.topiclist.responsive-show-all > li > dl').each(function() {  		var $this = $(this), -			block = $this.find('dt .responsive-show:last-child'), +			$block = $this.find('dt .responsive-show:last-child'),  			first = true;  		// Create block that is visible only on mobile devices -		if (!block.length) { +		if (!$block.length) {  			$this.find('dt > .list-inner').append('<div class="responsive-show" style="display:none;" />'); -			block = $this.find('dt .responsive-show:last-child'); -		} -		else { -			first = ($.trim(block.text()).length == 0); +			$block = $this.find('dt .responsive-show:last-child'); +		} else { +			first = ($.trim($block.text()).length === 0);  		}  		// Copy contents of each column  		$this.find('dd').not('.mark').each(function() {  			var column = $(this), -				children = column.children(), +				$children = column.children(),  				html = column.html(); -			if (children.length == 1 && children.text() == column.text()) { -				html = children.html(); +			if ($children.length == 1 && $children.text() == column.text()) { +				html = $children.html();  			} -			block.append((first ? '' : '<br />') + html); +			$block.append((first ? '' : '<br />') + html);  			first = false;  		}); @@ -689,15 +667,15 @@ function parse_document(container)  	* To add that functionality to .topiclist list simply add  	* responsive-show-columns to list of classes  	*/ -	container.find('.topiclist.responsive-show-columns').each(function() { -		var list = $(this), +	$container.find('.topiclist.responsive-show-columns').each(function() { +		var $list = $(this),  			headers = [],  			headersLength = 0;  		// Find all headers, get contents -		list.prev('.topiclist').find('li.header dd').not('.mark').each(function() { +		$list.prev('.topiclist').find('li.header dd').not('.mark').each(function() {  			headers.push($(this).text()); -			headersLength ++; +			headersLength++;  		});  		if (!headersLength) { @@ -705,18 +683,18 @@ function parse_document(container)  		}  		// Parse each row -		list.find('dl').each(function() { +		$list.find('dl').each(function() {  			var $this = $(this), -				block = $this.find('dt .responsive-show:last-child'), +				$block = $this.find('dt .responsive-show:last-child'),  				first = true;  			// Create block that is visible only on mobile devices -			if (!block.length) { +			if (!$block.length) {  				$this.find('dt > .list-inner').append('<div class="responsive-show" style="display:none;" />'); -				block = $this.find('dt .responsive-show:last-child'); +				$block = $this.find('dt .responsive-show:last-child');  			}  			else { -				first = ($.trim(block.text()).length == 0); +				first = ($.trim($block.text()).length === 0);  			}  			// Copy contents of each column @@ -734,7 +712,7 @@ function parse_document(container)  					html = headers[i] + ': <strong>' + html + '</strong>';  				} -				block.append((first ? '' : '<br />') + html); +				$block.append((first ? '' : '<br />') + html);  				first = false;  			}); @@ -744,16 +722,15 @@ function parse_document(container)  	/**  	* Responsive tables  	*/ -	container.find('table.table1').not('.not-responsive').each(function() { +	$container.find('table.table1').not('.not-responsive').each(function() {  		var $this = $(this), -			th = $this.find('thead > tr > th'), -			columns = th.length, +			$th = $this.find('thead > tr > th'),  			headers = [],  			totalHeaders = 0,  			i, headersLength;  		// Find each header -		th.each(function(column) { +		$th.each(function(column) {  			var cell = $(this),  				colspan = parseInt(cell.attr('colspan')),  				dfn = cell.attr('data-dfn'), @@ -761,10 +738,10 @@ function parse_document(container)  			colspan = isNaN(colspan) || colspan < 1 ? 1 : colspan; -			for (i=0; i<colspan; i++) { +			for (i = 0; i < colspan; i++) {  				headers.push(text);  			} -			totalHeaders ++; +			totalHeaders++;  			if (dfn && !column) {  				$this.addClass('show-header'); @@ -802,8 +779,7 @@ function parse_document(container)  				if ((text.length && text !== '-') || cell.children().length) {  					cell.prepend('<dfn style="display: none;">' + headers[column] + '</dfn>'); -				} -				else { +				} else {  					cell.addClass('empty');  				} @@ -816,10 +792,9 @@ function parse_document(container)  	/**  	* Hide empty responsive tables  	*/ -	container.find('table.responsive > tbody').not('.responsive-skip-empty').each(function() { -		var items = $(this).children('tr'); -		if (items.length == 0) -		{ +	$container.find('table.responsive > tbody').not('.responsive-skip-empty').each(function() { +		var $items = $(this).children('tr'); +		if (!$items.length) {  			$(this).parent('table:first').addClass('responsive-hide');  		}  	}); @@ -827,65 +802,64 @@ function parse_document(container)  	/**  	* Responsive tabs  	*/ -	container.find('#tabs, #minitabs').not('[data-skip-responsive]').each(function() { +	$container.find('#tabs, #minitabs').not('[data-skip-responsive]').each(function() {  		var $this = $(this),  			$body = $('body'), -			ul = $this.children(), -			tabs = ul.children().not('[data-skip-responsive]'), -			links = tabs.children('a'), -			item = ul.append('<li class="tab responsive-tab" style="display:none;"><a href="javascript:void(0);" class="responsive-tab-link"> </a><div class="dropdown tab-dropdown" style="display: none;"><div class="pointer"><div class="pointer-inner" /></div><ul class="dropdown-contents" /></div></li>').find('li.responsive-tab'), -			menu = item.find('.dropdown-contents'), +			$ul = $this.children(), +			$tabs = $ul.children().not('[data-skip-responsive]'), +			$links = $tabs.children('a'), +			$item = $ul.append('<li class="tab responsive-tab" style="display:none;"><a href="javascript:void(0);" class="responsive-tab-link"> </a><div class="dropdown tab-dropdown" style="display: none;"><div class="pointer"><div class="pointer-inner" /></div><ul class="dropdown-contents" /></div></li>').find('li.responsive-tab'), +			$menu = $item.find('.dropdown-contents'),  			maxHeight = 0,  			lastWidth = false,  			responsive = false; -		links.each(function() { -			var link = $(this); -			maxHeight = Math.max(maxHeight, Math.max(link.outerHeight(true), link.parent().outerHeight(true))); -		}) +		$links.each(function() { +			var $this = $(this); +			maxHeight = Math.max(maxHeight, Math.max($this.outerHeight(true), $this.parent().outerHeight(true))); +		});  		function check() {  			var width = $body.width(),  				height = $this.height(); -			if (arguments.length == 0 && (!responsive || width <= lastWidth) && height <= maxHeight) { +			if (!arguments.length && (!responsive || width <= lastWidth) && height <= maxHeight) {  				return;  			} -			tabs.show(); -			item.hide(); +			$tabs.show(); +			$item.hide();  			lastWidth = width;  			height = $this.height();  			if (height <= maxHeight) { -				responsive = false; -				if (item.hasClass('dropdown-visible')) { -					phpbb.toggleDropdown.call(item.find('a.responsive-tab-link').get(0)); +				if ($item.hasClass('dropdown-visible')) { +					phpbb.toggleDropdown.call($item.find('a.responsive-tab-link').get(0));  				}  				return;  			}  			responsive = true; -			item.show(); -			menu.html(''); +			$item.show(); +			$menu.html(''); -			var availableTabs = tabs.filter(':not(.activetab, .responsive-tab)'), -				total = availableTabs.length, -				i, tab; +			var $availableTabs = $tabs.filter(':not(.activetab, .responsive-tab)'), +				total = $availableTabs.length, +				i, $tab;  			for (i = total - 1; i >= 0; i --) { -				tab = availableTabs.eq(i); -				menu.prepend(tab.clone(true).removeClass('tab')); -				tab.hide(); +				$tab = $availableTabs.eq(i); +				$menu.prepend($tab.clone(true).removeClass('tab')); +				$tab.hide();  				if ($this.height() <= maxHeight) { -					menu.find('a').click(function() { check(true); }); +					$menu.find('a').click(function() { check(true); });  					return;  				}  			} -			menu.find('a').click(function() { check(true); }); +			$menu.find('a').click(function() { check(true); });  		} -		phpbb.registerDropdown(item.find('a.responsive-tab-link'), item.find('.dropdown'), {visibleClass: 'activetab'}); +		phpbb.registerDropdown($item.find('a.responsive-tab-link'), $item.find('.dropdown'), {visibleClass: 'activetab'});  		check(true);  		$(window).resize(check); @@ -894,10 +868,9 @@ function parse_document(container)  	/**  	 * Hide UCP/MCP navigation if there is only 1 item  	 */ -	container.find('#navigation').each(function() { -		var items = $(this).children('ol, ul').children('li'); -		if (items.length == 1) -		{ +	$container.find('#navigation').each(function() { +		var $items = $(this).children('ol, ul').children('li'); +		if ($items.length === 1) {  			$(this).addClass('responsive-hide');  		}  	}); @@ -905,7 +878,7 @@ function parse_document(container)  	/**  	* Replace responsive text  	*/ -	container.find('[data-responsive-text]').each(function() { +	$container.find('[data-responsive-text]').each(function() {  		var $this = $(this),  			fullText = $this.text(),  			responsiveText = $this.attr('data-responsive-text'), @@ -913,12 +886,16 @@ function parse_document(container)  		function check() {  			if ($(window).width() > 700) { -				if (!responsive) return; +				if (!responsive) { +					return; +				}  				$this.text(fullText);  				responsive = false;  				return;  			} -			if (responsive) return; +			if (responsive) { +				return; +			}  			$this.text(responsiveText);  			responsive = true;  		} @@ -931,18 +908,18 @@ function parse_document(container)  /**  * Run onload functions  */ -(function($) { -	$(document).ready(function() { -		// Swap .nojs and .hasjs -		$('#phpbb.nojs').toggleClass('nojs hasjs'); -		$('#phpbb').toggleClass('hastouch', phpbb.isTouch); -		$('#phpbb.hastouch').removeClass('notouch'); - -		// Focus forms -		$('form[data-focus]:first').each(function() { -			$('#' + this.getAttribute('data-focus')).focus(); -		}); +jQuery(function($) { +	'use strict'; + +	// Swap .nojs and .hasjs +	$('#phpbb.nojs').toggleClass('nojs hasjs'); +	$('#phpbb').toggleClass('hastouch', phpbb.isTouch); +	$('#phpbb.hastouch').removeClass('notouch'); -		parse_document($('body')); +	// Focus forms +	$('form[data-focus]:first').each(function() { +		$('#' + this.getAttribute('data-focus')).focus();  	}); -})(jQuery); + +	parseDocument($('body')); +}); diff --git a/phpBB/styles/prosilver/template/jumpbox.html b/phpBB/styles/prosilver/template/jumpbox.html index 44b479ab3f..3096d08318 100644 --- a/phpBB/styles/prosilver/template/jumpbox.html +++ b/phpBB/styles/prosilver/template/jumpbox.html @@ -6,7 +6,7 @@  <!-- ELSEIF SEARCH_TOPIC -->  	<p class="jumpbox-return"><a class="left-box arrow-{S_CONTENT_FLOW_BEGIN}" href="{U_SEARCH_TOPIC}" accesskey="r">{L_RETURN_TO_TOPIC}</a></p>  <!-- ELSEIF S_SEARCH_ACTION --> -	<p class="jumpbox-return"><a class="left-box arrow-{S_CONTENT_FLOW_BEGIN}" href="{U_SEARCH}" title="{L_SEARCH_ADV}" accesskey="r">{L_RETURN_TO_SEARCH_ADV}</a></p> +	<p class="jumpbox-return"><a class="left-box arrow-{S_CONTENT_FLOW_BEGIN}" href="{U_SEARCH}" title="{L_SEARCH_ADV}" accesskey="r">{L_GO_TO_SEARCH_ADV}</a></p>  <!-- ENDIF -->  <!-- IF S_DISPLAY_JUMPBOX --> diff --git a/phpBB/styles/prosilver/template/message_body.html b/phpBB/styles/prosilver/template/message_body.html index 8062fed9a0..71eca203bc 100644 --- a/phpBB/styles/prosilver/template/message_body.html +++ b/phpBB/styles/prosilver/template/message_body.html @@ -8,7 +8,7 @@  	<div class="inner">  	<h2 class="message-title">{MESSAGE_TITLE}</h2>  	<p>{MESSAGE_TEXT}</p> -	<!-- IF SCRIPT_NAME == "search" and not S_BOARD_DISABLED and not S_NO_SEARCH and L_RETURN_TO_SEARCH_ADV --><p><a href="{U_SEARCH}" class="arrow-{S_CONTENT_FLOW_BEGIN}">{L_RETURN_TO_SEARCH_ADV}</a></p><!-- ENDIF --> +	<!-- IF SCRIPT_NAME == "search" and not S_BOARD_DISABLED and not S_NO_SEARCH and L_RETURN_TO_SEARCH_ADV --><p><a href="{U_SEARCH}" class="arrow-{S_CONTENT_FLOW_BEGIN}">{L_GO_TO_SEARCH_ADV}</a></p><!-- ENDIF -->  	</div>  </div> diff --git a/phpBB/styles/prosilver/template/overall_footer.html b/phpBB/styles/prosilver/template/overall_footer.html index e9c95aa799..275859ac97 100644 --- a/phpBB/styles/prosilver/template/overall_footer.html +++ b/phpBB/styles/prosilver/template/overall_footer.html @@ -22,7 +22,7 @@  	<div id="phpbb_alert" class="phpbb_alert" data-l-err="{L_ERROR}" data-l-timeout-processing-req="{L_TIMEOUT_PROCESSING_REQ}">  		<a href="#" class="alert_close"></a> -		<h3 class="alert_title"></h3><p class="alert_text"></p> +		<h3 class="alert_title"> </h3><p class="alert_text"></p>  	</div>  	<div id="phpbb_confirm" class="phpbb_alert">  		<a href="#" class="alert_close"></a> diff --git a/phpBB/styles/prosilver/template/overall_header.html b/phpBB/styles/prosilver/template/overall_header.html index 076a3160f0..ad08c1220b 100644 --- a/phpBB/styles/prosilver/template/overall_header.html +++ b/phpBB/styles/prosilver/template/overall_header.html @@ -3,8 +3,6 @@  <head>  <meta charset="utf-8">  <meta name="viewport" content="width=device-width" /> -<meta name="keywords" content="" /> -<meta name="description" content="" />  {META}  <title><!-- IF UNREAD_NOTIFICATIONS_COUNT -->({UNREAD_NOTIFICATIONS_COUNT}) <!-- ENDIF --><!-- IF not S_VIEWTOPIC and not S_VIEWFORUM -->{SITENAME} - <!-- ENDIF --><!-- IF S_IN_MCP -->{L_MCP} - <!-- ELSEIF S_IN_UCP -->{L_UCP} - <!-- ENDIF -->{PAGE_TITLE}<!-- IF S_VIEWTOPIC or S_VIEWFORUM --> - {SITENAME}<!-- ENDIF --></title> @@ -43,7 +41,7 @@  	<link href="{T_THEME_PATH}/plupload.css?assets_version={T_ASSETS_VERSION}" rel="stylesheet" type="text/css" media="screen, projection" />  <!-- ENDIF --> -<!--[if lte IE 8]> +<!--[if lte IE 9]>  	<link href="{T_THEME_PATH}/tweaks.css?assets_version={T_ASSETS_VERSION}" rel="stylesheet" type="text/css" media="screen, projection" />  <![endif]--> @@ -71,17 +69,18 @@  				<p class="skiplink"><a href="#start_here">{L_SKIP}</a></p>  			</div> -		<!-- IF S_DISPLAY_SEARCH and not S_IN_SEARCH --> -			<div id="search-box"> +			<!-- IF S_DISPLAY_SEARCH and not S_IN_SEARCH --> +			<div id="search-box" class="search-box search-header">  				<form action="{U_SEARCH}" method="get" id="search">  				<fieldset> -					<input name="keywords" id="keywords" type="search" maxlength="128" title="{L_SEARCH_KEYWORDS}" class="inputbox search" value="{SEARCH_WORDS}" placeholder="{L_SEARCH_MINI}" /> -					<input class="button2" value="{L_SEARCH}" type="submit" /><br /> -					<a href="{U_SEARCH}" title="{L_SEARCH_ADV_EXPLAIN}">{L_SEARCH_ADV}</a> {S_SEARCH_HIDDEN_FIELDS} +					<input name="keywords" id="keywords" type="search" maxlength="128" title="{L_SEARCH_KEYWORDS}" class="inputbox search tiny" size="20" value="{SEARCH_WORDS}" placeholder="{L_SEARCH_MINI}" /> +					<button class="button icon-button search-icon" type="submit" title="{L_SEARCH}">{L_SEARCH}</button> +					<a href="{U_SEARCH}" class="button icon-button search-adv-icon" title="{L_SEARCH_ADV}">{L_SEARCH_ADV}</a> +					{S_SEARCH_HIDDEN_FIELDS}  				</fieldset>  				</form>  			</div> -		<!-- ENDIF --> +			<!-- ENDIF -->  			</div>  		</div> diff --git a/phpBB/styles/prosilver/template/pagination.html b/phpBB/styles/prosilver/template/pagination.html index cb2c09bff7..4680eaa175 100644 --- a/phpBB/styles/prosilver/template/pagination.html +++ b/phpBB/styles/prosilver/template/pagination.html @@ -7,7 +7,7 @@  			<ul class="dropdown-contents">  				<li>{L_JUMP_TO_PAGE}{L_COLON}</li>  				<li class="page-jump-form"> -					<input type="number" name="page-number"  maxlength="6" title="{L_JUMP_PAGE}" class="inputbox tiny" data-per-page="{PER_PAGE}" data-base-url="{BASE_URL|e('html_attr')}" data-start-name="{START_NAME}" /> +					<input type="number" name="page-number" min="1" maxlength="6" title="{L_JUMP_PAGE}" class="inputbox tiny" data-per-page="{PER_PAGE}" data-base-url="{BASE_URL|e('html_attr')}" data-start-name="{START_NAME}" />  					<input class="button2" value="{L_GO}" type="button" />  				</li>  			</ul> diff --git a/phpBB/styles/prosilver/template/search_results.html b/phpBB/styles/prosilver/template/search_results.html index 47aa8d85de..970a7bcdd1 100644 --- a/phpBB/styles/prosilver/template/search_results.html +++ b/phpBB/styles/prosilver/template/search_results.html @@ -8,20 +8,21 @@  <!-- IF SEARCH_TOPIC -->  	<p><a class="arrow-{S_CONTENT_FLOW_BEGIN}" href="{U_SEARCH_TOPIC}">{L_RETURN_TO_TOPIC}</a></p>  <!-- ELSE --> -	<p><a class="arrow-{S_CONTENT_FLOW_BEGIN}" href="{U_SEARCH}" title="{L_SEARCH_ADV}">{L_RETURN_TO_SEARCH_ADV}</a></p> +	<p><a class="arrow-{S_CONTENT_FLOW_BEGIN}" href="{U_SEARCH}" title="{L_SEARCH_ADV}">{L_GO_TO_SEARCH_ADV}</a></p>  <!-- ENDIF --> -<!-- IF .pagination or SEARCH_MATCHES or PAGE_NUMBER --> -	<form method="post" action="{S_SEARCH_ACTION}"> - +<!-- IF .pagination or SEARCH_MATCHES or TOTAL_MATCHES or PAGE_NUMBER -->  	<div class="action-bar top"> -	<!-- IF SEARCH_MATCHES --> +	<!-- IF TOTAL_MATCHES > 0 -->  		<div class="search-box"> -			<!-- IF SEARCH_IN_RESULTS --> -				<label for="add_keywords">{L_SEARCH_IN_RESULTS}{L_COLON} <input type="search" name="add_keywords" id="add_keywords" value="" class="inputbox narrow" /></label> -				<input class="button2" type="submit" name="submit" value="{L_SEARCH}" /> -			<!-- ENDIF --> +			<form method="post" action="{S_SEARCH_ACTION}"> +			<fieldset> +				<input class="inputbox search tiny" type="search" name="add_keywords" id="add_keywords" value="" placeholder="{L_SEARCH_IN_RESULTS}" /> +				<button class="button icon-button search-icon" type="submit" title="{L_SEARCH}">{L_SEARCH}</button> +				<a href="{U_SEARCH}" class="button icon-button search-adv-icon" title="{L_SEARCH_ADV}">{L_SEARCH_ADV}</a> +			</fieldset> +			</form>  		</div>  	<!-- ENDIF --> @@ -34,8 +35,6 @@  			<!-- ENDIF -->  		</div>  	</div> - -	</form>  <!-- ENDIF -->  <!-- IF S_SHOW_TOPICS --> @@ -179,9 +178,9 @@  <div class="action-bar bottom">  	<div class="pagination">  		{SEARCH_MATCHES} -		<!-- IF .pagination -->  +		<!-- IF .pagination -->  			<!-- INCLUDE pagination.html --> -		<!-- ELSE -->  +		<!-- ELSE -->  			 • {PAGE_NUMBER}  		<!-- ENDIF -->  	</div> diff --git a/phpBB/styles/prosilver/template/simple_header.html b/phpBB/styles/prosilver/template/simple_header.html index 610e5d5582..6d22a074be 100644 --- a/phpBB/styles/prosilver/template/simple_header.html +++ b/phpBB/styles/prosilver/template/simple_header.html @@ -3,8 +3,6 @@  <head>  <meta charset="utf-8">  <meta name="viewport" content="width=device-width" /> -<meta name="keywords" content="" /> -<meta name="description" content="" />  {META}  <title>{SITENAME} • <!-- IF S_IN_MCP -->{L_MCP} • <!-- ELSEIF S_IN_UCP -->{L_UCP} • <!-- ENDIF -->{PAGE_TITLE}</title> diff --git a/phpBB/styles/prosilver/template/timezone.js b/phpBB/styles/prosilver/template/timezone.js index e0d3da9ff7..44ec1b0979 100644 --- a/phpBB/styles/prosilver/template/timezone.js +++ b/phpBB/styles/prosilver/template/timezone.js @@ -1,6 +1,8 @@ +/* global phpbb */ +  (function($) { // Avoid conflicts with other libraries -"use strict"; +'use strict';  $('#tz_date').change(function() {  	phpbb.timezoneSwitchDate(false); @@ -10,12 +12,9 @@ $('#tz_select_date_suggest').click(function(){  	phpbb.timezonePreselectSelect(true);  }); -$(document).ready( -	phpbb.timezoneEnableDateSelection -); - -$(document).ready( -	phpbb.timezonePreselectSelect($('#tz_select_date_suggest').attr('timezone-preselect') === 'true') -); +$(function () { +	phpbb.timezoneEnableDateSelection(); +	phpbb.timezonePreselectSelect($('#tz_select_date_suggest').attr('timezone-preselect') === 'true'); +});  })(jQuery); // Avoid conflicts with other libraries diff --git a/phpBB/styles/prosilver/template/ucp_attachments.html b/phpBB/styles/prosilver/template/ucp_attachments.html index ddbf892dee..1d4963273c 100644 --- a/phpBB/styles/prosilver/template/ucp_attachments.html +++ b/phpBB/styles/prosilver/template/ucp_attachments.html @@ -12,7 +12,7 @@  	<!-- IF .attachrow -->  		<div class="action-bar top">  			<div class="pagination"> -				{TOTAL_ATTACHMENTS} {L_TITLE} +				{NUM_ATTACHMENTS}  				<!-- IF .pagination -->   					<!-- INCLUDE pagination.html -->  				<!-- ELSE -->  diff --git a/phpBB/styles/prosilver/template/viewforum_body.html b/phpBB/styles/prosilver/template/viewforum_body.html index e8c50f79b2..4362d50b37 100644 --- a/phpBB/styles/prosilver/template/viewforum_body.html +++ b/phpBB/styles/prosilver/template/viewforum_body.html @@ -50,7 +50,8 @@  			<form method="get" id="forum-search" action="{S_SEARCHBOX_ACTION}">  			<fieldset>  				<input class="inputbox search tiny" type="search" name="keywords" id="search_keywords" size="20" placeholder="{L_SEARCH_FORUM}" /> -				<input class="button2" type="submit" value="{L_SEARCH}" /> +				<button class="button icon-button search-icon" type="submit" title="{L_SEARCH}">{L_SEARCH}</button> +				<a href="{U_SEARCH}" class="button icon-button search-adv-icon" title="{L_SEARCH_ADV}">{L_SEARCH_ADV}</a>  				{S_SEARCH_LOCAL_HIDDEN_FIELDS}  			</fieldset>  			</form> diff --git a/phpBB/styles/prosilver/template/viewtopic_body.html b/phpBB/styles/prosilver/template/viewtopic_body.html index 7ed8569798..4463f6dfc0 100644 --- a/phpBB/styles/prosilver/template/viewtopic_body.html +++ b/phpBB/styles/prosilver/template/viewtopic_body.html @@ -42,7 +42,8 @@  			<form method="get" id="topic-search" action="{S_SEARCHBOX_ACTION}">  			<fieldset>  				<input class="inputbox search tiny"  type="search" name="keywords" id="search_keywords" size="20" placeholder="{L_SEARCH_TOPIC}" /> -				<input class="button2" type="submit" value="{L_SEARCH}" /> +				<button class="button icon-button search-icon" type="submit" title="{L_SEARCH}">{L_SEARCH}</button> +				<a href="{U_SEARCH}" class="button icon-button search-adv-icon" title="{L_SEARCH_ADV}">{L_SEARCH_ADV}</a>  				{S_SEARCH_LOCAL_HIDDEN_FIELDS}  			</fieldset>  			</form> @@ -137,7 +138,7 @@  			<!-- IF postrow.RANK_TITLE or postrow.RANK_IMG --><dd class="profile-rank">{postrow.RANK_TITLE}<!-- IF postrow.RANK_TITLE and postrow.RANK_IMG --><br /><!-- ENDIF -->{postrow.RANK_IMG}</dd><!-- ENDIF --> -		<!-- IF postrow.POSTER_POSTS != '' --><dd class="profile-posts"><strong>{L_POSTS}{L_COLON}</strong> {postrow.POSTER_POSTS}</dd><!-- ENDIF --> +		<!-- IF postrow.POSTER_POSTS != '' --><dd class="profile-posts"><strong>{L_POSTS}{L_COLON}</strong> <!-- IF postrow.U_SEARCH !== '' --><a href="{postrow.U_SEARCH}"><!-- ENDIF -->{postrow.POSTER_POSTS}<!-- IF postrow.U_SEARCH !== '' --></a><!-- ENDIF --></dd><!-- ENDIF -->  		<!-- IF postrow.POSTER_JOINED --><dd class="profile-joined"><strong>{L_JOINED}{L_COLON}</strong> {postrow.POSTER_JOINED}</dd><!-- ENDIF -->  		<!-- IF postrow.POSTER_WARNINGS --><dd class="profile-warnings"><strong>{L_WARNINGS}{L_COLON}</strong> {postrow.POSTER_WARNINGS}</dd><!-- ENDIF --> diff --git a/phpBB/styles/prosilver/theme/bidi.css b/phpBB/styles/prosilver/theme/bidi.css index 46fbbadef7..65123af4e5 100644 --- a/phpBB/styles/prosilver/theme/bidi.css +++ b/phpBB/styles/prosilver/theme/bidi.css @@ -25,24 +25,8 @@  	padding: 10px 10px 0 13px;  } -/* Search box +/* Site Description  --------------------------------------------- */ -.rtl #search-box { -	float: left; -	text-align: left; -	margin-right: 0; -	margin-left: 5px; -} - -.rtl #search-box li { -	text-align: left; -} - -.rtl #search-box img { -	margin-right: 0; -	margin-left: 3px; -} -  .rtl #site-description {  	float: right;  } @@ -643,6 +627,11 @@ li.breadcrumbs span:first-child > a {  	float: right;  } +.rtl .buttons .button, .rtl .dropdown-select { +	margin-left: 5px; +	margin-right: 0; +} +  /* Icon images  ---------------------------------------- */  .rtl .small-icon { @@ -947,16 +936,40 @@ li.breadcrumbs span:first-child > a {  	float: left;  } -/* Form button styles +/* Search box  ---------------------------------------- */  /* Topic and forum Search */  .rtl .search-box { -	margin-right: 5px; -	margin-left: 0;  	float: right;  } +.rtl .search-box .inputbox { +	border-left-width: 0; +	border-right-width: 1px; +	border-radius: 0 4px 4px 0; +	float: right; +	padding: 3px; +} + +.rtl .search-box .button { +	float: right; +} + +.rtl .search-box a.button { +	border-left-width: 1px; +	border-right-width: 0; +	border-radius: 4px 0 0 4px; +	padding-left: 5px; +	padding-right: 3px; +} + +.rtl .search-header { +	float: left; +	margin-right: 0; +	margin-left: 5px; +} +  .rtl input.search {  	background-position: right 1px;  	padding-right: 17px; @@ -967,6 +980,10 @@ li.breadcrumbs span:first-child > a {  * tweaks.css  */ + +/* Form button styles +---------------------------------------- */ +  /** Reference: Bug #27155 */  .rtl #wrap, .rtl .headerbar, .rtl #site-description, .rtl .navbar {  	position: relative; diff --git a/phpBB/styles/prosilver/theme/buttons.css b/phpBB/styles/prosilver/theme/buttons.css index a08b49a81c..d600e76b44 100644 --- a/phpBB/styles/prosilver/theme/buttons.css +++ b/phpBB/styles/prosilver/theme/buttons.css @@ -85,7 +85,7 @@  	font-size: 0;  } -.tools-icon:before, .modtools-icon:before { +.tools-icon:before, .modtools-icon:before, .search-icon:before, .search-adv-icon:before {  	background-position: -80px 0;  	height: 16px;  	margin-top: 2px; @@ -95,6 +95,12 @@  .dropdown-visible .tools-icon:before,  .nojs .dropdown-container:hover .tools-icon:before			{ background-position: -80px -20px; } +.search-icon:before											{ background-position: -245px 0; } +.search-icon:hover:before									{ background-position: -245px -20px; } + +.search-adv-icon:before										{ background-position: -265px 0; } +.search-adv-icon:hover:before								{ background-position: -265px -20px; } +  .modtools-icon:before										{ background-position: -225px 0; }  .dropdown-visible .modtools-icon:before,  .nojs .dropdown-container:hover .modtools-icon:before		{ background-position: -225px -20px; } @@ -239,3 +245,9 @@ ul.linklist.bulletin > li.small-icon:before {  .hasjs .postbody .post-buttons {  	max-width: 40%;  } + +/* Browser-specific tweaks */ +button::-moz-focus-inner { +	padding: 0; +	border: 0 +} diff --git a/phpBB/styles/prosilver/theme/colours.css b/phpBB/styles/prosilver/theme/colours.css index df27467cf8..505b18288b 100644 --- a/phpBB/styles/prosilver/theme/colours.css +++ b/phpBB/styles/prosilver/theme/colours.css @@ -29,16 +29,15 @@ hr {  /* Search box  --------------------------------------------- */ -#search-box { -	color: #FFFFFF; -} - -#search-box #keywords { -	background-color: #FFF; +.search-box .inputbox, +.search-box .inputbox:hover, +.search-box .inputbox:focus, +.search-box .button:hover { +	border-color: #C7C3BF;  } -#search-box input { -	border-color: #0075B0; +.search-header { +	box-shadow: 0 0 10px #0075B0;  }  /* Round cornered boxes and backgrounds @@ -249,11 +248,11 @@ a { color: #105289; }  a:hover	{ color: #D31141; }  /* Links on gradient backgrounds */ -#search-box a, .navbg a, .forumbg .header a, .forabg .header a, th a { +.forumbg .header a, .forabg .header a, th a {  	color: #FFFFFF;  } -#search-box a:hover, .navbg a:hover, .forumbg .header a:hover, .forabg .header a:hover, th a:hover { +.forumbg .header a:hover, .forabg .header a:hover, th a:hover {  	color: #A8D8FF;  } diff --git a/phpBB/styles/prosilver/theme/common.css b/phpBB/styles/prosilver/theme/common.css index a3a4157704..090046f54f 100644 --- a/phpBB/styles/prosilver/theme/common.css +++ b/phpBB/styles/prosilver/theme/common.css @@ -212,45 +212,10 @@ ol ol ul, ol ul ul, ul ol ul, ul ul ul {  	text-decoration: none;  } -/* Search box ---------------------------------------------- */ -#search-box { -	position: relative; -	margin-top: 30px; -	margin-right: 5px; -	display: block; -	float: right; -	text-align: right; -	white-space: nowrap; /* For Opera */ -} - -#search-box #keywords { -	width: 95px; -} - -#search-box input { -	border: 1px solid transparent; -} - -/* .button1 style defined later, just a few tweaks for the search button version */ -#search-box input.button1 { -	padding: 1px 5px; -} - -#search-box li { -	text-align: right; -	margin-top: 4px; -} - -#search-box img { -	vertical-align: middle; -	margin-right: 3px; -} -  /* Site description and logo */  #site-description {  	float: left; -	width: 70%; +	width: 65%;  }  #site-description h1 { @@ -1117,7 +1082,7 @@ ul.linklist:after,  .action-bar:after,  .notification_text:after,  .tabs-container:after, -#tabs > ul:after,  +#tabs > ul:after,  #minitabs > ul:after,  .postprofile .avatar-container:after {  	clear: both; diff --git a/phpBB/styles/prosilver/theme/content.css b/phpBB/styles/prosilver/theme/content.css index fa23a665f1..9388496c53 100644 --- a/phpBB/styles/prosilver/theme/content.css +++ b/phpBB/styles/prosilver/theme/content.css @@ -736,6 +736,10 @@ fieldset.polls dd div {  	max-width: 100%;  } +.postprofile .profile-posts a { +	font-weight: normal; +} +  dd.profile-warnings {  	font-weight: bold;  } diff --git a/phpBB/styles/prosilver/theme/forms.css b/phpBB/styles/prosilver/theme/forms.css index f0effa01c4..f08a8a9691 100644 --- a/phpBB/styles/prosilver/theme/forms.css +++ b/phpBB/styles/prosilver/theme/forms.css @@ -129,6 +129,10 @@ dd select {  	width: auto;  } +dd select[multiple] { +	width: 100%; +} +  dd textarea {  	width: 85%;  } @@ -289,6 +293,10 @@ input[type="search"]::-webkit-search-decoration, input[type="search"]::-webkit-s  	display: none;  } +input[type="search"]::-webkit-search-cancel-button { +	cursor: pointer; +} +  /* Form button styles  ---------------------------------------- */  input.button1, input.button2 { @@ -352,12 +360,62 @@ input.button1:focus, input.button2:focus, input.button3:focus {  /* Topic and forum Search */  .search-box { -	margin-top: 3px; -	margin-left: 5px;  	float: left;  } -.search-box input { +.search-box .inputbox { +	background-image: none; +	border-right-width: 0; +	border-radius: 4px 0 0 4px; +	float: left; +	height: 24px; +	padding: 3px; +	-webkit-box-sizing: border-box; +	-moz-box-sizing: border-box; +	box-sizing: border-box; +} + +.search-box button { +	float: left; +} + +.search-box button.search-icon { +	border-radius: 0; +	font-size: 0; +	height: 24px; +	margin: 0; +	padding: 3px 5px; +} + +.search-box a.button { +	border-left-width: 0; +	border-radius: 0 4px 4px 0; +	font-size: 0; +	margin: 0; +	padding: 2px 5px 2px 3px; +} + +/* Search box (header) +--------------------------------------------- */ +.search-header { +	border-radius: 4px; +	display: block; +	float: right; +	margin-right: 5px; +	margin-top: 30px; +} + +.search-header .inputbox { border: 0; } + +.search-header button { +	border-top: 0; +	border-bottom: 0; +} + +.search-header a.button { +	border: 0; +	border-left: 1px; +	padding: 3px 5px 3px 4px;  }  input.search { @@ -371,4 +429,3 @@ input.search {  .medium { width: 50%;}  .narrow { width: 25%;}  .tiny { width: 10%;} - diff --git a/phpBB/styles/prosilver/theme/images/icons_button.png b/phpBB/styles/prosilver/theme/images/icons_button.pngBinary files differ index da9ae6f1b4..50ac8994de 100644 --- a/phpBB/styles/prosilver/theme/images/icons_button.png +++ b/phpBB/styles/prosilver/theme/images/icons_button.png diff --git a/phpBB/styles/prosilver/theme/links.css b/phpBB/styles/prosilver/theme/links.css index 9b5c00d9b6..a2f512443c 100644 --- a/phpBB/styles/prosilver/theme/links.css +++ b/phpBB/styles/prosilver/theme/links.css @@ -18,11 +18,11 @@ a:hover	{ text-decoration: underline; }  }  /* Links on gradient backgrounds */ -#search-box a, .navbg a, .forumbg .header a, .forabg .header a, th a { +.forumbg .header a, .forabg .header a, th a {  	text-decoration: none;  } -#search-box a:hover, .navbg a:hover, .forumbg .header a:hover, .forabg .header a:hover, th a:hover { +.forumbg .header a:hover, .forabg .header a:hover, th a:hover {  	text-decoration: underline;  } diff --git a/phpBB/styles/prosilver/theme/responsive.css b/phpBB/styles/prosilver/theme/responsive.css index fc39e03da7..ed3ba61334 100644 --- a/phpBB/styles/prosilver/theme/responsive.css +++ b/phpBB/styles/prosilver/theme/responsive.css @@ -60,7 +60,7 @@ body {  	text-overflow: ellipsis;  } -#site-description p, #search-box { +#site-description p, .search-header {  	display: none;  } @@ -161,8 +161,7 @@ ul.topiclist.forums dd.topics dfn, ul.topiclist.topics dd.posts dfn {  	font-weight: normal;  } -@media only screen and (max-width: 550px), only screen and (max-device-width: 550px) -{ +@media only screen and (max-width: 550px), only screen and (max-device-width: 550px) {  	ul.topiclist.forums dt {  		margin-right: 0;  	} @@ -191,8 +190,7 @@ ul.topiclist li.row dt a.subforum {  /* Notifications list  ----------------------------------------*/ -@media only screen and (max-width: 350px), only screen and (max-device-width: 350px) -{ +@media only screen and (max-width: 350px), only screen and (max-device-width: 350px) {  	.dropdown-extended .dropdown-contents {  		width: auto;  	} @@ -344,15 +342,23 @@ fieldset.quick-login label[for="autologin"] {  	min-width: 50%;  } -@media only screen and (max-width: 500px), only screen and (max-device-width: 500px) -{ +@media only screen and (max-width: 500px), only screen and (max-device-width: 500px) { +	dd label { +		white-space: normal; +	} +  	select, .inputbox {  		max-width: 260px;  	}  } -@media only screen and (max-width: 320px), only screen and (max-device-width: 320px) -{ +@media only screen and (max-width: 430px), only screen and (max-device-width: 430px) { +	.section-viewtopic .search-box .inputbox { +		width: 110px; +	} +} + +@media only screen and (max-width: 320px), only screen and (max-device-width: 320px) {  	select, .inputbox {  		max-width: 240px;  	} @@ -365,8 +371,7 @@ fieldset.quick-login label[for="autologin"] {  	width: auto;  } -@media only screen and (max-width: 500px), only screen and (max-device-width: 500px) -{ +@media only screen and (max-width: 500px), only screen and (max-device-width: 500px) {  	dl.details dt, dl.details dd {  		width: auto;  		float: none; @@ -506,14 +511,17 @@ fieldset.display-actions {  	width: 100%;  } -@media only screen and (max-width: 500px), only screen and (max-device-width: 500px) -{ +@media only screen and (max-width: 500px), only screen and (max-device-width: 500px) {  	p.responsive-center {  		float: none;  		text-align: center; -		margin: 0; +		margin-bottom: 5px;  	} +	.action-bar > div { +		margin-bottom: 5px; + 	} +  	.action-bar > .pagination {  		float: none;  		clear: both; @@ -525,7 +533,7 @@ fieldset.display-actions {  		margin: 0 2px;  	} -	.action-bar > div.search-box, p.jumpbox-return { +	p.jumpbox-return {  		display: none;  	} diff --git a/phpBB/styles/prosilver/theme/tweaks.css b/phpBB/styles/prosilver/theme/tweaks.css index 851b3a6bb6..d2dad9e299 100644 --- a/phpBB/styles/prosilver/theme/tweaks.css +++ b/phpBB/styles/prosilver/theme/tweaks.css @@ -1,78 +1,29 @@  /* Style Sheet Tweaks -These style definitions are IE 7 and 8 specific -tweaks required due to its poor CSS support. --------------------------------------------------*/ +These style definitions are IE 8 & 9 only. +They are required due to the poor CSS support in IE browsers. +------------------------------------------------------------------------------*/ -/* Clear float fix for IE7 */ -.inner { -	zoom: 1; -} +/* IE 8 Tweaks (value)\9 equates to  IE <= 8 +------------------------------------------------------------------------------*/ -ul.linklist { -	zoom: 1; -} +/* Clear float fix */ +.inner, ul.linklist { zoom: 1\9; }  /* Align checkboxes/radio buttons nicely */ -dd label input { -	vertical-align: text-bottom; -	*vertical-align: middle; -} - -/* Simple fix so forum and topic lists always have a height set */ -dl.icon { -	*height: 35px; -} - -/* Correctly clear floating for details on profile view */ -dl.details dd { -	*margin-left: 30%; -	*float: none; -} - -/* Headerbar height fix for IE7 */ -#site-description p { -	*margin-bottom: 1.0em; -} +dd label input { vertical-align: text-bottom\9; } -/* Forum list column styles for IE7 */ -dl.icon dt, dl.icon dd { -	*min-height: 32px; -} - -dd.posts, dd.topics, dd.views, dd.extra, dd.mark { -	*width: 79px; -} +/* Fixes header-avatar aspect-ratio */ +.header-avatar img { height: 20px\9; } -dd.lastpost, dd.redirect, dd.moderation, dd.time, dd.info { -	*width: 249px; -} - -dd.option { -	*width: 124px; -} - -/* Notifications list for IE7 */ -.dropdown-extended { -	*left: 0; -} - -.dropdown-extended .header_settings { -	*position: absolute; -	*right: 10px; -	*top: 0; -} +/* IE8 often can't handle max-width in %, so we use px instead */ +.postprofile .avatar img { max-width: 150px\9; } -.icon-notification { -	*z-index: 2; -} -/* Fixes header-avatar aspect-ratio in IE8 */ -.header-avatar img { -	height: 20px; -} +/* IE 9 Tweaks +------------------------------------------------------------------------------*/ -/* IE8 often can't handle max-width in %, so we use px instead */ -.postprofile .avatar img { -	max-width: 150px;  +/* Border-radius bleed fix in IE9 */ +.search-header, .search-header .inputbox, .search-header a.button { +	border-radius: 0;  } diff --git a/phpBB/styles/subsilver2/style.cfg b/phpBB/styles/subsilver2/style.cfg index 3ef3154742..0c0bd04456 100644 --- a/phpBB/styles/subsilver2/style.cfg +++ b/phpBB/styles/subsilver2/style.cfg @@ -21,8 +21,8 @@  # General Information about this style  name = subsilver2  copyright = © 2005 phpBB Limited -style_version = 3.1.0-RC3 -phpbb_version = 3.1.0-RC3 +style_version = 3.1.0-RC4 +phpbb_version = 3.1.0-RC4  # Defining a different template bitfield  # template_bitfield = lNg= diff --git a/phpBB/styles/subsilver2/template/overall_header.html b/phpBB/styles/subsilver2/template/overall_header.html index ebb7b3be4d..4741154889 100644 --- a/phpBB/styles/subsilver2/template/overall_header.html +++ b/phpBB/styles/subsilver2/template/overall_header.html @@ -2,8 +2,6 @@  <html dir="{S_CONTENT_DIRECTION}" lang="{S_USER_LANG}">  <head>  <meta charset="utf-8"> -<meta name="keywords" content="" /> -<meta name="description" content="" />  {META}  <title><!-- IF UNREAD_NOTIFICATIONS_COUNT -->({UNREAD_NOTIFICATIONS_COUNT}) <!-- ENDIF --><!-- IF not S_VIEWTOPIC and not S_VIEWFORUM -->{SITENAME} - <!-- ENDIF --><!-- IF S_IN_MCP -->{L_MCP} - <!-- ELSEIF S_IN_UCP -->{L_UCP} - <!-- ENDIF -->{PAGE_TITLE}<!-- IF S_VIEWTOPIC or S_VIEWFORUM --> - {SITENAME}<!-- ENDIF --></title> diff --git a/phpBB/styles/subsilver2/template/simple_header.html b/phpBB/styles/subsilver2/template/simple_header.html index 0c3dff4a05..d292c4594a 100644 --- a/phpBB/styles/subsilver2/template/simple_header.html +++ b/phpBB/styles/subsilver2/template/simple_header.html @@ -2,8 +2,6 @@  <html dir="{S_CONTENT_DIRECTION}" lang="{S_USER_LANG}">  <head>  <meta charset="utf-8"> -<meta name="keywords" content="" /> -<meta name="description" content="" />  {META}  <title>{SITENAME} • <!-- IF S_IN_MCP -->{L_MCP} • <!-- ELSEIF S_IN_UCP -->{L_UCP} • <!-- ENDIF -->{PAGE_TITLE}</title> diff --git a/phpBB/styles/subsilver2/template/ucp_attachments.html b/phpBB/styles/subsilver2/template/ucp_attachments.html index 0f6101aac7..c513f933c0 100644 --- a/phpBB/styles/subsilver2/template/ucp_attachments.html +++ b/phpBB/styles/subsilver2/template/ucp_attachments.html @@ -17,7 +17,7 @@  				<table width="100%" cellspacing="1">  				<tr>  					<td class="nav" valign="middle" nowrap="nowrap"> {PAGE_NUMBER}<br /></td> -					<td class="gensmall" nowrap="nowrap"> [ {TOTAL_ATTACHMENTS} ] </td> +					<td class="gensmall" nowrap="nowrap"> [ {NUM_ATTACHMENTS} ] </td>  					<td class="gensmall" width="100%" align="{S_CONTENT_FLOW_END}" nowrap="nowrap"><!-- INCLUDE pagination.html --></td>  				</tr>  				</table> diff --git a/phpBB/viewforum.php b/phpBB/viewforum.php index 9ecbdea77a..6379da6802 100644 --- a/phpBB/viewforum.php +++ b/phpBB/viewforum.php @@ -251,7 +251,7 @@ $s_watching_forum = array(  	'is_watching'	=> false,  ); -if (($config['email_enable'] || $config['jab_enable']) && $config['allow_forum_notify'] && $forum_data['forum_type'] == FORUM_POST && ($auth->acl_get('f_subscribe', $forum_id) || $user->data['user_id'] == ANONYMOUS)) +if ($config['allow_forum_notify'] && $forum_data['forum_type'] == FORUM_POST && ($auth->acl_get('f_subscribe', $forum_id) || $user->data['user_id'] == ANONYMOUS))  {  	$notify_status = (isset($forum_data['notify_status'])) ? $forum_data['notify_status'] : NULL;  	watch_topic_forum('forum', $s_watching_forum, $user->data['user_id'], $forum_id, 0, $notify_status, $start, $forum_data['forum_name']); @@ -392,10 +392,15 @@ $sql_array = array(  * Event to modify the SQL query before the topic data is retrieved  *  * @event core.viewforum_get_topic_data -* @var	array	sql_array		The SQL array to get the data of all topics +* @var	array	forum_data			Array with forum data +* @var	array	sql_array			The SQL array to get the data of all topics  * @since 3.1.0-a1 +* @change 3.1.0-RC4 Added forum_data var   */ -$vars = array('sql_array'); +$vars = array( +	'forum_data', +	'sql_array', +);  extract($phpbb_dispatcher->trigger_event('core.viewforum_get_topic_data', compact($vars)));  $sql_approved = ' AND ' . $phpbb_content_visibility->get_visibility_sql('topic', $forum_id, 't.'); @@ -533,13 +538,46 @@ else  }  // Grab just the sorted topic ids -$sql = 'SELECT t.topic_id -	FROM ' . TOPICS_TABLE . " t -	WHERE $sql_where +$sql_ary = array( +	'SELECT'	=> 't.topic_id', +	'FROM'		=> array( +		TOPICS_TABLE => 't', +	), +	'WHERE'		=> "$sql_where  		AND t.topic_type IN (" . POST_NORMAL . ', ' . POST_STICKY . ")  		$sql_approved -		$sql_limit_time -	ORDER BY t.topic_type " . ((!$store_reverse) ? 'DESC' : 'ASC') . ', ' . $sql_sort_order; +		$sql_limit_time", +	'ORDER_BY'	=> 't.topic_type ' . ((!$store_reverse) ? 'DESC' : 'ASC') . ', ' . $sql_sort_order, +); + +/** +* Event to modify the SQL query before the topic ids data is retrieved +* +* @event core.viewforum_get_topic_ids_data +* @var	array	sql_ary			SQL query array to get the topic ids data +* @var	string	sql_approved	Topic visibility SQL string +* @var	int		sql_limit		Number of records to select +* @var	string	sql_limit_time	SQL string to limit topic_last_post_time data +* @var	array	sql_sort_order	SQL sorting string +* @var	int		sql_start		Offset point to start selection from +* @var	string	sql_where		SQL WHERE clause string +* @var	bool	store_reverse	Flag indicating if we select from the late pages +* +* @since 3.1.0-RC4 +*/ +$vars = array( +	'sql_ary', +	'sql_approved', +	'sql_limit', +	'sql_limit_time', +	'sql_sort_order', +	'sql_start', +	'sql_where', +	'store_reverse', +); +extract($phpbb_dispatcher->trigger_event('core.viewforum_get_topic_ids_data', compact($vars))); + +$sql = $db->sql_build_query('SELECT', $sql_ary);  $result = $db->sql_query_limit($sql, $sql_limit, $sql_start);  while ($row = $db->sql_fetchrow($result)) diff --git a/phpBB/viewonline.php b/phpBB/viewonline.php index a03a81a15e..9589fb54e2 100644 --- a/phpBB/viewonline.php +++ b/phpBB/viewonline.php @@ -372,7 +372,7 @@ while ($row = $db->sql_fetchrow($result))  	$vars = array('on_page', 'row', 'location', 'location_url', 'forum_data');  	extract($phpbb_dispatcher->trigger_event('core.viewonline_overwrite_location', compact($vars))); -	$template->assign_block_vars('user_row', array( +	$template_row = array(  		'USERNAME' 			=> $row['username'],  		'USERNAME_COLOUR'	=> $row['user_colour'],  		'USERNAME_FULL'		=> $username_full, @@ -389,7 +389,22 @@ while ($row = $db->sql_fetchrow($result))  		'S_USER_HIDDEN'		=> $s_user_hidden,  		'S_GUEST'			=> ($row['user_id'] == ANONYMOUS) ? true : false,  		'S_USER_TYPE'		=> $row['user_type'], -	)); +	); + +	/** +	* Modify viewonline template data before it is displayed in the list +	* +	* @event core.viewonline_modify_user_row +	* @var	array	on_page			File name and query string +	* @var	array	row				Array with the users sql row +	* @var	array	forum_data		Array with forum data +	* @var	array	template_row	Array with template variables for the user row +	* @since 3.1.0-RC4 +	*/ +	$vars = array('on_page', 'row', 'forum_data', 'template_row'); +	extract($phpbb_dispatcher->trigger_event('core.viewonline_modify_user_row', compact($vars))); + +	$template->assign_block_vars('user_row', $template_row);  }  $db->sql_freeresult($result);  unset($prev_id, $prev_ip); diff --git a/phpBB/viewtopic.php b/phpBB/viewtopic.php index 3c837bd136..f8b4a54f05 100644 --- a/phpBB/viewtopic.php +++ b/phpBB/viewtopic.php @@ -449,7 +449,7 @@ $s_watching_topic = array(  	'is_watching'	=> false,  ); -if (($config['email_enable'] || $config['jab_enable']) && $config['allow_topic_notify']) +if ($config['allow_topic_notify'])  {  	$notify_status = (isset($topic_data['notify_status'])) ? $topic_data['notify_status'] : null;  	watch_topic_forum('topic', $s_watching_topic, $user->data['user_id'], $forum_id, $topic_id, $notify_status, $start, $topic_data['topic_title']); diff --git a/tests/bootstrap.php b/tests/bootstrap.php index bb4a703cc3..40c6ef7dfa 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -19,6 +19,7 @@ require_once $phpbb_root_path . 'includes/startup.php';  $table_prefix = 'phpbb_';  require_once $phpbb_root_path . 'includes/constants.php';  require_once $phpbb_root_path . 'phpbb/class_loader.' . $phpEx; +require_once($phpbb_root_path . 'includes/utf/utf_tools.' . $phpEx);  $phpbb_class_loader_mock = new \phpbb\class_loader('phpbb_mock_', $phpbb_root_path . '../tests/mock/', "php");  $phpbb_class_loader_mock->register(); diff --git a/tests/controller/common_helper_route.php b/tests/controller/common_helper_route.php new file mode 100644 index 0000000000..1751578a75 --- /dev/null +++ b/tests/controller/common_helper_route.php @@ -0,0 +1,411 @@ +<?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. +* +*/ + +require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; + +use Symfony\Component\Routing\Generator\UrlGeneratorInterface; + +abstract class phpbb_controller_common_helper_route extends phpbb_test_case +{ +	protected $root_path; + +	public function setUp() +	{ +		global $phpbb_dispatcher, $phpbb_root_path, $phpEx; + +		$this->extension_manager = new phpbb_mock_extension_manager( +			dirname(__FILE__) . '/', +			array( +				'vendor2/foo' => array( +					'ext_name' => 'vendor2/foo', +					'ext_active' => '1', +					'ext_path' => 'ext/vendor2/foo/', +				), +			) +		); +		$this->generate_route_objects(); +		$phpbb_dispatcher = new phpbb_mock_event_dispatcher; +		$this->user = new \phpbb\user('\phpbb\datetime'); + +		$this->config = new \phpbb\config\config(array('enable_mod_rewrite' => '0')); +		$this->template = new phpbb\template\twig\twig($this->phpbb_path_helper, $this->config, $this->user, new \phpbb\template\context()); +	} + +	protected function get_phpbb_root_path() +	{ +		return ''; +	} + +	protected function get_uri() +	{ +		return '/app.php'; +	} + +	protected function get_script_name() +	{ +		return 'app.php'; +	} + +	protected function generate_route_objects() +	{ +		$request = new phpbb_mock_request(); +		$request->overwrite('SCRIPT_NAME', $this->get_uri(), \phpbb\request\request_interface::SERVER); +		$request->overwrite('SCRIPT_FILENAME', $this->get_script_name(), \phpbb\request\request_interface::SERVER); +		$request->overwrite('REQUEST_URI', $this->get_uri(), \phpbb\request\request_interface::SERVER); +		$request->overwrite('SERVER_NAME', 'localhost', \phpbb\request\request_interface::SERVER); +		$request->overwrite('SERVER_PORT', '80', \phpbb\request\request_interface::SERVER); + +		$this->symfony_request = new \phpbb\symfony_request( +			$request +		); +		$this->filesystem = new \phpbb\filesystem(); +		$this->phpbb_path_helper = new \phpbb\path_helper( +			$this->symfony_request, +			$this->filesystem, +			$this->getMock('\phpbb\request\request'), +			$phpbb_root_path, +			$phpEx +		); + +		$finder = new \phpbb\finder( +			new \phpbb\filesystem(), +			dirname(__FILE__) . '/', +			new phpbb_mock_cache() +		); +		$finder->set_extensions(array_keys($this->extension_manager->all_enabled())); +		$this->provider = new \phpbb\controller\provider(); +		$this->provider->find_routing_files($finder); +		$this->provider->find(dirname(__FILE__) . '/'); +		// Set correct current phpBB root path +		$this->root_path = $this->get_phpbb_root_path(); +	} + +	public function helper_url_data_no_rewrite() +	{ +		return array( +			array('controller2', array('t' => 1, 'f' => 2), true, false, '/app.php/foo/bar?t=1&f=2', 'parameters in params-argument as array'), +			array('controller2', array('t' => 1, 'f' => 2), false, false, '/app.php/foo/bar?t=1&f=2', 'parameters in params-argument as array'), +			array('controller3', array('p' => 3, 't' => 1, 'f' => 2), true, false, '/app.php/foo/bar/p-3?t=1&f=2', 'parameters in params-argument as array'), +			array('controller3', array('p' => 3, 't' => 1, 'f' => 2), false, false, '/app.php/foo/bar/p-3?t=1&f=2', 'parameters in params-argument as array'), + +			// Custom sid parameter +			array('controller2', array('t' => 1, 'f' => 2), true, 'custom-sid', '/app.php/foo/bar?t=1&f=2&sid=custom-sid', 'params-argument (array) using session_id'), +			array('controller2', array('t' => 1, 'f' => 2), false, 'custom-sid', '/app.php/foo/bar?t=1&f=2&sid=custom-sid', 'params-argument (array) using session_id'), +			array('controller3', array('p' => 3, 't' => 1, 'f' => 2), true, 'custom-sid', '/app.php/foo/bar/p-3?t=1&f=2&sid=custom-sid', 'params-argument (array) using session_id'), + +			// Testing anchors +			array('controller2', array('t' => 1, 'f' => 2, '#' => 'anchor'), true, false, '/app.php/foo/bar?t=1&f=2#anchor', 'anchor in params-argument (array)'), +			array('controller2', array('t' => 1, 'f' => 2, '#' => 'anchor'), false, false, '/app.php/foo/bar?t=1&f=2#anchor', 'anchor in params-argument (array)'), +			array('controller3', array('p' => 3, 't' => 1, 'f' => 2, '#' => 'anchor'), true, false, '/app.php/foo/bar/p-3?t=1&f=2#anchor', 'anchor in params-argument (array)'), + +			// Anchors and custom sid +			array('controller2', array('t' => 1, 'f' => 2, '#' => 'anchor'), true, 'custom-sid', '/app.php/foo/bar?t=1&f=2&sid=custom-sid#anchor', 'anchor in params-argument (array) using session_id'), +			array('controller2', array('t' => 1, 'f' => 2, '#' => 'anchor'), false, 'custom-sid', '/app.php/foo/bar?t=1&f=2&sid=custom-sid#anchor', 'anchor in params-argument (array) using session_id'), +			array('controller3', array('p' => 3, 't' => 1, 'f' => 2, '#' => 'anchor'), true, 'custom-sid', '/app.php/foo/bar/p-3?t=1&f=2&sid=custom-sid#anchor', 'anchor in params-argument (array) using session_id'), + +			// Empty parameters should not append the & or ? +			array('controller2', array(), true, false, '/app.php/foo/bar', 'no params using empty array'), +			array('controller2', array(), false, false, '/app.php/foo/bar', 'no params using empty array'), +			array('controller3', array('p' => 3), true, false, '/app.php/foo/bar/p-3', 'no params using empty array'), +		); +	} + +	/** +	* @dataProvider helper_url_data_no_rewrite() +	*/ +	public function test_helper_url_no_rewrite($route, $params, $is_amp, $session_id, $expected, $description) +	{ +		$this->helper = new phpbb_mock_controller_helper($this->template, $this->user, $this->config, $this->provider, $this->extension_manager, $this->symfony_request, $this->filesystem, $this->root_path, 'php', dirname(__FILE__) . '/'); +		$this->assertEquals($expected, $this->helper->route($route, $params, $is_amp, $session_id)); +	} + +	public function helper_url_data_with_rewrite() +	{ +		return array( +			array('controller2', array('t' => 1, 'f' => 2), true, false, '/foo/bar?t=1&f=2', 'parameters in params-argument as array'), +			array('controller2', array('t' => 1, 'f' => 2), false, false, '/foo/bar?t=1&f=2', 'parameters in params-argument as array'), +			array('controller3', array('p' => 3, 't' => 1, 'f' => 2), true, false, '/foo/bar/p-3?t=1&f=2', 'parameters in params-argument as array'), +			array('controller3', array('p' => 3, 't' => 1, 'f' => 2), false, false, '/foo/bar/p-3?t=1&f=2', 'parameters in params-argument as array'), + +			// Custom sid parameter +			array('controller2', array('t' => 1, 'f' => 2), true, 'custom-sid', '/foo/bar?t=1&f=2&sid=custom-sid', 'params-argument (array) using session_id'), +			array('controller2', array('t' => 1, 'f' => 2), false, 'custom-sid', '/foo/bar?t=1&f=2&sid=custom-sid', 'params-argument (array) using session_id'), +			array('controller3', array('p' => 3, 't' => 1, 'f' => 2), true, 'custom-sid', '/foo/bar/p-3?t=1&f=2&sid=custom-sid', 'params-argument (array) using session_id'), + +			// Testing anchors +			array('controller2', array('t' => 1, 'f' => 2, '#' => 'anchor'), true, false, '/foo/bar?t=1&f=2#anchor', 'anchor in params-argument (array)'), +			array('controller2', array('t' => 1, 'f' => 2, '#' => 'anchor'), false, false, '/foo/bar?t=1&f=2#anchor', 'anchor in params-argument (array)'), +			array('controller3', array('p' => 3, 't' => 1, 'f' => 2, '#' => 'anchor'), true, false, '/foo/bar/p-3?t=1&f=2#anchor', 'anchor in params-argument (array)'), + +			// Anchors and custom sid +			array('controller2', array('t' => 1, 'f' => 2, '#' => 'anchor'), true, 'custom-sid', '/foo/bar?t=1&f=2&sid=custom-sid#anchor', 'anchor in params-argument (array) using session_id'), +			array('controller2', array('t' => 1, 'f' => 2, '#' => 'anchor'), false, 'custom-sid', '/foo/bar?t=1&f=2&sid=custom-sid#anchor', 'anchor in params-argument (array) using session_id'), +			array('controller3', array('p' => 3, 't' => 1, 'f' => 2, '#' => 'anchor'), true, 'custom-sid', '/foo/bar/p-3?t=1&f=2&sid=custom-sid#anchor', 'anchor in params-argument (array) using session_id'), + +			// Empty parameters should not append the & or ? +			array('controller2', array(), true, false, '/foo/bar', 'no params using empty array'), +			array('controller2', array(), false, false, '/foo/bar', 'no params using empty array'), +			array('controller3', array('p' => 3), true, false, '/foo/bar/p-3', 'no params using empty array'), +		); +	} + +	/** +	* @dataProvider helper_url_data_with_rewrite() +	*/ +	public function test_helper_url_with_rewrite($route, $params, $is_amp, $session_id, $expected, $description) +	{ +		$this->config = new \phpbb\config\config(array('enable_mod_rewrite' => '1')); +		$this->helper = new phpbb_mock_controller_helper($this->template, $this->user, $this->config, $this->provider, $this->extension_manager, $this->symfony_request, $this->filesystem, $this->root_path, 'php', dirname(__FILE__) . '/'); +		$this->assertEquals($expected, $this->helper->route($route, $params, $is_amp, $session_id)); +	} + +	public function helper_url_data_absolute() +	{ +		return array( +			array('controller2', array('t' => 1, 'f' => 2), true, false, 'http://localhost/app.php/foo/bar?t=1&f=2', 'parameters in params-argument as array'), +			array('controller2', array('t' => 1, 'f' => 2), false, false, 'http://localhost/app.php/foo/bar?t=1&f=2', 'parameters in params-argument as array'), +			array('controller3', array('p' => 3, 't' => 1, 'f' => 2), true, false, 'http://localhost/app.php/foo/bar/p-3?t=1&f=2', 'parameters in params-argument as array'), +			array('controller3', array('p' => 3, 't' => 1, 'f' => 2), false, false, 'http://localhost/app.php/foo/bar/p-3?t=1&f=2', 'parameters in params-argument as array'), + +			// Custom sid parameter +			array('controller2', array('t' => 1, 'f' => 2), true, 'custom-sid', 'http://localhost/app.php/foo/bar?t=1&f=2&sid=custom-sid', 'params-argument (array) using session_id'), +			array('controller2', array('t' => 1, 'f' => 2), false, 'custom-sid', 'http://localhost/app.php/foo/bar?t=1&f=2&sid=custom-sid', 'params-argument (array) using session_id'), +			array('controller3', array('p' => 3, 't' => 1, 'f' => 2), true, 'custom-sid', 'http://localhost/app.php/foo/bar/p-3?t=1&f=2&sid=custom-sid', 'params-argument (array) using session_id'), + +			// Testing anchors +			array('controller2', array('t' => 1, 'f' => 2, '#' => 'anchor'), true, false, 'http://localhost/app.php/foo/bar?t=1&f=2#anchor', 'anchor in params-argument (array)'), +			array('controller2', array('t' => 1, 'f' => 2, '#' => 'anchor'), false, false, 'http://localhost/app.php/foo/bar?t=1&f=2#anchor', 'anchor in params-argument (array)'), +			array('controller3', array('p' => 3, 't' => 1, 'f' => 2, '#' => 'anchor'), true, false, 'http://localhost/app.php/foo/bar/p-3?t=1&f=2#anchor', 'anchor in params-argument (array)'), + +			// Anchors and custom sid +			array('controller2', array('t' => 1, 'f' => 2, '#' => 'anchor'), true, 'custom-sid', 'http://localhost/app.php/foo/bar?t=1&f=2&sid=custom-sid#anchor', 'anchor in params-argument (array) using session_id'), +			array('controller2', array('t' => 1, 'f' => 2, '#' => 'anchor'), false, 'custom-sid', 'http://localhost/app.php/foo/bar?t=1&f=2&sid=custom-sid#anchor', 'anchor in params-argument (array) using session_id'), +			array('controller3', array('p' => 3, 't' => 1, 'f' => 2, '#' => 'anchor'), true, 'custom-sid', 'http://localhost/app.php/foo/bar/p-3?t=1&f=2&sid=custom-sid#anchor', 'anchor in params-argument (array) using session_id'), + +			// Empty parameters should not append the & or ? +			array('controller2', array(), true, false, 'http://localhost/app.php/foo/bar', 'no params using empty array'), +			array('controller2', array(), false, false, 'http://localhost/app.php/foo/bar', 'no params using empty array'), +			array('controller3', array('p' => 3), true, false, 'http://localhost/app.php/foo/bar/p-3', 'no params using empty array'), +		); +	} + +	/** +	* @dataProvider helper_url_data_absolute() +	*/ +	public function test_helper_url_absolute($route, $params, $is_amp, $session_id, $expected, $description) +	{ +		$this->config = new \phpbb\config\config(array('enable_mod_rewrite' => '0')); +		$this->helper = new phpbb_mock_controller_helper($this->template, $this->user, $this->config, $this->provider, $this->extension_manager, $this->symfony_request, $this->filesystem, $this->root_path, 'php', dirname(__FILE__) . '/'); +		$this->assertEquals($expected, $this->helper->route($route, $params, $is_amp, $session_id, UrlGeneratorInterface::ABSOLUTE_URL)); +	} + +	public function helper_url_data_relative_path() +	{ +		return array( +			array('controller2', array('t' => 1, 'f' => 2), true, false, 'app.php/foo/bar?t=1&f=2', 'parameters in params-argument as array'), +			array('controller2', array('t' => 1, 'f' => 2), false, false, 'app.php/foo/bar?t=1&f=2', 'parameters in params-argument as array'), +			array('controller3', array('p' => 3, 't' => 1, 'f' => 2), true, false, 'app.php/foo/bar/p-3?t=1&f=2', 'parameters in params-argument as array'), +			array('controller3', array('p' => 3, 't' => 1, 'f' => 2), false, false, 'app.php/foo/bar/p-3?t=1&f=2', 'parameters in params-argument as array'), + +			// Custom sid parameter +			array('controller2', array('t' => 1, 'f' => 2), true, 'custom-sid', 'app.php/foo/bar?t=1&f=2&sid=custom-sid', 'params-argument (array) using session_id'), +			array('controller2', array('t' => 1, 'f' => 2), false, 'custom-sid', 'app.php/foo/bar?t=1&f=2&sid=custom-sid', 'params-argument (array) using session_id'), +			array('controller3', array('p' => 3, 't' => 1, 'f' => 2), true, 'custom-sid', 'app.php/foo/bar/p-3?t=1&f=2&sid=custom-sid', 'params-argument (array) using session_id'), + +			// Testing anchors +			array('controller2', array('t' => 1, 'f' => 2, '#' => 'anchor'), true, false, 'app.php/foo/bar?t=1&f=2#anchor', 'anchor in params-argument (array)'), +			array('controller2', array('t' => 1, 'f' => 2, '#' => 'anchor'), false, false, 'app.php/foo/bar?t=1&f=2#anchor', 'anchor in params-argument (array)'), +			array('controller3', array('p' => 3, 't' => 1, 'f' => 2, '#' => 'anchor'), true, false, 'app.php/foo/bar/p-3?t=1&f=2#anchor', 'anchor in params-argument (array)'), + +			// Anchors and custom sid +			array('controller2', array('t' => 1, 'f' => 2, '#' => 'anchor'), true, 'custom-sid', 'app.php/foo/bar?t=1&f=2&sid=custom-sid#anchor', 'anchor in params-argument (array) using session_id'), +			array('controller2', array('t' => 1, 'f' => 2, '#' => 'anchor'), false, 'custom-sid', 'app.php/foo/bar?t=1&f=2&sid=custom-sid#anchor', 'anchor in params-argument (array) using session_id'), +			array('controller3', array('p' => 3, 't' => 1, 'f' => 2, '#' => 'anchor'), true, 'custom-sid', 'app.php/foo/bar/p-3?t=1&f=2&sid=custom-sid#anchor', 'anchor in params-argument (array) using session_id'), + +			// Empty parameters should not append the & or ? +			array('controller2', array(), true, false, 'app.php/foo/bar', 'no params using empty array'), +			array('controller2', array(), false, false, 'app.php/foo/bar', 'no params using empty array'), +			array('controller3', array('p' => 3), true, false, 'app.php/foo/bar/p-3', 'no params using empty array'), +		); +	} + +	/** +	* @dataProvider helper_url_data_relative_path() +	*/ +	public function test_helper_url_relative_path($route, $params, $is_amp, $session_id, $expected, $description) +	{ +		$this->config = new \phpbb\config\config(array('enable_mod_rewrite' => '0')); +		$this->helper = new phpbb_mock_controller_helper($this->template, $this->user, $this->config, $this->provider, $this->extension_manager, $this->symfony_request, $this->filesystem, $this->root_path, 'php', dirname(__FILE__) . '/'); +		$this->assertEquals($expected, $this->helper->route($route, $params, $is_amp, $session_id, UrlGeneratorInterface::RELATIVE_PATH)); +	} + +	public function helper_url_data_network() +	{ +		return array( +			array('controller2', array('t' => 1, 'f' => 2), true, false, '//localhost/app.php/foo/bar?t=1&f=2', 'parameters in params-argument as array'), +			array('controller2', array('t' => 1, 'f' => 2), false, false, '//localhost/app.php/foo/bar?t=1&f=2', 'parameters in params-argument as array'), +			array('controller3', array('p' => 3, 't' => 1, 'f' => 2), true, false, '//localhost/app.php/foo/bar/p-3?t=1&f=2', 'parameters in params-argument as array'), +			array('controller3', array('p' => 3, 't' => 1, 'f' => 2), false, false, '//localhost/app.php/foo/bar/p-3?t=1&f=2', 'parameters in params-argument as array'), + +			// Custom sid parameter +			array('controller2', array('t' => 1, 'f' => 2), true, 'custom-sid', '//localhost/app.php/foo/bar?t=1&f=2&sid=custom-sid', 'params-argument (array) using session_id'), +			array('controller2', array('t' => 1, 'f' => 2), false, 'custom-sid', '//localhost/app.php/foo/bar?t=1&f=2&sid=custom-sid', 'params-argument (array) using session_id'), +			array('controller3', array('p' => 3, 't' => 1, 'f' => 2), true, 'custom-sid', '//localhost/app.php/foo/bar/p-3?t=1&f=2&sid=custom-sid', 'params-argument (array) using session_id'), + +			// Testing anchors +			array('controller2', array('t' => 1, 'f' => 2, '#' => 'anchor'), true, false, '//localhost/app.php/foo/bar?t=1&f=2#anchor', 'anchor in params-argument (array)'), +			array('controller2', array('t' => 1, 'f' => 2, '#' => 'anchor'), false, false, '//localhost/app.php/foo/bar?t=1&f=2#anchor', 'anchor in params-argument (array)'), +			array('controller3', array('p' => 3, 't' => 1, 'f' => 2, '#' => 'anchor'), true, false, '//localhost/app.php/foo/bar/p-3?t=1&f=2#anchor', 'anchor in params-argument (array)'), + +			// Anchors and custom sid +			array('controller2', array('t' => 1, 'f' => 2, '#' => 'anchor'), true, 'custom-sid', '//localhost/app.php/foo/bar?t=1&f=2&sid=custom-sid#anchor', 'anchor in params-argument (array) using session_id'), +			array('controller2', array('t' => 1, 'f' => 2, '#' => 'anchor'), false, 'custom-sid', '//localhost/app.php/foo/bar?t=1&f=2&sid=custom-sid#anchor', 'anchor in params-argument (array) using session_id'), +			array('controller3', array('p' => 3, 't' => 1, 'f' => 2, '#' => 'anchor'), true, 'custom-sid', '//localhost/app.php/foo/bar/p-3?t=1&f=2&sid=custom-sid#anchor', 'anchor in params-argument (array) using session_id'), + +			// Empty parameters should not append the & or ? +			array('controller2', array(), true, false, '//localhost/app.php/foo/bar', 'no params using empty array'), +			array('controller2', array(), false, false, '//localhost/app.php/foo/bar', 'no params using empty array'), +			array('controller3', array('p' => 3), true, false, '//localhost/app.php/foo/bar/p-3', 'no params using empty array'), +		); +	} + +	/** +	* @dataProvider helper_url_data_network() +	*/ +	public function test_helper_url_network($route, $params, $is_amp, $session_id, $expected, $description) +	{ +		$this->config = new \phpbb\config\config(array('enable_mod_rewrite' => '0')); +		$this->helper = new phpbb_mock_controller_helper($this->template, $this->user, $this->config, $this->provider, $this->extension_manager, $this->symfony_request, $this->filesystem, $this->root_path, 'php', dirname(__FILE__) . '/'); +		$this->assertEquals($expected, $this->helper->route($route, $params, $is_amp, $session_id, UrlGeneratorInterface::NETWORK_PATH)); +	} +//TODO +	public function helper_url_data_absolute_with_rewrite() +	{ +		return array( +			array('controller2', array('t' => 1, 'f' => 2), true, false, 'http://localhost/foo/bar?t=1&f=2', 'parameters in params-argument as array'), +			array('controller2', array('t' => 1, 'f' => 2), false, false, 'http://localhost/foo/bar?t=1&f=2', 'parameters in params-argument as array'), +			array('controller3', array('p' => 3, 't' => 1, 'f' => 2), true, false, 'http://localhost/foo/bar/p-3?t=1&f=2', 'parameters in params-argument as array'), +			array('controller3', array('p' => 3, 't' => 1, 'f' => 2), false, false, 'http://localhost/foo/bar/p-3?t=1&f=2', 'parameters in params-argument as array'), + +			// Custom sid parameter +			array('controller2', array('t' => 1, 'f' => 2), true, 'custom-sid', 'http://localhost/foo/bar?t=1&f=2&sid=custom-sid', 'params-argument (array) using session_id'), +			array('controller2', array('t' => 1, 'f' => 2), false, 'custom-sid', 'http://localhost/foo/bar?t=1&f=2&sid=custom-sid', 'params-argument (array) using session_id'), +			array('controller3', array('p' => 3, 't' => 1, 'f' => 2), true, 'custom-sid', 'http://localhost/foo/bar/p-3?t=1&f=2&sid=custom-sid', 'params-argument (array) using session_id'), + +			// Testing anchors +			array('controller2', array('t' => 1, 'f' => 2, '#' => 'anchor'), true, false, 'http://localhost/foo/bar?t=1&f=2#anchor', 'anchor in params-argument (array)'), +			array('controller2', array('t' => 1, 'f' => 2, '#' => 'anchor'), false, false, 'http://localhost/foo/bar?t=1&f=2#anchor', 'anchor in params-argument (array)'), +			array('controller3', array('p' => 3, 't' => 1, 'f' => 2, '#' => 'anchor'), true, false, 'http://localhost/foo/bar/p-3?t=1&f=2#anchor', 'anchor in params-argument (array)'), + +			// Anchors and custom sid +			array('controller2', array('t' => 1, 'f' => 2, '#' => 'anchor'), true, 'custom-sid', 'http://localhost/foo/bar?t=1&f=2&sid=custom-sid#anchor', 'anchor in params-argument (array) using session_id'), +			array('controller2', array('t' => 1, 'f' => 2, '#' => 'anchor'), false, 'custom-sid', 'http://localhost/foo/bar?t=1&f=2&sid=custom-sid#anchor', 'anchor in params-argument (array) using session_id'), +			array('controller3', array('p' => 3, 't' => 1, 'f' => 2, '#' => 'anchor'), true, 'custom-sid', 'http://localhost/foo/bar/p-3?t=1&f=2&sid=custom-sid#anchor', 'anchor in params-argument (array) using session_id'), + +			// Empty parameters should not append the & or ? +			array('controller2', array(), true, false, 'http://localhost/foo/bar', 'no params using empty array'), +			array('controller2', array(), false, false, 'http://localhost/foo/bar', 'no params using empty array'), +			array('controller3', array('p' => 3), true, false, 'http://localhost/foo/bar/p-3', 'no params using empty array'), +		); +	} + +	/** +	 * @dataProvider helper_url_data_absolute_with_rewrite() +	 */ +	public function test_helper_url_absolute_with_rewrite($route, $params, $is_amp, $session_id, $expected, $description) +	{ +		$this->config = new \phpbb\config\config(array('enable_mod_rewrite' => '1')); +		$this->helper = new phpbb_mock_controller_helper($this->template, $this->user, $this->config, $this->provider, $this->extension_manager, $this->symfony_request, $this->filesystem, $this->root_path, 'php', dirname(__FILE__) . '/'); +		$this->assertEquals($expected, $this->helper->route($route, $params, $is_amp, $session_id, UrlGeneratorInterface::ABSOLUTE_URL)); +	} + +	public function helper_url_data_relative_path_with_rewrite() +	{ +		return array( +			array('controller2', array('t' => 1, 'f' => 2), true, false, 'foo/bar?t=1&f=2', 'parameters in params-argument as array'), +			array('controller2', array('t' => 1, 'f' => 2), false, false, 'foo/bar?t=1&f=2', 'parameters in params-argument as array'), +			array('controller3', array('p' => 3, 't' => 1, 'f' => 2), true, false, 'foo/bar/p-3?t=1&f=2', 'parameters in params-argument as array'), +			array('controller3', array('p' => 3, 't' => 1, 'f' => 2), false, false, 'foo/bar/p-3?t=1&f=2', 'parameters in params-argument as array'), + +			// Custom sid parameter +			array('controller2', array('t' => 1, 'f' => 2), true, 'custom-sid', 'foo/bar?t=1&f=2&sid=custom-sid', 'params-argument (array) using session_id'), +			array('controller2', array('t' => 1, 'f' => 2), false, 'custom-sid', 'foo/bar?t=1&f=2&sid=custom-sid', 'params-argument (array) using session_id'), +			array('controller3', array('p' => 3, 't' => 1, 'f' => 2), true, 'custom-sid', 'foo/bar/p-3?t=1&f=2&sid=custom-sid', 'params-argument (array) using session_id'), + +			// Testing anchors +			array('controller2', array('t' => 1, 'f' => 2, '#' => 'anchor'), true, false, 'foo/bar?t=1&f=2#anchor', 'anchor in params-argument (array)'), +			array('controller2', array('t' => 1, 'f' => 2, '#' => 'anchor'), false, false, 'foo/bar?t=1&f=2#anchor', 'anchor in params-argument (array)'), +			array('controller3', array('p' => 3, 't' => 1, 'f' => 2, '#' => 'anchor'), true, false, 'foo/bar/p-3?t=1&f=2#anchor', 'anchor in params-argument (array)'), + +			// Anchors and custom sid +			array('controller2', array('t' => 1, 'f' => 2, '#' => 'anchor'), true, 'custom-sid', 'foo/bar?t=1&f=2&sid=custom-sid#anchor', 'anchor in params-argument (array) using session_id'), +			array('controller2', array('t' => 1, 'f' => 2, '#' => 'anchor'), false, 'custom-sid', 'foo/bar?t=1&f=2&sid=custom-sid#anchor', 'anchor in params-argument (array) using session_id'), +			array('controller3', array('p' => 3, 't' => 1, 'f' => 2, '#' => 'anchor'), true, 'custom-sid', 'foo/bar/p-3?t=1&f=2&sid=custom-sid#anchor', 'anchor in params-argument (array) using session_id'), + +			// Empty parameters should not append the & or ? +			array('controller2', array(), true, false, 'foo/bar', 'no params using empty array'), +			array('controller2', array(), false, false, 'foo/bar', 'no params using empty array'), +			array('controller3', array('p' => 3), true, false, 'foo/bar/p-3', 'no params using empty array'), +		); +	} + +	/** +	 * @dataProvider helper_url_data_relative_path_with_rewrite() +	 */ +	public function test_helper_url_relative_path_with_rewrite($route, $params, $is_amp, $session_id, $expected, $description) +	{ +		$this->config = new \phpbb\config\config(array('enable_mod_rewrite' => '1')); +		$this->helper = new phpbb_mock_controller_helper($this->template, $this->user, $this->config, $this->provider, $this->extension_manager, $this->symfony_request, $this->filesystem, $this->root_path, 'php', dirname(__FILE__) . '/'); +		$this->assertEquals($expected, $this->helper->route($route, $params, $is_amp, $session_id, UrlGeneratorInterface::RELATIVE_PATH)); +	} + +	public function helper_url_data_network_with_rewrite() +	{ +		return array( +			array('controller2', array('t' => 1, 'f' => 2), true, false, '//localhost/foo/bar?t=1&f=2', 'parameters in params-argument as array'), +			array('controller2', array('t' => 1, 'f' => 2), false, false, '//localhost/foo/bar?t=1&f=2', 'parameters in params-argument as array'), +			array('controller3', array('p' => 3, 't' => 1, 'f' => 2), true, false, '//localhost/foo/bar/p-3?t=1&f=2', 'parameters in params-argument as array'), +			array('controller3', array('p' => 3, 't' => 1, 'f' => 2), false, false, '//localhost/foo/bar/p-3?t=1&f=2', 'parameters in params-argument as array'), + +			// Custom sid parameter +			array('controller2', array('t' => 1, 'f' => 2), true, 'custom-sid', '//localhost/foo/bar?t=1&f=2&sid=custom-sid', 'params-argument (array) using session_id'), +			array('controller2', array('t' => 1, 'f' => 2), false, 'custom-sid', '//localhost/foo/bar?t=1&f=2&sid=custom-sid', 'params-argument (array) using session_id'), +			array('controller3', array('p' => 3, 't' => 1, 'f' => 2), true, 'custom-sid', '//localhost/foo/bar/p-3?t=1&f=2&sid=custom-sid', 'params-argument (array) using session_id'), + +			// Testing anchors +			array('controller2', array('t' => 1, 'f' => 2, '#' => 'anchor'), true, false, '//localhost/foo/bar?t=1&f=2#anchor', 'anchor in params-argument (array)'), +			array('controller2', array('t' => 1, 'f' => 2, '#' => 'anchor'), false, false, '//localhost/foo/bar?t=1&f=2#anchor', 'anchor in params-argument (array)'), +			array('controller3', array('p' => 3, 't' => 1, 'f' => 2, '#' => 'anchor'), true, false, '//localhost/foo/bar/p-3?t=1&f=2#anchor', 'anchor in params-argument (array)'), + +			// Anchors and custom sid +			array('controller2', array('t' => 1, 'f' => 2, '#' => 'anchor'), true, 'custom-sid', '//localhost/foo/bar?t=1&f=2&sid=custom-sid#anchor', 'anchor in params-argument (array) using session_id'), +			array('controller2', array('t' => 1, 'f' => 2, '#' => 'anchor'), false, 'custom-sid', '//localhost/foo/bar?t=1&f=2&sid=custom-sid#anchor', 'anchor in params-argument (array) using session_id'), +			array('controller3', array('p' => 3, 't' => 1, 'f' => 2, '#' => 'anchor'), true, 'custom-sid', '//localhost/foo/bar/p-3?t=1&f=2&sid=custom-sid#anchor', 'anchor in params-argument (array) using session_id'), + +			// Empty parameters should not append the & or ? +			array('controller2', array(), true, false, '//localhost/foo/bar', 'no params using empty array'), +			array('controller2', array(), false, false, '//localhost/foo/bar', 'no params using empty array'), +			array('controller3', array('p' => 3), true, false, '//localhost/foo/bar/p-3', 'no params using empty array'), +		); +	} + +	/** +	 * @dataProvider helper_url_data_network_with_rewrite() +	 */ +	public function test_helper_url_network_with_rewrite($route, $params, $is_amp, $session_id, $expected, $description) +	{ +		$this->config = new \phpbb\config\config(array('enable_mod_rewrite' => '1')); +		$this->helper = new phpbb_mock_controller_helper($this->template, $this->user, $this->config, $this->provider, $this->extension_manager, $this->symfony_request, $this->filesystem, $this->root_path, 'php', dirname(__FILE__) . '/'); +		$this->assertEquals($expected, $this->helper->route($route, $params, $is_amp, $session_id, UrlGeneratorInterface::NETWORK_PATH)); +	} +} diff --git a/tests/controller/helper_route_adm_subdir_test.php b/tests/controller/helper_route_adm_subdir_test.php new file mode 100644 index 0000000000..f27ac81b04 --- /dev/null +++ b/tests/controller/helper_route_adm_subdir_test.php @@ -0,0 +1,33 @@ +<?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. +* +*/ + +require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; +require_once dirname(__FILE__) . '/common_helper_route.php'; + +class phpbb_controller_helper_route_adm_subdir_test extends phpbb_controller_common_helper_route +{ +	protected function get_phpbb_root_path() +	{ +		return './../../'; +	} + +	protected function get_uri() +	{ +		return '/adm/subdir/index.php'; +	} + +	protected function get_script_name() +	{ +		return 'index.php'; +	} +} diff --git a/tests/controller/helper_route_adm_test.php b/tests/controller/helper_route_adm_test.php new file mode 100644 index 0000000000..86dc36ef1f --- /dev/null +++ b/tests/controller/helper_route_adm_test.php @@ -0,0 +1,33 @@ +<?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. +* +*/ + +require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; +require_once dirname(__FILE__) . '/common_helper_route.php'; + +class phpbb_controller_helper_route_adm_test extends phpbb_controller_common_helper_route +{ +	protected function get_phpbb_root_path() +	{ +		return './../'; +	} + +	protected function get_uri() +	{ +		return '/adm/index.php'; +	} + +	protected function get_script_name() +	{ +		return 'index.php'; +	} +} diff --git a/tests/controller/helper_route_root_test.php b/tests/controller/helper_route_root_test.php new file mode 100644 index 0000000000..63a2f2f8f7 --- /dev/null +++ b/tests/controller/helper_route_root_test.php @@ -0,0 +1,33 @@ +<?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. +* +*/ + +require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; +require_once dirname(__FILE__) . '/common_helper_route.php'; + +class phpbb_controller_helper_route_test extends phpbb_controller_common_helper_route +{ +	protected function get_phpbb_root_path() +	{ +		return ''; +	} + +	protected function get_uri() +	{ +		return '/app.php'; +	} + +	protected function get_script_name() +	{ +		return 'app.php'; +	} +} diff --git a/tests/controller/helper_route_test.php b/tests/controller/helper_route_test.php deleted file mode 100644 index 04bff81683..0000000000 --- a/tests/controller/helper_route_test.php +++ /dev/null @@ -1,135 +0,0 @@ -<?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. -* -*/ - -require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; - -class phpbb_controller_helper_route_test extends phpbb_test_case -{ -	public function setUp() -	{ -		global $phpbb_dispatcher, $phpbb_root_path, $phpEx; - -		$phpbb_dispatcher = new phpbb_mock_event_dispatcher; -		$this->user = new \phpbb\user('\phpbb\datetime'); -		$phpbb_path_helper = new \phpbb\path_helper( -			new \phpbb\symfony_request( -				new phpbb_mock_request() -			), -			new \phpbb\filesystem(), -			$this->getMock('\phpbb\request\request'), -			$phpbb_root_path, -			$phpEx -		); -		$this->config = new \phpbb\config\config(array('enable_mod_rewrite' => '0')); -		$this->template = new phpbb\template\twig\twig($phpbb_path_helper, $this->config, $this->user, new \phpbb\template\context()); -		$this->extension_manager = new phpbb_mock_extension_manager( -			dirname(__FILE__) . '/', -			array( -				'vendor2/foo' => array( -					'ext_name' => 'vendor2/foo', -					'ext_active' => '1', -					'ext_path' => 'ext/vendor2/foo/', -				), -			) -		); - -		$finder = new \phpbb\finder( -			new \phpbb\filesystem(), -			dirname(__FILE__) . '/', -			new phpbb_mock_cache() -		); -		$finder->set_extensions(array_keys($this->extension_manager->all_enabled())); -		$this->provider = new \phpbb\controller\provider(); -		$this->provider->find_routing_files($finder); -		$this->provider->find(dirname(__FILE__) . '/'); -	} - -	public function helper_url_data_no_rewrite() -	{ -		return array( -			array('controller2', array('t' => 1, 'f' => 2), true, false, 'app.php/foo/bar?t=1&f=2', 'parameters in params-argument as array'), -			array('controller2', array('t' => 1, 'f' => 2), false, false, 'app.php/foo/bar?t=1&f=2', 'parameters in params-argument as array'), -			array('controller3', array('p' => 3, 't' => 1, 'f' => 2), true, false, 'app.php/foo/bar/p-3?t=1&f=2', 'parameters in params-argument as array'), -			array('controller3', array('p' => 3, 't' => 1, 'f' => 2), false, false, 'app.php/foo/bar/p-3?t=1&f=2', 'parameters in params-argument as array'), - -			// Custom sid parameter -			array('controller2', array('t' => 1, 'f' => 2), true, 'custom-sid', 'app.php/foo/bar?t=1&f=2&sid=custom-sid', 'params-argument (array) using session_id'), -			array('controller2', array('t' => 1, 'f' => 2), false, 'custom-sid', 'app.php/foo/bar?t=1&f=2&sid=custom-sid', 'params-argument (array) using session_id'), -			array('controller3', array('p' => 3, 't' => 1, 'f' => 2), true, 'custom-sid', 'app.php/foo/bar/p-3?t=1&f=2&sid=custom-sid', 'params-argument (array) using session_id'), - -			// Testing anchors -			array('controller2', array('t' => 1, 'f' => 2, '#' => 'anchor'), true, false, 'app.php/foo/bar?t=1&f=2#anchor', 'anchor in params-argument (array)'), -			array('controller2', array('t' => 1, 'f' => 2, '#' => 'anchor'), false, false, 'app.php/foo/bar?t=1&f=2#anchor', 'anchor in params-argument (array)'), -			array('controller3', array('p' => 3, 't' => 1, 'f' => 2, '#' => 'anchor'), true, false, 'app.php/foo/bar/p-3?t=1&f=2#anchor', 'anchor in params-argument (array)'), - -			// Anchors and custom sid -			array('controller2', array('t' => 1, 'f' => 2, '#' => 'anchor'), true, 'custom-sid', 'app.php/foo/bar?t=1&f=2&sid=custom-sid#anchor', 'anchor in params-argument (array) using session_id'), -			array('controller2', array('t' => 1, 'f' => 2, '#' => 'anchor'), false, 'custom-sid', 'app.php/foo/bar?t=1&f=2&sid=custom-sid#anchor', 'anchor in params-argument (array) using session_id'), -			array('controller3', array('p' => 3, 't' => 1, 'f' => 2, '#' => 'anchor'), true, 'custom-sid', 'app.php/foo/bar/p-3?t=1&f=2&sid=custom-sid#anchor', 'anchor in params-argument (array) using session_id'), - -			// Empty parameters should not append the & or ? -			array('controller2', array(), true, false, 'app.php/foo/bar', 'no params using empty array'), -			array('controller2', array(), false, false, 'app.php/foo/bar', 'no params using empty array'), -			array('controller3', array('p' => 3), true, false, 'app.php/foo/bar/p-3', 'no params using empty array'), -		); -	} - -	/** -	* @dataProvider helper_url_data_no_rewrite() -	*/ -	public function test_helper_url_no_rewrite($route, $params, $is_amp, $session_id, $expected, $description) -	{ -		$this->helper = new phpbb_mock_controller_helper($this->template, $this->user, $this->config, $this->provider, $this->extension_manager, '', 'php', dirname(__FILE__) . '/'); -		$this->assertEquals($expected, $this->helper->route($route, $params, $is_amp, $session_id)); -	} - -	public function helper_url_data_with_rewrite() -	{ -		return array( -			array('controller2', array('t' => 1, 'f' => 2), true, false, 'foo/bar?t=1&f=2', 'parameters in params-argument as array'), -			array('controller2', array('t' => 1, 'f' => 2), false, false, 'foo/bar?t=1&f=2', 'parameters in params-argument as array'), -			array('controller3', array('p' => 3, 't' => 1, 'f' => 2), true, false, 'foo/bar/p-3?t=1&f=2', 'parameters in params-argument as array'), -			array('controller3', array('p' => 3, 't' => 1, 'f' => 2), false, false, 'foo/bar/p-3?t=1&f=2', 'parameters in params-argument as array'), - -			// Custom sid parameter -			array('controller2', array('t' => 1, 'f' => 2), true, 'custom-sid', 'foo/bar?t=1&f=2&sid=custom-sid', 'params-argument (array) using session_id'), -			array('controller2', array('t' => 1, 'f' => 2), false, 'custom-sid', 'foo/bar?t=1&f=2&sid=custom-sid', 'params-argument (array) using session_id'), -			array('controller3', array('p' => 3, 't' => 1, 'f' => 2), true, 'custom-sid', 'foo/bar/p-3?t=1&f=2&sid=custom-sid', 'params-argument (array) using session_id'), - -			// Testing anchors -			array('controller2', array('t' => 1, 'f' => 2, '#' => 'anchor'), true, false, 'foo/bar?t=1&f=2#anchor', 'anchor in params-argument (array)'), -			array('controller2', array('t' => 1, 'f' => 2, '#' => 'anchor'), false, false, 'foo/bar?t=1&f=2#anchor', 'anchor in params-argument (array)'), -			array('controller3', array('p' => 3, 't' => 1, 'f' => 2, '#' => 'anchor'), true, false, 'foo/bar/p-3?t=1&f=2#anchor', 'anchor in params-argument (array)'), - -			// Anchors and custom sid -			array('controller2', array('t' => 1, 'f' => 2, '#' => 'anchor'), true, 'custom-sid', 'foo/bar?t=1&f=2&sid=custom-sid#anchor', 'anchor in params-argument (array) using session_id'), -			array('controller2', array('t' => 1, 'f' => 2, '#' => 'anchor'), false, 'custom-sid', 'foo/bar?t=1&f=2&sid=custom-sid#anchor', 'anchor in params-argument (array) using session_id'), -			array('controller3', array('p' => 3, 't' => 1, 'f' => 2, '#' => 'anchor'), true, 'custom-sid', 'foo/bar/p-3?t=1&f=2&sid=custom-sid#anchor', 'anchor in params-argument (array) using session_id'), - -			// Empty parameters should not append the & or ? -			array('controller2', array(), true, false, 'foo/bar', 'no params using empty array'), -			array('controller2', array(), false, false, 'foo/bar', 'no params using empty array'), -			array('controller3', array('p' => 3), true, false, 'foo/bar/p-3', 'no params using empty array'), -		); -	} - -	/** -	* @dataProvider helper_url_data_with_rewrite() -	*/ -	public function test_helper_url_with_rewrite($route, $params, $is_amp, $session_id, $expected, $description) -	{ -		$this->config = new \phpbb\config\config(array('enable_mod_rewrite' => '1')); -		$this->helper = new phpbb_mock_controller_helper($this->template, $this->user, $this->config, $this->provider, $this->extension_manager, '', 'php', dirname(__FILE__) . '/'); -		$this->assertEquals($expected, $this->helper->route($route, $params, $is_amp, $session_id)); -	} -} diff --git a/tests/controller/helper_route_unclean_path_test.php b/tests/controller/helper_route_unclean_path_test.php new file mode 100644 index 0000000000..9d8b62bc1c --- /dev/null +++ b/tests/controller/helper_route_unclean_path_test.php @@ -0,0 +1,33 @@ +<?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. +* +*/ + +require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; +require_once dirname(__FILE__) . '/common_helper_route.php'; + +class phpbb_controller_helper_route_unclean_path_test extends phpbb_controller_common_helper_route +{ +	protected function get_phpbb_root_path() +	{ +		return './../'; +	} + +	protected function get_uri() +	{ +		return '/adm/../bertie/index.php'; +	} + +	protected function get_script_name() +	{ +		return 'index.php'; +	} +} diff --git a/tests/extension/ext/vendor2/bar/migrations/migration.php b/tests/extension/ext/vendor2/bar/migrations/migration.php new file mode 100644 index 0000000000..71caa34fd9 --- /dev/null +++ b/tests/extension/ext/vendor2/bar/migrations/migration.php @@ -0,0 +1,18 @@ +<?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 vendor2\bar\migrations; + +class migration extends \phpbb\db\migration\migration +{ +} diff --git a/tests/extension/extension_base_test.php b/tests/extension/extension_base_test.php new file mode 100644 index 0000000000..eee38186db --- /dev/null +++ b/tests/extension/extension_base_test.php @@ -0,0 +1,79 @@ +<?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. +* +*/ +require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; + +class phpbb_extension_extension_base_test extends phpbb_test_case +{ +	protected static $reflection_method_get_migration_file_list; + +	/** @var phpbb_mock_extension_manager */ +	protected $extension_manager; + +	public static function setUpBeforeClass() +	{ +		parent::setUpBeforeClass(); + +		$reflection_class = new ReflectionClass('\phpbb\extension\base'); +		self::$reflection_method_get_migration_file_list = $reflection_class->getMethod('get_migration_file_list'); +		self::$reflection_method_get_migration_file_list->setAccessible(true); +	} + +	public function setUp() +	{ +		$container = new phpbb_mock_container_builder(); +		$migrator = new phpbb_mock_migrator(); +		$container->set('migrator', $migrator); + +		$this->extension_manager = new phpbb_mock_extension_manager( +			dirname(__FILE__) . '/', +			array( +				'vendor2/foo' => array( +					'ext_name' => 'vendor2/foo', +					'ext_active' => '1', +					'ext_path' => 'ext/vendor2/foo/', +				), +				'vendor3/bar' => array( +					'ext_name' => 'vendor3/bar', +					'ext_active' => '1', +					'ext_path' => 'ext/vendor3/bar/', +				), +				'vendor2/bar' => array( +					'ext_name' => 'vendor2/bar', +					'ext_active' => '1', +					'ext_path' => 'ext/vendor2/bar/', +				), +			), +			$container); +	} + +	public function data_test_suffix_get_classes() +	{ +		return array( +			array( +				'vendor2/bar', +				array( +					'\vendor2\bar\migrations\migration', +				), +			), +		); +	} + +	/** +	* @dataProvider data_test_suffix_get_classes +	*/ +	public function test_suffix_get_classes($extension_name, $expected) +	{ +		$extension = $this->extension_manager->get_extension($extension_name); +		$this->assertEquals($expected, self::$reflection_method_get_migration_file_list->invoke($extension)); +	} +} diff --git a/tests/functions/get_preg_expression_test.php b/tests/functions/get_preg_expression_test.php new file mode 100644 index 0000000000..e74017d315 --- /dev/null +++ b/tests/functions/get_preg_expression_test.php @@ -0,0 +1,40 @@ +<?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. +* +*/ + +require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; + +class phpbb_functions_get_preg_expression_test extends phpbb_test_case +{ +	public function data_path_remove_dot_trailing_slash() +	{ +		return array( +			array('./../', '$2', '/..'), +			array('/../', '$2', '/..'), +			array('', '$2', ''), +			array('./', '$2', ''), +			array('/', '$2', ''), +			array('./../../', '$2', '/../..'), +			array('/../../', '$2', '/../..'), +			array('./dir/', '$2', '/dir'), +			array('./../dir/', '$2', '/../dir'), +		); +	} + +	/** +	 * @dataProvider data_path_remove_dot_trailing_slash +	 */ +	public function test_path_remove_dot_trailing_slash($input, $replace, $expected) +	{ +		$this->assertSame($expected, preg_replace(get_preg_expression('path_remove_dot_trailing_slash'), $replace, $input)); +	} +} diff --git a/tests/functions_user/delete_user_test.php b/tests/functions_user/delete_user_test.php new file mode 100644 index 0000000000..d5c78c64ad --- /dev/null +++ b/tests/functions_user/delete_user_test.php @@ -0,0 +1,440 @@ +<?php +/** +* +* @package testing +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; +require_once dirname(__FILE__) . '/../../phpBB/includes/functions_user.php'; +require_once dirname(__FILE__) . '/../../phpBB/includes/utf/utf_tools.php'; + +class phpbb_functions_user_delete_user_test extends phpbb_database_test_case +{ +	/** @var \phpbb\db\driver\driver_interface */ +	protected $db; + +	public function getDataSet() +	{ +		return $this->createXMLDataSet(dirname(__FILE__) . '/fixtures/delete_user.xml'); +	} + +	protected function setUp() +	{ +		parent::setUp(); + +		global $cache, $config, $db, $phpbb_dispatcher, $phpbb_container; + +		$db = $this->db = $this->new_dbal(); +		$config = new \phpbb\config\config(array( +			'load_online_time'	=> 5, +			'search_type'		=> '\phpbb\search\fulltext_mysql', +		)); +		set_config(false, false, false, $config); +		set_config_count(false, false, false, $config); +		$cache = new phpbb_mock_null_cache(); +		$phpbb_dispatcher = new phpbb_mock_event_dispatcher(); +		$phpbb_container = new phpbb_mock_container_builder(); +		$phpbb_container->set('notification_manager', new phpbb_mock_notification_manager()); +	} + +	 public function first_last_post_data() +	{ +		return array( +			array( +				'retain', false, +				array( +					array('post_id' => 1, 'poster_id' => ANONYMOUS, 'post_username' => ''), +					array('post_id' => 2, 'poster_id' => ANONYMOUS, 'post_username' => 'Other'), +					array('post_id' => 3, 'poster_id' => ANONYMOUS, 'post_username' => ''), +					array('post_id' => 4, 'poster_id' => ANONYMOUS, 'post_username' => 'Other'), +				), +				array( +					array( +						'topic_id' => 1, +						'topic_poster' => ANONYMOUS, 'topic_first_poster_name' => '', 'topic_first_poster_colour' => '', +						'topic_last_poster_id' => ANONYMOUS, 'topic_last_poster_name' => '', 'topic_last_poster_colour' => '', +					), +					array( +						'topic_id' => 2, +						'topic_poster' => ANONYMOUS, 'topic_first_poster_name' => 'Other', 'topic_first_poster_colour' => '', +						'topic_last_poster_id' => ANONYMOUS, 'topic_last_poster_name' => 'Other', 'topic_last_poster_colour' => '', +					), +					array( +						'topic_id' => 3, +						'topic_poster' => ANONYMOUS, 'topic_first_poster_name' => '', 'topic_first_poster_colour' => '', +						'topic_last_poster_id' => ANONYMOUS, 'topic_last_poster_name' => '', 'topic_last_poster_colour' => '', +					), +					array( +						'topic_id' => 4, +						'topic_poster' => ANONYMOUS, 'topic_first_poster_name' => 'Other', 'topic_first_poster_colour' => '', +						'topic_last_poster_id' => ANONYMOUS, 'topic_last_poster_name' => 'Other', 'topic_last_poster_colour' => '', +					), +				), +				array( +					array('forum_id' => 1, 'forum_last_poster_id' => ANONYMOUS, 'forum_last_poster_name' => '', 'forum_last_poster_colour' => ''), +					array('forum_id' => 2, 'forum_last_poster_id' => ANONYMOUS, 'forum_last_poster_name' => 'Other', 'forum_last_poster_colour' => ''), +					array('forum_id' => 3, 'forum_last_poster_id' => ANONYMOUS, 'forum_last_poster_name' => '', 'forum_last_poster_colour' => ''), +					array('forum_id' => 4, 'forum_last_poster_id' => ANONYMOUS, 'forum_last_poster_name' => 'Other', 'forum_last_poster_colour' => ''), +				), +			), +			array( +				'remove', false, +				array( +					array('post_id' => 2, 'poster_id' => ANONYMOUS, 'post_username' => 'Other'), +					array('post_id' => 4, 'poster_id' => ANONYMOUS, 'post_username' => 'Other'), +				), +				array( +					array( +						'topic_id' => 2, +						'topic_poster' => ANONYMOUS, 'topic_first_poster_name' => 'Other', 'topic_first_poster_colour' => '', +						'topic_last_poster_id' => ANONYMOUS, 'topic_last_poster_name' => 'Other', 'topic_last_poster_colour' => '', +					), +					array( +						'topic_id' => 4, +						'topic_poster' => ANONYMOUS, 'topic_first_poster_name' => 'Other', 'topic_first_poster_colour' => '', +						'topic_last_poster_id' => ANONYMOUS, 'topic_last_poster_name' => 'Other', 'topic_last_poster_colour' => '', +					), +				), +				array( +					array('forum_id' => 1, 'forum_last_poster_id' => 0, 'forum_last_poster_name' => '', 'forum_last_poster_colour' => ''), +					array('forum_id' => 2, 'forum_last_poster_id' => ANONYMOUS, 'forum_last_poster_name' => 'Other', 'forum_last_poster_colour' => ''), +					array('forum_id' => 3, 'forum_last_poster_id' => 0, 'forum_last_poster_name' => '', 'forum_last_poster_colour' => ''), +					array('forum_id' => 4, 'forum_last_poster_id' => ANONYMOUS, 'forum_last_poster_name' => 'Other', 'forum_last_poster_colour' => ''), +				), +			), +			array( +				'retain', true, +				array( +					array('post_id' => 1, 'poster_id' => ANONYMOUS, 'post_username' => 'Foobar'), +					array('post_id' => 2, 'poster_id' => ANONYMOUS, 'post_username' => 'Other'), +					array('post_id' => 3, 'poster_id' => ANONYMOUS, 'post_username' => 'Foobar'), +					array('post_id' => 4, 'poster_id' => ANONYMOUS, 'post_username' => 'Other'), +				), +				array( +					array( +						'topic_id' => 1, +						'topic_poster' => ANONYMOUS, 'topic_first_poster_name' => 'Foobar', 'topic_first_poster_colour' => '', +						'topic_last_poster_id' => ANONYMOUS, 'topic_last_poster_name' => 'Foobar', 'topic_last_poster_colour' => '', +					), +					array( +						'topic_id' => 2, +						'topic_poster' => ANONYMOUS, 'topic_first_poster_name' => 'Other', 'topic_first_poster_colour' => '', +						'topic_last_poster_id' => ANONYMOUS, 'topic_last_poster_name' => 'Other', 'topic_last_poster_colour' => '', +					), +					array( +						'topic_id' => 3, +						'topic_poster' => ANONYMOUS, 'topic_first_poster_name' => 'Foobar', 'topic_first_poster_colour' => '', +						'topic_last_poster_id' => ANONYMOUS, 'topic_last_poster_name' => 'Foobar', 'topic_last_poster_colour' => '', +					), +					array( +						'topic_id' => 4, +						'topic_poster' => ANONYMOUS, 'topic_first_poster_name' => 'Other', 'topic_first_poster_colour' => '', +						'topic_last_poster_id' => ANONYMOUS, 'topic_last_poster_name' => 'Other', 'topic_last_poster_colour' => '', +					), +				), +				array( +					array('forum_id' => 1, 'forum_last_poster_id' => ANONYMOUS, 'forum_last_poster_name' => 'Foobar', 'forum_last_poster_colour' => ''), +					array('forum_id' => 2, 'forum_last_poster_id' => ANONYMOUS, 'forum_last_poster_name' => 'Other', 'forum_last_poster_colour' => ''), +					array('forum_id' => 3, 'forum_last_poster_id' => ANONYMOUS, 'forum_last_poster_name' => 'Foobar', 'forum_last_poster_colour' => ''), +					array('forum_id' => 4, 'forum_last_poster_id' => ANONYMOUS, 'forum_last_poster_name' => 'Other', 'forum_last_poster_colour' => ''), +				), +			), +			array( +				'remove', true, +				array( +					array('post_id' => 2, 'poster_id' => ANONYMOUS, 'post_username' => 'Other'), +					array('post_id' => 4, 'poster_id' => ANONYMOUS, 'post_username' => 'Other'), +				), +				array( +					array( +						'topic_id' => 2, +						'topic_poster' => ANONYMOUS, 'topic_first_poster_name' => 'Other', 'topic_first_poster_colour' => '', +						'topic_last_poster_id' => ANONYMOUS, 'topic_last_poster_name' => 'Other', 'topic_last_poster_colour' => '', +					), +					array( +						'topic_id' => 4, +						'topic_poster' => ANONYMOUS, 'topic_first_poster_name' => 'Other', 'topic_first_poster_colour' => '', +						'topic_last_poster_id' => ANONYMOUS, 'topic_last_poster_name' => 'Other', 'topic_last_poster_colour' => '', +					), +				), +				array( +					array('forum_id' => 1, 'forum_last_poster_id' => 0, 'forum_last_poster_name' => '', 'forum_last_poster_colour' => ''), +					array('forum_id' => 2, 'forum_last_poster_id' => ANONYMOUS, 'forum_last_poster_name' => 'Other', 'forum_last_poster_colour' => ''), +					array('forum_id' => 3, 'forum_last_poster_id' => 0, 'forum_last_poster_name' => '', 'forum_last_poster_colour' => ''), +					array('forum_id' => 4, 'forum_last_poster_id' => ANONYMOUS, 'forum_last_poster_name' => 'Other', 'forum_last_poster_colour' => ''), +				), +			), +		); +	} + +	/** +	* @dataProvider first_last_post_data +	*/ +	public function test_first_last_post_info($mode, $retain_username, $expected_posts, $expected_topics, $expected_forums) +	{ +		$this->assertFalse(user_delete($mode, 2, $retain_username)); + +		$sql = 'SELECT post_id, poster_id, post_username +			FROM ' . POSTS_TABLE . ' +			ORDER BY post_id ASC'; +		$result = $this->db->sql_query($sql); +		$this->assertEquals($expected_posts, $this->db->sql_fetchrowset($result), 'Post table poster info is mismatching after deleting a user.'); +		$this->db->sql_freeresult($result); + +		$sql = 'SELECT topic_id, topic_poster, topic_first_poster_name, topic_first_poster_colour, topic_last_poster_id, topic_last_poster_name, topic_last_poster_colour +			FROM ' . TOPICS_TABLE . ' +			ORDER BY topic_id ASC'; +		$result = $this->db->sql_query($sql); +		$this->assertEquals($expected_topics, $this->db->sql_fetchrowset($result), 'Topic table first/last poster info is mismatching after deleting a user.'); +		$this->db->sql_freeresult($result); + +		$sql = 'SELECT forum_id, forum_last_poster_id, forum_last_poster_name, forum_last_poster_colour +			FROM ' . FORUMS_TABLE . ' +			ORDER BY forum_id ASC'; +		$result = $this->db->sql_query($sql); +		$this->assertEquals($expected_forums, $this->db->sql_fetchrowset($result), 'Forum table last poster info is mismatching after deleting a user.'); +		$this->db->sql_freeresult($result); +	} + +	 public function report_attachment_data() +	{ +		return array( +			array( +				'retain', +				array( +					array('post_id' => 1, 'post_reported' => 1, 'post_edit_user' => 1, 'post_delete_user' => 1), +					array('post_id' => 2, 'post_reported' => 1, 'post_edit_user' => 1, 'post_delete_user' => 1), +					array('post_id' => 3, 'post_reported' => 0, 'post_edit_user' => 1, 'post_delete_user' => 1), +					array('post_id' => 4, 'post_reported' => 0, 'post_edit_user' => 1, 'post_delete_user' => 1), +				), +				array( +					array('report_id' => 1, 'post_id' => 1, 'user_id' => 1), +					array('report_id' => 3, 'post_id' => 2, 'user_id' => 1), +				), +				array( +					array('topic_id' => 1, 'topic_reported' => 1, 'topic_delete_user' => 1), +					array('topic_id' => 2, 'topic_reported' => 1, 'topic_delete_user' => 1), +					array('topic_id' => 3, 'topic_reported' => 0, 'topic_delete_user' => 1), +					array('topic_id' => 4, 'topic_reported' => 0, 'topic_delete_user' => 1), +				), +				array( +					array('attach_id' => 1, 'post_msg_id' => 1, 'poster_id' => 1), +					array('attach_id' => 2, 'post_msg_id' => 2, 'poster_id' => 1), +					array('attach_id' => 3, 'post_msg_id' => 0, 'poster_id' => 1), // TODO should be deleted: PHPBB3-13089 +				), +			), +			array( +				'remove', +				array( +					array('post_id' => 2, 'post_reported' => 1, 'post_edit_user' => 1, 'post_delete_user' => 1), +					array('post_id' => 4, 'post_reported' => 0, 'post_edit_user' => 1, 'post_delete_user' => 1), +				), +				array( +					array('report_id' => 3, 'post_id' => 2, 'user_id' => 1), +				), +				array( +					array('topic_id' => 2, 'topic_reported' => 1, 'topic_delete_user' => 1), +					array('topic_id' => 4, 'topic_reported' => 0, 'topic_delete_user' => 1), +				), +				array( +					array('attach_id' => 2, 'post_msg_id' => 2, 'poster_id' => 1), +					array('attach_id' => 3, 'post_msg_id' => 0, 'poster_id' => 2), // TODO should be deleted: PHPBB3-13089 +				), +			), +		); +	} + +	/** +	* @dataProvider report_attachment_data +	*/ +	public function test_report_attachment_info($mode, $expected_posts, $expected_reports, $expected_topics, $expected_attach) +	{ +		$this->assertFalse(user_delete($mode, 2)); + +		$sql = 'SELECT post_id, post_reported, post_edit_user, post_delete_user +			FROM ' . POSTS_TABLE . ' +			ORDER BY post_id ASC'; +		$result = $this->db->sql_query($sql); +		$this->assertEquals($expected_posts, $this->db->sql_fetchrowset($result), 'Post report status content is mismatching after deleting a user.'); +		$this->db->sql_freeresult($result); + +		$sql = 'SELECT report_id, post_id, user_id +			FROM ' . REPORTS_TABLE . ' +			ORDER BY report_id ASC'; +		$result = $this->db->sql_query($sql); +		$this->assertEquals($expected_reports, $this->db->sql_fetchrowset($result), 'Report table content is mismatching after deleting a user.'); +		$this->db->sql_freeresult($result); + +		$sql = 'SELECT topic_id, topic_reported, topic_delete_user +			FROM ' . TOPICS_TABLE . ' +			ORDER BY topic_id ASC'; +		$result = $this->db->sql_query($sql); +		$this->assertEquals($expected_topics, $this->db->sql_fetchrowset($result), 'Topic report status is mismatching after deleting a user.'); +		$this->db->sql_freeresult($result); + +		$sql = 'SELECT attach_id, post_msg_id, poster_id +			FROM ' . ATTACHMENTS_TABLE . ' +			ORDER BY attach_id ASC'; +		$result = $this->db->sql_query($sql); +		$this->assertEquals($expected_attach, $this->db->sql_fetchrowset($result), 'Attachment table content is mismatching after deleting a user.'); +		$this->db->sql_freeresult($result); +	} + +	 public function delete_data() +	{ +		return array( +			array( +				'retain', +				array(array('user_id' => 1, 'user_posts' => 4)), +				array(array('user_id' => 1, 'zebra_id' => 3)), +				array(array('ban_id' => 2), array('ban_id' => 3)), +				array(array('session_id' => '12345678901234567890123456789013')), +				array( +					array('log_id' => 2, 'user_id' => 1, 'reportee_id' => 1), +					array('log_id' => 3, 'user_id' => 1, 'reportee_id' => 1), +				), +				array( +					array('msg_id' => 1, 'author_id' => 3, 'message_edit_user' => 3), +					array('msg_id' => 2, 'author_id' => 1, 'message_edit_user' => 1), +				), +			), +			array( +				'remove', +				array(array('user_id' => 1, 'user_posts' => 2)), +				array(array('user_id' => 1, 'zebra_id' => 3)), +				array(array('ban_id' => 2), array('ban_id' => 3)), +				array(array('session_id' => '12345678901234567890123456789013')), +				array( +					array('log_id' => 2, 'user_id' => 1, 'reportee_id' => 1), +					array('log_id' => 3, 'user_id' => 1, 'reportee_id' => 1), +				), +				array( +					array('msg_id' => 1, 'author_id' => 3, 'message_edit_user' => 3), +					array('msg_id' => 2, 'author_id' => 1, 'message_edit_user' => 1), +				), +			), +		); +	} + +	/** +	* @dataProvider delete_data +	*/ +	public function test_delete_data($mode, $expected_users, $expected_zebra, $expected_ban, $expected_sessions, $expected_logs, $expected_pms) +	{ +		$this->assertFalse(user_delete($mode, 2)); + +		$sql = 'SELECT user_id, user_posts +			FROM ' . USERS_TABLE . ' +			ORDER BY user_id ASC'; +		$result = $this->db->sql_query($sql); +		$this->assertEquals($expected_users, $this->db->sql_fetchrowset($result), 'User table content is mismatching after deleting a user.'); +		$this->db->sql_freeresult($result); + +		$sql = 'SELECT user_id, zebra_id +			FROM ' . ZEBRA_TABLE . ' +			ORDER BY user_id ASC, zebra_id ASC'; +		$result = $this->db->sql_query($sql); +		$this->assertEquals($expected_zebra, $this->db->sql_fetchrowset($result), 'Zebra table content is mismatching after deleting a user.'); +		$this->db->sql_freeresult($result); + +		$sql = 'SELECT ban_id +			FROM ' . BANLIST_TABLE . ' +			ORDER BY ban_id ASC'; +		$result = $this->db->sql_query($sql); +		$this->assertEquals($expected_ban, $this->db->sql_fetchrowset($result), 'Ban table content is mismatching after deleting a user.'); +		$this->db->sql_freeresult($result); + +		$sql = 'SELECT session_id +			FROM ' . SESSIONS_TABLE . ' +			ORDER BY session_id ASC'; +		$result = $this->db->sql_query($sql); +		$this->assertEquals($expected_sessions, $this->db->sql_fetchrowset($result), 'Session table content is mismatching after deleting a user.'); +		$this->db->sql_freeresult($result); + +		$sql = 'SELECT log_id, user_id, reportee_id +			FROM ' . LOG_TABLE . ' +			ORDER BY log_id ASC'; +		$result = $this->db->sql_query($sql); +		$this->assertEquals($expected_logs, $this->db->sql_fetchrowset($result), 'Log table content is mismatching after deleting a user.'); +		$this->db->sql_freeresult($result); + +		$sql = 'SELECT msg_id, author_id, message_edit_user +			FROM ' . PRIVMSGS_TABLE . ' +			ORDER BY msg_id ASC'; +		$result = $this->db->sql_query($sql); +		$this->assertEquals($expected_pms, $this->db->sql_fetchrowset($result), 'Private messages table content is mismatching after deleting a user.'); +		$this->db->sql_freeresult($result); +	} + +	 public function delete_user_id_data() +	{ +		return array( +			array( +				'retain', +				array( +					USER_GROUP_TABLE, +					TOPICS_WATCH_TABLE, +					FORUMS_WATCH_TABLE, +					ACL_USERS_TABLE, +					TOPICS_TRACK_TABLE, +					TOPICS_POSTED_TABLE, +					FORUMS_TRACK_TABLE, +					PROFILE_FIELDS_DATA_TABLE, +					MODERATOR_CACHE_TABLE, +					DRAFTS_TABLE, +					BOOKMARKS_TABLE, +					SESSIONS_KEYS_TABLE, +					PRIVMSGS_FOLDER_TABLE, +					PRIVMSGS_RULES_TABLE, +				), +			), +			array( +				'remove', +				array( +					USER_GROUP_TABLE, +					TOPICS_WATCH_TABLE, +					FORUMS_WATCH_TABLE, +					ACL_USERS_TABLE, +					TOPICS_TRACK_TABLE, +					TOPICS_POSTED_TABLE, +					FORUMS_TRACK_TABLE, +					PROFILE_FIELDS_DATA_TABLE, +					MODERATOR_CACHE_TABLE, +					DRAFTS_TABLE, +					BOOKMARKS_TABLE, +					SESSIONS_KEYS_TABLE, +					PRIVMSGS_FOLDER_TABLE, +					PRIVMSGS_RULES_TABLE, +				), +			), +		); +	} + +	/** +	* @dataProvider delete_user_id_data +	*/ +	public function test_delete_user_id_data($mode, $cleaned_tables) +	{ +		$this->assertFalse(user_delete($mode, 2)); + +		foreach ($cleaned_tables as $table) +		{ +			$sql = 'SELECT user_id +				FROM ' . $table . ' +				WHERE user_id = 2'; +			$result = $this->db->sql_query($sql); +			$this->assertFalse($this->db->sql_fetchfield('user_id'), 'Found data for deleted user in table: ' . $table); +			$this->db->sql_freeresult($result); + +			$sql = 'SELECT user_id +				FROM ' . $table . ' +				WHERE user_id = 3'; +			$result = $this->db->sql_query($sql); +			$this->assertEquals(3, $this->db->sql_fetchfield('user_id'), 'Missing data for user in table: ' . $table); +			$this->db->sql_freeresult($result); +		} +	} +} diff --git a/tests/functions_user/fixtures/delete_user.xml b/tests/functions_user/fixtures/delete_user.xml new file mode 100644 index 0000000000..56014b35d1 --- /dev/null +++ b/tests/functions_user/fixtures/delete_user.xml @@ -0,0 +1,549 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<dataset> +	<table name="phpbb_attachments"> +		<column>attach_id</column> +		<column>post_msg_id</column> +		<column>topic_id</column> +		<column>in_message</column> +		<column>poster_id</column> +		<column>is_orphan</column> +		<column>attach_comment</column> +		<row> +			<value>1</value> +			<value>1</value> +			<value>1</value> +			<value>0</value> +			<value>2</value> +			<value>0</value> +			<value></value> +		</row> +		<row> +			<value>2</value> +			<value>2</value> +			<value>2</value> +			<value>0</value> +			<value>1</value> +			<value>0</value> +			<value></value> +		</row> +		<row> +			<value>3</value> +			<value>0</value> +			<value>0</value> +			<value>0</value> +			<value>2</value> +			<value>1</value> +			<value></value> +		</row> +	</table> +	<table name="phpbb_banlist"> +		<column>ban_id</column> +		<column>ban_userid</column> +		<column>ban_email</column> +		<column>ban_reason</column> +		<column>ban_give_reason</column> +		<row> +			<value>1</value> +			<value>2</value> +			<value></value> +			<value></value> +			<value></value> +		</row> +		<row> +			<value>2</value> +			<value>3</value> +			<value></value> +			<value></value> +			<value></value> +		</row> +		<row> +			<value>3</value> +			<value>0</value> +			<value></value> +			<value></value> +			<value></value> +		</row> +	</table> +	<table name="phpbb_forums"> +		<column>forum_id</column> +		<column>forum_last_poster_id</column> +		<column>forum_last_poster_name</column> +		<column>forum_last_poster_colour</column> +		<column>forum_parents</column> +		<column>forum_desc</column> +		<column>forum_rules</column> +		<row> +			<value>1</value> +			<value>2</value> +			<value></value> +			<value>00AA00</value> +			<value></value> +			<value></value> +			<value></value> +		</row> +		<row> +			<value>2</value> +			<value>1</value> +			<value>Other</value> +			<value></value> +			<value></value> +			<value></value> +			<value></value> +		</row> +		<row> +			<value>3</value> +			<value>2</value> +			<value></value> +			<value>00AA00</value> +			<value></value> +			<value></value> +			<value></value> +		</row> +		<row> +			<value>4</value> +			<value>1</value> +			<value>Other</value> +			<value></value> +			<value></value> +			<value></value> +			<value></value> +		</row> +	</table> +	<table name="phpbb_log"> +		<column>log_id</column> +		<column>user_id</column> +		<column>reportee_id</column> +		<column>log_operation</column> +		<column>log_data</column> +		<row> +			<value>1</value> +			<value>1</value> +			<value>2</value> +			<value></value> +			<value></value> +		</row> +		<row> +			<value>2</value> +			<value>2</value> +			<value>1</value> +			<value></value> +			<value></value> +		</row> +		<row> +			<value>3</value> +			<value>1</value> +			<value>1</value> +			<value></value> +			<value></value> +		</row> +		<row> +			<value>4</value> +			<value>2</value> +			<value>2</value> +			<value></value> +			<value></value> +		</row> +	</table> +	<table name="phpbb_posts"> +		<column>post_id</column> +		<column>poster_id</column> +		<column>post_edit_user</column> +		<column>post_delete_user</column> +		<column>post_username</column> +		<column>topic_id</column> +		<column>forum_id</column> +		<column>post_visibility</column> +		<column>post_time</column> +		<column>post_text</column> +		<column>post_reported</column> +		<row> +			<value>1</value> +			<value>2</value> +			<value>2</value> +			<value>2</value> +			<value></value> +			<value>1</value> +			<value>1</value> +			<value>1</value> +			<value>1</value> +			<value></value> +			<value>1</value> +		</row> +		<row> +			<value>2</value> +			<value>1</value> +			<value>1</value> +			<value>1</value> +			<value>Other</value> +			<value>2</value> +			<value>2</value> +			<value>1</value> +			<value>1</value> +			<value></value> +			<value>1</value> +		</row> +		<row> +			<value>3</value> +			<value>2</value> +			<value>2</value> +			<value>2</value> +			<value></value> +			<value>3</value> +			<value>3</value> +			<value>1</value> +			<value>1</value> +			<value></value> +			<value>1</value> +		</row> +		<row> +			<value>4</value> +			<value>1</value> +			<value>1</value> +			<value>1</value> +			<value>Other</value> +			<value>4</value> +			<value>4</value> +			<value>1</value> +			<value>1</value> +			<value></value> +			<value>1</value> +		</row> +	</table> +	<table name="phpbb_privmsgs"> +		<column>msg_id</column> +		<column>author_id</column> +		<column>message_edit_user</column> +		<column>message_text</column> +		<column>to_address</column> +		<column>bcc_address</column> +		<row> +			<value>1</value> +			<value>3</value> +			<value>3</value> +			<value></value> +			<value></value> +			<value></value> +		</row> +		<row> +			<value>2</value> +			<value>2</value> +			<value>2</value> +			<value></value> +			<value></value> +			<value></value> +		</row> +	</table> +	<table name="phpbb_privmsgs_to"> +		<column>msg_id</column> +		<column>user_id</column> +		<column>author_id</column> +		<row> +			<value>1</value> +			<value>3</value> +			<value>3</value> +		</row> +		<row> +			<value>1</value> +			<value>2</value> +			<value>3</value> +		</row> +		<row> +			<value>2</value> +			<value>3</value> +			<value>2</value> +		</row> +		<row> +			<value>2</value> +			<value>2</value> +			<value>2</value> +		</row> +	</table> +	<table name="phpbb_reports"> +		<column>report_id</column> +		<column>post_id</column> +		<column>user_id</column> +		<column>report_text</column> +		<column>reported_post_text</column> +		<row> +			<value>1</value> +			<value>1</value> +			<value>1</value> +			<value>Post Removed?</value> +			<value></value> +		</row> +		<row> +			<value>2</value> +			<value>3</value> +			<value>2</value> +			<value>Post Removed?</value> +			<value></value> +		</row> +		<row> +			<value>3</value> +			<value>2</value> +			<value>1</value> +			<value>Keep</value> +			<value></value> +		</row> +		<row> +			<value>4</value> +			<value>4</value> +			<value>2</value> +			<value>Remove Report</value> +			<value></value> +		</row> +	</table> +	<table name="phpbb_sessions"> +		<column>session_id</column> +		<column>session_user_id</column> +		<column>session_page</column> +		<row> +			<value>12345678901234567890123456789012</value> +			<value>2</value> +			<value></value> +		</row> +		<row> +			<value>12345678901234567890123456789013</value> +			<value>3</value> +			<value></value> +		</row> +	</table> +	<table name="phpbb_topics"> +		<column>topic_id</column> +		<column>forum_id</column> +		<column>topic_reported</column> +		<column>topic_poster</column> +		<column>topic_delete_user</column> +		<column>topic_first_poster_name</column> +		<column>topic_first_poster_colour</column> +		<column>topic_last_poster_id</column> +		<column>topic_last_poster_name</column> +		<column>topic_last_poster_colour</column> +		<row> +			<value>1</value> +			<value>1</value> +			<value>1</value> +			<value>2</value> +			<value>2</value> +			<value></value> +			<value>00AA00</value> +			<value>2</value> +			<value></value> +			<value>00AA00</value> +		</row> +		<row> +			<value>2</value> +			<value>2</value> +			<value>1</value> +			<value>1</value> +			<value>1</value> +			<value>Other</value> +			<value></value> +			<value>1</value> +			<value>Other</value> +			<value></value> +		</row> +		<row> +			<value>3</value> +			<value>3</value> +			<value>1</value> +			<value>2</value> +			<value>2</value> +			<value></value> +			<value>00AA00</value> +			<value>2</value> +			<value></value> +			<value>00AA00</value> +		</row> +		<row> +			<value>4</value> +			<value>4</value> +			<value>1</value> +			<value>1</value> +			<value>1</value> +			<value>Other</value> +			<value></value> +			<value>1</value> +			<value>Other</value> +			<value></value> +		</row> +	</table> +	<table name="phpbb_users"> +		<column>user_id</column> +		<column>username</column> +		<column>username_clean</column> +		<column>user_permissions</column> +		<column>user_sig</column> +		<column>user_posts</column> +		<row> +			<value>1</value> +			<value>Anonymous</value> +			<value>anonymous</value> +			<value></value> +			<value></value> +			<value>2</value> +		</row> +		<row> +			<value>2</value> +			<value>Foobar</value> +			<value>foobar</value> +			<value></value> +			<value></value> +			<value>2</value> +		</row> +	</table> +	<table name="phpbb_zebra"> +		<column>user_id</column> +		<column>zebra_id</column> +		<row> +			<value>1</value> +			<value>2</value> +		</row> +		<row> +			<value>1</value> +			<value>3</value> +		</row> +		<row> +			<value>2</value> +			<value>1</value> +		</row> +	</table> +	<table name="phpbb_user_group"> +		<column>user_id</column> +		<row> +			<value>2</value> +		</row> +		<row> +			<value>3</value> +		</row> +	</table> +	<table name="phpbb_topics_watch"> +		<column>user_id</column> +		<row> +			<value>2</value> +		</row> +		<row> +			<value>3</value> +		</row> +	</table> +	<table name="phpbb_forums_watch"> +		<column>user_id</column> +		<row> +			<value>2</value> +		</row> +		<row> +			<value>3</value> +		</row> +	</table> +	<table name="phpbb_acl_users"> +		<column>user_id</column> +		<row> +			<value>2</value> +		</row> +		<row> +			<value>3</value> +		</row> +	</table> +	<table name="phpbb_topics_track"> +		<column>user_id</column> +		<row> +			<value>2</value> +		</row> +		<row> +			<value>3</value> +		</row> +	</table> +	<table name="phpbb_forums_track"> +		<column>user_id</column> +		<row> +			<value>2</value> +		</row> +		<row> +			<value>3</value> +		</row> +	</table> +	<table name="phpbb_topics_posted"> +		<column>user_id</column> +		<row> +			<value>2</value> +		</row> +		<row> +			<value>3</value> +		</row> +	</table> +	<table name="phpbb_profile_fields_data"> +		<column>user_id</column> +		<column>pf_phpbb_interests</column> +		<column>pf_phpbb_occupation</column> +		<row> +			<value>2</value> +			<value></value> +			<value></value> +		</row> +		<row> +			<value>3</value> +			<value></value> +			<value></value> +		</row> +	</table> +	<table name="phpbb_moderator_cache"> +		<column>user_id</column> +		<row> +			<value>2</value> +		</row> +		<row> +			<value>3</value> +		</row> +	</table> +	<table name="phpbb_bookmarks"> +		<column>user_id</column> +		<row> +			<value>2</value> +		</row> +		<row> +			<value>3</value> +		</row> +	</table> +	<table name="phpbb_sessions_keys"> +		<column>user_id</column> +		<row> +			<value>2</value> +		</row> +		<row> +			<value>3</value> +		</row> +	</table> +	<table name="phpbb_privmsgs_folder"> +		<column>user_id</column> +		<row> +			<value>2</value> +		</row> +		<row> +			<value>3</value> +		</row> +	</table> +	<table name="phpbb_privmsgs_rules"> +		<column>user_id</column> +		<column>rule_string</column> +		<row> +			<value>2</value> +			<value></value> +		</row> +		<row> +			<value>3</value> +			<value></value> +		</row> +	</table> +	<table name="phpbb_drafts"> +		<column>user_id</column> +		<column>draft_message</column> +		<row> +			<value>2</value> +			<value></value> +		</row> +		<row> +			<value>3</value> +			<value></value> +		</row> +	</table> +</dataset> diff --git a/tests/mock/controller_helper.php b/tests/mock/controller_helper.php index f9d231258e..9c13c309f2 100644 --- a/tests/mock/controller_helper.php +++ b/tests/mock/controller_helper.php @@ -13,11 +13,13 @@  class phpbb_mock_controller_helper extends \phpbb\controller\helper  { -	public function __construct(\phpbb\template\template $template, \phpbb\user $user, \phpbb\config\config $config, \phpbb\controller\provider $provider, \phpbb\extension\manager $manager, $phpbb_root_path, $php_ext, $phpbb_root_path_ext) +	public function __construct(\phpbb\template\template $template, \phpbb\user $user, \phpbb\config\config $config, \phpbb\controller\provider $provider, \phpbb\extension\manager $manager, \phpbb\symfony_request $symfony_request, \phpbb\filesystem $filesystem, $phpbb_root_path, $php_ext, $phpbb_root_path_ext)  	{  		$this->template = $template;  		$this->user = $user;  		$this->config = $config; +		$this->symfony_request = $symfony_request; +		$this->filesystem = $filesystem;  		$this->phpbb_root_path = $phpbb_root_path;  		$this->php_ext = $php_ext;  		$provider->find_routing_files($manager->get_finder()); diff --git a/tests/mock/extension_manager.php b/tests/mock/extension_manager.php index 1a475f62e0..3b759fbbc2 100644 --- a/tests/mock/extension_manager.php +++ b/tests/mock/extension_manager.php @@ -13,11 +13,12 @@  class phpbb_mock_extension_manager extends \phpbb\extension\manager  { -	public function __construct($phpbb_root_path, $extensions = array()) +	public function __construct($phpbb_root_path, $extensions = array(), $container = null)  	{  		$this->phpbb_root_path = $phpbb_root_path;  		$this->php_ext = 'php';  		$this->extensions = $extensions;  		$this->filesystem = new \phpbb\filesystem(); +		$this->container = $container;  	}  } diff --git a/tests/mock/migrator.php b/tests/mock/migrator.php new file mode 100644 index 0000000000..293f115335 --- /dev/null +++ b/tests/mock/migrator.php @@ -0,0 +1,55 @@ +<?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. +* +*/ + +class phpbb_mock_migrator extends \phpbb\db\migrator +{ +	public function __construct() +	{ +	} + +	public function load_migration_state() +	{ +	} + +	public function set_migrations($class_names) +	{ +	} + +	public function update() +	{ +	} + +	public function revert($migration) +	{ +	} + +	public function unfulfillable($name) +	{ +	} + +	public function finished() +	{ +	} + +	public function migration_state($migration) +	{ +	} + +	public function populate_migrations($migrations) +	{ +	} + +	public function create_migrations_table() +	{ +	} +} diff --git a/tests/pagination/pagination_test.php b/tests/pagination/pagination_test.php index 321d6c2caf..95856dd07d 100644 --- a/tests/pagination/pagination_test.php +++ b/tests/pagination/pagination_test.php @@ -34,9 +34,10 @@ class phpbb_pagination_pagination_test extends phpbb_template_template_test_case  			->method('lang')  			->will($this->returnCallback(array($this, 'return_callback_implode'))); +		$filesystem = new \phpbb\filesystem();  		$manager = new phpbb_mock_extension_manager(dirname(__FILE__) . '/', array());  		$finder = new \phpbb\finder( -			new \phpbb\filesystem(), +			$filesystem,  			dirname(__FILE__) . '/',  			new phpbb_mock_cache()  		); @@ -46,7 +47,17 @@ class phpbb_pagination_pagination_test extends phpbb_template_template_test_case  		$provider = new \phpbb\controller\provider();  		$provider->find_routing_files($finder);  		$provider->find(dirname(__FILE__) . '/'); -		$this->helper = new phpbb_mock_controller_helper($this->template, $this->user, $this->config, $provider, $manager, '', 'php', dirname(__FILE__) . '/'); + +		$request = new phpbb_mock_request(); +		$request->overwrite('SCRIPT_NAME', '/app.php', \phpbb\request\request_interface::SERVER); +		$request->overwrite('SCRIPT_FILENAME', 'app.php', \phpbb\request\request_interface::SERVER); +		$request->overwrite('REQUEST_URI', '/app.php', \phpbb\request\request_interface::SERVER); + +		$symfony_request = new \phpbb\symfony_request( +			$request +		); + +		$this->helper = new phpbb_mock_controller_helper($this->template, $this->user, $this->config, $provider, $manager, $symfony_request, $filesystem, '', 'php', dirname(__FILE__) . '/');  		$this->pagination = new \phpbb\pagination($this->template, $this->user, $this->helper);  	} @@ -110,17 +121,17 @@ class phpbb_pagination_pagination_test extends phpbb_template_template_test_case  				:per_page:10  				:current_page:2  				:base_url: -				:previous::test -				:else:1:test -				:current:2:test/page/2 -				:else:3:test/page/3 -				:else:4:test/page/4 -				:else:5:test/page/5 -				:ellipsis:9:test/page/9 -				:else:10:test/page/10 -				:next::test/page/3 -				:u_prev:test -				:u_next:test/page/3', +				:previous::/test +				:else:1:/test +				:current:2:/test/page/2 +				:else:3:/test/page/3 +				:else:4:/test/page/4 +				:else:5:/test/page/5 +				:ellipsis:9:/test/page/9 +				:else:10:/test/page/10 +				:next::/test/page/3 +				:u_prev:/test +				:u_next:/test/page/3',  			),  			array(  				array('routes' => array( @@ -135,17 +146,17 @@ class phpbb_pagination_pagination_test extends phpbb_template_template_test_case  				:per_page:10  				:current_page:3  				:base_url: -				:previous::test/page/2 -				:else:1:test -				:else:2:test/page/2 -				:current:3:test/page/3 -				:else:4:test/page/4 -				:else:5:test/page/5 -				:ellipsis:9:test/page/9 -				:else:10:test/page/10 -				:next::test/page/4 -				:u_prev:test/page/2 -				:u_next:test/page/4', +				:previous::/test/page/2 +				:else:1:/test +				:else:2:/test/page/2 +				:current:3:/test/page/3 +				:else:4:/test/page/4 +				:else:5:/test/page/5 +				:ellipsis:9:/test/page/9 +				:else:10:/test/page/10 +				:next::/test/page/4 +				:u_prev:/test/page/2 +				:u_next:/test/page/4',  			),  		);  	} diff --git a/tests/session/fixtures/sessions_empty.xml b/tests/session/fixtures/sessions_empty.xml index 2acba58f45..068951dc4c 100644 --- a/tests/session/fixtures/sessions_empty.xml +++ b/tests/session/fixtures/sessions_empty.xml @@ -30,4 +30,11 @@  		<column>session_ip</column>  		<column>session_browser</column>  	</table> +	<table name="phpbb_banlist"> +		<column>ban_id</column> +		<column>ban_userid</column> +		<column>ban_email</column> +		<column>ban_reason</column> +		<column>ban_give_reason</column> +	</table>  </dataset> diff --git a/tests/test_framework/phpbb_database_test_case.php b/tests/test_framework/phpbb_database_test_case.php index 46276bcfcb..9dbb7150f1 100644 --- a/tests/test_framework/phpbb_database_test_case.php +++ b/tests/test_framework/phpbb_database_test_case.php @@ -69,10 +69,9 @@ abstract class phpbb_database_test_case extends PHPUnit_Extensions_Database_Test  				global $phpbb_root_path, $phpEx, $table_prefix;  				$finder = new \phpbb\finder(new \phpbb\filesystem(), $phpbb_root_path, null, $phpEx); -				$classes = $finder->core_path('phpbb/') -					->core_directory('/db/migration/data') +				$classes = $finder->core_path('phpbb/db/migration/data/')  					->set_extensions($setup_extensions) -					->extension_directory('migrations') +					->extension_directory('/migrations')  					->get_classes();  				$db = new \phpbb\db\driver\sqlite(); | 
