From 9c4f0d51df4424f410534686f00bf629d98d53e0 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Thu, 10 Jan 2013 10:59:20 +0100 Subject: [PATCH 001/281] [ticket/11314] Cleanup core.js coding function errorHandler() was used in returnHandler() before it was defined. The unused variable alert has been removed from errorHandler(). Overuse of the var keyword for the variable sign has been removed and the if statement has been simplified. The definition of the variable i has been moved outside of the for loop definition. The var keyword shouldn't be used inside the definition of the for loop. PHPBB3-11314 --- phpBB/assets/javascript/core.js | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/phpBB/assets/javascript/core.js b/phpBB/assets/javascript/core.js index 16ed04746d..9323f4a447 100644 --- a/phpBB/assets/javascript/core.js +++ b/phpBB/assets/javascript/core.js @@ -252,6 +252,11 @@ phpbb.ajaxify = function(options) { return; } + function errorHandler() { + phpbb.clearLoadingTimeout(); + phpbb.alert(dark.attr('data-ajax-error-title'), dark.attr('data-ajax-error-text')); + } + /** * This is a private function used to handle the callbacks, refreshes * and alert. It calls the callback, refreshes the page if necessary, and @@ -320,13 +325,6 @@ phpbb.ajaxify = function(options) { } } - function errorHandler() { - var alert; - - phpbb.clearLoadingTimeout(); - alert = phpbb.alert(dark.attr('data-ajax-error-title'), dark.attr('data-ajax-error-text')); - } - // 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'); @@ -440,12 +438,11 @@ 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 = '-'; if (offset < 0) { - var sign = '+'; + sign = '+'; offset = -offset; - } else { - var sign = '-'; } var minutes = offset % 60; @@ -466,8 +463,9 @@ phpbb.timezonePreselectSelect = function(forceSelector) { var prefix = 'GMT' + sign + hours + ':' + minutes; var prefixLength = prefix.length; var selectorOptions = $('#tz_date > option'); + var i; - for (var i = 0; i < selectorOptions.length; ++i) { + for (i = 0; i < selectorOptions.length; ++i) { var option = selectorOptions[i]; if (option.value.substring(0, prefixLength) == prefix) { From 0fc863c68a6832fe6589b14b2ca9107f7b570621 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Thu, 10 Jan 2013 11:06:05 +0100 Subject: [PATCH 002/281] [ticket/11314] Add missing semi-colons Omitting the semi-colon is not legal behavior for JavaScript. PHPBB3-11314 --- phpBB/adm/style/ajax.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/phpBB/adm/style/ajax.js b/phpBB/adm/style/ajax.js index 294a35b615..8f7c210e00 100644 --- a/phpBB/adm/style/ajax.js +++ b/phpBB/adm/style/ajax.js @@ -115,9 +115,9 @@ phpbb.addAjaxCallback('activate_deactivate', function(res) { el.text(res.text); if (newHref.indexOf('deactivate') !== -1) { - newHref = newHref.replace('deactivate', 'activate') + newHref = newHref.replace('deactivate', 'activate'); } else { - newHref = newHref.replace('activate', 'deactivate') + newHref = newHref.replace('activate', 'deactivate'); } el.attr('href', newHref); From f7af4eb2e98a70cce267d01828437e205527e47f Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Thu, 10 Jan 2013 11:11:30 +0100 Subject: [PATCH 003/281] [ticket/11314] Use return variable instead of overusing the return keyword Use a return variable and modify it to our needs. PHPBB3-11314 --- phpBB/styles/prosilver/template/ajax.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/phpBB/styles/prosilver/template/ajax.js b/phpBB/styles/prosilver/template/ajax.js index 8583fb565c..771981b3e3 100644 --- a/phpBB/styles/prosilver/template/ajax.js +++ b/phpBB/styles/prosilver/template/ajax.js @@ -173,18 +173,19 @@ phpbb.ajaxify({ refresh: true, filter: function (data) { var action = $('#quick-mod-select').val(); + var ret = false; if (action === 'make_normal') { - return $(this).find('select option[value="make_global"]').length > 0; + ret = $(this).find('select option[value="make_global"]').length > 0; } else if (action === 'lock' || action === 'unlock') { - return true; + ret = true; } if (action === 'delete_topic' || action === 'make_sticky' || action === 'make_announce' || action === 'make_global') { - return true; + ret = true; } - return false; + return ret; } }); From c31f489cce8fd5d60eb484928221bef0666f3c06 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Thu, 10 Jan 2013 11:14:07 +0100 Subject: [PATCH 004/281] [ticket/11314] Add missing "use strict" to timezone.js files PHPBB3-11314 --- phpBB/adm/style/timezone.js | 2 ++ phpBB/styles/prosilver/template/timezone.js | 2 ++ phpBB/styles/subsilver2/template/timezone.js | 2 ++ 3 files changed, 6 insertions(+) diff --git a/phpBB/adm/style/timezone.js b/phpBB/adm/style/timezone.js index 419d37c34f..b5e27c907c 100644 --- a/phpBB/adm/style/timezone.js +++ b/phpBB/adm/style/timezone.js @@ -1,5 +1,7 @@ (function($) { // Avoid conflicts with other libraries +"use strict"; + $('#tz_date').change(function() { phpbb.timezoneSwitchDate(false); }); diff --git a/phpBB/styles/prosilver/template/timezone.js b/phpBB/styles/prosilver/template/timezone.js index af8206d12d..b0e8a38366 100644 --- a/phpBB/styles/prosilver/template/timezone.js +++ b/phpBB/styles/prosilver/template/timezone.js @@ -1,5 +1,7 @@ (function($) { // Avoid conflicts with other libraries +"use strict"; + $('#tz_date').change(function() { phpbb.timezoneSwitchDate(false); }); diff --git a/phpBB/styles/subsilver2/template/timezone.js b/phpBB/styles/subsilver2/template/timezone.js index af8206d12d..b0e8a38366 100644 --- a/phpBB/styles/subsilver2/template/timezone.js +++ b/phpBB/styles/subsilver2/template/timezone.js @@ -1,5 +1,7 @@ (function($) { // Avoid conflicts with other libraries +"use strict"; + $('#tz_date').change(function() { phpbb.timezoneSwitchDate(false); }); From 49edfa49ab9b475e02997f8a89050acc73bf30c8 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Sat, 12 Jan 2013 19:08:34 +0100 Subject: [PATCH 005/281] [ticket/11314] Fix whitespace issues PHPBB3-11314 --- phpBB/assets/javascript/core.js | 12 ++++++------ phpBB/styles/subsilver2/template/editor.js | 5 ++--- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/phpBB/assets/javascript/core.js b/phpBB/assets/javascript/core.js index 9323f4a447..f38b35d613 100644 --- a/phpBB/assets/javascript/core.js +++ b/phpBB/assets/javascript/core.js @@ -57,7 +57,7 @@ phpbb.clearLoadingTimeout = function() { * @param string title Title of the message, eg "Information" (HTML). * @param string msg Message to display (HTML). * @param bool fadedark Remove the dark background when done? Defaults - * to yes. + * to yes. * * @returns object Returns the div created. */ @@ -121,9 +121,9 @@ phpbb.alert = function(title, msg, fadedark) { * * @param string msg Message to display (HTML). * @param function callback Callback. Bool param, whether the user pressed - * yes or no (or whatever their language is). + * yes or no (or whatever their language is). * @param bool fadedark Remove the dark background when done? Defaults - * to yes. + * to yes. * * @returns object Returns the div created. */ @@ -232,10 +232,10 @@ phpbb.parseQuerystring = function(string) { * * @param object options Options. * @param bool/function refresh If we are sent back a refresh, should it be - * acted upon? This can either be true / false / a function. + * acted upon? This can either be true / false / a function. * @param function callback Callback to call on completion of event. Has - * three parameters: the element that the event was evoked from, the JSON - * that was returned and (if it is a form) the form action. + * three parameters: the element that the event was evoked from, the JSON + * that was returned and (if it is a form) the form action. */ phpbb.ajaxify = function(options) { var elements = $(options.selector), diff --git a/phpBB/styles/subsilver2/template/editor.js b/phpBB/styles/subsilver2/template/editor.js index 151cf53ff1..0b5b15643a 100644 --- a/phpBB/styles/subsilver2/template/editor.js +++ b/phpBB/styles/subsilver2/template/editor.js @@ -179,11 +179,10 @@ function insert_text(text, spaces, popup) { textarea.value = textarea.value + text; } - if (!popup) + if (!popup) { textarea.focus(); - } - + } } /** From 2f6b072bb13ce9d7c7784136bedec651b73ae11b Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Sun, 13 Jan 2013 23:00:48 +0100 Subject: [PATCH 006/281] [ticket/11314] Add missing radix parameters PHPBB3-11314 --- phpBB/adm/style/editor.js | 2 +- phpBB/styles/prosilver/template/editor.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/phpBB/adm/style/editor.js b/phpBB/adm/style/editor.js index c9e8afe08e..2b814a10c6 100644 --- a/phpBB/adm/style/editor.js +++ b/phpBB/adm/style/editor.js @@ -10,7 +10,7 @@ var theSelection = false; // Check for Browser & Platform for PC & IE specific bits // More details from: http://www.mozilla.org/docs/web-developer/sniffer/browser_type.html var clientPC = navigator.userAgent.toLowerCase(); // Get client info -var clientVer = parseInt(navigator.appVersion); // Get browser version +var clientVer = parseInt(navigator.appVersion, 10); // Get browser version var is_ie = ((clientPC.indexOf('msie') != -1) && (clientPC.indexOf('opera') == -1)); var is_win = ((clientPC.indexOf('win') != -1) || (clientPC.indexOf('16bit') != -1)); diff --git a/phpBB/styles/prosilver/template/editor.js b/phpBB/styles/prosilver/template/editor.js index c16b0ef703..c099466005 100644 --- a/phpBB/styles/prosilver/template/editor.js +++ b/phpBB/styles/prosilver/template/editor.js @@ -11,7 +11,7 @@ var bbcodeEnabled = true; // Check for Browser & Platform for PC & IE specific bits // More details from: http://www.mozilla.org/docs/web-developer/sniffer/browser_type.html var clientPC = navigator.userAgent.toLowerCase(); // Get client info -var clientVer = parseInt(navigator.appVersion); // Get browser version +var clientVer = parseInt(navigator.appVersion, 10); // Get browser version var is_ie = ((clientPC.indexOf('msie') != -1) && (clientPC.indexOf('opera') == -1)); var is_win = ((clientPC.indexOf('win') != -1) || (clientPC.indexOf('16bit') != -1)); From 6704a82bbea45ab53a05c7490c87e46e1c57dd00 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Sat, 9 Mar 2013 09:21:31 -0600 Subject: [PATCH 007/281] [ticket/11422] Increment assets when database_update is complete PHPBB3-11422 --- phpBB/install/database_update.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/phpBB/install/database_update.php b/phpBB/install/database_update.php index 2ecddf49d4..867235e607 100644 --- a/phpBB/install/database_update.php +++ b/phpBB/install/database_update.php @@ -41,10 +41,12 @@ if (!function_exists('phpbb_require_updated')) } } -function phpbb_end_update($cache) +function phpbb_end_update($cache, $config) { $cache->purge(); + $config->increment('assets_version', 1); + ?>

@@ -232,7 +234,7 @@ while (!$migrator->finished()) { echo $e->getLocalisedMessage($user); - phpbb_end_update($cache); + phpbb_end_update($cache, $config); } $state = array_merge(array( @@ -265,7 +267,7 @@ while (!$migrator->finished()) echo $user->lang['DATABASE_UPDATE_NOT_COMPLETED'] . '
'; echo '' . $user->lang['DATABASE_UPDATE_CONTINUE'] . ''; - phpbb_end_update($cache); + phpbb_end_update($cache, $config); } } @@ -276,4 +278,4 @@ if ($orig_version != $config['version']) echo $user->lang['DATABASE_UPDATE_COMPLETE']; -phpbb_end_update($cache); +phpbb_end_update($cache, $config); From df98de971ca9e8362f1bbf5ce59967db16268531 Mon Sep 17 00:00:00 2001 From: erangamapa Date: Tue, 12 Mar 2013 10:19:29 +0530 Subject: [PATCH 008/281] [ticket/11106] Undefined index EDITED_TIME_TOTAL notice. When viewing a private message, when message edit count is 1 Undefined index EDITED_TIME_TOTAL php notice appears. Changed the message formatting method to what is used in viewtopic.php. PHPBB3-11106 --- phpBB/includes/ucp/ucp_pm_viewmessage.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/phpBB/includes/ucp/ucp_pm_viewmessage.php b/phpBB/includes/ucp/ucp_pm_viewmessage.php index c85b05f144..e2b61f1b02 100644 --- a/phpBB/includes/ucp/ucp_pm_viewmessage.php +++ b/phpBB/includes/ucp/ucp_pm_viewmessage.php @@ -94,8 +94,7 @@ function view_message($id, $mode, $folder_id, $msg_id, $folder, $message_row) // Editing information if ($message_row['message_edit_count'] && $config['display_last_edited']) { - $l_edit_time_total = ($message_row['message_edit_count'] == 1) ? $user->lang['EDITED_TIME_TOTAL'] : $user->lang['EDITED_TIMES_TOTAL']; - $l_edited_by = '

' . sprintf($l_edit_time_total, (!$message_row['message_edit_user']) ? $message_row['username'] : $message_row['message_edit_user'], $user->format_date($message_row['message_edit_time'], false, true), $message_row['message_edit_count']); + $l_edited_by = $user->lang('EDITED_TIMES_TOTAL', (int) $message_row['message_edit_count'], (!$message_row['message_edit_user']) ? $message_row['username'] : $message_row['message_edit_user'], $user->format_date($message_row['message_edit_time'], false, true)); } else { From 567eefb2bd2bf280391786ea171dad0bdb0b442d Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 12 Mar 2013 22:35:31 +0100 Subject: [PATCH 009/281] [ticket/11362] Correctly sanitise the directory path We need to correctly remove ../ form the path if possible by removing the previous folder aswell. Otherwise the finder is unable to locate /adm/style directories in extensions as he is looking for /adm/../adm/style instead. PHPBB3-11362 --- phpBB/includes/extension/finder.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/includes/extension/finder.php b/phpBB/includes/extension/finder.php index f71e32bc8d..d9aacc38ff 100644 --- a/phpBB/includes/extension/finder.php +++ b/phpBB/includes/extension/finder.php @@ -227,7 +227,7 @@ class phpbb_extension_finder */ protected function sanitise_directory($directory) { - $directory = preg_replace('#(?:^|/)\./#', '/', $directory); + $directory = phpbb_clean_path($directory); $dir_len = strlen($directory); if ($dir_len > 1 && $directory[$dir_len - 1] === '/') From 1fd5be859e3fe85e67fe7f5632e4630b96ca3634 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 12 Mar 2013 22:45:44 +0100 Subject: [PATCH 010/281] [ticket/11362] Add unit test for ../ in directory paths PHPBB3-11362 --- tests/extension/finder_test.php | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/extension/finder_test.php b/tests/extension/finder_test.php index c96b11a73c..3781591b19 100644 --- a/tests/extension/finder_test.php +++ b/tests/extension/finder_test.php @@ -6,6 +6,7 @@ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ +require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; class phpbb_extension_finder_test extends phpbb_test_case { @@ -142,6 +143,21 @@ class phpbb_extension_finder_test extends phpbb_test_case ); } + public function test_uncleansub_directory_get_classes() + { + $classes = $this->finder + ->directory('/sub/../sub/type') + ->get_classes(); + + sort($classes); + $this->assertEquals( + array( + 'phpbb_ext_foo_sub_type_alternative', + ), + $classes + ); + } + /** * These do not work because of changes with PHPBB3-11386 * They do not seem neccessary to me, so I am commenting them out for now From a38a92424ddf00383c17a6dffffe522065e25c9f Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Thu, 14 Mar 2013 10:45:17 -0700 Subject: [PATCH 011/281] [ticket/10155] Update jQuery to 1.8.3 Currently included jQuery is old by now, v1.6.2. We should update to 1.8.3. This allows us to take advantage of the latest form of jQuery event delegation ($.on). I don't think it wise to update to jQuery 1.9.x yet, as many 3rd party scripts still need to be updated to cope with its deprecated features ($.browser). Therefor, 1.8.3 is the latest and most widely compatible stable version right now. PHPBB3-10155 --- phpBB/assets/javascript/jquery.js | 20 ++------------------ phpBB/includes/db/migration/data/310/dev.php | 2 +- phpBB/install/schemas/schema_data.sql | 2 +- 3 files changed, 4 insertions(+), 20 deletions(-) diff --git a/phpBB/assets/javascript/jquery.js b/phpBB/assets/javascript/jquery.js index 48590ecb96..83589daa70 100644 --- a/phpBB/assets/javascript/jquery.js +++ b/phpBB/assets/javascript/jquery.js @@ -1,18 +1,2 @@ -/*! - * jQuery JavaScript Library v1.6.2 - * http://jquery.com/ - * - * Copyright 2011, John Resig - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * Includes Sizzle.js - * http://sizzlejs.com/ - * Copyright 2011, The Dojo Foundation - * Released under the MIT, BSD, and GPL Licenses. - * - * Date: Thu Jun 30 14:16:56 2011 -0400 - */ -(function(a,b){function cv(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cs(a){if(!cg[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){ch||(ch=c.createElement("iframe"),ch.frameBorder=ch.width=ch.height=0),b.appendChild(ch);if(!ci||!ch.createElement)ci=(ch.contentWindow||ch.contentDocument).document,ci.write((c.compatMode==="CSS1Compat"?"":"")+""),ci.close();d=ci.createElement(a),ci.body.appendChild(d),e=f.css(d,"display"),b.removeChild(ch)}cg[a]=e}return cg[a]}function cr(a,b){var c={};f.each(cm.concat.apply([],cm.slice(0,b)),function(){c[this]=a});return c}function cq(){cn=b}function cp(){setTimeout(cq,0);return cn=f.now()}function cf(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ce(){try{return new a.XMLHttpRequest}catch(b){}}function b$(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g0){c!=="border"&&f.each(e,function(){c||(d-=parseFloat(f.css(a,"padding"+this))||0),c==="margin"?d+=parseFloat(f.css(a,c+this))||0:d-=parseFloat(f.css(a,"border"+this+"Width"))||0});return d+"px"}d=bx(a,b,b);if(d<0||d==null)d=a.style[b]||0;d=parseFloat(d)||0,c&&f.each(e,function(){d+=parseFloat(f.css(a,"padding"+this))||0,c!=="padding"&&(d+=parseFloat(f.css(a,"border"+this+"Width"))||0),c==="margin"&&(d+=parseFloat(f.css(a,c+this))||0)});return d+"px"}function bm(a,b){b.src?f.ajax({url:b.src,async:!1,dataType:"script"}):f.globalEval((b.text||b.textContent||b.innerHTML||"").replace(be,"/*$0*/")),b.parentNode&&b.parentNode.removeChild(b)}function bl(a){f.nodeName(a,"input")?bk(a):"getElementsByTagName"in a&&f.grep(a.getElementsByTagName("input"),bk)}function bk(a){if(a.type==="checkbox"||a.type==="radio")a.defaultChecked=a.checked}function bj(a){return"getElementsByTagName"in a?a.getElementsByTagName("*"):"querySelectorAll"in a?a.querySelectorAll("*"):[]}function bi(a,b){var c;if(b.nodeType===1){b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase();if(c==="object")b.outerHTML=a.outerHTML;else if(c!=="input"||a.type!=="checkbox"&&a.type!=="radio"){if(c==="option")b.selected=a.defaultSelected;else if(c==="input"||c==="textarea")b.defaultValue=a.defaultValue}else a.checked&&(b.defaultChecked=b.checked=a.checked),b.value!==a.value&&(b.value=a.value);b.removeAttribute(f.expando)}}function bh(a,b){if(b.nodeType===1&&!!f.hasData(a)){var c=f.expando,d=f.data(a),e=f.data(b,d);if(d=d[c]){var g=d.events;e=e[c]=f.extend({},d);if(g){delete e.handle,e.events={};for(var h in g)for(var i=0,j=g[h].length;i=0===c})}function V(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function N(a,b){return(a&&a!=="*"?a+".":"")+b.replace(z,"`").replace(A,"&")}function M(a){var b,c,d,e,g,h,i,j,k,l,m,n,o,p=[],q=[],r=f._data(this,"events");if(!(a.liveFired===this||!r||!r.live||a.target.disabled||a.button&&a.type==="click")){a.namespace&&(n=new RegExp("(^|\\.)"+a.namespace.split(".").join("\\.(?:.*\\.)?")+"(\\.|$)")),a.liveFired=this;var s=r.live.slice(0);for(i=0;ic)break;a.currentTarget=e.elem,a.data=e.handleObj.data,a.handleObj=e.handleObj,o=e.handleObj.origHandler.apply(e.elem,arguments);if(o===!1||a.isPropagationStopped()){c=e.level,o===!1&&(b=!1);if(a.isImmediatePropagationStopped())break}}return b}}function K(a,c,d){var e=f.extend({},d[0]);e.type=a,e.originalEvent={},e.liveFired=b,f.event.handle.call(c,e),e.isDefaultPrevented()&&d[0].preventDefault()}function E(){return!0}function D(){return!1}function m(a,c,d){var e=c+"defer",g=c+"queue",h=c+"mark",i=f.data(a,e,b,!0);i&&(d==="queue"||!f.data(a,g,b,!0))&&(d==="mark"||!f.data(a,h,b,!0))&&setTimeout(function(){!f.data(a,g,b,!0)&&!f.data(a,h,b,!0)&&(f.removeData(a,e,!0),i.resolve())},0)}function l(a){for(var b in a)if(b!=="toJSON")return!1;return!0}function k(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(j,"$1-$2").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNaN(d)?i.test(d)?f.parseJSON(d):d:parseFloat(d)}catch(g){}f.data(a,c,d)}else d=b}return d}var c=a.document,d=a.navigator,e=a.location,f=function(){function J(){if(!e.isReady){try{c.documentElement.doScroll("left")}catch(a){setTimeout(J,1);return}e.ready()}}var e=function(a,b){return new e.fn.init(a,b,h)},f=a.jQuery,g=a.$,h,i=/^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/\d/,n=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,o=/^[\],:{}\s]*$/,p=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,q=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,r=/(?:^|:|,)(?:\s*\[)+/g,s=/(webkit)[ \/]([\w.]+)/,t=/(opera)(?:.*version)?[ \/]([\w.]+)/,u=/(msie) ([\w.]+)/,v=/(mozilla)(?:.*? rv:([\w.]+))?/,w=/-([a-z])/ig,x=function(a,b){return b.toUpperCase()},y=d.userAgent,z,A,B,C=Object.prototype.toString,D=Object.prototype.hasOwnProperty,E=Array.prototype.push,F=Array.prototype.slice,G=String.prototype.trim,H=Array.prototype.indexOf,I={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=n.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.6.2",length:0,size:function(){return this.length},toArray:function(){return F.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?E.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),A.done(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(F.apply(this,arguments),"slice",F.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:E,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j0)return;A.resolveWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").unbind("ready")}},bindReady:function(){if(!A){A=e._Deferred();if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",B,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",B),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&J()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNaN:function(a){return a==null||!m.test(a)||isNaN(a)},type:function(a){return a==null?String(a):I[C.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;if(a.constructor&&!D.call(a,"constructor")&&!D.call(a.constructor.prototype,"isPrototypeOf"))return!1;var c;for(c in a);return c===b||D.call(a,c)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw a},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(o.test(b.replace(p,"@").replace(q,"]").replace(r,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(b,c,d){a.DOMParser?(d=new DOMParser,c=d.parseFromString(b,"text/xml")):(c=new ActiveXObject("Microsoft.XMLDOM"),c.async="false",c.loadXML(b)),d=c.documentElement,(!d||!d.nodeName||d.nodeName==="parsererror")&&e.error("Invalid XML: "+b);return c},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(w,x)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i1?h.call(arguments,0):c,--e||g.resolveWith(g,h.call(b,0))}}var b=arguments,c=0,d=b.length,e=d,g=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred();if(d>1){for(;c
a",d=a.getElementsByTagName("*"),e=a.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=a.getElementsByTagName("input")[0],k={leadingWhitespace:a.firstChild.nodeType===3,tbody:!a.getElementsByTagName("tbody").length,htmlSerialize:!!a.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55$/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:a.className!=="t",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,k.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,k.optDisabled=!h.disabled;try{delete a.test}catch(v){k.deleteExpando=!1}!a.addEventListener&&a.attachEvent&&a.fireEvent&&(a.attachEvent("onclick",function(){k.noCloneEvent=!1}),a.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),k.radioValue=i.value==="t",i.setAttribute("checked","checked"),a.appendChild(i),l=c.createDocumentFragment(),l.appendChild(a.firstChild),k.checkClone=l.cloneNode(!0).cloneNode(!0).lastChild.checked,a.innerHTML="",a.style.width=a.style.paddingLeft="1px",m=c.getElementsByTagName("body")[0],o=c.createElement(m?"div":"body"),p={visibility:"hidden",width:0,height:0,border:0,margin:0},m&&f.extend(p,{position:"absolute",left:-1e3,top:-1e3});for(t in p)o.style[t]=p[t];o.appendChild(a),n=m||b,n.insertBefore(o,n.firstChild),k.appendChecked=i.checked,k.boxModel=a.offsetWidth===2,"zoom"in a.style&&(a.style.display="inline",a.style.zoom=1,k.inlineBlockNeedsLayout=a.offsetWidth===2,a.style.display="",a.innerHTML="
",k.shrinkWrapBlocks=a.offsetWidth!==2),a.innerHTML="
t
",q=a.getElementsByTagName("td"),u=q[0].offsetHeight===0,q[0].style.display="",q[1].style.display="none",k.reliableHiddenOffsets=u&&q[0].offsetHeight===0,a.innerHTML="",c.defaultView&&c.defaultView.getComputedStyle&&(j=c.createElement("div"),j.style.width="0",j.style.marginRight="0",a.appendChild(j),k.reliableMarginRight=(parseInt((c.defaultView.getComputedStyle(j,null)||{marginRight:0}).marginRight,10)||0)===0),o.innerHTML="",n.removeChild(o);if(a.attachEvent)for(t in{submit:1,change:1,focusin:1})s="on"+t,u=s in a,u||(a.setAttribute(s,"return;"),u=typeof a[s]=="function"),k[t+"Bubbles"]=u;o=l=g=h=m=j=a=i=null;return k}(),f.boxModel=f.support.boxModel;var i=/^(?:\{.*\}|\[.*\])$/,j=/([a-z])([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!l(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g=f.expando,h=typeof c=="string",i,j=a.nodeType,k=j?f.cache:a,l=j?a[f.expando]:a[f.expando]&&f.expando;if((!l||e&&l&&!k[l][g])&&h&&d===b)return;l||(j?a[f.expando]=l=++f.uuid:l=f.expando),k[l]||(k[l]={},j||(k[l].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?k[l][g]=f.extend(k[l][g],c):k[l]=f.extend(k[l],c);i=k[l],e&&(i[g]||(i[g]={}),i=i[g]),d!==b&&(i[f.camelCase(c)]=d);if(c==="events"&&!i[c])return i[g]&&i[g].events;return h?i[f.camelCase(c)]||i[c]:i}},removeData:function(b,c,d){if(!!f.acceptData(b)){var e=f.expando,g=b.nodeType,h=g?f.cache:b,i=g?b[f.expando]:f.expando;if(!h[i])return;if(c){var j=d?h[i][e]:h[i];if(j){delete j[c];if(!l(j))return}}if(d){delete h[i][e];if(!l(h[i]))return}var k=h[i][e];f.support.deleteExpando||h!=a?delete h[i]:h[i]=null,k?(h[i]={},g||(h[i].toJSON=f.noop),h[i][e]=k):g&&(f.support.deleteExpando?delete b[f.expando]:b.removeAttribute?b.removeAttribute(f.expando):b[f.expando]=null)}},_data:function(a,b,c){return f.data(a,b,c,!0)},acceptData:function(a){if(a.nodeName){var b=f.noData[a.nodeName.toLowerCase()];if(b)return b!==!0&&a.getAttribute("classid")===b}return!0}}),f.fn.extend({data:function(a,c){var d=null;if(typeof a=="undefined"){if(this.length){d=f.data(this[0]);if(this[0].nodeType===1){var e=this[0].attributes,g;for(var h=0,i=e.length;h-1)return!0;return!1},val:function(a){var c,d,e=this[0];if(!arguments.length){if(e){c=f.valHooks[e.nodeName.toLowerCase()]||f.valHooks[e.type];if(c&&"get"in c&&(d=c.get(e,"value"))!==b)return d;d=e.value;return typeof d=="string"?d.replace(p,""):d==null?"":d}return b}var g=f.isFunction(a);return this.each(function(d){var e=f(this),h;if(this.nodeType===1){g?h=a.call(this,d,e.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c=a.selectedIndex,d=[],e=a.options,g=a.type==="select-one";if(c<0)return null;for(var h=g?c:0,i=g?c+1:e.length;h=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attrFix:{tabindex:"tabIndex"},attr:function(a,c,d,e){var g=a.nodeType;if(!a||g===3||g===8||g===2)return b;if(e&&c in f.attrFn)return f(a)[c](d);if(!("getAttribute"in a))return f.prop(a,c,d);var h,i,j=g!==1||!f.isXMLDoc(a);j&&(c=f.attrFix[c]||c,i=f.attrHooks[c],i||(t.test(c)?i=w:v&&c!=="className"&&(f.nodeName(a,"form")||u.test(c))&&(i=v)));if(d!==b){if(d===null){f.removeAttr(a,c);return b}if(i&&"set"in i&&j&&(h=i.set(a,d,c))!==b)return h;a.setAttribute(c,""+d);return d}if(i&&"get"in i&&j&&(h=i.get(a,c))!==null)return h;h=a.getAttribute(c);return h===null?b:h},removeAttr:function(a,b){var c;a.nodeType===1&&(b=f.attrFix[b]||b,f.support.getSetAttribute?a.removeAttribute(b):(f.attr(a,b,""),a.removeAttributeNode(a.getAttributeNode(b))),t.test(b)&&(c=f.propFix[b]||b)in a&&(a[c]=!1))},attrHooks:{type:{set:function(a,b){if(q.test(a.nodeName)&&a.parentNode)f.error("type property can't be changed");else if(!f.support.radioValue&&b==="radio"&&f.nodeName(a,"input")){var c=a.value;a.setAttribute("type",b),c&&(a.value=c);return b}}},tabIndex:{get:function(a){var c=a.getAttributeNode("tabIndex");return c&&c.specified?parseInt(c.value,10):r.test(a.nodeName)||s.test(a.nodeName)&&a.href?0:b}},value:{get:function(a,b){if(v&&f.nodeName(a,"button"))return v.get(a,b);return b in a?a.value:null},set:function(a,b,c){if(v&&f.nodeName(a,"button"))return v.set(a,b,c);a.value=b}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(a,c,d){var e=a.nodeType;if(!a||e===3||e===8||e===2)return b;var g,h,i=e!==1||!f.isXMLDoc(a);i&&(c=f.propFix[c]||c,h=f.propHooks[c]);return d!==b?h&&"set"in h&&(g=h.set(a,d,c))!==b?g:a[c]=d:h&&"get"in h&&(g=h.get(a,c))!==b?g:a[c]},propHooks:{}}),w={get:function(a,c){return f.prop(a,c)?c.toLowerCase():b},set:function(a,b,c){var d;b===!1?f.removeAttr(a,c):(d=f.propFix[c]||c,d in a&&(a[d]=!0),a.setAttribute(c,c.toLowerCase()));return c}},f.support.getSetAttribute||(f.attrFix=f.propFix,v=f.attrHooks.name=f.attrHooks.title=f.valHooks.button={get:function(a,c){var d;d=a.getAttributeNode(c);return d&&d.nodeValue!==""?d.nodeValue:b},set:function(a,b,c){var d=a.getAttributeNode(c);if(d){d.nodeValue=b;return b}}},f.each(["width","height"],function(a,b){f.attrHooks[b]=f.extend(f.attrHooks[b],{set:function(a,c){if(c===""){a.setAttribute(b,"auto");return c}}})})),f.support.hrefNormalized||f.each(["href","src","width","height"],function(a,c){f.attrHooks[c]=f.extend(f.attrHooks[c],{get:function(a){var d=a.getAttribute(c,2);return d===null?b:d}})}),f.support.style||(f.attrHooks.style={get:function(a){return a.style.cssText.toLowerCase()||b},set:function(a,b){return a.style.cssText=""+b}}),f.support.optSelected||(f.propHooks.selected=f.extend(f.propHooks.selected,{get:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}})),f.support.checkOn||f.each(["radio","checkbox"],function(){f.valHooks[this]={get:function(a){return a.getAttribute("value")===null?"on":a.value}}}),f.each(["radio","checkbox"],function(){f.valHooks[this]=f.extend(f.valHooks[this],{set:function(a,b){if(f.isArray(b))return a.checked=f.inArray(f(a).val(),b)>=0}})});var x=/\.(.*)$/,y=/^(?:textarea|input|select)$/i,z=/\./g,A=/ /g,B=/[^\w\s.|`]/g,C=function(a){return a.replace(B,"\\$&")};f.event={add:function(a,c,d,e){if(a.nodeType!==3&&a.nodeType!==8){if(d===!1)d=D;else if(!d)return;var g,h;d.handler&&(g=d,d=g.handler),d.guid||(d.guid=f.guid++);var i=f._data(a);if(!i)return;var j=i.events,k=i.handle;j||(i.events=j={}),k||(i.handle=k=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.handle.apply(k.elem,arguments):b}),k.elem=a,c=c.split(" ");var l,m=0,n;while(l=c[m++]){h=g?f.extend({},g):{handler:d,data:e},l.indexOf(".")>-1?(n=l.split("."),l=n.shift(),h.namespace=n.slice(0).sort().join(".")):(n=[],h.namespace=""),h.type=l,h.guid||(h.guid=d.guid);var o=j[l],p=f.event.special[l]||{};if(!o){o=j[l]=[];if(!p.setup||p.setup.call(a,e,n,k)===!1)a.addEventListener?a.addEventListener(l,k,!1):a.attachEvent&&a.attachEvent("on"+l,k)}p.add&&(p.add.call(a,h),h.handler.guid||(h.handler.guid=d.guid)),o.push(h),f.event.global[l]=!0}a=null}},global:{},remove:function(a,c,d,e){if(a.nodeType!==3&&a.nodeType!==8){d===!1&&(d=D);var g,h,i,j,k=0,l,m,n,o,p,q,r,s=f.hasData(a)&&f._data(a),t=s&&s.events;if(!s||!t)return;c&&c.type&&(d=c.handler,c=c.type);if(!c||typeof c=="string"&&c.charAt(0)==="."){c=c||"";for(h in t)f.event.remove(a,h+c);return}c=c.split(" ");while(h=c[k++]){r=h,q=null,l=h.indexOf(".")<0,m=[],l||(m=h.split("."),h=m.shift(),n=new RegExp("(^|\\.)"+f.map(m.slice(0).sort(),C).join("\\.(?:.*\\.)?")+"(\\.|$)")),p=t[h];if(!p)continue;if(!d){for(j=0;j=0&&(h=h.slice(0,-1),j=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i. -shift(),i.sort());if(!!e&&!f.event.customEvent[h]||!!f.event.global[h]){c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.exclusive=j,c.namespace=i.join("."),c.namespace_re=new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)");if(g||!e)c.preventDefault(),c.stopPropagation();if(!e){f.each(f.cache,function(){var a=f.expando,b=this[a];b&&b.events&&b.events[h]&&f.event.trigger(c,d,b.handle.elem)});return}if(e.nodeType===3||e.nodeType===8)return;c.result=b,c.target=e,d=d!=null?f.makeArray(d):[],d.unshift(c);var k=e,l=h.indexOf(":")<0?"on"+h:"";do{var m=f._data(k,"handle");c.currentTarget=k,m&&m.apply(k,d),l&&f.acceptData(k)&&k[l]&&k[l].apply(k,d)===!1&&(c.result=!1,c.preventDefault()),k=k.parentNode||k.ownerDocument||k===c.target.ownerDocument&&a}while(k&&!c.isPropagationStopped());if(!c.isDefaultPrevented()){var n,o=f.event.special[h]||{};if((!o._default||o._default.call(e.ownerDocument,c)===!1)&&(h!=="click"||!f.nodeName(e,"a"))&&f.acceptData(e)){try{l&&e[h]&&(n=e[l],n&&(e[l]=null),f.event.triggered=h,e[h]())}catch(p){}n&&(e[l]=n),f.event.triggered=b}}return c.result}},handle:function(c){c=f.event.fix(c||a.event);var d=((f._data(this,"events")||{})[c.type]||[]).slice(0),e=!c.exclusive&&!c.namespace,g=Array.prototype.slice.call(arguments,0);g[0]=c,c.currentTarget=this;for(var h=0,i=d.length;h-1?f.map(a.options,function(a){return a.selected}).join("-"):"":f.nodeName(a,"select")&&(c=a.selectedIndex);return c},J=function(c){var d=c.target,e,g;if(!!y.test(d.nodeName)&&!d.readOnly){e=f._data(d,"_change_data"),g=I(d),(c.type!=="focusout"||d.type!=="radio")&&f._data(d,"_change_data",g);if(e===b||g===e)return;if(e!=null||g)c.type="change",c.liveFired=b,f.event.trigger(c,arguments[1],d)}};f.event.special.change={filters:{focusout:J,beforedeactivate:J,click:function(a){var b=a.target,c=f.nodeName(b,"input")?b.type:"";(c==="radio"||c==="checkbox"||f.nodeName(b,"select"))&&J.call(this,a)},keydown:function(a){var b=a.target,c=f.nodeName(b,"input")?b.type:"";(a.keyCode===13&&!f.nodeName(b,"textarea")||a.keyCode===32&&(c==="checkbox"||c==="radio")||c==="select-multiple")&&J.call(this,a)},beforeactivate:function(a){var b=a.target;f._data(b,"_change_data",I(b))}},setup:function(a,b){if(this.type==="file")return!1;for(var c in H)f.event.add(this,c+".specialChange",H[c]);return y.test(this.nodeName)},teardown:function(a){f.event.remove(this,".specialChange");return y.test(this.nodeName)}},H=f.event.special.change.filters,H.focus=H.beforeactivate}f.support.focusinBubbles||f.each({focus:"focusin",blur:"focusout"},function(a,b){function e(a){var c=f.event.fix(a);c.type=b,c.originalEvent={},f.event.trigger(c,null,c.target),c.isDefaultPrevented()&&a.preventDefault()}var d=0;f.event.special[b]={setup:function(){d++===0&&c.addEventListener(a,e,!0)},teardown:function(){--d===0&&c.removeEventListener(a,e,!0)}}}),f.each(["bind","one"],function(a,c){f.fn[c]=function(a,d,e){var g;if(typeof a=="object"){for(var h in a)this[c](h,d,a[h],e);return this}if(arguments.length===2||d===!1)e=d,d=b;c==="one"?(g=function(a){f(this).unbind(a,g);return e.apply(this,arguments)},g.guid=e.guid||f.guid++):g=e;if(a==="unload"&&c!=="one")this.one(a,d,e);else for(var i=0,j=this.length;i0?this.bind(b,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0)}),function(){function u(a,b,c,d,e,f){for(var g=0,h=d.length;g0){j=i;break}}i=i[a]}d[g]=j}}}function t(a,b,c,d,e,f){for(var g=0,h=d.length;g+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d=0,e=Object.prototype.toString,g=!1,h=!0,i=/\\/g,j=/\W/;[0,0].sort(function(){h=!1;return 0});var k=function(b,d,f,g){f=f||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return f;var i,j,n,o,q,r,s,t,u=!0,w=k.isXML(d),x=[],y=b;do{a.exec(""),i=a.exec(y);if(i){y=i[3],x.push(i[1]);if(i[2]){o=i[3];break}}}while(i);if(x.length>1&&m.exec(b))if(x.length===2&&l.relative[x[0]])j=v(x[0]+x[1],d);else{j=l.relative[x[0]]?[d]:k(x.shift(),d);while(x.length)b=x.shift(),l.relative[b]&&(b+=x.shift()),j=v(b,j)}else{!g&&x.length>1&&d.nodeType===9&&!w&&l.match.ID.test(x[0])&&!l.match.ID.test(x[x.length-1])&&(q=k.find(x.shift(),d,w),d=q.expr?k.filter(q.expr,q.set)[0]:q.set[0]);if(d){q=g?{expr:x.pop(),set:p(g)}:k.find(x.pop(),x.length===1&&(x[0]==="~"||x[0]==="+")&&d.parentNode?d.parentNode:d,w),j=q.expr?k.filter(q.expr,q.set):q.set,x.length>0?n=p(j):u=!1;while(x.length)r=x.pop(),s=r,l.relative[r]?s=x.pop():r="",s==null&&(s=d),l.relative[r](n,s,w)}else n=x=[]}n||(n=j),n||k.error(r||b);if(e.call(n)==="[object Array]")if(!u)f.push.apply(f,n);else if(d&&d.nodeType===1)for(t=0;n[t]!=null;t++)n[t]&&(n[t]===!0||n[t].nodeType===1&&k.contains(d,n[t]))&&f.push(j[t]);else for(t=0;n[t]!=null;t++)n[t]&&n[t].nodeType===1&&f.push(j[t]);else p(n,f);o&&(k(o,h,f,g),k.uniqueSort(f));return f};k.uniqueSort=function(a){if(r){g=h,a.sort(r);if(g)for(var b=1;b0},k.find=function(a,b,c){var d;if(!a)return[];for(var e=0,f=l.order.length;e":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!j.test(b)){b=b.toLowerCase();for(;e=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(i,"")},TAG:function(a,b){return a[1].replace(i,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||k.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&k.error(a[0]);a[0]=d++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(i,"");!f&&l.attrMap[g]&&(a[1]=l.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(i,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=k(b[3],null,null,c);else{var g=k.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(l.match.POS.test(b[0])||l.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!k(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return bc[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=l.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||k.getText([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=l.attrHandle[c]?l.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=l.setFilters[e];if(f)return f(a,c,b,d)}}},m=l.match.POS,n=function(a,b){return"\\"+(b-0+1)};for(var o in l.match)l.match[o]=new RegExp(l.match[o].source+/(?![^\[]*\])(?![^\(]*\))/.source),l.leftMatch[o]=new RegExp(/(^(?:.|\r|\n)*?)/.source+l.match[o].source.replace(/\\(\d+)/g,n));var p=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(q){p=function(a,b){var c=0,d=b||[];if(e.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var f=a.length;c",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(l.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},l.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(l.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(l.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=k,b=c.createElement("div"),d="__sizzle__";b.innerHTML="

";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){k=function(b,e,f,g){e=e||c;if(!g&&!k.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return p(e.getElementsByTagName(b),f);if(h[2]&&l.find.CLASS&&e.getElementsByClassName)return p(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return p([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return p([],f);if(i.id===h[3])return p([i],f)}try{return p(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var m=e,n=e.getAttribute("id"),o=n||d,q=e.parentNode,r=/^\s*[+~]/.test(b);n?o=o.replace(/'/g,"\\$&"):e.setAttribute("id",o),r&&q&&(e=e.parentNode);try{if(!r||q)return p(e.querySelectorAll("[id='"+o+"'] "+b),f)}catch(s){}finally{n||m.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)k[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}k.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!k.isXML(a))try{if(e||!l.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return k(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="
";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;l.order.splice(1,0,"CLASS"),l.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?k.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?k.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:k.contains=function(){return!1},k.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var v=function(a,b){var c,d=[],e="",f=b.nodeType?[b]:b;while(c=l.match.PSEUDO.exec(a))e+=c[0],a=a.replace(l.match.PSEUDO,"");a=l.relative[a]?a+"*":a;for(var g=0,h=f.length;g0)for(h=g;h0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h,i,j={},k=1;if(g&&a.length){for(d=0,e=a.length;d-1:f(g).is(h))&&c.push({selector:i,elem:g,level:k});g=g.parentNode,k++}}return c}var l=T.test(a)||typeof a!="string"?f(a,b||this.context):0;for(d=0,e=this.length;d-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a||typeof a=="string")return f.inArray(this[0],a?f(a):this.parent().children());return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(V(c[0])||V(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c),g=S.call(arguments);O.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!U[a]?f.unique(e):e,(this.length>1||Q.test(d))&&P.test(a)&&(e=e.reverse());return this.pushStack(e,a,g.join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var X=/ jQuery\d+="(?:\d+|null)"/g,Y=/^\s+/,Z=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,$=/<([\w:]+)/,_=/",""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]};bf.optgroup=bf.option,bf.tbody=bf.tfoot=bf.colgroup=bf.caption=bf.thead,bf.th=bf.td,f.support.htmlSerialize||(bf._default=[1,"div
","
"]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){f(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f(arguments[0]).toArray());return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(X,""):null;if(typeof a=="string"&&!bb.test(a)&&(f.support.leadingWhitespace||!Y.test(a))&&!bf[($.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Z,"<$1>");try{for(var c=0,d=this.length;c1&&l0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j -)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d=a.cloneNode(!0),e,g,h;if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bi(a,d),e=bj(a),g=bj(d);for(h=0;e[h];++h)bi(e[h],g[h])}if(b){bh(a,d);if(c){e=bj(a),g=bj(d);for(h=0;e[h];++h)bh(e[h],g[h])}}e=g=null;return d},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!ba.test(k))k=b.createTextNode(k);else{k=k.replace(Z,"<$1>");var l=($.exec(k)||["",""])[1].toLowerCase(),m=bf[l]||bf._default,n=m[0],o=b.createElement("div");o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=_.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]===""&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&Y.test(k)&&o.insertBefore(b.createTextNode(Y.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return bo.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle;c.zoom=1;var e=f.isNaN(b)?"":"alpha(opacity="+b*100+")",g=d&&d.filter||c.filter||"";c.filter=bn.test(g)?g.replace(bn,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bx(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(by=function(a,c){var d,e,g;c=c.replace(bp,"-$1").toLowerCase();if(!(e=a.ownerDocument.defaultView))return b;if(g=e.getComputedStyle(a,null))d=g.getPropertyValue(c),d===""&&!f.contains(a.ownerDocument.documentElement,a)&&(d=f.style(a,c));return d}),c.documentElement.currentStyle&&(bz=function(a,b){var c,d=a.currentStyle&&a.currentStyle[b],e=a.runtimeStyle&&a.runtimeStyle[b],f=a.style;!bq.test(d)&&br.test(d)&&(c=f.left,e&&(a.runtimeStyle.left=a.currentStyle.left),f.left=b==="fontSize"?"1em":d||0,d=f.pixelLeft+"px",f.left=c,e&&(a.runtimeStyle.left=e));return d===""?"auto":d}),bx=by||bz,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bB=/%20/g,bC=/\[\]$/,bD=/\r?\n/g,bE=/#.*$/,bF=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bG=/^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bH=/^(?:about|app|app\-storage|.+\-extension|file|widget):$/,bI=/^(?:GET|HEAD)$/,bJ=/^\/\//,bK=/\?/,bL=/)<[^<]*)*<\/script>/gi,bM=/^(?:select|textarea)/i,bN=/\s+/,bO=/([?&])_=[^&]*/,bP=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bQ=f.fn.load,bR={},bS={},bT,bU;try{bT=e.href}catch(bV){bT=c.createElement("a"),bT.href="",bT=bT.href}bU=bP.exec(bT.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bQ)return bQ.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("
").append(c.replace(bL,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bM.test(this.nodeName)||bG.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bD,"\r\n")}}):{name:b.name,value:c.replace(bD,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.bind(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?f.extend(!0,a,f.ajaxSettings,b):(b=a,a=f.extend(!0,f.ajaxSettings,b));for(var c in{context:1,url:1})c in b?a[c]=b[c]:c in f.ajaxSettings&&(a[c]=f.ajaxSettings[c]);return a},ajaxSettings:{url:bT,isLocal:bH.test(bU[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":"*/*"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML}},ajaxPrefilter:bW(bR),ajaxTransport:bW(bS),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a?4:0;var o,r,u,w=l?bZ(d,v,l):b,x,y;if(a>=200&&a<300||a===304){if(d.ifModified){if(x=v.getResponseHeader("Last-Modified"))f.lastModified[k]=x;if(y=v.getResponseHeader("Etag"))f.etag[k]=y}if(a===304)c="notmodified",o=!0;else try{r=b$(d,w),c="success",o=!0}catch(z){c="parsererror",u=z}}else{u=c;if(!c||a)c="error",a<0&&(a=0)}v.status=a,v.statusText=c,o?h.resolveWith(e,[r,c,v]):h.rejectWith(e,[v,c,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.resolveWith(e,[v,c]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f._Deferred(),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bF.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.done,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bE,"").replace(bJ,bU[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bN),d.crossDomain==null&&(r=bP.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bU[1]&&r[2]==bU[2]&&(r[3]||(r[1]==="http:"?80:443))==(bU[3]||(bU[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),bX(bR,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bI.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bK.test(d.url)?"&":"?")+d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bO,"$1_="+x);d.url=y+(y===d.url?(bK.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", */*; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=bX(bS,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){status<2?w(-1,z):f.error(z)}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)bY(g,a[g],c,e);return d.join("&").replace(bB,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var b_=f.now(),ca=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+b_++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=b.contentType==="application/x-www-form-urlencoded"&&typeof b.data=="string";if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(ca.test(b.url)||e&&ca.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(ca,l),b.url===j&&(e&&(k=k.replace(ca,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var cb=a.ActiveXObject?function(){for(var a in cd)cd[a](0,1)}:!1,cc=0,cd;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ce()||cf()}:ce,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,cb&&delete cd[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n),m.text=h.responseText;try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cc,cb&&(cd||(cd={},f(a).unload(cb)),cd[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var cg={},ch,ci,cj=/^(?:toggle|show|hide)$/,ck=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cl,cm=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cn,co=a.webkitRequestAnimationFrame||a.mozRequestAnimationFrame||a.oRequestAnimationFrame;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(cr("show",3),a,b,c);for(var g=0,h=this.length;g=e.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),e.animatedProperties[this.prop]=!0;for(g in e.animatedProperties)e.animatedProperties[g]!==!0&&(c=!1);if(c){e.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){d.style["overflow"+b]=e.overflow[a]}),e.hide&&f(d).hide();if(e.hide||e.show)for(var i in e.animatedProperties)f.style(d,i,e.orig[i]);e.complete.call(d)}return!1}e.duration==Infinity?this.now=b:(h=b-this.startTime,this.state=h/e.duration,this.pos=f.easing[e.animatedProperties[this.prop]](this.state,h,0,1,e.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){for(var a=f.timers,b=0;b
";f.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"}),b.innerHTML=j,a.insertBefore(b,a.firstChild),d=b.firstChild,e=d.firstChild,h=d.nextSibling.firstChild.firstChild,this.doesNotAddBorder=e.offsetTop!==5,this.doesAddBorderForTableAndCells=h.offsetTop===5,e.style.position="fixed",e.style.top="20px",this.supportsFixedPosition=e.offsetTop===20||e.offsetTop===15,e.style.position=e.style.top="",d.style.overflow="hidden",d.style.position="relative",this.subtractsBorderForOverflowNotVisible=e.offsetTop===-5,this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==i,a.removeChild(b),f.offset.initialize=f.noop},bodyOffset:function(a){var b=a.offsetTop,c=a.offsetLeft;f.offset.initialize(),f.offset.doesNotIncludeMarginInBodyOffset&&(b+=parseFloat(f.css(a,"marginTop"))||0,c+=parseFloat(f.css(a,"marginLeft"))||0);return{top:b,left:c}},setOffset:function(a,b,c){var d=f.css(a,"position");d==="static"&&(a.style.position="relative");var e=f(a),g=e.offset(),h=f.css(a,"top"),i=f.css(a,"left"),j=(d==="absolute"||d==="fixed")&&f.inArray("auto",[h,i])>-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cu.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cu.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each(["Left","Top"],function(a,c){var d="scroll"+c;f.fn[d]=function(c){var e,g;if(c===b){e=this[0];if(!e)return null;g=cv(e);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:f.support.boxModel&&g.document.documentElement[d]||g.document.body[d]:e[d]}return this.each(function(){g=cv(this),g?g.scrollTo(a?f(g).scrollLeft():c,a?c:f(g).scrollTop()):this[d]=c})}}),f.each(["Height","Width"],function(a,c){var d=c.toLowerCase();f.fn["inner"+c]=function(){var a=this[0];return a&&a.style?parseFloat(f.css(a,d,"padding")):null},f.fn["outer"+c]=function(a){var b=this[0];return b&&b.style?parseFloat(f.css(b,d,a?"margin":"border")):null},f.fn[d]=function(a){var e=this[0];if(!e)return a==null?null:this;if(f.isFunction(a))return this.each(function(b){var c=f(this);c[d](a.call(this,b,c[d]()))});if(f.isWindow(e)){var g=e.document.documentElement["client"+c];return e.document.compatMode==="CSS1Compat"&&g||e.document.body["client"+c]||g}if(e.nodeType===9)return Math.max(e.documentElement["client"+c],e.body["scroll"+c],e.documentElement["scroll"+c],e.body["offset"+c],e.documentElement["offset"+c]);if(a===b){var h=f.css(e,d),i=parseFloat(h);return f.isNaN(i)?h:i}return this.css(d,typeof a=="string"?a:a+"px")}}),a.jQuery=a.$=f})(window); \ No newline at end of file +/*! jQuery v1.8.3 jquery.com | jquery.org/license */ +(function(e,t){function _(e){var t=M[e]={};return v.each(e.split(y),function(e,n){t[n]=!0}),t}function H(e,n,r){if(r===t&&e.nodeType===1){var i="data-"+n.replace(P,"-$1").toLowerCase();r=e.getAttribute(i);if(typeof r=="string"){try{r=r==="true"?!0:r==="false"?!1:r==="null"?null:+r+""===r?+r:D.test(r)?v.parseJSON(r):r}catch(s){}v.data(e,n,r)}else r=t}return r}function B(e){var t;for(t in e){if(t==="data"&&v.isEmptyObject(e[t]))continue;if(t!=="toJSON")return!1}return!0}function et(){return!1}function tt(){return!0}function ut(e){return!e||!e.parentNode||e.parentNode.nodeType===11}function at(e,t){do e=e[t];while(e&&e.nodeType!==1);return e}function ft(e,t,n){t=t||0;if(v.isFunction(t))return v.grep(e,function(e,r){var i=!!t.call(e,r,e);return i===n});if(t.nodeType)return v.grep(e,function(e,r){return e===t===n});if(typeof t=="string"){var r=v.grep(e,function(e){return e.nodeType===1});if(it.test(t))return v.filter(t,r,!n);t=v.filter(t,r)}return v.grep(e,function(e,r){return v.inArray(e,t)>=0===n})}function lt(e){var t=ct.split("|"),n=e.createDocumentFragment();if(n.createElement)while(t.length)n.createElement(t.pop());return n}function Lt(e,t){return e.getElementsByTagName(t)[0]||e.appendChild(e.ownerDocument.createElement(t))}function At(e,t){if(t.nodeType!==1||!v.hasData(e))return;var n,r,i,s=v._data(e),o=v._data(t,s),u=s.events;if(u){delete o.handle,o.events={};for(n in u)for(r=0,i=u[n].length;r").appendTo(i.body),n=t.css("display");t.remove();if(n==="none"||n===""){Pt=i.body.appendChild(Pt||v.extend(i.createElement("iframe"),{frameBorder:0,width:0,height:0}));if(!Ht||!Pt.createElement)Ht=(Pt.contentWindow||Pt.contentDocument).document,Ht.write(""),Ht.close();t=Ht.body.appendChild(Ht.createElement(e)),n=Dt(t,"display"),i.body.removeChild(Pt)}return Wt[e]=n,n}function fn(e,t,n,r){var i;if(v.isArray(t))v.each(t,function(t,i){n||sn.test(e)?r(e,i):fn(e+"["+(typeof i=="object"?t:"")+"]",i,n,r)});else if(!n&&v.type(t)==="object")for(i in t)fn(e+"["+i+"]",t[i],n,r);else r(e,t)}function Cn(e){return function(t,n){typeof t!="string"&&(n=t,t="*");var r,i,s,o=t.toLowerCase().split(y),u=0,a=o.length;if(v.isFunction(n))for(;u)[^>]*$|#([\w\-]*)$)/,E=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,S=/^[\],:{}\s]*$/,x=/(?:^|:|,)(?:\s*\[)+/g,T=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,N=/"[^"\\\r\n]*"|true|false|null|-?(?:\d\d*\.|)\d+(?:[eE][\-+]?\d+|)/g,C=/^-ms-/,k=/-([\da-z])/gi,L=function(e,t){return(t+"").toUpperCase()},A=function(){i.addEventListener?(i.removeEventListener("DOMContentLoaded",A,!1),v.ready()):i.readyState==="complete"&&(i.detachEvent("onreadystatechange",A),v.ready())},O={};v.fn=v.prototype={constructor:v,init:function(e,n,r){var s,o,u,a;if(!e)return this;if(e.nodeType)return this.context=this[0]=e,this.length=1,this;if(typeof e=="string"){e.charAt(0)==="<"&&e.charAt(e.length-1)===">"&&e.length>=3?s=[null,e,null]:s=w.exec(e);if(s&&(s[1]||!n)){if(s[1])return n=n instanceof v?n[0]:n,a=n&&n.nodeType?n.ownerDocument||n:i,e=v.parseHTML(s[1],a,!0),E.test(s[1])&&v.isPlainObject(n)&&this.attr.call(e,n,!0),v.merge(this,e);o=i.getElementById(s[2]);if(o&&o.parentNode){if(o.id!==s[2])return r.find(e);this.length=1,this[0]=o}return this.context=i,this.selector=e,this}return!n||n.jquery?(n||r).find(e):this.constructor(n).find(e)}return v.isFunction(e)?r.ready(e):(e.selector!==t&&(this.selector=e.selector,this.context=e.context),v.makeArray(e,this))},selector:"",jquery:"1.8.3",length:0,size:function(){return this.length},toArray:function(){return l.call(this)},get:function(e){return e==null?this.toArray():e<0?this[this.length+e]:this[e]},pushStack:function(e,t,n){var r=v.merge(this.constructor(),e);return r.prevObject=this,r.context=this.context,t==="find"?r.selector=this.selector+(this.selector?" ":"")+n:t&&(r.selector=this.selector+"."+t+"("+n+")"),r},each:function(e,t){return v.each(this,e,t)},ready:function(e){return v.ready.promise().done(e),this},eq:function(e){return e=+e,e===-1?this.slice(e):this.slice(e,e+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(l.apply(this,arguments),"slice",l.call(arguments).join(","))},map:function(e){return this.pushStack(v.map(this,function(t,n){return e.call(t,n,t)}))},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:[].sort,splice:[].splice},v.fn.init.prototype=v.fn,v.extend=v.fn.extend=function(){var e,n,r,i,s,o,u=arguments[0]||{},a=1,f=arguments.length,l=!1;typeof u=="boolean"&&(l=u,u=arguments[1]||{},a=2),typeof u!="object"&&!v.isFunction(u)&&(u={}),f===a&&(u=this,--a);for(;a0)return;r.resolveWith(i,[v]),v.fn.trigger&&v(i).trigger("ready").off("ready")},isFunction:function(e){return v.type(e)==="function"},isArray:Array.isArray||function(e){return v.type(e)==="array"},isWindow:function(e){return e!=null&&e==e.window},isNumeric:function(e){return!isNaN(parseFloat(e))&&isFinite(e)},type:function(e){return e==null?String(e):O[h.call(e)]||"object"},isPlainObject:function(e){if(!e||v.type(e)!=="object"||e.nodeType||v.isWindow(e))return!1;try{if(e.constructor&&!p.call(e,"constructor")&&!p.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(n){return!1}var r;for(r in e);return r===t||p.call(e,r)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},error:function(e){throw new Error(e)},parseHTML:function(e,t,n){var r;return!e||typeof e!="string"?null:(typeof t=="boolean"&&(n=t,t=0),t=t||i,(r=E.exec(e))?[t.createElement(r[1])]:(r=v.buildFragment([e],t,n?null:[]),v.merge([],(r.cacheable?v.clone(r.fragment):r.fragment).childNodes)))},parseJSON:function(t){if(!t||typeof t!="string")return null;t=v.trim(t);if(e.JSON&&e.JSON.parse)return e.JSON.parse(t);if(S.test(t.replace(T,"@").replace(N,"]").replace(x,"")))return(new Function("return "+t))();v.error("Invalid JSON: "+t)},parseXML:function(n){var r,i;if(!n||typeof n!="string")return null;try{e.DOMParser?(i=new DOMParser,r=i.parseFromString(n,"text/xml")):(r=new ActiveXObject("Microsoft.XMLDOM"),r.async="false",r.loadXML(n))}catch(s){r=t}return(!r||!r.documentElement||r.getElementsByTagName("parsererror").length)&&v.error("Invalid XML: "+n),r},noop:function(){},globalEval:function(t){t&&g.test(t)&&(e.execScript||function(t){e.eval.call(e,t)})(t)},camelCase:function(e){return e.replace(C,"ms-").replace(k,L)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,n,r){var i,s=0,o=e.length,u=o===t||v.isFunction(e);if(r){if(u){for(i in e)if(n.apply(e[i],r)===!1)break}else for(;s0&&e[0]&&e[a-1]||a===0||v.isArray(e));if(f)for(;u-1)a.splice(n,1),i&&(n<=o&&o--,n<=u&&u--)}),this},has:function(e){return v.inArray(e,a)>-1},empty:function(){return a=[],this},disable:function(){return a=f=n=t,this},disabled:function(){return!a},lock:function(){return f=t,n||c.disable(),this},locked:function(){return!f},fireWith:function(e,t){return t=t||[],t=[e,t.slice?t.slice():t],a&&(!r||f)&&(i?f.push(t):l(t)),this},fire:function(){return c.fireWith(this,arguments),this},fired:function(){return!!r}};return c},v.extend({Deferred:function(e){var t=[["resolve","done",v.Callbacks("once memory"),"resolved"],["reject","fail",v.Callbacks("once memory"),"rejected"],["notify","progress",v.Callbacks("memory")]],n="pending",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return v.Deferred(function(n){v.each(t,function(t,r){var s=r[0],o=e[t];i[r[1]](v.isFunction(o)?function(){var e=o.apply(this,arguments);e&&v.isFunction(e.promise)?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[s+"With"](this===i?n:this,[e])}:n[s])}),e=null}).promise()},promise:function(e){return e!=null?v.extend(e,r):r}},i={};return r.pipe=r.then,v.each(t,function(e,s){var o=s[2],u=s[3];r[s[1]]=o.add,u&&o.add(function(){n=u},t[e^1][2].disable,t[2][2].lock),i[s[0]]=o.fire,i[s[0]+"With"]=o.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t=0,n=l.call(arguments),r=n.length,i=r!==1||e&&v.isFunction(e.promise)?r:0,s=i===1?e:v.Deferred(),o=function(e,t,n){return function(r){t[e]=this,n[e]=arguments.length>1?l.call(arguments):r,n===u?s.notifyWith(t,n):--i||s.resolveWith(t,n)}},u,a,f;if(r>1){u=new Array(r),a=new Array(r),f=new Array(r);for(;t
a",n=p.getElementsByTagName("*"),r=p.getElementsByTagName("a")[0];if(!n||!r||!n.length)return{};s=i.createElement("select"),o=s.appendChild(i.createElement("option")),u=p.getElementsByTagName("input")[0],r.style.cssText="top:1px;float:left;opacity:.5",t={leadingWhitespace:p.firstChild.nodeType===3,tbody:!p.getElementsByTagName("tbody").length,htmlSerialize:!!p.getElementsByTagName("link").length,style:/top/.test(r.getAttribute("style")),hrefNormalized:r.getAttribute("href")==="/a",opacity:/^0.5/.test(r.style.opacity),cssFloat:!!r.style.cssFloat,checkOn:u.value==="on",optSelected:o.selected,getSetAttribute:p.className!=="t",enctype:!!i.createElement("form").enctype,html5Clone:i.createElement("nav").cloneNode(!0).outerHTML!=="<:nav>",boxModel:i.compatMode==="CSS1Compat",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,boxSizingReliable:!0,pixelPosition:!1},u.checked=!0,t.noCloneChecked=u.cloneNode(!0).checked,s.disabled=!0,t.optDisabled=!o.disabled;try{delete p.test}catch(d){t.deleteExpando=!1}!p.addEventListener&&p.attachEvent&&p.fireEvent&&(p.attachEvent("onclick",h=function(){t.noCloneEvent=!1}),p.cloneNode(!0).fireEvent("onclick"),p.detachEvent("onclick",h)),u=i.createElement("input"),u.value="t",u.setAttribute("type","radio"),t.radioValue=u.value==="t",u.setAttribute("checked","checked"),u.setAttribute("name","t"),p.appendChild(u),a=i.createDocumentFragment(),a.appendChild(p.lastChild),t.checkClone=a.cloneNode(!0).cloneNode(!0).lastChild.checked,t.appendChecked=u.checked,a.removeChild(u),a.appendChild(p);if(p.attachEvent)for(l in{submit:!0,change:!0,focusin:!0})f="on"+l,c=f in p,c||(p.setAttribute(f,"return;"),c=typeof p[f]=="function"),t[l+"Bubbles"]=c;return v(function(){var n,r,s,o,u="padding:0;margin:0;border:0;display:block;overflow:hidden;",a=i.getElementsByTagName("body")[0];if(!a)return;n=i.createElement("div"),n.style.cssText="visibility:hidden;border:0;width:0;height:0;position:static;top:0;margin-top:1px",a.insertBefore(n,a.firstChild),r=i.createElement("div"),n.appendChild(r),r.innerHTML="
t
",s=r.getElementsByTagName("td"),s[0].style.cssText="padding:0;margin:0;border:0;display:none",c=s[0].offsetHeight===0,s[0].style.display="",s[1].style.display="none",t.reliableHiddenOffsets=c&&s[0].offsetHeight===0,r.innerHTML="",r.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;",t.boxSizing=r.offsetWidth===4,t.doesNotIncludeMarginInBodyOffset=a.offsetTop!==1,e.getComputedStyle&&(t.pixelPosition=(e.getComputedStyle(r,null)||{}).top!=="1%",t.boxSizingReliable=(e.getComputedStyle(r,null)||{width:"4px"}).width==="4px",o=i.createElement("div"),o.style.cssText=r.style.cssText=u,o.style.marginRight=o.style.width="0",r.style.width="1px",r.appendChild(o),t.reliableMarginRight=!parseFloat((e.getComputedStyle(o,null)||{}).marginRight)),typeof r.style.zoom!="undefined"&&(r.innerHTML="",r.style.cssText=u+"width:1px;padding:1px;display:inline;zoom:1",t.inlineBlockNeedsLayout=r.offsetWidth===3,r.style.display="block",r.style.overflow="visible",r.innerHTML="
",r.firstChild.style.width="5px",t.shrinkWrapBlocks=r.offsetWidth!==3,n.style.zoom=1),a.removeChild(n),n=r=s=o=null}),a.removeChild(p),n=r=s=o=u=a=p=null,t}();var D=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,P=/([A-Z])/g;v.extend({cache:{},deletedIds:[],uuid:0,expando:"jQuery"+(v.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(e){return e=e.nodeType?v.cache[e[v.expando]]:e[v.expando],!!e&&!B(e)},data:function(e,n,r,i){if(!v.acceptData(e))return;var s,o,u=v.expando,a=typeof n=="string",f=e.nodeType,l=f?v.cache:e,c=f?e[u]:e[u]&&u;if((!c||!l[c]||!i&&!l[c].data)&&a&&r===t)return;c||(f?e[u]=c=v.deletedIds.pop()||v.guid++:c=u),l[c]||(l[c]={},f||(l[c].toJSON=v.noop));if(typeof n=="object"||typeof n=="function")i?l[c]=v.extend(l[c],n):l[c].data=v.extend(l[c].data,n);return s=l[c],i||(s.data||(s.data={}),s=s.data),r!==t&&(s[v.camelCase(n)]=r),a?(o=s[n],o==null&&(o=s[v.camelCase(n)])):o=s,o},removeData:function(e,t,n){if(!v.acceptData(e))return;var r,i,s,o=e.nodeType,u=o?v.cache:e,a=o?e[v.expando]:v.expando;if(!u[a])return;if(t){r=n?u[a]:u[a].data;if(r){v.isArray(t)||(t in r?t=[t]:(t=v.camelCase(t),t in r?t=[t]:t=t.split(" ")));for(i=0,s=t.length;i1,null,!1))},removeData:function(e){return this.each(function(){v.removeData(this,e)})}}),v.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=v._data(e,t),n&&(!r||v.isArray(n)?r=v._data(e,t,v.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=v.queue(e,t),r=n.length,i=n.shift(),s=v._queueHooks(e,t),o=function(){v.dequeue(e,t)};i==="inprogress"&&(i=n.shift(),r--),i&&(t==="fx"&&n.unshift("inprogress"),delete s.stop,i.call(e,o,s)),!r&&s&&s.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return v._data(e,n)||v._data(e,n,{empty:v.Callbacks("once memory").add(function(){v.removeData(e,t+"queue",!0),v.removeData(e,n,!0)})})}}),v.fn.extend({queue:function(e,n){var r=2;return typeof e!="string"&&(n=e,e="fx",r--),arguments.length1)},removeAttr:function(e){return this.each(function(){v.removeAttr(this,e)})},prop:function(e,t){return v.access(this,v.prop,e,t,arguments.length>1)},removeProp:function(e){return e=v.propFix[e]||e,this.each(function(){try{this[e]=t,delete this[e]}catch(n){}})},addClass:function(e){var t,n,r,i,s,o,u;if(v.isFunction(e))return this.each(function(t){v(this).addClass(e.call(this,t,this.className))});if(e&&typeof e=="string"){t=e.split(y);for(n=0,r=this.length;n=0)r=r.replace(" "+n[s]+" "," ");i.className=e?v.trim(r):""}}}return this},toggleClass:function(e,t){var n=typeof e,r=typeof t=="boolean";return v.isFunction(e)?this.each(function(n){v(this).toggleClass(e.call(this,n,this.className,t),t)}):this.each(function(){if(n==="string"){var i,s=0,o=v(this),u=t,a=e.split(y);while(i=a[s++])u=r?u:!o.hasClass(i),o[u?"addClass":"removeClass"](i)}else if(n==="undefined"||n==="boolean")this.className&&v._data(this,"__className__",this.className),this.className=this.className||e===!1?"":v._data(this,"__className__")||""})},hasClass:function(e){var t=" "+e+" ",n=0,r=this.length;for(;n=0)return!0;return!1},val:function(e){var n,r,i,s=this[0];if(!arguments.length){if(s)return n=v.valHooks[s.type]||v.valHooks[s.nodeName.toLowerCase()],n&&"get"in n&&(r=n.get(s,"value"))!==t?r:(r=s.value,typeof r=="string"?r.replace(R,""):r==null?"":r);return}return i=v.isFunction(e),this.each(function(r){var s,o=v(this);if(this.nodeType!==1)return;i?s=e.call(this,r,o.val()):s=e,s==null?s="":typeof s=="number"?s+="":v.isArray(s)&&(s=v.map(s,function(e){return e==null?"":e+""})),n=v.valHooks[this.type]||v.valHooks[this.nodeName.toLowerCase()];if(!n||!("set"in n)||n.set(this,s,"value")===t)this.value=s})}}),v.extend({valHooks:{option:{get:function(e){var t=e.attributes.value;return!t||t.specified?e.value:e.text}},select:{get:function(e){var t,n,r=e.options,i=e.selectedIndex,s=e.type==="select-one"||i<0,o=s?null:[],u=s?i+1:r.length,a=i<0?u:s?i:0;for(;a=0}),n.length||(e.selectedIndex=-1),n}}},attrFn:{},attr:function(e,n,r,i){var s,o,u,a=e.nodeType;if(!e||a===3||a===8||a===2)return;if(i&&v.isFunction(v.fn[n]))return v(e)[n](r);if(typeof e.getAttribute=="undefined")return v.prop(e,n,r);u=a!==1||!v.isXMLDoc(e),u&&(n=n.toLowerCase(),o=v.attrHooks[n]||(X.test(n)?F:j));if(r!==t){if(r===null){v.removeAttr(e,n);return}return o&&"set"in o&&u&&(s=o.set(e,r,n))!==t?s:(e.setAttribute(n,r+""),r)}return o&&"get"in o&&u&&(s=o.get(e,n))!==null?s:(s=e.getAttribute(n),s===null?t:s)},removeAttr:function(e,t){var n,r,i,s,o=0;if(t&&e.nodeType===1){r=t.split(y);for(;o=0}})});var $=/^(?:textarea|input|select)$/i,J=/^([^\.]*|)(?:\.(.+)|)$/,K=/(?:^|\s)hover(\.\S+|)\b/,Q=/^key/,G=/^(?:mouse|contextmenu)|click/,Y=/^(?:focusinfocus|focusoutblur)$/,Z=function(e){return v.event.special.hover?e:e.replace(K,"mouseenter$1 mouseleave$1")};v.event={add:function(e,n,r,i,s){var o,u,a,f,l,c,h,p,d,m,g;if(e.nodeType===3||e.nodeType===8||!n||!r||!(o=v._data(e)))return;r.handler&&(d=r,r=d.handler,s=d.selector),r.guid||(r.guid=v.guid++),a=o.events,a||(o.events=a={}),u=o.handle,u||(o.handle=u=function(e){return typeof v=="undefined"||!!e&&v.event.triggered===e.type?t:v.event.dispatch.apply(u.elem,arguments)},u.elem=e),n=v.trim(Z(n)).split(" ");for(f=0;f=0&&(y=y.slice(0,-1),a=!0),y.indexOf(".")>=0&&(b=y.split("."),y=b.shift(),b.sort());if((!s||v.event.customEvent[y])&&!v.event.global[y])return;n=typeof n=="object"?n[v.expando]?n:new v.Event(y,n):new v.Event(y),n.type=y,n.isTrigger=!0,n.exclusive=a,n.namespace=b.join("."),n.namespace_re=n.namespace?new RegExp("(^|\\.)"+b.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,h=y.indexOf(":")<0?"on"+y:"";if(!s){u=v.cache;for(f in u)u[f].events&&u[f].events[y]&&v.event.trigger(n,r,u[f].handle.elem,!0);return}n.result=t,n.target||(n.target=s),r=r!=null?v.makeArray(r):[],r.unshift(n),p=v.event.special[y]||{};if(p.trigger&&p.trigger.apply(s,r)===!1)return;m=[[s,p.bindType||y]];if(!o&&!p.noBubble&&!v.isWindow(s)){g=p.delegateType||y,l=Y.test(g+y)?s:s.parentNode;for(c=s;l;l=l.parentNode)m.push([l,g]),c=l;c===(s.ownerDocument||i)&&m.push([c.defaultView||c.parentWindow||e,g])}for(f=0;f=0:v.find(h,this,null,[s]).length),u[h]&&f.push(c);f.length&&w.push({elem:s,matches:f})}d.length>m&&w.push({elem:this,matches:d.slice(m)});for(r=0;r0?this.on(t,null,e,n):this.trigger(t)},Q.test(t)&&(v.event.fixHooks[t]=v.event.keyHooks),G.test(t)&&(v.event.fixHooks[t]=v.event.mouseHooks)}),function(e,t){function nt(e,t,n,r){n=n||[],t=t||g;var i,s,a,f,l=t.nodeType;if(!e||typeof e!="string")return n;if(l!==1&&l!==9)return[];a=o(t);if(!a&&!r)if(i=R.exec(e))if(f=i[1]){if(l===9){s=t.getElementById(f);if(!s||!s.parentNode)return n;if(s.id===f)return n.push(s),n}else if(t.ownerDocument&&(s=t.ownerDocument.getElementById(f))&&u(t,s)&&s.id===f)return n.push(s),n}else{if(i[2])return S.apply(n,x.call(t.getElementsByTagName(e),0)),n;if((f=i[3])&&Z&&t.getElementsByClassName)return S.apply(n,x.call(t.getElementsByClassName(f),0)),n}return vt(e.replace(j,"$1"),t,n,r,a)}function rt(e){return function(t){var n=t.nodeName.toLowerCase();return n==="input"&&t.type===e}}function it(e){return function(t){var n=t.nodeName.toLowerCase();return(n==="input"||n==="button")&&t.type===e}}function st(e){return N(function(t){return t=+t,N(function(n,r){var i,s=e([],n.length,t),o=s.length;while(o--)n[i=s[o]]&&(n[i]=!(r[i]=n[i]))})})}function ot(e,t,n){if(e===t)return n;var r=e.nextSibling;while(r){if(r===t)return-1;r=r.nextSibling}return 1}function ut(e,t){var n,r,s,o,u,a,f,l=L[d][e+" "];if(l)return t?0:l.slice(0);u=e,a=[],f=i.preFilter;while(u){if(!n||(r=F.exec(u)))r&&(u=u.slice(r[0].length)||u),a.push(s=[]);n=!1;if(r=I.exec(u))s.push(n=new m(r.shift())),u=u.slice(n.length),n.type=r[0].replace(j," ");for(o in i.filter)(r=J[o].exec(u))&&(!f[o]||(r=f[o](r)))&&(s.push(n=new m(r.shift())),u=u.slice(n.length),n.type=o,n.matches=r);if(!n)break}return t?u.length:u?nt.error(e):L(e,a).slice(0)}function at(e,t,r){var i=t.dir,s=r&&t.dir==="parentNode",o=w++;return t.first?function(t,n,r){while(t=t[i])if(s||t.nodeType===1)return e(t,n,r)}:function(t,r,u){if(!u){var a,f=b+" "+o+" ",l=f+n;while(t=t[i])if(s||t.nodeType===1){if((a=t[d])===l)return t.sizset;if(typeof a=="string"&&a.indexOf(f)===0){if(t.sizset)return t}else{t[d]=l;if(e(t,r,u))return t.sizset=!0,t;t.sizset=!1}}}else while(t=t[i])if(s||t.nodeType===1)if(e(t,r,u))return t}}function ft(e){return e.length>1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function lt(e,t,n,r,i){var s,o=[],u=0,a=e.length,f=t!=null;for(;u-1&&(s[f]=!(o[f]=c))}}else g=lt(g===o?g.splice(d,g.length):g),i?i(null,o,g,a):S.apply(o,g)})}function ht(e){var t,n,r,s=e.length,o=i.relative[e[0].type],u=o||i.relative[" "],a=o?1:0,f=at(function(e){return e===t},u,!0),l=at(function(e){return T.call(t,e)>-1},u,!0),h=[function(e,n,r){return!o&&(r||n!==c)||((t=n).nodeType?f(e,n,r):l(e,n,r))}];for(;a1&&ft(h),a>1&&e.slice(0,a-1).join("").replace(j,"$1"),n,a0,s=e.length>0,o=function(u,a,f,l,h){var p,d,v,m=[],y=0,w="0",x=u&&[],T=h!=null,N=c,C=u||s&&i.find.TAG("*",h&&a.parentNode||a),k=b+=N==null?1:Math.E;T&&(c=a!==g&&a,n=o.el);for(;(p=C[w])!=null;w++){if(s&&p){for(d=0;v=e[d];d++)if(v(p,a,f)){l.push(p);break}T&&(b=k,n=++o.el)}r&&((p=!v&&p)&&y--,u&&x.push(p))}y+=w;if(r&&w!==y){for(d=0;v=t[d];d++)v(x,m,a,f);if(u){if(y>0)while(w--)!x[w]&&!m[w]&&(m[w]=E.call(l));m=lt(m)}S.apply(l,m),T&&!u&&m.length>0&&y+t.length>1&&nt.uniqueSort(l)}return T&&(b=k,c=N),x};return o.el=0,r?N(o):o}function dt(e,t,n){var r=0,i=t.length;for(;r2&&(f=u[0]).type==="ID"&&t.nodeType===9&&!s&&i.relative[u[1].type]){t=i.find.ID(f.matches[0].replace($,""),t,s)[0];if(!t)return n;e=e.slice(u.shift().length)}for(o=J.POS.test(e)?-1:u.length-1;o>=0;o--){f=u[o];if(i.relative[l=f.type])break;if(c=i.find[l])if(r=c(f.matches[0].replace($,""),z.test(u[0].type)&&t.parentNode||t,s)){u.splice(o,1),e=r.length&&u.join("");if(!e)return S.apply(n,x.call(r,0)),n;break}}}return a(e,h)(r,t,s,n,z.test(e)),n}function mt(){}var n,r,i,s,o,u,a,f,l,c,h=!0,p="undefined",d=("sizcache"+Math.random()).replace(".",""),m=String,g=e.document,y=g.documentElement,b=0,w=0,E=[].pop,S=[].push,x=[].slice,T=[].indexOf||function(e){var t=0,n=this.length;for(;ti.cacheLength&&delete e[t.shift()],e[n+" "]=r},e)},k=C(),L=C(),A=C(),O="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+",_=M.replace("w","w#"),D="([*^$|!~]?=)",P="\\["+O+"*("+M+")"+O+"*(?:"+D+O+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+_+")|)|)"+O+"*\\]",H=":("+M+")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|([^()[\\]]*|(?:(?:"+P+")|[^:]|\\\\.)*|.*))\\)|)",B=":(even|odd|eq|gt|lt|nth|first|last)(?:\\("+O+"*((?:-\\d)?\\d*)"+O+"*\\)|)(?=[^-]|$)",j=new RegExp("^"+O+"+|((?:^|[^\\\\])(?:\\\\.)*)"+O+"+$","g"),F=new RegExp("^"+O+"*,"+O+"*"),I=new RegExp("^"+O+"*([\\x20\\t\\r\\n\\f>+~])"+O+"*"),q=new RegExp(H),R=/^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/,U=/^:not/,z=/[\x20\t\r\n\f]*[+~]/,W=/:not\($/,X=/h\d/i,V=/input|select|textarea|button/i,$=/\\(?!\\)/g,J={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),NAME:new RegExp("^\\[name=['\"]?("+M+")['\"]?\\]"),TAG:new RegExp("^("+M.replace("w","w*")+")"),ATTR:new RegExp("^"+P),PSEUDO:new RegExp("^"+H),POS:new RegExp(B,"i"),CHILD:new RegExp("^:(only|nth|first|last)-child(?:\\("+O+"*(even|odd|(([+-]|)(\\d*)n|)"+O+"*(?:([+-]|)"+O+"*(\\d+)|))"+O+"*\\)|)","i"),needsContext:new RegExp("^"+O+"*[>+~]|"+B,"i")},K=function(e){var t=g.createElement("div");try{return e(t)}catch(n){return!1}finally{t=null}},Q=K(function(e){return e.appendChild(g.createComment("")),!e.getElementsByTagName("*").length}),G=K(function(e){return e.innerHTML="",e.firstChild&&typeof e.firstChild.getAttribute!==p&&e.firstChild.getAttribute("href")==="#"}),Y=K(function(e){e.innerHTML="";var t=typeof e.lastChild.getAttribute("multiple");return t!=="boolean"&&t!=="string"}),Z=K(function(e){return e.innerHTML="",!e.getElementsByClassName||!e.getElementsByClassName("e").length?!1:(e.lastChild.className="e",e.getElementsByClassName("e").length===2)}),et=K(function(e){e.id=d+0,e.innerHTML="
",y.insertBefore(e,y.firstChild);var t=g.getElementsByName&&g.getElementsByName(d).length===2+g.getElementsByName(d+0).length;return r=!g.getElementById(d),y.removeChild(e),t});try{x.call(y.childNodes,0)[0].nodeType}catch(tt){x=function(e){var t,n=[];for(;t=this[e];e++)n.push(t);return n}}nt.matches=function(e,t){return nt(e,null,null,t)},nt.matchesSelector=function(e,t){return nt(t,null,null,[e]).length>0},s=nt.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(i===1||i===9||i===11){if(typeof e.textContent=="string")return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=s(e)}else if(i===3||i===4)return e.nodeValue}else for(;t=e[r];r++)n+=s(t);return n},o=nt.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return t?t.nodeName!=="HTML":!1},u=nt.contains=y.contains?function(e,t){var n=e.nodeType===9?e.documentElement:e,r=t&&t.parentNode;return e===r||!!(r&&r.nodeType===1&&n.contains&&n.contains(r))}:y.compareDocumentPosition?function(e,t){return t&&!!(e.compareDocumentPosition(t)&16)}:function(e,t){while(t=t.parentNode)if(t===e)return!0;return!1},nt.attr=function(e,t){var n,r=o(e);return r||(t=t.toLowerCase()),(n=i.attrHandle[t])?n(e):r||Y?e.getAttribute(t):(n=e.getAttributeNode(t),n?typeof e[t]=="boolean"?e[t]?t:null:n.specified?n.value:null:null)},i=nt.selectors={cacheLength:50,createPseudo:N,match:J,attrHandle:G?{}:{href:function(e){return e.getAttribute("href",2)},type:function(e){return e.getAttribute("type")}},find:{ID:r?function(e,t,n){if(typeof t.getElementById!==p&&!n){var r=t.getElementById(e);return r&&r.parentNode?[r]:[]}}:function(e,n,r){if(typeof n.getElementById!==p&&!r){var i=n.getElementById(e);return i?i.id===e||typeof i.getAttributeNode!==p&&i.getAttributeNode("id").value===e?[i]:t:[]}},TAG:Q?function(e,t){if(typeof t.getElementsByTagName!==p)return t.getElementsByTagName(e)}:function(e,t){var n=t.getElementsByTagName(e);if(e==="*"){var r,i=[],s=0;for(;r=n[s];s++)r.nodeType===1&&i.push(r);return i}return n},NAME:et&&function(e,t){if(typeof t.getElementsByName!==p)return t.getElementsByName(name)},CLASS:Z&&function(e,t,n){if(typeof t.getElementsByClassName!==p&&!n)return t.getElementsByClassName(e)}},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace($,""),e[3]=(e[4]||e[5]||"").replace($,""),e[2]==="~="&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),e[1]==="nth"?(e[2]||nt.error(e[0]),e[3]=+(e[3]?e[4]+(e[5]||1):2*(e[2]==="even"||e[2]==="odd")),e[4]=+(e[6]+e[7]||e[2]==="odd")):e[2]&&nt.error(e[0]),e},PSEUDO:function(e){var t,n;if(J.CHILD.test(e[0]))return null;if(e[3])e[2]=e[3];else if(t=e[4])q.test(t)&&(n=ut(t,!0))&&(n=t.indexOf(")",t.length-n)-t.length)&&(t=t.slice(0,n),e[0]=e[0].slice(0,n)),e[2]=t;return e.slice(0,3)}},filter:{ID:r?function(e){return e=e.replace($,""),function(t){return t.getAttribute("id")===e}}:function(e){return e=e.replace($,""),function(t){var n=typeof t.getAttributeNode!==p&&t.getAttributeNode("id");return n&&n.value===e}},TAG:function(e){return e==="*"?function(){return!0}:(e=e.replace($,"").toLowerCase(),function(t){return t.nodeName&&t.nodeName.toLowerCase()===e})},CLASS:function(e){var t=k[d][e+" "];return t||(t=new RegExp("(^|"+O+")"+e+"("+O+"|$)"))&&k(e,function(e){return t.test(e.className||typeof e.getAttribute!==p&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r,i){var s=nt.attr(r,e);return s==null?t==="!=":t?(s+="",t==="="?s===n:t==="!="?s!==n:t==="^="?n&&s.indexOf(n)===0:t==="*="?n&&s.indexOf(n)>-1:t==="$="?n&&s.substr(s.length-n.length)===n:t==="~="?(" "+s+" ").indexOf(n)>-1:t==="|="?s===n||s.substr(0,n.length+1)===n+"-":!1):!0}},CHILD:function(e,t,n,r){return e==="nth"?function(e){var t,i,s=e.parentNode;if(n===1&&r===0)return!0;if(s){i=0;for(t=s.firstChild;t;t=t.nextSibling)if(t.nodeType===1){i++;if(e===t)break}}return i-=r,i===n||i%n===0&&i/n>=0}:function(t){var n=t;switch(e){case"only":case"first":while(n=n.previousSibling)if(n.nodeType===1)return!1;if(e==="first")return!0;n=t;case"last":while(n=n.nextSibling)if(n.nodeType===1)return!1;return!0}}},PSEUDO:function(e,t){var n,r=i.pseudos[e]||i.setFilters[e.toLowerCase()]||nt.error("unsupported pseudo: "+e);return r[d]?r(t):r.length>1?(n=[e,e,"",t],i.setFilters.hasOwnProperty(e.toLowerCase())?N(function(e,n){var i,s=r(e,t),o=s.length;while(o--)i=T.call(e,s[o]),e[i]=!(n[i]=s[o])}):function(e){return r(e,0,n)}):r}},pseudos:{not:N(function(e){var t=[],n=[],r=a(e.replace(j,"$1"));return r[d]?N(function(e,t,n,i){var s,o=r(e,null,i,[]),u=e.length;while(u--)if(s=o[u])e[u]=!(t[u]=s)}):function(e,i,s){return t[0]=e,r(t,null,s,n),!n.pop()}}),has:N(function(e){return function(t){return nt(e,t).length>0}}),contains:N(function(e){return function(t){return(t.textContent||t.innerText||s(t)).indexOf(e)>-1}}),enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return t==="input"&&!!e.checked||t==="option"&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},parent:function(e){return!i.pseudos.empty(e)},empty:function(e){var t;e=e.firstChild;while(e){if(e.nodeName>"@"||(t=e.nodeType)===3||t===4)return!1;e=e.nextSibling}return!0},header:function(e){return X.test(e.nodeName)},text:function(e){var t,n;return e.nodeName.toLowerCase()==="input"&&(t=e.type)==="text"&&((n=e.getAttribute("type"))==null||n.toLowerCase()===t)},radio:rt("radio"),checkbox:rt("checkbox"),file:rt("file"),password:rt("password"),image:rt("image"),submit:it("submit"),reset:it("reset"),button:function(e){var t=e.nodeName.toLowerCase();return t==="input"&&e.type==="button"||t==="button"},input:function(e){return V.test(e.nodeName)},focus:function(e){var t=e.ownerDocument;return e===t.activeElement&&(!t.hasFocus||t.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},active:function(e){return e===e.ownerDocument.activeElement},first:st(function(){return[0]}),last:st(function(e,t){return[t-1]}),eq:st(function(e,t,n){return[n<0?n+t:n]}),even:st(function(e,t){for(var n=0;n=0;)e.push(r);return e}),gt:st(function(e,t,n){for(var r=n<0?n+t:n;++r",e.querySelectorAll("[selected]").length||i.push("\\["+O+"*(?:checked|disabled|ismap|multiple|readonly|selected|value)"),e.querySelectorAll(":checked").length||i.push(":checked")}),K(function(e){e.innerHTML="

",e.querySelectorAll("[test^='']").length&&i.push("[*^$]="+O+"*(?:\"\"|'')"),e.innerHTML="",e.querySelectorAll(":enabled").length||i.push(":enabled",":disabled")}),i=new RegExp(i.join("|")),vt=function(e,r,s,o,u){if(!o&&!u&&!i.test(e)){var a,f,l=!0,c=d,h=r,p=r.nodeType===9&&e;if(r.nodeType===1&&r.nodeName.toLowerCase()!=="object"){a=ut(e),(l=r.getAttribute("id"))?c=l.replace(n,"\\$&"):r.setAttribute("id",c),c="[id='"+c+"'] ",f=a.length;while(f--)a[f]=c+a[f].join("");h=z.test(e)&&r.parentNode||r,p=a.join(",")}if(p)try{return S.apply(s,x.call(h.querySelectorAll(p),0)),s}catch(v){}finally{l||r.removeAttribute("id")}}return t(e,r,s,o,u)},u&&(K(function(t){e=u.call(t,"div");try{u.call(t,"[test!='']:sizzle"),s.push("!=",H)}catch(n){}}),s=new RegExp(s.join("|")),nt.matchesSelector=function(t,n){n=n.replace(r,"='$1']");if(!o(t)&&!s.test(n)&&!i.test(n))try{var a=u.call(t,n);if(a||e||t.document&&t.document.nodeType!==11)return a}catch(f){}return nt(n,null,null,[t]).length>0})}(),i.pseudos.nth=i.pseudos.eq,i.filters=mt.prototype=i.pseudos,i.setFilters=new mt,nt.attr=v.attr,v.find=nt,v.expr=nt.selectors,v.expr[":"]=v.expr.pseudos,v.unique=nt.uniqueSort,v.text=nt.getText,v.isXMLDoc=nt.isXML,v.contains=nt.contains}(e);var nt=/Until$/,rt=/^(?:parents|prev(?:Until|All))/,it=/^.[^:#\[\.,]*$/,st=v.expr.match.needsContext,ot={children:!0,contents:!0,next:!0,prev:!0};v.fn.extend({find:function(e){var t,n,r,i,s,o,u=this;if(typeof e!="string")return v(e).filter(function(){for(t=0,n=u.length;t0)for(i=r;i=0:v.filter(e,this).length>0:this.filter(e).length>0)},closest:function(e,t){var n,r=0,i=this.length,s=[],o=st.test(e)||typeof e!="string"?v(e,t||this.context):0;for(;r-1:v.find.matchesSelector(n,e)){s.push(n);break}n=n.parentNode}}return s=s.length>1?v.unique(s):s,this.pushStack(s,"closest",e)},index:function(e){return e?typeof e=="string"?v.inArray(this[0],v(e)):v.inArray(e.jquery?e[0]:e,this):this[0]&&this[0].parentNode?this.prevAll().length:-1},add:function(e,t){var n=typeof e=="string"?v(e,t):v.makeArray(e&&e.nodeType?[e]:e),r=v.merge(this.get(),n);return this.pushStack(ut(n[0])||ut(r[0])?r:v.unique(r))},addBack:function(e){return this.add(e==null?this.prevObject:this.prevObject.filter(e))}}),v.fn.andSelf=v.fn.addBack,v.each({parent:function(e){var t=e.parentNode;return t&&t.nodeType!==11?t:null},parents:function(e){return v.dir(e,"parentNode")},parentsUntil:function(e,t,n){return v.dir(e,"parentNode",n)},next:function(e){return at(e,"nextSibling")},prev:function(e){return at(e,"previousSibling")},nextAll:function(e){return v.dir(e,"nextSibling")},prevAll:function(e){return v.dir(e,"previousSibling")},nextUntil:function(e,t,n){return v.dir(e,"nextSibling",n)},prevUntil:function(e,t,n){return v.dir(e,"previousSibling",n)},siblings:function(e){return v.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return v.sibling(e.firstChild)},contents:function(e){return v.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:v.merge([],e.childNodes)}},function(e,t){v.fn[e]=function(n,r){var i=v.map(this,t,n);return nt.test(e)||(r=n),r&&typeof r=="string"&&(i=v.filter(r,i)),i=this.length>1&&!ot[e]?v.unique(i):i,this.length>1&&rt.test(e)&&(i=i.reverse()),this.pushStack(i,e,l.call(arguments).join(","))}}),v.extend({filter:function(e,t,n){return n&&(e=":not("+e+")"),t.length===1?v.find.matchesSelector(t[0],e)?[t[0]]:[]:v.find.matches(e,t)},dir:function(e,n,r){var i=[],s=e[n];while(s&&s.nodeType!==9&&(r===t||s.nodeType!==1||!v(s).is(r)))s.nodeType===1&&i.push(s),s=s[n];return i},sibling:function(e,t){var n=[];for(;e;e=e.nextSibling)e.nodeType===1&&e!==t&&n.push(e);return n}});var ct="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",ht=/ jQuery\d+="(?:null|\d+)"/g,pt=/^\s+/,dt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,vt=/<([\w:]+)/,mt=/]","i"),Et=/^(?:checkbox|radio)$/,St=/checked\s*(?:[^=]|=\s*.checked.)/i,xt=/\/(java|ecma)script/i,Tt=/^\s*\s*$/g,Nt={option:[1,""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]},Ct=lt(i),kt=Ct.appendChild(i.createElement("div"));Nt.optgroup=Nt.option,Nt.tbody=Nt.tfoot=Nt.colgroup=Nt.caption=Nt.thead,Nt.th=Nt.td,v.support.htmlSerialize||(Nt._default=[1,"X
","
"]),v.fn.extend({text:function(e){return v.access(this,function(e){return e===t?v.text(this):this.empty().append((this[0]&&this[0].ownerDocument||i).createTextNode(e))},null,e,arguments.length)},wrapAll:function(e){if(v.isFunction(e))return this.each(function(t){v(this).wrapAll(e.call(this,t))});if(this[0]){var t=v(e,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstChild&&e.firstChild.nodeType===1)e=e.firstChild;return e}).append(this)}return this},wrapInner:function(e){return v.isFunction(e)?this.each(function(t){v(this).wrapInner(e.call(this,t))}):this.each(function(){var t=v(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=v.isFunction(e);return this.each(function(n){v(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){v.nodeName(this,"body")||v(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(e){(this.nodeType===1||this.nodeType===11)&&this.appendChild(e)})},prepend:function(){return this.domManip(arguments,!0,function(e){(this.nodeType===1||this.nodeType===11)&&this.insertBefore(e,this.firstChild)})},before:function(){if(!ut(this[0]))return this.domManip(arguments,!1,function(e){this.parentNode.insertBefore(e,this)});if(arguments.length){var e=v.clean(arguments);return this.pushStack(v.merge(e,this),"before",this.selector)}},after:function(){if(!ut(this[0]))return this.domManip(arguments,!1,function(e){this.parentNode.insertBefore(e,this.nextSibling)});if(arguments.length){var e=v.clean(arguments);return this.pushStack(v.merge(this,e),"after",this.selector)}},remove:function(e,t){var n,r=0;for(;(n=this[r])!=null;r++)if(!e||v.filter(e,[n]).length)!t&&n.nodeType===1&&(v.cleanData(n.getElementsByTagName("*")),v.cleanData([n])),n.parentNode&&n.parentNode.removeChild(n);return this},empty:function(){var e,t=0;for(;(e=this[t])!=null;t++){e.nodeType===1&&v.cleanData(e.getElementsByTagName("*"));while(e.firstChild)e.removeChild(e.firstChild)}return this},clone:function(e,t){return e=e==null?!1:e,t=t==null?e:t,this.map(function(){return v.clone(this,e,t)})},html:function(e){return v.access(this,function(e){var n=this[0]||{},r=0,i=this.length;if(e===t)return n.nodeType===1?n.innerHTML.replace(ht,""):t;if(typeof e=="string"&&!yt.test(e)&&(v.support.htmlSerialize||!wt.test(e))&&(v.support.leadingWhitespace||!pt.test(e))&&!Nt[(vt.exec(e)||["",""])[1].toLowerCase()]){e=e.replace(dt,"<$1>");try{for(;r1&&typeof f=="string"&&St.test(f))return this.each(function(){v(this).domManip(e,n,r)});if(v.isFunction(f))return this.each(function(i){var s=v(this);e[0]=f.call(this,i,n?s.html():t),s.domManip(e,n,r)});if(this[0]){i=v.buildFragment(e,this,l),o=i.fragment,s=o.firstChild,o.childNodes.length===1&&(o=s);if(s){n=n&&v.nodeName(s,"tr");for(u=i.cacheable||c-1;a0?this.clone(!0):this).get(),v(o[i])[t](r),s=s.concat(r);return this.pushStack(s,e,o.selector)}}),v.extend({clone:function(e,t,n){var r,i,s,o;v.support.html5Clone||v.isXMLDoc(e)||!wt.test("<"+e.nodeName+">")?o=e.cloneNode(!0):(kt.innerHTML=e.outerHTML,kt.removeChild(o=kt.firstChild));if((!v.support.noCloneEvent||!v.support.noCloneChecked)&&(e.nodeType===1||e.nodeType===11)&&!v.isXMLDoc(e)){Ot(e,o),r=Mt(e),i=Mt(o);for(s=0;r[s];++s)i[s]&&Ot(r[s],i[s])}if(t){At(e,o);if(n){r=Mt(e),i=Mt(o);for(s=0;r[s];++s)At(r[s],i[s])}}return r=i=null,o},clean:function(e,t,n,r){var s,o,u,a,f,l,c,h,p,d,m,g,y=t===i&&Ct,b=[];if(!t||typeof t.createDocumentFragment=="undefined")t=i;for(s=0;(u=e[s])!=null;s++){typeof u=="number"&&(u+="");if(!u)continue;if(typeof u=="string")if(!gt.test(u))u=t.createTextNode(u);else{y=y||lt(t),c=t.createElement("div"),y.appendChild(c),u=u.replace(dt,"<$1>"),a=(vt.exec(u)||["",""])[1].toLowerCase(),f=Nt[a]||Nt._default,l=f[0],c.innerHTML=f[1]+u+f[2];while(l--)c=c.lastChild;if(!v.support.tbody){h=mt.test(u),p=a==="table"&&!h?c.firstChild&&c.firstChild.childNodes:f[1]===""&&!h?c.childNodes:[];for(o=p.length-1;o>=0;--o)v.nodeName(p[o],"tbody")&&!p[o].childNodes.length&&p[o].parentNode.removeChild(p[o])}!v.support.leadingWhitespace&&pt.test(u)&&c.insertBefore(t.createTextNode(pt.exec(u)[0]),c.firstChild),u=c.childNodes,c.parentNode.removeChild(c)}u.nodeType?b.push(u):v.merge(b,u)}c&&(u=c=y=null);if(!v.support.appendChecked)for(s=0;(u=b[s])!=null;s++)v.nodeName(u,"input")?_t(u):typeof u.getElementsByTagName!="undefined"&&v.grep(u.getElementsByTagName("input"),_t);if(n){m=function(e){if(!e.type||xt.test(e.type))return r?r.push(e.parentNode?e.parentNode.removeChild(e):e):n.appendChild(e)};for(s=0;(u=b[s])!=null;s++)if(!v.nodeName(u,"script")||!m(u))n.appendChild(u),typeof u.getElementsByTagName!="undefined"&&(g=v.grep(v.merge([],u.getElementsByTagName("script")),m),b.splice.apply(b,[s+1,0].concat(g)),s+=g.length)}return b},cleanData:function(e,t){var n,r,i,s,o=0,u=v.expando,a=v.cache,f=v.support.deleteExpando,l=v.event.special;for(;(i=e[o])!=null;o++)if(t||v.acceptData(i)){r=i[u],n=r&&a[r];if(n){if(n.events)for(s in n.events)l[s]?v.event.remove(i,s):v.removeEvent(i,s,n.handle);a[r]&&(delete a[r],f?delete i[u]:i.removeAttribute?i.removeAttribute(u):i[u]=null,v.deletedIds.push(r))}}}}),function(){var e,t;v.uaMatch=function(e){e=e.toLowerCase();var t=/(chrome)[ \/]([\w.]+)/.exec(e)||/(webkit)[ \/]([\w.]+)/.exec(e)||/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(e)||/(msie) ([\w.]+)/.exec(e)||e.indexOf("compatible")<0&&/(mozilla)(?:.*? rv:([\w.]+)|)/.exec(e)||[];return{browser:t[1]||"",version:t[2]||"0"}},e=v.uaMatch(o.userAgent),t={},e.browser&&(t[e.browser]=!0,t.version=e.version),t.chrome?t.webkit=!0:t.webkit&&(t.safari=!0),v.browser=t,v.sub=function(){function e(t,n){return new e.fn.init(t,n)}v.extend(!0,e,this),e.superclass=this,e.fn=e.prototype=this(),e.fn.constructor=e,e.sub=this.sub,e.fn.init=function(r,i){return i&&i instanceof v&&!(i instanceof e)&&(i=e(i)),v.fn.init.call(this,r,i,t)},e.fn.init.prototype=e.fn;var t=e(i);return e}}();var Dt,Pt,Ht,Bt=/alpha\([^)]*\)/i,jt=/opacity=([^)]*)/,Ft=/^(top|right|bottom|left)$/,It=/^(none|table(?!-c[ea]).+)/,qt=/^margin/,Rt=new RegExp("^("+m+")(.*)$","i"),Ut=new RegExp("^("+m+")(?!px)[a-z%]+$","i"),zt=new RegExp("^([-+])=("+m+")","i"),Wt={BODY:"block"},Xt={position:"absolute",visibility:"hidden",display:"block"},Vt={letterSpacing:0,fontWeight:400},$t=["Top","Right","Bottom","Left"],Jt=["Webkit","O","Moz","ms"],Kt=v.fn.toggle;v.fn.extend({css:function(e,n){return v.access(this,function(e,n,r){return r!==t?v.style(e,n,r):v.css(e,n)},e,n,arguments.length>1)},show:function(){return Yt(this,!0)},hide:function(){return Yt(this)},toggle:function(e,t){var n=typeof e=="boolean";return v.isFunction(e)&&v.isFunction(t)?Kt.apply(this,arguments):this.each(function(){(n?e:Gt(this))?v(this).show():v(this).hide()})}}),v.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Dt(e,"opacity");return n===""?"1":n}}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":v.support.cssFloat?"cssFloat":"styleFloat"},style:function(e,n,r,i){if(!e||e.nodeType===3||e.nodeType===8||!e.style)return;var s,o,u,a=v.camelCase(n),f=e.style;n=v.cssProps[a]||(v.cssProps[a]=Qt(f,a)),u=v.cssHooks[n]||v.cssHooks[a];if(r===t)return u&&"get"in u&&(s=u.get(e,!1,i))!==t?s:f[n];o=typeof r,o==="string"&&(s=zt.exec(r))&&(r=(s[1]+1)*s[2]+parseFloat(v.css(e,n)),o="number");if(r==null||o==="number"&&isNaN(r))return;o==="number"&&!v.cssNumber[a]&&(r+="px");if(!u||!("set"in u)||(r=u.set(e,r,i))!==t)try{f[n]=r}catch(l){}},css:function(e,n,r,i){var s,o,u,a=v.camelCase(n);return n=v.cssProps[a]||(v.cssProps[a]=Qt(e.style,a)),u=v.cssHooks[n]||v.cssHooks[a],u&&"get"in u&&(s=u.get(e,!0,i)),s===t&&(s=Dt(e,n)),s==="normal"&&n in Vt&&(s=Vt[n]),r||i!==t?(o=parseFloat(s),r||v.isNumeric(o)?o||0:s):s},swap:function(e,t,n){var r,i,s={};for(i in t)s[i]=e.style[i],e.style[i]=t[i];r=n.call(e);for(i in t)e.style[i]=s[i];return r}}),e.getComputedStyle?Dt=function(t,n){var r,i,s,o,u=e.getComputedStyle(t,null),a=t.style;return u&&(r=u.getPropertyValue(n)||u[n],r===""&&!v.contains(t.ownerDocument,t)&&(r=v.style(t,n)),Ut.test(r)&&qt.test(n)&&(i=a.width,s=a.minWidth,o=a.maxWidth,a.minWidth=a.maxWidth=a.width=r,r=u.width,a.width=i,a.minWidth=s,a.maxWidth=o)),r}:i.documentElement.currentStyle&&(Dt=function(e,t){var n,r,i=e.currentStyle&&e.currentStyle[t],s=e.style;return i==null&&s&&s[t]&&(i=s[t]),Ut.test(i)&&!Ft.test(t)&&(n=s.left,r=e.runtimeStyle&&e.runtimeStyle.left,r&&(e.runtimeStyle.left=e.currentStyle.left),s.left=t==="fontSize"?"1em":i,i=s.pixelLeft+"px",s.left=n,r&&(e.runtimeStyle.left=r)),i===""?"auto":i}),v.each(["height","width"],function(e,t){v.cssHooks[t]={get:function(e,n,r){if(n)return e.offsetWidth===0&&It.test(Dt(e,"display"))?v.swap(e,Xt,function(){return tn(e,t,r)}):tn(e,t,r)},set:function(e,n,r){return Zt(e,n,r?en(e,t,r,v.support.boxSizing&&v.css(e,"boxSizing")==="border-box"):0)}}}),v.support.opacity||(v.cssHooks.opacity={get:function(e,t){return jt.test((t&&e.currentStyle?e.currentStyle.filter:e.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":t?"1":""},set:function(e,t){var n=e.style,r=e.currentStyle,i=v.isNumeric(t)?"alpha(opacity="+t*100+")":"",s=r&&r.filter||n.filter||"";n.zoom=1;if(t>=1&&v.trim(s.replace(Bt,""))===""&&n.removeAttribute){n.removeAttribute("filter");if(r&&!r.filter)return}n.filter=Bt.test(s)?s.replace(Bt,i):s+" "+i}}),v(function(){v.support.reliableMarginRight||(v.cssHooks.marginRight={get:function(e,t){return v.swap(e,{display:"inline-block"},function(){if(t)return Dt(e,"marginRight")})}}),!v.support.pixelPosition&&v.fn.position&&v.each(["top","left"],function(e,t){v.cssHooks[t]={get:function(e,n){if(n){var r=Dt(e,t);return Ut.test(r)?v(e).position()[t]+"px":r}}}})}),v.expr&&v.expr.filters&&(v.expr.filters.hidden=function(e){return e.offsetWidth===0&&e.offsetHeight===0||!v.support.reliableHiddenOffsets&&(e.style&&e.style.display||Dt(e,"display"))==="none"},v.expr.filters.visible=function(e){return!v.expr.filters.hidden(e)}),v.each({margin:"",padding:"",border:"Width"},function(e,t){v.cssHooks[e+t]={expand:function(n){var r,i=typeof n=="string"?n.split(" "):[n],s={};for(r=0;r<4;r++)s[e+$t[r]+t]=i[r]||i[r-2]||i[0];return s}},qt.test(e)||(v.cssHooks[e+t].set=Zt)});var rn=/%20/g,sn=/\[\]$/,on=/\r?\n/g,un=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,an=/^(?:select|textarea)/i;v.fn.extend({serialize:function(){return v.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?v.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||an.test(this.nodeName)||un.test(this.type))}).map(function(e,t){var n=v(this).val();return n==null?null:v.isArray(n)?v.map(n,function(e,n){return{name:t.name,value:e.replace(on,"\r\n")}}):{name:t.name,value:n.replace(on,"\r\n")}}).get()}}),v.param=function(e,n){var r,i=[],s=function(e,t){t=v.isFunction(t)?t():t==null?"":t,i[i.length]=encodeURIComponent(e)+"="+encodeURIComponent(t)};n===t&&(n=v.ajaxSettings&&v.ajaxSettings.traditional);if(v.isArray(e)||e.jquery&&!v.isPlainObject(e))v.each(e,function(){s(this.name,this.value)});else for(r in e)fn(r,e[r],n,s);return i.join("&").replace(rn,"+")};var ln,cn,hn=/#.*$/,pn=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,dn=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,vn=/^(?:GET|HEAD)$/,mn=/^\/\//,gn=/\?/,yn=/)<[^<]*)*<\/script>/gi,bn=/([?&])_=[^&]*/,wn=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,En=v.fn.load,Sn={},xn={},Tn=["*/"]+["*"];try{cn=s.href}catch(Nn){cn=i.createElement("a"),cn.href="",cn=cn.href}ln=wn.exec(cn.toLowerCase())||[],v.fn.load=function(e,n,r){if(typeof e!="string"&&En)return En.apply(this,arguments);if(!this.length)return this;var i,s,o,u=this,a=e.indexOf(" ");return a>=0&&(i=e.slice(a,e.length),e=e.slice(0,a)),v.isFunction(n)?(r=n,n=t):n&&typeof n=="object"&&(s="POST"),v.ajax({url:e,type:s,dataType:"html",data:n,complete:function(e,t){r&&u.each(r,o||[e.responseText,t,e])}}).done(function(e){o=arguments,u.html(i?v("
").append(e.replace(yn,"")).find(i):e)}),this},v.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(e,t){v.fn[t]=function(e){return this.on(t,e)}}),v.each(["get","post"],function(e,n){v[n]=function(e,r,i,s){return v.isFunction(r)&&(s=s||i,i=r,r=t),v.ajax({type:n,url:e,data:r,success:i,dataType:s})}}),v.extend({getScript:function(e,n){return v.get(e,t,n,"script")},getJSON:function(e,t,n){return v.get(e,t,n,"json")},ajaxSetup:function(e,t){return t?Ln(e,v.ajaxSettings):(t=e,e=v.ajaxSettings),Ln(e,t),e},ajaxSettings:{url:cn,isLocal:dn.test(ln[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded; charset=UTF-8",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":Tn},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":e.String,"text html":!0,"text json":v.parseJSON,"text xml":v.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:Cn(Sn),ajaxTransport:Cn(xn),ajax:function(e,n){function T(e,n,s,a){var l,y,b,w,S,T=n;if(E===2)return;E=2,u&&clearTimeout(u),o=t,i=a||"",x.readyState=e>0?4:0,s&&(w=An(c,x,s));if(e>=200&&e<300||e===304)c.ifModified&&(S=x.getResponseHeader("Last-Modified"),S&&(v.lastModified[r]=S),S=x.getResponseHeader("Etag"),S&&(v.etag[r]=S)),e===304?(T="notmodified",l=!0):(l=On(c,w),T=l.state,y=l.data,b=l.error,l=!b);else{b=T;if(!T||e)T="error",e<0&&(e=0)}x.status=e,x.statusText=(n||T)+"",l?d.resolveWith(h,[y,T,x]):d.rejectWith(h,[x,T,b]),x.statusCode(g),g=t,f&&p.trigger("ajax"+(l?"Success":"Error"),[x,c,l?y:b]),m.fireWith(h,[x,T]),f&&(p.trigger("ajaxComplete",[x,c]),--v.active||v.event.trigger("ajaxStop"))}typeof e=="object"&&(n=e,e=t),n=n||{};var r,i,s,o,u,a,f,l,c=v.ajaxSetup({},n),h=c.context||c,p=h!==c&&(h.nodeType||h instanceof v)?v(h):v.event,d=v.Deferred(),m=v.Callbacks("once memory"),g=c.statusCode||{},b={},w={},E=0,S="canceled",x={readyState:0,setRequestHeader:function(e,t){if(!E){var n=e.toLowerCase();e=w[n]=w[n]||e,b[e]=t}return this},getAllResponseHeaders:function(){return E===2?i:null},getResponseHeader:function(e){var n;if(E===2){if(!s){s={};while(n=pn.exec(i))s[n[1].toLowerCase()]=n[2]}n=s[e.toLowerCase()]}return n===t?null:n},overrideMimeType:function(e){return E||(c.mimeType=e),this},abort:function(e){return e=e||S,o&&o.abort(e),T(0,e),this}};d.promise(x),x.success=x.done,x.error=x.fail,x.complete=m.add,x.statusCode=function(e){if(e){var t;if(E<2)for(t in e)g[t]=[g[t],e[t]];else t=e[x.status],x.always(t)}return this},c.url=((e||c.url)+"").replace(hn,"").replace(mn,ln[1]+"//"),c.dataTypes=v.trim(c.dataType||"*").toLowerCase().split(y),c.crossDomain==null&&(a=wn.exec(c.url.toLowerCase()),c.crossDomain=!(!a||a[1]===ln[1]&&a[2]===ln[2]&&(a[3]||(a[1]==="http:"?80:443))==(ln[3]||(ln[1]==="http:"?80:443)))),c.data&&c.processData&&typeof c.data!="string"&&(c.data=v.param(c.data,c.traditional)),kn(Sn,c,n,x);if(E===2)return x;f=c.global,c.type=c.type.toUpperCase(),c.hasContent=!vn.test(c.type),f&&v.active++===0&&v.event.trigger("ajaxStart");if(!c.hasContent){c.data&&(c.url+=(gn.test(c.url)?"&":"?")+c.data,delete c.data),r=c.url;if(c.cache===!1){var N=v.now(),C=c.url.replace(bn,"$1_="+N);c.url=C+(C===c.url?(gn.test(c.url)?"&":"?")+"_="+N:"")}}(c.data&&c.hasContent&&c.contentType!==!1||n.contentType)&&x.setRequestHeader("Content-Type",c.contentType),c.ifModified&&(r=r||c.url,v.lastModified[r]&&x.setRequestHeader("If-Modified-Since",v.lastModified[r]),v.etag[r]&&x.setRequestHeader("If-None-Match",v.etag[r])),x.setRequestHeader("Accept",c.dataTypes[0]&&c.accepts[c.dataTypes[0]]?c.accepts[c.dataTypes[0]]+(c.dataTypes[0]!=="*"?", "+Tn+"; q=0.01":""):c.accepts["*"]);for(l in c.headers)x.setRequestHeader(l,c.headers[l]);if(!c.beforeSend||c.beforeSend.call(h,x,c)!==!1&&E!==2){S="abort";for(l in{success:1,error:1,complete:1})x[l](c[l]);o=kn(xn,c,n,x);if(!o)T(-1,"No Transport");else{x.readyState=1,f&&p.trigger("ajaxSend",[x,c]),c.async&&c.timeout>0&&(u=setTimeout(function(){x.abort("timeout")},c.timeout));try{E=1,o.send(b,T)}catch(k){if(!(E<2))throw k;T(-1,k)}}return x}return x.abort()},active:0,lastModified:{},etag:{}});var Mn=[],_n=/\?/,Dn=/(=)\?(?=&|$)|\?\?/,Pn=v.now();v.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Mn.pop()||v.expando+"_"+Pn++;return this[e]=!0,e}}),v.ajaxPrefilter("json jsonp",function(n,r,i){var s,o,u,a=n.data,f=n.url,l=n.jsonp!==!1,c=l&&Dn.test(f),h=l&&!c&&typeof a=="string"&&!(n.contentType||"").indexOf("application/x-www-form-urlencoded")&&Dn.test(a);if(n.dataTypes[0]==="jsonp"||c||h)return s=n.jsonpCallback=v.isFunction(n.jsonpCallback)?n.jsonpCallback():n.jsonpCallback,o=e[s],c?n.url=f.replace(Dn,"$1"+s):h?n.data=a.replace(Dn,"$1"+s):l&&(n.url+=(_n.test(f)?"&":"?")+n.jsonp+"="+s),n.converters["script json"]=function(){return u||v.error(s+" was not called"),u[0]},n.dataTypes[0]="json",e[s]=function(){u=arguments},i.always(function(){e[s]=o,n[s]&&(n.jsonpCallback=r.jsonpCallback,Mn.push(s)),u&&v.isFunction(o)&&o(u[0]),u=o=t}),"script"}),v.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(e){return v.globalEval(e),e}}}),v.ajaxPrefilter("script",function(e){e.cache===t&&(e.cache=!1),e.crossDomain&&(e.type="GET",e.global=!1)}),v.ajaxTransport("script",function(e){if(e.crossDomain){var n,r=i.head||i.getElementsByTagName("head")[0]||i.documentElement;return{send:function(s,o){n=i.createElement("script"),n.async="async",e.scriptCharset&&(n.charset=e.scriptCharset),n.src=e.url,n.onload=n.onreadystatechange=function(e,i){if(i||!n.readyState||/loaded|complete/.test(n.readyState))n.onload=n.onreadystatechange=null,r&&n.parentNode&&r.removeChild(n),n=t,i||o(200,"success")},r.insertBefore(n,r.firstChild)},abort:function(){n&&n.onload(0,1)}}}});var Hn,Bn=e.ActiveXObject?function(){for(var e in Hn)Hn[e](0,1)}:!1,jn=0;v.ajaxSettings.xhr=e.ActiveXObject?function(){return!this.isLocal&&Fn()||In()}:Fn,function(e){v.extend(v.support,{ajax:!!e,cors:!!e&&"withCredentials"in e})}(v.ajaxSettings.xhr()),v.support.ajax&&v.ajaxTransport(function(n){if(!n.crossDomain||v.support.cors){var r;return{send:function(i,s){var o,u,a=n.xhr();n.username?a.open(n.type,n.url,n.async,n.username,n.password):a.open(n.type,n.url,n.async);if(n.xhrFields)for(u in n.xhrFields)a[u]=n.xhrFields[u];n.mimeType&&a.overrideMimeType&&a.overrideMimeType(n.mimeType),!n.crossDomain&&!i["X-Requested-With"]&&(i["X-Requested-With"]="XMLHttpRequest");try{for(u in i)a.setRequestHeader(u,i[u])}catch(f){}a.send(n.hasContent&&n.data||null),r=function(e,i){var u,f,l,c,h;try{if(r&&(i||a.readyState===4)){r=t,o&&(a.onreadystatechange=v.noop,Bn&&delete Hn[o]);if(i)a.readyState!==4&&a.abort();else{u=a.status,l=a.getAllResponseHeaders(),c={},h=a.responseXML,h&&h.documentElement&&(c.xml=h);try{c.text=a.responseText}catch(p){}try{f=a.statusText}catch(p){f=""}!u&&n.isLocal&&!n.crossDomain?u=c.text?200:404:u===1223&&(u=204)}}}catch(d){i||s(-1,d)}c&&s(u,f,c,l)},n.async?a.readyState===4?setTimeout(r,0):(o=++jn,Bn&&(Hn||(Hn={},v(e).unload(Bn)),Hn[o]=r),a.onreadystatechange=r):r()},abort:function(){r&&r(0,1)}}}});var qn,Rn,Un=/^(?:toggle|show|hide)$/,zn=new RegExp("^(?:([-+])=|)("+m+")([a-z%]*)$","i"),Wn=/queueHooks$/,Xn=[Gn],Vn={"*":[function(e,t){var n,r,i=this.createTween(e,t),s=zn.exec(t),o=i.cur(),u=+o||0,a=1,f=20;if(s){n=+s[2],r=s[3]||(v.cssNumber[e]?"":"px");if(r!=="px"&&u){u=v.css(i.elem,e,!0)||n||1;do a=a||".5",u/=a,v.style(i.elem,e,u+r);while(a!==(a=i.cur()/o)&&a!==1&&--f)}i.unit=r,i.start=u,i.end=s[1]?u+(s[1]+1)*n:n}return i}]};v.Animation=v.extend(Kn,{tweener:function(e,t){v.isFunction(e)?(t=e,e=["*"]):e=e.split(" ");var n,r=0,i=e.length;for(;r-1,f={},l={},c,h;a?(l=i.position(),c=l.top,h=l.left):(c=parseFloat(o)||0,h=parseFloat(u)||0),v.isFunction(t)&&(t=t.call(e,n,s)),t.top!=null&&(f.top=t.top-s.top+c),t.left!=null&&(f.left=t.left-s.left+h),"using"in t?t.using.call(e,f):i.css(f)}},v.fn.extend({position:function(){if(!this[0])return;var e=this[0],t=this.offsetParent(),n=this.offset(),r=er.test(t[0].nodeName)?{top:0,left:0}:t.offset();return n.top-=parseFloat(v.css(e,"marginTop"))||0,n.left-=parseFloat(v.css(e,"marginLeft"))||0,r.top+=parseFloat(v.css(t[0],"borderTopWidth"))||0,r.left+=parseFloat(v.css(t[0],"borderLeftWidth"))||0,{top:n.top-r.top,left:n.left-r.left}},offsetParent:function(){return this.map(function(){var e=this.offsetParent||i.body;while(e&&!er.test(e.nodeName)&&v.css(e,"position")==="static")e=e.offsetParent;return e||i.body})}}),v.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(e,n){var r=/Y/.test(n);v.fn[e]=function(i){return v.access(this,function(e,i,s){var o=tr(e);if(s===t)return o?n in o?o[n]:o.document.documentElement[i]:e[i];o?o.scrollTo(r?v(o).scrollLeft():s,r?s:v(o).scrollTop()):e[i]=s},e,i,arguments.length,null)}}),v.each({Height:"height",Width:"width"},function(e,n){v.each({padding:"inner"+e,content:n,"":"outer"+e},function(r,i){v.fn[i]=function(i,s){var o=arguments.length&&(r||typeof i!="boolean"),u=r||(i===!0||s===!0?"margin":"border");return v.access(this,function(n,r,i){var s;return v.isWindow(n)?n.document.documentElement["client"+e]:n.nodeType===9?(s=n.documentElement,Math.max(n.body["scroll"+e],s["scroll"+e],n.body["offset"+e],s["offset"+e],s["client"+e])):i===t?v.css(n,r,i,u):v.style(n,r,i,u)},n,o?i:t,o,null)}})}),e.jQuery=e.$=v,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return v})})(window); \ No newline at end of file diff --git a/phpBB/includes/db/migration/data/310/dev.php b/phpBB/includes/db/migration/data/310/dev.php index 13b36bbf30..982dc9662e 100644 --- a/phpBB/includes/db/migration/data/310/dev.php +++ b/phpBB/includes/db/migration/data/310/dev.php @@ -91,7 +91,7 @@ class phpbb_db_migration_data_310_dev extends phpbb_db_migration array('config.add', array('fulltext_sphinx_indexer_mem_limit', 512)), array('config.add', array('load_jquery_cdn', 0)), - array('config.add', array('load_jquery_url', '//ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js')), + array('config.add', array('load_jquery_url', '//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js')), array('config.add', array('use_system_cron', 0)), diff --git a/phpBB/install/schemas/schema_data.sql b/phpBB/install/schemas/schema_data.sql index f118d330ba..8295be7e1a 100644 --- a/phpBB/install/schemas/schema_data.sql +++ b/phpBB/install/schemas/schema_data.sql @@ -173,7 +173,7 @@ INSERT INTO phpbb_config (config_name, config_value) VALUES ('load_cpf_viewtopic INSERT INTO phpbb_config (config_name, config_value) VALUES ('load_db_lastread', '1'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('load_db_track', '1'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('load_jquery_cdn', '0'); -INSERT INTO phpbb_config (config_name, config_value) VALUES ('load_jquery_url', '//ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('load_jquery_url', '//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('load_jumpbox', '1'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('load_moderators', '1'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('load_notifications', '1'); From b17c0aa098485994355a173299ab54fd91629f8e Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Fri, 15 Mar 2013 01:21:12 +0100 Subject: [PATCH 012/281] [ticket/11440] Remove useless/incorrect comment. PHPBB3-11440 --- phpBB/includes/user_loader.php | 1 - 1 file changed, 1 deletion(-) diff --git a/phpBB/includes/user_loader.php b/phpBB/includes/user_loader.php index 77128d6570..a834051ab3 100644 --- a/phpBB/includes/user_loader.php +++ b/phpBB/includes/user_loader.php @@ -70,7 +70,6 @@ class phpbb_user_loader { $user_ids[] = ANONYMOUS; - // Load the users $user_ids = array_unique($user_ids); // Do not load users we already have in $this->users From 1694dc6e2853c294c502e387d2d2463501d2d844 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Fri, 15 Mar 2013 01:22:00 +0100 Subject: [PATCH 013/281] [ticket/11440] Cast values of the $user_ids array to integer before sql_in_set. PHPBB3-11440 --- phpBB/includes/user_loader.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/phpBB/includes/user_loader.php b/phpBB/includes/user_loader.php index a834051ab3..37bf9648c1 100644 --- a/phpBB/includes/user_loader.php +++ b/phpBB/includes/user_loader.php @@ -70,7 +70,8 @@ class phpbb_user_loader { $user_ids[] = ANONYMOUS; - $user_ids = array_unique($user_ids); + // Make user_ids unique and convert to integer. + $user_ids = array_map('intval', array_unique($user_ids)); // Do not load users we already have in $this->users $user_ids = array_diff($user_ids, array_keys($this->users)); From 8c512b0d2d73a0930a420030dd6fecb8cb2d506f Mon Sep 17 00:00:00 2001 From: David King Date: Fri, 18 Jan 2013 14:00:40 -0500 Subject: [PATCH 014/281] [ticket/11334] Properly generate controller URL until paths issue gets fixed PHPBB3-11334 --- phpBB/includes/controller/helper.php | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/phpBB/includes/controller/helper.php b/phpBB/includes/controller/helper.php index 6cacc8fefa..2098f51edf 100644 --- a/phpBB/includes/controller/helper.php +++ b/phpBB/includes/controller/helper.php @@ -85,17 +85,14 @@ class phpbb_controller_helper } /** - * Easily generate a URL + * Generate a URL * - * @param array $url_parts Each array element is a 'folder' - * i.e. array('my', 'ext') maps to ./app.php/my/ext - * @param mixed $query The Query string, passed directly into the second - * argument of append_sid() - * @return string A URL that has already been run through append_sid() + * @param string $route The route to travel + * @return string The URL already passed through append_sid() */ - public function url(array $url_parts, $query = '') + protected function url($route) { - return append_sid($this->phpbb_root_path . implode('/', $url_parts), $query); + return append_sid($this->phpbb_root_path . 'app.' . $this->php_ext, array('controller' => $route)); } /** From d3e2fae66d74f79ef7dcfe2e24f47efaa5c106e2 Mon Sep 17 00:00:00 2001 From: David King Date: Fri, 15 Feb 2013 16:48:43 -0500 Subject: [PATCH 015/281] [ticket/11334] Add a test for the controller helper URL method PHPBB3-11334 --- phpBB/includes/controller/helper.php | 2 +- tests/controller/controller_test.php | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/phpBB/includes/controller/helper.php b/phpBB/includes/controller/helper.php index 2098f51edf..0e64829874 100644 --- a/phpBB/includes/controller/helper.php +++ b/phpBB/includes/controller/helper.php @@ -55,7 +55,7 @@ class phpbb_controller_helper * @param string $phpbb_root_path phpBB root path * @param string $php_ext PHP extension */ - public function __construct(phpbb_template $template, phpbb_user $user, $phpbb_root_path, $php_ext) + public function __construct(phpbb_template $template = null, phpbb_user $user = null, $phpbb_root_path = './', $php_ext = '.php') { $this->template = $template; $this->user = $user; diff --git a/tests/controller/controller_test.php b/tests/controller/controller_test.php index 198fb3c6dd..97f6d6152a 100644 --- a/tests/controller/controller_test.php +++ b/tests/controller/controller_test.php @@ -40,6 +40,12 @@ class phpbb_controller_test extends phpbb_test_case $this->assertEquals(2, sizeof($routes)); } + public function test_controller_url_helper() + { + $helper = new phpbb_controller_helper; + $this->assertEquals($helper->url('foo/bar'),'./app.php?controller=foo/bar'); + } + public function test_controller_resolver() { $container = new ContainerBuilder(); From 5e89ce1898857f29e5345adf31d62bbed1fb985b Mon Sep 17 00:00:00 2001 From: David King Date: Fri, 15 Feb 2013 16:52:54 -0500 Subject: [PATCH 016/281] [ticket/11334] Make url helper method public PHPBB3-11334 --- phpBB/includes/controller/helper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/includes/controller/helper.php b/phpBB/includes/controller/helper.php index 0e64829874..f2beca2056 100644 --- a/phpBB/includes/controller/helper.php +++ b/phpBB/includes/controller/helper.php @@ -90,7 +90,7 @@ class phpbb_controller_helper * @param string $route The route to travel * @return string The URL already passed through append_sid() */ - protected function url($route) + public function url($route) { return append_sid($this->phpbb_root_path . 'app.' . $this->php_ext, array('controller' => $route)); } From 48aefb13b0f66dd84f5e7a2f18ca485fabe4833b Mon Sep 17 00:00:00 2001 From: David King Date: Sat, 16 Feb 2013 19:18:16 -0500 Subject: [PATCH 017/281] [ticket/11334] Make $phpbb_dispatcher global, as done in append_sid test PHPBB3-11334 --- tests/controller/controller_test.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/controller/controller_test.php b/tests/controller/controller_test.php index 97f6d6152a..c4818dbd6a 100644 --- a/tests/controller/controller_test.php +++ b/tests/controller/controller_test.php @@ -42,6 +42,9 @@ class phpbb_controller_test extends phpbb_test_case public function test_controller_url_helper() { + global $phpbb_dispatcher; + + $phpbb_dispatcher = new phpbb_mock_event_dispatcher; $helper = new phpbb_controller_helper; $this->assertEquals($helper->url('foo/bar'),'./app.php?controller=foo/bar'); } From 5850a2cbf6e8313feeb55154e1083d73b45f4dc3 Mon Sep 17 00:00:00 2001 From: David King Date: Sat, 16 Feb 2013 19:21:34 -0500 Subject: [PATCH 018/281] [ticket/11334] Remove extraneous period PHPBB3-11334 --- phpBB/includes/controller/helper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/includes/controller/helper.php b/phpBB/includes/controller/helper.php index f2beca2056..451c448a18 100644 --- a/phpBB/includes/controller/helper.php +++ b/phpBB/includes/controller/helper.php @@ -92,7 +92,7 @@ class phpbb_controller_helper */ public function url($route) { - return append_sid($this->phpbb_root_path . 'app.' . $this->php_ext, array('controller' => $route)); + return append_sid($this->phpbb_root_path . 'app' . $this->php_ext, array('controller' => $route)); } /** From cd697e68129868dc811c141660652360e0f0f983 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 15 Mar 2013 13:35:00 +0100 Subject: [PATCH 019/281] [ticket/11334] Include functions.php and fix class name in tests PHPBB3-11334 --- tests/controller/controller_test.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/controller/controller_test.php b/tests/controller/controller_test.php index c4818dbd6a..8cdedb27e2 100644 --- a/tests/controller/controller_test.php +++ b/tests/controller/controller_test.php @@ -7,6 +7,8 @@ * */ +require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; + use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Routing\Route; use Symfony\Component\Routing\RouteCollection; @@ -14,7 +16,7 @@ use Symfony\Component\Config\FileLocator; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; -class phpbb_controller_test extends phpbb_test_case +class phpbb_controller_controller_test extends phpbb_test_case { public function setUp() { From ff9a0e4ef4756c5a9cce3f023b07d9f9a0e5653a Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 15 Mar 2013 13:35:43 +0100 Subject: [PATCH 020/281] [ticket/11334] Expand functionality of helper->url() Expanded the functionality of helper->url() to support all parameters of append_sid() itself. PHPBB3-11334 --- phpBB/includes/controller/helper.php | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/phpBB/includes/controller/helper.php b/phpBB/includes/controller/helper.php index 451c448a18..4c021849f4 100644 --- a/phpBB/includes/controller/helper.php +++ b/phpBB/includes/controller/helper.php @@ -87,12 +87,30 @@ class phpbb_controller_helper /** * Generate a URL * - * @param string $route The route to travel + * @param string $route The route to travel + * @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 * @return string The URL already passed through append_sid() */ - public function url($route) + public function url($route, $params = false, $is_amp = true, $session_id = false) { - return append_sid($this->phpbb_root_path . 'app' . $this->php_ext, array('controller' => $route)); + if (is_array($params) && !empty($params)) + { + $params = array_merge(array( + 'controller' => $route, + ), $params); + } + else if (is_string($params) && $params) + { + $params = 'controller=' . $route . (($is_amp) ? '&' : '&') . $params; + } + else + { + $params = array('controller' => $route); + } + + return append_sid($this->phpbb_root_path . 'app' . $this->php_ext, $params, $is_amp, $session_id); } /** From 9259e635cacce34699115b909f256f9302ec3aaa Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 15 Mar 2013 14:01:15 +0100 Subject: [PATCH 021/281] [ticket/11334] Move unit tests for helper->url() into own file PHPBB3-11334 --- tests/controller/controller_test.php | 11 ------ tests/controller/helper_url_test.php | 55 ++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 11 deletions(-) create mode 100644 tests/controller/helper_url_test.php diff --git a/tests/controller/controller_test.php b/tests/controller/controller_test.php index 8cdedb27e2..c06bf7d548 100644 --- a/tests/controller/controller_test.php +++ b/tests/controller/controller_test.php @@ -7,8 +7,6 @@ * */ -require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; - use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Routing\Route; use Symfony\Component\Routing\RouteCollection; @@ -42,15 +40,6 @@ class phpbb_controller_controller_test extends phpbb_test_case $this->assertEquals(2, sizeof($routes)); } - public function test_controller_url_helper() - { - global $phpbb_dispatcher; - - $phpbb_dispatcher = new phpbb_mock_event_dispatcher; - $helper = new phpbb_controller_helper; - $this->assertEquals($helper->url('foo/bar'),'./app.php?controller=foo/bar'); - } - public function test_controller_resolver() { $container = new ContainerBuilder(); diff --git a/tests/controller/helper_url_test.php b/tests/controller/helper_url_test.php new file mode 100644 index 0000000000..6e3f535cf3 --- /dev/null +++ b/tests/controller/helper_url_test.php @@ -0,0 +1,55 @@ + 1, 'f' => 2), true, false, 'app.php?controller=foo/bar&t=1&f=2', 'parameters in params-argument as array'), + + // Custom sid parameter + array('foo/bar', 't=1&f=2', true, 'custom-sid', 'app.php?controller=foo/bar&t=1&f=2&sid=custom-sid', 'using session_id'), + + // Testing anchors + // Unsupported: array('foo/bar?t=1&f=2#anchor', false, true, false, 'app.php?controller=foo/bar&t=1&f=2#anchor', 'anchor in url-argument'), + array('foo/bar', 't=1&f=2#anchor', true, false, 'app.php?controller=foo/bar&t=1&f=2#anchor', 'anchor in params-argument'), + array('foo/bar', array('t' => 1, 'f' => 2, '#' => 'anchor'), true, false, 'app.php?controller=foo/bar&t=1&f=2#anchor', 'anchor in params-argument (array)'), + + // Anchors and custom sid + // Unsupported: array('foo/bar?t=1&f=2#anchor', false, true, 'custom-sid', 'app.php?controller=foo/bar&t=1&f=2&sid=custom-sid#anchor', 'anchor in url-argument using session_id'), + array('foo/bar', 't=1&f=2#anchor', true, 'custom-sid', 'app.php?controller=foo/bar&t=1&f=2&sid=custom-sid#anchor', 'anchor in params-argument using session_id'), + array('foo/bar', array('t' => 1, 'f' => 2, '#' => 'anchor'), true, 'custom-sid', 'app.php?controller=foo/bar&t=1&f=2&sid=custom-sid#anchor', 'anchor in params-argument (array) using session_id'), + + // Empty parameters should not append the & + array('foo/bar', false, true, false, 'app.php?controller=foo/bar', 'no params using bool false'), + array('foo/bar', '', true, false, 'app.php?controller=foo/bar', 'no params using empty string'), + array('foo/bar', array(), true, false, 'app.php?controller=foo/bar', 'no params using empty array'), + ); + } + + /** + * @dataProvider helper_url_data + */ + public function test_helper_url($route, $params, $is_amp, $session_id, $expected, $description) + { + global $phpbb_dispatcher; + + $phpbb_dispatcher = new phpbb_mock_event_dispatcher; + $helper = new phpbb_controller_helper; + $this->assertEquals($helper->url($route, $params, $is_amp, $session_id), $expected); + } +} + From 076711d9a95e05083143b7ac4a589914a2e2b2ad Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 15 Mar 2013 14:02:46 +0100 Subject: [PATCH 022/281] [ticket/11334] Use mocks instead of making parameters optional PHPBB3-11334 --- phpBB/includes/controller/helper.php | 2 +- tests/controller/helper_url_test.php | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/phpBB/includes/controller/helper.php b/phpBB/includes/controller/helper.php index 4c021849f4..1464267711 100644 --- a/phpBB/includes/controller/helper.php +++ b/phpBB/includes/controller/helper.php @@ -55,7 +55,7 @@ class phpbb_controller_helper * @param string $phpbb_root_path phpBB root path * @param string $php_ext PHP extension */ - public function __construct(phpbb_template $template = null, phpbb_user $user = null, $phpbb_root_path = './', $php_ext = '.php') + public function __construct(phpbb_template $template, phpbb_user $user, $phpbb_root_path, $php_ext) { $this->template = $template; $this->user = $user; diff --git a/tests/controller/helper_url_test.php b/tests/controller/helper_url_test.php index 6e3f535cf3..7754278219 100644 --- a/tests/controller/helper_url_test.php +++ b/tests/controller/helper_url_test.php @@ -48,7 +48,11 @@ class phpbb_controller_helper_url_test extends phpbb_test_case global $phpbb_dispatcher; $phpbb_dispatcher = new phpbb_mock_event_dispatcher; - $helper = new phpbb_controller_helper; + $this->style_resource_locator = new phpbb_style_resource_locator(); + $this->user = $this->getMock('phpbb_user'); + $this->template = new phpbb_template($phpbb_root_path, $phpEx, $config, $this->user, $this->style_resource_locator, new phpbb_template_context()); + + $helper = new phpbb_controller_helper($this->template, $this->user, '', '.php'); $this->assertEquals($helper->url($route, $params, $is_amp, $session_id), $expected); } } From 9157095cdabe629765ab0583f2850c2d4771c1d1 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 15 Mar 2013 14:06:56 +0100 Subject: [PATCH 023/281] [ticket/11334] Fix copyright year in test file PHPBB3-11334 --- tests/controller/helper_url_test.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/controller/helper_url_test.php b/tests/controller/helper_url_test.php index 7754278219..f27c03501d 100644 --- a/tests/controller/helper_url_test.php +++ b/tests/controller/helper_url_test.php @@ -2,7 +2,7 @@ /** * * @package testing -* @copyright (c) 2011 phpBB Group +* @copyright (c) 2013 phpBB Group * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ From 3b0cdc53629c3a852762ae9b96b809cf4b1af2c4 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 15 Mar 2013 15:21:15 +0100 Subject: [PATCH 024/281] [ticket/11334] Allow parameters to be specified in the route PHPBB3-11334 --- phpBB/includes/controller/helper.php | 9 ++++++++- tests/controller/helper_url_test.php | 6 +++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/phpBB/includes/controller/helper.php b/phpBB/includes/controller/helper.php index 1464267711..46c6307cb4 100644 --- a/phpBB/includes/controller/helper.php +++ b/phpBB/includes/controller/helper.php @@ -95,6 +95,13 @@ class phpbb_controller_helper */ public function url($route, $params = false, $is_amp = true, $session_id = false) { + $route_params = ''; + if (($route_delim = strpos($route, '?')) !== false) + { + $route_params = substr($route, $route_delim); + $route = substr($route, 0, $route_delim); + } + if (is_array($params) && !empty($params)) { $params = array_merge(array( @@ -110,7 +117,7 @@ class phpbb_controller_helper $params = array('controller' => $route); } - return append_sid($this->phpbb_root_path . 'app' . $this->php_ext, $params, $is_amp, $session_id); + return append_sid($this->phpbb_root_path . 'app' . $this->php_ext . $route_params, $params, $is_amp, $session_id); } /** diff --git a/tests/controller/helper_url_test.php b/tests/controller/helper_url_test.php index f27c03501d..195f48d8a9 100644 --- a/tests/controller/helper_url_test.php +++ b/tests/controller/helper_url_test.php @@ -15,7 +15,7 @@ class phpbb_controller_helper_url_test extends phpbb_test_case public function helper_url_data() { return array( - // Unsupported: array('foo/bar?t=1&f=2', false, true, false, 'app.php?controller=foo/bar&t=1&f=2', 'parameters in url-argument'), + array('foo/bar?t=1&f=2', false, true, false, 'app.php?t=1&f=2&controller=foo/bar', 'parameters in url-argument'), array('foo/bar', 't=1&f=2', true, false, 'app.php?controller=foo/bar&t=1&f=2', 'parameters in params-argument using amp'), array('foo/bar', 't=1&f=2', false, false, 'app.php?controller=foo/bar&t=1&f=2', 'parameters in params-argument using &'), array('foo/bar', array('t' => 1, 'f' => 2), true, false, 'app.php?controller=foo/bar&t=1&f=2', 'parameters in params-argument as array'), @@ -24,12 +24,12 @@ class phpbb_controller_helper_url_test extends phpbb_test_case array('foo/bar', 't=1&f=2', true, 'custom-sid', 'app.php?controller=foo/bar&t=1&f=2&sid=custom-sid', 'using session_id'), // Testing anchors - // Unsupported: array('foo/bar?t=1&f=2#anchor', false, true, false, 'app.php?controller=foo/bar&t=1&f=2#anchor', 'anchor in url-argument'), + array('foo/bar?t=1&f=2#anchor', false, true, false, 'app.php?t=1&f=2&controller=foo/bar#anchor', 'anchor in url-argument'), array('foo/bar', 't=1&f=2#anchor', true, false, 'app.php?controller=foo/bar&t=1&f=2#anchor', 'anchor in params-argument'), array('foo/bar', array('t' => 1, 'f' => 2, '#' => 'anchor'), true, false, 'app.php?controller=foo/bar&t=1&f=2#anchor', 'anchor in params-argument (array)'), // Anchors and custom sid - // Unsupported: array('foo/bar?t=1&f=2#anchor', false, true, 'custom-sid', 'app.php?controller=foo/bar&t=1&f=2&sid=custom-sid#anchor', 'anchor in url-argument using session_id'), + array('foo/bar?t=1&f=2#anchor', false, true, 'custom-sid', 'app.php?t=1&f=2&controller=foo/bar&sid=custom-sid#anchor', 'anchor in url-argument using session_id'), array('foo/bar', 't=1&f=2#anchor', true, 'custom-sid', 'app.php?controller=foo/bar&t=1&f=2&sid=custom-sid#anchor', 'anchor in params-argument using session_id'), array('foo/bar', array('t' => 1, 'f' => 2, '#' => 'anchor'), true, 'custom-sid', 'app.php?controller=foo/bar&t=1&f=2&sid=custom-sid#anchor', 'anchor in params-argument (array) using session_id'), From 56914e72b7ec2e4063e0d510f2d61a56c37f80d0 Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Fri, 15 Mar 2013 09:51:34 -0700 Subject: [PATCH 025/281] [ticket/10155] Use new migration file for jQuery config update --- phpBB/includes/db/migration/data/310/dev.php | 2 +- .../includes/db/migration/data/310/dev_p2.php | 31 +++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 phpBB/includes/db/migration/data/310/dev_p2.php diff --git a/phpBB/includes/db/migration/data/310/dev.php b/phpBB/includes/db/migration/data/310/dev.php index 982dc9662e..13b36bbf30 100644 --- a/phpBB/includes/db/migration/data/310/dev.php +++ b/phpBB/includes/db/migration/data/310/dev.php @@ -91,7 +91,7 @@ class phpbb_db_migration_data_310_dev extends phpbb_db_migration array('config.add', array('fulltext_sphinx_indexer_mem_limit', 512)), array('config.add', array('load_jquery_cdn', 0)), - array('config.add', array('load_jquery_url', '//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js')), + array('config.add', array('load_jquery_url', '//ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js')), array('config.add', array('use_system_cron', 0)), diff --git a/phpBB/includes/db/migration/data/310/dev_p2.php b/phpBB/includes/db/migration/data/310/dev_p2.php new file mode 100644 index 0000000000..f5ec6eeb01 --- /dev/null +++ b/phpBB/includes/db/migration/data/310/dev_p2.php @@ -0,0 +1,31 @@ +config['load_jquery_url']); + } + + static public function depends_on() + { + return array( + 'phpbb_db_migration_data_310_dev', + ); + } + + public function update_data() + { + return array( + array('config.update', array('load_jquery_url', '//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js')), + ); + } + +} From 21a946255336bbd3b3572db5cc2ade2c48076a93 Mon Sep 17 00:00:00 2001 From: erangamapa Date: Sat, 16 Mar 2013 00:05:12 +0530 Subject: [PATCH 026/281] [ticket/11106] Added missing line breaks. Added two missing line breaks into 'edited by' message. PHPBB3-11106 --- phpBB/includes/ucp/ucp_pm_viewmessage.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/includes/ucp/ucp_pm_viewmessage.php b/phpBB/includes/ucp/ucp_pm_viewmessage.php index e2b61f1b02..e2dd1d5306 100644 --- a/phpBB/includes/ucp/ucp_pm_viewmessage.php +++ b/phpBB/includes/ucp/ucp_pm_viewmessage.php @@ -94,7 +94,7 @@ function view_message($id, $mode, $folder_id, $msg_id, $folder, $message_row) // Editing information if ($message_row['message_edit_count'] && $config['display_last_edited']) { - $l_edited_by = $user->lang('EDITED_TIMES_TOTAL', (int) $message_row['message_edit_count'], (!$message_row['message_edit_user']) ? $message_row['username'] : $message_row['message_edit_user'], $user->format_date($message_row['message_edit_time'], false, true)); + $l_edited_by = '

' . $user->lang('EDITED_TIMES_TOTAL', (int) $message_row['message_edit_count'], (!$message_row['message_edit_user']) ? $message_row['username'] : $message_row['message_edit_user'], $user->format_date($message_row['message_edit_time'], false, true)); } else { From c9e7247ab4234ad13d239e2b34c4ec4b305ef8ae Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Sat, 16 Mar 2013 21:49:00 +0100 Subject: [PATCH 027/281] [ticket/11445] Add abstract class phpbb_notification_method_messenger_base. PHPBB3-11445 --- phpBB/includes/notification/method/email.php | 78 +------------- phpBB/includes/notification/method/jabber.php | 18 +--- .../notification/method/messenger_base.php | 100 ++++++++++++++++++ 3 files changed, 103 insertions(+), 93 deletions(-) create mode 100644 phpBB/includes/notification/method/messenger_base.php diff --git a/phpBB/includes/notification/method/email.php b/phpBB/includes/notification/method/email.php index 4a7fea6df3..dc505c0d41 100644 --- a/phpBB/includes/notification/method/email.php +++ b/phpBB/includes/notification/method/email.php @@ -33,20 +33,6 @@ class phpbb_notification_method_email extends phpbb_notification_method_base return 'email'; } - /** - * Notify method (since jabber gets sent through the same messenger, we let the jabber class inherit from this to reduce code duplication) - * - * @var mixed - */ - protected $notify_method = NOTIFY_EMAIL; - - /** - * Base directory to prepend to the email template name - * - * @var string - */ - protected $email_template_base_dir = ''; - /** * Is this method available for the user? * This is checked on the notifications options @@ -61,68 +47,6 @@ class phpbb_notification_method_email extends phpbb_notification_method_base */ public function notify() { - if (!sizeof($this->queue)) - { - return; - } - - // Load all users we want to notify (we need their email address) - $user_ids = $users = array(); - foreach ($this->queue as $notification) - { - $user_ids[] = $notification->user_id; - } - - // We do not send emails to banned users - if (!function_exists('phpbb_get_banned_user_ids')) - { - include($this->phpbb_root_path . 'includes/functions_user.' . $this->php_ext); - } - $banned_users = phpbb_get_banned_user_ids($user_ids); - - // Load all the users we need - $this->user_loader->load_users($user_ids); - - // Load the messenger - if (!class_exists('messenger')) - { - include($this->phpbb_root_path . 'includes/functions_messenger.' . $this->php_ext); - } - $messenger = new messenger(); - $board_url = generate_board_url(); - - // Time to go through the queue and send emails - foreach ($this->queue as $notification) - { - if ($notification->get_email_template() === false) - { - continue; - } - - $user = $this->user_loader->get_user($notification->user_id); - - if ($user['user_type'] == USER_IGNORE || in_array($notification->user_id, $banned_users)) - { - continue; - } - - $messenger->template($this->email_template_base_dir . $notification->get_email_template(), $user['user_lang']); - - $messenger->to($user['user_email'], $user['username']); - - $messenger->assign_vars(array_merge(array( - 'USERNAME' => $user['username'], - - 'U_NOTIFICATION_SETTINGS' => generate_board_url() . '/ucp.' . $this->php_ext . '?i=ucp_notifications', - ), $notification->get_email_template_variables())); - - $messenger->send($this->notify_method); - } - - // Save the queue in the messenger class (has to be called or these emails could be lost?) - $messenger->save_queue(); - - // We're done, empty the queue - $this->empty_queue(); + return $this->notify_using_messenger(NOTIFY_EMAIL); } } diff --git a/phpBB/includes/notification/method/jabber.php b/phpBB/includes/notification/method/jabber.php index 863846b8a5..debffa8ce5 100644 --- a/phpBB/includes/notification/method/jabber.php +++ b/phpBB/includes/notification/method/jabber.php @@ -21,7 +21,7 @@ if (!defined('IN_PHPBB')) * * @package notifications */ -class phpbb_notification_method_jabber extends phpbb_notification_method_email +class phpbb_notification_method_jabber extends phpbb_notification_method_messenger_base { /** * Get notification method name @@ -33,20 +33,6 @@ class phpbb_notification_method_jabber extends phpbb_notification_method_email return 'jabber'; } - /** - * Notify method (since jabber gets sent through the same messenger, we let the jabber class inherit from this to reduce code duplication) - * - * @var mixed - */ - protected $notify_method = NOTIFY_IM; - - /** - * Base directory to prepend to the email template name - * - * @var string - */ - protected $email_template_base_dir = 'short/'; - /** * Is this method available for the user? * This is checked on the notifications options @@ -72,6 +58,6 @@ class phpbb_notification_method_jabber extends phpbb_notification_method_email return; } - return parent::notify(); + return $this->notify_using_messenger(NOTIFY_IM, 'short/'); } } diff --git a/phpBB/includes/notification/method/messenger_base.php b/phpBB/includes/notification/method/messenger_base.php new file mode 100644 index 0000000000..ce1ecc09ce --- /dev/null +++ b/phpBB/includes/notification/method/messenger_base.php @@ -0,0 +1,100 @@ +queue)) + { + return; + } + + // Load all users we want to notify (we need their email address) + $user_ids = $users = array(); + foreach ($this->queue as $notification) + { + $user_ids[] = $notification->user_id; + } + + // We do not send emails to banned users + if (!function_exists('phpbb_get_banned_user_ids')) + { + include($this->phpbb_root_path . 'includes/functions_user.' . $this->php_ext); + } + $banned_users = phpbb_get_banned_user_ids($user_ids); + + // Load all the users we need + $this->user_loader->load_users($user_ids); + + // Load the messenger + if (!class_exists('messenger')) + { + include($this->phpbb_root_path . 'includes/functions_messenger.' . $this->php_ext); + } + $messenger = new messenger(); + $board_url = generate_board_url(); + + // Time to go through the queue and send emails + foreach ($this->queue as $notification) + { + if ($notification->get_email_template() === false) + { + continue; + } + + $user = $this->user_loader->get_user($notification->user_id); + + if ($user['user_type'] == USER_IGNORE || in_array($notification->user_id, $banned_users)) + { + continue; + } + + $messenger->template($email_template_base_dir . $notification->get_email_template(), $user['user_lang']); + + $messenger->to($user['user_email'], $user['username']); + + $messenger->assign_vars(array_merge(array( + 'USERNAME' => $user['username'], + + 'U_NOTIFICATION_SETTINGS' => generate_board_url() . '/ucp.' . $this->php_ext . '?i=ucp_notifications', + ), $notification->get_email_template_variables())); + + $messenger->send($notify_method); + } + + // Save the queue in the messenger class (has to be called or these emails could be lost?) + $messenger->save_queue(); + + // We're done, empty the queue + $this->empty_queue(); + } +} From 58d7acbf5a4483f7e2ebac6d9ed38189c48facfb Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Sun, 17 Mar 2013 19:54:32 +0100 Subject: [PATCH 028/281] [ticket/11452] Now notification_method_email checks whether user has address. Make sure the user has an email address set before offering email notifications. The address could be missing for whatever reason, e.g. external authentication. This is also consistent with XMPP/Jabber now. PHPBB3-11452 --- phpBB/includes/notification/method/email.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/includes/notification/method/email.php b/phpBB/includes/notification/method/email.php index 4a7fea6df3..2cd1ba3ef6 100644 --- a/phpBB/includes/notification/method/email.php +++ b/phpBB/includes/notification/method/email.php @@ -53,7 +53,7 @@ class phpbb_notification_method_email extends phpbb_notification_method_base */ public function is_available() { - return (bool) $this->config['email_enable']; + return $this->config['email_enable'] && $this->user->data['user_email']; } /** From ac26be98c69094173c90acc49d208f751b93b7df Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Sun, 17 Mar 2013 17:01:38 -0700 Subject: [PATCH 029/281] [ticket/10155] Use more descriptive title for migration file PHPBB3-10155 --- .../db/migration/data/310/{dev_p2.php => jquery_update.php} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename phpBB/includes/db/migration/data/310/{dev_p2.php => jquery_update.php} (87%) diff --git a/phpBB/includes/db/migration/data/310/dev_p2.php b/phpBB/includes/db/migration/data/310/jquery_update.php similarity index 87% rename from phpBB/includes/db/migration/data/310/dev_p2.php rename to phpBB/includes/db/migration/data/310/jquery_update.php index f5ec6eeb01..ac6cf2666a 100644 --- a/phpBB/includes/db/migration/data/310/dev_p2.php +++ b/phpBB/includes/db/migration/data/310/jquery_update.php @@ -7,7 +7,7 @@ * */ -class phpbb_db_migration_data_310_dev_p2 extends phpbb_db_migration +class phpbb_db_migration_data_310_jquery_update extends phpbb_db_migration { public function effectively_installed() { From 1ac94699e456e8358ab88a0eec959f21333cb687 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Tue, 19 Mar 2013 19:25:34 +0100 Subject: [PATCH 030/281] [ticket/11460] Drop incorrect phpbb_notification_{type,method}_ prefix. PHPBB3-11460 --- phpBB/install/schemas/schema_data.sql | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/phpBB/install/schemas/schema_data.sql b/phpBB/install/schemas/schema_data.sql index f118d330ba..c25925a9c8 100644 --- a/phpBB/install/schemas/schema_data.sql +++ b/phpBB/install/schemas/schema_data.sql @@ -777,9 +777,9 @@ INSERT INTO phpbb_extensions (group_id, extension) VALUES (9, 'ogg'); INSERT INTO phpbb_extensions (group_id, extension) VALUES (9, 'ogm'); # User Notification Options (for first user) -INSERT INTO phpbb_user_notifications (item_type, item_id, user_id, method) VALUES('phpbb_notification_type_post', 0, 2, ''); -INSERT INTO phpbb_user_notifications (item_type, item_id, user_id, method) VALUES('phpbb_notification_type_post', 0, 2, 'phpbb_notification_method_email'); -INSERT INTO phpbb_user_notifications (item_type, item_id, user_id, method) VALUES('phpbb_notification_type_topic', 0, 2, ''); -INSERT INTO phpbb_user_notifications (item_type, item_id, user_id, method) VALUES('phpbb_notification_type_topic', 0, 2, 'phpbb_notification_method_email'); +INSERT INTO phpbb_user_notifications (item_type, item_id, user_id, method) VALUES('post', 0, 2, ''); +INSERT INTO phpbb_user_notifications (item_type, item_id, user_id, method) VALUES('post', 0, 2, 'email'); +INSERT INTO phpbb_user_notifications (item_type, item_id, user_id, method) VALUES('topic', 0, 2, ''); +INSERT INTO phpbb_user_notifications (item_type, item_id, user_id, method) VALUES('topic', 0, 2, 'email'); # POSTGRES COMMIT # From 433fbfd4d9e155046d9b8c14dc5f4c5c6a1f2130 Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Wed, 13 Mar 2013 15:04:06 -0700 Subject: [PATCH 031/281] [ticket/11461] Add template event in the footer of view topic pages PHPBB3-11461 --- phpBB/styles/prosilver/template/viewtopic_body.html | 1 + phpBB/styles/subsilver2/template/viewtopic_body.html | 1 + 2 files changed, 2 insertions(+) diff --git a/phpBB/styles/prosilver/template/viewtopic_body.html b/phpBB/styles/prosilver/template/viewtopic_body.html index c9a6882b6f..5ec8480deb 100644 --- a/phpBB/styles/prosilver/template/viewtopic_body.html +++ b/phpBB/styles/prosilver/template/viewtopic_body.html @@ -301,6 +301,7 @@
+ diff --git a/phpBB/styles/subsilver2/template/viewtopic_body.html b/phpBB/styles/subsilver2/template/viewtopic_body.html index 9e6377022a..b561b99abd 100644 --- a/phpBB/styles/subsilver2/template/viewtopic_body.html +++ b/phpBB/styles/subsilver2/template/viewtopic_body.html @@ -328,6 +328,7 @@ + From c9da6c5952e95791602d91465af238896abb1bb5 Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Thu, 14 Mar 2013 22:18:34 -0700 Subject: [PATCH 032/281] [ticket/11461] Add viewtopic_body_footer_before to the event docs PHPBB3-11461 --- phpBB/docs/events.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/phpBB/docs/events.md b/phpBB/docs/events.md index f0b3b81822..7666fcda48 100644 --- a/phpBB/docs/events.md +++ b/phpBB/docs/events.md @@ -124,6 +124,13 @@ viewtopic_print_head_append * Location: styles/prosilver/template/viewtopic_print.html * Purpose: Add asset calls directly before the `` tag of the Print Topic screen +viewtopic_body_footer_before +=== +* Locations: + + styles/prosilver/template/viewtopic_body.html + + styles/subsilver2/template/viewtopic_body.html +* Purpose: Add content to the bottom of the viewtopic page after all posts and pagination links + viewtopic_topic_title_prepend === * Locations: From 578ed03b7eb93fe00e67fc83db04b45fadc0fc74 Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Fri, 15 Mar 2013 00:41:21 -0700 Subject: [PATCH 033/281] [ticket/11461] Further clarify doc for viewtopic_body_footer_before PHPBB3-11461 --- phpBB/docs/events.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/docs/events.md b/phpBB/docs/events.md index 7666fcda48..041e2f2ad6 100644 --- a/phpBB/docs/events.md +++ b/phpBB/docs/events.md @@ -129,7 +129,7 @@ viewtopic_body_footer_before * Locations: + styles/prosilver/template/viewtopic_body.html + styles/subsilver2/template/viewtopic_body.html -* Purpose: Add content to the bottom of the viewtopic page after all posts and pagination links +* Purpose: Add content to the bottom of the View topic screen below the posts and quick reply, directly before the jumpbox in Prosilver, breadcrumbs in Subsilver2. viewtopic_topic_title_prepend === From 3089f5d0bbccd923b41264412682978a0c21e313 Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Fri, 15 Mar 2013 09:24:37 -0700 Subject: [PATCH 034/281] [ticket/11461] cut doc entry to 79 cols PHPBB3-11461 --- phpBB/docs/events.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/phpBB/docs/events.md b/phpBB/docs/events.md index 041e2f2ad6..3723bf7b3f 100644 --- a/phpBB/docs/events.md +++ b/phpBB/docs/events.md @@ -129,7 +129,9 @@ viewtopic_body_footer_before * Locations: + styles/prosilver/template/viewtopic_body.html + styles/subsilver2/template/viewtopic_body.html -* Purpose: Add content to the bottom of the View topic screen below the posts and quick reply, directly before the jumpbox in Prosilver, breadcrumbs in Subsilver2. +* Purpose: Add content to the bottom of the View topic screen below the posts +and quick reply, directly before the jumpbox in Prosilver, breadcrumbs in +Subsilver2. viewtopic_topic_title_prepend === From 940d16b585ac83ace7ee76b0fd7d033bcedda318 Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Wed, 20 Mar 2013 11:39:06 -0700 Subject: [PATCH 035/281] [ticket/11463] Add title attribute to topics in search results We use this title attribute in viewforum_body.html, but not in search_results.html. Perhaps we should, as this will maintain consitency between all these topic view pages. PHPBB3-11463 --- phpBB/styles/prosilver/template/search_results.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/styles/prosilver/template/search_results.html b/phpBB/styles/prosilver/template/search_results.html index 62b7c61eb3..6e63a65993 100644 --- a/phpBB/styles/prosilver/template/search_results.html +++ b/phpBB/styles/prosilver/template/search_results.html @@ -60,7 +60,7 @@
  • -
    style="background-image: url({T_ICONS_PATH}{searchresults.TOPIC_ICON_IMG}); background-repeat: no-repeat;"> +
    style="background-image: url({T_ICONS_PATH}{searchresults.TOPIC_ICON_IMG}); background-repeat: no-repeat;" title="{searchresults.TOPIC_FOLDER_IMG_ALT}"> {NEWEST_POST_IMG} {searchresults.TOPIC_TITLE} {searchresults.ATTACH_ICON_IMG} {searchresults.UNAPPROVED_IMG} From 15aec0bbb24be10da850f78d85a3d10880c6f28a Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Thu, 21 Mar 2013 03:07:50 +0100 Subject: [PATCH 036/281] [ticket/11460] Add methods for checkbox handling to phpbb_functional_test_case. PHPBB3-11460 --- .../phpbb_functional_test_case.php | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/tests/test_framework/phpbb_functional_test_case.php b/tests/test_framework/phpbb_functional_test_case.php index 887dfea3b5..a62f5341ca 100644 --- a/tests/test_framework/phpbb_functional_test_case.php +++ b/tests/test_framework/phpbb_functional_test_case.php @@ -463,4 +463,68 @@ class phpbb_functional_test_case extends phpbb_test_case $this->assertGreaterThan(0, count($nodes), $msg); return $nodes; } + + /** + * Asserts that exactly one checkbox with name $name exists within the scope + * of $crawler and that the checkbox is checked. + * + * @param Symfony\Component\DomCrawler\Crawler $crawler + * @param string $name + * @param string $message + * + * @return null + */ + public function assert_checkbox_is_checked($crawler, $name, $message = '') + { + $this->assertSame( + 'checked', + $this->assert_find_one_checkbox($crawler, $name)->attr('checked'), + $message ?: "Failed asserting that checkbox $name is checked." + ); + } + + /** + * Asserts that exactly one checkbox with name $name exists within the scope + * of $crawler and that the checkbox is unchecked. + * + * @param Symfony\Component\DomCrawler\Crawler $crawler + * @param string $name + * @param string $message + * + * @return null + */ + public function assert_checkbox_is_unchecked($crawler, $name, $message = '') + { + $this->assertSame( + '', + $this->assert_find_one_checkbox($crawler, $name)->attr('checked'), + $message ?: "Failed asserting that checkbox $name is unchecked." + ); + } + + /** + * Searches for an input element of type checkbox with the name $name using + * $crawler. Contains an assertion that only one such checkbox exists within + * the scope of $crawler. + * + * @param Symfony\Component\DomCrawler\Crawler $crawler + * @param string $name + * @param string $message + * + * @return Symfony\Component\DomCrawler\Crawler + */ + public function assert_find_one_checkbox($crawler, $name, $message = '') + { + $query = sprintf('//input[@type="checkbox" and @name="%s"]', $name); + $result = $crawler->filterXPath($query); + + $this->assertEquals( + 1, + sizeof($result), + $message ?: 'Failed asserting that exactly one checkbox with name' . + " $name exists in crawler scope." + ); + + return $result; + } } From 16a60253721330323ae201032f0b852697ce2a00 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Thu, 21 Mar 2013 23:04:17 +0100 Subject: [PATCH 037/281] [ticket/11469] Add SQL insert buffer allowing easier handling of multi inserts. 1. Tries to prevent going over max packet size by flushing to the database after a certain number of rows have been added. 2. Because of 1., it is less likely to reach a connection timeout when inserting a huge number of rows. 3. By flushing the buffer when a certain size is reached, memory usage should be lower compared to building the whole insert row set first. PHPBB3-11469 --- phpBB/includes/db/sql_insert_buffer.php | 111 ++++++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 phpBB/includes/db/sql_insert_buffer.php diff --git a/phpBB/includes/db/sql_insert_buffer.php b/phpBB/includes/db/sql_insert_buffer.php new file mode 100644 index 0000000000..8d4b03ef53 --- /dev/null +++ b/phpBB/includes/db/sql_insert_buffer.php @@ -0,0 +1,111 @@ +db = $db; + $this->db_supports_multi_insert = $db->multi_insert; + $this->table_name = $table_name; + $this->max_buffered_rows = $max_buffered_rows; + } + + /** + * Inserts a single row into the buffer if multi insert is supported by the + * database (otherwise an insert query is sent immediately). Then flushes + * the buffer if the number of rows in the buffer is now greater than or + * equal to $max_buffered_rows. + * + * @param array $row + * + * @return null + */ + public function insert(array $row) + { + if (!$this->db_supports_multi_insert) + { + $this->db->sql_multi_insert($this->table_name, array($row)); + } + + $this->buffer[] = $row; + + if (sizeof($this->buffer) >= $this->max_buffered_rows) + { + $this->flush(); + } + } + + /** + * Inserts a row set, i.e. an array of rows, by calling insert(). + * + * Please note that it is in most cases better to use insert() instead of + * first building a huge rowset. Or at least sizeof($rows) should be kept + * small. + * + * @param array $rows + * + * @return null + */ + public function insert_all(array $rows) + { + foreach ($rows as $row) + { + $this->insert($row); + } + } + + /** + * Flushes the buffer content to the DB and clears the buffer. + * + * @return null + */ + public function flush() + { + if (!empty($this->buffer)) + { + $this->db->sql_multi_insert($this->table_name, $this->buffer); + $this->buffer = array(); + } + } +} From 73d6855edf2f7a72a2f4836e7cce8f94e34f5502 Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Fri, 22 Mar 2013 11:22:25 -0700 Subject: [PATCH 038/281] [ticket/10155] Make effectively installed test more specific PHPBB3-10155 --- phpBB/includes/db/migration/data/310/jquery_update.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/includes/db/migration/data/310/jquery_update.php b/phpBB/includes/db/migration/data/310/jquery_update.php index ac6cf2666a..bb0c48550a 100644 --- a/phpBB/includes/db/migration/data/310/jquery_update.php +++ b/phpBB/includes/db/migration/data/310/jquery_update.php @@ -11,7 +11,7 @@ class phpbb_db_migration_data_310_jquery_update extends phpbb_db_migration { public function effectively_installed() { - return !isset($this->config['load_jquery_url']); + return $this->config['load_jquery_url'] !== '//ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js'; } static public function depends_on() From 69df6b49db73d1a475d0b410f38fb4efb56d7451 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Thu, 21 Mar 2013 03:08:15 +0100 Subject: [PATCH 039/281] [ticket/11460] Add test for whether post_email and topic_email are checked. PHPBB3-11460 --- tests/functional/notification_test.php | 46 ++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 tests/functional/notification_test.php diff --git a/tests/functional/notification_test.php b/tests/functional/notification_test.php new file mode 100644 index 0000000000..519fb8152b --- /dev/null +++ b/tests/functional/notification_test.php @@ -0,0 +1,46 @@ +login(); + $crawler = $this->request('GET', 'ucp.php?i=ucp_notifications&mode=notification_options'); + $this->assert_response_success(); + + $cplist = $crawler->filter('.cplist'); + if ($expected_status) + { + $this->assert_checkbox_is_checked($cplist, $checkbox_name); + } + else + { + $this->assert_checkbox_is_unchecked($cplist, $checkbox_name); + } + } +} From 02817158fc4209b57893eaba107f732274835fa7 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Fri, 22 Mar 2013 22:42:05 +0100 Subject: [PATCH 040/281] [ticket/11460] Configure functional test board email using dummy SMTP data. PHPBB3-11460 --- tests/test_framework/phpbb_functional_test_case.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/test_framework/phpbb_functional_test_case.php b/tests/test_framework/phpbb_functional_test_case.php index a62f5341ca..a411d9c98a 100644 --- a/tests/test_framework/phpbb_functional_test_case.php +++ b/tests/test_framework/phpbb_functional_test_case.php @@ -196,12 +196,12 @@ class phpbb_functional_test_case extends phpbb_test_case $parseURL = parse_url(self::$config['phpbb_functional_url']); $data = array_merge($data, array( - 'email_enable' => false, - 'smtp_delivery' => false, - 'smtp_host' => '', - 'smtp_auth' => '', - 'smtp_user' => '', - 'smtp_pass' => '', + 'email_enable' => true, + 'smtp_delivery' => true, + 'smtp_host' => 'nxdomain.phpbb.com', + 'smtp_auth' => '', + 'smtp_user' => 'nxuser', + 'smtp_pass' => 'nxpass', 'cookie_secure' => false, 'force_server_vars' => false, 'server_protocol' => $parseURL['scheme'] . '://', From bc5f8e30d09be1ded463b7d7a0e0d9b001de6b3b Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Sat, 23 Mar 2013 13:20:32 +0100 Subject: [PATCH 041/281] [ticket/11405] Add some basic tests for notifications in submit_post() Poster, should NOT receive a notification Topic subscribed, should receive a notification Topic subscribed, but unauthed to read, should NOT receive a notification Topic subscribed, but already notified, should NOT receive a new notification Topic and forum subscribed, should receive ONE notification Forum subscribed, should receive a notification Forum subscribed, but already notified, should NOT receive a new notification PHPBB3-11405 --- .../fixtures/submit_post_notification.xml | 132 ++++++++++++ .../submit_post_notifications_test.php | 195 ++++++++++++++++++ 2 files changed, 327 insertions(+) create mode 100644 tests/notification/fixtures/submit_post_notification.xml create mode 100644 tests/notification/submit_post_notifications_test.php diff --git a/tests/notification/fixtures/submit_post_notification.xml b/tests/notification/fixtures/submit_post_notification.xml new file mode 100644 index 0000000000..c082402056 --- /dev/null +++ b/tests/notification/fixtures/submit_post_notification.xml @@ -0,0 +1,132 @@ + + +
  • + forum_id + user_id + notify_status + + 1 + 6 + 0 + + + 1 + 7 + 0 + + + 1 + 8 + 0 + +
    + + item_type + user_id + item_id + item_parent_id + notification_data + + post + 5 + 1 + 1 + + + + post + 8 + 1 + 1 + + +
    + +
    + + topic_id + user_id + notify_status + + 1 + 2 + 0 + + + 1 + 3 + 0 + + + 1 + 4 + 0 + + + 1 + 5 + 0 + + + 1 + 6 + 0 + +
    + + item_type + item_id + user_id + method + notify + + post + 0 + 2 + + 1 + + + post + 0 + 3 + + 1 + + + post + 0 + 4 + + 1 + + + post + 0 + 5 + + 1 + + + post + 0 + 6 + + 1 + + + post + 0 + 7 + + 1 + + + post + 0 + 8 + + 1 + +
    + diff --git a/tests/notification/submit_post_notifications_test.php b/tests/notification/submit_post_notifications_test.php new file mode 100644 index 0000000000..e08d7a439a --- /dev/null +++ b/tests/notification/submit_post_notifications_test.php @@ -0,0 +1,195 @@ +createXMLDataSet(dirname(__FILE__) . '/fixtures/submit_post_notification.xml'); + } + + public function setUp() + { + parent::setUp(); + + global $auth, $cache, $config, $db, $phpbb_container, $phpbb_dispatcher, $user, $request, $phpEx, $phpbb_root_path; + + // Database + $this->db = $this->new_dbal(); + $db = $this->db; + + // Cache + $cache = new phpbb_mock_cache(); + + // Auth + $auth = $this->getMock('phpbb_auth'); + $auth->expects($this->any()) + ->method('acl_get') + ->with($this->stringContains('_'), + $this->anything()) + ->will($this->returnValueMap(array( + array('f_noapprove', 1, true), + array('f_postcount', 1, true), + array('m_edit', 1, false), + ))); + + $auth->expects($this->any()) + ->method('acl_get_list') + ->with($this->anything(), + $this->stringContains('_'), + $this->greaterThan(0)) + ->will($this->returnValueMap(array( + array( + array( + 0 => '3', + 1 => '4', + 2 => '5', + 3 => '6', + 5 => '7', + 6 => '8', + ), + 'f_read', + 1, + array( + 1 => array( + 'f_read' => array(3, 5, 6, 7, 8,), + ), + ), + ), + array( + array( + 0 => '3', + 1 => '4', + 2 => '5', + 3 => '6', + ), + 'f_read', + 1, + array( + 1 => array( + 'f_read' => array(3, 5, 6,), + ), + ), + ), + ))); + + // Config + $config = new phpbb_config(array('num_topics' => 1,'num_posts' => 1,)); + set_config(null, null, null, $config); + set_config_count(null, null, null, $config); + + // Event dispatcher + $phpbb_dispatcher = new phpbb_mock_event_dispatcher(); + + // User + $user = $this->getMock('phpbb_user'); + $user->ip = ''; + $user->data = array( + 'user_id' => 2, + 'username' => 'user-name', + 'is_registered' => true, + 'user_colour' => '', + ); + + // Request + $type_cast_helper = $this->getMock('phpbb_request_type_cast_helper_interface'); + $request = $this->getMock('phpbb_request'); + + // Container + $phpbb_container = new phpbb_mock_container_builder(); + + $user_loader = new phpbb_user_loader($db, $phpbb_root_path, '.' . $phpEx, USERS_TABLE); + + // Notification Manager + $phpbb_notifications = new phpbb_notification_manager(array(), array(), + $phpbb_container, $user_loader, $db, $user, + $phpbb_root_path, '.' . $phpEx, + NOTIFICATION_TYPES_TABLE, NOTIFICATIONS_TABLE, USER_NOTIFICATIONS_TABLE); + $phpbb_container->set('notification_manager', $phpbb_notifications); + + // Notification Types + $notification_types = array('quote', 'bookmark', 'post'); + foreach ($notification_types as $type) + { + $class_name = 'phpbb_notification_type_' . $type; + $phpbb_container->set('notification.type.' . $type, new $class_name( + $user_loader, $db, $cache, $user, $auth, $config, + $phpbb_root_path, '.' . $phpEx, + NOTIFICATION_TYPES_TABLE, NOTIFICATIONS_TABLE, USER_NOTIFICATIONS_TABLE)); + } + } + + /** + * submit_post() Notifications test + * + * User => State description + * 2 => Poster, should NOT receive a notification + * 3 => Topic subscribed, should receive a notification + * 4 => Topic subscribed, but unauthed to read, should NOT receive a notification + * 5 => Topic subscribed, but already notified, should NOT receive a new notification + * 6 => Topic and forum subscribed, should receive ONE notification + * 7 => Forum subscribed, should receive a notification + * 8 => Forum subscribed, but already notified, should NOT receive a new notification + */ + public function test_type_post() + { + $sql = 'SELECT user_id, item_id, item_parent_id + FROM ' . NOTIFICATIONS_TABLE . " + WHERE item_type = 'post' + ORDER BY user_id, item_id ASC"; + $result = $this->db->sql_query($sql); + $this->assertEquals(array( + array('user_id' => 5, 'item_id' => 1, 'item_parent_id' => 1), + array('user_id' => 8, 'item_id' => 1, 'item_parent_id' => 1), + ), $this->db->sql_fetchrowset($result)); + $this->db->sql_freeresult($result); + + $poll = array(); + $data = array( + 'forum_id' => 1, + 'topic_id' => 1, + 'topic_title' => 'topic_title', + 'icon_id' => 0, + 'enable_bbcode' => 0, + 'enable_smilies' => 0, + 'enable_urls' => 0, + 'enable_sig' => 0, + 'message' => '', + 'message_md5' => '', + 'attachment_data' => array(), + 'bbcode_bitfield' => '', + 'bbcode_uid' => '', + 'post_edit_locked' => false, + //'force_approved_state' => 1, + ); + + submit_post('reply', '', 'poster-name', POST_NORMAL, $poll, $data, false, false); + + $sql = 'SELECT user_id, item_id, item_parent_id + FROM ' . NOTIFICATIONS_TABLE . " + WHERE item_type = 'post' + ORDER BY user_id ASC, item_id ASC"; + $result = $this->db->sql_query($sql); + $this->assertEquals(array( + array('user_id' => 3, 'item_id' => 1, 'item_parent_id' => 1,), + array('user_id' => 5, 'item_id' => 1, 'item_parent_id' => 1,), + array('user_id' => 6, 'item_id' => 1, 'item_parent_id' => 1,), + array('user_id' => 7, 'item_id' => 1, 'item_parent_id' => 1,), + array('user_id' => 8, 'item_id' => 1, 'item_parent_id' => 1,), + ), $this->db->sql_fetchrowset($result)); + $this->db->sql_freeresult($result); + } +} From d3decaeedff926f2945285b713e85c09c3de9daf Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Sun, 24 Mar 2013 23:42:13 +0100 Subject: [PATCH 042/281] [ticket/11460] Add default behaviour tests for notification and email types. PHPBB3-11460 --- tests/functional/notification_test.php | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/tests/functional/notification_test.php b/tests/functional/notification_test.php index 519fb8152b..ec495da602 100644 --- a/tests/functional/notification_test.php +++ b/tests/functional/notification_test.php @@ -15,12 +15,22 @@ class phpbb_functional_notification_test extends phpbb_functional_test_case static public function user_subscription_data() { return array( + // Rows inserted by phpBB/install/schemas/schema_data.sql + // Also see PHPBB3-11460 array('post_notification', true), array('topic_notification', true), - - // PHPBB3-11460 array('post_email', true), array('topic_email', true), + + // Default behaviour for in-board notifications: + // If user did not opt-out, in-board notifications are on. + array('bookmark_notification', true), + array('quote_notification', true), + + // Default behaviour for email notifications: + // If user did not opt-in, email notifications are off. + array('bookmark_email', false), + array('quote_email', false), ); } From a91ffe06c79dd067162fe3d659be44382a20df0e Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Sat, 23 Mar 2013 13:25:01 +0100 Subject: [PATCH 043/281] [ticket/11405] Send post notifications to forum subscribers Like in 3.0 we should also send notifications about new posts to users that subscribed to the forum. (Subscriptions are verbose) PHPBB3-11405 --- phpBB/includes/notification/type/post.php | 15 ++++++++++++ .../submit_post_notifications_test.php | 24 +------------------ 2 files changed, 16 insertions(+), 23 deletions(-) diff --git a/phpBB/includes/notification/type/post.php b/phpBB/includes/notification/type/post.php index d8ffdea81d..626c13b7fd 100644 --- a/phpBB/includes/notification/type/post.php +++ b/phpBB/includes/notification/type/post.php @@ -106,11 +106,26 @@ class phpbb_notification_type_post extends phpbb_notification_type_base } $this->db->sql_freeresult($result); + $sql = 'SELECT user_id + FROM ' . FORUMS_WATCH_TABLE . ' + WHERE forum_id = ' . (int) $post['forum_id'] . ' + AND notify_status = ' . NOTIFY_YES . ' + AND user_id <> ' . (int) $post['poster_id']; + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + $users[] = $row['user_id']; + } + $this->db->sql_freeresult($result); + if (empty($users)) { return array(); } + $users = array_unique($users); + sort($users); + $auth_read = $this->auth->acl_get_list($users, 'f_read', $post['forum_id']); if (empty($auth_read)) diff --git a/tests/notification/submit_post_notifications_test.php b/tests/notification/submit_post_notifications_test.php index e08d7a439a..3dfb948ca9 100644 --- a/tests/notification/submit_post_notifications_test.php +++ b/tests/notification/submit_post_notifications_test.php @@ -53,14 +53,7 @@ class phpbb_notification_submit_post_notifications_test extends phpbb_database_t $this->greaterThan(0)) ->will($this->returnValueMap(array( array( - array( - 0 => '3', - 1 => '4', - 2 => '5', - 3 => '6', - 5 => '7', - 6 => '8', - ), + array('3', '4', '5', '6', '7', '8',), 'f_read', 1, array( @@ -69,21 +62,6 @@ class phpbb_notification_submit_post_notifications_test extends phpbb_database_t ), ), ), - array( - array( - 0 => '3', - 1 => '4', - 2 => '5', - 3 => '6', - ), - 'f_read', - 1, - array( - 1 => array( - 'f_read' => array(3, 5, 6,), - ), - ), - ), ))); // Config From 7d5949ae3d2faba5dc76c3d355e73b5abaa8e6c1 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Mon, 25 Mar 2013 14:37:22 +0100 Subject: [PATCH 044/281] [ticket/11405] Fix some coding style issues PHPBB3-11405 --- .../submit_post_notifications_test.php | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/tests/notification/submit_post_notifications_test.php b/tests/notification/submit_post_notifications_test.php index 3dfb948ca9..6b61624481 100644 --- a/tests/notification/submit_post_notifications_test.php +++ b/tests/notification/submit_post_notifications_test.php @@ -53,12 +53,12 @@ class phpbb_notification_submit_post_notifications_test extends phpbb_database_t $this->greaterThan(0)) ->will($this->returnValueMap(array( array( - array('3', '4', '5', '6', '7', '8',), + array('3', '4', '5', '6', '7', '8'), 'f_read', 1, array( 1 => array( - 'f_read' => array(3, 5, 6, 7, 8,), + 'f_read' => array(3, 5, 6, 7, 8), ), ), ), @@ -113,6 +113,9 @@ class phpbb_notification_submit_post_notifications_test extends phpbb_database_t /** * submit_post() Notifications test * + * submit_post() $mode = 'reply' + * Notification item_type = 'post' + * * User => State description * 2 => Poster, should NOT receive a notification * 3 => Topic subscribed, should receive a notification @@ -162,11 +165,11 @@ class phpbb_notification_submit_post_notifications_test extends phpbb_database_t ORDER BY user_id ASC, item_id ASC"; $result = $this->db->sql_query($sql); $this->assertEquals(array( - array('user_id' => 3, 'item_id' => 1, 'item_parent_id' => 1,), - array('user_id' => 5, 'item_id' => 1, 'item_parent_id' => 1,), - array('user_id' => 6, 'item_id' => 1, 'item_parent_id' => 1,), - array('user_id' => 7, 'item_id' => 1, 'item_parent_id' => 1,), - array('user_id' => 8, 'item_id' => 1, 'item_parent_id' => 1,), + array('user_id' => 3, 'item_id' => 1, 'item_parent_id' => 1), + array('user_id' => 5, 'item_id' => 1, 'item_parent_id' => 1), + array('user_id' => 6, 'item_id' => 1, 'item_parent_id' => 1), + array('user_id' => 7, 'item_id' => 1, 'item_parent_id' => 1), + array('user_id' => 8, 'item_id' => 1, 'item_parent_id' => 1), ), $this->db->sql_fetchrowset($result)); $this->db->sql_freeresult($result); } From 499eded88004f0bbae554090939b38e6158c8271 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Mon, 25 Mar 2013 14:40:53 +0100 Subject: [PATCH 045/281] [ticket/11405] Add unit tests for quoted users notifications PHPBB3-11405 --- .../fixtures/submit_post_notification.xml | 98 ++++++++++ ...est.php => submit_post_type_post_test.php} | 2 +- .../submit_post_type_quote_test.php | 180 ++++++++++++++++++ 3 files changed, 279 insertions(+), 1 deletion(-) rename tests/notification/{submit_post_notifications_test.php => submit_post_type_post_test.php} (98%) create mode 100644 tests/notification/submit_post_type_quote_test.php diff --git a/tests/notification/fixtures/submit_post_notification.xml b/tests/notification/fixtures/submit_post_notification.xml index c082402056..5c59edf073 100644 --- a/tests/notification/fixtures/submit_post_notification.xml +++ b/tests/notification/fixtures/submit_post_notification.xml @@ -33,6 +33,13 @@ 1 + + quote + 5 + 1 + 1 + + post 8 @@ -73,6 +80,62 @@ 0 + + user_id + username_clean + user_permissions + user_sig + user_occ + user_interests + + 2 + poster + + + + + + + 3 + test + + + + + + + 4 + unauthorized + + + + + + + 5 + notified + + + + + + + 6 + disabled + + + + + + + 7 + default + + + + + +
    item_typeitem_id @@ -86,6 +149,13 @@ 1 + + quote + 0 + 2 + + 1 + post 0 @@ -93,6 +163,13 @@ 1 + + quote + 0 + 3 + + 1 + post 0 @@ -100,6 +177,13 @@ 1 + + quote + 0 + 4 + + 1 + post 0 @@ -107,6 +191,13 @@ 1 + + quote + 0 + 5 + + 1 + post 0 @@ -114,6 +205,13 @@ 1 + + quote + 0 + 6 + + 0 + post 0 diff --git a/tests/notification/submit_post_notifications_test.php b/tests/notification/submit_post_type_post_test.php similarity index 98% rename from tests/notification/submit_post_notifications_test.php rename to tests/notification/submit_post_type_post_test.php index 6b61624481..b1e4b86b15 100644 --- a/tests/notification/submit_post_notifications_test.php +++ b/tests/notification/submit_post_type_post_test.php @@ -12,7 +12,7 @@ require_once dirname(__FILE__) . '/../../phpBB/includes/functions_content.php'; require_once dirname(__FILE__) . '/../../phpBB/includes/functions_posting.php'; require_once dirname(__FILE__) . '/../../phpBB/includes/utf/utf_tools.php'; -class phpbb_notification_submit_post_notifications_test extends phpbb_database_test_case +class phpbb_notification_submit_post_type_post_test extends phpbb_database_test_case { protected $notifications, $db, $container, $user, $config, $auth, $cache; diff --git a/tests/notification/submit_post_type_quote_test.php b/tests/notification/submit_post_type_quote_test.php new file mode 100644 index 0000000000..82f4eaf189 --- /dev/null +++ b/tests/notification/submit_post_type_quote_test.php @@ -0,0 +1,180 @@ +createXMLDataSet(dirname(__FILE__) . '/fixtures/submit_post_notification.xml'); + } + + public function setUp() + { + parent::setUp(); + + global $auth, $cache, $config, $db, $phpbb_container, $phpbb_dispatcher, $user, $request, $phpEx, $phpbb_root_path; + + // Database + $this->db = $this->new_dbal(); + $db = $this->db; + + // Cache + $cache = new phpbb_mock_cache(); + + // Auth + $auth = $this->getMock('phpbb_auth'); + $auth->expects($this->any()) + ->method('acl_get') + ->with($this->stringContains('_'), + $this->anything()) + ->will($this->returnValueMap(array( + array('f_noapprove', 1, true), + array('f_postcount', 1, true), + array('m_edit', 1, false), + ))); + + $auth->expects($this->any()) + ->method('acl_get_list') + ->with($this->anything(), + $this->stringContains('_'), + $this->greaterThan(0)) + ->will($this->returnValueMap(array( + array( + array('3', '4', '5', '6', '7'), + 'f_read', + 1, + array( + 1 => array( + 'f_read' => array(3, 5, 6, 7), + ), + ), + ), + ))); + + // Config + $config = new phpbb_config(array('num_topics' => 1,'num_posts' => 1,)); + set_config(null, null, null, $config); + set_config_count(null, null, null, $config); + + // Event dispatcher + $phpbb_dispatcher = new phpbb_mock_event_dispatcher(); + + // User + $user = $this->getMock('phpbb_user'); + $user->ip = ''; + $user->data = array( + 'user_id' => 2, + 'username' => 'user-name', + 'is_registered' => true, + 'user_colour' => '', + ); + + // Request + $type_cast_helper = $this->getMock('phpbb_request_type_cast_helper_interface'); + $request = $this->getMock('phpbb_request'); + + // Container + $phpbb_container = new phpbb_mock_container_builder(); + + $user_loader = new phpbb_user_loader($db, $phpbb_root_path, '.' . $phpEx, USERS_TABLE); + + // Notification Manager + $phpbb_notifications = new phpbb_notification_manager(array(), array(), + $phpbb_container, $user_loader, $db, $user, + $phpbb_root_path, '.' . $phpEx, + NOTIFICATION_TYPES_TABLE, NOTIFICATIONS_TABLE, USER_NOTIFICATIONS_TABLE); + $phpbb_container->set('notification_manager', $phpbb_notifications); + + // Notification Types + $notification_types = array('quote', 'bookmark', 'post'); + foreach ($notification_types as $type) + { + $class_name = 'phpbb_notification_type_' . $type; + $phpbb_container->set('notification.type.' . $type, new $class_name( + $user_loader, $db, $cache, $user, $auth, $config, + $phpbb_root_path, '.' . $phpEx, + NOTIFICATION_TYPES_TABLE, NOTIFICATIONS_TABLE, USER_NOTIFICATIONS_TABLE)); + } + } + + /** + * submit_post() Notifications test + * + * submit_post() $mode = 'reply' + * Notification item_type = 'quote' + * + * User => State description + * 2 => Poster, should NOT receive a notification + * 3 => Quoted, should receive a notification + * 4 => Quoted, but unauthed to read, should NOT receive a notification + * 5 => Quoted, but already notified, should NOT receive a new notification + * 6 => Quoted, but option disabled, should NOT receive a notification + * 7 => Quoted, option set to default, should receive a notification + */ + public function test_type_quote() + { + $sql = 'SELECT user_id, item_id, item_parent_id + FROM ' . NOTIFICATIONS_TABLE . " + WHERE item_type = 'quote' + ORDER BY user_id, item_id ASC"; + $result = $this->db->sql_query($sql); + $this->assertEquals(array( + array('user_id' => 5, 'item_id' => 1, 'item_parent_id' => 1), + ), $this->db->sql_fetchrowset($result)); + $this->db->sql_freeresult($result); + + $poll = array(); + $data = array( + 'forum_id' => 1, + 'topic_id' => 1, + 'topic_title' => 'topic_title', + 'icon_id' => 0, + 'enable_bbcode' => 0, + 'enable_smilies' => 0, + 'enable_urls' => 0, + 'enable_sig' => 0, + 'message' => implode(' ', array( + '[quote="poster":uid]poster should not be notified[/quote:uid]', + '[quote="test":uid]test should be notified[/quote:uid]', + '[quote="unauthorized":uid]unauthorized to read, should not receive a notification[/quote:uid]', + '[quote="notified":uid]already notified, should not receive a new notification[/quote:uid]', + '[quote="disabled":uid]option disabled, should not receive a notification[/quote:uid]', + '[quote="default":uid]option set to default, should receive a notification[/quote:uid]', + '[quote="doesn\'t exist":uid]user does not exist, should not receive a notification[/quote:uid]', + )), + 'message_md5' => '', + 'attachment_data' => array(), + 'bbcode_bitfield' => '', + 'bbcode_uid' => 'uid', + 'post_edit_locked' => false, + //'force_approved_state' => 1, + ); + + submit_post('reply', '', 'poster-name', POST_NORMAL, $poll, $data, false, false); + + $sql = 'SELECT user_id, item_id, item_parent_id + FROM ' . NOTIFICATIONS_TABLE . " + WHERE item_type = 'quote' + ORDER BY user_id ASC, item_id ASC"; + $result = $this->db->sql_query($sql); + $this->assertEquals(array( + array('user_id' => 3, 'item_id' => 1, 'item_parent_id' => 1), + array('user_id' => 5, 'item_id' => 1, 'item_parent_id' => 1), + array('user_id' => 7, 'item_id' => 1, 'item_parent_id' => 1), + ), $this->db->sql_fetchrowset($result)); + $this->db->sql_freeresult($result); + } +} From 1259117d213d9364ec7eaeb637f9a3fd8838e816 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Mon, 25 Mar 2013 14:41:31 +0100 Subject: [PATCH 046/281] [ticket/11405] Sort $users array in order to prevent issues on postgres PHPBB3-11405 --- phpBB/includes/notification/type/quote.php | 1 + 1 file changed, 1 insertion(+) diff --git a/phpBB/includes/notification/type/quote.php b/phpBB/includes/notification/type/quote.php index 5453b267c8..e9eb7bea21 100644 --- a/phpBB/includes/notification/type/quote.php +++ b/phpBB/includes/notification/type/quote.php @@ -108,6 +108,7 @@ class phpbb_notification_type_quote extends phpbb_notification_type_post { return array(); } + sort($users); $auth_read = $this->auth->acl_get_list($users, 'f_read', $post['forum_id']); From 060876e627db127c72a953d37e83f5176a085e5d Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Mon, 25 Mar 2013 15:16:29 +0100 Subject: [PATCH 047/281] [ticket/11405] Add a base class to avoid duplicated setUp() code PHPBB3-11405 --- tests/notification/submit_post_base.php | 94 +++++++++++++++++++ .../submit_post_type_post_test.php | 81 +--------------- .../submit_post_type_quote_test.php | 81 +--------------- 3 files changed, 102 insertions(+), 154 deletions(-) create mode 100644 tests/notification/submit_post_base.php diff --git a/tests/notification/submit_post_base.php b/tests/notification/submit_post_base.php new file mode 100644 index 0000000000..60d0e798cb --- /dev/null +++ b/tests/notification/submit_post_base.php @@ -0,0 +1,94 @@ +createXMLDataSet(dirname(__FILE__) . '/fixtures/submit_post_notification.xml'); + } + + public function setUp() + { + parent::setUp(); + + global $auth, $cache, $config, $db, $phpbb_container, $phpbb_dispatcher, $user, $request, $phpEx, $phpbb_root_path; + + // Database + $this->db = $this->new_dbal(); + $db = $this->db; + + // Cache + $cache = new phpbb_mock_cache(); + + // Auth + $auth = $this->getMock('phpbb_auth'); + $auth->expects($this->any()) + ->method('acl_get') + ->with($this->stringContains('_'), + $this->anything()) + ->will($this->returnValueMap(array( + array('f_noapprove', 1, true), + array('f_postcount', 1, true), + array('m_edit', 1, false), + ))); + + // Config + $config = new phpbb_config(array('num_topics' => 1,'num_posts' => 1,)); + set_config(null, null, null, $config); + set_config_count(null, null, null, $config); + + // Event dispatcher + $phpbb_dispatcher = new phpbb_mock_event_dispatcher(); + + // User + $user = $this->getMock('phpbb_user'); + $user->ip = ''; + $user->data = array( + 'user_id' => 2, + 'username' => 'user-name', + 'is_registered' => true, + 'user_colour' => '', + ); + + // Request + $type_cast_helper = $this->getMock('phpbb_request_type_cast_helper_interface'); + $request = $this->getMock('phpbb_request'); + + // Container + $phpbb_container = new phpbb_mock_container_builder(); + + $user_loader = new phpbb_user_loader($db, $phpbb_root_path, '.' . $phpEx, USERS_TABLE); + + // Notification Manager + $phpbb_notifications = new phpbb_notification_manager(array(), array(), + $phpbb_container, $user_loader, $db, $user, + $phpbb_root_path, '.' . $phpEx, + NOTIFICATION_TYPES_TABLE, NOTIFICATIONS_TABLE, USER_NOTIFICATIONS_TABLE); + $phpbb_container->set('notification_manager', $phpbb_notifications); + + // Notification Types + $notification_types = array('quote', 'bookmark', 'post'); + foreach ($notification_types as $type) + { + $class_name = 'phpbb_notification_type_' . $type; + $phpbb_container->set('notification.type.' . $type, new $class_name( + $user_loader, $db, $cache, $user, $auth, $config, + $phpbb_root_path, '.' . $phpEx, + NOTIFICATION_TYPES_TABLE, NOTIFICATIONS_TABLE, USER_NOTIFICATIONS_TABLE)); + } + } +} diff --git a/tests/notification/submit_post_type_post_test.php b/tests/notification/submit_post_type_post_test.php index b1e4b86b15..2e269ff080 100644 --- a/tests/notification/submit_post_type_post_test.php +++ b/tests/notification/submit_post_type_post_test.php @@ -7,45 +7,17 @@ * */ -require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; -require_once dirname(__FILE__) . '/../../phpBB/includes/functions_content.php'; -require_once dirname(__FILE__) . '/../../phpBB/includes/functions_posting.php'; -require_once dirname(__FILE__) . '/../../phpBB/includes/utf/utf_tools.php'; +require_once dirname(__FILE__) . '/submit_post_base.php'; -class phpbb_notification_submit_post_type_post_test extends phpbb_database_test_case +class phpbb_notification_submit_post_type_post_test extends phpbb_notification_submit_post_base { - protected $notifications, $db, $container, $user, $config, $auth, $cache; - - public function getDataSet() - { - return $this->createXMLDataSet(dirname(__FILE__) . '/fixtures/submit_post_notification.xml'); - } - public function setUp() { parent::setUp(); - global $auth, $cache, $config, $db, $phpbb_container, $phpbb_dispatcher, $user, $request, $phpEx, $phpbb_root_path; - - // Database - $this->db = $this->new_dbal(); - $db = $this->db; - - // Cache - $cache = new phpbb_mock_cache(); - - // Auth - $auth = $this->getMock('phpbb_auth'); - $auth->expects($this->any()) - ->method('acl_get') - ->with($this->stringContains('_'), - $this->anything()) - ->will($this->returnValueMap(array( - array('f_noapprove', 1, true), - array('f_postcount', 1, true), - array('m_edit', 1, false), - ))); + global $auth; + // Add additional permissions $auth->expects($this->any()) ->method('acl_get_list') ->with($this->anything(), @@ -63,51 +35,6 @@ class phpbb_notification_submit_post_type_post_test extends phpbb_database_test_ ), ), ))); - - // Config - $config = new phpbb_config(array('num_topics' => 1,'num_posts' => 1,)); - set_config(null, null, null, $config); - set_config_count(null, null, null, $config); - - // Event dispatcher - $phpbb_dispatcher = new phpbb_mock_event_dispatcher(); - - // User - $user = $this->getMock('phpbb_user'); - $user->ip = ''; - $user->data = array( - 'user_id' => 2, - 'username' => 'user-name', - 'is_registered' => true, - 'user_colour' => '', - ); - - // Request - $type_cast_helper = $this->getMock('phpbb_request_type_cast_helper_interface'); - $request = $this->getMock('phpbb_request'); - - // Container - $phpbb_container = new phpbb_mock_container_builder(); - - $user_loader = new phpbb_user_loader($db, $phpbb_root_path, '.' . $phpEx, USERS_TABLE); - - // Notification Manager - $phpbb_notifications = new phpbb_notification_manager(array(), array(), - $phpbb_container, $user_loader, $db, $user, - $phpbb_root_path, '.' . $phpEx, - NOTIFICATION_TYPES_TABLE, NOTIFICATIONS_TABLE, USER_NOTIFICATIONS_TABLE); - $phpbb_container->set('notification_manager', $phpbb_notifications); - - // Notification Types - $notification_types = array('quote', 'bookmark', 'post'); - foreach ($notification_types as $type) - { - $class_name = 'phpbb_notification_type_' . $type; - $phpbb_container->set('notification.type.' . $type, new $class_name( - $user_loader, $db, $cache, $user, $auth, $config, - $phpbb_root_path, '.' . $phpEx, - NOTIFICATION_TYPES_TABLE, NOTIFICATIONS_TABLE, USER_NOTIFICATIONS_TABLE)); - } } /** diff --git a/tests/notification/submit_post_type_quote_test.php b/tests/notification/submit_post_type_quote_test.php index 82f4eaf189..603f7b2020 100644 --- a/tests/notification/submit_post_type_quote_test.php +++ b/tests/notification/submit_post_type_quote_test.php @@ -7,45 +7,17 @@ * */ -require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; -require_once dirname(__FILE__) . '/../../phpBB/includes/functions_content.php'; -require_once dirname(__FILE__) . '/../../phpBB/includes/functions_posting.php'; -require_once dirname(__FILE__) . '/../../phpBB/includes/utf/utf_tools.php'; +require_once dirname(__FILE__) . '/submit_post_base.php'; -class phpbb_notification_submit_post_type_quote_test extends phpbb_database_test_case +class phpbb_notification_submit_post_type_quote_test extends phpbb_notification_submit_post_base { - protected $notifications, $db, $container, $user, $config, $auth, $cache; - - public function getDataSet() - { - return $this->createXMLDataSet(dirname(__FILE__) . '/fixtures/submit_post_notification.xml'); - } - public function setUp() { parent::setUp(); - global $auth, $cache, $config, $db, $phpbb_container, $phpbb_dispatcher, $user, $request, $phpEx, $phpbb_root_path; - - // Database - $this->db = $this->new_dbal(); - $db = $this->db; - - // Cache - $cache = new phpbb_mock_cache(); - - // Auth - $auth = $this->getMock('phpbb_auth'); - $auth->expects($this->any()) - ->method('acl_get') - ->with($this->stringContains('_'), - $this->anything()) - ->will($this->returnValueMap(array( - array('f_noapprove', 1, true), - array('f_postcount', 1, true), - array('m_edit', 1, false), - ))); + global $auth; + // Add additional permissions $auth->expects($this->any()) ->method('acl_get_list') ->with($this->anything(), @@ -63,51 +35,6 @@ class phpbb_notification_submit_post_type_quote_test extends phpbb_database_test ), ), ))); - - // Config - $config = new phpbb_config(array('num_topics' => 1,'num_posts' => 1,)); - set_config(null, null, null, $config); - set_config_count(null, null, null, $config); - - // Event dispatcher - $phpbb_dispatcher = new phpbb_mock_event_dispatcher(); - - // User - $user = $this->getMock('phpbb_user'); - $user->ip = ''; - $user->data = array( - 'user_id' => 2, - 'username' => 'user-name', - 'is_registered' => true, - 'user_colour' => '', - ); - - // Request - $type_cast_helper = $this->getMock('phpbb_request_type_cast_helper_interface'); - $request = $this->getMock('phpbb_request'); - - // Container - $phpbb_container = new phpbb_mock_container_builder(); - - $user_loader = new phpbb_user_loader($db, $phpbb_root_path, '.' . $phpEx, USERS_TABLE); - - // Notification Manager - $phpbb_notifications = new phpbb_notification_manager(array(), array(), - $phpbb_container, $user_loader, $db, $user, - $phpbb_root_path, '.' . $phpEx, - NOTIFICATION_TYPES_TABLE, NOTIFICATIONS_TABLE, USER_NOTIFICATIONS_TABLE); - $phpbb_container->set('notification_manager', $phpbb_notifications); - - // Notification Types - $notification_types = array('quote', 'bookmark', 'post'); - foreach ($notification_types as $type) - { - $class_name = 'phpbb_notification_type_' . $type; - $phpbb_container->set('notification.type.' . $type, new $class_name( - $user_loader, $db, $cache, $user, $auth, $config, - $phpbb_root_path, '.' . $phpEx, - NOTIFICATION_TYPES_TABLE, NOTIFICATIONS_TABLE, USER_NOTIFICATIONS_TABLE)); - } } /** From 053c75543de4c8e5d787a2e344b837f867842f8d Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Mon, 25 Mar 2013 15:34:18 +0100 Subject: [PATCH 048/281] [ticket/11405] Correctly prefill the tables (missed the posts and not-types) PHPBB3-11405 --- .../fixtures/submit_post_notification.xml | 34 +++++++++++++++++++ .../submit_post_type_post_test.php | 6 ++-- .../submit_post_type_quote_test.php | 4 +-- 3 files changed, 39 insertions(+), 5 deletions(-) diff --git a/tests/notification/fixtures/submit_post_notification.xml b/tests/notification/fixtures/submit_post_notification.xml index 5c59edf073..51dd2f8dbd 100644 --- a/tests/notification/fixtures/submit_post_notification.xml +++ b/tests/notification/fixtures/submit_post_notification.xml @@ -25,12 +25,14 @@ user_id item_id item_parent_id + notification_read notification_data post 5 1 1 + 0 @@ -38,6 +40,7 @@ 5 1 1 + 0 @@ -45,10 +48,41 @@ 8 1 1 + 0
    + + notification_type + notification_type_enabled + + post + 1 + + + quote + 1 + +
    + post_id + topic_id + forum_id + post_text + + 1 + 1 + 1 + + +
    + + topic_id + forum_id + + 1 + 1 +
    topic_id diff --git a/tests/notification/submit_post_type_post_test.php b/tests/notification/submit_post_type_post_test.php index 2e269ff080..f439c49167 100644 --- a/tests/notification/submit_post_type_post_test.php +++ b/tests/notification/submit_post_type_post_test.php @@ -92,10 +92,10 @@ class phpbb_notification_submit_post_type_post_test extends phpbb_notification_s ORDER BY user_id ASC, item_id ASC"; $result = $this->db->sql_query($sql); $this->assertEquals(array( - array('user_id' => 3, 'item_id' => 1, 'item_parent_id' => 1), + array('user_id' => 3, 'item_id' => 2, 'item_parent_id' => 1), array('user_id' => 5, 'item_id' => 1, 'item_parent_id' => 1), - array('user_id' => 6, 'item_id' => 1, 'item_parent_id' => 1), - array('user_id' => 7, 'item_id' => 1, 'item_parent_id' => 1), + array('user_id' => 6, 'item_id' => 2, 'item_parent_id' => 1), + array('user_id' => 7, 'item_id' => 2, 'item_parent_id' => 1), array('user_id' => 8, 'item_id' => 1, 'item_parent_id' => 1), ), $this->db->sql_fetchrowset($result)); $this->db->sql_freeresult($result); diff --git a/tests/notification/submit_post_type_quote_test.php b/tests/notification/submit_post_type_quote_test.php index 603f7b2020..9b2323f770 100644 --- a/tests/notification/submit_post_type_quote_test.php +++ b/tests/notification/submit_post_type_quote_test.php @@ -98,9 +98,9 @@ class phpbb_notification_submit_post_type_quote_test extends phpbb_notification_ ORDER BY user_id ASC, item_id ASC"; $result = $this->db->sql_query($sql); $this->assertEquals(array( - array('user_id' => 3, 'item_id' => 1, 'item_parent_id' => 1), + array('user_id' => 3, 'item_id' => 2, 'item_parent_id' => 1), array('user_id' => 5, 'item_id' => 1, 'item_parent_id' => 1), - array('user_id' => 7, 'item_id' => 1, 'item_parent_id' => 1), + array('user_id' => 7, 'item_id' => 2, 'item_parent_id' => 1), ), $this->db->sql_fetchrowset($result)); $this->db->sql_freeresult($result); } From fc8bf3f3c767067a03d240403598d62fb22ce889 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Mon, 25 Mar 2013 01:41:09 +0100 Subject: [PATCH 049/281] [ticket/11469] Add comment about using sql_multi_insert when not buffering. PHPBB3-11469 --- phpBB/includes/db/sql_insert_buffer.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/phpBB/includes/db/sql_insert_buffer.php b/phpBB/includes/db/sql_insert_buffer.php index 8d4b03ef53..fe45206893 100644 --- a/phpBB/includes/db/sql_insert_buffer.php +++ b/phpBB/includes/db/sql_insert_buffer.php @@ -65,6 +65,9 @@ class phpbb_db_sql_insert_buffer { if (!$this->db_supports_multi_insert) { + // The database does not support multi inserts. + // Pass data on to sql_multi_insert right away which will + // immediately send an INSERT INTO query to the database. $this->db->sql_multi_insert($this->table_name, array($row)); } From 36168b311e5f12937977ffd1040ca4a39f70a0e8 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Wed, 27 Feb 2013 23:12:34 +0100 Subject: [PATCH 050/281] [ticket/11314] Fix issues mentioned in jshint report Additionally, the editor.js files are now the same file in both subsilver2, prosilver, and the acp. PHPBB3-11314 --- phpBB/adm/style/permissions.js | 46 ++++---- phpBB/adm/style/tooltip.js | 16 +-- phpBB/assets/javascript/core.js | 14 +-- phpBB/styles/prosilver/template/ajax.js | 6 +- phpBB/styles/prosilver/template/editor.js | 92 ++++++++-------- phpBB/styles/prosilver/template/forum_fn.js | 114 ++++++++++++-------- phpBB/styles/prosilver/template/timezone.js | 2 +- phpBB/styles/subsilver2/template/editor.js | 98 ++++++++--------- 8 files changed, 207 insertions(+), 181 deletions(-) diff --git a/phpBB/adm/style/permissions.js b/phpBB/adm/style/permissions.js index adc8995c23..9210f864b2 100644 --- a/phpBB/adm/style/permissions.js +++ b/phpBB/adm/style/permissions.js @@ -2,7 +2,7 @@ * Hide and show all checkboxes * status = true (show boxes), false (hide boxes) */ -function display_checkboxes(status) +function display_checkboxes(status) { var form = document.getElementById('set-permissions'); var cb = document.getElementsByTagName('input'); @@ -21,7 +21,7 @@ function display_checkboxes(status) for (var i = 0; i < cb.length; i++ ) { - if (cb[i].className == 'permissions-checkbox') + if (cb[i].className === 'permissions-checkbox') { cb[i].style.display = display; } @@ -51,7 +51,7 @@ function toggle_opacity(block_id) { var cb = document.getElementById('checkbox' + block_id); var fs = document.getElementById('perm' + block_id); - if (cb.checked) + if (cb.checked) { set_opacity(fs, 5); } @@ -78,13 +78,13 @@ function reset_opacity(status, except_id) { for (var i = 0; i < fs.length; i++ ) { - if (fs[i].className != 'quick') + if (fs[i].className !== 'quick') { set_opacity(fs[i], opacity); } } - if (typeof(except_id) != 'undefined') + if (typeof(except_id) !== 'undefined') { set_opacity(document.getElementById('perm' + except_id), 10); } @@ -99,11 +99,11 @@ function reset_opacity(status, except_id) { * index = offset for the row of inputs (0 == first row, 1 == second, 2 == third), * rb = array of radiobuttons */ -function get_radio_status(index, rb) +function get_radio_status(index, rb) { for (var i = index; i < rb.length; i = i + 3 ) { - if (rb[i].checked != true) + if (rb[i].checked !== true) { if (i > index) { @@ -130,7 +130,7 @@ function set_colours(id, init, quick) var table = document.getElementById('table' + id); var tab = document.getElementById('tab' + id); - if (typeof(quick) != 'undefined') + if (typeof(quick) !== 'undefined') { tab.className = 'permissions-preset-' + quick + ' activetab'; return; @@ -141,25 +141,25 @@ function set_colours(id, init, quick) var status = get_radio_status(0, rb); - if (status == 1) + if (status === 1) { colour = 'yes'; } - else if (status == 0) + else if (status === 0) { // We move on to No status = get_radio_status(1, rb); - if (status == 1) + if (status === 1) { colour = 'no'; } - else if (status == 0) + else if (status === 0) { // We move on to Never status = get_radio_status(2, rb); - if (status == 1) + if (status === 1) { colour = 'never'; } @@ -188,7 +188,7 @@ function init_colours(block_id) for (var i = 0; i < panels.length; i++) { - if(panels[i].className == 'permissions-panel') + if(panels[i].className === 'permissions-panel') { set_colours(panels[i].id.replace(/options/, ''), true); } @@ -212,7 +212,7 @@ function swap_options(pmask, fmask, cat, adv, view) var new_tab = document.getElementById('tab' + id); var adv_block = document.getElementById('advanced' + pmask + fmask); - if (adv_block.style.display == 'block' && adv == true) + if (adv_block.style.display === 'block' && adv === true) { dE('advanced' + pmask + fmask, -1); reset_opacity(1); @@ -221,19 +221,19 @@ function swap_options(pmask, fmask, cat, adv, view) } // no need to set anything if we are clicking on the same tab again - if (new_tab == old_tab && !adv) + if (new_tab === old_tab && !adv) { return; } // init colours - if (adv && (pmask + fmask) != (active_pmask + active_fmask)) + if (adv && (pmask + fmask) !== (active_pmask + active_fmask)) { init_colours(pmask + fmask); display_checkboxes(true); reset_opacity(1); } - else if (adv) + else if (adv) { //Checkbox might have been clicked, but we need full visibility display_checkboxes(true); @@ -244,7 +244,7 @@ function swap_options(pmask, fmask, cat, adv, view) old_tab.className = old_tab.className.replace(/\ activetab/g, ''); new_tab.className = new_tab.className + ' activetab'; - if (id == active_option && adv != true) + if (id === active_option && adv !== true) { return; } @@ -256,7 +256,7 @@ function swap_options(pmask, fmask, cat, adv, view) { dE('checkbox' + pmask + fmask, -1); - if ((pmask + fmask) != (active_pmask + active_fmask)) + if ((pmask + fmask) !== (active_pmask + active_fmask)) { document.getElementById('checkbox' + active_pmask + active_fmask).style.display = 'inline'; } @@ -295,7 +295,7 @@ function mark_options(id, s) for (var r = 0; r < rb.length; r++) { - if (rb[r].id.substr(rb[r].id.length-1) == s) + if (rb[r].id.substr(rb[r].id.length-1) === s) { rb[r].checked = true; } @@ -315,7 +315,7 @@ function mark_one_option(id, field_name, s) for (var r = 0; r < rb.length; r++) { - if (rb[r].id.substr(rb[r].id.length-field_name.length-3, field_name.length) == field_name && rb[r].id.substr(rb[r].id.length-1) == s) + if (rb[r].id.substr(rb[r].id.length-field_name.length-3, field_name.length) === field_name && rb[r].id.substr(rb[r].id.length-1) === s) { rb[r].checked = true; } @@ -354,6 +354,6 @@ function set_role_settings(role_id, target_id) for (var r in settings) { - mark_one_option(target_id, r, (settings[r] == 1) ? 'y' : 'n'); + mark_one_option(target_id, r, (settings[r] === 1) ? 'y' : 'n'); } } diff --git a/phpBB/adm/style/tooltip.js b/phpBB/adm/style/tooltip.js index 20610b52fe..14f4772efa 100644 --- a/phpBB/adm/style/tooltip.js +++ b/phpBB/adm/style/tooltip.js @@ -33,7 +33,7 @@ function enable_tooltips_link(id, headline, sub_id) document.getElementsByTagName('body')[0].appendChild(hold); - if (id == null) + if (id === null) { links = document.getElementsByTagName('a'); } @@ -46,7 +46,7 @@ function enable_tooltips_link(id, headline, sub_id) { if (sub_id) { - if (links[i].id.substr(0, sub_id.length) == sub_id) + if (links[i].id.substr(0, sub_id.length) === sub_id) { prepare(links[i]); } @@ -81,7 +81,7 @@ function enable_tooltips_select(id, headline, sub_id) document.getElementsByTagName('body')[0].appendChild(hold); - if (id == null) + if (id === null) { links = document.getElementsByTagName('option'); } @@ -94,7 +94,7 @@ function enable_tooltips_select(id, headline, sub_id) { if (sub_id) { - if (links[i].parentNode.id.substr(0, sub_id.length) == sub_id) + if (links[i].parentNode.id.substr(0, sub_id.length) === sub_id) { prepare(links[i]); } @@ -117,7 +117,7 @@ function prepare(element) text = element.getAttribute('title'); - if (text == null || text.length == 0) + if (text === null || text.length === 0) { return; } @@ -139,7 +139,7 @@ function prepare(element) element.onmouseover = show_tooltip; element.onmouseout = hide_tooltip; - if (tooltip_mode == 'link') + if (tooltip_mode === 'link') { element.onmousemove = locate; } @@ -200,7 +200,7 @@ function locate(e) if (e.offsetParent) { - for (var posx = 0, posy = 0; e.offsetParent; e = e.offsetParent) + for (posx = 0, posy = 0; e.offsetParent; e = e.offsetParent) { posx += e.offsetLeft; posy += e.offsetTop; @@ -212,7 +212,7 @@ function locate(e) posy = e.offsetTop; } - if (tooltip_mode == 'link') + if (tooltip_mode === 'link') { document.getElementById('_tooltip_container').style.top=(posy+20) + 'px'; document.getElementById('_tooltip_container').style.left=(posx-20) + 'px'; diff --git a/phpBB/assets/javascript/core.js b/phpBB/assets/javascript/core.js index f38b35d613..b718dabe6c 100644 --- a/phpBB/assets/javascript/core.js +++ b/phpBB/assets/javascript/core.js @@ -353,7 +353,7 @@ phpbb.ajaxify = function(options) { return; } - if (overlay && (typeof $this.attr('data-overlay') === 'undefined' || $this.attr('data-overlay') == 'true')) + if (overlay && (typeof $this.attr('data-overlay') === 'undefined' || $this.attr('data-overlay') === 'true')) { phpbb.loadingAlert(); } @@ -387,7 +387,7 @@ phpbb.ajaxify = function(options) { * @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) { + if ($('#timezone_copy').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 @@ -397,17 +397,17 @@ phpbb.timezoneSwitchDate = function(keepSelection) { $('#timezone').replaceWith($('#timezone_copy').clone().attr('id', 'timezone').css('display', 'block').attr('name', 'tz')); } - if ($('#tz_date').val() != '') { + if ($('#tz_date').val() !== '') { $('#timezone > optgroup').remove(":not([label='" + $('#tz_date').val() + "'])"); } - if ($('#tz_date').val() == $('#tz_select_date_suggest').attr('data-suggested-tz')) { + if ($('#tz_date').val() === $('#tz_select_date_suggest').attr('data-suggested-tz')) { $('#tz_select_date_suggest').css('display', 'none'); } else { $('#tz_select_date_suggest').css('display', 'inline'); } - if ($("#timezone > optgroup[label='" + $('#tz_date').val() + "'] > option").size() == 1) { + if ($("#timezone > optgroup[label='" + $('#tz_date').val() + "'] > option").size() === 1) { // If there is only one timezone for the selected date, we just select that automatically. $("#timezone > optgroup[label='" + $('#tz_date').val() + "'] > option:first").attr('selected', true); keepSelection = true; @@ -468,8 +468,8 @@ phpbb.timezonePreselectSelect = function(forceSelector) { for (i = 0; i < selectorOptions.length; ++i) { var option = selectorOptions[i]; - if (option.value.substring(0, prefixLength) == prefix) { - if ($('#tz_date').val() != option.value && !forceSelector) { + if (option.value.substring(0, prefixLength) === prefix) { + if ($('#tz_date').val() !== option.value && !forceSelector) { // We do not select the option for the user, but notify him, // that we would suggest a different setting. phpbb.timezoneSwitchDate(true); diff --git a/phpBB/styles/prosilver/template/ajax.js b/phpBB/styles/prosilver/template/ajax.js index e38e3d4cb2..8c61be5942 100644 --- a/phpBB/styles/prosilver/template/ajax.js +++ b/phpBB/styles/prosilver/template/ajax.js @@ -39,7 +39,7 @@ phpbb.addAjaxCallback('mark_forums_read', function(res) { // Mark topics read if we are watching a category and showing active topics if ($('#active_topics').length) { - phpbb.ajaxCallbacks['mark_topics_read'].call(this, res, false); + phpbb.ajaxCallbacks.mark_topics_read.call(this, res, false); } // Update mark forums read links @@ -75,7 +75,7 @@ phpbb.addAjaxCallback('mark_topics_read', function(res, update_topic_links) { $.each(iconsArray, function(unreadClass, readClass) { $.each(iconsState, function(key, value) { // Only topics can be hot - if ((value == '_hot' || value == '_hot_mine') && unreadClass != 'topic_unread') { + if ((value === '_hot' || value === '_hot_mine') && unreadClass !== 'topic_unread') { return true; } classMap[unreadClass + value] = readClass + value; @@ -218,7 +218,7 @@ $('#quick-mod-select').change(function () { */ $('#member_search').click(function () { $('#memberlist_search').slideToggle('fast'); - phpbb.ajax_callbacks['alt_text'].call(this); + phpbb.ajax_callbacks.alt_text.call(this); // Focus on the username textbox if it's available and displayed if ($('#memberlist_search').is(':visible')) { $('#username').focus(); diff --git a/phpBB/styles/prosilver/template/editor.js b/phpBB/styles/prosilver/template/editor.js index c099466005..13e9ca3c66 100644 --- a/phpBB/styles/prosilver/template/editor.js +++ b/phpBB/styles/prosilver/template/editor.js @@ -6,15 +6,15 @@ // Startup variables var imageTag = false; var theSelection = false; - var bbcodeEnabled = true; + // Check for Browser & Platform for PC & IE specific bits // More details from: http://www.mozilla.org/docs/web-developer/sniffer/browser_type.html var clientPC = navigator.userAgent.toLowerCase(); // Get client info var clientVer = parseInt(navigator.appVersion, 10); // Get browser version -var is_ie = ((clientPC.indexOf('msie') != -1) && (clientPC.indexOf('opera') == -1)); -var is_win = ((clientPC.indexOf('win') != -1) || (clientPC.indexOf('16bit') != -1)); +var is_ie = ((clientPC.indexOf('msie') !== -1) && (clientPC.indexOf('opera') === -1)); +var is_win = ((clientPC.indexOf('win') !== -1) || (clientPC.indexOf('16bit') !== -1)); var baseHeight; /** @@ -29,7 +29,7 @@ function helpline(help) * Fix a bug involving the TextRange object. From * http://www.frostjedi.com/terra/scripts/demo/caretBug.html */ -function initInsertions() +function initInsertions() { var doc; @@ -37,14 +37,14 @@ function initInsertions() { doc = document; } - else + else { doc = opener.document; } var textarea = doc.forms[form_name].elements[text_name]; - if (is_ie && typeof(baseHeight) != 'number') + if (is_ie && typeof(baseHeight) !== 'number') { textarea.focus(); baseHeight = doc.selection.createRange().duplicate().boundingHeight; @@ -60,12 +60,12 @@ function initInsertions() * bbstyle */ function bbstyle(bbnumber) -{ - if (bbnumber != -1) +{ + if (bbnumber !== -1) { bbfontstyle(bbtags[bbnumber], bbtags[bbnumber+1]); - } - else + } + else { insert_text('[*]'); document.forms[form_name].elements[text_name].focus(); @@ -104,10 +104,10 @@ function bbfontstyle(bbopen, bbclose) theSelection = ''; return; } - + //The new position for the cursor after adding the bbcode var caret_pos = getCaretPosition(textarea).start; - var new_pos = caret_pos + bbopen.length; + var new_pos = caret_pos + bbopen.length; // Open tag insert_text(bbopen + bbclose); @@ -118,7 +118,7 @@ function bbfontstyle(bbopen, bbclose) { textarea.selectionStart = new_pos; textarea.selectionEnd = new_pos; - } + } // IE else if (document.selection) { @@ -138,16 +138,17 @@ function bbfontstyle(bbopen, bbclose) function insert_text(text, spaces, popup) { var textarea; - - if (!popup) + + if (!popup) { textarea = document.forms[form_name].elements[text_name]; - } - else + } + else { textarea = opener.document.forms[form_name].elements[text_name]; } - if (spaces) + + if (spaces) { text = ' ' + text + ' '; } @@ -165,20 +166,21 @@ function insert_text(text, spaces, popup) } else if (textarea.createTextRange && textarea.caretPos) { - if (baseHeight != textarea.caretPos.boundingHeight) + if (baseHeight !== textarea.caretPos.boundingHeight) { textarea.focus(); storeCaret(textarea); } var caret_pos = textarea.caretPos; - caret_pos.text = caret_pos.text.charAt(caret_pos.text.length - 1) == ' ' ? caret_pos.text + text + ' ' : caret_pos.text + text; + caret_pos.text = caret_pos.text.charAt(caret_pos.text.length - 1) === ' ' ? caret_pos.text + text + ' ' : caret_pos.text + text; } else { textarea.value = textarea.value + text; } - if (!popup) + + if (!popup) { textarea.focus(); } @@ -201,6 +203,7 @@ function addquote(post_id, username, l_wrote) var message_name = 'message_' + post_id; var theSelection = ''; var divarea = false; + var i; if (l_wrote === undefined) { @@ -232,7 +235,7 @@ function addquote(post_id, username, l_wrote) theSelection = document.selection.createRange().text; } - if (theSelection == '' || typeof theSelection == 'undefined' || theSelection == null) + if (theSelection === '' || typeof theSelection === 'undefined' || theSelection === null) { if (divarea.innerHTML) { @@ -282,6 +285,8 @@ function split_lines(text) var lines = text.split('\n'); var splitLines = new Array(); var j = 0; + var i; + for(i = 0; i < lines.length; i++) { if (lines[i].length <= 80) @@ -292,11 +297,12 @@ function split_lines(text) else { var line = lines[i]; + var splitAt; do { - var splitAt = line.indexOf(' ', 80); - - if (splitAt == -1) + splitAt = line.indexOf(' ', 80); + + if (splitAt === -1) { splitLines[j] = line; j++; @@ -308,22 +314,23 @@ function split_lines(text) j++; } } - while(splitAt != -1); + while(splitAt !== -1); } } return splitLines; } + /** * From http://www.massless.org/mozedit/ */ function mozWrap(txtarea, open, close) { - var selLength = (typeof(txtarea.textLength) == 'undefined') ? txtarea.value.length : txtarea.textLength; + var selLength = (typeof(txtarea.textLength) === 'undefined') ? txtarea.value.length : txtarea.textLength; var selStart = txtarea.selectionStart; var selEnd = txtarea.selectionEnd; var scrollTop = txtarea.scrollTop; - if (selEnd == 1 || selEnd == 2) + if (selEnd === 1 || selEnd === 2) { selEnd = selLength; } @@ -372,18 +379,18 @@ function colorPalette(dir, width, height) for (r = 0; r < 5; r++) { - if (dir == 'h') + if (dir === 'h') { document.writeln(''); } for (g = 0; g < 5; g++) { - if (dir == 'v') + if (dir === 'v') { document.writeln(''); } - + for (b = 0; b < 5; b++) { color = String(numberList[r]) + String(numberList[g]) + String(numberList[b]); @@ -392,13 +399,13 @@ function colorPalette(dir, width, height) document.writeln(''); } - if (dir == 'v') + if (dir === 'v') { document.writeln(''); } } - if (dir == 'h') + if (dir === 'h') { document.writeln(''); } @@ -406,7 +413,6 @@ function colorPalette(dir, width, height) document.writeln('
    '); } - /** * Caret Position object */ @@ -416,43 +422,41 @@ function caretPosition() var end = null; } - /** * Get the caret position in an textarea */ function getCaretPosition(txtarea) { var caretPos = new caretPosition(); - + // simple Gecko/Opera way - if(txtarea.selectionStart || txtarea.selectionStart == 0) + if (txtarea.selectionStart || txtarea.selectionStart === 0) { caretPos.start = txtarea.selectionStart; caretPos.end = txtarea.selectionEnd; } // dirty and slow IE way - else if(document.selection) + else if (document.selection) { - // get current selection var range = document.selection.createRange(); // a new selection of the whole textarea var range_all = document.body.createTextRange(); range_all.moveToElementText(txtarea); - + // calculate selection start point by moving beginning of range_all to beginning of range var sel_start; for (sel_start = 0; range_all.compareEndPoints('StartToStart', range) < 0; sel_start++) - { + { range_all.moveStart('character', 1); } - + txtarea.sel_start = sel_start; - + // we ignore the end value for IE, this is already dirty enough and we don't need it caretPos.start = txtarea.sel_start; - caretPos.end = txtarea.sel_start; + caretPos.end = txtarea.sel_start; } return caretPos; diff --git a/phpBB/styles/prosilver/template/forum_fn.js b/phpBB/styles/prosilver/template/forum_fn.js index 995b4b0ab7..677e9274c4 100644 --- a/phpBB/styles/prosilver/template/forum_fn.js +++ b/phpBB/styles/prosilver/template/forum_fn.js @@ -23,9 +23,9 @@ function jumpto() { var page = prompt(jump_page, on_page); - if (page !== null && !isNaN(page) && page == Math.floor(page) && page > 0) + if (page !== null && !isNaN(page) && page === Math.floor(page) && page > 0) { - if (base_url.indexOf('?') == -1) + if (base_url.indexOf('?') === -1) { document.location.href = base_url + '?start=' + ((page - 1) * per_page); } @@ -53,7 +53,7 @@ function marklist(id, name, state) for (var r = 0; r < rb.length; r++) { - if (rb[r].name.substr(0, name.length) == name) + if (rb[r].name.substr(0, name.length) === name) { rb[r].checked = state; } @@ -66,7 +66,10 @@ function marklist(id, name, state) */ function viewableArea(e, itself) { - if (!e) return; + if (!e) { + return; + } + if (!itself) { e = e.parentNode; @@ -106,9 +109,9 @@ function dE(n, s, type) var e = document.getElementById(n); if (!s) { - s = (e.style.display == '' || e.style.display == type) ? -1 : 1; + s = (e.style.display === '' || e.style.display === type) ? -1 : 1; } - e.style.display = (s == 1) ? type : 'none'; + e.style.display = (s === 1) ? type : 'none'; } /** @@ -118,7 +121,7 @@ function subPanels(p) { var i, e, t; - if (typeof(p) == 'string') + if (typeof(p) === 'string') { show_panel = p; } @@ -130,7 +133,7 @@ function subPanels(p) if (e) { - if (panels[i] == show_panel) + if (panels[i] === show_panel) { e.style.display = 'block'; if (t) @@ -173,7 +176,7 @@ function printPage() */ function displayBlocks(c, e, t) { - var s = (e.checked == true) ? 1 : -1; + var s = (e.checked === true) ? 1 : -1; if (t) { @@ -184,9 +187,9 @@ function displayBlocks(c, e, t) for (var d = 0; d < divs.length; d++) { - if (divs[d].className.indexOf(c) == 0) + if (divs[d].className.indexOf(c) === 0) { - divs[d].style.display = (s == 1) ? 'none' : 'block'; + divs[d].style.display = (s === 1) ? 'none' : 'block'; } } } @@ -195,11 +198,12 @@ function selectCode(a) { // Get ID of code block var e = a.parentNode.parentNode.getElementsByTagName('CODE')[0]; + var s, r; // Not IE and IE9+ if (window.getSelection) { - var s = window.getSelection(); + s = window.getSelection(); // Safari if (s.setBaseAndExtent) { @@ -209,12 +213,12 @@ function selectCode(a) else { // workaround for bug # 42885 - if (window.opera && e.innerHTML.substring(e.innerHTML.length - 4) == '
    ') + if (window.opera && e.innerHTML.substring(e.innerHTML.length - 4) === '
    ') { e.innerHTML = e.innerHTML + ' '; } - var r = document.createRange(); + r = document.createRange(); r.selectNodeContents(e); s.removeAllRanges(); s.addRange(r); @@ -223,8 +227,8 @@ function selectCode(a) // Some older browsers else if (document.getSelection) { - var s = document.getSelection(); - var r = document.createRange(); + s = document.getSelection(); + r = document.createRange(); r.selectNodeContents(e); s.removeAllRanges(); s.addRange(r); @@ -232,7 +236,7 @@ function selectCode(a) // IE else if (document.selection) { - var r = document.body.createTextRange(); + r = document.body.createTextRange(); r.moveToElementText(e); r.select(); } @@ -245,22 +249,23 @@ function selectCode(a) function play_qt_file(obj) { var rectangle = obj.GetRectangle(); + var width, height; if (rectangle) { rectangle = rectangle.split(','); - var x1 = parseInt(rectangle[0]); - var x2 = parseInt(rectangle[2]); - var y1 = parseInt(rectangle[1]); - var y2 = parseInt(rectangle[3]); + var x1 = parseInt(rectangle[0], 10); + var x2 = parseInt(rectangle[2], 10); + var y1 = parseInt(rectangle[1], 10); + var y2 = parseInt(rectangle[3], 10); - var width = (x1 < 0) ? (x1 * -1) + x2 : x2 - x1; - var height = (y1 < 0) ? (y1 * -1) + y2 : y2 - y1; + width = (x1 < 0) ? (x1 * -1) + x2 : x2 - x1; + height = (y1 < 0) ? (y1 * -1) + y2 : y2 - y1; } else { - var width = 200; - var height = 0; + width = 200; + height = 0; } obj.width = width; @@ -276,7 +281,7 @@ function play_qt_file(obj) */ function is_node_name(elem, name) { - return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase(); + return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase(); } /** @@ -285,10 +290,12 @@ function is_node_name(elem, name) */ function is_in_array(elem, array) { - for (var i = 0, length = array.length; i < length; i++) + for (var i = 0, length = array.length; i < length; i++) { // === is correct (IE) - if (array[i] === elem) + if (array[i] === elem) { return i; + } + } return -1; } @@ -304,17 +311,22 @@ function find_in_tree(node, tag, type, class_name) for (element = node.childNodes[0]; i < length; element = node.childNodes[++i]) { - if (!element || element.nodeType != 1) continue; + if (!element || element.nodeType !== 1) { + continue; + } - if ((!tag || is_node_name(element, tag)) && (!type || element.type == type) && (!class_name || is_in_array(class_name, (element.className || element).toString().split(/\s+/)) > -1)) + if ((!tag || is_node_name(element, tag)) && (!type || element.type === type) && (!class_name || is_in_array(class_name, (element.className || element).toString().split(/\s+/)) > -1)) { return element; } - if (element.childNodes.length) + if (element.childNodes.length) { result = find_in_tree(element, tag, type, class_name); + } - if (result) return result; + if (result) { + return result; + } } } @@ -327,14 +339,15 @@ var last_key_entered = ''; function phpbb_check_key(event) { // Keycode is array down or up? - if (event.keyCode && (event.keyCode == 40 || event.keyCode == 38)) + if (event.keyCode && (event.keyCode === 40 || event.keyCode === 38)) { in_autocomplete = true; + } // Make sure we are not within an "autocompletion" field if (in_autocomplete) { // If return pressed and key changed we reset the autocompletion - if (!last_key_entered || last_key_entered == event.which) + if (!last_key_entered || last_key_entered === event.which) { in_autocompletion = false; return true; @@ -342,7 +355,7 @@ function phpbb_check_key(event) } // Keycode is not return, then return. ;) - if (event.which != 13) + if (event.which !== 13) { last_key_entered = event.which; return true; @@ -357,17 +370,20 @@ function phpbb_check_key(event) function submit_default_button(event, selector, class_name) { // Add which for key events - if (!event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode)) + if (!event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode)) { event.which = event.charCode || event.keyCode; + } - if (phpbb_check_key(event)) + if (phpbb_check_key(event)) { return true; + } - var current = selector['parentNode']; + var current = selector.parentNode; // Search parent form element - while (current && (!current.nodeName || current.nodeType != 1 || !is_node_name(current, 'form')) && current != document) - current = current['parentNode']; + while (current && (!current.nodeName || current.nodeType !== 1 || !is_node_name(current, 'form')) && current !== document) { + current = current.parentNode; + } // Find the input submit button with the class name //current = find_in_tree(current, 'input', 'submit', class_name); @@ -376,12 +392,14 @@ function submit_default_button(event, selector, class_name) for (var i = 0, element = input_tags[0]; i < input_tags.length; element = input_tags[++i]) { - if (element.type == 'submit' && is_in_array(class_name, (element.className || element).toString().split(/\s+/)) > -1) + if (element.type === 'submit' && is_in_array(class_name, (element.className || element).toString().split(/\s+/)) > -1) { current = element; + } } - if (!current) + if (!current) { return true; + } // Submit form current.focus(); @@ -403,13 +421,15 @@ function apply_onkeypress_event() { var default_button = jQuery(this).parents('form').find('input[type=submit].default-submit-action'); - if (!default_button || default_button.length <= 0) + if (!default_button || default_button.length <= 0) { return true; + } - if (phpbb_check_key(e)) + if (phpbb_check_key(e)) { return true; + } - if ((e.which && e.which == 13) || (e.keyCode && e.keyCode == 13)) + if ((e.which && e.which === 13) || (e.keyCode && e.keyCode === 13)) { default_button.click(); return false; @@ -425,7 +445,7 @@ function apply_onkeypress_event() for (var i = 0, element = input_tags[0]; i < input_tags.length ; element = input_tags[++i]) { - if (element.type == 'text' || element.type == 'password') + if (element.type === 'text' || element.type === 'password') { // onkeydown is possible too element.onkeypress = function (evt) { submit_default_button((evt || window.event), this, 'default-submit-action'); }; @@ -436,4 +456,4 @@ function apply_onkeypress_event() /** * Detect JQuery existance. We currently do not deliver it, but some styles do, so why not benefit from it. ;) */ -var jquery_present = typeof jQuery == 'function'; +var jquery_present = typeof jQuery === 'function'; diff --git a/phpBB/styles/prosilver/template/timezone.js b/phpBB/styles/prosilver/template/timezone.js index b0e8a38366..ed7cf0e051 100644 --- a/phpBB/styles/prosilver/template/timezone.js +++ b/phpBB/styles/prosilver/template/timezone.js @@ -15,7 +15,7 @@ $(document).ready( ); $(document).ready( - phpbb.timezonePreselectSelect($('#tz_select_date_suggest').attr('data-is-registration') == 'true') + phpbb.timezonePreselectSelect($('#tz_select_date_suggest').attr('data-is-registration') === 'true') ); })(jQuery); // Avoid conflicts with other libraries diff --git a/phpBB/styles/subsilver2/template/editor.js b/phpBB/styles/subsilver2/template/editor.js index 0b5b15643a..13e9ca3c66 100644 --- a/phpBB/styles/subsilver2/template/editor.js +++ b/phpBB/styles/subsilver2/template/editor.js @@ -11,11 +11,10 @@ var bbcodeEnabled = true; // Check for Browser & Platform for PC & IE specific bits // More details from: http://www.mozilla.org/docs/web-developer/sniffer/browser_type.html var clientPC = navigator.userAgent.toLowerCase(); // Get client info -var clientVer = parseInt(navigator.appVersion); // Get browser version - -var is_ie = ((clientPC.indexOf('msie') != -1) && (clientPC.indexOf('opera') == -1)); -var is_win = ((clientPC.indexOf('win') != -1) || (clientPC.indexOf('16bit') != -1)); +var clientVer = parseInt(navigator.appVersion, 10); // Get browser version +var is_ie = ((clientPC.indexOf('msie') !== -1) && (clientPC.indexOf('opera') === -1)); +var is_win = ((clientPC.indexOf('win') !== -1) || (clientPC.indexOf('16bit') !== -1)); var baseHeight; /** @@ -30,7 +29,7 @@ function helpline(help) * Fix a bug involving the TextRange object. From * http://www.frostjedi.com/terra/scripts/demo/caretBug.html */ -function initInsertions() +function initInsertions() { var doc; @@ -38,14 +37,15 @@ function initInsertions() { doc = document; } - else + else { doc = opener.document; } var textarea = doc.forms[form_name].elements[text_name]; - if (is_ie && typeof(baseHeight) != 'number') - { + + if (is_ie && typeof(baseHeight) !== 'number') + { textarea.focus(); baseHeight = doc.selection.createRange().duplicate().boundingHeight; @@ -60,12 +60,12 @@ function initInsertions() * bbstyle */ function bbstyle(bbnumber) -{ - if (bbnumber != -1) +{ + if (bbnumber !== -1) { bbfontstyle(bbtags[bbnumber], bbtags[bbnumber+1]); - } - else + } + else { insert_text('[*]'); document.forms[form_name].elements[text_name].focus(); @@ -78,7 +78,7 @@ function bbstyle(bbnumber) function bbfontstyle(bbopen, bbclose) { theSelection = false; - + var textarea = document.forms[form_name].elements[text_name]; textarea.focus(); @@ -104,7 +104,7 @@ function bbfontstyle(bbopen, bbclose) theSelection = ''; return; } - + //The new position for the cursor after adding the bbcode var caret_pos = getCaretPosition(textarea).start; var new_pos = caret_pos + bbopen.length; @@ -118,7 +118,7 @@ function bbfontstyle(bbopen, bbclose) { textarea.selectionStart = new_pos; textarea.selectionEnd = new_pos; - } + } // IE else if (document.selection) { @@ -138,16 +138,17 @@ function bbfontstyle(bbopen, bbclose) function insert_text(text, spaces, popup) { var textarea; - - if (!popup) + + if (!popup) { textarea = document.forms[form_name].elements[text_name]; - } - else + } + else { textarea = opener.document.forms[form_name].elements[text_name]; } - if (spaces) + + if (spaces) { text = ' ' + text + ' '; } @@ -162,23 +163,23 @@ function insert_text(text, spaces, popup) mozWrap(textarea, text, ''); textarea.selectionStart = sel_start + text.length; textarea.selectionEnd = sel_end + text.length; - } - + } else if (textarea.createTextRange && textarea.caretPos) { - if (baseHeight != textarea.caretPos.boundingHeight) + if (baseHeight !== textarea.caretPos.boundingHeight) { textarea.focus(); storeCaret(textarea); - } + } + var caret_pos = textarea.caretPos; - caret_pos.text = caret_pos.text.charAt(caret_pos.text.length - 1) == ' ' ? caret_pos.text + text + ' ' : caret_pos.text + text; - + caret_pos.text = caret_pos.text.charAt(caret_pos.text.length - 1) === ' ' ? caret_pos.text + text + ' ' : caret_pos.text + text; } else { textarea.value = textarea.value + text; } + if (!popup) { textarea.focus(); @@ -202,6 +203,7 @@ function addquote(post_id, username, l_wrote) var message_name = 'message_' + post_id; var theSelection = ''; var divarea = false; + var i; if (l_wrote === undefined) { @@ -233,7 +235,7 @@ function addquote(post_id, username, l_wrote) theSelection = document.selection.createRange().text; } - if (theSelection == '' || typeof theSelection == 'undefined' || theSelection == null) + if (theSelection === '' || typeof theSelection === 'undefined' || theSelection === null) { if (divarea.innerHTML) { @@ -278,12 +280,13 @@ function addquote(post_id, username, l_wrote) return; } - function split_lines(text) { var lines = text.split('\n'); var splitLines = new Array(); var j = 0; + var i; + for(i = 0; i < lines.length; i++) { if (lines[i].length <= 80) @@ -294,11 +297,12 @@ function split_lines(text) else { var line = lines[i]; + var splitAt; do { - var splitAt = line.indexOf(' ', 80); - - if (splitAt == -1) + splitAt = line.indexOf(' ', 80); + + if (splitAt === -1) { splitLines[j] = line; j++; @@ -310,7 +314,7 @@ function split_lines(text) j++; } } - while(splitAt != -1); + while(splitAt !== -1); } } return splitLines; @@ -321,12 +325,12 @@ function split_lines(text) */ function mozWrap(txtarea, open, close) { - var selLength = (typeof(txtarea.textLength) == 'undefined') ? txtarea.value.length : txtarea.textLength; + var selLength = (typeof(txtarea.textLength) === 'undefined') ? txtarea.value.length : txtarea.textLength; var selStart = txtarea.selectionStart; var selEnd = txtarea.selectionEnd; var scrollTop = txtarea.scrollTop; - if (selEnd == 1 || selEnd == 2) + if (selEnd === 1 || selEnd === 2) { selEnd = selLength; } @@ -375,18 +379,18 @@ function colorPalette(dir, width, height) for (r = 0; r < 5; r++) { - if (dir == 'h') + if (dir === 'h') { document.writeln(''); } for (g = 0; g < 5; g++) { - if (dir == 'v') + if (dir === 'v') { document.writeln(''); } - + for (b = 0; b < 5; b++) { color = String(numberList[r]) + String(numberList[g]) + String(numberList[b]); @@ -395,13 +399,13 @@ function colorPalette(dir, width, height) document.writeln(''); } - if (dir == 'v') + if (dir === 'v') { document.writeln(''); } } - if (dir == 'h') + if (dir === 'h') { document.writeln(''); } @@ -409,7 +413,6 @@ function colorPalette(dir, width, height) document.writeln(''); } - /** * Caret Position object */ @@ -419,22 +422,21 @@ function caretPosition() var end = null; } - /** * Get the caret position in an textarea */ function getCaretPosition(txtarea) { var caretPos = new caretPosition(); - + // simple Gecko/Opera way - if(txtarea.selectionStart || txtarea.selectionStart == 0) + if (txtarea.selectionStart || txtarea.selectionStart === 0) { caretPos.start = txtarea.selectionStart; caretPos.end = txtarea.selectionEnd; } // dirty and slow IE way - else if(document.selection) + else if (document.selection) { // get current selection var range = document.selection.createRange(); @@ -442,16 +444,16 @@ function getCaretPosition(txtarea) // a new selection of the whole textarea var range_all = document.body.createTextRange(); range_all.moveToElementText(txtarea); - + // calculate selection start point by moving beginning of range_all to beginning of range var sel_start; for (sel_start = 0; range_all.compareEndPoints('StartToStart', range) < 0; sel_start++) - { + { range_all.moveStart('character', 1); } - + txtarea.sel_start = sel_start; - + // we ignore the end value for IE, this is already dirty enough and we don't need it caretPos.start = txtarea.sel_start; caretPos.end = txtarea.sel_start; From 4870387f3a63531a4921de37d24e6a5cc867da21 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Tue, 26 Mar 2013 11:19:03 +0100 Subject: [PATCH 051/281] [ticket/11314] Fix JSHint issues in adm editor.js This time without changing the behavior. PHPBB3-11314 --- phpBB/adm/style/editor.js | 69 +++++++++++++++++++-------------------- 1 file changed, 33 insertions(+), 36 deletions(-) diff --git a/phpBB/adm/style/editor.js b/phpBB/adm/style/editor.js index 2b814a10c6..a1c47c72ef 100644 --- a/phpBB/adm/style/editor.js +++ b/phpBB/adm/style/editor.js @@ -12,9 +12,8 @@ var theSelection = false; var clientPC = navigator.userAgent.toLowerCase(); // Get client info var clientVer = parseInt(navigator.appVersion, 10); // Get browser version -var is_ie = ((clientPC.indexOf('msie') != -1) && (clientPC.indexOf('opera') == -1)); -var is_win = ((clientPC.indexOf('win') != -1) || (clientPC.indexOf('16bit') != -1)); - +var is_ie = ((clientPC.indexOf('msie') !== -1) && (clientPC.indexOf('opera') === -1)); +var is_win = ((clientPC.indexOf('win') !== -1) || (clientPC.indexOf('16bit') !== -1)); var baseHeight; /** @@ -29,10 +28,11 @@ function helpline(help) * Fix a bug involving the TextRange object. From * http://www.frostjedi.com/terra/scripts/demo/caretBug.html */ -function initInsertions() +function initInsertions() { var doc; - if(document.forms[form_name]) + + if (document.forms[form_name]) { doc = document; } @@ -42,7 +42,8 @@ function initInsertions() } var textarea = doc.forms[form_name].elements[text_name]; - if (is_ie && typeof(baseHeight) != 'number') + + if (is_ie && typeof(baseHeight) !== 'number') { textarea.focus(); baseHeight = doc.selection.createRange().duplicate().boundingHeight; @@ -59,14 +60,14 @@ function initInsertions() */ function bbstyle(bbnumber) { - if (bbnumber != -1) + if (bbnumber !== -1) { bbfontstyle(bbtags[bbnumber], bbtags[bbnumber+1]); } else { insert_text('[*]'); - document.forms[form_name].elements[text_name].focus(); + document.forms[form_name].elements[text_name].focus(); } } @@ -76,7 +77,7 @@ function bbstyle(bbnumber) function bbfontstyle(bbopen, bbclose) { theSelection = false; - + var textarea = document.forms[form_name].elements[text_name]; textarea.focus(); @@ -102,10 +103,10 @@ function bbfontstyle(bbopen, bbclose) theSelection = ''; return; } - + //The new position for the cursor after adding the bbcode var caret_pos = getCaretPosition(textarea).start; - var new_pos = caret_pos + bbopen.length; + var new_pos = caret_pos + bbopen.length; // Open tag insert_text(bbopen + bbclose); @@ -116,7 +117,7 @@ function bbfontstyle(bbopen, bbclose) { textarea.selectionStart = new_pos; textarea.selectionEnd = new_pos; - } + } // IE else if (document.selection) { @@ -136,7 +137,7 @@ function bbfontstyle(bbopen, bbclose) function insert_text(text, spaces, popup) { var textarea; - + if (!popup) { textarea = document.forms[form_name].elements[text_name]; @@ -159,18 +160,17 @@ function insert_text(text, spaces, popup) mozWrap(textarea, text, ''); textarea.selectionStart = sel_start + text.length; textarea.selectionEnd = sel_end + text.length; - } - + } else if (textarea.createTextRange && textarea.caretPos) { - if (baseHeight != textarea.caretPos.boundingHeight) + if (baseHeight !== textarea.caretPos.boundingHeight) { textarea.focus(); storeCaret(textarea); } + var caret_pos = textarea.caretPos; - caret_pos.text = caret_pos.text.charAt(caret_pos.text.length - 1) == ' ' ? caret_pos.text + text + ' ' : caret_pos.text + text; - + caret_pos.text = caret_pos.text.charAt(caret_pos.text.length - 1) === ' ' ? caret_pos.text + text + ' ' : caret_pos.text + text; } else { @@ -181,7 +181,6 @@ function insert_text(text, spaces, popup) { textarea.focus(); } - } /** @@ -225,7 +224,7 @@ function addquote(post_id, username) theSelection = document.selection.createRange().text; } - if (theSelection == '' || typeof theSelection == 'undefined' || theSelection == null) + if (theSelection === '' || typeof theSelection === 'undefined' || theSelection === null) { if (divarea.innerHTML) { @@ -233,7 +232,7 @@ function addquote(post_id, username) theSelection = theSelection.replace(//ig, '\n'); theSelection = theSelection.replace(/<\;/ig, '<'); theSelection = theSelection.replace(/>\;/ig, '>'); - theSelection = theSelection.replace(/&\;/ig, '&'); + theSelection = theSelection.replace(/&\;/ig, '&'); theSelection = theSelection.replace(/ \;/ig, ' '); } else if (document.all) @@ -263,12 +262,12 @@ function addquote(post_id, username) */ function mozWrap(txtarea, open, close) { - var selLength = (typeof(txtarea.textLength) == 'undefined') ? txtarea.value.length : txtarea.textLength; + var selLength = (typeof(txtarea.textLength) === 'undefined') ? txtarea.value.length : txtarea.textLength; var selStart = txtarea.selectionStart; var selEnd = txtarea.selectionEnd; var scrollTop = txtarea.scrollTop; - if (selEnd == 1 || selEnd == 2) + if (selEnd === 1 || selEnd === 2) { selEnd = selLength; } @@ -317,18 +316,18 @@ function colorPalette(dir, width, height) for (r = 0; r < 5; r++) { - if (dir == 'h') + if (dir === 'h') { document.writeln(''); } for (g = 0; g < 5; g++) { - if (dir == 'v') + if (dir === 'v') { document.writeln(''); } - + for (b = 0; b < 5; b++) { color = String(numberList[r]) + String(numberList[g]) + String(numberList[b]); @@ -337,13 +336,13 @@ function colorPalette(dir, width, height) document.writeln(''); } - if (dir == 'v') + if (dir === 'v') { document.writeln(''); } } - if (dir == 'h') + if (dir === 'h') { document.writeln(''); } @@ -351,7 +350,6 @@ function colorPalette(dir, width, height) document.writeln(''); } - /** * Caret Position object */ @@ -361,16 +359,15 @@ function caretPosition() var end = null; } - /** * Get the caret position in an textarea */ function getCaretPosition(txtarea) { var caretPos = new caretPosition(); - + // simple Gecko/Opera way - if (txtarea.selectionStart || txtarea.selectionStart == 0) + if (txtarea.selectionStart || txtarea.selectionStart === 0) { caretPos.start = txtarea.selectionStart; caretPos.end = txtarea.selectionEnd; @@ -384,19 +381,19 @@ function getCaretPosition(txtarea) // a new selection of the whole textarea var range_all = document.body.createTextRange(); range_all.moveToElementText(txtarea); - + // calculate selection start point by moving beginning of range_all to beginning of range var sel_start; for (sel_start = 0; range_all.compareEndPoints('StartToStart', range) < 0; sel_start++) { range_all.moveStart('character', 1); } - + txtarea.sel_start = sel_start; - + // we ignore the end value for IE, this is already dirty enough and we don't need it caretPos.start = txtarea.sel_start; - caretPos.end = txtarea.sel_start; + caretPos.end = txtarea.sel_start; } return caretPos; From cdd45cb8ba4d420bfc44a9bb7a4c43662ec78156 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 26 Mar 2013 12:58:14 +0100 Subject: [PATCH 052/281] [ticket/11405] Move test to submit_post_base.php and use data sets for testing PHPBB3-11405 --- tests/notification/submit_post_base.php | 47 ++++++- .../submit_post_type_post_test.php | 99 +++++++-------- .../submit_post_type_quote_test.php | 120 +++++++++--------- 3 files changed, 155 insertions(+), 111 deletions(-) diff --git a/tests/notification/submit_post_base.php b/tests/notification/submit_post_base.php index 60d0e798cb..f458a4896a 100644 --- a/tests/notification/submit_post_base.php +++ b/tests/notification/submit_post_base.php @@ -16,6 +16,27 @@ class phpbb_notification_submit_post_base extends phpbb_database_test_case { protected $notifications, $db, $container, $user, $config, $auth, $cache; + protected $item_type = ''; + + protected $poll_data = array(); + protected $post_data = array( + 'forum_id' => 1, + 'topic_id' => 1, + 'topic_title' => 'topic_title', + 'icon_id' => 0, + 'enable_bbcode' => 0, + 'enable_smilies' => 0, + 'enable_urls' => 0, + 'enable_sig' => 0, + 'message' => '', + 'message_md5' => '', + 'attachment_data' => array(), + 'bbcode_bitfield' => '', + 'bbcode_uid' => '', + 'post_edit_locked' => false, + //'force_approved_state' => 1, + ); + public function getDataSet() { return $this->createXMLDataSet(dirname(__FILE__) . '/fixtures/submit_post_notification.xml'); @@ -81,7 +102,7 @@ class phpbb_notification_submit_post_base extends phpbb_database_test_case $phpbb_container->set('notification_manager', $phpbb_notifications); // Notification Types - $notification_types = array('quote', 'bookmark', 'post'); + $notification_types = array('quote', 'bookmark', 'post', 'post_in_queue'); foreach ($notification_types as $type) { $class_name = 'phpbb_notification_type_' . $type; @@ -91,4 +112,28 @@ class phpbb_notification_submit_post_base extends phpbb_database_test_case NOTIFICATION_TYPES_TABLE, NOTIFICATIONS_TABLE, USER_NOTIFICATIONS_TABLE)); } } + + /** + * @dataProvider submit_post_data + */ + public function test_submit_post($additional_post_data, $expected_before, $expected_after) + { + $sql = 'SELECT user_id, item_id, item_parent_id + FROM ' . NOTIFICATIONS_TABLE . " + WHERE item_type = '" . $this->item_type . "' + ORDER BY user_id, item_id ASC"; + $result = $this->db->sql_query($sql); + $this->assertEquals($expected_before, $this->db->sql_fetchrowset($result)); + $this->db->sql_freeresult($result); + + submit_post('reply', '', 'poster-name', POST_NORMAL, $this->poll_data, array_merge($this->post_data, $additional_post_data), false, false); + + $sql = 'SELECT user_id, item_id, item_parent_id + FROM ' . NOTIFICATIONS_TABLE . " + WHERE item_type = '" . $this->item_type . "' + ORDER BY user_id ASC, item_id ASC"; + $result = $this->db->sql_query($sql); + $this->assertEquals($expected_after, $this->db->sql_fetchrowset($result)); + $this->db->sql_freeresult($result); + } } diff --git a/tests/notification/submit_post_type_post_test.php b/tests/notification/submit_post_type_post_test.php index f439c49167..473247a764 100644 --- a/tests/notification/submit_post_type_post_test.php +++ b/tests/notification/submit_post_type_post_test.php @@ -11,6 +11,8 @@ require_once dirname(__FILE__) . '/submit_post_base.php'; class phpbb_notification_submit_post_type_post_test extends phpbb_notification_submit_post_base { + protected $item_type = 'post'; + public function setUp() { parent::setUp(); @@ -42,62 +44,53 @@ class phpbb_notification_submit_post_type_post_test extends phpbb_notification_s * * submit_post() $mode = 'reply' * Notification item_type = 'post' - * - * User => State description - * 2 => Poster, should NOT receive a notification - * 3 => Topic subscribed, should receive a notification - * 4 => Topic subscribed, but unauthed to read, should NOT receive a notification - * 5 => Topic subscribed, but already notified, should NOT receive a new notification - * 6 => Topic and forum subscribed, should receive ONE notification - * 7 => Forum subscribed, should receive a notification - * 8 => Forum subscribed, but already notified, should NOT receive a new notification */ - public function test_type_post() + public function submit_post_data() { - $sql = 'SELECT user_id, item_id, item_parent_id - FROM ' . NOTIFICATIONS_TABLE . " - WHERE item_type = 'post' - ORDER BY user_id, item_id ASC"; - $result = $this->db->sql_query($sql); - $this->assertEquals(array( - array('user_id' => 5, 'item_id' => 1, 'item_parent_id' => 1), - array('user_id' => 8, 'item_id' => 1, 'item_parent_id' => 1), - ), $this->db->sql_fetchrowset($result)); - $this->db->sql_freeresult($result); + return array( + /** + * Normal post + * + * User => State description + * 2 => Poster, should NOT receive a notification + * 3 => Topic subscribed, should receive a notification + * 4 => Topic subscribed, but unauthed to read, should NOT receive a notification + * 5 => Topic subscribed, but already notified, should NOT receive a new notification + * 6 => Topic and forum subscribed, should receive ONE notification + * 7 => Forum subscribed, should receive a notification + * 8 => Forum subscribed, but already notified, should NOT receive a new notification + */ + array( + array(), + array( + array('user_id' => 5, 'item_id' => 1, 'item_parent_id' => 1), + array('user_id' => 8, 'item_id' => 1, 'item_parent_id' => 1), + ), + array( + array('user_id' => 3, 'item_id' => 2, 'item_parent_id' => 1), + array('user_id' => 5, 'item_id' => 1, 'item_parent_id' => 1), + array('user_id' => 6, 'item_id' => 2, 'item_parent_id' => 1), + array('user_id' => 7, 'item_id' => 2, 'item_parent_id' => 1), + array('user_id' => 8, 'item_id' => 1, 'item_parent_id' => 1), + ), + ), - $poll = array(); - $data = array( - 'forum_id' => 1, - 'topic_id' => 1, - 'topic_title' => 'topic_title', - 'icon_id' => 0, - 'enable_bbcode' => 0, - 'enable_smilies' => 0, - 'enable_urls' => 0, - 'enable_sig' => 0, - 'message' => '', - 'message_md5' => '', - 'attachment_data' => array(), - 'bbcode_bitfield' => '', - 'bbcode_uid' => '', - 'post_edit_locked' => false, - //'force_approved_state' => 1, + /** + * Unapproved post + * + * No new notifications + */ + array( + array('force_approved_state' => false), + array( + array('user_id' => 5, 'item_id' => 1, 'item_parent_id' => 1), + array('user_id' => 8, 'item_id' => 1, 'item_parent_id' => 1), + ), + array( + array('user_id' => 5, 'item_id' => 1, 'item_parent_id' => 1), + array('user_id' => 8, 'item_id' => 1, 'item_parent_id' => 1), + ), + ), ); - - submit_post('reply', '', 'poster-name', POST_NORMAL, $poll, $data, false, false); - - $sql = 'SELECT user_id, item_id, item_parent_id - FROM ' . NOTIFICATIONS_TABLE . " - WHERE item_type = 'post' - ORDER BY user_id ASC, item_id ASC"; - $result = $this->db->sql_query($sql); - $this->assertEquals(array( - array('user_id' => 3, 'item_id' => 2, 'item_parent_id' => 1), - array('user_id' => 5, 'item_id' => 1, 'item_parent_id' => 1), - array('user_id' => 6, 'item_id' => 2, 'item_parent_id' => 1), - array('user_id' => 7, 'item_id' => 2, 'item_parent_id' => 1), - array('user_id' => 8, 'item_id' => 1, 'item_parent_id' => 1), - ), $this->db->sql_fetchrowset($result)); - $this->db->sql_freeresult($result); } } diff --git a/tests/notification/submit_post_type_quote_test.php b/tests/notification/submit_post_type_quote_test.php index 9b2323f770..2b66d9c6a1 100644 --- a/tests/notification/submit_post_type_quote_test.php +++ b/tests/notification/submit_post_type_quote_test.php @@ -11,6 +11,8 @@ require_once dirname(__FILE__) . '/submit_post_base.php'; class phpbb_notification_submit_post_type_quote_test extends phpbb_notification_submit_post_base { + protected $item_type = 'quote'; + public function setUp() { parent::setUp(); @@ -42,66 +44,70 @@ class phpbb_notification_submit_post_type_quote_test extends phpbb_notification_ * * submit_post() $mode = 'reply' * Notification item_type = 'quote' - * - * User => State description - * 2 => Poster, should NOT receive a notification - * 3 => Quoted, should receive a notification - * 4 => Quoted, but unauthed to read, should NOT receive a notification - * 5 => Quoted, but already notified, should NOT receive a new notification - * 6 => Quoted, but option disabled, should NOT receive a notification - * 7 => Quoted, option set to default, should receive a notification */ - public function test_type_quote() + public function submit_post_data() { - $sql = 'SELECT user_id, item_id, item_parent_id - FROM ' . NOTIFICATIONS_TABLE . " - WHERE item_type = 'quote' - ORDER BY user_id, item_id ASC"; - $result = $this->db->sql_query($sql); - $this->assertEquals(array( - array('user_id' => 5, 'item_id' => 1, 'item_parent_id' => 1), - ), $this->db->sql_fetchrowset($result)); - $this->db->sql_freeresult($result); + return array( + /** + * Normal post + * + * User => State description + * 2 => Poster, should NOT receive a notification + * 3 => Quoted, should receive a notification + * 4 => Quoted, but unauthed to read, should NOT receive a notification + * 5 => Quoted, but already notified, should NOT receive a new notification + * 6 => Quoted, but option disabled, should NOT receive a notification + * 7 => Quoted, option set to default, should receive a notification + */ + array( + array( + 'message' => implode(' ', array( + '[quote="poster":uid]poster should not be notified[/quote:uid]', + '[quote="test":uid]test should be notified[/quote:uid]', + '[quote="unauthorized":uid]unauthorized to read, should not receive a notification[/quote:uid]', + '[quote="notified":uid]already notified, should not receive a new notification[/quote:uid]', + '[quote="disabled":uid]option disabled, should not receive a notification[/quote:uid]', + '[quote="default":uid]option set to default, should receive a notification[/quote:uid]', + '[quote="doesn\'t exist":uid]user does not exist, should not receive a notification[/quote:uid]', + )), + 'bbcode_uid' => 'uid', + ), + array( + array('user_id' => 5, 'item_id' => 1, 'item_parent_id' => 1), + ), + array( + array('user_id' => 3, 'item_id' => 2, 'item_parent_id' => 1), + array('user_id' => 5, 'item_id' => 1, 'item_parent_id' => 1), + array('user_id' => 7, 'item_id' => 2, 'item_parent_id' => 1), + ), + ), - $poll = array(); - $data = array( - 'forum_id' => 1, - 'topic_id' => 1, - 'topic_title' => 'topic_title', - 'icon_id' => 0, - 'enable_bbcode' => 0, - 'enable_smilies' => 0, - 'enable_urls' => 0, - 'enable_sig' => 0, - 'message' => implode(' ', array( - '[quote="poster":uid]poster should not be notified[/quote:uid]', - '[quote="test":uid]test should be notified[/quote:uid]', - '[quote="unauthorized":uid]unauthorized to read, should not receive a notification[/quote:uid]', - '[quote="notified":uid]already notified, should not receive a new notification[/quote:uid]', - '[quote="disabled":uid]option disabled, should not receive a notification[/quote:uid]', - '[quote="default":uid]option set to default, should receive a notification[/quote:uid]', - '[quote="doesn\'t exist":uid]user does not exist, should not receive a notification[/quote:uid]', - )), - 'message_md5' => '', - 'attachment_data' => array(), - 'bbcode_bitfield' => '', - 'bbcode_uid' => 'uid', - 'post_edit_locked' => false, - //'force_approved_state' => 1, + /** + * Unapproved post + * + * No new notifications + */ + array( + array( + 'message' => implode(' ', array( + '[quote="poster":uid]poster should not be notified[/quote:uid]', + '[quote="test":uid]test should be notified[/quote:uid]', + '[quote="unauthorized":uid]unauthorized to read, should not receive a notification[/quote:uid]', + '[quote="notified":uid]already notified, should not receive a new notification[/quote:uid]', + '[quote="disabled":uid]option disabled, should not receive a notification[/quote:uid]', + '[quote="default":uid]option set to default, should receive a notification[/quote:uid]', + '[quote="doesn\'t exist":uid]user does not exist, should not receive a notification[/quote:uid]', + )), + 'bbcode_uid' => 'uid', + 'force_approved_state' => false, + ), + array( + array('user_id' => 5, 'item_id' => 1, 'item_parent_id' => 1), + ), + array( + array('user_id' => 5, 'item_id' => 1, 'item_parent_id' => 1), + ), + ), ); - - submit_post('reply', '', 'poster-name', POST_NORMAL, $poll, $data, false, false); - - $sql = 'SELECT user_id, item_id, item_parent_id - FROM ' . NOTIFICATIONS_TABLE . " - WHERE item_type = 'quote' - ORDER BY user_id ASC, item_id ASC"; - $result = $this->db->sql_query($sql); - $this->assertEquals(array( - array('user_id' => 3, 'item_id' => 2, 'item_parent_id' => 1), - array('user_id' => 5, 'item_id' => 1, 'item_parent_id' => 1), - array('user_id' => 7, 'item_id' => 2, 'item_parent_id' => 1), - ), $this->db->sql_fetchrowset($result)); - $this->db->sql_freeresult($result); } } From 7e2f80ec0ab69c512383602c42b84db1c767180e Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 26 Mar 2013 12:59:35 +0100 Subject: [PATCH 053/281] [ticket/11405] Add unit tests for bookmarking PHPBB3-11405 --- .../fixtures/submit_post_notification.xml | 75 ++++++++++++++++ .../submit_post_type_bookmark_test.php | 90 +++++++++++++++++++ 2 files changed, 165 insertions(+) create mode 100644 tests/notification/submit_post_type_bookmark_test.php diff --git a/tests/notification/fixtures/submit_post_notification.xml b/tests/notification/fixtures/submit_post_notification.xml index 51dd2f8dbd..3f46bc2962 100644 --- a/tests/notification/fixtures/submit_post_notification.xml +++ b/tests/notification/fixtures/submit_post_notification.xml @@ -1,5 +1,33 @@ + + topic_id + user_id + + 1 + 2 + + + 1 + 3 + + + 1 + 4 + + + 1 + 5 + + + 1 + 6 + + + 1 + 7 + +
    forum_iduser_id @@ -43,6 +71,14 @@ 0 + + bookmark + 5 + 1 + 1 + 0 + + post 8 @@ -63,6 +99,10 @@ quote 1 + + bookmark + 1 +
    post_id @@ -190,6 +230,13 @@ 1 + + bookmark + 0 + 2 + + 1 + post 0 @@ -204,6 +251,13 @@ 1 + + bookmark + 0 + 3 + + 1 + post 0 @@ -218,6 +272,13 @@ 1 + + bookmark + 0 + 4 + + 1 + post 0 @@ -232,6 +293,13 @@ 1 + + bookmark + 0 + 5 + + 1 + post 0 @@ -246,6 +314,13 @@ 0 + + bookmark + 0 + 6 + + 0 + post 0 diff --git a/tests/notification/submit_post_type_bookmark_test.php b/tests/notification/submit_post_type_bookmark_test.php new file mode 100644 index 0000000000..861017ff5f --- /dev/null +++ b/tests/notification/submit_post_type_bookmark_test.php @@ -0,0 +1,90 @@ +expects($this->any()) + ->method('acl_get_list') + ->with($this->anything(), + $this->stringContains('_'), + $this->greaterThan(0)) + ->will($this->returnValueMap(array( + array( + array('3', '4', '5', '6', '7'), + 'f_read', + 1, + array( + 1 => array( + 'f_read' => array(3, 5, 6, 7), + ), + ), + ), + ))); + } + + /** + * submit_post() Notifications test + * + * submit_post() $mode = 'reply' + * Notification item_type = 'bookmark' + */ + public function submit_post_data() + { + return array( + /** + * Normal post + * + * User => State description + * 2 => Poster, should NOT receive a notification + * 3 => Bookmarked, should receive a notification + * 4 => Bookmarked, but unauthed to read, should NOT receive a notification + * 5 => Bookmarked, but already notified, should NOT receive a new notification + * 6 => Bookmarked, but option disabled, should NOT receive a notification + * 7 => Bookmarked, option set to default, should receive a notification + */ + array( + array(), + array( + array('user_id' => 5, 'item_id' => 1, 'item_parent_id' => 1), + ), + array( + array('user_id' => 3, 'item_id' => 2, 'item_parent_id' => 1), + array('user_id' => 5, 'item_id' => 1, 'item_parent_id' => 1), + array('user_id' => 7, 'item_id' => 2, 'item_parent_id' => 1), + ), + ), + + /** + * Unapproved post + * + * No new notifications + */ + array( + array('force_approved_state' => false), + array( + array('user_id' => 5, 'item_id' => 1, 'item_parent_id' => 1), + ), + array( + array('user_id' => 5, 'item_id' => 1, 'item_parent_id' => 1), + ), + ), + ); + } +} From e20b0a423474eb6f4dce362283ae2ebb3d3e0f8d Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 26 Mar 2013 13:06:04 +0100 Subject: [PATCH 054/281] [ticket/11405] Use different fixtures so it's not a total mess PHPBB3-11405 --- .../fixtures/submit_post_bookmark.xml | 173 ++++++++++++++++++ ..._notification.xml => submit_post_post.xml} | 122 ------------ .../fixtures/submit_post_quote.xml | 145 +++++++++++++++ tests/notification/submit_post_base.php | 2 +- 4 files changed, 319 insertions(+), 123 deletions(-) create mode 100644 tests/notification/fixtures/submit_post_bookmark.xml rename tests/notification/fixtures/{submit_post_notification.xml => submit_post_post.xml} (66%) create mode 100644 tests/notification/fixtures/submit_post_quote.xml diff --git a/tests/notification/fixtures/submit_post_bookmark.xml b/tests/notification/fixtures/submit_post_bookmark.xml new file mode 100644 index 0000000000..b669d4c1b6 --- /dev/null +++ b/tests/notification/fixtures/submit_post_bookmark.xml @@ -0,0 +1,173 @@ + + +
    + topic_id + user_id + + 1 + 2 + + + 1 + 3 + + + 1 + 4 + + + 1 + 5 + + + 1 + 6 + + + 1 + 7 + +
    + + item_type + user_id + item_id + item_parent_id + notification_read + notification_data + + bookmark + 5 + 1 + 1 + 0 + + +
    + + notification_type + notification_type_enabled + + bookmark + 1 + +
    + + post_id + topic_id + forum_id + post_text + + 1 + 1 + 1 + + +
    + + topic_id + forum_id + + 1 + 1 + +
    + + user_id + username_clean + user_permissions + user_sig + user_occ + user_interests + + 2 + poster + + + + + + + 3 + test + + + + + + + 4 + unauthorized + + + + + + + 5 + notified + + + + + + + 6 + disabled + + + + + + + 7 + default + + + + + +
    + + item_type + item_id + user_id + method + notify + + bookmark + 0 + 2 + + 1 + + + bookmark + 0 + 3 + + 1 + + + bookmark + 0 + 4 + + 1 + + + bookmark + 0 + 5 + + 1 + + + bookmark + 0 + 6 + + 0 + +
    +
    diff --git a/tests/notification/fixtures/submit_post_notification.xml b/tests/notification/fixtures/submit_post_post.xml similarity index 66% rename from tests/notification/fixtures/submit_post_notification.xml rename to tests/notification/fixtures/submit_post_post.xml index 3f46bc2962..cead4f7c26 100644 --- a/tests/notification/fixtures/submit_post_notification.xml +++ b/tests/notification/fixtures/submit_post_post.xml @@ -1,33 +1,5 @@ - - topic_id - user_id - - 1 - 2 - - - 1 - 3 - - - 1 - 4 - - - 1 - 5 - - - 1 - 6 - - - 1 - 7 - -
    forum_iduser_id @@ -63,22 +35,6 @@ 0 - - quote - 5 - 1 - 1 - 0 - - - - bookmark - 5 - 1 - 1 - 0 - - post 8 @@ -95,14 +51,6 @@ post 1 - - quote - 1 - - - bookmark - 1 -
    post_id @@ -223,20 +171,6 @@ 1 - - quote - 0 - 2 - - 1 - - - bookmark - 0 - 2 - - 1 - post 0 @@ -244,20 +178,6 @@ 1 - - quote - 0 - 3 - - 1 - - - bookmark - 0 - 3 - - 1 - post 0 @@ -265,20 +185,6 @@ 1 - - quote - 0 - 4 - - 1 - - - bookmark - 0 - 4 - - 1 - post 0 @@ -286,20 +192,6 @@ 1 - - quote - 0 - 5 - - 1 - - - bookmark - 0 - 5 - - 1 - post 0 @@ -307,20 +199,6 @@ 1 - - quote - 0 - 6 - - 0 - - - bookmark - 0 - 6 - - 0 - post 0 diff --git a/tests/notification/fixtures/submit_post_quote.xml b/tests/notification/fixtures/submit_post_quote.xml new file mode 100644 index 0000000000..884a84af4a --- /dev/null +++ b/tests/notification/fixtures/submit_post_quote.xml @@ -0,0 +1,145 @@ + + +
    + item_type + user_id + item_id + item_parent_id + notification_read + notification_data + + quote + 5 + 1 + 1 + 0 + + +
    + + notification_type + notification_type_enabled + + quote + 1 + +
    + + post_id + topic_id + forum_id + post_text + + 1 + 1 + 1 + + +
    + + topic_id + forum_id + + 1 + 1 + +
    + + user_id + username_clean + user_permissions + user_sig + user_occ + user_interests + + 2 + poster + + + + + + + 3 + test + + + + + + + 4 + unauthorized + + + + + + + 5 + notified + + + + + + + 6 + disabled + + + + + + + 7 + default + + + + + +
    + + item_type + item_id + user_id + method + notify + + quote + 0 + 2 + + 1 + + + quote + 0 + 3 + + 1 + + + quote + 0 + 4 + + 1 + + + quote + 0 + 5 + + 1 + + + quote + 0 + 6 + + 0 + +
    +
    diff --git a/tests/notification/submit_post_base.php b/tests/notification/submit_post_base.php index f458a4896a..d306e3f381 100644 --- a/tests/notification/submit_post_base.php +++ b/tests/notification/submit_post_base.php @@ -39,7 +39,7 @@ class phpbb_notification_submit_post_base extends phpbb_database_test_case public function getDataSet() { - return $this->createXMLDataSet(dirname(__FILE__) . '/fixtures/submit_post_notification.xml'); + return $this->createXMLDataSet(dirname(__FILE__) . '/fixtures/submit_post_' . $this->item_type . '.xml'); } public function setUp() From f0b0978538a1b1e25b688cce1794c764f2d363f0 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Tue, 26 Mar 2013 13:13:33 +0100 Subject: [PATCH 055/281] [ticket/11314] Modify files to comply with coding standards PHPBB3-11314 --- phpBB/adm/style/editor.js | 172 +++++----------- phpBB/adm/style/permissions.js | 183 ++++++----------- phpBB/adm/style/tooltip.js | 102 +++------- phpBB/assets/javascript/core.js | 5 +- phpBB/styles/prosilver/template/ajax.js | 9 +- phpBB/styles/prosilver/template/editor.js | 211 ++++++-------------- phpBB/styles/prosilver/template/forum_fn.js | 193 ++++++------------ phpBB/styles/subsilver2/template/editor.js | 211 ++++++-------------- 8 files changed, 352 insertions(+), 734 deletions(-) diff --git a/phpBB/adm/style/editor.js b/phpBB/adm/style/editor.js index a1c47c72ef..9938ff5d0b 100644 --- a/phpBB/adm/style/editor.js +++ b/phpBB/adm/style/editor.js @@ -19,8 +19,7 @@ var baseHeight; /** * Shows the help messages in the helpline window */ -function helpline(help) -{ +function helpline(help) { document.forms[form_name].helpbox.value = help_line[help]; } @@ -28,28 +27,22 @@ function helpline(help) * Fix a bug involving the TextRange object. From * http://www.frostjedi.com/terra/scripts/demo/caretBug.html */ -function initInsertions() -{ +function initInsertions() { var doc; - if (document.forms[form_name]) - { + if (document.forms[form_name]) { doc = document; - } - else - { + } else { doc = opener.document; } var textarea = doc.forms[form_name].elements[text_name]; - if (is_ie && typeof(baseHeight) !== 'number') - { + if (is_ie && typeof(baseHeight) !== 'number') { textarea.focus(); baseHeight = doc.selection.createRange().duplicate().boundingHeight; - if (!document.forms[form_name]) - { + if (!document.forms[form_name]) { document.body.focus(); } } @@ -58,14 +51,10 @@ function initInsertions() /** * bbstyle */ -function bbstyle(bbnumber) -{ - if (bbnumber !== -1) - { +function bbstyle(bbnumber) { + if (bbnumber !== -1) { bbfontstyle(bbtags[bbnumber], bbtags[bbnumber+1]); - } - else - { + } else { insert_text('[*]'); document.forms[form_name].elements[text_name].focus(); } @@ -74,30 +63,26 @@ function bbstyle(bbnumber) /** * Apply bbcodes */ -function bbfontstyle(bbopen, bbclose) -{ +function bbfontstyle(bbopen, bbclose) { theSelection = false; var textarea = document.forms[form_name].elements[text_name]; textarea.focus(); - if ((clientVer >= 4) && is_ie && is_win) - { + if ((clientVer >= 4) && is_ie && is_win) { // Get text selection theSelection = document.selection.createRange().text; - if (theSelection) - { + if (theSelection) { // Add tags around selection document.selection.createRange().text = bbopen + theSelection + bbclose; document.forms[form_name].elements[text_name].focus(); theSelection = ''; return; } - } - else if (document.forms[form_name].elements[text_name].selectionEnd && (document.forms[form_name].elements[text_name].selectionEnd - document.forms[form_name].elements[text_name].selectionStart > 0)) - { + } else if (document.forms[form_name].elements[text_name].selectionEnd + && (document.forms[form_name].elements[text_name].selectionEnd - document.forms[form_name].elements[text_name].selectionStart > 0)) { mozWrap(document.forms[form_name].elements[text_name], bbopen, bbclose); document.forms[form_name].elements[text_name].focus(); theSelection = ''; @@ -113,14 +98,12 @@ function bbfontstyle(bbopen, bbclose) // Center the cursor when we don't have a selection // Gecko and proper browsers - if (!isNaN(textarea.selectionStart)) - { + if (!isNaN(textarea.selectionStart)) { textarea.selectionStart = new_pos; textarea.selectionEnd = new_pos; } // IE - else if (document.selection) - { + else if (document.selection) { var range = textarea.createTextRange(); range.move("character", new_pos); range.select(); @@ -134,51 +117,39 @@ function bbfontstyle(bbopen, bbclose) /** * Insert text at position */ -function insert_text(text, spaces, popup) -{ +function insert_text(text, spaces, popup) { var textarea; - if (!popup) - { + if (!popup) { textarea = document.forms[form_name].elements[text_name]; - } - else - { + } else { textarea = opener.document.forms[form_name].elements[text_name]; } - if (spaces) - { + if (spaces) { text = ' ' + text + ' '; } - if (!isNaN(textarea.selectionStart)) - { + if (!isNaN(textarea.selectionStart)) { var sel_start = textarea.selectionStart; var sel_end = textarea.selectionEnd; mozWrap(textarea, text, ''); textarea.selectionStart = sel_start + text.length; textarea.selectionEnd = sel_end + text.length; - } - else if (textarea.createTextRange && textarea.caretPos) - { - if (baseHeight !== textarea.caretPos.boundingHeight) - { + } else if (textarea.createTextRange && textarea.caretPos) { + if (baseHeight !== textarea.caretPos.boundingHeight) { textarea.focus(); storeCaret(textarea); } var caret_pos = textarea.caretPos; caret_pos.text = caret_pos.text.charAt(caret_pos.text.length - 1) === ' ' ? caret_pos.text + text + ' ' : caret_pos.text + text; - } - else - { + } else { textarea.value = textarea.value + text; } - if (!popup) - { + if (!popup) { textarea.focus(); } } @@ -186,8 +157,7 @@ function insert_text(text, spaces, popup) /** * Add inline attachment at position */ -function attach_inline(index, filename) -{ +function attach_inline(index, filename) { insert_text('[attachment=' + index + ']' + filename + '[/attachment]'); document.forms[form_name].elements[text_name].focus(); } @@ -201,56 +171,39 @@ function addquote(post_id, username) var theSelection = ''; var divarea = false; - if (document.all) - { + if (document.all) { divarea = document.all[message_name]; - } - else - { + } else { divarea = document.getElementById(message_name); } // Get text selection - not only the post content :( - if (window.getSelection) - { + if (window.getSelection) { theSelection = window.getSelection().toString(); - } - else if (document.getSelection) - { + } else if (document.getSelection) { theSelection = document.getSelection(); - } - else if (document.selection) - { + } else if (document.selection) { theSelection = document.selection.createRange().text; } - if (theSelection === '' || typeof theSelection === 'undefined' || theSelection === null) - { - if (divarea.innerHTML) - { + if (theSelection === '' || typeof theSelection === 'undefined' || theSelection === null) { + if (divarea.innerHTML) { theSelection = divarea.innerHTML.replace(/
    /ig, '\n'); theSelection = theSelection.replace(//ig, '\n'); theSelection = theSelection.replace(/<\;/ig, '<'); theSelection = theSelection.replace(/>\;/ig, '>'); theSelection = theSelection.replace(/&\;/ig, '&'); theSelection = theSelection.replace(/ \;/ig, ' '); - } - else if (document.all) - { + } else if (document.all) { theSelection = divarea.innerText; - } - else if (divarea.textContent) - { + } else if (divarea.textContent) { theSelection = divarea.textContent; - } - else if (divarea.firstChild.nodeValue) - { + } else if (divarea.firstChild.nodeValue) { theSelection = divarea.firstChild.nodeValue; } } - if (theSelection) - { + if (theSelection) { insert_text('[quote="' + username + '"]' + theSelection + '[/quote]'); } @@ -260,15 +213,13 @@ function addquote(post_id, username) /** * From http://www.massless.org/mozedit/ */ -function mozWrap(txtarea, open, close) -{ +function mozWrap(txtarea, open, close) { var selLength = (typeof(txtarea.textLength) === 'undefined') ? txtarea.value.length : txtarea.textLength; var selStart = txtarea.selectionStart; var selEnd = txtarea.selectionEnd; var scrollTop = txtarea.scrollTop; - if (selEnd === 1 || selEnd === 2) - { + if (selEnd === 1 || selEnd === 2) { selEnd = selLength; } @@ -289,10 +240,8 @@ function mozWrap(txtarea, open, close) * Insert at Caret position. Code from * http://www.faqts.com/knowledge_base/view.phtml/aid/1052/fid/130 */ -function storeCaret(textEl) -{ - if (textEl.createTextRange) - { +function storeCaret(textEl) { + if (textEl.createTextRange) { textEl.caretPos = document.selection.createRange().duplicate(); } } @@ -300,8 +249,7 @@ function storeCaret(textEl) /** * Color pallette */ -function colorPalette(dir, width, height) -{ +function colorPalette(dir, width, height) { var r = 0, g = 0, b = 0; var numberList = new Array(6); var color = ''; @@ -314,36 +262,29 @@ function colorPalette(dir, width, height) document.writeln(''); - for (r = 0; r < 5; r++) - { - if (dir === 'h') - { + for (r = 0; r < 5; r++) { + if (dir === 'h') { document.writeln(''); } - for (g = 0; g < 5; g++) - { - if (dir === 'v') - { + for (g = 0; g < 5; g++) { + if (dir === 'v') { document.writeln(''); } - for (b = 0; b < 5; b++) - { + for (b = 0; b < 5; b++) { color = String(numberList[r]) + String(numberList[g]) + String(numberList[b]); document.write(''); } - if (dir === 'v') - { + if (dir === 'v') { document.writeln(''); } } - if (dir === 'h') - { + if (dir === 'h') { document.writeln(''); } } @@ -353,8 +294,7 @@ function colorPalette(dir, width, height) /** * Caret Position object */ -function caretPosition() -{ +function caretPosition() { var start = null; var end = null; } @@ -362,19 +302,16 @@ function caretPosition() /** * Get the caret position in an textarea */ -function getCaretPosition(txtarea) -{ +function getCaretPosition(txtarea) { var caretPos = new caretPosition(); // simple Gecko/Opera way - if (txtarea.selectionStart || txtarea.selectionStart === 0) - { + if (txtarea.selectionStart || txtarea.selectionStart === 0) { caretPos.start = txtarea.selectionStart; caretPos.end = txtarea.selectionEnd; } // dirty and slow IE way - else if (document.selection) - { + else if (document.selection) { // get current selection var range = document.selection.createRange(); @@ -384,8 +321,7 @@ function getCaretPosition(txtarea) // calculate selection start point by moving beginning of range_all to beginning of range var sel_start; - for (sel_start = 0; range_all.compareEndPoints('StartToStart', range) < 0; sel_start++) - { + for (sel_start = 0; range_all.compareEndPoints('StartToStart', range) < 0; sel_start++) { range_all.moveStart('character', 1); } diff --git a/phpBB/adm/style/permissions.js b/phpBB/adm/style/permissions.js index 9210f864b2..1c85fbd9ef 100644 --- a/phpBB/adm/style/permissions.js +++ b/phpBB/adm/style/permissions.js @@ -2,35 +2,27 @@ * Hide and show all checkboxes * status = true (show boxes), false (hide boxes) */ -function display_checkboxes(status) -{ +function display_checkboxes(status) { var form = document.getElementById('set-permissions'); var cb = document.getElementsByTagName('input'); var display; //show - if (status) - { + if (status) { display = 'inline'; } //hide - else - { + else { display = 'none'; } - - for (var i = 0; i < cb.length; i++ ) - { - if (cb[i].className === 'permissions-checkbox') - { + + for (var i = 0; i < cb.length; i++ ) { + if (cb[i].className === 'permissions-checkbox') { cb[i].style.display = display; } - - } - + } } - /** * Change opacity of element * e = element @@ -38,7 +30,7 @@ function display_checkboxes(status) */ function set_opacity(e, value) { e.style.opacity = value/10; - + //IE opacity currently turned off, because of its astronomical stupidity //e.style.filter = 'alpha(opacity=' + value*10 + ')'; } @@ -50,13 +42,10 @@ function set_opacity(e, value) { function toggle_opacity(block_id) { var cb = document.getElementById('checkbox' + block_id); var fs = document.getElementById('perm' + block_id); - - if (cb.checked) - { + + if (cb.checked) { set_opacity(fs, 5); - } - else - { + } else { set_opacity(fs, 10); } } @@ -71,21 +60,17 @@ function reset_opacity(status, except_id) { var fs = perm.getElementsByTagName('fieldset'); var opacity = 5; - if (status) - { - opacity = 10; + if (status) { + opacity = 10; } - - for (var i = 0; i < fs.length; i++ ) - { - if (fs[i].className !== 'quick') - { + + for (var i = 0; i < fs.length; i++ ) { + if (fs[i].className !== 'quick') { set_opacity(fs[i], opacity); } } - if (typeof(except_id) !== 'undefined') - { + if (typeof(except_id) !== 'undefined') { set_opacity(document.getElementById('perm' + except_id), 10); } @@ -93,20 +78,15 @@ function reset_opacity(status, except_id) { marklist('set-permissions', 'inherit', !status); } - /** * Check whether we have a full radiobutton row of true * index = offset for the row of inputs (0 == first row, 1 == second, 2 == third), * rb = array of radiobuttons */ -function get_radio_status(index, rb) -{ - for (var i = index; i < rb.length; i = i + 3 ) - { - if (rb[i].checked !== true) - { - if (i > index) - { +function get_radio_status(index, rb) { + for (var i = index; i < rb.length; i = i + 3 ) { + if (rb[i].checked !== true) { + if (i > index) { //at least one is true, but not all (custom) return 2; } @@ -121,17 +101,15 @@ function get_radio_status(index, rb) /** * Set tab colours -* id = panel the tab needs to be set for, -* init = initialising on open, +* id = panel the tab needs to be set for, +* init = initialising on open, * quick = If no calculation needed, this contains the colour */ -function set_colours(id, init, quick) -{ +function set_colours(id, init, quick) { var table = document.getElementById('table' + id); var tab = document.getElementById('tab' + id); - if (typeof(quick) !== 'undefined') - { + if (typeof(quick) !== 'undefined') { tab.className = 'permissions-preset-' + quick + ' activetab'; return; } @@ -141,37 +119,27 @@ function set_colours(id, init, quick) var status = get_radio_status(0, rb); - if (status === 1) - { + if (status === 1) { colour = 'yes'; - } - else if (status === 0) - { + } else if (status === 0) { // We move on to No status = get_radio_status(1, rb); - if (status === 1) - { + if (status === 1) { colour = 'no'; - } - else if (status === 0) - { + } else if (status === 0) { // We move on to Never status = get_radio_status(2, rb); - if (status === 1) - { + if (status === 1) { colour = 'never'; } } } - if (init) - { + if (init) { tab.className = 'permissions-preset-' + colour; - } - else - { + } else { tab.className = 'permissions-preset-' + colour + ' activetab'; } } @@ -180,16 +148,13 @@ function set_colours(id, init, quick) * Initialise advanced tab colours on first load * block_id = block that is opened */ -function init_colours(block_id) -{ +function init_colours(block_id) { var block = document.getElementById('advanced' + block_id); var panels = block.getElementsByTagName('div'); var tab = document.getElementById('tab' + id); - for (var i = 0; i < panels.length; i++) - { - if(panels[i].className === 'permissions-panel') - { + for (var i = 0; i < panels.length; i++) { + if (panels[i].className === 'permissions-panel') { set_colours(panels[i].id.replace(/options/, ''), true); } } @@ -203,17 +168,15 @@ function init_colours(block_id) * adv = we are opening advanced permissions * view = called from view permissions */ -function swap_options(pmask, fmask, cat, adv, view) -{ +function swap_options(pmask, fmask, cat, adv, view) { id = pmask + fmask + cat; active_option = active_pmask + active_fmask + active_cat; - var old_tab = document.getElementById('tab' + active_option); + var old_tab = document.getElementById('tab' + active_option); var new_tab = document.getElementById('tab' + id); var adv_block = document.getElementById('advanced' + pmask + fmask); - if (adv_block.style.display === 'block' && adv === true) - { + if (adv_block.style.display === 'block' && adv === true) { dE('advanced' + pmask + fmask, -1); reset_opacity(1); display_checkboxes(false); @@ -221,20 +184,16 @@ function swap_options(pmask, fmask, cat, adv, view) } // no need to set anything if we are clicking on the same tab again - if (new_tab === old_tab && !adv) - { + if (new_tab === old_tab && !adv) { return; } // init colours - if (adv && (pmask + fmask) !== (active_pmask + active_fmask)) - { + if (adv && (pmask + fmask) !== (active_pmask + active_fmask)) { init_colours(pmask + fmask); display_checkboxes(true); reset_opacity(1); - } - else if (adv) - { + } else if (adv) { //Checkbox might have been clicked, but we need full visibility display_checkboxes(true); reset_opacity(1); @@ -244,31 +203,26 @@ function swap_options(pmask, fmask, cat, adv, view) old_tab.className = old_tab.className.replace(/\ activetab/g, ''); new_tab.className = new_tab.className + ' activetab'; - if (id === active_option && adv !== true) - { + if (id === active_option && adv !== true) { return; } dE('options' + active_option, -1); - + //hiding and showing the checkbox - if (document.getElementById('checkbox' + active_pmask + active_fmask)) - { - dE('checkbox' + pmask + fmask, -1); - - if ((pmask + fmask) !== (active_pmask + active_fmask)) - { + if (document.getElementById('checkbox' + active_pmask + active_fmask)) { + dE('checkbox' + pmask + fmask, -1); + + if ((pmask + fmask) !== (active_pmask + active_fmask)) { document.getElementById('checkbox' + active_pmask + active_fmask).style.display = 'inline'; } } - if (!view) - { + if (!view) { dE('advanced' + active_pmask + active_fmask, -1); } - if (!view) - { + if (!view) { dE('advanced' + pmask + fmask, 1); } dE('options' + id, 1); @@ -282,41 +236,33 @@ function swap_options(pmask, fmask, cat, adv, view) * Mark all radio buttons in one panel * id = table ID container, s = status ['y'/'u'/'n'] */ -function mark_options(id, s) -{ +function mark_options(id, s) { var t = document.getElementById(id); - if (!t) - { + if (!t) { return; } var rb = t.getElementsByTagName('input'); - for (var r = 0; r < rb.length; r++) - { - if (rb[r].id.substr(rb[r].id.length-1) === s) - { + for (var r = 0; r < rb.length; r++) { + if (rb[r].id.substr(rb[r].id.length-1) === s) { rb[r].checked = true; } } } -function mark_one_option(id, field_name, s) -{ +function mark_one_option(id, field_name, s) { var t = document.getElementById(id); - if (!t) - { + if (!t) { return; } var rb = t.getElementsByTagName('input'); - for (var r = 0; r < rb.length; r++) - { - if (rb[r].id.substr(rb[r].id.length-field_name.length-3, field_name.length) === field_name && rb[r].id.substr(rb[r].id.length-1) === s) - { + for (var r = 0; r < rb.length; r++) { + if (rb[r].id.substr(rb[r].id.length-field_name.length-3, field_name.length) === field_name && rb[r].id.substr(rb[r].id.length-1) === s) { rb[r].checked = true; } } @@ -325,12 +271,10 @@ function mark_one_option(id, field_name, s) /** * Reset role dropdown field to Select role... if an option gets changed */ -function reset_role(id) -{ +function reset_role(id) { var t = document.getElementById(id); - if (!t) - { + if (!t) { return; } @@ -340,20 +284,17 @@ function reset_role(id) /** * Load role and set options accordingly */ -function set_role_settings(role_id, target_id) -{ +function set_role_settings(role_id, target_id) { settings = role_options[role_id]; - if (!settings) - { + if (!settings) { return; } // Mark all options to no (unset) first... mark_options(target_id, 'u'); - for (var r in settings) - { + for (var r in settings) { mark_one_option(target_id, r, (settings[r] === 1) ? 'y' : 'n'); } } diff --git a/phpBB/adm/style/tooltip.js b/phpBB/adm/style/tooltip.js index 14f4772efa..3a89008706 100644 --- a/phpBB/adm/style/tooltip.js +++ b/phpBB/adm/style/tooltip.js @@ -1,6 +1,6 @@ /* javascript for Bubble Tooltips by Alessandro Fulciniti -- http://pro.html.it - http://web-graphics.com +- http://pro.html.it - http://web-graphics.com obtained from: http://web-graphics.com/mtarchive/001717.php phpBB Development Team: @@ -15,14 +15,12 @@ var head_text, tooltip_mode; /** * Enable tooltip replacements for links */ -function enable_tooltips_link(id, headline, sub_id) -{ +function enable_tooltips_link(id, headline, sub_id) { var links, i, hold; - + head_text = headline; - if (!document.getElementById || !document.getElementsByTagName) - { + if (!document.getElementById || !document.getElementsByTagName) { return; } @@ -33,26 +31,18 @@ function enable_tooltips_link(id, headline, sub_id) document.getElementsByTagName('body')[0].appendChild(hold); - if (id === null) - { + if (id === null) { links = document.getElementsByTagName('a'); - } - else - { + } else { links = document.getElementById(id).getElementsByTagName('a'); } - for (i = 0; i < links.length; i++) - { - if (sub_id) - { - if (links[i].id.substr(0, sub_id.length) === sub_id) - { + for (i = 0; i < links.length; i++) { + if (sub_id) { + if (links[i].id.substr(0, sub_id.length) === sub_id) { prepare(links[i]); } - } - else - { + } else { prepare(links[i]); } } @@ -63,14 +53,12 @@ function enable_tooltips_link(id, headline, sub_id) /** * Enable tooltip replacements for selects */ -function enable_tooltips_select(id, headline, sub_id) -{ +function enable_tooltips_select(id, headline, sub_id) { var links, i, hold; - + head_text = headline; - if (!document.getElementById || !document.getElementsByTagName) - { + if (!document.getElementById || !document.getElementsByTagName) { return; } @@ -81,26 +69,18 @@ function enable_tooltips_select(id, headline, sub_id) document.getElementsByTagName('body')[0].appendChild(hold); - if (id === null) - { + if (id === null) { links = document.getElementsByTagName('option'); - } - else - { + } else { links = document.getElementById(id).getElementsByTagName('option'); } - for (i = 0; i < links.length; i++) - { - if (sub_id) - { - if (links[i].parentNode.id.substr(0, sub_id.length) === sub_id) - { + for (i = 0; i < links.length; i++) { + if (sub_id) { + if (links[i].parentNode.id.substr(0, sub_id.length) === sub_id) { prepare(links[i]); } - } - else - { + } else { prepare(links[i]); } } @@ -111,14 +91,12 @@ function enable_tooltips_select(id, headline, sub_id) /** * Prepare elements to replace */ -function prepare(element) -{ +function prepare(element) { var tooltip, text, desc, title; text = element.getAttribute('title'); - if (text === null || text.length === 0) - { + if (text === null || text.length === 0) { return; } @@ -139,8 +117,7 @@ function prepare(element) element.onmouseover = show_tooltip; element.onmouseout = hide_tooltip; - if (tooltip_mode === 'link') - { + if (tooltip_mode === 'link') { element.onmousemove = locate; } } @@ -148,8 +125,7 @@ function prepare(element) /** * Show tooltip */ -function show_tooltip(e) -{ +function show_tooltip(e) { document.getElementById('_tooltip_container').appendChild(this.tooltip); locate(this); } @@ -157,11 +133,9 @@ function show_tooltip(e) /** * Hide tooltip */ -function hide_tooltip(e) -{ +function hide_tooltip(e) { var d = document.getElementById('_tooltip_container'); - if (d.childNodes.length > 0) - { + if (d.childNodes.length > 0) { d.removeChild(d.firstChild); } } @@ -169,8 +143,7 @@ function hide_tooltip(e) /** * Set opacity on tooltip element */ -function set_opacity(element) -{ +function set_opacity(element) { element.style.filter = 'alpha(opacity:95)'; element.style.KHTMLOpacity = '0.95'; element.style.MozOpacity = '0.95'; @@ -180,8 +153,7 @@ function set_opacity(element) /** * Create new element */ -function create_element(tag, c) -{ +function create_element(tag, c) { var x = document.createElement(tag); x.className = c; x.style.display = 'block'; @@ -191,34 +163,26 @@ function create_element(tag, c) /** * Correct positioning of tooltip container */ -function locate(e) -{ +function locate(e) { var posx = 0; var posy = 0; e = e.parentNode; - if (e.offsetParent) - { - for (posx = 0, posy = 0; e.offsetParent; e = e.offsetParent) - { + if (e.offsetParent) { + for (posx = 0, posy = 0; e.offsetParent; e = e.offsetParent) { posx += e.offsetLeft; posy += e.offsetTop; } - } - else - { + } else { posx = e.offsetLeft; posy = e.offsetTop; } - if (tooltip_mode === 'link') - { + if (tooltip_mode === 'link') { document.getElementById('_tooltip_container').style.top=(posy+20) + 'px'; document.getElementById('_tooltip_container').style.left=(posx-20) + 'px'; - } - else - { + } else { document.getElementById('_tooltip_container').style.top=(posy+30) + 'px'; document.getElementById('_tooltip_container').style.left=(posx-205) + 'px'; } diff --git a/phpBB/assets/javascript/core.js b/phpBB/assets/javascript/core.js index b718dabe6c..424989a9f3 100644 --- a/phpBB/assets/javascript/core.js +++ b/phpBB/assets/javascript/core.js @@ -57,7 +57,7 @@ phpbb.clearLoadingTimeout = function() { * @param string title Title of the message, eg "Information" (HTML). * @param string msg Message to display (HTML). * @param bool fadedark Remove the dark background when done? Defaults - * to yes. + * to yes. * * @returns object Returns the div created. */ @@ -353,8 +353,7 @@ phpbb.ajaxify = function(options) { return; } - if (overlay && (typeof $this.attr('data-overlay') === 'undefined' || $this.attr('data-overlay') === 'true')) - { + if (overlay && (typeof $this.attr('data-overlay') === 'undefined' || $this.attr('data-overlay') === 'true')) { phpbb.loadingAlert(); } diff --git a/phpBB/styles/prosilver/template/ajax.js b/phpBB/styles/prosilver/template/ajax.js index 8c61be5942..8dd1f58c97 100644 --- a/phpBB/styles/prosilver/template/ajax.js +++ b/phpBB/styles/prosilver/template/ajax.js @@ -189,19 +189,18 @@ phpbb.ajaxify({ refresh: true, filter: function (data) { var action = $('#quick-mod-select').val(); - var ret = false; if (action === 'make_normal') { - ret = $(this).find('select option[value="make_global"]').length > 0; + return $(this).find('select option[value="make_global"]').length > 0; } else if (action === 'lock' || action === 'unlock') { - ret = true; + return true; } if (action === 'delete_topic' || action === 'make_sticky' || action === 'make_announce' || action === 'make_global') { - ret = true; + return true; } - return ret; + return false; } }); diff --git a/phpBB/styles/prosilver/template/editor.js b/phpBB/styles/prosilver/template/editor.js index 13e9ca3c66..93506b8d4a 100644 --- a/phpBB/styles/prosilver/template/editor.js +++ b/phpBB/styles/prosilver/template/editor.js @@ -20,8 +20,7 @@ var baseHeight; /** * Shows the help messages in the helpline window */ -function helpline(help) -{ +function helpline(help) { document.forms[form_name].helpbox.value = help_line[help]; } @@ -29,28 +28,22 @@ function helpline(help) * Fix a bug involving the TextRange object. From * http://www.frostjedi.com/terra/scripts/demo/caretBug.html */ -function initInsertions() -{ +function initInsertions() { var doc; - if (document.forms[form_name]) - { + if (document.forms[form_name]) { doc = document; - } - else - { + } else { doc = opener.document; } var textarea = doc.forms[form_name].elements[text_name]; - if (is_ie && typeof(baseHeight) !== 'number') - { + if (is_ie && typeof(baseHeight) !== 'number') { textarea.focus(); baseHeight = doc.selection.createRange().duplicate().boundingHeight; - if (!document.forms[form_name]) - { + if (!document.forms[form_name]) { document.body.focus(); } } @@ -59,14 +52,10 @@ function initInsertions() /** * bbstyle */ -function bbstyle(bbnumber) -{ - if (bbnumber !== -1) - { +function bbstyle(bbnumber) { + if (bbnumber !== -1) { bbfontstyle(bbtags[bbnumber], bbtags[bbnumber+1]); - } - else - { + } else { insert_text('[*]'); document.forms[form_name].elements[text_name].focus(); } @@ -75,30 +64,26 @@ function bbstyle(bbnumber) /** * Apply bbcodes */ -function bbfontstyle(bbopen, bbclose) -{ +function bbfontstyle(bbopen, bbclose) { theSelection = false; var textarea = document.forms[form_name].elements[text_name]; textarea.focus(); - if ((clientVer >= 4) && is_ie && is_win) - { + if ((clientVer >= 4) && is_ie && is_win) { // Get text selection theSelection = document.selection.createRange().text; - if (theSelection) - { + if (theSelection) { // Add tags around selection document.selection.createRange().text = bbopen + theSelection + bbclose; document.forms[form_name].elements[text_name].focus(); theSelection = ''; return; } - } - else if (document.forms[form_name].elements[text_name].selectionEnd && (document.forms[form_name].elements[text_name].selectionEnd - document.forms[form_name].elements[text_name].selectionStart > 0)) - { + } else if (document.forms[form_name].elements[text_name].selectionEnd + && (document.forms[form_name].elements[text_name].selectionEnd - document.forms[form_name].elements[text_name].selectionStart > 0)) { mozWrap(document.forms[form_name].elements[text_name], bbopen, bbclose); document.forms[form_name].elements[text_name].focus(); theSelection = ''; @@ -114,14 +99,12 @@ function bbfontstyle(bbopen, bbclose) // Center the cursor when we don't have a selection // Gecko and proper browsers - if (!isNaN(textarea.selectionStart)) - { + if (!isNaN(textarea.selectionStart)) { textarea.selectionStart = new_pos; textarea.selectionEnd = new_pos; } // IE - else if (document.selection) - { + else if (document.selection) { var range = textarea.createTextRange(); range.move("character", new_pos); range.select(); @@ -135,53 +118,41 @@ function bbfontstyle(bbopen, bbclose) /** * Insert text at position */ -function insert_text(text, spaces, popup) -{ +function insert_text(text, spaces, popup) { var textarea; - if (!popup) - { + if (!popup) { textarea = document.forms[form_name].elements[text_name]; - } - else - { + } else { textarea = opener.document.forms[form_name].elements[text_name]; } - if (spaces) - { + if (spaces) { text = ' ' + text + ' '; } // Since IE9, IE also has textarea.selectionStart, but it still needs to be treated the old way. // Therefore we simply add a !is_ie here until IE fixes the text-selection completely. - if (!isNaN(textarea.selectionStart) && !is_ie) - { + if (!isNaN(textarea.selectionStart) && !is_ie) { var sel_start = textarea.selectionStart; var sel_end = textarea.selectionEnd; mozWrap(textarea, text, ''); textarea.selectionStart = sel_start + text.length; textarea.selectionEnd = sel_end + text.length; - } - else if (textarea.createTextRange && textarea.caretPos) - { - if (baseHeight !== textarea.caretPos.boundingHeight) - { + } else if (textarea.createTextRange && textarea.caretPos) { + if (baseHeight !== textarea.caretPos.boundingHeight) { textarea.focus(); storeCaret(textarea); } var caret_pos = textarea.caretPos; caret_pos.text = caret_pos.text.charAt(caret_pos.text.length - 1) === ' ' ? caret_pos.text + text + ' ' : caret_pos.text + text; - } - else - { + } else { textarea.value = textarea.value + text; } - if (!popup) - { + if (!popup) { textarea.focus(); } } @@ -189,8 +160,7 @@ function insert_text(text, spaces, popup) /** * Add inline attachment at position */ -function attach_inline(index, filename) -{ +function attach_inline(index, filename) { insert_text('[attachment=' + index + ']' + filename + '[/attachment]'); document.forms[form_name].elements[text_name].focus(); } @@ -198,80 +168,57 @@ function attach_inline(index, filename) /** * Add quote text to message */ -function addquote(post_id, username, l_wrote) -{ +function addquote(post_id, username, l_wrote) { var message_name = 'message_' + post_id; var theSelection = ''; var divarea = false; var i; - if (l_wrote === undefined) - { + if (l_wrote === undefined) { // Backwards compatibility l_wrote = 'wrote'; } - if (document.all) - { + if (document.all) { divarea = document.all[message_name]; - } - else - { + } else { divarea = document.getElementById(message_name); } // Get text selection - not only the post content :( // IE9 must use the document.selection method but has the *.getSelection so we just force no IE - if (window.getSelection && !is_ie && !window.opera) - { + if (window.getSelection && !is_ie && !window.opera) { theSelection = window.getSelection().toString(); - } - else if (document.getSelection && !is_ie) - { + } else if (document.getSelection && !is_ie) { theSelection = document.getSelection(); - } - else if (document.selection) - { + } else if (document.selection) { theSelection = document.selection.createRange().text; } - if (theSelection === '' || typeof theSelection === 'undefined' || theSelection === null) - { - if (divarea.innerHTML) - { + if (theSelection === '' || typeof theSelection === 'undefined' || theSelection === null) { + if (divarea.innerHTML) { theSelection = divarea.innerHTML.replace(/
    /ig, '\n'); theSelection = theSelection.replace(//ig, '\n'); theSelection = theSelection.replace(/<\;/ig, '<'); theSelection = theSelection.replace(/>\;/ig, '>'); theSelection = theSelection.replace(/&\;/ig, '&'); theSelection = theSelection.replace(/ \;/ig, ' '); - } - else if (document.all) - { + } else if (document.all) { theSelection = divarea.innerText; - } - else if (divarea.textContent) - { + } else if (divarea.textContent) { theSelection = divarea.textContent; - } - else if (divarea.firstChild.nodeValue) - { + } else if (divarea.firstChild.nodeValue) { theSelection = divarea.firstChild.nodeValue; } } - if (theSelection) - { - if (bbcodeEnabled) - { + if (theSelection) { + if (bbcodeEnabled) { insert_text('[quote="' + username + '"]' + theSelection + '[/quote]'); - } - else - { + } else { insert_text(username + ' ' + l_wrote + ':' + '\n'); var lines = split_lines(theSelection); - for (i = 0; i < lines.length; i++) - { + for (i = 0; i < lines.length; i++) { insert_text('> ' + lines[i] + '\n'); } } @@ -280,35 +227,26 @@ function addquote(post_id, username, l_wrote) return; } -function split_lines(text) -{ +function split_lines(text) { var lines = text.split('\n'); var splitLines = new Array(); var j = 0; var i; - for(i = 0; i < lines.length; i++) - { - if (lines[i].length <= 80) - { + for(i = 0; i < lines.length; i++) { + if (lines[i].length <= 80) { splitLines[j] = lines[i]; j++; - } - else - { + } else { var line = lines[i]; var splitAt; - do - { + do { splitAt = line.indexOf(' ', 80); - if (splitAt === -1) - { + if (splitAt === -1) { splitLines[j] = line; j++; - } - else - { + } else { splitLines[j] = line.substring(0, splitAt); line = line.substring(splitAt); j++; @@ -323,15 +261,13 @@ function split_lines(text) /** * From http://www.massless.org/mozedit/ */ -function mozWrap(txtarea, open, close) -{ +function mozWrap(txtarea, open, close) { var selLength = (typeof(txtarea.textLength) === 'undefined') ? txtarea.value.length : txtarea.textLength; var selStart = txtarea.selectionStart; var selEnd = txtarea.selectionEnd; var scrollTop = txtarea.scrollTop; - if (selEnd === 1 || selEnd === 2) - { + if (selEnd === 1 || selEnd === 2) { selEnd = selLength; } @@ -352,10 +288,8 @@ function mozWrap(txtarea, open, close) * Insert at Caret position. Code from * http://www.faqts.com/knowledge_base/view.phtml/aid/1052/fid/130 */ -function storeCaret(textEl) -{ - if (textEl.createTextRange) - { +function storeCaret(textEl) { + if (textEl.createTextRange) { textEl.caretPos = document.selection.createRange().duplicate(); } } @@ -363,8 +297,7 @@ function storeCaret(textEl) /** * Color pallette */ -function colorPalette(dir, width, height) -{ +function colorPalette(dir, width, height) { var r = 0, g = 0, b = 0; var numberList = new Array(6); var color = ''; @@ -377,36 +310,29 @@ function colorPalette(dir, width, height) document.writeln('
    '); document.write('#' + color + ''); document.writeln('
    '); - for (r = 0; r < 5; r++) - { - if (dir === 'h') - { + for (r = 0; r < 5; r++) { + if (dir === 'h') { document.writeln(''); } - for (g = 0; g < 5; g++) - { - if (dir === 'v') - { + for (g = 0; g < 5; g++) { + if (dir === 'v') { document.writeln(''); } - for (b = 0; b < 5; b++) - { + for (b = 0; b < 5; b++) { color = String(numberList[r]) + String(numberList[g]) + String(numberList[b]); document.write(''); } - if (dir === 'v') - { + if (dir === 'v') { document.writeln(''); } } - if (dir === 'h') - { + if (dir === 'h') { document.writeln(''); } } @@ -416,8 +342,7 @@ function colorPalette(dir, width, height) /** * Caret Position object */ -function caretPosition() -{ +function caretPosition() { var start = null; var end = null; } @@ -425,19 +350,16 @@ function caretPosition() /** * Get the caret position in an textarea */ -function getCaretPosition(txtarea) -{ +function getCaretPosition(txtarea) { var caretPos = new caretPosition(); // simple Gecko/Opera way - if (txtarea.selectionStart || txtarea.selectionStart === 0) - { + if (txtarea.selectionStart || txtarea.selectionStart === 0) { caretPos.start = txtarea.selectionStart; caretPos.end = txtarea.selectionEnd; } // dirty and slow IE way - else if (document.selection) - { + else if (document.selection) { // get current selection var range = document.selection.createRange(); @@ -447,8 +369,7 @@ function getCaretPosition(txtarea) // calculate selection start point by moving beginning of range_all to beginning of range var sel_start; - for (sel_start = 0; range_all.compareEndPoints('StartToStart', range) < 0; sel_start++) - { + for (sel_start = 0; range_all.compareEndPoints('StartToStart', range) < 0; sel_start++) { range_all.moveStart('character', 1); } diff --git a/phpBB/styles/prosilver/template/forum_fn.js b/phpBB/styles/prosilver/template/forum_fn.js index 677e9274c4..19fe5ca4d2 100644 --- a/phpBB/styles/prosilver/template/forum_fn.js +++ b/phpBB/styles/prosilver/template/forum_fn.js @@ -5,10 +5,8 @@ /** * Window popup */ -function popup(url, width, height, name) -{ - if (!name) - { +function popup(url, width, height, name) { + if (!name) { name = '_popup'; } @@ -19,18 +17,13 @@ function popup(url, width, height, name) /** * Jump to page */ -function jumpto() -{ +function jumpto() { var page = prompt(jump_page, on_page); - if (page !== null && !isNaN(page) && page === Math.floor(page) && page > 0) - { - if (base_url.indexOf('?') === -1) - { + if (page !== null && !isNaN(page) && page === Math.floor(page) && page > 0) { + if (base_url.indexOf('?') === -1) { document.location.href = base_url + '?start=' + ((page - 1) * per_page); - } - else - { + } else { document.location.href = base_url.replace(/&/g, '&') + '&start=' + ((page - 1) * per_page); } } @@ -40,21 +33,17 @@ function jumpto() * Mark/unmark checklist * id = ID of parent container, name = name prefix, state = state [true/false] */ -function marklist(id, name, state) -{ +function marklist(id, name, state) { var parent = document.getElementById(id) || document[id]; - if (!parent) - { + if (!parent) { return; } var rb = parent.getElementsByTagName('input'); - - for (var r = 0; r < rb.length; r++) - { - if (rb[r].name.substr(0, name.length) === name) - { + + for (var r = 0; r < rb.length; r++) { + if (rb[r].name.substr(0, name.length) === name) { rb[r].checked = state; } } @@ -64,28 +53,23 @@ function marklist(id, name, state) * Resize viewable area for attached image or topic review panel (possibly others to come) * e = element */ -function viewableArea(e, itself) -{ +function viewableArea(e, itself) { if (!e) { return; } - if (!itself) - { + if (!itself) { e = e.parentNode; } - - if (!e.vaHeight) - { + + if (!e.vaHeight) { // Store viewable area height before changing style to auto e.vaHeight = e.offsetHeight; e.vaMaxHeight = e.style.maxHeight; e.style.height = 'auto'; e.style.maxHeight = 'none'; e.style.overflow = 'visible'; - } - else - { + } else { // Restore viewable area height to the default e.style.height = e.vaHeight + 'px'; e.style.overflow = 'auto'; @@ -99,16 +83,13 @@ function viewableArea(e, itself) * s[-1,0,1] = hide,toggle display,show * type = string: inline, block, inline-block or other CSS "display" type */ -function dE(n, s, type) -{ - if (!type) - { +function dE(n, s, type) { + if (!type) { type = 'block'; } var e = document.getElementById(n); - if (!s) - { + if (!s) { s = (e.style.display === '' || e.style.display === type) ? -1 : 1; } e.style.display = (s === 1) ? type : 'none'; @@ -117,35 +98,26 @@ function dE(n, s, type) /** * Alternate display of subPanels */ -function subPanels(p) -{ +function subPanels(p) { var i, e, t; - if (typeof(p) === 'string') - { + if (typeof(p) === 'string') { show_panel = p; } - for (i = 0; i < panels.length; i++) - { + for (i = 0; i < panels.length; i++) { e = document.getElementById(panels[i]); t = document.getElementById(panels[i] + '-tab'); - if (e) - { - if (panels[i] === show_panel) - { + if (e) { + if (panels[i] === show_panel) { e.style.display = 'block'; - if (t) - { + if (t) { t.className = 'activetab'; } - } - else - { + } else { e.style.display = 'none'; - if (t) - { + if (t) { t.className = ''; } } @@ -156,14 +128,10 @@ function subPanels(p) /** * Call print preview */ -function printPage() -{ - if (is_ie) - { +function printPage() { + if (is_ie) { printPreview(); - } - else - { + } else { window.print(); } } @@ -172,49 +140,40 @@ function printPage() * 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) +* t = toggle dispay state (used to show 'grip-show' image in the profile block when hiding the profiles) */ -function displayBlocks(c, e, t) -{ +function displayBlocks(c, e, t) { var s = (e.checked === true) ? 1 : -1; - if (t) - { + if (t) { s *= -1; } var divs = document.getElementsByTagName("DIV"); - for (var d = 0; d < divs.length; d++) - { - if (divs[d].className.indexOf(c) === 0) - { + for (var d = 0; d < divs.length; d++) { + if (divs[d].className.indexOf(c) === 0) { divs[d].style.display = (s === 1) ? 'none' : 'block'; } } } -function selectCode(a) -{ +function selectCode(a) { // Get ID of code block var e = a.parentNode.parentNode.getElementsByTagName('CODE')[0]; var s, r; // Not IE and IE9+ - if (window.getSelection) - { + if (window.getSelection) { s = window.getSelection(); // Safari - if (s.setBaseAndExtent) - { + if (s.setBaseAndExtent) { s.setBaseAndExtent(e, 0, e, e.innerText.length - 1); } // Firefox and Opera - else - { + else { // workaround for bug # 42885 - if (window.opera && e.innerHTML.substring(e.innerHTML.length - 4) === '
    ') - { + if (window.opera && e.innerHTML.substring(e.innerHTML.length - 4) === '
    ') { e.innerHTML = e.innerHTML + ' '; } @@ -225,8 +184,7 @@ function selectCode(a) } } // Some older browsers - else if (document.getSelection) - { + else if (document.getSelection) { s = document.getSelection(); r = document.createRange(); r.selectNodeContents(e); @@ -234,8 +192,7 @@ function selectCode(a) s.addRange(r); } // IE - else if (document.selection) - { + else if (document.selection) { r = document.body.createTextRange(); r.moveToElementText(e); r.select(); @@ -246,13 +203,11 @@ function selectCode(a) * Play quicktime file by determining it's width/height * from the displayed rectangle area */ -function play_qt_file(obj) -{ +function play_qt_file(obj) { var rectangle = obj.GetRectangle(); var width, height; - if (rectangle) - { + if (rectangle) { rectangle = rectangle.split(','); var x1 = parseInt(rectangle[0], 10); var x2 = parseInt(rectangle[2], 10); @@ -261,9 +216,7 @@ function play_qt_file(obj) width = (x1 < 0) ? (x1 * -1) + x2 : x2 - x1; height = (y1 < 0) ? (y1 * -1) + y2 : y2 - y1; - } - else - { + } else { width = 200; height = 0; } @@ -279,8 +232,7 @@ function play_qt_file(obj) * Check if the nodeName of elem is name * @author jQuery */ -function is_node_name(elem, name) -{ +function is_node_name(elem, name) { return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase(); } @@ -288,8 +240,7 @@ function is_node_name(elem, name) * Check if elem is in array, return position * @author jQuery */ -function is_in_array(elem, array) -{ +function is_in_array(elem, array) { for (var i = 0, length = array.length; i < length; i++) { // === is correct (IE) if (array[i] === elem) { @@ -305,18 +256,16 @@ function is_in_array(elem, array) * Not used, but may come in handy for those not using JQuery * @author jQuery.find, Meik Sievertsen */ -function find_in_tree(node, tag, type, class_name) -{ +function find_in_tree(node, tag, type, class_name) { var result, element, i = 0, length = node.childNodes.length; - for (element = node.childNodes[0]; i < length; element = node.childNodes[++i]) - { + for (element = node.childNodes[0]; i < length; element = node.childNodes[++i]) { if (!element || element.nodeType !== 1) { continue; } - if ((!tag || is_node_name(element, tag)) && (!type || element.type === type) && (!class_name || is_in_array(class_name, (element.className || element).toString().split(/\s+/)) > -1)) - { + if ((!tag || is_node_name(element, tag)) && (!type || element.type === type) + && (!class_name || is_in_array(class_name, (element.className || element).toString().split(/\s+/)) > -1)) { return element; } @@ -336,27 +285,23 @@ var last_key_entered = ''; /** * Check event key */ -function phpbb_check_key(event) -{ +function phpbb_check_key(event) { // Keycode is array down or up? if (event.keyCode && (event.keyCode === 40 || event.keyCode === 38)) { in_autocomplete = true; } // Make sure we are not within an "autocompletion" field - if (in_autocomplete) - { + if (in_autocomplete) { // If return pressed and key changed we reset the autocompletion - if (!last_key_entered || last_key_entered === event.which) - { + if (!last_key_entered || last_key_entered === event.which) { in_autocompletion = false; return true; } } // Keycode is not return, then return. ;) - if (event.which !== 13) - { + if (event.which !== 13) { last_key_entered = event.which; return true; } @@ -367,8 +312,7 @@ function phpbb_check_key(event) /** * Usually used for onkeypress event, to submit a form on enter */ -function submit_default_button(event, selector, class_name) -{ +function submit_default_button(event, selector, class_name) { // Add which for key events if (!event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode)) { event.which = event.charCode || event.keyCode; @@ -390,8 +334,7 @@ function submit_default_button(event, selector, class_name) var input_tags = current.getElementsByTagName('input'); current = false; - for (var i = 0, element = input_tags[0]; i < input_tags.length; element = input_tags[++i]) - { + for (var i = 0, element = input_tags[0]; i < input_tags.length; element = input_tags[++i]) { if (element.type === 'submit' && is_in_array(class_name, (element.className || element).toString().split(/\s+/)) > -1) { current = element; } @@ -412,15 +355,12 @@ function submit_default_button(event, selector, class_name) * The jQuery snippet used is based on http://greatwebguy.com/programming/dom/default-html-button-submit-on-enter-with-jquery/ * The non-jQuery code is a mimick of the jQuery code ;) */ -function apply_onkeypress_event() -{ +function apply_onkeypress_event() { // jQuery code in case jQuery is used - if (jquery_present) - { - jQuery('form input[type=text], form input[type=password]').live('keypress', function (e) - { + if (jquery_present) { + jQuery('form input[type=text], form input[type=password]').live('keypress', function (e) { var default_button = jQuery(this).parents('form').find('input[type=submit].default-submit-action'); - + if (!default_button || default_button.length <= 0) { return true; } @@ -429,24 +369,21 @@ function apply_onkeypress_event() return true; } - if ((e.which && e.which === 13) || (e.keyCode && e.keyCode === 13)) - { + if ((e.which && e.which === 13) || (e.keyCode && e.keyCode === 13)) { default_button.click(); return false; } return true; }); - + return; } var input_tags = document.getElementsByTagName('input'); - for (var i = 0, element = input_tags[0]; i < input_tags.length ; element = input_tags[++i]) - { - if (element.type === 'text' || element.type === 'password') - { + for (var i = 0, element = input_tags[0]; i < input_tags.length ; element = input_tags[++i]) { + if (element.type === 'text' || element.type === 'password') { // onkeydown is possible too element.onkeypress = function (evt) { submit_default_button((evt || window.event), this, 'default-submit-action'); }; } diff --git a/phpBB/styles/subsilver2/template/editor.js b/phpBB/styles/subsilver2/template/editor.js index 13e9ca3c66..93506b8d4a 100644 --- a/phpBB/styles/subsilver2/template/editor.js +++ b/phpBB/styles/subsilver2/template/editor.js @@ -20,8 +20,7 @@ var baseHeight; /** * Shows the help messages in the helpline window */ -function helpline(help) -{ +function helpline(help) { document.forms[form_name].helpbox.value = help_line[help]; } @@ -29,28 +28,22 @@ function helpline(help) * Fix a bug involving the TextRange object. From * http://www.frostjedi.com/terra/scripts/demo/caretBug.html */ -function initInsertions() -{ +function initInsertions() { var doc; - if (document.forms[form_name]) - { + if (document.forms[form_name]) { doc = document; - } - else - { + } else { doc = opener.document; } var textarea = doc.forms[form_name].elements[text_name]; - if (is_ie && typeof(baseHeight) !== 'number') - { + if (is_ie && typeof(baseHeight) !== 'number') { textarea.focus(); baseHeight = doc.selection.createRange().duplicate().boundingHeight; - if (!document.forms[form_name]) - { + if (!document.forms[form_name]) { document.body.focus(); } } @@ -59,14 +52,10 @@ function initInsertions() /** * bbstyle */ -function bbstyle(bbnumber) -{ - if (bbnumber !== -1) - { +function bbstyle(bbnumber) { + if (bbnumber !== -1) { bbfontstyle(bbtags[bbnumber], bbtags[bbnumber+1]); - } - else - { + } else { insert_text('[*]'); document.forms[form_name].elements[text_name].focus(); } @@ -75,30 +64,26 @@ function bbstyle(bbnumber) /** * Apply bbcodes */ -function bbfontstyle(bbopen, bbclose) -{ +function bbfontstyle(bbopen, bbclose) { theSelection = false; var textarea = document.forms[form_name].elements[text_name]; textarea.focus(); - if ((clientVer >= 4) && is_ie && is_win) - { + if ((clientVer >= 4) && is_ie && is_win) { // Get text selection theSelection = document.selection.createRange().text; - if (theSelection) - { + if (theSelection) { // Add tags around selection document.selection.createRange().text = bbopen + theSelection + bbclose; document.forms[form_name].elements[text_name].focus(); theSelection = ''; return; } - } - else if (document.forms[form_name].elements[text_name].selectionEnd && (document.forms[form_name].elements[text_name].selectionEnd - document.forms[form_name].elements[text_name].selectionStart > 0)) - { + } else if (document.forms[form_name].elements[text_name].selectionEnd + && (document.forms[form_name].elements[text_name].selectionEnd - document.forms[form_name].elements[text_name].selectionStart > 0)) { mozWrap(document.forms[form_name].elements[text_name], bbopen, bbclose); document.forms[form_name].elements[text_name].focus(); theSelection = ''; @@ -114,14 +99,12 @@ function bbfontstyle(bbopen, bbclose) // Center the cursor when we don't have a selection // Gecko and proper browsers - if (!isNaN(textarea.selectionStart)) - { + if (!isNaN(textarea.selectionStart)) { textarea.selectionStart = new_pos; textarea.selectionEnd = new_pos; } // IE - else if (document.selection) - { + else if (document.selection) { var range = textarea.createTextRange(); range.move("character", new_pos); range.select(); @@ -135,53 +118,41 @@ function bbfontstyle(bbopen, bbclose) /** * Insert text at position */ -function insert_text(text, spaces, popup) -{ +function insert_text(text, spaces, popup) { var textarea; - if (!popup) - { + if (!popup) { textarea = document.forms[form_name].elements[text_name]; - } - else - { + } else { textarea = opener.document.forms[form_name].elements[text_name]; } - if (spaces) - { + if (spaces) { text = ' ' + text + ' '; } // Since IE9, IE also has textarea.selectionStart, but it still needs to be treated the old way. // Therefore we simply add a !is_ie here until IE fixes the text-selection completely. - if (!isNaN(textarea.selectionStart) && !is_ie) - { + if (!isNaN(textarea.selectionStart) && !is_ie) { var sel_start = textarea.selectionStart; var sel_end = textarea.selectionEnd; mozWrap(textarea, text, ''); textarea.selectionStart = sel_start + text.length; textarea.selectionEnd = sel_end + text.length; - } - else if (textarea.createTextRange && textarea.caretPos) - { - if (baseHeight !== textarea.caretPos.boundingHeight) - { + } else if (textarea.createTextRange && textarea.caretPos) { + if (baseHeight !== textarea.caretPos.boundingHeight) { textarea.focus(); storeCaret(textarea); } var caret_pos = textarea.caretPos; caret_pos.text = caret_pos.text.charAt(caret_pos.text.length - 1) === ' ' ? caret_pos.text + text + ' ' : caret_pos.text + text; - } - else - { + } else { textarea.value = textarea.value + text; } - if (!popup) - { + if (!popup) { textarea.focus(); } } @@ -189,8 +160,7 @@ function insert_text(text, spaces, popup) /** * Add inline attachment at position */ -function attach_inline(index, filename) -{ +function attach_inline(index, filename) { insert_text('[attachment=' + index + ']' + filename + '[/attachment]'); document.forms[form_name].elements[text_name].focus(); } @@ -198,80 +168,57 @@ function attach_inline(index, filename) /** * Add quote text to message */ -function addquote(post_id, username, l_wrote) -{ +function addquote(post_id, username, l_wrote) { var message_name = 'message_' + post_id; var theSelection = ''; var divarea = false; var i; - if (l_wrote === undefined) - { + if (l_wrote === undefined) { // Backwards compatibility l_wrote = 'wrote'; } - if (document.all) - { + if (document.all) { divarea = document.all[message_name]; - } - else - { + } else { divarea = document.getElementById(message_name); } // Get text selection - not only the post content :( // IE9 must use the document.selection method but has the *.getSelection so we just force no IE - if (window.getSelection && !is_ie && !window.opera) - { + if (window.getSelection && !is_ie && !window.opera) { theSelection = window.getSelection().toString(); - } - else if (document.getSelection && !is_ie) - { + } else if (document.getSelection && !is_ie) { theSelection = document.getSelection(); - } - else if (document.selection) - { + } else if (document.selection) { theSelection = document.selection.createRange().text; } - if (theSelection === '' || typeof theSelection === 'undefined' || theSelection === null) - { - if (divarea.innerHTML) - { + if (theSelection === '' || typeof theSelection === 'undefined' || theSelection === null) { + if (divarea.innerHTML) { theSelection = divarea.innerHTML.replace(/
    /ig, '\n'); theSelection = theSelection.replace(//ig, '\n'); theSelection = theSelection.replace(/<\;/ig, '<'); theSelection = theSelection.replace(/>\;/ig, '>'); theSelection = theSelection.replace(/&\;/ig, '&'); theSelection = theSelection.replace(/ \;/ig, ' '); - } - else if (document.all) - { + } else if (document.all) { theSelection = divarea.innerText; - } - else if (divarea.textContent) - { + } else if (divarea.textContent) { theSelection = divarea.textContent; - } - else if (divarea.firstChild.nodeValue) - { + } else if (divarea.firstChild.nodeValue) { theSelection = divarea.firstChild.nodeValue; } } - if (theSelection) - { - if (bbcodeEnabled) - { + if (theSelection) { + if (bbcodeEnabled) { insert_text('[quote="' + username + '"]' + theSelection + '[/quote]'); - } - else - { + } else { insert_text(username + ' ' + l_wrote + ':' + '\n'); var lines = split_lines(theSelection); - for (i = 0; i < lines.length; i++) - { + for (i = 0; i < lines.length; i++) { insert_text('> ' + lines[i] + '\n'); } } @@ -280,35 +227,26 @@ function addquote(post_id, username, l_wrote) return; } -function split_lines(text) -{ +function split_lines(text) { var lines = text.split('\n'); var splitLines = new Array(); var j = 0; var i; - for(i = 0; i < lines.length; i++) - { - if (lines[i].length <= 80) - { + for(i = 0; i < lines.length; i++) { + if (lines[i].length <= 80) { splitLines[j] = lines[i]; j++; - } - else - { + } else { var line = lines[i]; var splitAt; - do - { + do { splitAt = line.indexOf(' ', 80); - if (splitAt === -1) - { + if (splitAt === -1) { splitLines[j] = line; j++; - } - else - { + } else { splitLines[j] = line.substring(0, splitAt); line = line.substring(splitAt); j++; @@ -323,15 +261,13 @@ function split_lines(text) /** * From http://www.massless.org/mozedit/ */ -function mozWrap(txtarea, open, close) -{ +function mozWrap(txtarea, open, close) { var selLength = (typeof(txtarea.textLength) === 'undefined') ? txtarea.value.length : txtarea.textLength; var selStart = txtarea.selectionStart; var selEnd = txtarea.selectionEnd; var scrollTop = txtarea.scrollTop; - if (selEnd === 1 || selEnd === 2) - { + if (selEnd === 1 || selEnd === 2) { selEnd = selLength; } @@ -352,10 +288,8 @@ function mozWrap(txtarea, open, close) * Insert at Caret position. Code from * http://www.faqts.com/knowledge_base/view.phtml/aid/1052/fid/130 */ -function storeCaret(textEl) -{ - if (textEl.createTextRange) - { +function storeCaret(textEl) { + if (textEl.createTextRange) { textEl.caretPos = document.selection.createRange().duplicate(); } } @@ -363,8 +297,7 @@ function storeCaret(textEl) /** * Color pallette */ -function colorPalette(dir, width, height) -{ +function colorPalette(dir, width, height) { var r = 0, g = 0, b = 0; var numberList = new Array(6); var color = ''; @@ -377,36 +310,29 @@ function colorPalette(dir, width, height) document.writeln('
    '); document.write('#' + color + ''); document.writeln('
    '); - for (r = 0; r < 5; r++) - { - if (dir === 'h') - { + for (r = 0; r < 5; r++) { + if (dir === 'h') { document.writeln(''); } - for (g = 0; g < 5; g++) - { - if (dir === 'v') - { + for (g = 0; g < 5; g++) { + if (dir === 'v') { document.writeln(''); } - for (b = 0; b < 5; b++) - { + for (b = 0; b < 5; b++) { color = String(numberList[r]) + String(numberList[g]) + String(numberList[b]); document.write(''); } - if (dir === 'v') - { + if (dir === 'v') { document.writeln(''); } } - if (dir === 'h') - { + if (dir === 'h') { document.writeln(''); } } @@ -416,8 +342,7 @@ function colorPalette(dir, width, height) /** * Caret Position object */ -function caretPosition() -{ +function caretPosition() { var start = null; var end = null; } @@ -425,19 +350,16 @@ function caretPosition() /** * Get the caret position in an textarea */ -function getCaretPosition(txtarea) -{ +function getCaretPosition(txtarea) { var caretPos = new caretPosition(); // simple Gecko/Opera way - if (txtarea.selectionStart || txtarea.selectionStart === 0) - { + if (txtarea.selectionStart || txtarea.selectionStart === 0) { caretPos.start = txtarea.selectionStart; caretPos.end = txtarea.selectionEnd; } // dirty and slow IE way - else if (document.selection) - { + else if (document.selection) { // get current selection var range = document.selection.createRange(); @@ -447,8 +369,7 @@ function getCaretPosition(txtarea) // calculate selection start point by moving beginning of range_all to beginning of range var sel_start; - for (sel_start = 0; range_all.compareEndPoints('StartToStart', range) < 0; sel_start++) - { + for (sel_start = 0; range_all.compareEndPoints('StartToStart', range) < 0; sel_start++) { range_all.moveStart('character', 1); } From 81cf02e057080dda384716022b6cc4c9cc1ff461 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 26 Mar 2013 13:34:20 +0100 Subject: [PATCH 056/281] [ticket/11405] Order users in bookmark, in order to pass postgres tests PHPBB3-11405 --- phpBB/includes/notification/type/bookmark.php | 1 + 1 file changed, 1 insertion(+) diff --git a/phpBB/includes/notification/type/bookmark.php b/phpBB/includes/notification/type/bookmark.php index 4e48a967d0..946cb9b4ed 100644 --- a/phpBB/includes/notification/type/bookmark.php +++ b/phpBB/includes/notification/type/bookmark.php @@ -89,6 +89,7 @@ class phpbb_notification_type_bookmark extends phpbb_notification_type_post { return array(); } + sort($users); $auth_read = $this->auth->acl_get_list($users, 'f_read', $post['forum_id']); From 0f204595d9b69c29716e8cf0ccf5033e66f5294f Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 26 Mar 2013 14:09:35 +0100 Subject: [PATCH 057/281] [ticket/11405] Fix "only variables should be passed by reference" PHPBB3-11405 --- tests/notification/submit_post_base.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/notification/submit_post_base.php b/tests/notification/submit_post_base.php index d306e3f381..c5b2450e1c 100644 --- a/tests/notification/submit_post_base.php +++ b/tests/notification/submit_post_base.php @@ -126,7 +126,9 @@ class phpbb_notification_submit_post_base extends phpbb_database_test_case $this->assertEquals($expected_before, $this->db->sql_fetchrowset($result)); $this->db->sql_freeresult($result); - submit_post('reply', '', 'poster-name', POST_NORMAL, $this->poll_data, array_merge($this->post_data, $additional_post_data), false, false); + $poll_data = $this->poll_data; + $post_data = array_merge($this->post_data, $additional_post_data); + submit_post('reply', '', 'poster-name', POST_NORMAL, $poll_data, $post_data, false, false); $sql = 'SELECT user_id, item_id, item_parent_id FROM ' . NOTIFICATIONS_TABLE . " From 8a94e08e3009fece3f9de2d28c8f873dc4471b52 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 26 Mar 2013 13:33:32 +0100 Subject: [PATCH 058/281] [ticket/11405] Add unit tests for post_in_queue PHPBB3-11405 --- .../fixtures/submit_post_post_in_queue.xml | 160 ++++++++++++++++++ .../submit_post_type_post_in_queue_test.php | 102 +++++++++++ 2 files changed, 262 insertions(+) create mode 100644 tests/notification/fixtures/submit_post_post_in_queue.xml create mode 100644 tests/notification/submit_post_type_post_in_queue_test.php diff --git a/tests/notification/fixtures/submit_post_post_in_queue.xml b/tests/notification/fixtures/submit_post_post_in_queue.xml new file mode 100644 index 0000000000..4162d01d7f --- /dev/null +++ b/tests/notification/fixtures/submit_post_post_in_queue.xml @@ -0,0 +1,160 @@ + + +
    '); document.write('#' + color + ''); document.writeln('
    + item_type + user_id + item_id + item_parent_id + notification_read + notification_data + + post_in_queue + 6 + 1 + 1 + 0 + + +
    + + notification_type + notification_type_enabled + + post_in_queue + 1 + +
    + + post_id + topic_id + forum_id + post_text + + 1 + 1 + 1 + + +
    + + topic_id + forum_id + + 1 + 1 + +
    + + user_id + username_clean + user_permissions + user_sig + user_occ + user_interests + + 2 + poster + + + + + + + 3 + test + + + + + + + 4 + unauthorized-mod + + + + + + + 5 + unauthorized-read + + + + + + + 6 + notified + + + + + + + 7 + disabled + + + + + + + 8 + default + + + + + +
    + + item_type + item_id + user_id + method + notify + + needs_approval + 0 + 2 + + 1 + + + needs_approval + 0 + 3 + + 1 + + + needs_approval + 0 + 4 + + 1 + + + needs_approval + 0 + 5 + + 1 + + + needs_approval + 0 + 6 + + 1 + + + needs_approval + 0 + 7 + + 0 + +
    + diff --git a/tests/notification/submit_post_type_post_in_queue_test.php b/tests/notification/submit_post_type_post_in_queue_test.php new file mode 100644 index 0000000000..375ee3fbef --- /dev/null +++ b/tests/notification/submit_post_type_post_in_queue_test.php @@ -0,0 +1,102 @@ +expects($this->any()) + ->method('acl_get_list') + ->with($this->anything(), + $this->stringContains('_'), + $this->greaterThan(0)) + ->will($this->returnValueMap(array( + array( + false, + 'm_approve', + array(1, 0), + array( + 1 => array( + 'm_approve' => array(3, 4, 6, 7, 8), + ), + ), + ), + array( + array(3, 4, 6, 7, 8), + 'f_read', + 1, + array( + 1 => array( + 'f_read' => array(3, 6, 7, 8), + ), + ), + ), + ))); + } + + /** + * submit_post() Notifications test + * + * submit_post() $mode = 'reply' + * Notification item_type = 'post_in_queue' + */ + public function submit_post_data() + { + return array( + /** + * Normal post + * + * No new notifications + */ + array( + array(), + array( + array('user_id' => 6, 'item_id' => 1, 'item_parent_id' => 1), + ), + array( + array('user_id' => 6, 'item_id' => 1, 'item_parent_id' => 1), + ), + ), + + /** + * Unapproved post + * + * User => State description + * 2 => Poster, should NOT receive a notification + * 3 => Moderator, should receive a notification + * 4 => Moderator, but unauthed to read, should NOT receive a notification + * 5 => Moderator, but unauthed to approve, should NOT receive a notification + * 6 => Moderator, but already notified, should STILL receive a new notification + * 7 => Moderator, but option disabled, should NOT receive a notification + * 8 => Moderator, option set to default, should receive a notification + */ + array( + array('force_approved_state' => false), + array( + array('user_id' => 6, 'item_id' => 1, 'item_parent_id' => 1), + ), + array( + array('user_id' => 3, 'item_id' => 2, 'item_parent_id' => 1), + array('user_id' => 6, 'item_id' => 1, 'item_parent_id' => 1), + array('user_id' => 6, 'item_id' => 2, 'item_parent_id' => 1), + array('user_id' => 8, 'item_id' => 2, 'item_parent_id' => 1), + ), + ), + ); + } +} From 1af89968dda7270de73d21bfb5285f25ddee9963 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 26 Mar 2013 20:14:40 +0100 Subject: [PATCH 059/281] [ticket/11474] Check read permission before sending *_in_queue notifications PHPBB3-11405 PHPBB3-11474 --- phpBB/includes/notification/type/post_in_queue.php | 9 ++++++++- phpBB/includes/notification/type/topic_in_queue.php | 9 ++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/phpBB/includes/notification/type/post_in_queue.php b/phpBB/includes/notification/type/post_in_queue.php index 9c719205e6..a167dc2faf 100644 --- a/phpBB/includes/notification/type/post_in_queue.php +++ b/phpBB/includes/notification/type/post_in_queue.php @@ -101,8 +101,15 @@ class phpbb_notification_type_post_in_queue extends phpbb_notification_type_post { $has_permission = array_unique(array_merge($has_permission, $auth_approve[0][$this->permission])); } + sort($has_permission); - return $this->check_user_notification_options($has_permission, array_merge($options, array( + $auth_read = $this->auth->acl_get_list($has_permission, 'f_read', $post['forum_id']); + if (empty($auth_read)) + { + return array(); + } + + return $this->check_user_notification_options($auth_read[$post['forum_id']]['f_read'], array_merge($options, array( 'item_type' => self::$notification_option['id'], ))); } diff --git a/phpBB/includes/notification/type/topic_in_queue.php b/phpBB/includes/notification/type/topic_in_queue.php index c501434c43..4fe4325118 100644 --- a/phpBB/includes/notification/type/topic_in_queue.php +++ b/phpBB/includes/notification/type/topic_in_queue.php @@ -101,8 +101,15 @@ class phpbb_notification_type_topic_in_queue extends phpbb_notification_type_top { $has_permission = array_unique(array_merge($has_permission, $auth_approve[0][$this->permission])); } + sort($has_permission); - return $this->check_user_notification_options($has_permission, array_merge($options, array( + $auth_read = $this->auth->acl_get_list($has_permission, 'f_read', $topic['forum_id']); + if (empty($auth_read)) + { + return array(); + } + + return $this->check_user_notification_options($auth_read[$topic['forum_id']]['f_read'], array_merge($options, array( 'item_type' => self::$notification_option['id'], ))); } From d8a63047aaef2d8839baf32bbb8df724e1e46b02 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 26 Mar 2013 20:16:07 +0100 Subject: [PATCH 060/281] [ticket/11474] Clarify comment with "global" and forum_id = 0 Forum ID 0 in permission checks, checks the global moderator permission. PHPBB3-11405 PHPBB3-11474 --- phpBB/includes/notification/type/post_in_queue.php | 2 +- phpBB/includes/notification/type/topic_in_queue.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/phpBB/includes/notification/type/post_in_queue.php b/phpBB/includes/notification/type/post_in_queue.php index a167dc2faf..bc4b15cdc3 100644 --- a/phpBB/includes/notification/type/post_in_queue.php +++ b/phpBB/includes/notification/type/post_in_queue.php @@ -82,7 +82,7 @@ class phpbb_notification_type_post_in_queue extends phpbb_notification_type_post 'ignore_users' => array(), ), $options); - // 0 is for global + // 0 is for global moderator permissions $auth_approve = $this->auth->acl_get_list(false, $this->permission, array($post['forum_id'], 0)); if (empty($auth_approve)) diff --git a/phpBB/includes/notification/type/topic_in_queue.php b/phpBB/includes/notification/type/topic_in_queue.php index 4fe4325118..f735e10c00 100644 --- a/phpBB/includes/notification/type/topic_in_queue.php +++ b/phpBB/includes/notification/type/topic_in_queue.php @@ -82,7 +82,7 @@ class phpbb_notification_type_topic_in_queue extends phpbb_notification_type_top 'ignore_users' => array(), ), $options); - // 0 is for global + // 0 is for global moderator permissions $auth_approve = $this->auth->acl_get_list(false, 'm_approve', array($topic['forum_id'], 0)); if (empty($auth_approve)) From 6dddc22ec7241cdf32cd28788ff04fb296648203 Mon Sep 17 00:00:00 2001 From: David King Date: Tue, 26 Mar 2013 17:07:20 -0400 Subject: [PATCH 061/281] [ticket/11448] Use of $user_id parameter to mark a user's notifications read Currently, the $user_id is a parameter but is not used. This patch fixes that. PHPBB3-11448 --- phpBB/includes/notification/manager.php | 1 + 1 file changed, 1 insertion(+) diff --git a/phpBB/includes/notification/manager.php b/phpBB/includes/notification/manager.php index ff83d4bb37..4e26234390 100644 --- a/phpBB/includes/notification/manager.php +++ b/phpBB/includes/notification/manager.php @@ -256,6 +256,7 @@ class phpbb_notification_manager SET notification_read = 1 WHERE notification_time <= " . (int) $time . (($item_type !== false) ? ' AND ' . (is_array($item_type) ? $this->db->sql_in_set('item_type', $item_type) : " item_type = '" . $this->db->sql_escape($item_type) . "'") : '') . + (($user_id !== false) ? ' AND ' . (is_array($user_id) ? $this->db->sql_in_set('user_id', $user_id) : 'user_id = ' . (int) $user_id) : '') . (($item_id !== false) ? ' AND ' . (is_array($item_id) ? $this->db->sql_in_set('item_id', $item_id) : 'item_id = ' . (int) $item_id) : ''); $this->db->sql_query($sql); } From 6ab9ef54a20670b4620850b9aa62740470936f43 Mon Sep 17 00:00:00 2001 From: David King Date: Tue, 26 Mar 2013 17:21:35 -0400 Subject: [PATCH 062/281] [ticket/11466] Remove old database driver files from PHPUnit exclude As per the ticket comments, these can simply be removed, rather than having to be renamed to the new file locations. PHPBB3-11466 --- phpunit.xml.all | 9 --------- phpunit.xml.dist | 9 --------- phpunit.xml.functional | 9 --------- 3 files changed, 27 deletions(-) diff --git a/phpunit.xml.all b/phpunit.xml.all index fde3bbb1a7..3639843771 100644 --- a/phpunit.xml.all +++ b/phpunit.xml.all @@ -24,15 +24,6 @@ ./phpBB/includes/ - ./phpBB/includes/db/firebird.php - ./phpBB/includes/db/mysql.php - ./phpBB/includes/db/mysqli.php - ./phpBB/includes/db/mssql.php - ./phpBB/includes/db/mssql_odbc.php - ./phpBB/includes/db/mssqlnative.php - ./phpBB/includes/db/oracle.php - ./phpBB/includes/db/postgres.php - ./phpBB/includes/db/sqlite.php ./phpBB/includes/search/fulltext_native.php ./phpBB/includes/search/fulltext_mysql.php ./phpBB/includes/captcha/ diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 27dee48aac..f1cb4b9d09 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -31,15 +31,6 @@ ./phpBB/includes/ - ./phpBB/includes/db/firebird.php - ./phpBB/includes/db/mysql.php - ./phpBB/includes/db/mysqli.php - ./phpBB/includes/db/mssql.php - ./phpBB/includes/db/mssql_odbc.php - ./phpBB/includes/db/mssqlnative.php - ./phpBB/includes/db/oracle.php - ./phpBB/includes/db/postgres.php - ./phpBB/includes/db/sqlite.php ./phpBB/includes/search/fulltext_native.php ./phpBB/includes/search/fulltext_mysql.php ./phpBB/includes/captcha/ diff --git a/phpunit.xml.functional b/phpunit.xml.functional index 9facbcff8b..99f11477aa 100644 --- a/phpunit.xml.functional +++ b/phpunit.xml.functional @@ -30,15 +30,6 @@ ./phpBB/includes/ - ./phpBB/includes/db/firebird.php - ./phpBB/includes/db/mysql.php - ./phpBB/includes/db/mysqli.php - ./phpBB/includes/db/mssql.php - ./phpBB/includes/db/mssql_odbc.php - ./phpBB/includes/db/mssqlnative.php - ./phpBB/includes/db/oracle.php - ./phpBB/includes/db/postgres.php - ./phpBB/includes/db/sqlite.php ./phpBB/includes/search/fulltext_native.php ./phpBB/includes/search/fulltext_mysql.php ./phpBB/includes/captcha/ From bdd2062a667fdf9acde75946c7a9d5d84e84b092 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Wed, 27 Mar 2013 11:12:33 +0100 Subject: [PATCH 063/281] [ticket/11474] Add test user with only global m_approve permissions PHPBB3-11405 PHPBB3-11474 --- .../fixtures/submit_post_post_in_queue.xml | 15 +++++++++++++++ .../submit_post_type_post_in_queue_test.php | 9 +++++++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/tests/notification/fixtures/submit_post_post_in_queue.xml b/tests/notification/fixtures/submit_post_post_in_queue.xml index 4162d01d7f..eedcebf71d 100644 --- a/tests/notification/fixtures/submit_post_post_in_queue.xml +++ b/tests/notification/fixtures/submit_post_post_in_queue.xml @@ -107,6 +107,14 @@ + + 9 + test glboal-permissions + + + + + item_type @@ -156,5 +164,12 @@ 0 + + needs_approval + 0 + 9 + + 1 +
    diff --git a/tests/notification/submit_post_type_post_in_queue_test.php b/tests/notification/submit_post_type_post_in_queue_test.php index 375ee3fbef..6a7ac44e39 100644 --- a/tests/notification/submit_post_type_post_in_queue_test.php +++ b/tests/notification/submit_post_type_post_in_queue_test.php @@ -31,18 +31,21 @@ class phpbb_notification_submit_post_type_post_in_queue_test extends phpbb_notif 'm_approve', array(1, 0), array( + 0 => array( + 'm_approve' => array(9), + ), 1 => array( 'm_approve' => array(3, 4, 6, 7, 8), ), ), ), array( - array(3, 4, 6, 7, 8), + array(3, 4, 6, 7, 8, 9), 'f_read', 1, array( 1 => array( - 'f_read' => array(3, 6, 7, 8), + 'f_read' => array(3, 6, 7, 8, 9), ), ), ), @@ -84,6 +87,7 @@ class phpbb_notification_submit_post_type_post_in_queue_test extends phpbb_notif * 6 => Moderator, but already notified, should STILL receive a new notification * 7 => Moderator, but option disabled, should NOT receive a notification * 8 => Moderator, option set to default, should receive a notification + * 9 => Moderator, has only global mod permissions, should receive a notification */ array( array('force_approved_state' => false), @@ -95,6 +99,7 @@ class phpbb_notification_submit_post_type_post_in_queue_test extends phpbb_notif array('user_id' => 6, 'item_id' => 1, 'item_parent_id' => 1), array('user_id' => 6, 'item_id' => 2, 'item_parent_id' => 1), array('user_id' => 8, 'item_id' => 2, 'item_parent_id' => 1), + array('user_id' => 9, 'item_id' => 2, 'item_parent_id' => 1), ), ), ); From 8dd26dee8349a14abac00db6ad5039d7517bda57 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Wed, 27 Mar 2013 11:45:45 +0100 Subject: [PATCH 064/281] [ticket/11469] Add some basic unit tests for phpbb_db_sql_insert_buffer PHPBB3-11469 --- tests/dbal/sql_insert_buffer_test.php | 176 ++++++++++++++++++++++++++ 1 file changed, 176 insertions(+) create mode 100644 tests/dbal/sql_insert_buffer_test.php diff --git a/tests/dbal/sql_insert_buffer_test.php b/tests/dbal/sql_insert_buffer_test.php new file mode 100644 index 0000000000..a67ccbe89f --- /dev/null +++ b/tests/dbal/sql_insert_buffer_test.php @@ -0,0 +1,176 @@ +createXMLDataSet(dirname(__FILE__).'/fixtures/config.xml'); + } + + public function insert_buffer_data() + { + $db = $this->new_dbal(); + + if ($db->multi_insert) + { + // Test with enabled and disabled multi_insert + return array( + array(true), + array(false), + ); + } + else + { + // Only test with disabled multi_insert, the DB doesn't support it + return array( + array(false), + ); + } + } + + /** + * @dataProvider insert_buffer_data + */ + public function test_insert_and_flush($force_multi_insert) + { + $db = $this->new_dbal(); + $db->multi_insert = $force_multi_insert; + + $buffer = new phpbb_db_sql_insert_buffer($db, 'phpbb_config', 2); + + $sql = 'SELECT COUNT(*) AS num_configs + FROM phpbb_config'; + $result = $db->sql_query_limit($sql, 1); + $this->assertEquals(2, $db->sql_fetchfield('num_configs')); + $db->sql_freeresult($result); + + // This call can be buffered + $buffer->insert(array( + 'config_name' => 'name1', + 'config_value' => 'value1', + 'is_dynamic' => '0', + )); + + if ($db->multi_insert) + { + $sql = 'SELECT COUNT(*) AS num_configs + FROM phpbb_config'; + $result = $db->sql_query_limit($sql, 1); + $this->assertEquals(2, $db->sql_fetchfield('num_configs')); + $db->sql_freeresult($result); + } + else + { + $sql = 'SELECT COUNT(*) AS num_configs + FROM phpbb_config'; + $result = $db->sql_query_limit($sql, 1); + $this->assertEquals(3, $db->sql_fetchfield('num_configs')); + $db->sql_freeresult($result); + } + + // Manually flush + $buffer->flush(); + + $sql = 'SELECT COUNT(*) AS num_configs + FROM phpbb_config'; + $result = $db->sql_query_limit($sql, 1); + $this->assertEquals(3, $db->sql_fetchfield('num_configs')); + $db->sql_freeresult($result); + } + + /** + * @dataProvider insert_buffer_data + */ + public function test_insert_with_flush($force_multi_insert) + { + $db = $this->new_dbal(); + $db->multi_insert = $force_multi_insert; + + $buffer = new phpbb_db_sql_insert_buffer($db, 'phpbb_config', 2); + + $sql = 'SELECT COUNT(*) AS num_configs + FROM phpbb_config'; + $result = $db->sql_query_limit($sql, 1); + $this->assertEquals(2, $db->sql_fetchfield('num_configs')); + $db->sql_freeresult($result); + + $buffer->insert(array( + 'config_name' => 'name1', + 'config_value' => 'value1', + 'is_dynamic' => '0', + )); + + // This call flushes the values + $buffer->insert(array( + 'config_name' => 'name2', + 'config_value' => 'value2', + 'is_dynamic' => '0', + )); + + $sql = 'SELECT COUNT(*) AS num_configs + FROM phpbb_config'; + $result = $db->sql_query_limit($sql, 1); + $this->assertEquals(4, $db->sql_fetchfield('num_configs')); + $db->sql_freeresult($result); + } + + /** + * @dataProvider insert_buffer_data + */ + public function test_insert_all_and_flush($force_multi_insert) + { + $db = $this->new_dbal(); + $db->multi_insert = $force_multi_insert; + + $buffer = new phpbb_db_sql_insert_buffer($db, 'phpbb_config', 2); + + $sql = 'SELECT COUNT(*) AS num_configs + FROM phpbb_config'; + $result = $db->sql_query_limit($sql, 1); + $this->assertEquals(2, $db->sql_fetchfield('num_configs')); + $db->sql_freeresult($result); + + $buffer->insert_all(array( + array( + 'config_name' => 'name1', + 'config_value' => 'value1', + 'is_dynamic' => '0', + ), + array( + 'config_name' => 'name2', + 'config_value' => 'value2', + 'is_dynamic' => '0', + ), + array( + 'config_name' => 'name3', + 'config_value' => 'value3', + 'is_dynamic' => '0', + ), + )); + + if ($db->multi_insert) + { + $sql = 'SELECT COUNT(*) AS num_configs + FROM phpbb_config'; + $result = $db->sql_query_limit($sql, 1); + $this->assertEquals(4, $db->sql_fetchfield('num_configs')); + $db->sql_freeresult($result); + + // Manually flush + $buffer->flush(); + } + + $sql = 'SELECT COUNT(*) AS num_configs + FROM phpbb_config'; + $result = $db->sql_query_limit($sql, 1); + $this->assertEquals(5, $db->sql_fetchfield('num_configs')); + $db->sql_freeresult($result); + } +} From bf6f2c5875f2476366c1bd660506e70c0f006c9d Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Wed, 27 Mar 2013 11:47:40 +0100 Subject: [PATCH 065/281] [ticket/11469] Return after sql_multi_insert when multi_insert is false PHPBB3-11469 --- phpBB/includes/db/sql_insert_buffer.php | 1 + 1 file changed, 1 insertion(+) diff --git a/phpBB/includes/db/sql_insert_buffer.php b/phpBB/includes/db/sql_insert_buffer.php index fe45206893..49cf5b8ef6 100644 --- a/phpBB/includes/db/sql_insert_buffer.php +++ b/phpBB/includes/db/sql_insert_buffer.php @@ -69,6 +69,7 @@ class phpbb_db_sql_insert_buffer // Pass data on to sql_multi_insert right away which will // immediately send an INSERT INTO query to the database. $this->db->sql_multi_insert($this->table_name, array($row)); + return; } $this->buffer[] = $row; From af9f30cd52fd7b53b17b946a0c646fd72c4a6f4f Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Wed, 27 Mar 2013 14:09:04 +0100 Subject: [PATCH 066/281] [ticket/11469] Use method to check config count, instead of repeating it PHPBB3-11469 --- tests/dbal/sql_insert_buffer_test.php | 63 ++++++++------------------- 1 file changed, 18 insertions(+), 45 deletions(-) diff --git a/tests/dbal/sql_insert_buffer_test.php b/tests/dbal/sql_insert_buffer_test.php index a67ccbe89f..e3ee767937 100644 --- a/tests/dbal/sql_insert_buffer_test.php +++ b/tests/dbal/sql_insert_buffer_test.php @@ -14,6 +14,15 @@ class phpbb_dbal_sql_insert_buffer_test extends phpbb_database_test_case return $this->createXMLDataSet(dirname(__FILE__).'/fixtures/config.xml'); } + protected function assert_config_count($db, $num_configs) + { + $sql = 'SELECT COUNT(*) AS num_configs + FROM phpbb_config'; + $result = $db->sql_query($sql); + $this->assertEquals($num_configs, $db->sql_fetchfield('num_configs')); + $db->sql_freeresult($result); + } + public function insert_buffer_data() { $db = $this->new_dbal(); @@ -45,11 +54,7 @@ class phpbb_dbal_sql_insert_buffer_test extends phpbb_database_test_case $buffer = new phpbb_db_sql_insert_buffer($db, 'phpbb_config', 2); - $sql = 'SELECT COUNT(*) AS num_configs - FROM phpbb_config'; - $result = $db->sql_query_limit($sql, 1); - $this->assertEquals(2, $db->sql_fetchfield('num_configs')); - $db->sql_freeresult($result); + $this->assert_config_count($db, 2); // This call can be buffered $buffer->insert(array( @@ -60,29 +65,17 @@ class phpbb_dbal_sql_insert_buffer_test extends phpbb_database_test_case if ($db->multi_insert) { - $sql = 'SELECT COUNT(*) AS num_configs - FROM phpbb_config'; - $result = $db->sql_query_limit($sql, 1); - $this->assertEquals(2, $db->sql_fetchfield('num_configs')); - $db->sql_freeresult($result); + $this->assert_config_count($db, 2); } else { - $sql = 'SELECT COUNT(*) AS num_configs - FROM phpbb_config'; - $result = $db->sql_query_limit($sql, 1); - $this->assertEquals(3, $db->sql_fetchfield('num_configs')); - $db->sql_freeresult($result); + $this->assert_config_count($db, 3); } // Manually flush $buffer->flush(); - $sql = 'SELECT COUNT(*) AS num_configs - FROM phpbb_config'; - $result = $db->sql_query_limit($sql, 1); - $this->assertEquals(3, $db->sql_fetchfield('num_configs')); - $db->sql_freeresult($result); + $this->assert_config_count($db, 3); } /** @@ -95,11 +88,7 @@ class phpbb_dbal_sql_insert_buffer_test extends phpbb_database_test_case $buffer = new phpbb_db_sql_insert_buffer($db, 'phpbb_config', 2); - $sql = 'SELECT COUNT(*) AS num_configs - FROM phpbb_config'; - $result = $db->sql_query_limit($sql, 1); - $this->assertEquals(2, $db->sql_fetchfield('num_configs')); - $db->sql_freeresult($result); + $this->assert_config_count($db, 2); $buffer->insert(array( 'config_name' => 'name1', @@ -114,11 +103,7 @@ class phpbb_dbal_sql_insert_buffer_test extends phpbb_database_test_case 'is_dynamic' => '0', )); - $sql = 'SELECT COUNT(*) AS num_configs - FROM phpbb_config'; - $result = $db->sql_query_limit($sql, 1); - $this->assertEquals(4, $db->sql_fetchfield('num_configs')); - $db->sql_freeresult($result); + $this->assert_config_count($db, 4); } /** @@ -131,11 +116,7 @@ class phpbb_dbal_sql_insert_buffer_test extends phpbb_database_test_case $buffer = new phpbb_db_sql_insert_buffer($db, 'phpbb_config', 2); - $sql = 'SELECT COUNT(*) AS num_configs - FROM phpbb_config'; - $result = $db->sql_query_limit($sql, 1); - $this->assertEquals(2, $db->sql_fetchfield('num_configs')); - $db->sql_freeresult($result); + $this->assert_config_count($db, 2); $buffer->insert_all(array( array( @@ -157,20 +138,12 @@ class phpbb_dbal_sql_insert_buffer_test extends phpbb_database_test_case if ($db->multi_insert) { - $sql = 'SELECT COUNT(*) AS num_configs - FROM phpbb_config'; - $result = $db->sql_query_limit($sql, 1); - $this->assertEquals(4, $db->sql_fetchfield('num_configs')); - $db->sql_freeresult($result); + $this->assert_config_count($db, 4); // Manually flush $buffer->flush(); } - $sql = 'SELECT COUNT(*) AS num_configs - FROM phpbb_config'; - $result = $db->sql_query_limit($sql, 1); - $this->assertEquals(5, $db->sql_fetchfield('num_configs')); - $db->sql_freeresult($result); + $this->assert_config_count($db, 5); } } From c629b2c7b3bd8bcb836ed8d0b4e583170ede2558 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Wed, 27 Mar 2013 15:01:36 +0100 Subject: [PATCH 067/281] [ticket/11476] Remove pass-by-reference from sql_mutli_insert The method never writes to the array passed by reference. So it can be passed by value instead to avoid certain problems. PHPBB3-11476 --- phpBB/includes/db/driver/driver.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/phpBB/includes/db/driver/driver.php b/phpBB/includes/db/driver/driver.php index 8dda94bc2c..b915ee081b 100644 --- a/phpBB/includes/db/driver/driver.php +++ b/phpBB/includes/db/driver/driver.php @@ -568,12 +568,12 @@ class phpbb_db_driver * Run more than one insert statement. * * @param string $table table name to run the statements on - * @param array &$sql_ary multi-dimensional array holding the statement data. + * @param array $sql_ary multi-dimensional array holding the statement data. * * @return bool false if no statements were executed. * @access public */ - function sql_multi_insert($table, &$sql_ary) + function sql_multi_insert($table, $sql_ary) { if (!sizeof($sql_ary)) { From 94a15f85a64db283a9c9402c40b2d35cb484fb37 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Wed, 27 Mar 2013 18:06:48 +0100 Subject: [PATCH 068/281] [ticket/11469] Add example code to class documentation. PHPBB3-11469 --- phpBB/includes/db/sql_insert_buffer.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/phpBB/includes/db/sql_insert_buffer.php b/phpBB/includes/db/sql_insert_buffer.php index fe45206893..772f368987 100644 --- a/phpBB/includes/db/sql_insert_buffer.php +++ b/phpBB/includes/db/sql_insert_buffer.php @@ -19,6 +19,21 @@ if (!defined('IN_PHPBB')) * Collects rows for insert into a database until the buffer size is reached. * Then flushes the buffer to the database and starts over again. * +* Usage: +* +* $buffer = new phpbb_db_sql_insert_buffer($db, 'test_table', 1234); +* +* while (do_stuff()) +* { +* $buffer->insert(array( +* 'column1' => 'value1', +* 'column2' => 'value2', +* )); +* } +* +* $buffer->flush(); +* +* * @package dbal */ class phpbb_db_sql_insert_buffer From 8c5fcac2325356bacb72517f6fbd95f9bfdaf16d Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Wed, 27 Mar 2013 18:22:59 +0100 Subject: [PATCH 069/281] [ticket/11469] Add benefits over collecting huge insert arrays to class doc. PHPBB3-11469 --- phpBB/includes/db/sql_insert_buffer.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/phpBB/includes/db/sql_insert_buffer.php b/phpBB/includes/db/sql_insert_buffer.php index 6b884dd412..4bf0608227 100644 --- a/phpBB/includes/db/sql_insert_buffer.php +++ b/phpBB/includes/db/sql_insert_buffer.php @@ -19,6 +19,18 @@ if (!defined('IN_PHPBB')) * Collects rows for insert into a database until the buffer size is reached. * Then flushes the buffer to the database and starts over again. * +* Benefits over collecting a (possibly huge) insert array and then using +* $db->sql_multi_insert() include: +* +* - Going over max packet size of the database connection is usually prevented +* because the data is submitted in batches. +* +* - Reaching database connection timeout is usually prevented because +* submission of batches talks to the database every now and then. +* +* - Usage of less PHP memory because data no longer needed is discarded on +* buffer flush. +* * Usage: * * $buffer = new phpbb_db_sql_insert_buffer($db, 'test_table', 1234); From dc766f29b4381e3cecfacbfeb848b4e13c3e48f9 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Wed, 27 Mar 2013 19:19:26 +0100 Subject: [PATCH 070/281] [ticket/11469] Have all methods of phpbb_db_sql_insert_buffer provide feedback. PHPBB3-11469 --- phpBB/includes/db/sql_insert_buffer.php | 26 +++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/phpBB/includes/db/sql_insert_buffer.php b/phpBB/includes/db/sql_insert_buffer.php index 4bf0608227..dd4a62a948 100644 --- a/phpBB/includes/db/sql_insert_buffer.php +++ b/phpBB/includes/db/sql_insert_buffer.php @@ -86,7 +86,8 @@ class phpbb_db_sql_insert_buffer * * @param array $row * - * @return null + * @return bool True when some data was flushed to the database. + * False otherwise. */ public function insert(array $row) { @@ -96,15 +97,18 @@ class phpbb_db_sql_insert_buffer // Pass data on to sql_multi_insert right away which will // immediately send an INSERT INTO query to the database. $this->db->sql_multi_insert($this->table_name, array($row)); - return; + + return true; } $this->buffer[] = $row; if (sizeof($this->buffer) >= $this->max_buffered_rows) { - $this->flush(); + return $this->flush(); } + + return false; } /** @@ -116,20 +120,26 @@ class phpbb_db_sql_insert_buffer * * @param array $rows * - * @return null + * @return bool True when some data was flushed to the database. + * False otherwise. */ public function insert_all(array $rows) { + $result = false; + foreach ($rows as $row) { - $this->insert($row); + $result |= $this->insert($row); } + + return $result; } /** * Flushes the buffer content to the DB and clears the buffer. * - * @return null + * @return bool True when some data was flushed to the database. + * False otherwise. */ public function flush() { @@ -137,6 +147,10 @@ class phpbb_db_sql_insert_buffer { $this->db->sql_multi_insert($this->table_name, $this->buffer); $this->buffer = array(); + + return true; } + + return false; } } From 53f9e2131c9b87d35207ea585981fc9b084d0a11 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Wed, 27 Mar 2013 19:27:27 +0100 Subject: [PATCH 071/281] [ticket/11469] Add note about calling flush() after batch insert is done. PHPBB3-11469 --- phpBB/includes/db/sql_insert_buffer.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/phpBB/includes/db/sql_insert_buffer.php b/phpBB/includes/db/sql_insert_buffer.php index dd4a62a948..3bd96616b3 100644 --- a/phpBB/includes/db/sql_insert_buffer.php +++ b/phpBB/includes/db/sql_insert_buffer.php @@ -31,6 +31,11 @@ if (!defined('IN_PHPBB')) * - Usage of less PHP memory because data no longer needed is discarded on * buffer flush. * +* Attention: +* Please note that users of this class have to call flush() to flush the +* remaining rows to the database after their batch insert operation is +* finished. +* * Usage: * * $buffer = new phpbb_db_sql_insert_buffer($db, 'test_table', 1234); From 9606ccc2021e7e169473d92306e28680e4b9f966 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Wed, 27 Mar 2013 20:54:20 +0100 Subject: [PATCH 072/281] [ticket/11469] Split tests and skip multi_insert if unavailable PHPBB3-11469 --- tests/dbal/sql_insert_buffer_test.php | 149 +++++++++++++++++--------- 1 file changed, 100 insertions(+), 49 deletions(-) diff --git a/tests/dbal/sql_insert_buffer_test.php b/tests/dbal/sql_insert_buffer_test.php index e3ee767937..bdf3544bbc 100644 --- a/tests/dbal/sql_insert_buffer_test.php +++ b/tests/dbal/sql_insert_buffer_test.php @@ -23,34 +23,10 @@ class phpbb_dbal_sql_insert_buffer_test extends phpbb_database_test_case $db->sql_freeresult($result); } - public function insert_buffer_data() + public function test_multi_insert_disabled_insert_and_flush() { $db = $this->new_dbal(); - - if ($db->multi_insert) - { - // Test with enabled and disabled multi_insert - return array( - array(true), - array(false), - ); - } - else - { - // Only test with disabled multi_insert, the DB doesn't support it - return array( - array(false), - ); - } - } - - /** - * @dataProvider insert_buffer_data - */ - public function test_insert_and_flush($force_multi_insert) - { - $db = $this->new_dbal(); - $db->multi_insert = $force_multi_insert; + $db->multi_insert = false; $buffer = new phpbb_db_sql_insert_buffer($db, 'phpbb_config', 2); @@ -63,14 +39,7 @@ class phpbb_dbal_sql_insert_buffer_test extends phpbb_database_test_case 'is_dynamic' => '0', )); - if ($db->multi_insert) - { - $this->assert_config_count($db, 2); - } - else - { - $this->assert_config_count($db, 3); - } + $this->assert_config_count($db, 3); // Manually flush $buffer->flush(); @@ -78,13 +47,38 @@ class phpbb_dbal_sql_insert_buffer_test extends phpbb_database_test_case $this->assert_config_count($db, 3); } - /** - * @dataProvider insert_buffer_data - */ - public function test_insert_with_flush($force_multi_insert) + public function test_multi_insert_enabled_insert_and_flush() { $db = $this->new_dbal(); - $db->multi_insert = $force_multi_insert; + + if (!$db->multi_insert) + { + $this->markTestSkipped('Database does not support multi_insert'); + } + + $buffer = new phpbb_db_sql_insert_buffer($db, 'phpbb_config', 2); + + $this->assert_config_count($db, 2); + + // This call can be buffered + $buffer->insert(array( + 'config_name' => 'name1', + 'config_value' => 'value1', + 'is_dynamic' => '0', + )); + + $this->assert_config_count($db, 2); + + // Manually flush + $buffer->flush(); + + $this->assert_config_count($db, 3); + } + + public function test_multi_insert_disabled_insert_with_flush() + { + $db = $this->new_dbal(); + $db->multi_insert = false; $buffer = new phpbb_db_sql_insert_buffer($db, 'phpbb_config', 2); @@ -106,13 +100,39 @@ class phpbb_dbal_sql_insert_buffer_test extends phpbb_database_test_case $this->assert_config_count($db, 4); } - /** - * @dataProvider insert_buffer_data - */ - public function test_insert_all_and_flush($force_multi_insert) + public function test_multi_insert_enabled_insert_with_flush() { $db = $this->new_dbal(); - $db->multi_insert = $force_multi_insert; + + if (!$db->multi_insert) + { + $this->markTestSkipped('Database does not support multi_insert'); + } + + $buffer = new phpbb_db_sql_insert_buffer($db, 'phpbb_config', 2); + + $this->assert_config_count($db, 2); + + $buffer->insert(array( + 'config_name' => 'name1', + 'config_value' => 'value1', + 'is_dynamic' => '0', + )); + + // This call flushes the values + $buffer->insert(array( + 'config_name' => 'name2', + 'config_value' => 'value2', + 'is_dynamic' => '0', + )); + + $this->assert_config_count($db, 4); + } + + public function test_multi_insert_disabled_insert_all_and_flush() + { + $db = $this->new_dbal(); + $db->multi_insert = false; $buffer = new phpbb_db_sql_insert_buffer($db, 'phpbb_config', 2); @@ -136,14 +156,45 @@ class phpbb_dbal_sql_insert_buffer_test extends phpbb_database_test_case ), )); - if ($db->multi_insert) - { - $this->assert_config_count($db, 4); + $this->assert_config_count($db, 5); + } - // Manually flush - $buffer->flush(); + public function test_multi_insert_enabled_insert_all_and_flush() + { + $db = $this->new_dbal(); + + if (!$db->multi_insert) + { + $this->markTestSkipped('Database does not support multi_insert'); } + $buffer = new phpbb_db_sql_insert_buffer($db, 'phpbb_config', 2); + + $this->assert_config_count($db, 2); + + $buffer->insert_all(array( + array( + 'config_name' => 'name1', + 'config_value' => 'value1', + 'is_dynamic' => '0', + ), + array( + 'config_name' => 'name2', + 'config_value' => 'value2', + 'is_dynamic' => '0', + ), + array( + 'config_name' => 'name3', + 'config_value' => 'value3', + 'is_dynamic' => '0', + ), + )); + + $this->assert_config_count($db, 4); + + // Manually flush + $buffer->flush(); + $this->assert_config_count($db, 5); } } From 69ad4aab787db4c80c431c412a76d731a1abdf63 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Wed, 27 Mar 2013 20:55:08 +0100 Subject: [PATCH 073/281] [ticket/11469] Check return values of the functions PHPBB3-11469 --- tests/dbal/sql_insert_buffer_test.php | 38 +++++++++++++-------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/tests/dbal/sql_insert_buffer_test.php b/tests/dbal/sql_insert_buffer_test.php index bdf3544bbc..fd92ca9bba 100644 --- a/tests/dbal/sql_insert_buffer_test.php +++ b/tests/dbal/sql_insert_buffer_test.php @@ -33,16 +33,16 @@ class phpbb_dbal_sql_insert_buffer_test extends phpbb_database_test_case $this->assert_config_count($db, 2); // This call can be buffered - $buffer->insert(array( + $this->assertTrue($buffer->insert(array( 'config_name' => 'name1', 'config_value' => 'value1', 'is_dynamic' => '0', - )); + ))); $this->assert_config_count($db, 3); // Manually flush - $buffer->flush(); + $this->assertFalse($buffer->flush()); $this->assert_config_count($db, 3); } @@ -61,16 +61,16 @@ class phpbb_dbal_sql_insert_buffer_test extends phpbb_database_test_case $this->assert_config_count($db, 2); // This call can be buffered - $buffer->insert(array( + $this->assertFalse($buffer->insert(array( 'config_name' => 'name1', 'config_value' => 'value1', 'is_dynamic' => '0', - )); + ))); $this->assert_config_count($db, 2); // Manually flush - $buffer->flush(); + $this->assertTrue($buffer->flush()); $this->assert_config_count($db, 3); } @@ -84,18 +84,18 @@ class phpbb_dbal_sql_insert_buffer_test extends phpbb_database_test_case $this->assert_config_count($db, 2); - $buffer->insert(array( + $this->assertTrue($buffer->insert(array( 'config_name' => 'name1', 'config_value' => 'value1', 'is_dynamic' => '0', - )); + ))); // This call flushes the values - $buffer->insert(array( + $this->assertTrue($buffer->insert(array( 'config_name' => 'name2', 'config_value' => 'value2', 'is_dynamic' => '0', - )); + ))); $this->assert_config_count($db, 4); } @@ -113,18 +113,18 @@ class phpbb_dbal_sql_insert_buffer_test extends phpbb_database_test_case $this->assert_config_count($db, 2); - $buffer->insert(array( + $this->assertFalse($buffer->insert(array( 'config_name' => 'name1', 'config_value' => 'value1', 'is_dynamic' => '0', - )); + ))); // This call flushes the values - $buffer->insert(array( + $this->assertTrue($buffer->insert(array( 'config_name' => 'name2', 'config_value' => 'value2', 'is_dynamic' => '0', - )); + ))); $this->assert_config_count($db, 4); } @@ -138,7 +138,7 @@ class phpbb_dbal_sql_insert_buffer_test extends phpbb_database_test_case $this->assert_config_count($db, 2); - $buffer->insert_all(array( + $this->assertTrue($buffer->insert_all(array( array( 'config_name' => 'name1', 'config_value' => 'value1', @@ -154,7 +154,7 @@ class phpbb_dbal_sql_insert_buffer_test extends phpbb_database_test_case 'config_value' => 'value3', 'is_dynamic' => '0', ), - )); + ))); $this->assert_config_count($db, 5); } @@ -172,7 +172,7 @@ class phpbb_dbal_sql_insert_buffer_test extends phpbb_database_test_case $this->assert_config_count($db, 2); - $buffer->insert_all(array( + $this->assertTrue($buffer->insert_all(array( array( 'config_name' => 'name1', 'config_value' => 'value1', @@ -188,12 +188,12 @@ class phpbb_dbal_sql_insert_buffer_test extends phpbb_database_test_case 'config_value' => 'value3', 'is_dynamic' => '0', ), - )); + ))); $this->assert_config_count($db, 4); // Manually flush - $buffer->flush(); + $this->assertTrue($buffer->flush()); $this->assert_config_count($db, 5); } From c9f059c4f2793e9f98c3e0fbaad06708dd557d31 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Wed, 27 Mar 2013 20:55:48 +0100 Subject: [PATCH 074/281] [ticket/11469] Cast $result to boolean in insert_all() |= returns integer values PHPBB3-11469 --- phpBB/includes/db/sql_insert_buffer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/includes/db/sql_insert_buffer.php b/phpBB/includes/db/sql_insert_buffer.php index 3bd96616b3..dd7932c7bd 100644 --- a/phpBB/includes/db/sql_insert_buffer.php +++ b/phpBB/includes/db/sql_insert_buffer.php @@ -137,7 +137,7 @@ class phpbb_db_sql_insert_buffer $result |= $this->insert($row); } - return $result; + return (bool) $result; } /** From a534497d82cb9febaa18ee6c858ef68217bc2d14 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Wed, 27 Mar 2013 23:21:29 +0100 Subject: [PATCH 075/281] [ticket/11469] Move protected method to end of test file. PHPBB3-11469 --- tests/dbal/sql_insert_buffer_test.php | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/tests/dbal/sql_insert_buffer_test.php b/tests/dbal/sql_insert_buffer_test.php index fd92ca9bba..0cf476b14a 100644 --- a/tests/dbal/sql_insert_buffer_test.php +++ b/tests/dbal/sql_insert_buffer_test.php @@ -14,15 +14,6 @@ class phpbb_dbal_sql_insert_buffer_test extends phpbb_database_test_case return $this->createXMLDataSet(dirname(__FILE__).'/fixtures/config.xml'); } - protected function assert_config_count($db, $num_configs) - { - $sql = 'SELECT COUNT(*) AS num_configs - FROM phpbb_config'; - $result = $db->sql_query($sql); - $this->assertEquals($num_configs, $db->sql_fetchfield('num_configs')); - $db->sql_freeresult($result); - } - public function test_multi_insert_disabled_insert_and_flush() { $db = $this->new_dbal(); @@ -197,4 +188,13 @@ class phpbb_dbal_sql_insert_buffer_test extends phpbb_database_test_case $this->assert_config_count($db, 5); } + + protected function assert_config_count($db, $num_configs) + { + $sql = 'SELECT COUNT(*) AS num_configs + FROM phpbb_config'; + $result = $db->sql_query($sql); + $this->assertEquals($num_configs, $db->sql_fetchfield('num_configs')); + $db->sql_freeresult($result); + } } From 873f098b6ccc108dc293054f2cf7cb7231684caa Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Wed, 27 Mar 2013 23:30:23 +0100 Subject: [PATCH 076/281] [ticket/11469] Do not repeat array with three rows. PHPBB3-11469 --- tests/dbal/sql_insert_buffer_test.php | 57 +++++++++++---------------- 1 file changed, 23 insertions(+), 34 deletions(-) diff --git a/tests/dbal/sql_insert_buffer_test.php b/tests/dbal/sql_insert_buffer_test.php index 0cf476b14a..59bfb73d0f 100644 --- a/tests/dbal/sql_insert_buffer_test.php +++ b/tests/dbal/sql_insert_buffer_test.php @@ -129,23 +129,7 @@ class phpbb_dbal_sql_insert_buffer_test extends phpbb_database_test_case $this->assert_config_count($db, 2); - $this->assertTrue($buffer->insert_all(array( - array( - 'config_name' => 'name1', - 'config_value' => 'value1', - 'is_dynamic' => '0', - ), - array( - 'config_name' => 'name2', - 'config_value' => 'value2', - 'is_dynamic' => '0', - ), - array( - 'config_name' => 'name3', - 'config_value' => 'value3', - 'is_dynamic' => '0', - ), - ))); + $this->assertTrue($buffer->insert_all($this->get_three_rows())); $this->assert_config_count($db, 5); } @@ -163,23 +147,7 @@ class phpbb_dbal_sql_insert_buffer_test extends phpbb_database_test_case $this->assert_config_count($db, 2); - $this->assertTrue($buffer->insert_all(array( - array( - 'config_name' => 'name1', - 'config_value' => 'value1', - 'is_dynamic' => '0', - ), - array( - 'config_name' => 'name2', - 'config_value' => 'value2', - 'is_dynamic' => '0', - ), - array( - 'config_name' => 'name3', - 'config_value' => 'value3', - 'is_dynamic' => '0', - ), - ))); + $this->assertTrue($buffer->insert_all($this->get_three_rows())); $this->assert_config_count($db, 4); @@ -197,4 +165,25 @@ class phpbb_dbal_sql_insert_buffer_test extends phpbb_database_test_case $this->assertEquals($num_configs, $db->sql_fetchfield('num_configs')); $db->sql_freeresult($result); } + + protected function get_three_rows() + { + return array( + array( + 'config_name' => 'name1', + 'config_value' => 'value1', + 'is_dynamic' => '0', + ), + array( + 'config_name' => 'name2', + 'config_value' => 'value2', + 'is_dynamic' => '0', + ), + array( + 'config_name' => 'name3', + 'config_value' => 'value3', + 'is_dynamic' => '0', + ), + ); + } } From b88eb3c8e099e1a0634ab84e9e1c215c00410264 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Wed, 27 Mar 2013 23:33:13 +0100 Subject: [PATCH 077/281] [ticket/11469] Do not repeat row generation. PHPBB3-11469 --- tests/dbal/sql_insert_buffer_test.php | 63 ++++++++------------------- 1 file changed, 18 insertions(+), 45 deletions(-) diff --git a/tests/dbal/sql_insert_buffer_test.php b/tests/dbal/sql_insert_buffer_test.php index 59bfb73d0f..650a42c36d 100644 --- a/tests/dbal/sql_insert_buffer_test.php +++ b/tests/dbal/sql_insert_buffer_test.php @@ -24,11 +24,7 @@ class phpbb_dbal_sql_insert_buffer_test extends phpbb_database_test_case $this->assert_config_count($db, 2); // This call can be buffered - $this->assertTrue($buffer->insert(array( - 'config_name' => 'name1', - 'config_value' => 'value1', - 'is_dynamic' => '0', - ))); + $this->assertTrue($buffer->insert($this->get_row(1))); $this->assert_config_count($db, 3); @@ -52,11 +48,7 @@ class phpbb_dbal_sql_insert_buffer_test extends phpbb_database_test_case $this->assert_config_count($db, 2); // This call can be buffered - $this->assertFalse($buffer->insert(array( - 'config_name' => 'name1', - 'config_value' => 'value1', - 'is_dynamic' => '0', - ))); + $this->assertFalse($buffer->insert($this->get_row(1))); $this->assert_config_count($db, 2); @@ -75,18 +67,10 @@ class phpbb_dbal_sql_insert_buffer_test extends phpbb_database_test_case $this->assert_config_count($db, 2); - $this->assertTrue($buffer->insert(array( - 'config_name' => 'name1', - 'config_value' => 'value1', - 'is_dynamic' => '0', - ))); + $this->assertTrue($buffer->insert($this->get_row(1))); // This call flushes the values - $this->assertTrue($buffer->insert(array( - 'config_name' => 'name2', - 'config_value' => 'value2', - 'is_dynamic' => '0', - ))); + $this->assertTrue($buffer->insert($this->get_row(2))); $this->assert_config_count($db, 4); } @@ -104,18 +88,10 @@ class phpbb_dbal_sql_insert_buffer_test extends phpbb_database_test_case $this->assert_config_count($db, 2); - $this->assertFalse($buffer->insert(array( - 'config_name' => 'name1', - 'config_value' => 'value1', - 'is_dynamic' => '0', - ))); + $this->assertFalse($buffer->insert($this->get_row(1))); // This call flushes the values - $this->assertTrue($buffer->insert(array( - 'config_name' => 'name2', - 'config_value' => 'value2', - 'is_dynamic' => '0', - ))); + $this->assertTrue($buffer->insert($this->get_row(2))); $this->assert_config_count($db, 4); } @@ -166,24 +142,21 @@ class phpbb_dbal_sql_insert_buffer_test extends phpbb_database_test_case $db->sql_freeresult($result); } + protected function get_row($rownum) + { + return array( + 'config_name' => "name$rownum", + 'config_value' => "value$rownum", + 'is_dynamic' => '0', + ); + } + protected function get_three_rows() { return array( - array( - 'config_name' => 'name1', - 'config_value' => 'value1', - 'is_dynamic' => '0', - ), - array( - 'config_name' => 'name2', - 'config_value' => 'value2', - 'is_dynamic' => '0', - ), - array( - 'config_name' => 'name3', - 'config_value' => 'value3', - 'is_dynamic' => '0', - ), + $this->get_row(1), + $this->get_row(2), + $this->get_row(3), ); } } From 4132573088c376fcb44cc588d9341c8d38b6d694 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Wed, 27 Mar 2013 23:35:36 +0100 Subject: [PATCH 078/281] [ticket/11469] Use buffer with a single element instead of extra code path. PHPBB3-11469 --- phpBB/includes/db/sql_insert_buffer.php | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/phpBB/includes/db/sql_insert_buffer.php b/phpBB/includes/db/sql_insert_buffer.php index dd7932c7bd..03c8a875b9 100644 --- a/phpBB/includes/db/sql_insert_buffer.php +++ b/phpBB/includes/db/sql_insert_buffer.php @@ -96,19 +96,11 @@ class phpbb_db_sql_insert_buffer */ public function insert(array $row) { - if (!$this->db_supports_multi_insert) - { - // The database does not support multi inserts. - // Pass data on to sql_multi_insert right away which will - // immediately send an INSERT INTO query to the database. - $this->db->sql_multi_insert($this->table_name, array($row)); - - return true; - } - $this->buffer[] = $row; - if (sizeof($this->buffer) >= $this->max_buffered_rows) + // Flush buffer if it is full or when DB does not support multi inserts. + // In the later case, the buffer will always only contain one row. + if (!$this->db_supports_multi_insert || sizeof($this->buffer) >= $this->max_buffered_rows) { return $this->flush(); } From 1bd13acb753553ed5b9ab54144d0ca6507b031a3 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Wed, 27 Mar 2013 23:37:08 +0100 Subject: [PATCH 079/281] [ticket/11469] Use multi insert property from DB. Do not copy value to buffer. PHPBB3-11469 --- phpBB/includes/db/sql_insert_buffer.php | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/phpBB/includes/db/sql_insert_buffer.php b/phpBB/includes/db/sql_insert_buffer.php index 03c8a875b9..46d397e7b4 100644 --- a/phpBB/includes/db/sql_insert_buffer.php +++ b/phpBB/includes/db/sql_insert_buffer.php @@ -58,9 +58,6 @@ class phpbb_db_sql_insert_buffer /** @var phpbb_db_driver */ protected $db; - /** @var bool */ - protected $db_supports_multi_insert; - /** @var string */ protected $table_name; @@ -78,7 +75,6 @@ class phpbb_db_sql_insert_buffer public function __construct(phpbb_db_driver $db, $table_name, $max_buffered_rows = 500) { $this->db = $db; - $this->db_supports_multi_insert = $db->multi_insert; $this->table_name = $table_name; $this->max_buffered_rows = $max_buffered_rows; } @@ -100,7 +96,7 @@ class phpbb_db_sql_insert_buffer // Flush buffer if it is full or when DB does not support multi inserts. // In the later case, the buffer will always only contain one row. - if (!$this->db_supports_multi_insert || sizeof($this->buffer) >= $this->max_buffered_rows) + if (!$this->db->multi_insert || sizeof($this->buffer) >= $this->max_buffered_rows) { return $this->flush(); } From b48c4d9549acaff8bbe7846b2390267ccd36d39a Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Wed, 27 Mar 2013 23:45:10 +0100 Subject: [PATCH 080/281] [ticket/11469] Use setUp() to setup DB and a buffer with size 2. PHPBB3-11469 --- tests/dbal/sql_insert_buffer_test.php | 104 ++++++++++++-------------- 1 file changed, 47 insertions(+), 57 deletions(-) diff --git a/tests/dbal/sql_insert_buffer_test.php b/tests/dbal/sql_insert_buffer_test.php index 650a42c36d..bc6508b30a 100644 --- a/tests/dbal/sql_insert_buffer_test.php +++ b/tests/dbal/sql_insert_buffer_test.php @@ -9,6 +9,17 @@ class phpbb_dbal_sql_insert_buffer_test extends phpbb_database_test_case { + protected $db; + protected $buffer; + + public function setUp() + { + parent::setUp(); + + $this->db = $this->new_dbal(); + $this->buffer = new phpbb_db_sql_insert_buffer($this->db, 'phpbb_config', 2); + } + public function getDataSet() { return $this->createXMLDataSet(dirname(__FILE__).'/fixtures/config.xml'); @@ -16,130 +27,109 @@ class phpbb_dbal_sql_insert_buffer_test extends phpbb_database_test_case public function test_multi_insert_disabled_insert_and_flush() { - $db = $this->new_dbal(); - $db->multi_insert = false; + $this->db->multi_insert = false; - $buffer = new phpbb_db_sql_insert_buffer($db, 'phpbb_config', 2); - - $this->assert_config_count($db, 2); + $this->assert_config_count(2); // This call can be buffered - $this->assertTrue($buffer->insert($this->get_row(1))); + $this->assertTrue($this->buffer->insert($this->get_row(1))); - $this->assert_config_count($db, 3); + $this->assert_config_count(3); // Manually flush - $this->assertFalse($buffer->flush()); + $this->assertFalse($this->buffer->flush()); - $this->assert_config_count($db, 3); + $this->assert_config_count(3); } public function test_multi_insert_enabled_insert_and_flush() { - $db = $this->new_dbal(); - - if (!$db->multi_insert) + if (!$this->db->multi_insert) { $this->markTestSkipped('Database does not support multi_insert'); } - $buffer = new phpbb_db_sql_insert_buffer($db, 'phpbb_config', 2); - - $this->assert_config_count($db, 2); + $this->assert_config_count(2); // This call can be buffered - $this->assertFalse($buffer->insert($this->get_row(1))); + $this->assertFalse($this->buffer->insert($this->get_row(1))); - $this->assert_config_count($db, 2); + $this->assert_config_count(2); // Manually flush - $this->assertTrue($buffer->flush()); + $this->assertTrue($this->buffer->flush()); - $this->assert_config_count($db, 3); + $this->assert_config_count(3); } public function test_multi_insert_disabled_insert_with_flush() { - $db = $this->new_dbal(); - $db->multi_insert = false; + $this->db->multi_insert = false; - $buffer = new phpbb_db_sql_insert_buffer($db, 'phpbb_config', 2); + $this->assert_config_count(2); - $this->assert_config_count($db, 2); - - $this->assertTrue($buffer->insert($this->get_row(1))); + $this->assertTrue($this->buffer->insert($this->get_row(1))); // This call flushes the values - $this->assertTrue($buffer->insert($this->get_row(2))); + $this->assertTrue($this->buffer->insert($this->get_row(2))); - $this->assert_config_count($db, 4); + $this->assert_config_count(4); } public function test_multi_insert_enabled_insert_with_flush() { - $db = $this->new_dbal(); - - if (!$db->multi_insert) + if (!$this->db->multi_insert) { $this->markTestSkipped('Database does not support multi_insert'); } - $buffer = new phpbb_db_sql_insert_buffer($db, 'phpbb_config', 2); + $this->assert_config_count(2); - $this->assert_config_count($db, 2); - - $this->assertFalse($buffer->insert($this->get_row(1))); + $this->assertFalse($this->buffer->insert($this->get_row(1))); // This call flushes the values - $this->assertTrue($buffer->insert($this->get_row(2))); + $this->assertTrue($this->buffer->insert($this->get_row(2))); - $this->assert_config_count($db, 4); + $this->assert_config_count(4); } public function test_multi_insert_disabled_insert_all_and_flush() { - $db = $this->new_dbal(); - $db->multi_insert = false; + $this->db->multi_insert = false; - $buffer = new phpbb_db_sql_insert_buffer($db, 'phpbb_config', 2); + $this->assert_config_count(2); - $this->assert_config_count($db, 2); + $this->assertTrue($this->buffer->insert_all($this->get_three_rows())); - $this->assertTrue($buffer->insert_all($this->get_three_rows())); - - $this->assert_config_count($db, 5); + $this->assert_config_count(5); } public function test_multi_insert_enabled_insert_all_and_flush() { - $db = $this->new_dbal(); - - if (!$db->multi_insert) + if (!$this->db->multi_insert) { $this->markTestSkipped('Database does not support multi_insert'); } - $buffer = new phpbb_db_sql_insert_buffer($db, 'phpbb_config', 2); + $this->assert_config_count(2); - $this->assert_config_count($db, 2); + $this->assertTrue($this->buffer->insert_all($this->get_three_rows())); - $this->assertTrue($buffer->insert_all($this->get_three_rows())); - - $this->assert_config_count($db, 4); + $this->assert_config_count(4); // Manually flush - $this->assertTrue($buffer->flush()); + $this->assertTrue($this->buffer->flush()); - $this->assert_config_count($db, 5); + $this->assert_config_count(5); } - protected function assert_config_count($db, $num_configs) + protected function assert_config_count($num_configs) { $sql = 'SELECT COUNT(*) AS num_configs FROM phpbb_config'; - $result = $db->sql_query($sql); - $this->assertEquals($num_configs, $db->sql_fetchfield('num_configs')); - $db->sql_freeresult($result); + $result = $this->db->sql_query($sql); + $this->assertEquals($num_configs, $this->db->sql_fetchfield('num_configs')); + $this->db->sql_freeresult($result); } protected function get_row($rownum) From c909d9602b8a8d91d9c6cd72e01c1ddf21dcf593 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Wed, 27 Mar 2013 23:46:39 +0100 Subject: [PATCH 081/281] [ticket/11469] Do not repeat assert_config_count(2). Also move to setUp(). PHPBB3-11469 --- tests/dbal/sql_insert_buffer_test.php | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/tests/dbal/sql_insert_buffer_test.php b/tests/dbal/sql_insert_buffer_test.php index bc6508b30a..4aad852149 100644 --- a/tests/dbal/sql_insert_buffer_test.php +++ b/tests/dbal/sql_insert_buffer_test.php @@ -18,6 +18,7 @@ class phpbb_dbal_sql_insert_buffer_test extends phpbb_database_test_case $this->db = $this->new_dbal(); $this->buffer = new phpbb_db_sql_insert_buffer($this->db, 'phpbb_config', 2); + $this->assert_config_count(2); } public function getDataSet() @@ -29,8 +30,6 @@ class phpbb_dbal_sql_insert_buffer_test extends phpbb_database_test_case { $this->db->multi_insert = false; - $this->assert_config_count(2); - // This call can be buffered $this->assertTrue($this->buffer->insert($this->get_row(1))); @@ -49,8 +48,6 @@ class phpbb_dbal_sql_insert_buffer_test extends phpbb_database_test_case $this->markTestSkipped('Database does not support multi_insert'); } - $this->assert_config_count(2); - // This call can be buffered $this->assertFalse($this->buffer->insert($this->get_row(1))); @@ -66,8 +63,6 @@ class phpbb_dbal_sql_insert_buffer_test extends phpbb_database_test_case { $this->db->multi_insert = false; - $this->assert_config_count(2); - $this->assertTrue($this->buffer->insert($this->get_row(1))); // This call flushes the values @@ -83,8 +78,6 @@ class phpbb_dbal_sql_insert_buffer_test extends phpbb_database_test_case $this->markTestSkipped('Database does not support multi_insert'); } - $this->assert_config_count(2); - $this->assertFalse($this->buffer->insert($this->get_row(1))); // This call flushes the values @@ -97,8 +90,6 @@ class phpbb_dbal_sql_insert_buffer_test extends phpbb_database_test_case { $this->db->multi_insert = false; - $this->assert_config_count(2); - $this->assertTrue($this->buffer->insert_all($this->get_three_rows())); $this->assert_config_count(5); @@ -111,8 +102,6 @@ class phpbb_dbal_sql_insert_buffer_test extends phpbb_database_test_case $this->markTestSkipped('Database does not support multi_insert'); } - $this->assert_config_count(2); - $this->assertTrue($this->buffer->insert_all($this->get_three_rows())); $this->assert_config_count(4); From eacd0f3e7d200924a1d98d1ce34a454eda707dd4 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Wed, 27 Mar 2013 23:48:48 +0100 Subject: [PATCH 082/281] [ticket/11469] Fix spacing in getDataSet(). PHPBB3-11469 --- tests/dbal/sql_insert_buffer_test.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/dbal/sql_insert_buffer_test.php b/tests/dbal/sql_insert_buffer_test.php index 4aad852149..bd03fb9c05 100644 --- a/tests/dbal/sql_insert_buffer_test.php +++ b/tests/dbal/sql_insert_buffer_test.php @@ -23,7 +23,7 @@ class phpbb_dbal_sql_insert_buffer_test extends phpbb_database_test_case public function getDataSet() { - return $this->createXMLDataSet(dirname(__FILE__).'/fixtures/config.xml'); + return $this->createXMLDataSet(dirname(__FILE__) . '/fixtures/config.xml'); } public function test_multi_insert_disabled_insert_and_flush() From 6f946e2188d08bdc939e56143bff9e663c0b6931 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Wed, 27 Mar 2013 23:53:03 +0100 Subject: [PATCH 083/281] [ticket/11469] Refactor get_three_rows() into get_rows($n). PHPBB3-11469 --- tests/dbal/sql_insert_buffer_test.php | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/tests/dbal/sql_insert_buffer_test.php b/tests/dbal/sql_insert_buffer_test.php index bd03fb9c05..f06df26b0c 100644 --- a/tests/dbal/sql_insert_buffer_test.php +++ b/tests/dbal/sql_insert_buffer_test.php @@ -90,7 +90,7 @@ class phpbb_dbal_sql_insert_buffer_test extends phpbb_database_test_case { $this->db->multi_insert = false; - $this->assertTrue($this->buffer->insert_all($this->get_three_rows())); + $this->assertTrue($this->buffer->insert_all($this->get_rows(3))); $this->assert_config_count(5); } @@ -102,7 +102,7 @@ class phpbb_dbal_sql_insert_buffer_test extends phpbb_database_test_case $this->markTestSkipped('Database does not support multi_insert'); } - $this->assertTrue($this->buffer->insert_all($this->get_three_rows())); + $this->assertTrue($this->buffer->insert_all($this->get_rows(3))); $this->assert_config_count(4); @@ -130,12 +130,13 @@ class phpbb_dbal_sql_insert_buffer_test extends phpbb_database_test_case ); } - protected function get_three_rows() + protected function get_rows($n) { - return array( - $this->get_row(1), - $this->get_row(2), - $this->get_row(3), - ); + $result = array(); + for ($i = 0; $i < $n; ++$i) + { + $result[] = $this->get_row($i); + } + return $result; } } From a04fe625a86c0b1fcc037687afec39c659fbd830 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Wed, 27 Mar 2013 23:55:26 +0100 Subject: [PATCH 084/281] [ticket/11469] Do not repeat markTestSkipped() message. PHPBB3-11469 --- tests/dbal/sql_insert_buffer_test.php | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/tests/dbal/sql_insert_buffer_test.php b/tests/dbal/sql_insert_buffer_test.php index f06df26b0c..9357278a62 100644 --- a/tests/dbal/sql_insert_buffer_test.php +++ b/tests/dbal/sql_insert_buffer_test.php @@ -43,10 +43,7 @@ class phpbb_dbal_sql_insert_buffer_test extends phpbb_database_test_case public function test_multi_insert_enabled_insert_and_flush() { - if (!$this->db->multi_insert) - { - $this->markTestSkipped('Database does not support multi_insert'); - } + $this->check_multi_insert_support(); // This call can be buffered $this->assertFalse($this->buffer->insert($this->get_row(1))); @@ -73,10 +70,7 @@ class phpbb_dbal_sql_insert_buffer_test extends phpbb_database_test_case public function test_multi_insert_enabled_insert_with_flush() { - if (!$this->db->multi_insert) - { - $this->markTestSkipped('Database does not support multi_insert'); - } + $this->check_multi_insert_support(); $this->assertFalse($this->buffer->insert($this->get_row(1))); @@ -97,10 +91,7 @@ class phpbb_dbal_sql_insert_buffer_test extends phpbb_database_test_case public function test_multi_insert_enabled_insert_all_and_flush() { - if (!$this->db->multi_insert) - { - $this->markTestSkipped('Database does not support multi_insert'); - } + $this->check_multi_insert_support(); $this->assertTrue($this->buffer->insert_all($this->get_rows(3))); @@ -121,6 +112,14 @@ class phpbb_dbal_sql_insert_buffer_test extends phpbb_database_test_case $this->db->sql_freeresult($result); } + protected function check_multi_insert_support() + { + if (!$this->db->multi_insert) + { + $this->markTestSkipped('Database does not support multi_insert'); + } + } + protected function get_row($rownum) { return array( From e022a7e8f602de67472e4ea5b6ecb6280f4054e4 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Thu, 28 Mar 2013 00:03:48 +0100 Subject: [PATCH 085/281] [ticket/11469] Remove comments. Method names should be good enough now. PHPBB3-11469 --- tests/dbal/sql_insert_buffer_test.php | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/tests/dbal/sql_insert_buffer_test.php b/tests/dbal/sql_insert_buffer_test.php index 9357278a62..04ef6a3d52 100644 --- a/tests/dbal/sql_insert_buffer_test.php +++ b/tests/dbal/sql_insert_buffer_test.php @@ -29,77 +29,50 @@ class phpbb_dbal_sql_insert_buffer_test extends phpbb_database_test_case public function test_multi_insert_disabled_insert_and_flush() { $this->db->multi_insert = false; - - // This call can be buffered $this->assertTrue($this->buffer->insert($this->get_row(1))); - $this->assert_config_count(3); - - // Manually flush $this->assertFalse($this->buffer->flush()); - $this->assert_config_count(3); } public function test_multi_insert_enabled_insert_and_flush() { $this->check_multi_insert_support(); - - // This call can be buffered $this->assertFalse($this->buffer->insert($this->get_row(1))); - $this->assert_config_count(2); - - // Manually flush $this->assertTrue($this->buffer->flush()); - $this->assert_config_count(3); } public function test_multi_insert_disabled_insert_with_flush() { $this->db->multi_insert = false; - $this->assertTrue($this->buffer->insert($this->get_row(1))); - - // This call flushes the values $this->assertTrue($this->buffer->insert($this->get_row(2))); - $this->assert_config_count(4); } public function test_multi_insert_enabled_insert_with_flush() { $this->check_multi_insert_support(); - $this->assertFalse($this->buffer->insert($this->get_row(1))); - - // This call flushes the values $this->assertTrue($this->buffer->insert($this->get_row(2))); - $this->assert_config_count(4); } public function test_multi_insert_disabled_insert_all_and_flush() { $this->db->multi_insert = false; - $this->assertTrue($this->buffer->insert_all($this->get_rows(3))); - $this->assert_config_count(5); } public function test_multi_insert_enabled_insert_all_and_flush() { $this->check_multi_insert_support(); - $this->assertTrue($this->buffer->insert_all($this->get_rows(3))); - $this->assert_config_count(4); - - // Manually flush $this->assertTrue($this->buffer->flush()); - $this->assert_config_count(5); } From e3a6935de6185bde189e53452fca024ef9474c1b Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Thu, 28 Mar 2013 00:20:24 +0100 Subject: [PATCH 086/281] [ticket/11469] Add more table status assertions. PHPBB3-11469 --- tests/dbal/sql_insert_buffer_test.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/dbal/sql_insert_buffer_test.php b/tests/dbal/sql_insert_buffer_test.php index 04ef6a3d52..45339a6b50 100644 --- a/tests/dbal/sql_insert_buffer_test.php +++ b/tests/dbal/sql_insert_buffer_test.php @@ -48,6 +48,7 @@ class phpbb_dbal_sql_insert_buffer_test extends phpbb_database_test_case { $this->db->multi_insert = false; $this->assertTrue($this->buffer->insert($this->get_row(1))); + $this->assert_config_count(3); $this->assertTrue($this->buffer->insert($this->get_row(2))); $this->assert_config_count(4); } @@ -56,6 +57,7 @@ class phpbb_dbal_sql_insert_buffer_test extends phpbb_database_test_case { $this->check_multi_insert_support(); $this->assertFalse($this->buffer->insert($this->get_row(1))); + $this->assert_config_count(2); $this->assertTrue($this->buffer->insert($this->get_row(2))); $this->assert_config_count(4); } From 4bd5f279dc98f036021c04172ecbb30c092de59f Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Thu, 28 Mar 2013 00:27:02 +0100 Subject: [PATCH 087/281] [ticket/11469] Add comment about using bitwise operator. PHPBB3-11469 --- phpBB/includes/db/sql_insert_buffer.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/phpBB/includes/db/sql_insert_buffer.php b/phpBB/includes/db/sql_insert_buffer.php index 46d397e7b4..c18f908429 100644 --- a/phpBB/includes/db/sql_insert_buffer.php +++ b/phpBB/includes/db/sql_insert_buffer.php @@ -118,11 +118,12 @@ class phpbb_db_sql_insert_buffer */ public function insert_all(array $rows) { - $result = false; + // Using bitwise |= because PHP does not have logical ||= + $result = 0; foreach ($rows as $row) { - $result |= $this->insert($row); + $result |= (int) $this->insert($row); } return (bool) $result; From 9e5cde7f668a614ff74dc15d9c72df48dd114dbc Mon Sep 17 00:00:00 2001 From: Tabitha Backoff Date: Thu, 28 Mar 2013 02:34:36 -0400 Subject: [PATCH 088/281] Ticket# 11477 - Allow customisation of "Board index" --- phpBB/includes/acp/acp_board.php | 1 + phpBB/includes/db/migration/data/310/dev.php | 2 ++ phpBB/includes/functions.php | 2 +- phpBB/install/schemas/schema_data.sql | 1 + phpBB/language/en/acp/board.php | 2 ++ 5 files changed, 7 insertions(+), 1 deletion(-) diff --git a/phpBB/includes/acp/acp_board.php b/phpBB/includes/acp/acp_board.php index 6543427677..e609eab01e 100644 --- a/phpBB/includes/acp/acp_board.php +++ b/phpBB/includes/acp/acp_board.php @@ -55,6 +55,7 @@ class acp_board 'site_desc' => array('lang' => 'SITE_DESC', 'validate' => 'string', 'type' => 'text:40:255', 'explain' => false), 'site_home_url' => array('lang' => 'SITE_HOME_URL', 'validate' => 'string', 'type' => 'text:40:255', 'explain' => true), 'site_home_text' => array('lang' => 'SITE_HOME_TEXT', 'validate' => 'string', 'type' => 'text:40:255', 'explain' => true), + 'board_home_text' => array('lang' => 'BOARD_HOME_TEXT', 'validate' => 'string', 'type' => 'text:40:255', 'explain' => true), 'board_disable' => array('lang' => 'DISABLE_BOARD', 'validate' => 'bool', 'type' => 'custom', 'method' => 'board_disable', 'explain' => true), 'board_disable_msg' => false, 'default_lang' => array('lang' => 'DEFAULT_LANGUAGE', 'validate' => 'lang', 'type' => 'select', 'function' => 'language_select', 'params' => array('{CONFIG_VALUE}'), 'explain' => false), diff --git a/phpBB/includes/db/migration/data/310/dev.php b/phpBB/includes/db/migration/data/310/dev.php index 13b36bbf30..950d84c09e 100644 --- a/phpBB/includes/db/migration/data/310/dev.php +++ b/phpBB/includes/db/migration/data/310/dev.php @@ -108,6 +108,8 @@ class phpbb_db_migration_data_310_dev extends phpbb_db_migration array('config.add', array('site_home_url', '')), array('config.add', array('site_home_text', '')), + array('config.add', array('board_home_text', '')), + array('permission.add', array('u_chgprofileinfo', true, 'u_sig')), array('module.add', array( diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index 98a2c0db79..0dca9bb2dc 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -5292,7 +5292,7 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0 'BOARD_URL' => $board_url, 'L_LOGIN_LOGOUT' => $l_login_logout, - 'L_INDEX' => $user->lang['FORUM_INDEX'], + 'L_INDEX' => ($config['board_home_text'] !== '') ? $config['board_home_text'] : $user->lang['FORUM_INDEX'], 'L_SITE_HOME' => ($config['site_home_text'] !== '') ? $config['site_home_text'] : $user->lang['HOME'], 'L_ONLINE_EXPLAIN' => $l_online_time, diff --git a/phpBB/install/schemas/schema_data.sql b/phpBB/install/schemas/schema_data.sql index c25925a9c8..62f9618364 100644 --- a/phpBB/install/schemas/schema_data.sql +++ b/phpBB/install/schemas/schema_data.sql @@ -59,6 +59,7 @@ INSERT INTO phpbb_config (config_name, config_value) VALUES ('board_email', 'add INSERT INTO phpbb_config (config_name, config_value) VALUES ('board_email_form', '0'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('board_email_sig', '{L_CONFIG_BOARD_EMAIL_SIG}'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('board_hide_emails', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('board_home_text', ''); INSERT INTO phpbb_config (config_name, config_value) VALUES ('board_timezone', 'UTC'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('browser_check', '1'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('bump_interval', '10'); diff --git a/phpBB/language/en/acp/board.php b/phpBB/language/en/acp/board.php index ff686f2360..bfc2a22e39 100644 --- a/phpBB/language/en/acp/board.php +++ b/phpBB/language/en/acp/board.php @@ -37,6 +37,8 @@ if (empty($lang) || !is_array($lang)) // Board Settings $lang = array_merge($lang, array( 'ACP_BOARD_SETTINGS_EXPLAIN' => 'Here you can determine the basic operation of your board, give it a fitting name and description, and among other settings adjust the default values for timezone and language.', + 'BOARD_HOME_TEXT' => 'Board index text', + 'BOARD_HOME_TEXT_EXPLAIN' => 'This text is displayed as the board index in the board’s breadcrumbs. If not specified, it will default to “Board index”.', 'CUSTOM_DATEFORMAT' => 'Custom…', 'DEFAULT_DATE_FORMAT' => 'Date format', 'DEFAULT_DATE_FORMAT_EXPLAIN' => 'The date format is the same as the PHP date function.', From a8f5695666229512ccd5d122daa0a7ad7004015b Mon Sep 17 00:00:00 2001 From: Tabitha Backoff Date: Thu, 28 Mar 2013 17:53:14 -0400 Subject: [PATCH 089/281] Migration file and change board_home_text to board_index_text --- phpBB/includes/acp/acp_board.php | 2 +- .../db/migration/data/310/boardindex.php | 23 +++++++++++++++++++ phpBB/includes/db/migration/data/310/dev.php | 2 -- phpBB/includes/functions.php | 2 +- phpBB/install/schemas/schema_data.sql | 2 +- phpBB/language/en/acp/board.php | 4 ++-- 6 files changed, 28 insertions(+), 7 deletions(-) create mode 100644 phpBB/includes/db/migration/data/310/boardindex.php diff --git a/phpBB/includes/acp/acp_board.php b/phpBB/includes/acp/acp_board.php index e609eab01e..bacf0d6e57 100644 --- a/phpBB/includes/acp/acp_board.php +++ b/phpBB/includes/acp/acp_board.php @@ -55,7 +55,7 @@ class acp_board 'site_desc' => array('lang' => 'SITE_DESC', 'validate' => 'string', 'type' => 'text:40:255', 'explain' => false), 'site_home_url' => array('lang' => 'SITE_HOME_URL', 'validate' => 'string', 'type' => 'text:40:255', 'explain' => true), 'site_home_text' => array('lang' => 'SITE_HOME_TEXT', 'validate' => 'string', 'type' => 'text:40:255', 'explain' => true), - 'board_home_text' => array('lang' => 'BOARD_HOME_TEXT', 'validate' => 'string', 'type' => 'text:40:255', 'explain' => true), + 'board_index_text' => array('lang' => 'BOARD_INDEX_TEXT', 'validate' => 'string', 'type' => 'text:40:255', 'explain' => true), 'board_disable' => array('lang' => 'DISABLE_BOARD', 'validate' => 'bool', 'type' => 'custom', 'method' => 'board_disable', 'explain' => true), 'board_disable_msg' => false, 'default_lang' => array('lang' => 'DEFAULT_LANGUAGE', 'validate' => 'lang', 'type' => 'select', 'function' => 'language_select', 'params' => array('{CONFIG_VALUE}'), 'explain' => false), diff --git a/phpBB/includes/db/migration/data/310/boardindex.php b/phpBB/includes/db/migration/data/310/boardindex.php new file mode 100644 index 0000000000..5a1ff62a47 --- /dev/null +++ b/phpBB/includes/db/migration/data/310/boardindex.php @@ -0,0 +1,23 @@ +config['version'], '3.1.0-dev', '>='); + } + + public function update_data() + { + return array( + array('config.add', array('board_index_text', '')), + ); + } +} diff --git a/phpBB/includes/db/migration/data/310/dev.php b/phpBB/includes/db/migration/data/310/dev.php index 950d84c09e..13b36bbf30 100644 --- a/phpBB/includes/db/migration/data/310/dev.php +++ b/phpBB/includes/db/migration/data/310/dev.php @@ -108,8 +108,6 @@ class phpbb_db_migration_data_310_dev extends phpbb_db_migration array('config.add', array('site_home_url', '')), array('config.add', array('site_home_text', '')), - array('config.add', array('board_home_text', '')), - array('permission.add', array('u_chgprofileinfo', true, 'u_sig')), array('module.add', array( diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index 0dca9bb2dc..58d2ad4760 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -5292,7 +5292,7 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0 'BOARD_URL' => $board_url, 'L_LOGIN_LOGOUT' => $l_login_logout, - 'L_INDEX' => ($config['board_home_text'] !== '') ? $config['board_home_text'] : $user->lang['FORUM_INDEX'], + 'L_INDEX' => ($config['board_index_text'] !== '') ? $config['board_index_text'] : $user->lang['FORUM_INDEX'], 'L_SITE_HOME' => ($config['site_home_text'] !== '') ? $config['site_home_text'] : $user->lang['HOME'], 'L_ONLINE_EXPLAIN' => $l_online_time, diff --git a/phpBB/install/schemas/schema_data.sql b/phpBB/install/schemas/schema_data.sql index 62f9618364..8a8740a220 100644 --- a/phpBB/install/schemas/schema_data.sql +++ b/phpBB/install/schemas/schema_data.sql @@ -59,7 +59,7 @@ INSERT INTO phpbb_config (config_name, config_value) VALUES ('board_email', 'add INSERT INTO phpbb_config (config_name, config_value) VALUES ('board_email_form', '0'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('board_email_sig', '{L_CONFIG_BOARD_EMAIL_SIG}'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('board_hide_emails', '1'); -INSERT INTO phpbb_config (config_name, config_value) VALUES ('board_home_text', ''); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('board_index_text', ''); INSERT INTO phpbb_config (config_name, config_value) VALUES ('board_timezone', 'UTC'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('browser_check', '1'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('bump_interval', '10'); diff --git a/phpBB/language/en/acp/board.php b/phpBB/language/en/acp/board.php index bfc2a22e39..f387158a0b 100644 --- a/phpBB/language/en/acp/board.php +++ b/phpBB/language/en/acp/board.php @@ -37,8 +37,8 @@ if (empty($lang) || !is_array($lang)) // Board Settings $lang = array_merge($lang, array( 'ACP_BOARD_SETTINGS_EXPLAIN' => 'Here you can determine the basic operation of your board, give it a fitting name and description, and among other settings adjust the default values for timezone and language.', - 'BOARD_HOME_TEXT' => 'Board index text', - 'BOARD_HOME_TEXT_EXPLAIN' => 'This text is displayed as the board index in the board’s breadcrumbs. If not specified, it will default to “Board index”.', + 'BOARD_INDEX_TEXT' => 'Board index text', + 'BOARD_INDEX_TEXT_EXPLAIN' => 'This text is displayed as the board index in the board’s breadcrumbs. If not specified, it will default to “Board index”.', 'CUSTOM_DATEFORMAT' => 'Custom…', 'DEFAULT_DATE_FORMAT' => 'Date format', 'DEFAULT_DATE_FORMAT_EXPLAIN' => 'The date format is the same as the PHP date function.', From 6910d441546f5213eab11b2329b49e5a6626ad67 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Sun, 17 Mar 2013 22:15:10 +0100 Subject: [PATCH 090/281] [ticket/11403] phpbb_notification_manager: Use SQL multi insert in batches. PHPBB3-11403 --- phpBB/includes/notification/manager.php | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/phpBB/includes/notification/manager.php b/phpBB/includes/notification/manager.php index 4e26234390..ee81cc0f7c 100644 --- a/phpBB/includes/notification/manager.php +++ b/phpBB/includes/notification/manager.php @@ -430,6 +430,13 @@ class phpbb_notification_manager // Store the creation array in our new rows that will be inserted later $new_rows[] = $notification->create_insert_array($data, $pre_create_data); + // Flush to DB if $new_rows is big enough. + if (sizeof($new_rows) > 500) + { + $this->db->sql_multi_insert($this->notifications_table, $new_rows); + $new_rows = array(); + } + // Users are needed to send notifications $user_ids = array_merge($user_ids, $notification->users_to_query()); @@ -448,8 +455,10 @@ class phpbb_notification_manager } } - // insert into the db - $this->db->sql_multi_insert($this->notifications_table, $new_rows); + if (!empty($new_rows)) + { + $this->db->sql_multi_insert($this->notifications_table, $new_rows); + } // We need to load all of the users to send notifications $this->user_loader->load_users($user_ids); From b156b22f35eab64a9780167bfe8d515f2e2a8480 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Fri, 29 Mar 2013 16:44:29 +0100 Subject: [PATCH 091/281] [ticket/11403] Use an instance of phpbb_db_sql_insert_buffer instead. PHPBB3-11403 --- phpBB/includes/notification/manager.php | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/phpBB/includes/notification/manager.php b/phpBB/includes/notification/manager.php index ee81cc0f7c..9eceeb753a 100644 --- a/phpBB/includes/notification/manager.php +++ b/phpBB/includes/notification/manager.php @@ -390,7 +390,6 @@ class phpbb_notification_manager $user_ids = array(); $notification_objects = $notification_methods = array(); - $new_rows = array(); // Never send notifications to the anonymous user! unset($notify_users[ANONYMOUS]); @@ -420,6 +419,8 @@ class phpbb_notification_manager $pre_create_data = $notification->pre_create_insert_array($data, $notify_users); unset($notification); + $insert_buffer = new phpbb_db_sql_insert_buffer($this->db, $this->notifications_table); + // Go through each user so we can insert a row in the DB and then notify them by their desired means foreach ($notify_users as $user => $methods) { @@ -427,15 +428,8 @@ class phpbb_notification_manager $notification->user_id = (int) $user; - // Store the creation array in our new rows that will be inserted later - $new_rows[] = $notification->create_insert_array($data, $pre_create_data); - - // Flush to DB if $new_rows is big enough. - if (sizeof($new_rows) > 500) - { - $this->db->sql_multi_insert($this->notifications_table, $new_rows); - $new_rows = array(); - } + // Insert notification row using buffer. + $insert_buffer->insert($notification->create_insert_array($data, $pre_create_data)); // Users are needed to send notifications $user_ids = array_merge($user_ids, $notification->users_to_query()); @@ -455,10 +449,7 @@ class phpbb_notification_manager } } - if (!empty($new_rows)) - { - $this->db->sql_multi_insert($this->notifications_table, $new_rows); - } + $insert_buffer->flush(); // We need to load all of the users to send notifications $this->user_loader->load_users($user_ids); From 5d669ed1c52250d6f0a378f6aa4ee6538daf86e3 Mon Sep 17 00:00:00 2001 From: Tabitha Backoff Date: Sun, 31 Mar 2013 18:46:25 -0400 Subject: [PATCH 092/281] Changing effectively_installed function to check if the config var is set. --- phpBB/includes/db/migration/data/310/boardindex.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/includes/db/migration/data/310/boardindex.php b/phpBB/includes/db/migration/data/310/boardindex.php index 5a1ff62a47..965e32c15c 100644 --- a/phpBB/includes/db/migration/data/310/boardindex.php +++ b/phpBB/includes/db/migration/data/310/boardindex.php @@ -11,7 +11,7 @@ class phpbb_db_migration_data_310_boardindex extends phpbb_db_migration { public function effectively_installed() { - return version_compare($this->config['version'], '3.1.0-dev', '>='); + return isset($this->config['board_index_text']); } public function update_data() From 7c261f64dc14eaa7321d824e8e75271c5c6a191e Mon Sep 17 00:00:00 2001 From: Dhruv Date: Tue, 9 Apr 2013 15:22:14 +0530 Subject: [PATCH 093/281] [ticket/11485] add columns to styles table during updating schema before updating the data PHPBB3-10485 --- .../db/migration/data/310/style_update_p1.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/phpBB/includes/db/migration/data/310/style_update_p1.php b/phpBB/includes/db/migration/data/310/style_update_p1.php index e324ce7f24..9a936e5f53 100644 --- a/phpBB/includes/db/migration/data/310/style_update_p1.php +++ b/phpBB/includes/db/migration/data/310/style_update_p1.php @@ -19,6 +19,20 @@ class phpbb_db_migration_data_310_style_update_p1 extends phpbb_db_migration return array('phpbb_db_migration_data_30x_3_0_11'); } + public function update_schema() + { + return array( + 'add_columns' => array( + $this->table_prefix . 'styles' => array( + 'style_path' => array('VCHAR:100', ''), + 'bbcode_bitfield' => array('VCHAR:255', 'kNg='), + 'style_parent_id' => array('UINT', 0), + 'style_parent_tree' => array('TEXT', ''), + ), + ), + ); + } + public function update_data() { return array( From 5a4438d486bc9a8738765fb671e584e269353c06 Mon Sep 17 00:00:00 2001 From: Dhruv Date: Tue, 9 Apr 2013 15:38:28 +0530 Subject: [PATCH 094/281] [ticket/11485] add revert_schema for the updated columns PHPBB3-11485 --- .../db/migration/data/310/style_update_p1.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/phpBB/includes/db/migration/data/310/style_update_p1.php b/phpBB/includes/db/migration/data/310/style_update_p1.php index 9a936e5f53..d43537559d 100644 --- a/phpBB/includes/db/migration/data/310/style_update_p1.php +++ b/phpBB/includes/db/migration/data/310/style_update_p1.php @@ -33,6 +33,20 @@ class phpbb_db_migration_data_310_style_update_p1 extends phpbb_db_migration ); } + public function revert_schema() + { + return array( + 'drop_columns' => array( + $this->table_prefix . 'styles' => array( + 'style_path', + 'bbcode_bitfield', + 'style_parent_id', + 'style_parent_tree', + ), + ), + ); + } + public function update_data() { return array( From effc8a9bd0f4d1ad71436b888442e003d353f186 Mon Sep 17 00:00:00 2001 From: hjpotter92 Date: Thu, 11 Apr 2013 00:00:48 +0530 Subject: [PATCH 095/281] [ticket/11225] Deletion of unused mcp_jumpbox.html file The file/template is no longer used(as mentioned in it). PHPBB3-11225 --- .../subsilver2/template/mcp_jumpbox.html | 19 ------------------- 1 file changed, 19 deletions(-) delete mode 100644 phpBB/styles/subsilver2/template/mcp_jumpbox.html diff --git a/phpBB/styles/subsilver2/template/mcp_jumpbox.html b/phpBB/styles/subsilver2/template/mcp_jumpbox.html deleted file mode 100644 index e6ef4ecdad..0000000000 --- a/phpBB/styles/subsilver2/template/mcp_jumpbox.html +++ /dev/null @@ -1,19 +0,0 @@ - - -
    - - {HIDDEN_FIELDS_FOR_JUMPBOX} - {L_JUMP_TO}{L_COLON}   -
    From 694eb3ccb50c064acf7b3f9aba23620111b8814a Mon Sep 17 00:00:00 2001 From: rechosen Date: Thu, 11 Apr 2013 12:47:33 +0200 Subject: [PATCH 096/281] [ticket/11116] Made ACP "extension not available" error message E_USER_WARNING The error message generated when an administrator tries to enable an incompatible extension used to be displayed in the green of the default E_USER_NOTICE. Changed it to E_USER_WARNING to make it appear in red, as requested in the ticket. PHPBB3-11116 --- phpBB/includes/acp/acp_extensions.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/phpBB/includes/acp/acp_extensions.php b/phpBB/includes/acp/acp_extensions.php index 24211196bd..e4f8059b45 100644 --- a/phpBB/includes/acp/acp_extensions.php +++ b/phpBB/includes/acp/acp_extensions.php @@ -81,7 +81,7 @@ class acp_extensions case 'enable_pre': if (!$md_manager->validate_enable()) { - trigger_error($user->lang['EXTENSION_NOT_AVAILABLE'] . adm_back_link($this->u_action)); + trigger_error($user->lang['EXTENSION_NOT_AVAILABLE'] . adm_back_link($this->u_action), E_USER_WARNING); } if ($phpbb_extension_manager->enabled($ext_name)) @@ -100,7 +100,7 @@ class acp_extensions case 'enable': if (!$md_manager->validate_enable()) { - trigger_error($user->lang['EXTENSION_NOT_AVAILABLE'] . adm_back_link($this->u_action)); + trigger_error($user->lang['EXTENSION_NOT_AVAILABLE'] . adm_back_link($this->u_action), E_USER_WARNING); } try From f89b80e1837503295232623ae9af4d4d5eea9595 Mon Sep 17 00:00:00 2001 From: Vjacheslav Trushkin Date: Thu, 11 Apr 2013 14:31:17 +0300 Subject: [PATCH 097/281] [ticket/4412] Shorten long profile fields Shorten long profile fields using CSS PHPBB3-4412 --- phpBB/styles/prosilver/theme/common.css | 2 ++ phpBB/styles/prosilver/theme/content.css | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/phpBB/styles/prosilver/theme/common.css b/phpBB/styles/prosilver/theme/common.css index ed462c770d..26ec23b2e6 100644 --- a/phpBB/styles/prosilver/theme/common.css +++ b/phpBB/styles/prosilver/theme/common.css @@ -476,6 +476,8 @@ dl.details dd { margin-bottom: 5px; float: left; width: 65%; + overflow: hidden; + text-overflow: ellipsis; } .clearfix, #tabs, #minitabs, fieldset dl, ul.topiclist dl, dl.polls { diff --git a/phpBB/styles/prosilver/theme/content.css b/phpBB/styles/prosilver/theme/content.css index b6012f8a63..bf9e587ce1 100644 --- a/phpBB/styles/prosilver/theme/content.css +++ b/phpBB/styles/prosilver/theme/content.css @@ -669,6 +669,11 @@ fieldset.polls dd div { margin-left: 8px; } +.postprofile dd { + overflow: hidden; + text-overflow: ellipsis; +} + .postprofile strong { font-weight: normal; } From 60713c8a203b4d92db016f38cf8d78165d72b30a Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 11 Apr 2013 14:06:08 +0200 Subject: [PATCH 098/281] [ticket/11492] Add functional test for empty teampage PHPBB3-11492 --- tests/functional/memberlist_test.php | 9 +++++ .../phpbb_functional_test_case.php | 40 +++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/tests/functional/memberlist_test.php b/tests/functional/memberlist_test.php index 879bee2f0e..5c5d96d777 100644 --- a/tests/functional/memberlist_test.php +++ b/tests/functional/memberlist_test.php @@ -40,4 +40,13 @@ class phpbb_functional_memberlist_test extends phpbb_functional_test_case $this->assert_response_success(); $this->assertContains('admin', $crawler->filter('h2')->text()); } + + public function test_leaders() + { + $this->login(); + $this->remove_user_group('ADMINISTRATORS', array('admin')); + + $crawler = $this->request('GET', 'memberlist.php?mode=leaders&sid=' . $this->sid); + $this->assert_response_success(); + } } diff --git a/tests/test_framework/phpbb_functional_test_case.php b/tests/test_framework/phpbb_functional_test_case.php index a411d9c98a..283110a104 100644 --- a/tests/test_framework/phpbb_functional_test_case.php +++ b/tests/test_framework/phpbb_functional_test_case.php @@ -316,6 +316,46 @@ class phpbb_functional_test_case extends phpbb_test_case return user_add($user_row); } + protected function remove_user_group($group_name, $usernames) + { + global $db, $cache, $auth, $config, $phpbb_dispatcher, $phpbb_container; + + $config = new phpbb_config(array()); + $config['coppa_enable'] = 0; + + $db = $this->get_db(); + + $cache = new phpbb_mock_null_cache; + + $cache_driver = new phpbb_cache_driver_null(); + $phpbb_container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface'); + $phpbb_container + ->expects($this->any()) + ->method('get') + ->with('cache.driver') + ->will($this->returnValue($cache_driver)); + + if (!function_exists('utf_clean_string')) + { + require_once(__DIR__ . '/../../phpBB/includes/utf/utf_tools.php'); + } + if (!function_exists('group_user_del')) + { + require_once(__DIR__ . '/../../phpBB/includes/functions_user.php'); + } + $phpbb_dispatcher = new phpbb_mock_event_dispatcher(); + $auth = $this->getMock('Observer', array('acl_clear_prefetch')); + + $sql = 'SELECT group_id + FROM ' . GROUPS_TABLE . " + WHERE group_name = '" . $db->sql_escape($group_name) . "'"; + $result = $db->sql_query($sql); + $group_id = (int) $db->sql_fetchfield('group_id'); + $db->sql_freeresult($result); + + return group_user_del($group_id, false, $usernames, $group_name); + } + protected function login($username = 'admin') { $this->add_lang('ucp'); From 59ad90b25c50f0a4062ae5e190b27811c4c0279b Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 11 Apr 2013 15:18:47 +0200 Subject: [PATCH 099/281] [ticket/11492] Add tests for removing/adding users PHPBB3-11492 --- tests/functional/memberlist_test.php | 25 ++++++++- .../phpbb_functional_test_case.php | 52 ++++++++++++++++++- 2 files changed, 75 insertions(+), 2 deletions(-) diff --git a/tests/functional/memberlist_test.php b/tests/functional/memberlist_test.php index 5c5d96d777..f27092aa36 100644 --- a/tests/functional/memberlist_test.php +++ b/tests/functional/memberlist_test.php @@ -44,9 +44,32 @@ class phpbb_functional_memberlist_test extends phpbb_functional_test_case public function test_leaders() { $this->login(); - $this->remove_user_group('ADMINISTRATORS', array('admin')); + $this->create_user('memberlist-test-user'); + $this->create_user('memberlist-test-moderator'); + // Admin should be listed, user not $crawler = $this->request('GET', 'memberlist.php?mode=leaders&sid=' . $this->sid); $this->assert_response_success(); + $this->assertContains('admin', $crawler->filter('tr')->text()); + $this->assertNotContains('memberlist-test-user', $crawler->filter('tr')->text()); + $this->assertNotContains('memberlist-test-moderator', $crawler->filter('tr')->text()); + + // Remove admin from admins, still a moderator + $this->remove_user_group('ADMINISTRATORS', array('admin')); + $crawler = $this->request('GET', 'memberlist.php?mode=leaders&sid=' . $this->sid); + $this->assert_response_success(); + $this->assertContains('admin', $crawler->filter('tr')->text()); + + // Remove admin from moderators + $this->remove_user_group('GLOBAL_MODERATORS', array('admin')); + $crawler = $this->request('GET', 'memberlist.php?mode=leaders&sid=' . $this->sid); + $this->assert_response_success(); + $this->assertNotContains('admin', $crawler->filter('tr')->text()); + + // Add mod to moderators + $this->add_user_group('GLOBAL_MODERATORS', array('memberlist-test-moderator')); + $crawler = $this->request('GET', 'memberlist.php?mode=leaders&sid=' . $this->sid); + $this->assert_response_success(); + $this->assertContains('memberlist-test-moderator', $crawler->filter('tr')->text()); } } diff --git a/tests/test_framework/phpbb_functional_test_case.php b/tests/test_framework/phpbb_functional_test_case.php index 283110a104..3eba57caa7 100644 --- a/tests/test_framework/phpbb_functional_test_case.php +++ b/tests/test_framework/phpbb_functional_test_case.php @@ -318,13 +318,18 @@ class phpbb_functional_test_case extends phpbb_test_case protected function remove_user_group($group_name, $usernames) { - global $db, $cache, $auth, $config, $phpbb_dispatcher, $phpbb_container; + global $db, $cache, $auth, $config, $phpbb_dispatcher, $phpbb_log, $phpbb_container; $config = new phpbb_config(array()); $config['coppa_enable'] = 0; $db = $this->get_db(); + $phpbb_log = $this->getMock('phpbb_log'); + $phpbb_log + ->expects($this->any()) + ->method('add') + ->will($this->returnValue(true)); $cache = new phpbb_mock_null_cache; $cache_driver = new phpbb_cache_driver_null(); @@ -356,6 +361,51 @@ class phpbb_functional_test_case extends phpbb_test_case return group_user_del($group_id, false, $usernames, $group_name); } + protected function add_user_group($group_name, $usernames) + { + global $db, $cache, $auth, $config, $phpbb_dispatcher, $phpbb_log, $phpbb_container; + + $config = new phpbb_config(array()); + $config['coppa_enable'] = 0; + + $db = $this->get_db(); + + $phpbb_log = $this->getMock('phpbb_log'); + $phpbb_log + ->expects($this->any()) + ->method('add') + ->will($this->returnValue(true)); + $cache = new phpbb_mock_null_cache; + + $cache_driver = new phpbb_cache_driver_null(); + $phpbb_container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface'); + $phpbb_container + ->expects($this->any()) + ->method('get') + ->with('cache.driver') + ->will($this->returnValue($cache_driver)); + + if (!function_exists('utf_clean_string')) + { + require_once(__DIR__ . '/../../phpBB/includes/utf/utf_tools.php'); + } + if (!function_exists('group_user_del')) + { + require_once(__DIR__ . '/../../phpBB/includes/functions_user.php'); + } + $phpbb_dispatcher = new phpbb_mock_event_dispatcher(); + $auth = $this->getMock('Observer', array('acl_clear_prefetch')); + + $sql = 'SELECT group_id + FROM ' . GROUPS_TABLE . " + WHERE group_name = '" . $db->sql_escape($group_name) . "'"; + $result = $db->sql_query($sql); + $group_id = (int) $db->sql_fetchfield('group_id'); + $db->sql_freeresult($result); + + return group_user_add($group_id, false, $usernames, $group_name); + } + protected function login($username = 'admin') { $this->add_lang('ucp'); From e5503e20d84c94c66de33500324afb9a4c774c77 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 11 Apr 2013 15:28:55 +0200 Subject: [PATCH 100/281] [ticket/11492] Do not add the user again PHPBB3-11492 --- tests/functional/memberlist_test.php | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/functional/memberlist_test.php b/tests/functional/memberlist_test.php index f27092aa36..c822c06263 100644 --- a/tests/functional/memberlist_test.php +++ b/tests/functional/memberlist_test.php @@ -44,7 +44,6 @@ class phpbb_functional_memberlist_test extends phpbb_functional_test_case public function test_leaders() { $this->login(); - $this->create_user('memberlist-test-user'); $this->create_user('memberlist-test-moderator'); // Admin should be listed, user not From f920c69ad5cbe9d435a2235180dfd5e7dc9905d4 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 11 Apr 2013 15:44:54 +0200 Subject: [PATCH 101/281] [ticket/11492] Split into mutliple tests PHPBB3-11492 --- tests/functional/memberlist_test.php | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/tests/functional/memberlist_test.php b/tests/functional/memberlist_test.php index c822c06263..46d7976230 100644 --- a/tests/functional/memberlist_test.php +++ b/tests/functional/memberlist_test.php @@ -49,26 +49,36 @@ class phpbb_functional_memberlist_test extends phpbb_functional_test_case // Admin should be listed, user not $crawler = $this->request('GET', 'memberlist.php?mode=leaders&sid=' . $this->sid); $this->assert_response_success(); - $this->assertContains('admin', $crawler->filter('tr')->text()); - $this->assertNotContains('memberlist-test-user', $crawler->filter('tr')->text()); - $this->assertNotContains('memberlist-test-moderator', $crawler->filter('tr')->text()); + $this->assertContains('admin', $crawler->text()); + $this->assertNotContains('memberlist-test-user', $crawler->text()); + $this->assertNotContains('memberlist-test-moderator', $crawler->text()); + } + + public function test_leaders_remove_users() + { + $this->login(); // Remove admin from admins, still a moderator $this->remove_user_group('ADMINISTRATORS', array('admin')); $crawler = $this->request('GET', 'memberlist.php?mode=leaders&sid=' . $this->sid); $this->assert_response_success(); - $this->assertContains('admin', $crawler->filter('tr')->text()); + $this->assertContains('admin', $crawler->text()); // Remove admin from moderators $this->remove_user_group('GLOBAL_MODERATORS', array('admin')); $crawler = $this->request('GET', 'memberlist.php?mode=leaders&sid=' . $this->sid); $this->assert_response_success(); - $this->assertNotContains('admin', $crawler->filter('tr')->text()); + $this->assertNotContains('admin', $crawler->text()); + } + + public function test_leaders_add_users() + { + $this->login(); // Add mod to moderators $this->add_user_group('GLOBAL_MODERATORS', array('memberlist-test-moderator')); $crawler = $this->request('GET', 'memberlist.php?mode=leaders&sid=' . $this->sid); $this->assert_response_success(); - $this->assertContains('memberlist-test-moderator', $crawler->filter('tr')->text()); + $this->assertContains('memberlist-test-moderator', $crawler->text()); } } From 7f527e801221bf5638acf0d46a94c0e28ec03331 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 11 Apr 2013 15:59:31 +0200 Subject: [PATCH 102/281] [ticket/11492] Fix issues with log object PHPBB3-11492 --- .../phpbb_functional_test_case.php | 26 +++++++------------ 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/tests/test_framework/phpbb_functional_test_case.php b/tests/test_framework/phpbb_functional_test_case.php index 3eba57caa7..db6a6066e4 100644 --- a/tests/test_framework/phpbb_functional_test_case.php +++ b/tests/test_framework/phpbb_functional_test_case.php @@ -318,18 +318,17 @@ class phpbb_functional_test_case extends phpbb_test_case protected function remove_user_group($group_name, $usernames) { - global $db, $cache, $auth, $config, $phpbb_dispatcher, $phpbb_log, $phpbb_container; + global $db, $cache, $auth, $config, $phpbb_dispatcher, $phpbb_log, $phpbb_container, $phpbb_root_path, $phpEx; $config = new phpbb_config(array()); $config['coppa_enable'] = 0; $db = $this->get_db(); + $phpbb_dispatcher = new phpbb_mock_event_dispatcher(); + $user = $this->getMock('phpbb_user'); + $auth = $this->getMock('phpbb_auth'); - $phpbb_log = $this->getMock('phpbb_log'); - $phpbb_log - ->expects($this->any()) - ->method('add') - ->will($this->returnValue(true)); + $phpbb_log = new phpbb_log($db, $user, $auth, $phpbb_dispatcher, $phpbb_root_path, 'adm/', $phpEx, LOG_TABLE); $cache = new phpbb_mock_null_cache; $cache_driver = new phpbb_cache_driver_null(); @@ -348,8 +347,6 @@ class phpbb_functional_test_case extends phpbb_test_case { require_once(__DIR__ . '/../../phpBB/includes/functions_user.php'); } - $phpbb_dispatcher = new phpbb_mock_event_dispatcher(); - $auth = $this->getMock('Observer', array('acl_clear_prefetch')); $sql = 'SELECT group_id FROM ' . GROUPS_TABLE . " @@ -363,18 +360,17 @@ class phpbb_functional_test_case extends phpbb_test_case protected function add_user_group($group_name, $usernames) { - global $db, $cache, $auth, $config, $phpbb_dispatcher, $phpbb_log, $phpbb_container; + global $db, $cache, $auth, $config, $phpbb_dispatcher, $phpbb_log, $phpbb_container, $phpbb_root_path, $phpEx; $config = new phpbb_config(array()); $config['coppa_enable'] = 0; $db = $this->get_db(); + $phpbb_dispatcher = new phpbb_mock_event_dispatcher(); + $user = $this->getMock('phpbb_user'); + $auth = $this->getMock('phpbb_auth'); - $phpbb_log = $this->getMock('phpbb_log'); - $phpbb_log - ->expects($this->any()) - ->method('add') - ->will($this->returnValue(true)); + $phpbb_log = new phpbb_log($db, $user, $auth, $phpbb_dispatcher, $phpbb_root_path, 'adm/', $phpEx, LOG_TABLE); $cache = new phpbb_mock_null_cache; $cache_driver = new phpbb_cache_driver_null(); @@ -393,8 +389,6 @@ class phpbb_functional_test_case extends phpbb_test_case { require_once(__DIR__ . '/../../phpBB/includes/functions_user.php'); } - $phpbb_dispatcher = new phpbb_mock_event_dispatcher(); - $auth = $this->getMock('Observer', array('acl_clear_prefetch')); $sql = 'SELECT group_id FROM ' . GROUPS_TABLE . " From 4d4cf25edddac7de305f0d291550189ba8a5492e Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 11 Apr 2013 16:28:10 +0200 Subject: [PATCH 103/281] [ticket/11492] Fix the test once more PHPBB3-11492 --- tests/functional/memberlist_test.php | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/tests/functional/memberlist_test.php b/tests/functional/memberlist_test.php index 46d7976230..66e3591f21 100644 --- a/tests/functional/memberlist_test.php +++ b/tests/functional/memberlist_test.php @@ -58,17 +58,11 @@ class phpbb_functional_memberlist_test extends phpbb_functional_test_case { $this->login(); - // Remove admin from admins, still a moderator + // Remove admin from admins $this->remove_user_group('ADMINISTRATORS', array('admin')); $crawler = $this->request('GET', 'memberlist.php?mode=leaders&sid=' . $this->sid); $this->assert_response_success(); $this->assertContains('admin', $crawler->text()); - - // Remove admin from moderators - $this->remove_user_group('GLOBAL_MODERATORS', array('admin')); - $crawler = $this->request('GET', 'memberlist.php?mode=leaders&sid=' . $this->sid); - $this->assert_response_success(); - $this->assertNotContains('admin', $crawler->text()); } public function test_leaders_add_users() From 1296417b526312f3b79d2b64bff86476209fb037 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 11 Apr 2013 16:38:14 +0200 Subject: [PATCH 104/281] [ticket/11492] Initialize $user_ids and $group_users arrays Also avoid unneccessary calls to permissions when user_ids is empty PHPBB3-11492 --- phpBB/memberlist.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/phpBB/memberlist.php b/phpBB/memberlist.php index d25583b84a..e6045b151a 100644 --- a/phpBB/memberlist.php +++ b/phpBB/memberlist.php @@ -146,7 +146,7 @@ switch ($mode) $result = $db->sql_query($db->sql_build_query('SELECT', $sql_ary)); - $user_ary = array(); + $user_ary = $user_ids = $group_users = array(); while ($row = $db->sql_fetchrow($result)) { $row['forums'] = ''; @@ -157,11 +157,13 @@ switch ($mode) } $db->sql_freeresult($result); - if ($config['teampage_forums']) + $user_ids = array_unique($user_ids); + + if (!empty($user_ids) && $config['teampage_forums']) { $template->assign_var('S_DISPLAY_MODERATOR_FORUMS', true); // Get all moderators - $perm_ary = $auth->acl_get_list(array_unique($user_ids), array('m_'), false); + $perm_ary = $auth->acl_get_list($user_ids, array('m_'), false); foreach ($perm_ary as $forum_id => $forum_ary) { From 5c24474c2a85d159d2b76d4483c62ab1e9861222 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 11 Apr 2013 22:11:52 +0200 Subject: [PATCH 105/281] [ticket/11494] Fix memberlist leaders functional tests The scope of the crawler should be reduced to the specific table PHPBB3-11494 --- tests/functional/memberlist_test.php | 32 +++++++++++++++++++++------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/tests/functional/memberlist_test.php b/tests/functional/memberlist_test.php index 66e3591f21..2e3d7907bf 100644 --- a/tests/functional/memberlist_test.php +++ b/tests/functional/memberlist_test.php @@ -46,33 +46,49 @@ class phpbb_functional_memberlist_test extends phpbb_functional_test_case $this->login(); $this->create_user('memberlist-test-moderator'); - // Admin should be listed, user not $crawler = $this->request('GET', 'memberlist.php?mode=leaders&sid=' . $this->sid); $this->assert_response_success(); - $this->assertContains('admin', $crawler->text()); - $this->assertNotContains('memberlist-test-user', $crawler->text()); - $this->assertNotContains('memberlist-test-moderator', $crawler->text()); + + // Admin in admin group, but not in moderators + $this->assertContains('admin', $crawler->filter('.forumbg-table')->eq(0)->text()); + $this->assertNotContains('admin', $crawler->filter('.forumbg-table')->eq(1)->text()); + + // memberlist-test-user in neither group + $this->assertNotContains('memberlist-test-user', $crawler->filter('.forumbg-table')->eq(0)->text()); + $this->assertNotContains('memberlist-test-user', $crawler->filter('.forumbg-table')->eq(1)->text()); + + // memberlist-test-moderator in neither group + $this->assertNotContains('memberlist-test-moderator', $crawler->filter('.forumbg-table')->eq(0)->text()); + $this->assertNotContains('memberlist-test-moderator', $crawler->filter('.forumbg-table')->eq(1)->text()); } public function test_leaders_remove_users() { $this->login(); - // Remove admin from admins + // Remove admin from admins, but is now in moderators $this->remove_user_group('ADMINISTRATORS', array('admin')); $crawler = $this->request('GET', 'memberlist.php?mode=leaders&sid=' . $this->sid); $this->assert_response_success(); - $this->assertContains('admin', $crawler->text()); + $this->assertNotContains('admin', $crawler->filter('.forumbg-table')->eq(0)->text()); + $this->assertContains('admin', $crawler->filter('.forumbg-table')->eq(1)->text()); + + // Remove admin from moderators, should not be visible anymore + $this->remove_user_group('GLOBAL_MODERATORS', array('admin')); + $crawler = $this->request('GET', 'memberlist.php?mode=leaders&sid=' . $this->sid); + $this->assertNotContains('admin', $crawler->filter('.forumbg-table')->eq(0)->text()); + $this->assertNotContains('admin', $crawler->filter('.forumbg-table')->eq(1)->text()); } public function test_leaders_add_users() { $this->login(); - // Add mod to moderators + // Add memberlist-test-moderator to moderators $this->add_user_group('GLOBAL_MODERATORS', array('memberlist-test-moderator')); $crawler = $this->request('GET', 'memberlist.php?mode=leaders&sid=' . $this->sid); $this->assert_response_success(); - $this->assertContains('memberlist-test-moderator', $crawler->text()); + $this->assertNotContains('memberlist-test-moderator', $crawler->filter('.forumbg-table')->eq(0)->text()); + $this->assertContains('memberlist-test-moderator', $crawler->filter('.forumbg-table')->eq(1)->text()); } } From b2b8b62fad58e1c53545212074894a07d7aca6a9 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 12 Apr 2013 01:08:09 +0200 Subject: [PATCH 106/281] [ticket/11491] Move file to correct directory PHPBB3-11491 --- tests/{extension/acp.php => functional/extension_acp_test.php} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename tests/{extension/acp.php => functional/extension_acp_test.php} (100%) diff --git a/tests/extension/acp.php b/tests/functional/extension_acp_test.php similarity index 100% rename from tests/extension/acp.php rename to tests/functional/extension_acp_test.php From 4c99229be81332b6c2bce11b98ae6538e07d141f Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 12 Apr 2013 01:08:40 +0200 Subject: [PATCH 107/281] [ticket/11491] Fix class name of functional test PHPBB3-11491 --- tests/functional/extension_acp_test.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/functional/extension_acp_test.php b/tests/functional/extension_acp_test.php index 790df77c0d..1ecff49353 100644 --- a/tests/functional/extension_acp_test.php +++ b/tests/functional/extension_acp_test.php @@ -7,7 +7,7 @@ * */ -class acp_test extends phpbb_functional_test_case +class phpbb_functional_extension_acp_test extends phpbb_functional_test_case { static private $copied_files = array(); static private $helper; From 08e7bd6166f28b106be28d6eb947ed950bedeaa1 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 12 Apr 2013 01:09:09 +0200 Subject: [PATCH 108/281] [ticket/11491] Add extension_acp_test.php to functional group PHPBB3-11491 --- tests/functional/extension_acp_test.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/functional/extension_acp_test.php b/tests/functional/extension_acp_test.php index 1ecff49353..399af2b452 100644 --- a/tests/functional/extension_acp_test.php +++ b/tests/functional/extension_acp_test.php @@ -7,6 +7,9 @@ * */ +/** +* @group functional +*/ class phpbb_functional_extension_acp_test extends phpbb_functional_test_case { static private $copied_files = array(); From 56bcf7497e6b866d67d8c7e2f8b679d2190639a7 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 12 Apr 2013 01:10:09 +0200 Subject: [PATCH 109/281] [ticket/11491] Fix path to the ext/ folder PHPBB3-11491 --- tests/functional/extension_acp_test.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/functional/extension_acp_test.php b/tests/functional/extension_acp_test.php index 399af2b452..4dab5ecf82 100644 --- a/tests/functional/extension_acp_test.php +++ b/tests/functional/extension_acp_test.php @@ -34,7 +34,7 @@ class phpbb_functional_extension_acp_test extends phpbb_functional_test_case self::$helper->empty_dir($phpbb_root_path . 'ext/'); // Copy our ext/ files from the test case to the board - self::$copied_files = array_merge(self::$copied_files, self::$helper->copy_dir(dirname(__FILE__) . '/ext/', $phpbb_root_path . 'ext/')); + self::$copied_files = array_merge(self::$copied_files, self::$helper->copy_dir(dirname(__FILE__) . '/../extension/ext/', $phpbb_root_path . 'ext/')); } public function setUp() From 0b64db275bae14649e09031483b03ccc1943310b Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 12 Apr 2013 01:40:45 +0200 Subject: [PATCH 110/281] [ticket/11491] Correctly remove the store/temp_ext/ directory after use PHPBB3-11491 --- tests/functional/extension_acp_test.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/functional/extension_acp_test.php b/tests/functional/extension_acp_test.php index 4dab5ecf82..e829e4582e 100644 --- a/tests/functional/extension_acp_test.php +++ b/tests/functional/extension_acp_test.php @@ -90,10 +90,10 @@ class phpbb_functional_extension_acp_test extends phpbb_functional_test_case // Copy back the board installed extensions from the temp directory self::$helper->copy_dir($phpbb_root_path . 'store/temp_ext/', $phpbb_root_path . 'ext/'); - self::$copied_files[] = $phpbb_root_path . 'store/temp_ext/'; - // Remove all of the files we copied around (from board ext -> temp_ext, from test ext -> board ext) self::$helper->remove_files(self::$copied_files); + + self::$helper->empty_dir($phpbb_root_path . 'store/temp_ext/'); } public function test_list() From 3436e3f1020cce0a7d78edb7517335dfa6645024 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 12 Apr 2013 02:03:58 +0200 Subject: [PATCH 111/281] [ticket/11491] Only copy files from phpBB/ext/ the directory exists PHPBB3-11491 --- tests/functional/extension_acp_test.php | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/tests/functional/extension_acp_test.php b/tests/functional/extension_acp_test.php index e829e4582e..cb908e0f98 100644 --- a/tests/functional/extension_acp_test.php +++ b/tests/functional/extension_acp_test.php @@ -27,11 +27,16 @@ class phpbb_functional_extension_acp_test extends phpbb_functional_test_case self::$helper = new phpbb_test_case_helpers(self); - // First, move any extensions setup on the board to a temp directory - self::$copied_files = self::$helper->copy_dir($phpbb_root_path . 'ext/', $phpbb_root_path . 'store/temp_ext/'); + self::$copied_files = array(); - // Then empty the ext/ directory on the board (for accurate test cases) - self::$helper->empty_dir($phpbb_root_path . 'ext/'); + if (file_exists($phpbb_root_path . 'ext/')) + { + // First, move any extensions setup on the board to a temp directory + self::$copied_files = self::$helper->copy_dir($phpbb_root_path . 'ext/', $phpbb_root_path . 'store/temp_ext/'); + + // Then empty the ext/ directory on the board (for accurate test cases) + self::$helper->empty_dir($phpbb_root_path . 'ext/'); + } // Copy our ext/ files from the test case to the board self::$copied_files = array_merge(self::$copied_files, self::$helper->copy_dir(dirname(__FILE__) . '/../extension/ext/', $phpbb_root_path . 'ext/')); From 13ca1f55985b4e481876e78f84f8957aa94e21f3 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 12 Apr 2013 02:15:37 +0200 Subject: [PATCH 112/281] [ticket/11491] Copy files back only if we saved them previously PHPBB3-11491 --- tests/functional/extension_acp_test.php | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/tests/functional/extension_acp_test.php b/tests/functional/extension_acp_test.php index cb908e0f98..1879cbd62c 100644 --- a/tests/functional/extension_acp_test.php +++ b/tests/functional/extension_acp_test.php @@ -92,13 +92,19 @@ class phpbb_functional_extension_acp_test extends phpbb_functional_test_case { global $phpbb_root_path; - // Copy back the board installed extensions from the temp directory - self::$helper->copy_dir($phpbb_root_path . 'store/temp_ext/', $phpbb_root_path . 'ext/'); + if (file_exists($phpbb_root_path . 'store/temp_ext/')) + { + // Copy back the board installed extensions from the temp directory + self::$helper->copy_dir($phpbb_root_path . 'store/temp_ext/', $phpbb_root_path . 'ext/'); + } // Remove all of the files we copied around (from board ext -> temp_ext, from test ext -> board ext) self::$helper->remove_files(self::$copied_files); - self::$helper->empty_dir($phpbb_root_path . 'store/temp_ext/'); + if (file_exists($phpbb_root_path . 'store/temp_ext/')) + { + self::$helper->empty_dir($phpbb_root_path . 'store/temp_ext/'); + } } public function test_list() From 00b45fa4dcc287f395e994e461173adf10764126 Mon Sep 17 00:00:00 2001 From: erangamapa Date: Tue, 5 Mar 2013 07:29:41 +0530 Subject: [PATCH 113/281] [ticket/11358] Fixed the code according to coding guidlines. Added proper indentation and new line after break in switch statement. PHPBB3-11358 --- phpBB/includes/acp/acp_groups.php | 101 +++++++++++++++--------------- 1 file changed, 51 insertions(+), 50 deletions(-) diff --git a/phpBB/includes/acp/acp_groups.php b/phpBB/includes/acp/acp_groups.php index 00ca26dfa6..b4aa102fcd 100644 --- a/phpBB/includes/acp/acp_groups.php +++ b/phpBB/includes/acp/acp_groups.php @@ -141,57 +141,58 @@ class acp_groups 'action' => $action)) ); } - - break; - case 'set_default_on_all': - if (confirm_box(true)) - { - $group_name = ($group_row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $group_row['group_name']] : $group_row['group_name']; - - $start = 0; - - do - { - $sql = 'SELECT user_id - FROM ' . USER_GROUP_TABLE . " - WHERE group_id = $group_id - ORDER BY user_id"; - $result = $db->sql_query_limit($sql, 200, $start); - - $mark_ary = array(); - if ($row = $db->sql_fetchrow($result)) - { - do - { - $mark_ary[] = $row['user_id']; - } - while ($row = $db->sql_fetchrow($result)); - - group_user_attributes('default', $group_id, $mark_ary, false, $group_name, $group_row); - - $start = (sizeof($mark_ary) < 200) ? 0 : $start + 200; - } - else - { - $start = 0; - } - $db->sql_freeresult($result); - } - while ($start); - - trigger_error($user->lang['GROUP_DEFS_UPDATED'] . adm_back_link($this->u_action . '&action=list&g=' . $group_id)); - } - else - { - confirm_box(false, $user->lang['CONFIRM_OPERATION'], build_hidden_fields(array( - 'mark' => $mark_ary, - 'g' => $group_id, - 'i' => $id, - 'mode' => $mode, - 'action' => $action)) - ); - } break; + + case 'set_default_on_all': + if (confirm_box(true)) + { + $group_name = ($group_row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $group_row['group_name']] : $group_row['group_name']; + + $start = 0; + + do + { + $sql = 'SELECT user_id + FROM ' . USER_GROUP_TABLE . " + WHERE group_id = $group_id + ORDER BY user_id"; + $result = $db->sql_query_limit($sql, 200, $start); + + $mark_ary = array(); + if ($row = $db->sql_fetchrow($result)) + { + do + { + $mark_ary[] = $row['user_id']; + } + while ($row = $db->sql_fetchrow($result)); + + group_user_attributes('default', $group_id, $mark_ary, false, $group_name, $group_row); + + $start = (sizeof($mark_ary) < 200) ? 0 : $start + 200; + } + else + { + $start = 0; + } + $db->sql_freeresult($result); + } + while ($start); + + trigger_error($user->lang['GROUP_DEFS_UPDATED'] . adm_back_link($this->u_action . '&action=list&g=' . $group_id)); + } + else + { + confirm_box(false, $user->lang['CONFIRM_OPERATION'], build_hidden_fields(array( + 'mark' => $mark_ary, + 'g' => $group_id, + 'i' => $id, + 'mode' => $mode, + 'action' => $action)) + ); + } + break; + case 'deleteusers': if (empty($mark_ary)) { From 7d8bbcd596ca2d6a3821134c6f8c7478650a2d7a Mon Sep 17 00:00:00 2001 From: erangamapa Date: Tue, 5 Mar 2013 23:52:15 +0530 Subject: [PATCH 114/281] [ticket/11358] Removed all trailing white spaces. Removed all trailing white spaces with new lines. PHPBB3-11358 --- phpBB/includes/acp/acp_groups.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/phpBB/includes/acp/acp_groups.php b/phpBB/includes/acp/acp_groups.php index b4aa102fcd..beb7aefee5 100644 --- a/phpBB/includes/acp/acp_groups.php +++ b/phpBB/includes/acp/acp_groups.php @@ -142,12 +142,12 @@ class acp_groups ); } break; - + case 'set_default_on_all': if (confirm_box(true)) { $group_name = ($group_row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $group_row['group_name']] : $group_row['group_name']; - + $start = 0; do @@ -178,7 +178,7 @@ class acp_groups $db->sql_freeresult($result); } while ($start); - + trigger_error($user->lang['GROUP_DEFS_UPDATED'] . adm_back_link($this->u_action . '&action=list&g=' . $group_id)); } else @@ -192,7 +192,7 @@ class acp_groups ); } break; - + case 'deleteusers': if (empty($mark_ary)) { From fafbce8124e27448164a0a68ef5a8420114309ad Mon Sep 17 00:00:00 2001 From: Vjacheslav Trushkin Date: Fri, 12 Apr 2013 16:40:32 +0300 Subject: [PATCH 115/281] [ticket/11275] Do not use document.write() for color palette Replace document.write() for color palette function PHPBB3-11275 --- phpBB/styles/prosilver/template/editor.js | 44 ++++++++++++------- .../prosilver/template/posting_buttons.html | 39 +++++++--------- 2 files changed, 44 insertions(+), 39 deletions(-) diff --git a/phpBB/styles/prosilver/template/editor.js b/phpBB/styles/prosilver/template/editor.js index 93506b8d4a..9e5665de99 100644 --- a/phpBB/styles/prosilver/template/editor.js +++ b/phpBB/styles/prosilver/template/editor.js @@ -298,9 +298,12 @@ function storeCaret(textEl) { * Color pallette */ function colorPalette(dir, width, height) { - var r = 0, g = 0, b = 0; - var numberList = new Array(6); - var color = ''; + var r = 0, + g = 0, + b = 0, + numberList = new Array(6); + color = '', + html = ''; numberList[0] = '00'; numberList[1] = '40'; @@ -308,37 +311,46 @@ function colorPalette(dir, width, height) { numberList[3] = 'BF'; numberList[4] = 'FF'; - document.writeln(''); + html += '
    '; for (r = 0; r < 5; r++) { - if (dir === 'h') { - document.writeln(''); + if (dir == 'h') { + html += ''; } for (g = 0; g < 5; g++) { - if (dir === 'v') { - document.writeln(''); + if (dir == 'v') { + html += ''; } for (b = 0; b < 5; b++) { color = String(numberList[r]) + String(numberList[g]) + String(numberList[b]); - document.write(''); + html += ''; } - if (dir === 'v') { - document.writeln(''); + if (dir == 'v') { + html += ''; } } - if (dir === 'h') { - document.writeln(''); + if (dir == 'h') { + html += ''; } } - document.writeln('
    '); - document.write('#' + color + ''); - document.writeln(''; + html += '#' + color + ''; + html += '
    '); + html += ''; + return html; } +(function($) { + $(document).ready(function() { + $('#color_palette_placeholder').each(function() { + $(this).html(colorPalette('h', 15, 10)); + }); + }); +})(jQuery); + /** * Caret Position object */ diff --git a/phpBB/styles/prosilver/template/posting_buttons.html b/phpBB/styles/prosilver/template/posting_buttons.html index 8e87407757..fadbc9b3ca 100644 --- a/phpBB/styles/prosilver/template/posting_buttons.html +++ b/phpBB/styles/prosilver/template/posting_buttons.html @@ -35,37 +35,30 @@ var panels = new Array('options-panel', 'attach-panel', 'poll-panel'); var show_panel = 'options-panel'; + function change_palette() + { + dE('colour_palette'); + e = document.getElementById('colour_palette'); + + if (e.style.display == 'block') + { + document.getElementById('bbpalette').value = '{LA_FONT_COLOR_HIDE}'; + } + else + { + document.getElementById('bbpalette').value = '{LA_FONT_COLOR}'; + } + } // ]]> - + From 2387e7eb4122ebc7ecd87bd709d6d661535b2ae2 Mon Sep 17 00:00:00 2001 From: Vjacheslav Trushkin Date: Fri, 12 Apr 2013 16:42:36 +0300 Subject: [PATCH 116/281] [ticket/11275] Do not use spacer.gif in color picker PHPBB3-11275 --- phpBB/styles/prosilver/template/editor.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/phpBB/styles/prosilver/template/editor.js b/phpBB/styles/prosilver/template/editor.js index 9e5665de99..0a749347ad 100644 --- a/phpBB/styles/prosilver/template/editor.js +++ b/phpBB/styles/prosilver/template/editor.js @@ -326,7 +326,7 @@ function colorPalette(dir, width, height) { for (b = 0; b < 5; b++) { color = String(numberList[r]) + String(numberList[g]) + String(numberList[b]); html += ''; - html += '#' + color + ''; + html += ''; html += ''; } @@ -346,7 +346,7 @@ function colorPalette(dir, width, height) { (function($) { $(document).ready(function() { $('#color_palette_placeholder').each(function() { - $(this).html(colorPalette('h', 15, 10)); + $(this).html(colorPalette('h', 15, 12)); }); }); })(jQuery); From 88072fd6c2c3ec6cc6d2a880bd76a9c601fd0767 Mon Sep 17 00:00:00 2001 From: Vjacheslav Trushkin Date: Tue, 9 Apr 2013 18:38:59 +0300 Subject: [PATCH 117/281] [ticket/10741] Function to resize textarea elements New function to automatically resize textarea elements as user types text PHPBB3-10741 --- phpBB/assets/javascript/core.js | 85 +++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/phpBB/assets/javascript/core.js b/phpBB/assets/javascript/core.js index 8bbea8b8c9..6fe71d141a 100644 --- a/phpBB/assets/javascript/core.js +++ b/phpBB/assets/javascript/core.js @@ -568,4 +568,89 @@ phpbb.addAjaxCallback('toggle_link', function() { el.parent().attr('class', toggleClass); }); +/** +* Automatically resize textarea +* +* This function automatically resizes textarea elements when user +* types text. +* +* @param jQuery item jQuery object to resize +* @param object options Optional parameter that adjusts default +* configuration. See configuration variable +*/ +phpbb.resizeTextArea = function(items) { + // Configuration + var configuration = { + minWindowHeight: 500, // Minimum browser window height when textareas are resized + minHeight: 200, // Minimum height of textarea + maxHeight: 500, // Maximum height of textarea + heightDiff: 200, // Minimum difference between window and textarea height + // In following callbacks parameter "item" is jQuery object. "this" points to DOM object + resizeCallback: function(item) { }, // Function to call after resizing textarea. + resetCallback: function(item) { } // Function to call when resize has been canceled + } + + if (arguments.length > 1) + { + configuration = $.extend(configuration, arguments[1]); + } + + function resetAutoResize(item) + { + var $item = $(item); + if ($item.hasClass('auto-resized')) + { + $(item).css('height', '').removeClass('auto-resized'); + configuration.resetCallback.call(item, $item); + } + }; + + function autoResize(item) + { + function setHeight(height) + { + $item.css('height', height + 'px').addClass('auto-resized'); + configuration.resizeCallback.call(item, $item); + } + + var windowHeight = $(window).height(); + + if (windowHeight < configuration.minWindowHeight) + { + resetAutoResize(item); + return; + } + + 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; + + if (height > maxHeight) + { + setHeight(maxHeight); + } + else if (scrollHeight > (height + 5)) + { + setHeight(Math.min(maxHeight, scrollHeight)); + } + }; + + items.bind('focus change keyup', function() { + $(this).each(function() { + autoResize(this); + }); + }).css('resize', 'none').change(); + + $(window).resize(function() { + items.each(function() { + if ($(this).hasClass('auto-resized')) + { + autoResize(this); + } + }); + }); +}; + + })(jQuery); // Avoid conflicts with other libraries From 316efcbbbb72058bb9986be08af3d11173817386 Mon Sep 17 00:00:00 2001 From: Vjacheslav Trushkin Date: Tue, 9 Apr 2013 18:39:47 +0300 Subject: [PATCH 118/281] [ticket/10741] Automatically resize textareas in prosilver and ACP Automatically resize textareas in prosilver and ACP. PHPBB3-10741 --- phpBB/adm/style/ajax.js | 6 ++++++ phpBB/styles/prosilver/template/ajax.js | 9 +++++++++ 2 files changed, 15 insertions(+) diff --git a/phpBB/adm/style/ajax.js b/phpBB/adm/style/ajax.js index 8f7c210e00..8211bdd014 100644 --- a/phpBB/adm/style/ajax.js +++ b/phpBB/adm/style/ajax.js @@ -148,6 +148,12 @@ $('[data-ajax]').each(function() { } }); +/** +* Automatically resize textarea +*/ +$(document).ready(function() { + phpbb.resizeTextArea($('textarea'), {minHeight: 75}); +}); })(jQuery); // Avoid conflicts with other libraries diff --git a/phpBB/styles/prosilver/template/ajax.js b/phpBB/styles/prosilver/template/ajax.js index 8dd1f58c97..e7dfe95009 100644 --- a/phpBB/styles/prosilver/template/ajax.js +++ b/phpBB/styles/prosilver/template/ajax.js @@ -225,4 +225,13 @@ $('#member_search').click(function () { return false; }); +/** +* Automatically resize textarea +*/ +$(document).ready(function() { + phpbb.resizeTextArea($('textarea:not(#message-box textarea)'), {minHeight: 75, maxHeight: 250}); + phpbb.resizeTextArea($('#message-box textarea')); +}); + + })(jQuery); // Avoid conflicts with other libraries From 67f0e19128415210f0ece4a8cd3df12e4b35eaf6 Mon Sep 17 00:00:00 2001 From: Vjacheslav Trushkin Date: Tue, 9 Apr 2013 18:47:08 +0300 Subject: [PATCH 119/281] [ticket/10741] Do not resize textarea.no-auto-resize Do not auto-resize textareas with class .no-auto-resize PHPBB3-10741 --- phpBB/adm/style/ajax.js | 2 +- phpBB/styles/prosilver/template/ajax.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/phpBB/adm/style/ajax.js b/phpBB/adm/style/ajax.js index 8211bdd014..6f21dfa6ac 100644 --- a/phpBB/adm/style/ajax.js +++ b/phpBB/adm/style/ajax.js @@ -152,7 +152,7 @@ $('[data-ajax]').each(function() { * Automatically resize textarea */ $(document).ready(function() { - phpbb.resizeTextArea($('textarea'), {minHeight: 75}); + phpbb.resizeTextArea($('textarea:not(.no-auto-resize)'), {minHeight: 75}); }); diff --git a/phpBB/styles/prosilver/template/ajax.js b/phpBB/styles/prosilver/template/ajax.js index e7dfe95009..2528b96ece 100644 --- a/phpBB/styles/prosilver/template/ajax.js +++ b/phpBB/styles/prosilver/template/ajax.js @@ -229,7 +229,7 @@ $('#member_search').click(function () { * Automatically resize textarea */ $(document).ready(function() { - phpbb.resizeTextArea($('textarea:not(#message-box textarea)'), {minHeight: 75, maxHeight: 250}); + phpbb.resizeTextArea($('textarea:not(#message-box textarea, .no-auto-resize)'), {minHeight: 75, maxHeight: 250}); phpbb.resizeTextArea($('#message-box textarea')); }); From cbb9f084fce0fd42ed1481233f417c79e8a0abfa Mon Sep 17 00:00:00 2001 From: Vjacheslav Trushkin Date: Wed, 10 Apr 2013 09:08:25 +0300 Subject: [PATCH 120/281] [ticket/10741] Fix for browser-specific resizing of textarea Disable browser-specific resizing only after textarea has been resized Enable browser-specific resizing after script resizing has been reset PHPBB3-10741 --- phpBB/assets/javascript/core.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/phpBB/assets/javascript/core.js b/phpBB/assets/javascript/core.js index 6fe71d141a..827ed2e34a 100644 --- a/phpBB/assets/javascript/core.js +++ b/phpBB/assets/javascript/core.js @@ -600,7 +600,7 @@ phpbb.resizeTextArea = function(items) { var $item = $(item); if ($item.hasClass('auto-resized')) { - $(item).css('height', '').removeClass('auto-resized'); + $(item).css({height: '', resize: ''}).removeClass('auto-resized'); configuration.resetCallback.call(item, $item); } }; @@ -609,7 +609,7 @@ phpbb.resizeTextArea = function(items) { { function setHeight(height) { - $item.css('height', height + 'px').addClass('auto-resized'); + $item.css({height: height + 'px', resize: 'none'}).addClass('auto-resized'); configuration.resizeCallback.call(item, $item); } @@ -640,7 +640,7 @@ phpbb.resizeTextArea = function(items) { $(this).each(function() { autoResize(this); }); - }).css('resize', 'none').change(); + }).change(); $(window).resize(function() { items.each(function() { From 6a3d77d76e9a6ee17acbd29da8486742f60a2514 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Mon, 1 Apr 2013 10:34:06 +0200 Subject: [PATCH 121/281] [ticket/10844] Add phpbb_root_path to phpbb_style_extension_path_provider The phpbb_root_path needs to be removed from the style path, before giving the path to the finder, because the finder prepends it later again and is therefor unable to find style files when the root path is not ./ PHPBB3-10844 --- phpBB/config/services.yml | 1 + phpBB/includes/bbcode.php | 2 +- phpBB/includes/functions_messenger.php | 2 +- phpBB/includes/style/extension_path_provider.php | 15 ++++++++++++++- 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/phpBB/config/services.yml b/phpBB/config/services.yml index b9c71844dc..6b7b3f2f2b 100644 --- a/phpBB/config/services.yml +++ b/phpBB/config/services.yml @@ -242,6 +242,7 @@ services: arguments: - @ext.manager - @style.path_provider + - %core.root_path% style.path_provider: class: phpbb_style_path_provider diff --git a/phpBB/includes/bbcode.php b/phpBB/includes/bbcode.php index e8681420d4..c198abeb54 100644 --- a/phpBB/includes/bbcode.php +++ b/phpBB/includes/bbcode.php @@ -133,7 +133,7 @@ class bbcode $this->template_bitfield = new bitfield($user->style['bbcode_bitfield']); $style_resource_locator = new phpbb_style_resource_locator(); - $style_path_provider = new phpbb_style_extension_path_provider($phpbb_extension_manager, new phpbb_style_path_provider()); + $style_path_provider = new phpbb_style_extension_path_provider($phpbb_extension_manager, new phpbb_style_path_provider(), $phpbb_root_path); $template = new phpbb_template($phpbb_root_path, $phpEx, $config, $user, $style_resource_locator, new phpbb_template_context(), $phpbb_extension_manager); $style = new phpbb_style($phpbb_root_path, $phpEx, $config, $user, $style_resource_locator, $style_path_provider, $template); $style->set_style(); diff --git a/phpBB/includes/functions_messenger.php b/phpBB/includes/functions_messenger.php index 821f0d970d..e580f6b675 100644 --- a/phpBB/includes/functions_messenger.php +++ b/phpBB/includes/functions_messenger.php @@ -209,7 +209,7 @@ class messenger if (!isset($this->tpl_msg[$template_lang . $template_file])) { $style_resource_locator = new phpbb_style_resource_locator(); - $style_path_provider = new phpbb_style_extension_path_provider($phpbb_extension_manager, new phpbb_style_path_provider()); + $style_path_provider = new phpbb_style_extension_path_provider($phpbb_extension_manager, new phpbb_style_path_provider(), $phpbb_root_path); $tpl = new phpbb_template($phpbb_root_path, $phpEx, $config, $user, $style_resource_locator, new phpbb_template_context(), $phpbb_extension_manager); $style = new phpbb_style($phpbb_root_path, $phpEx, $config, $user, $style_resource_locator, $style_path_provider, $tpl); diff --git a/phpBB/includes/style/extension_path_provider.php b/phpBB/includes/style/extension_path_provider.php index 6976a45ed0..e658abcb42 100644 --- a/phpBB/includes/style/extension_path_provider.php +++ b/phpBB/includes/style/extension_path_provider.php @@ -40,17 +40,22 @@ class phpbb_style_extension_path_provider extends phpbb_extension_provider imple */ protected $base_path_provider; + /** @var string */ + protected $phpbb_root_path; + /** * Constructor stores extension manager * * @param phpbb_extension_manager $extension_manager phpBB extension manager * @param phpbb_style_path_provider $base_path_provider A simple path provider * to provide paths to be located in extensions + * @param string $phpbb_root_path phpBB root path */ - public function __construct(phpbb_extension_manager $extension_manager, phpbb_style_path_provider $base_path_provider) + public function __construct(phpbb_extension_manager $extension_manager, phpbb_style_path_provider $base_path_provider, $phpbb_root_path) { parent::__construct($extension_manager); $this->base_path_provider = $base_path_provider; + $this->phpbb_root_path = $phpbb_root_path; } /** @@ -91,6 +96,14 @@ class phpbb_style_extension_path_provider extends phpbb_extension_provider imple $directories['style'][] = $path; if ($path && !phpbb_is_absolute($path)) { + // Remove phpBB root path from the style path, + // so the finder is able to find extension styles, + // when the root path is not ./ + if (strpos($path, $this->phpbb_root_path) === 0) + { + $path = substr($path, strlen($this->phpbb_root_path)); + } + $result = $finder->directory('/' . $this->ext_dir_prefix . $path) ->get_directories(true, false, true); foreach ($result as $ext => $ext_path) From bbaa3411b04c06c519e8dd215a0251c97263eac4 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 12 Apr 2013 21:19:09 +0200 Subject: [PATCH 122/281] [ticket/10844] Make sure ext_path has no trailing slash PHPBB3-10844 --- phpBB/includes/style/extension_path_provider.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/phpBB/includes/style/extension_path_provider.php b/phpBB/includes/style/extension_path_provider.php index e658abcb42..ec1d85f821 100644 --- a/phpBB/includes/style/extension_path_provider.php +++ b/phpBB/includes/style/extension_path_provider.php @@ -108,6 +108,11 @@ class phpbb_style_extension_path_provider extends phpbb_extension_provider imple ->get_directories(true, false, true); foreach ($result as $ext => $ext_path) { + // Make sure $ext_path has no ending slash + if (substr($ext_path, -1) === '/') + { + $ext_path = substr($ext_path, 0, -1); + } $directories[$ext][] = $ext_path; } } From 06e32e36dff55dffcb60c19e768656db237ee836 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 12 Apr 2013 21:20:34 +0200 Subject: [PATCH 123/281] [ticket/10844] Add unit tests for different root_paths PHPBB3-10844 --- tests/extension/style_path_provider_test.php | 50 +++++++++++++++++++ .../subdir/style_path_provider_test.php | 18 +++++++ 2 files changed, 68 insertions(+) create mode 100644 tests/extension/style_path_provider_test.php create mode 100644 tests/extension/subdir/style_path_provider_test.php diff --git a/tests/extension/style_path_provider_test.php b/tests/extension/style_path_provider_test.php new file mode 100644 index 0000000000..e1021c20ac --- /dev/null +++ b/tests/extension/style_path_provider_test.php @@ -0,0 +1,50 @@ +relative_root_path = './'; + $this->root_path = dirname(__FILE__) . '/'; + } + + public function test_find() + { + $phpbb_style_path_provider = new phpbb_style_path_provider(); + $phpbb_style_path_provider->set_styles(array($this->relative_root_path . 'styles/prosilver')); + $phpbb_style_extension_path_provider = new phpbb_style_extension_path_provider(new phpbb_mock_extension_manager( + $this->root_path, + array( + 'foo' => array( + 'ext_name' => 'foo', + 'ext_active' => '1', + 'ext_path' => 'ext/foo/', + ), + 'bar' => array( + 'ext_name' => 'bar', + 'ext_active' => '1', + 'ext_path' => 'ext/bar/', + ), + )), $phpbb_style_path_provider, $this->relative_root_path); + + $this->assertEquals(array( + 'style' => array( + $this->relative_root_path . 'styles/prosilver', + ), + 'bar' => array( + $this->root_path . 'ext/bar/styles/prosilver', + ), + ), $phpbb_style_extension_path_provider->find()); + } +} diff --git a/tests/extension/subdir/style_path_provider_test.php b/tests/extension/subdir/style_path_provider_test.php new file mode 100644 index 0000000000..1b5ce62e5f --- /dev/null +++ b/tests/extension/subdir/style_path_provider_test.php @@ -0,0 +1,18 @@ +relative_root_path = '../'; + $this->root_path = dirname(__FILE__) . '/../'; + } +} From cbfe866eba5b2a7bb9f141e5145292dbef135e78 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Sat, 13 Apr 2013 18:03:02 +0200 Subject: [PATCH 124/281] [ticket/11494] Use functions instead of repeating PHPBB3-11494 --- tests/functional/memberlist_test.php | 48 +++++++++++++++++----------- 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/tests/functional/memberlist_test.php b/tests/functional/memberlist_test.php index 2e3d7907bf..0065147d11 100644 --- a/tests/functional/memberlist_test.php +++ b/tests/functional/memberlist_test.php @@ -41,25 +41,37 @@ class phpbb_functional_memberlist_test extends phpbb_functional_test_case $this->assertContains('admin', $crawler->filter('h2')->text()); } + protected function get_memberlist_leaders_crawler() + { + $crawler = $this->request('GET', 'memberlist.php?mode=leaders&sid=' . $this->sid); + $this->assert_response_success(); + + return $crawler; + } + + protected function get_crawler_table_text($crawler, $table) + { + return $crawler->filter('.forumbg-table')->eq($table)->text(); + } + public function test_leaders() { $this->login(); $this->create_user('memberlist-test-moderator'); - $crawler = $this->request('GET', 'memberlist.php?mode=leaders&sid=' . $this->sid); - $this->assert_response_success(); + $crawler = $this->get_memberlist_leaders_crawler(); // Admin in admin group, but not in moderators - $this->assertContains('admin', $crawler->filter('.forumbg-table')->eq(0)->text()); - $this->assertNotContains('admin', $crawler->filter('.forumbg-table')->eq(1)->text()); + $this->assertContains('admin', $this->get_crawler_table_text($crawler, 0)); + $this->assertNotContains('admin', $this->get_crawler_table_text($crawler, 1)); // memberlist-test-user in neither group - $this->assertNotContains('memberlist-test-user', $crawler->filter('.forumbg-table')->eq(0)->text()); - $this->assertNotContains('memberlist-test-user', $crawler->filter('.forumbg-table')->eq(1)->text()); + $this->assertNotContains('memberlist-test-user', $this->get_crawler_table_text($crawler, 0)); + $this->assertNotContains('memberlist-test-user', $this->get_crawler_table_text($crawler, 1)); // memberlist-test-moderator in neither group - $this->assertNotContains('memberlist-test-moderator', $crawler->filter('.forumbg-table')->eq(0)->text()); - $this->assertNotContains('memberlist-test-moderator', $crawler->filter('.forumbg-table')->eq(1)->text()); + $this->assertNotContains('memberlist-test-moderator', $this->get_crawler_table_text($crawler, 0)); + $this->assertNotContains('memberlist-test-moderator', $this->get_crawler_table_text($crawler, 1)); } public function test_leaders_remove_users() @@ -68,16 +80,15 @@ class phpbb_functional_memberlist_test extends phpbb_functional_test_case // Remove admin from admins, but is now in moderators $this->remove_user_group('ADMINISTRATORS', array('admin')); - $crawler = $this->request('GET', 'memberlist.php?mode=leaders&sid=' . $this->sid); - $this->assert_response_success(); - $this->assertNotContains('admin', $crawler->filter('.forumbg-table')->eq(0)->text()); - $this->assertContains('admin', $crawler->filter('.forumbg-table')->eq(1)->text()); + $crawler = $this->get_memberlist_leaders_crawler(); + $this->assertNotContains('admin', $this->get_crawler_table_text($crawler, 0)); + $this->assertContains('admin', $this->get_crawler_table_text($crawler, 1)); // Remove admin from moderators, should not be visible anymore $this->remove_user_group('GLOBAL_MODERATORS', array('admin')); - $crawler = $this->request('GET', 'memberlist.php?mode=leaders&sid=' . $this->sid); - $this->assertNotContains('admin', $crawler->filter('.forumbg-table')->eq(0)->text()); - $this->assertNotContains('admin', $crawler->filter('.forumbg-table')->eq(1)->text()); + $crawler = $this->get_memberlist_leaders_crawler(); + $this->assertNotContains('admin', $this->get_crawler_table_text($crawler, 0)); + $this->assertNotContains('admin', $this->get_crawler_table_text($crawler, 1)); } public function test_leaders_add_users() @@ -86,9 +97,8 @@ class phpbb_functional_memberlist_test extends phpbb_functional_test_case // Add memberlist-test-moderator to moderators $this->add_user_group('GLOBAL_MODERATORS', array('memberlist-test-moderator')); - $crawler = $this->request('GET', 'memberlist.php?mode=leaders&sid=' . $this->sid); - $this->assert_response_success(); - $this->assertNotContains('memberlist-test-moderator', $crawler->filter('.forumbg-table')->eq(0)->text()); - $this->assertContains('memberlist-test-moderator', $crawler->filter('.forumbg-table')->eq(1)->text()); + $crawler = $this->get_memberlist_leaders_crawler(); + $this->assertNotContains('memberlist-test-moderator', $this->get_crawler_table_text($crawler, 0)); + $this->assertContains('memberlist-test-moderator', $this->get_crawler_table_text($crawler, 1)); } } From 6bcc220df3499e2e58735c9f3a586521784c4edf Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Mon, 15 Apr 2013 03:30:07 +0200 Subject: [PATCH 125/281] [ticket/11494] Filter crawler in first place PHPBB3-11494 --- tests/functional/memberlist_test.php | 41 ++++++++++++---------------- 1 file changed, 18 insertions(+), 23 deletions(-) diff --git a/tests/functional/memberlist_test.php b/tests/functional/memberlist_test.php index 0065147d11..92ede8bd04 100644 --- a/tests/functional/memberlist_test.php +++ b/tests/functional/memberlist_test.php @@ -41,17 +41,12 @@ class phpbb_functional_memberlist_test extends phpbb_functional_test_case $this->assertContains('admin', $crawler->filter('h2')->text()); } - protected function get_memberlist_leaders_crawler() + protected function get_memberlist_leaders_table_crawler() { $crawler = $this->request('GET', 'memberlist.php?mode=leaders&sid=' . $this->sid); $this->assert_response_success(); - return $crawler; - } - - protected function get_crawler_table_text($crawler, $table) - { - return $crawler->filter('.forumbg-table')->eq($table)->text(); + return $crawler->filter('.forumbg-table'); } public function test_leaders() @@ -59,19 +54,19 @@ class phpbb_functional_memberlist_test extends phpbb_functional_test_case $this->login(); $this->create_user('memberlist-test-moderator'); - $crawler = $this->get_memberlist_leaders_crawler(); + $crawler = $this->get_memberlist_leaders_table_crawler(); // Admin in admin group, but not in moderators - $this->assertContains('admin', $this->get_crawler_table_text($crawler, 0)); - $this->assertNotContains('admin', $this->get_crawler_table_text($crawler, 1)); + $this->assertContains('admin', $crawler->eq(0)->text()); + $this->assertNotContains('admin', $crawler->eq(1)->text()); // memberlist-test-user in neither group - $this->assertNotContains('memberlist-test-user', $this->get_crawler_table_text($crawler, 0)); - $this->assertNotContains('memberlist-test-user', $this->get_crawler_table_text($crawler, 1)); + $this->assertNotContains('memberlist-test-user', $crawler->eq(0)->text()); + $this->assertNotContains('memberlist-test-user', $crawler->eq(1)->text()); // memberlist-test-moderator in neither group - $this->assertNotContains('memberlist-test-moderator', $this->get_crawler_table_text($crawler, 0)); - $this->assertNotContains('memberlist-test-moderator', $this->get_crawler_table_text($crawler, 1)); + $this->assertNotContains('memberlist-test-moderator', $crawler->eq(0)->text()); + $this->assertNotContains('memberlist-test-moderator', $crawler->eq(1)->text()); } public function test_leaders_remove_users() @@ -80,15 +75,15 @@ class phpbb_functional_memberlist_test extends phpbb_functional_test_case // Remove admin from admins, but is now in moderators $this->remove_user_group('ADMINISTRATORS', array('admin')); - $crawler = $this->get_memberlist_leaders_crawler(); - $this->assertNotContains('admin', $this->get_crawler_table_text($crawler, 0)); - $this->assertContains('admin', $this->get_crawler_table_text($crawler, 1)); + $crawler = $this->get_memberlist_leaders_table_crawler(); + $this->assertNotContains('admin', $crawler->eq(0)->text()); + $this->assertContains('admin', $crawler->eq(1)->text()); // Remove admin from moderators, should not be visible anymore $this->remove_user_group('GLOBAL_MODERATORS', array('admin')); - $crawler = $this->get_memberlist_leaders_crawler(); - $this->assertNotContains('admin', $this->get_crawler_table_text($crawler, 0)); - $this->assertNotContains('admin', $this->get_crawler_table_text($crawler, 1)); + $crawler = $this->get_memberlist_leaders_table_crawler(); + $this->assertNotContains('admin', $crawler->eq(0)->text()); + $this->assertNotContains('admin', $crawler->eq(1)->text()); } public function test_leaders_add_users() @@ -97,8 +92,8 @@ class phpbb_functional_memberlist_test extends phpbb_functional_test_case // Add memberlist-test-moderator to moderators $this->add_user_group('GLOBAL_MODERATORS', array('memberlist-test-moderator')); - $crawler = $this->get_memberlist_leaders_crawler(); - $this->assertNotContains('memberlist-test-moderator', $this->get_crawler_table_text($crawler, 0)); - $this->assertContains('memberlist-test-moderator', $this->get_crawler_table_text($crawler, 1)); + $crawler = $this->get_memberlist_leaders_table_crawler(); + $this->assertNotContains('memberlist-test-moderator', $crawler->eq(0)->text()); + $this->assertContains('memberlist-test-moderator', $crawler->eq(1)->text()); } } From c1dedabdfb688501dceade55f6f3e96e3495e5dd Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Mon, 15 Apr 2013 12:50:21 +0200 Subject: [PATCH 126/281] [ticket/11488] Use correct base class in email notification method In ticket/11451 this was not correctly changed to reflect the new class phpbb_notifcation_method_messenger_base. Additionally, an undefined variable error has been fixed in messenger_base.php (change should be confirmed by bantu though). PHPBB3-11488 --- phpBB/includes/notification/method/email.php | 2 +- phpBB/includes/notification/method/messenger_base.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/phpBB/includes/notification/method/email.php b/phpBB/includes/notification/method/email.php index dc505c0d41..44666b1422 100644 --- a/phpBB/includes/notification/method/email.php +++ b/phpBB/includes/notification/method/email.php @@ -21,7 +21,7 @@ if (!defined('IN_PHPBB')) * * @package notifications */ -class phpbb_notification_method_email extends phpbb_notification_method_base +class phpbb_notification_method_email extends phpbb_notification_method_messenger_base { /** * Get notification method name diff --git a/phpBB/includes/notification/method/messenger_base.php b/phpBB/includes/notification/method/messenger_base.php index ce1ecc09ce..2f9073e80b 100644 --- a/phpBB/includes/notification/method/messenger_base.php +++ b/phpBB/includes/notification/method/messenger_base.php @@ -78,7 +78,7 @@ abstract class phpbb_notification_method_messenger_base extends phpbb_notificati continue; } - $messenger->template($email_template_base_dir . $notification->get_email_template(), $user['user_lang']); + $messenger->template($template_dir_prefix . $notification->get_email_template(), $user['user_lang']); $messenger->to($user['user_email'], $user['username']); From 82a630cd648b193079cd147144ad5b035450d824 Mon Sep 17 00:00:00 2001 From: Dhruv Date: Mon, 15 Apr 2013 20:41:05 +0530 Subject: [PATCH 127/281] [ticket/11493] add check for phpBB Debug in functional tests PHPBB3-11493 --- tests/test_framework/phpbb_functional_test_case.php | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_framework/phpbb_functional_test_case.php b/tests/test_framework/phpbb_functional_test_case.php index 8ab6469e9a..c600cba5f8 100644 --- a/tests/test_framework/phpbb_functional_test_case.php +++ b/tests/test_framework/phpbb_functional_test_case.php @@ -349,5 +349,6 @@ class phpbb_functional_test_case extends phpbb_test_case $this->assertEquals(200, $this->client->getResponse()->getStatus()); $content = $this->client->getResponse()->getContent(); $this->assertNotContains('Fatal error:', $content); + $this->assertNotContains('[phpBB Debug]', $content); } } From 14071e6085d55f459728ade117ff93b3957045d2 Mon Sep 17 00:00:00 2001 From: Dhruv Date: Mon, 15 Apr 2013 22:02:21 +0530 Subject: [PATCH 128/281] [ticket/11493] add checks for Notice and Warning PHPBB3-11493 --- tests/test_framework/phpbb_functional_test_case.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/test_framework/phpbb_functional_test_case.php b/tests/test_framework/phpbb_functional_test_case.php index c600cba5f8..83c931f924 100644 --- a/tests/test_framework/phpbb_functional_test_case.php +++ b/tests/test_framework/phpbb_functional_test_case.php @@ -349,6 +349,8 @@ class phpbb_functional_test_case extends phpbb_test_case $this->assertEquals(200, $this->client->getResponse()->getStatus()); $content = $this->client->getResponse()->getContent(); $this->assertNotContains('Fatal error:', $content); + $this->assertNotContains('Notice:', $content); + $this->assertNotContains('Warning:', $content); $this->assertNotContains('[phpBB Debug]', $content); } } From a1183a58894967bfec7da01c5004138e4daeb583 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 16 Apr 2013 23:07:48 +0200 Subject: [PATCH 129/281] [ticket/11495] Add basic interface with nestedset operations PHPBB3-11495 --- phpBB/includes/nestedset/interface.php | 131 ++++++++++++++++++++ phpBB/includes/nestedset/item/interface.php | 61 +++++++++ 2 files changed, 192 insertions(+) create mode 100644 phpBB/includes/nestedset/interface.php create mode 100644 phpBB/includes/nestedset/item/interface.php diff --git a/phpBB/includes/nestedset/interface.php b/phpBB/includes/nestedset/interface.php new file mode 100644 index 0000000000..7ef6ff87bb --- /dev/null +++ b/phpBB/includes/nestedset/interface.php @@ -0,0 +1,131 @@ + down, > 0 => up + * @return bool True if the item was moved + */ + public function move(phpbb_nestedset_item_interface $item, $delta); + + /** + * Move an item down by 1 + * + * @param phpbb_nestedset_item_interface $item The item to be moved + * @return bool True if the item was moved + */ + public function move_down(phpbb_nestedset_item_interface $item); + + /** + * Move an item up by 1 + * + * @param phpbb_nestedset_item_interface $item The item to be moved + * @return bool True if the item was moved + */ + public function move_up(phpbb_nestedset_item_interface $item); + + /** + * Moves all children of one item to another item + * + * @param phpbb_nestedset_item_interface $current_parent The current parent item + * @param phpbb_nestedset_item_interface $new_parent The new parent item + * @return bool True if any items where moved + */ + public function move_children(phpbb_nestedset_item_interface $current_parent, phpbb_nestedset_item_interface $new_parent); + + /** + * Set the parent item + * + * @param phpbb_nestedset_item_interface $item The item to be moved + * @param phpbb_nestedset_item_interface $new_parent The new parent item + * @return bool True if the parent was set successfully + */ + public function set_parent(phpbb_nestedset_item_interface $item, phpbb_nestedset_item_interface $new_parent); + + /** + * Get branch of the item + * + * This method can return all parents, children or both of the given item + * + * @param phpbb_nestedset_item_interface $item The item to get the branch from + * @param string $type One of all|parent|children + * @param bool $order_desc Order the items descending (most outer parent first) + * @param bool $include_item Should the given item be included in the list aswell + * @return array Array of items (containing all columns from the item table) + * ID => Item data + */ + public function get_branch_data(phpbb_nestedset_item_interface $item, $type, $order_desc, $include_item); + + /** + * Get base information of parent items + * + * @param phpbb_nestedset_item_interface $item The item to get the parents from + * @return array Array of items (containing basic columns from the item table) + * ID => Item data + */ + public function get_parent_data(phpbb_nestedset_item_interface $item); + + /** + * Recalculate Nested Sets + * + * @param int $new_id First left_id to be used (should start with 1) + * @param int $parent_id parent_id of the current set (default = 0) + * @param bool $reset_ids Should we reset all left_id/right_id on the first call? + * @return int $new_id The next left_id/right_id that should be used + */ + public function recalculate_nested_set($new_id, $parent_id = 0, $reset_ids = false); +} diff --git a/phpBB/includes/nestedset/item/interface.php b/phpBB/includes/nestedset/item/interface.php new file mode 100644 index 0000000000..18206d752e --- /dev/null +++ b/phpBB/includes/nestedset/item/interface.php @@ -0,0 +1,61 @@ + Date: Tue, 16 Apr 2013 23:08:35 +0200 Subject: [PATCH 130/281] [ticket/11495] Add abstract implementation of the interface PHPBB3-11495 --- phpBB/includes/nestedset/base.php | 632 +++++++++++++++++++++++++ phpBB/includes/nestedset/item/base.php | 82 ++++ 2 files changed, 714 insertions(+) create mode 100644 phpBB/includes/nestedset/base.php create mode 100644 phpBB/includes/nestedset/item/base.php diff --git a/phpBB/includes/nestedset/base.php b/phpBB/includes/nestedset/base.php new file mode 100644 index 0000000000..7f4691b7e0 --- /dev/null +++ b/phpBB/includes/nestedset/base.php @@ -0,0 +1,632 @@ + 'item_id', + 'left_id' => 'left_id', + 'right_id' => 'right_id', + 'parent_id' => 'parent_id', + 'item_parents' => 'item_parents', + ); + + /** + * Additional SQL restrictions + * Allows to have multiple nested sets in one table + * @var String + */ + protected $sql_where = ''; + + /** + * List of item properties to be cached in $item_parents + * @var array + */ + protected $item_basic_data = array('*'); + + /** + * Delete an item from the nested set (also deletes the rows form the table) + * + * Also deletes all subitems from the nested set + * + * @param string $operator SQL operator that needs to be prepended to sql_where, + * if it is not empty. + * @param string $column_prefix Prefix that needs to be prepended to column names + * @return bool True if the item was deleted + */ + public function get_sql_where($operator = 'AND', $column_prefix = '') + { + return (!$this->sql_where) ? '' : $operator . ' ' . sprintf($this->sql_where, $column_prefix); + } + + /** + * @inheritdoc + */ + public function insert(array $additional_data) + { + $item_data = array_merge($additional_data, array( + $this->table_columns['parent_id'] => 0, + $this->table_columns['left_id'] => 0, + $this->table_columns['right_id'] => 0, + $this->table_columns['item_parents'] => '', + )); + + unset($item_data[$this->table_columns['item_id']]); + + $sql = 'INSERT INTO ' . $this->table_name . ' ' . $this->db->sql_build_array('INSERT', $item_data); + $this->db->sql_query($sql); + + $item_data[$this->table_columns['item_id']] = (int) $this->db->sql_nextid(); + + $item = new $this->item_class($item_data); + + return array_merge($item_data, $this->add($item)); + } + + /** + * @inheritdoc + */ + public function add(phpbb_nestedset_item_interface $item) + { + $sql = 'SELECT MAX(' . $this->table_columns['right_id'] . ') AS ' . $this->table_columns['right_id'] . ' + FROM ' . $this->table_name . ' + ' . $this->get_sql_where('WHERE'); + $result = $this->db->sql_query($sql); + $current_max_right_id = (int) $this->db->sql_fetchfield($this->table_columns['right_id']); + $this->db->sql_freeresult($result); + + $update_item_data = array( + $this->table_columns['parent_id'] => 0, + $this->table_columns['left_id'] => $current_max_right_id + 1, + $this->table_columns['right_id'] => $current_max_right_id + 2, + $this->table_columns['item_parents'] => '', + ); + + $sql = 'UPDATE ' . $this->table_name . ' + SET ' . $this->db->sql_build_array('UPDATE', $update_item_data) . ' + WHERE ' . $this->table_columns['item_id'] . ' = ' . $item->get_item_id(); + $this->db->sql_query($sql); + + return $update_item_data; + } + + /** + * @inheritdoc + */ + public function remove(phpbb_nestedset_item_interface $item) + { + if ($item->has_children()) + { + $items = array_keys($this->get_branch_data($item, 'children')); + } + else + { + $items = array($item->get_item_id()); + } + + $this->remove_subset($items, $item); + + return $items; + } + + /** + * @inheritdoc + */ + public function delete(phpbb_nestedset_item_interface $item) + { + $removed_items = $this->remove($item); + + $sql = 'DELETE FROM ' . $this->table_name . ' + WHERE ' . $this->db->sql_in_set($this->table_columns['item_id'], $removed_items) . ' + ' . $this->get_sql_where('AND'); + $this->db->sql_query($sql); + + return $removed_items; + } + + /** + * @inheritdoc + */ + public function move(phpbb_nestedset_item_interface $item, $delta) + { + if ($delta == 0) + { + return false; + } + + $action = ($delta > 0) ? 'move_up' : 'move_down'; + $delta = abs($delta); + + /** + * Fetch all the siblings between the item's current spot + * and where we want to move it to. If there are less than $delta + * siblings between the current spot and the target then the + * item will move as far as possible + */ + $sql = 'SELECT ' . implode(', ', $this->table_columns) . ' + FROM ' . $this->table_name . ' + WHERE ' . $this->table_columns['parent_id'] . ' = ' . $item->get_parent_id() . ' + ' . $this->get_sql_where() . ' + AND '; + + if ($action == 'move_up') + { + $sql .= $this->table_columns['right_id'] . ' < ' . $item->get_right_id() . ' ORDER BY ' . $this->table_columns['right_id'] . ' DESC'; + } + else + { + $sql .= $this->table_columns['left_id'] . ' > ' . $item->get_left_id() . ' ORDER BY ' . $this->table_columns['left_id'] . ' ASC'; + } + + $result = $this->db->sql_query_limit($sql, $delta); + + $target = null; + while ($row = $this->db->sql_fetchrow($result)) + { + $target = new $this->item_class($row); + } + $this->db->sql_freeresult($result); + + if (is_null($target)) + { + // The item is already on top or bottom + return false; + } + + /** + * $left_id and $right_id define the scope of the items that are affected by the move. + * $diff_up and $diff_down are the values to substract or add to each item's left_id + * and right_id in order to move them up or down. + * $move_up_left and $move_up_right define the scope of the items that are moving + * up. Other items in the scope of ($left_id, $right_id) are considered to move down. + */ + if ($action == 'move_up') + { + $left_id = $target->get_left_id(); + $right_id = $item->get_right_id(); + + $diff_up = $item->get_left_id() - $target->get_left_id(); + $diff_down = $item->get_right_id() + 1 - $item->get_left_id(); + + $move_up_left = $item->get_left_id(); + $move_up_right = $item->get_right_id(); + } + else + { + $left_id = $item->get_left_id(); + $right_id = $target->get_right_id(); + + $diff_up = $item->get_right_id() + 1 - $item->get_left_id(); + $diff_down = $target->get_right_id() - $item->get_right_id(); + + $move_up_left = $item->get_right_id() + 1; + $move_up_right = $target->get_right_id(); + } + + // Now do the dirty job + $sql = 'UPDATE ' . $this->table_name . ' + SET ' . $this->table_columns['left_id'] . ' = ' . $this->table_columns['left_id'] . ' + CASE + WHEN ' . $this->table_columns['left_id'] . " BETWEEN {$move_up_left} AND {$move_up_right} THEN -{$diff_up} + ELSE {$diff_down} + END, + " . $this->table_columns['right_id'] . ' = ' . $this->table_columns['right_id'] . ' + CASE + WHEN ' . $this->table_columns['right_id'] . " BETWEEN {$move_up_left} AND {$move_up_right} THEN -{$diff_up} + ELSE {$diff_down} + END, + " . $this->table_columns['item_parents'] . " = '' + WHERE + " . $this->table_columns['left_id'] . " BETWEEN {$left_id} AND {$right_id} + AND " . $this->table_columns['right_id'] . " BETWEEN {$left_id} AND {$right_id} + " . $this->get_sql_where(); + $this->db->sql_query($sql); + + return true; + } + + /** + * @inheritdoc + */ + public function move_down(phpbb_nestedset_item_interface $item) + { + return $this->move($item, -1); + } + + /** + * @inheritdoc + */ + public function move_up(phpbb_nestedset_item_interface $item) + { + return $this->move($item, 1); + } + + /** + * @inheritdoc + */ + public function move_children(phpbb_nestedset_item_interface $current_parent, phpbb_nestedset_item_interface $new_parent) + { + if (!$current_parent->has_children() || !$current_parent->get_item_id() || $current_parent->get_item_id() == $new_parent->get_item_id()) + { + return false; + } + + $move_items = array_keys($this->get_branch_data($current_parent, 'children', true, false)); + + if (in_array($new_parent->get_item_id(), $move_items)) + { + throw new phpbb_nestedset_exception('INVALID_PARENT'); + } + + $diff = sizeof($move_items) * 2; + $sql_exclude_moved_items = $this->db->sql_in_set($this->table_columns['item_id'], $move_items, true); + + $this->db->sql_transaction('begin'); + + $this->remove_subset($move_items, $current_parent, false); + + if ($new_parent->get_item_id()) + { + // Retrieve new-parent again, it may have been changed... + $sql = 'SELECT * + FROM ' . $this->table_name . ' + WHERE ' . $this->table_columns['item_id'] . ' = ' . $new_parent->get_item_id(); + $result = $this->db->sql_query($sql); + $parent_data = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + if (!$parent_data) + { + $this->db->sql_transaction('rollback'); + throw new phpbb_nestedset_exception('INVALID_PARENT'); + } + + $new_parent = new $this->item_class($parent_data); + + $new_right_id = $this->prepare_adding_subset($move_items, $new_parent); + + if ($new_right_id > $current_parent->get_right_id()) + { + $diff = ' + ' . ($new_right_id - $current_parent->get_right_id()); + } + else + { + $diff = ' - ' . abs($new_right_id - $current_parent->get_right_id()); + } + } + else + { + $sql = 'SELECT MAX(' . $this->table_columns['right_id'] . ') AS ' . $this->table_columns['right_id'] . ' + FROM ' . $this->table_name . ' + WHERE ' . $sql_exclude_moved_items . ' + ' . $this->get_sql_where('AND'); + $result = $this->db->sql_query($sql); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + $diff = ' + ' . ($row[$this->table_columns['right_id']] - $current_parent->get_left_id()); + } + + $sql = 'UPDATE ' . $this->table_name . ' + SET ' . $this->table_columns['left_id'] . ' = ' . $this->table_columns['left_id'] . $diff . ', + ' . $this->table_columns['right_id'] . ' = ' . $this->table_columns['right_id'] . $diff . ', + ' . $this->table_columns['parent_id'] . ' = ' . $this->db->sql_case($this->table_columns['parent_id'] . ' = ' . $current_parent->get_item_id(), $new_parent->get_item_id(), $this->table_columns['parent_id']) . ', + ' . $this->table_columns['item_parents'] . " = '' + WHERE " . $this->db->sql_in_set($this->table_columns['item_id'], $move_items) . ' + ' . $this->get_sql_where('AND'); + $this->db->sql_query($sql); + + $this->db->sql_transaction('commit'); + + return true; + } + + /** + * @inheritdoc + */ + public function set_parent(phpbb_nestedset_item_interface $item, phpbb_nestedset_item_interface $new_parent) + { + $move_items = array_keys($this->get_branch_data($item, 'children')); + + if (in_array($new_parent->get_item_id(), $move_items)) + { + throw new phpbb_nestedset_exception('INVALID_PARENT'); + } + + $diff = sizeof($move_items) * 2; + $sql_exclude_moved_items = $this->db->sql_in_set($this->table_columns['item_id'], $move_items, true); + + $this->db->sql_transaction('begin'); + + $this->remove_subset($move_items, $item, false); + + if ($new_parent->get_item_id()) + { + // Retrieve new-parent again, it may have been changed... + $sql = 'SELECT * + FROM ' . $this->table_name . ' + WHERE ' . $this->table_columns['item_id'] . ' = ' . $new_parent->get_item_id(); + $result = $this->db->sql_query($sql); + $parent_data = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + if (!$parent_data) + { + $this->db->sql_transaction('rollback'); + throw new phpbb_nestedset_exception('INVALID_PARENT'); + } + + $new_parent = new $this->item_class($parent_data); + + $new_right_id = $this->prepare_adding_subset($move_items, $new_parent); + + if ($new_right_id > $item->get_right_id()) + { + $diff = ' + ' . ($new_right_id - $item->get_right_id() - 1); + } + else + { + $diff = ' - ' . abs($new_right_id - $item->get_right_id() - 1); + } + } + else + { + $sql = 'SELECT MAX(' . $this->table_columns['right_id'] . ') AS ' . $this->table_columns['right_id'] . ' + FROM ' . $this->table_name . ' + WHERE ' . $sql_exclude_moved_items . ' + ' . $this->get_sql_where('AND'); + $result = $this->db->sql_query($sql); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + $diff = ' + ' . ($row[$this->table_columns['right_id']] - $item->get_left_id() + 1); + } + + $sql = 'UPDATE ' . $this->table_name . ' + SET ' . $this->table_columns['left_id'] . ' = ' . $this->table_columns['left_id'] . $diff . ', + ' . $this->table_columns['right_id'] . ' = ' . $this->table_columns['right_id'] . $diff . ', + ' . $this->table_columns['parent_id'] . ' = ' . $this->db->sql_case($this->table_columns['item_id'] . ' = ' . $item->get_item_id(), $new_parent->get_item_id(), $this->table_columns['parent_id']) . ', + ' . $this->table_columns['item_parents'] . " = '' + WHERE " . $this->db->sql_in_set($this->table_columns['item_id'], $move_items) . ' + ' . $this->get_sql_where('AND'); + $this->db->sql_query($sql); + + $this->db->sql_transaction('commit'); + + return true; + } + + /** + * @inheritdoc + */ + public function get_branch_data(phpbb_nestedset_item_interface $item, $type = 'all', $order_desc = true, $include_item = true) + { + switch ($type) + { + case 'parents': + $condition = 'i1.' . $this->table_columns['left_id'] . ' BETWEEN i2.' . $this->table_columns['left_id'] . ' AND i2.' . $this->table_columns['right_id'] . ''; + break; + + case 'children': + $condition = 'i2.' . $this->table_columns['left_id'] . ' BETWEEN i1.' . $this->table_columns['left_id'] . ' AND i1.' . $this->table_columns['right_id'] . ''; + break; + + default: + $condition = 'i2.' . $this->table_columns['left_id'] . ' BETWEEN i1.' . $this->table_columns['left_id'] . ' AND i1.' . $this->table_columns['right_id'] . ' + OR i1.' . $this->table_columns['left_id'] . ' BETWEEN i2.' . $this->table_columns['left_id'] . ' AND i2.' . $this->table_columns['right_id']; + break; + } + + $rows = array(); + + $sql = 'SELECT i2.* + FROM ' . $this->table_name . ' i1 + LEFT JOIN ' . $this->table_name . " i2 + ON (($condition) " . $this->get_sql_where('AND', 'i2.') . ') + WHERE i1.' . $this->table_columns['item_id'] . ' = ' . $item->get_item_id() . ' + ' . $this->get_sql_where('AND', 'i1.') . ' + ORDER BY i2.' . $this->table_columns['left_id'] . ' ' . ($order_desc ? 'ASC' : 'DESC'); + $result = $this->db->sql_query($sql); + + while ($row = $this->db->sql_fetchrow($result)) + { + if (!$include_item && $item->get_item_id() === (int) $row[$this->table_columns['item_id']]) + { + continue; + } + + $rows[$row[$this->table_columns['item_id']]] = $row; + } + $this->db->sql_freeresult($result); + + return $rows; + } + + /** + * Get base information of parent items + * + * Data is cached in the item_parents column in the item table + * + * @inheritdoc + */ + public function get_parent_data(phpbb_nestedset_item_interface $item) + { + $parents = array(); + if ($item->get_parent_id()) + { + if (!$item->get_item_parents_data()) + { + $sql = 'SELECT ' . implode(', ', $this->item_basic_data) . ' + FROM ' . $this->table_name . ' + WHERE ' . $this->table_columns['left_id'] . ' < ' . $item->get_left_id() . ' + AND ' . $this->table_columns['right_id'] . ' > ' . $item->get_right_id() . ' + ' . $this->get_sql_where('AND') . ' + ORDER BY ' . $this->table_columns['left_id'] . ' ASC'; + $result = $this->db->sql_query($sql); + + while ($row = $this->db->sql_fetchrow($result)) + { + $parents[$row[$this->table_columns['item_id']]] = $row; + } + $this->db->sql_freeresult($result); + + $item_parents = serialize($parents); + + $sql = 'UPDATE ' . $this->table_name . ' + SET ' . $this->table_columns['item_parents'] . " = '" . $this->db->sql_escape($item_parents) . "' + WHERE " . $this->table_columns['parent_id'] . ' = ' . $item->get_parent_id(); + $this->db->sql_query($sql); + } + else + { + $parents = unserialize($item->get_item_parents_data()); + } + } + + return $parents; + } + + /** + * Remove a subset from the nested set + * + * @param array $subset_items Subset of items to remove + * @param phpbb_nestedset_item_interface $bounding_item Item containing the right bound of the subset + * @param bool $set_subset_zero Should the parent, left and right id of the item be set to 0, or kept unchanged? + * @return null + */ + protected function remove_subset(array $subset_items, phpbb_nestedset_item_interface $bounding_item, $set_subset_zero = true) + { + $diff = sizeof($subset_items) * 2; + $sql_subset_items = $this->db->sql_in_set($this->table_columns['item_id'], $subset_items); + $sql_not_subset_items = $this->db->sql_in_set($this->table_columns['item_id'], $subset_items, true); + + $sql_is_parent = $this->table_columns['left_id'] . ' <= ' . $bounding_item->get_right_id() . ' + AND ' . $this->table_columns['right_id'] . ' >= ' . $bounding_item->get_right_id(); + + $sql_is_right = $this->table_columns['left_id'] . ' > ' . $bounding_item->get_right_id(); + + $set_left_id = $this->db->sql_case($sql_is_right, $this->table_columns['left_id'] . ' - ' . $diff, $this->table_columns['left_id']); + $set_right_id = $this->db->sql_case($sql_is_parent . ' OR ' . $sql_is_right, $this->table_columns['right_id'] . ' - ' . $diff, $this->table_columns['right_id']); + + if ($set_subset_zero) + { + $set_left_id = $this->db->sql_case($sql_subset_items, 0, $set_left_id); + $set_right_id = $this->db->sql_case($sql_subset_items, 0, $set_right_id); + } + + $sql = 'UPDATE ' . $this->table_name . ' + SET ' . $this->table_columns['left_id'] . ' = ' . $set_left_id . ', + ' . $this->table_columns['right_id'] . ' = ' . $set_right_id . ', + ' . (($set_subset_zero) ? $this->table_columns['parent_id'] . ' = ' . $this->db->sql_case($sql_subset_items, 0, $this->table_columns['parent_id']) . ',' : '') . ' + ' . $this->table_columns['item_parents'] . " = '' + " . ((!$set_subset_zero) ? ' WHERE ' . $sql_not_subset_items . ' ' . $this->get_sql_where('AND') : $this->get_sql_where('WHERE')); + $this->db->sql_query($sql); + } + + /** + * Add a subset to the nested set + * + * @param array $subset_items Subset of items to add + * @param phpbb_nestedset_item_interface $new_parent Item containing the right bound of the new parent + * @return int New right id of the parent item + */ + protected function prepare_adding_subset(array $subset_items, phpbb_nestedset_item_interface $new_parent) + { + $diff = sizeof($subset_items) * 2; + $sql_not_subset_items = $this->db->sql_in_set($this->table_columns['item_id'], $subset_items, true); + + $set_left_id = $this->db->sql_case($this->table_columns['left_id'] . ' > ' . $new_parent->get_right_id(), $this->table_columns['left_id'] . ' + ' . $diff, $this->table_columns['left_id']); + $set_right_id = $this->db->sql_case($this->table_columns['right_id'] . ' >= ' . $new_parent->get_right_id(), $this->table_columns['right_id'] . ' + ' . $diff, $this->table_columns['right_id']); + + $sql = 'UPDATE ' . $this->table_name . ' + SET ' . $this->table_columns['left_id'] . ' = ' . $set_left_id . ', + ' . $this->table_columns['right_id'] . ' = ' . $set_right_id . ', + ' . $this->table_columns['item_parents'] . " = '' + WHERE " . $sql_not_subset_items . ' + ' . $this->get_sql_where('AND'); + $this->db->sql_query($sql); + + return $new_parent->get_right_id() + $diff; + } + + /** + * @inheritdoc + */ + public function recalculate_nested_set($new_id, $parent_id = 0, $reset_ids = false) + { + if ($reset_ids) + { + $sql = 'UPDATE ' . $this->table_name . ' + SET ' . $this->db->sql_build_array('UPDATE', array( + $this->table_columns['left_id'] => 0, + $this->table_columns['right_id'] => 0, + $this->table_columns['item_parents'] => '', + )) . ' + ' . $this->get_sql_where('WHERE'); + $this->db->sql_query($sql); + } + + $sql = 'SELECT * + FROM ' . $this->table_name . ' + WHERE ' . $this->table_columns['parent_id'] . ' = ' . (int) $parent_id . ' + ' . $this->get_sql_where('AND') . ' + ORDER BY ' . $this->table_columns['left_id'] . ', ' . $this->table_columns['item_id'] . ' ASC'; + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + // First we update the left_id for this module + if ($row[$this->table_columns['left_id']] != $new_id) + { + $sql = 'UPDATE ' . $this->table_name . ' + SET ' . $this->db->sql_build_array('UPDATE', array( + $this->table_columns['left_id'] => $new_id, + $this->table_columns['item_parents'] => '', + )) . ' + WHERE ' . $this->table_columns['item_id'] . ' = ' . $row[$this->table_columns['item_id']]; + $this->db->sql_query($sql); + } + $new_id++; + + // Then we go through any children and update their left/right id's + $new_id = $this->recalculate_nested_set($new_id, $row[$this->table_columns['item_id']]); + + // Then we come back and update the right_id for this module + if ($row[$this->table_columns['right_id']] != $new_id) + { + $sql = 'UPDATE ' . $this->table_name . ' + SET ' . $this->db->sql_build_array('UPDATE', array($this->table_columns['right_id'] => $new_id)) . ' + WHERE ' . $this->table_columns['item_id'] . ' = ' . $row[$this->table_columns['item_id']]; + $this->db->sql_query($sql); + } + $new_id++; + } + $this->db->sql_freeresult($result); + + return $new_id; + } +} diff --git a/phpBB/includes/nestedset/item/base.php b/phpBB/includes/nestedset/item/base.php new file mode 100644 index 0000000000..c3a7600827 --- /dev/null +++ b/phpBB/includes/nestedset/item/base.php @@ -0,0 +1,82 @@ +item_id; + } + + /** + * @inheritdoc + */ + public function get_parent_id() + { + return (int) $this->parent_id; + } + + /** + * @inheritdoc + */ + public function get_item_parents_data() + { + return (string) $this->item_parents_data; + } + + /** + * @inheritdoc + */ + public function get_left_id() + { + return (int) $this->left_id; + } + + /** + * @inheritdoc + */ + public function get_right_id() + { + return (int) $this->right_id; + } + + /** + * @inheritdoc + */ + public function has_children() + { + return $this->right_id - $this->left_id > 1; + } +} From 57a05e7cf509f56309591aaf9344226a8f1a9a8e Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 16 Apr 2013 23:09:21 +0200 Subject: [PATCH 131/281] [ticket/11495] Add forum implementation of nestedset PHPBB3-11495 --- phpBB/includes/nestedset/exception.php | 20 ++++ phpBB/includes/nestedset/forum.php | 121 ++++++++++++++++++++++++ phpBB/includes/nestedset/item/forum.php | 28 ++++++ 3 files changed, 169 insertions(+) create mode 100644 phpBB/includes/nestedset/exception.php create mode 100644 phpBB/includes/nestedset/forum.php create mode 100644 phpBB/includes/nestedset/item/forum.php diff --git a/phpBB/includes/nestedset/exception.php b/phpBB/includes/nestedset/exception.php new file mode 100644 index 0000000000..10937d0b29 --- /dev/null +++ b/phpBB/includes/nestedset/exception.php @@ -0,0 +1,20 @@ + 'forum_id', + 'left_id' => 'left_id', + 'right_id' => 'right_id', + 'parent_id' => 'parent_id', + 'item_parents' => 'forum_parents', + ); + + /** + * Additional SQL restrictions + * Allows to have multiple nestedsets in one table + * Columns must be prefixed with %1$s + * @var String + */ + protected $sql_where = ''; + + /** + * List of item properties to be cached in $item_parents + * @var array + */ + protected $item_basic_data = array('forum_id', 'forum_name', 'forum_type'); + + /** + * Construct + * + * @param phpbb_db_driver $db Database connection + * @param phpbb_lock_db $lock Lock class used to lock the table when moving forums around + * @param string $table_name Table name + */ + public function __construct(phpbb_db_driver $db, phpbb_lock_db $lock, $table_name) + { + $this->db = $db; + $this->lock = $lock; + $this->table_name = $table_name; + } + + /** + * @inheritdoc + */ + public function move_children(phpbb_nestedset_item_interface $current_parent, phpbb_nestedset_item_interface $new_parent) + { + while (!$this->lock->acquire()) + { + // Retry after 0.2 seconds + usleep(200 * 1000); + } + + try + { + $return = parent::move_children($current_parent, $new_parent); + } + catch (phpbb_nestedset_exception $e) + { + $this->lock->release(); + throw new phpbb_nestedset_exception('FORUM_NESTEDSET_' . $e->getMessage()); + } + $this->lock->release(); + + return $return; + } + + /** + * @inheritdoc + */ + public function set_parent(phpbb_nestedset_item_interface $item, phpbb_nestedset_item_interface $new_parent) + { + while (!$this->lock->acquire()) + { + // Retry after 0.2 seconds + usleep(200 * 1000); + } + + try + { + $return = parent::set_parent($item, $new_parent); + } + catch (phpbb_nestedset_exception $e) + { + $this->lock->release(); + throw new phpbb_nestedset_exception('FORUM_NESTEDSET_' . $e->getMessage()); + } + $this->lock->release(); + + return $return; + } +} diff --git a/phpBB/includes/nestedset/item/forum.php b/phpBB/includes/nestedset/item/forum.php new file mode 100644 index 0000000000..9475517999 --- /dev/null +++ b/phpBB/includes/nestedset/item/forum.php @@ -0,0 +1,28 @@ +item_id = (int) $forum_row['forum_id']; + $this->parent_id = (int) $forum_row['parent_id']; + $this->left_id = (int) $forum_row['left_id']; + $this->right_id = (int) $forum_row['right_id']; + $this->item_parents_data = (string) $forum_row['forum_parents']; + } +} From dcee7961e80a0d188d887a13cc6409623bc1ff6e Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 16 Apr 2013 23:09:56 +0200 Subject: [PATCH 132/281] [ticket/11495] Add unit tests for the implemented functions PHPBB3-11495 --- tests/nestedset/fixtures/phpbb_forums.xml | 123 ++++ tests/nestedset/item_forum_test.php | 31 + tests/nestedset/set_forum_add_remove_test.php | 195 ++++++ tests/nestedset/set_forum_base.php | 61 ++ tests/nestedset/set_forum_get_data_test.php | 96 +++ tests/nestedset/set_forum_move_test.php | 565 ++++++++++++++++++ .../nestedset/set_forum_recalculate_test.php | 72 +++ tests/nestedset/set_forum_test.php | 116 ++++ 8 files changed, 1259 insertions(+) create mode 100644 tests/nestedset/fixtures/phpbb_forums.xml create mode 100644 tests/nestedset/item_forum_test.php create mode 100644 tests/nestedset/set_forum_add_remove_test.php create mode 100644 tests/nestedset/set_forum_base.php create mode 100644 tests/nestedset/set_forum_get_data_test.php create mode 100644 tests/nestedset/set_forum_move_test.php create mode 100644 tests/nestedset/set_forum_recalculate_test.php create mode 100644 tests/nestedset/set_forum_test.php diff --git a/tests/nestedset/fixtures/phpbb_forums.xml b/tests/nestedset/fixtures/phpbb_forums.xml new file mode 100644 index 0000000000..016c8ea7c5 --- /dev/null +++ b/tests/nestedset/fixtures/phpbb_forums.xml @@ -0,0 +1,123 @@ + + + + forum_id + parent_id + left_id + right_id + forum_parents + forum_name + forum_desc + forum_rules + + 1 + 0 + 1 + 6 + + Parent with two flat children + + + + + 2 + 1 + 2 + 3 + + Flat child #1 + + + + + 3 + 1 + 4 + 5 + + Flat child #2 + + + + + 4 + 0 + 7 + 12 + + Parent with two nested children + + + + + 5 + 4 + 8 + 11 + + Nested child #1 + + + + + 6 + 5 + 9 + 10 + + Nested child #2 + + + + + 7 + 0 + 13 + 22 + + Parent with flat and nested children + + + + + 8 + 7 + 14 + 15 + + Mixed child #1 + + + + + 9 + 7 + 16 + 19 + + Mixed child #2 + + + + + 10 + 9 + 17 + 18 + + Nested child #1 of Mixed child #2 + + + + + 11 + 7 + 20 + 21 + + Mixed child #3 + + + +
    +
    diff --git a/tests/nestedset/item_forum_test.php b/tests/nestedset/item_forum_test.php new file mode 100644 index 0000000000..1ca89ebd2f --- /dev/null +++ b/tests/nestedset/item_forum_test.php @@ -0,0 +1,31 @@ + 1, + 'forum_id' => 5, + 'user_id' => 32, + 'left_id' => 2, + 'right_id' => 3, + 'forum_parents' => '', + ); + + $forum = new phpbb_nestedset_item_forum($forum_data); + + $this->assertEquals($forum->get_item_id(), $forum_data['forum_id']); + $this->assertEquals($forum->get_left_id(), $forum_data['left_id']); + $this->assertEquals($forum->get_right_id(), $forum_data['right_id']); + $this->assertEquals($forum->get_parent_id(), $forum_data['parent_id']); + $this->assertEquals($forum->get_item_parents_data(), $forum_data['forum_parents']); + } +} diff --git a/tests/nestedset/set_forum_add_remove_test.php b/tests/nestedset/set_forum_add_remove_test.php new file mode 100644 index 0000000000..f7d4980292 --- /dev/null +++ b/tests/nestedset/set_forum_add_remove_test.php @@ -0,0 +1,195 @@ + 1, 'parent_id' => 0, 'left_id' => 0, 'right_id' => 0, 'forum_parents' => ''), + array('forum_id' => 2, 'parent_id' => 0, 'left_id' => 0, 'right_id' => 0, 'forum_parents' => ''), + array('forum_id' => 3, 'parent_id' => 0, 'left_id' => 0, 'right_id' => 0, 'forum_parents' => ''), + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => ''), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 2, 'right_id' => 5, 'forum_parents' => ''), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 3, 'right_id' => 4, 'forum_parents' => ''), + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 16, 'forum_parents' => ''), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 8, 'right_id' => 9, 'forum_parents' => ''), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 10, 'right_id' => 13, 'forum_parents' => ''), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 11, 'right_id' => 12, 'forum_parents' => ''), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => ''), + ), array( + 1 => array('parent_id' => 0, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => ''), + 2 => array('parent_id' => 0, 'left_id' => 19, 'right_id' => 20, 'forum_parents' => ''), + 3 => array('parent_id' => 0, 'left_id' => 21, 'right_id' => 22, 'forum_parents' => ''), + ), array( + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => ''), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 2, 'right_id' => 5, 'forum_parents' => ''), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 3, 'right_id' => 4, 'forum_parents' => ''), + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 16, 'forum_parents' => ''), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 8, 'right_id' => 9, 'forum_parents' => ''), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 10, 'right_id' => 13, 'forum_parents' => ''), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 11, 'right_id' => 12, 'forum_parents' => ''), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => ''), + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => ''), + array('forum_id' => 2, 'parent_id' => 0, 'left_id' => 19, 'right_id' => 20, 'forum_parents' => ''), + array('forum_id' => 3, 'parent_id' => 0, 'left_id' => 21, 'right_id' => 22, 'forum_parents' => ''), + )), + array(2, array(2), array( + array('forum_id' => 2, 'parent_id' => 0, 'left_id' => 0, 'right_id' => 0, 'forum_parents' => ''), + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 4, 'forum_parents' => ''), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => ''), + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 5, 'right_id' => 10, 'forum_parents' => ''), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 6, 'right_id' => 9, 'forum_parents' => ''), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 7, 'right_id' => 8, 'forum_parents' => ''), + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 11, 'right_id' => 20, 'forum_parents' => ''), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 12, 'right_id' => 13, 'forum_parents' => ''), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 17, 'forum_parents' => ''), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 15, 'right_id' => 16, 'forum_parents' => ''), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 18, 'right_id' => 19, 'forum_parents' => ''), + ), array( + 2 => array('parent_id' => 0, 'left_id' => 21, 'right_id' => 22, 'forum_parents' => '') + ), array( + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 4, 'forum_parents' => ''), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => ''), + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 5, 'right_id' => 10, 'forum_parents' => ''), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 6, 'right_id' => 9, 'forum_parents' => ''), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 7, 'right_id' => 8, 'forum_parents' => ''), + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 11, 'right_id' => 20, 'forum_parents' => ''), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 12, 'right_id' => 13, 'forum_parents' => ''), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 17, 'forum_parents' => ''), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 15, 'right_id' => 16, 'forum_parents' => ''), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 18, 'right_id' => 19, 'forum_parents' => ''), + array('forum_id' => 2, 'parent_id' => 0, 'left_id' => 21, 'right_id' => 22, 'forum_parents' => ''), + )), + ); + } + + /** + * @dataProvider remove_add_data + */ + public function test_remove_add($forum_id, $expected_removed, $expected_remove_table, $expected_added, $expected_add_table) + { + $forum = new phpbb_nestedset_item_forum($this->forum_data[$forum_id]); + + $removed_items = $this->set->remove($forum); + + $this->assertEquals($expected_removed, $removed_items); + + $result = $this->db->sql_query("SELECT forum_id, parent_id, left_id, right_id, forum_parents + FROM phpbb_forums + ORDER BY left_id, forum_id ASC"); + $this->assertEquals($expected_remove_table, $this->db->sql_fetchrowset($result)); + + $added_items = array(); + foreach ($removed_items as $item_id) + { + $forum = new phpbb_nestedset_item_forum($this->forum_data[$item_id]); + $added_items[$item_id] = $this->set->add($forum); + } + $this->assertEquals($expected_added, $added_items); + + $result = $this->db->sql_query("SELECT forum_id, parent_id, left_id, right_id, forum_parents + FROM phpbb_forums + ORDER BY left_id, forum_id ASC"); + $this->assertEquals($expected_add_table, $this->db->sql_fetchrowset($result)); + } + + public function delete_data() + { + return array( + array(1, array(1, 2, 3), array( + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => ''), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 2, 'right_id' => 5, 'forum_parents' => ''), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 3, 'right_id' => 4, 'forum_parents' => ''), + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 16, 'forum_parents' => ''), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 8, 'right_id' => 9, 'forum_parents' => ''), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 10, 'right_id' => 13, 'forum_parents' => ''), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 11, 'right_id' => 12, 'forum_parents' => ''), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => ''), + )), + array(2, array(2), array( + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 4, 'forum_parents' => ''), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => ''), + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 5, 'right_id' => 10, 'forum_parents' => ''), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 6, 'right_id' => 9, 'forum_parents' => ''), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 7, 'right_id' => 8, 'forum_parents' => ''), + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 11, 'right_id' => 20, 'forum_parents' => ''), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 12, 'right_id' => 13, 'forum_parents' => ''), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 17, 'forum_parents' => ''), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 15, 'right_id' => 16, 'forum_parents' => ''), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 18, 'right_id' => 19, 'forum_parents' => ''), + )), + ); + } + + /** + * @dataProvider delete_data + */ + public function test_delete($forum_id, $expected_deleted, $expected) + { + $forum = new phpbb_nestedset_item_forum($this->forum_data[$forum_id]); + + $this->assertEquals($expected_deleted, $this->set->delete($forum)); + + $result = $this->db->sql_query("SELECT forum_id, parent_id, left_id, right_id, forum_parents + FROM phpbb_forums + ORDER BY left_id, forum_id ASC"); + $this->assertEquals($expected, $this->db->sql_fetchrowset($result)); + } + + public function insert_data() + { + return array( + array(array( + 'forum_desc' => '', + 'forum_rules' => '', + 'forum_id' => 12, + 'parent_id' => 0, + 'left_id' => 23, + 'right_id' => 24, + 'forum_parents' => '', + ), array( + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => ''), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => ''), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => ''), + + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12, 'forum_parents' => ''), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 8, 'right_id' => 11, 'forum_parents' => ''), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 9, 'right_id' => 10, 'forum_parents' => ''), + + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => ''), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => ''), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => ''), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => ''), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => ''), + + array('forum_id' => 12, 'parent_id' => 0, 'left_id' => 23, 'right_id' => 24, 'forum_parents' => ''), + )), + ); + } + + /** + * @dataProvider insert_data + */ + public function test_insert($expected_data, $expected) + { + $this->assertEquals($expected_data, $this->set->insert(array( + 'forum_desc' => '', + 'forum_rules' => '', + ))); + + $result = $this->db->sql_query('SELECT forum_id, parent_id, left_id, right_id, forum_parents + FROM phpbb_forums + ORDER BY left_id, forum_id ASC'); + $this->assertEquals($expected, $this->db->sql_fetchrowset($result)); + } +} diff --git a/tests/nestedset/set_forum_base.php b/tests/nestedset/set_forum_base.php new file mode 100644 index 0000000000..4523f12897 --- /dev/null +++ b/tests/nestedset/set_forum_base.php @@ -0,0 +1,61 @@ +createXMLDataSet(dirname(__FILE__) . '/fixtures/phpbb_forums.xml'); + } + + protected $forum_data = array( + // \__/ + 1 => array('forum_id' => 1, 'parent_id' => 0, 'user_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => ''), + 2 => array('forum_id' => 2, 'parent_id' => 1, 'user_id' => 0, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => ''), + 3 => array('forum_id' => 3, 'parent_id' => 1, 'user_id' => 0, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => ''), + + // \ / + // \/ + 4 => array('forum_id' => 4, 'parent_id' => 0, 'user_id' => 0, 'left_id' => 7, 'right_id' => 12, 'forum_parents' => ''), + 5 => array('forum_id' => 5, 'parent_id' => 4, 'user_id' => 0, 'left_id' => 8, 'right_id' => 11, 'forum_parents' => ''), + 6 => array('forum_id' => 6, 'parent_id' => 5, 'user_id' => 0, 'left_id' => 9, 'right_id' => 10, 'forum_parents' => ''), + + // \_ _/ + // \/ + 7 => array('forum_id' => 7, 'parent_id' => 0, 'user_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => ''), + 8 => array('forum_id' => 8, 'parent_id' => 7, 'user_id' => 0, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => ''), + 9 => array('forum_id' => 9, 'parent_id' => 7, 'user_id' => 0, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => ''), + 10 => array('forum_id' => 10, 'parent_id' => 9, 'user_id' => 0, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => ''), + 11 => array('forum_id' => 11, 'parent_id' => 7, 'user_id' => 0, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => ''), + + // Unexisting forums + 0 => array('forum_id' => 0, 'parent_id' => 0, 'user_id' => 0, 'left_id' => 0, 'right_id' => 0, 'forum_parents' => ''), + 200 => array('forum_id' => 200, 'parent_id' => 0, 'user_id' => 0, 'left_id' => 0, 'right_id' => 0, 'forum_parents' => ''), + ); + + protected $set, + $config, + $lock, + $db; + + public function setUp() + { + parent::setUp(); + + $this->db = $this->new_dbal(); + + global $config; + + $config = $this->config = new phpbb_config(array('nestedset_forum_lock' => 0)); + set_config(null, null, null, $this->config); + + $this->lock = new phpbb_lock_db('nestedset_forum_lock', $this->config, $this->db); + $this->set = new phpbb_nestedset_forum($this->db, $this->lock, 'phpbb_forums'); + } +} diff --git a/tests/nestedset/set_forum_get_data_test.php b/tests/nestedset/set_forum_get_data_test.php new file mode 100644 index 0000000000..b7314efd15 --- /dev/null +++ b/tests/nestedset/set_forum_get_data_test.php @@ -0,0 +1,96 @@ +forum_data[$forum_id]); + + $this->assertEquals($expected, array_keys($this->set->get_branch_data($forum, $type, $order_desc, $include_item))); + } + + public function get_parent_data_data() + { + return array( + array(1, array(), array()), + array(1, array('forum_parents' => serialize(array())), array()), + array(2, array(), array(1)), + array(2, array('forum_parents' => serialize(array(1 => array()))), array(1)), + array(10, array(), array(7, 9)), + array(10, array('forum_parents' => serialize(array(7 => array(), 9 => array()))), array(7, 9)), + ); + } + + /** + * @dataProvider get_parent_data_data + */ + public function test_get_parent_data($forum_id, $forum_data, $expected) + { + $data = array_merge($this->forum_data[$forum_id], $forum_data); + $forum = new phpbb_nestedset_item_forum($data); + + $this->assertEquals($expected, array_keys($this->set->get_parent_data($forum))); + } +} diff --git a/tests/nestedset/set_forum_move_test.php b/tests/nestedset/set_forum_move_test.php new file mode 100644 index 0000000000..7e1c03e60f --- /dev/null +++ b/tests/nestedset/set_forum_move_test.php @@ -0,0 +1,565 @@ + 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => ''), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => ''), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => ''), + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12, 'forum_parents' => ''), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 8, 'right_id' => 11, 'forum_parents' => ''), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 9, 'right_id' => 10, 'forum_parents' => ''), + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => ''), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => ''), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => ''), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => ''), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => ''), + )), + array('Move last item down', + 7, -1, false, array( + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => ''), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => ''), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => ''), + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12, 'forum_parents' => ''), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 8, 'right_id' => 11, 'forum_parents' => ''), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 9, 'right_id' => 10, 'forum_parents' => ''), + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => ''), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => ''), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => ''), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => ''), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => ''), + )), + array('Move first item down', + 1, -1, true, array( + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => ''), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 2, 'right_id' => 5, 'forum_parents' => ''), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 3, 'right_id' => 4, 'forum_parents' => ''), + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12, 'forum_parents' => ''), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 8, 'right_id' => 9, 'forum_parents' => ''), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 10, 'right_id' => 11, 'forum_parents' => ''), + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => ''), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => ''), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => ''), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => ''), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => ''), + )), + array('Move second item up', + 4, 1, true, array( + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => ''), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 2, 'right_id' => 5, 'forum_parents' => ''), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 3, 'right_id' => 4, 'forum_parents' => ''), + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12, 'forum_parents' => ''), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 8, 'right_id' => 9, 'forum_parents' => ''), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 10, 'right_id' => 11, 'forum_parents' => ''), + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => ''), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => ''), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => ''), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => ''), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => ''), + )), + array('Move last item up', + 7, 1, true, array( + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => ''), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => ''), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => ''), + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 16, 'forum_parents' => ''), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 8, 'right_id' => 9, 'forum_parents' => ''), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 10, 'right_id' => 13, 'forum_parents' => ''), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 11, 'right_id' => 12, 'forum_parents' => ''), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => ''), + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 17, 'right_id' => 22, 'forum_parents' => ''), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 18, 'right_id' => 21, 'forum_parents' => ''), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 19, 'right_id' => 20, 'forum_parents' => ''), + )), + array('Move last item up by 2', + 7, 2, true, array( + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 10, 'forum_parents' => ''), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => ''), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 4, 'right_id' => 7, 'forum_parents' => ''), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 5, 'right_id' => 6, 'forum_parents' => ''), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 8, 'right_id' => 9, 'forum_parents' => ''), + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 11, 'right_id' => 16, 'forum_parents' => ''), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 12, 'right_id' => 13, 'forum_parents' => ''), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => ''), + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 17, 'right_id' => 22, 'forum_parents' => ''), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 18, 'right_id' => 21, 'forum_parents' => ''), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 19, 'right_id' => 20, 'forum_parents' => ''), + )), + array('Move last item up by 100', + 7, 100, true, array( + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 10, 'forum_parents' => ''), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => ''), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 4, 'right_id' => 7, 'forum_parents' => ''), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 5, 'right_id' => 6, 'forum_parents' => ''), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 8, 'right_id' => 9, 'forum_parents' => ''), + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 11, 'right_id' => 16, 'forum_parents' => ''), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 12, 'right_id' => 13, 'forum_parents' => ''), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => ''), + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 17, 'right_id' => 22, 'forum_parents' => ''), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 18, 'right_id' => 21, 'forum_parents' => ''), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 19, 'right_id' => 20, 'forum_parents' => ''), + )), + ); + } + + /** + * @dataProvider move_data + */ + public function test_move($explain, $forum_id, $delta, $expected_moved, $expected) + { + $forum = new phpbb_nestedset_item_forum($this->forum_data[$forum_id]); + + $this->assertEquals($expected_moved, $this->set->move($forum, $delta)); + + $result = $this->db->sql_query("SELECT forum_id, parent_id, left_id, right_id, forum_parents + FROM phpbb_forums + ORDER BY left_id, forum_id ASC"); + $this->assertEquals($expected, $this->db->sql_fetchrowset($result)); + } + + public function move_down_data() + { + return array( + array('Move last item down', + 7, false, array( + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => ''), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => ''), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => ''), + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12, 'forum_parents' => ''), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 8, 'right_id' => 11, 'forum_parents' => ''), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 9, 'right_id' => 10, 'forum_parents' => ''), + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => ''), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => ''), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => ''), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => ''), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => ''), + )), + array('Move first item down', + 1, true, array( + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => ''), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 2, 'right_id' => 5, 'forum_parents' => ''), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 3, 'right_id' => 4, 'forum_parents' => ''), + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12, 'forum_parents' => ''), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 8, 'right_id' => 9, 'forum_parents' => ''), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 10, 'right_id' => 11, 'forum_parents' => ''), + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => ''), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => ''), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => ''), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => ''), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => ''), + )), + ); + } + + /** + * @dataProvider move_down_data + */ + public function test_move_down($explain, $forum_id, $expected_moved, $expected) + { + $forum = new phpbb_nestedset_item_forum($this->forum_data[$forum_id]); + + $this->assertEquals($expected_moved, $this->set->move_down($forum)); + + $result = $this->db->sql_query("SELECT forum_id, parent_id, left_id, right_id, forum_parents + FROM phpbb_forums + ORDER BY left_id, forum_id ASC"); + $this->assertEquals($expected, $this->db->sql_fetchrowset($result)); + } + + public function move_up_data() + { + return array( + array('Move first item up', + 1, false, array( + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => ''), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => ''), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => ''), + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12, 'forum_parents' => ''), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 8, 'right_id' => 11, 'forum_parents' => ''), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 9, 'right_id' => 10, 'forum_parents' => ''), + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => ''), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => ''), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => ''), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => ''), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => ''), + )), + array('Move second item up', + 4, true, array( + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => ''), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 2, 'right_id' => 5, 'forum_parents' => ''), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 3, 'right_id' => 4, 'forum_parents' => ''), + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12, 'forum_parents' => ''), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 8, 'right_id' => 9, 'forum_parents' => ''), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 10, 'right_id' => 11, 'forum_parents' => ''), + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => ''), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => ''), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => ''), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => ''), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => ''), + )), + ); + } + + /** + * @dataProvider move_up_data + */ + public function test_move_up($explain, $forum_id, $expected_moved, $expected) + { + $forum = new phpbb_nestedset_item_forum($this->forum_data[$forum_id]); + + $this->assertEquals($expected_moved, $this->set->move_up($forum)); + + $result = $this->db->sql_query("SELECT forum_id, parent_id, left_id, right_id, forum_parents + FROM phpbb_forums + ORDER BY left_id, forum_id ASC"); + $this->assertEquals($expected, $this->db->sql_fetchrowset($result)); + } + + public function move_children_data() + { + return array( + array('Item has no children', + 2, 1, false, array( + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => ''), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => ''), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => ''), + + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12, 'forum_parents' => ''), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 8, 'right_id' => 11, 'forum_parents' => ''), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 9, 'right_id' => 10, 'forum_parents' => ''), + + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => ''), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => ''), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => ''), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => ''), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => ''), + )), + array('Move to same parent', + 4, 4, false, array( + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => ''), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => ''), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => ''), + + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12, 'forum_parents' => ''), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 8, 'right_id' => 11, 'forum_parents' => ''), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 9, 'right_id' => 10, 'forum_parents' => ''), + + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => ''), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => ''), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => ''), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => ''), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => ''), + )), + array('Parent is 0', + 0, 1, false, array( + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => ''), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => ''), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => ''), + + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12, 'forum_parents' => ''), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 8, 'right_id' => 11, 'forum_parents' => ''), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 9, 'right_id' => 10, 'forum_parents' => ''), + + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => ''), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => ''), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => ''), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => ''), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => ''), + )), + array('Move single child up', + 5, 1, true, array( + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 8, 'forum_parents' => ''), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => ''), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => ''), + array('forum_id' => 6, 'parent_id' => 1, 'left_id' => 6, 'right_id' => 7, 'forum_parents' => ''), + + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 9, 'right_id' => 12, 'forum_parents' => ''), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 10, 'right_id' => 11, 'forum_parents' => ''), + + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => ''), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => ''), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => ''), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => ''), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => ''), + )), + array('Move nested children up', + 4, 1, true, array( + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 10, 'forum_parents' => ''), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => ''), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => ''), + array('forum_id' => 5, 'parent_id' => 1, 'left_id' => 6, 'right_id' => 9, 'forum_parents' => ''), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 7, 'right_id' => 8, 'forum_parents' => ''), + + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 11, 'right_id' => 12, 'forum_parents' => ''), + + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => ''), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => ''), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => ''), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => ''), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => ''), + )), + array('Move single child down', + 5, 7, true, array( + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => ''), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => ''), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => ''), + + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 10, 'forum_parents' => ''), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 8, 'right_id' => 9, 'forum_parents' => ''), + + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 11, 'right_id' => 22, 'forum_parents' => ''), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 12, 'right_id' => 13, 'forum_parents' => ''), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 17, 'forum_parents' => ''), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 15, 'right_id' => 16, 'forum_parents' => ''), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 18, 'right_id' => 19, 'forum_parents' => ''), + array('forum_id' => 6, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => ''), + + )), + array('Move nested children down', + 4, 7, true, array( + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => ''), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => ''), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => ''), + + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 8, 'forum_parents' => ''), + + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 9, 'right_id' => 22, 'forum_parents' => ''), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 10, 'right_id' => 11, 'forum_parents' => ''), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 12, 'right_id' => 15, 'forum_parents' => ''), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 13, 'right_id' => 14, 'forum_parents' => ''), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 17, 'forum_parents' => ''), + array('forum_id' => 5, 'parent_id' => 7, 'left_id' => 18, 'right_id' => 21, 'forum_parents' => ''), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 19, 'right_id' => 20, 'forum_parents' => ''), + )), + array('Move single child to parent 0', + 5, 0, true, array( + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => ''), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => ''), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => ''), + + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 10, 'forum_parents' => ''), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 8, 'right_id' => 9, 'forum_parents' => ''), + + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 11, 'right_id' => 20, 'forum_parents' => ''), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 12, 'right_id' => 13, 'forum_parents' => ''), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 17, 'forum_parents' => ''), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 15, 'right_id' => 16, 'forum_parents' => ''), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 18, 'right_id' => 19, 'forum_parents' => ''), + + array('forum_id' => 6, 'parent_id' => 0, 'left_id' => 21, 'right_id' => 22, 'forum_parents' => ''), + )), + array('Move nested children to parent 0', + 4, 0, true, array( + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => ''), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => ''), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => ''), + + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 8, 'forum_parents' => ''), + + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 9, 'right_id' => 18, 'forum_parents' => ''), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 10, 'right_id' => 11, 'forum_parents' => ''), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 12, 'right_id' => 15, 'forum_parents' => ''), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 13, 'right_id' => 14, 'forum_parents' => ''), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 17, 'forum_parents' => ''), + + array('forum_id' => 5, 'parent_id' => 0, 'left_id' => 19, 'right_id' => 22, 'forum_parents' => ''), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => ''), + )), + ); + } + + /** + * @dataProvider move_children_data + */ + public function test_move_children($explain, $forum_id, $target_id, $expected_moved, $expected) + { + $forum = new phpbb_nestedset_item_forum($this->forum_data[$forum_id]); + $target = new phpbb_nestedset_item_forum($this->forum_data[$target_id]); + + $this->assertEquals($expected_moved, $this->set->move_children($forum, $target)); + + $result = $this->db->sql_query("SELECT forum_id, parent_id, left_id, right_id, forum_parents + FROM phpbb_forums + ORDER BY left_id, forum_id ASC"); + $this->assertEquals($expected, $this->db->sql_fetchrowset($result)); + } + + public function move_children_throws_data() + { + return array( + array('New parent is child', 4, 5), + array('New parent is child 2', 7, 9), + array('New parent does not exist', 1, 200), + ); + } + + /** + * @dataProvider move_children_throws_data + * + * @expectedException phpbb_nestedset_exception + * @expectedExceptionMessage FORUM_NESTEDSET_INVALID_PARENT + */ + public function test_move_children_throws($explain, $forum_id, $target_id) + { + $forum = new phpbb_nestedset_item_forum($this->forum_data[$forum_id]); + $target = new phpbb_nestedset_item_forum($this->forum_data[$target_id]); + + $this->set->move_children($forum, $target); + } + + public function set_parent_data() + { + return array( + array('Move single child up', + 6, 1, true, array( + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 8, 'forum_parents' => ''), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => ''), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => ''), + array('forum_id' => 6, 'parent_id' => 1, 'left_id' => 6, 'right_id' => 7, 'forum_parents' => ''), + + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 9, 'right_id' => 12, 'forum_parents' => ''), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 10, 'right_id' => 11, 'forum_parents' => ''), + + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => ''), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => ''), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => ''), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => ''), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => ''), + )), + array('Move nested children up', + 5, 1, true, array( + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 10, 'forum_parents' => ''), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => ''), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => ''), + array('forum_id' => 5, 'parent_id' => 1, 'left_id' => 6, 'right_id' => 9, 'forum_parents' => ''), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 7, 'right_id' => 8, 'forum_parents' => ''), + + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 11, 'right_id' => 12, 'forum_parents' => ''), + + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => ''), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => ''), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => ''), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => ''), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => ''), + )), + array('Move single child down', + 6, 7, true, array( + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => ''), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => ''), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => ''), + + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 10, 'forum_parents' => ''), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 8, 'right_id' => 9, 'forum_parents' => ''), + + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 11, 'right_id' => 22, 'forum_parents' => ''), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 12, 'right_id' => 13, 'forum_parents' => ''), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 17, 'forum_parents' => ''), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 15, 'right_id' => 16, 'forum_parents' => ''), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 18, 'right_id' => 19, 'forum_parents' => ''), + array('forum_id' => 6, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => ''), + )), + array('Move nested children down', + 5, 7, true, array( + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => ''), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => ''), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => ''), + + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 8, 'forum_parents' => ''), + + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 9, 'right_id' => 22, 'forum_parents' => ''), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 10, 'right_id' => 11, 'forum_parents' => ''), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 12, 'right_id' => 15, 'forum_parents' => ''), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 13, 'right_id' => 14, 'forum_parents' => ''), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 17, 'forum_parents' => ''), + array('forum_id' => 5, 'parent_id' => 7, 'left_id' => 18, 'right_id' => 21, 'forum_parents' => ''), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 19, 'right_id' => 20, 'forum_parents' => ''), + )), + array('Move single child to parent 0', + 6, 0, true, array( + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => ''), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => ''), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => ''), + + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 10, 'forum_parents' => ''), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 8, 'right_id' => 9, 'forum_parents' => ''), + + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 11, 'right_id' => 20, 'forum_parents' => ''), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 12, 'right_id' => 13, 'forum_parents' => ''), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 17, 'forum_parents' => ''), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 15, 'right_id' => 16, 'forum_parents' => ''), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 18, 'right_id' => 19, 'forum_parents' => ''), + + array('forum_id' => 6, 'parent_id' => 0, 'left_id' => 21, 'right_id' => 22, 'forum_parents' => ''), + )), + array('Move nested children to parent 0', + 5, 0, true, array( + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => ''), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => ''), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => ''), + + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 8, 'forum_parents' => ''), + + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 9, 'right_id' => 18, 'forum_parents' => ''), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 10, 'right_id' => 11, 'forum_parents' => ''), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 12, 'right_id' => 15, 'forum_parents' => ''), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 13, 'right_id' => 14, 'forum_parents' => ''), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 17, 'forum_parents' => ''), + + array('forum_id' => 5, 'parent_id' => 0, 'left_id' => 19, 'right_id' => 22, 'forum_parents' => ''), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => ''), + )), + ); + } + + /** + * @dataProvider set_parent_data + */ + public function test_set_parent($explain, $forum_id, $target_id, $expected_moved, $expected) + { + $forum = new phpbb_nestedset_item_forum($this->forum_data[$forum_id]); + $target = new phpbb_nestedset_item_forum($this->forum_data[$target_id]); + + $this->assertEquals($expected_moved, $this->set->set_parent($forum, $target)); + + $result = $this->db->sql_query("SELECT forum_id, parent_id, left_id, right_id, forum_parents + FROM phpbb_forums + ORDER BY left_id, forum_id ASC"); + $this->assertEquals($expected, $this->db->sql_fetchrowset($result)); + } + + public function set_parent_throws_data() + { + return array( + array('New parent is child', 4, 5), + array('New parent is child 2', 7, 9), + array('New parent does not exist', 1, 200), + ); + } + + /** + * @dataProvider set_parent_throws_data + * + * @expectedException phpbb_nestedset_exception + * @expectedExceptionMessage FORUM_NESTEDSET_INVALID_PARENT + */ + public function test_set_parent_throws($explain, $forum_id, $target_id) + { + $forum = new phpbb_nestedset_item_forum($this->forum_data[$forum_id]); + $target = new phpbb_nestedset_item_forum($this->forum_data[$target_id]); + + $this->set->set_parent($forum, $target); + } +} diff --git a/tests/nestedset/set_forum_recalculate_test.php b/tests/nestedset/set_forum_recalculate_test.php new file mode 100644 index 0000000000..6ff7a372a4 --- /dev/null +++ b/tests/nestedset/set_forum_recalculate_test.php @@ -0,0 +1,72 @@ + 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => ''), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => ''), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => ''), + + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12, 'forum_parents' => ''), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 8, 'right_id' => 11, 'forum_parents' => ''), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 9, 'right_id' => 10, 'forum_parents' => ''), + + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => ''), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => ''), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => ''), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => ''), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => ''), + ); + + public function recalculate_nested_set_data() + { + return array( + array('UPDATE phpbb_forums + SET left_id = 0, + right_id = 0', false), + array('UPDATE phpbb_forums + SET left_id = 28, + right_id = 28 + WHERE left_id > 12', false), + array('UPDATE phpbb_forums + SET left_id = left_id * 2, + right_id = right_id * 2', false), + array('UPDATE phpbb_forums + SET left_id = left_id * 2, + right_id = right_id * 2 + WHERE left_id > 12', false), + array('UPDATE phpbb_forums + SET left_id = left_id - 4, + right_id = right_id * 4 + WHERE left_id > 4', false), + array('UPDATE phpbb_forums + SET left_id = 0, + right_id = 0 + WHERE left_id > 12', true), + ); + } + + /** + * @dataProvider recalculate_nested_set_data + */ + public function test_recalculate_nested_set($breaking_query, $reset_ids) + { + $result = $this->db->sql_query($breaking_query); + + $this->assertEquals(23, $this->set->recalculate_nested_set(1, 0, $reset_ids)); + + $result = $this->db->sql_query('SELECT forum_id, parent_id, left_id, right_id, forum_parents + FROM phpbb_forums + ORDER BY left_id, forum_id ASC'); + $this->assertEquals($this->fixed_set, $this->db->sql_fetchrowset($result)); + } +} diff --git a/tests/nestedset/set_forum_test.php b/tests/nestedset/set_forum_test.php new file mode 100644 index 0000000000..ab4da1ff1e --- /dev/null +++ b/tests/nestedset/set_forum_test.php @@ -0,0 +1,116 @@ + 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => ''), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => ''), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => ''), + + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12, 'forum_parents' => ''), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 8, 'right_id' => 11, 'forum_parents' => ''), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 9, 'right_id' => 10, 'forum_parents' => ''), + + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => ''), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => ''), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => ''), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => ''), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => ''), + )), + ); + } + + /** + * @dataProvider forum_constructor_data + */ + public function test_forum_constructor($expected) + { + $result = $this->db->sql_query('SELECT forum_id, parent_id, left_id, right_id, forum_parents + FROM phpbb_forums + ORDER BY left_id, forum_id ASC'); + $this->assertEquals($expected, $this->db->sql_fetchrowset($result)); + } + + public function get_sql_where_data() + { + return array( + array('SELECT forum_id, parent_id, left_id, right_id, forum_parents + FROM phpbb_forums + %s + ORDER BY left_id, forum_id ASC', + 'WHERE', '', array( + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => ''), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => ''), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => ''), + + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12, 'forum_parents' => ''), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 8, 'right_id' => 11, 'forum_parents' => ''), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 9, 'right_id' => 10, 'forum_parents' => ''), + + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => ''), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => ''), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => ''), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => ''), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => ''), + )), + array('SELECT f.forum_id, f.parent_id, f.left_id, f.right_id, f.forum_parents + FROM phpbb_forums f + %s + ORDER BY f.left_id, f.forum_id ASC', + 'WHERE', 'f.', array( + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => ''), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => ''), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => ''), + + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12, 'forum_parents' => ''), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 8, 'right_id' => 11, 'forum_parents' => ''), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 9, 'right_id' => 10, 'forum_parents' => ''), + + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => ''), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => ''), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => ''), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => ''), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => ''), + )), + array('SELECT forum_id, parent_id, left_id, right_id, forum_parents + FROM phpbb_forums + WHERE forum_id < 4 %s + ORDER BY left_id, forum_id ASC', + 'AND', '', array( + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => ''), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => ''), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => ''), + )), + array('SELECT f.forum_id, f.parent_id, f.left_id, f.right_id, f.forum_parents + FROM phpbb_forums f + WHERE f.forum_id < 4 %s + ORDER BY f.left_id, f.forum_id ASC', + 'AND', 'f.', array( + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => ''), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => ''), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => ''), + )), + ); + } + + /** + * @dataProvider get_sql_where_data + */ + public function test_get_sql_where($sql_query, $operator, $column_prefix, $expected) + { + $result = $this->db->sql_query(sprintf($sql_query, $this->set->get_sql_where($operator, $column_prefix))); + $this->assertEquals($expected, $this->db->sql_fetchrowset($result)); + } +} From 869e00a23b0400b9ad81c1130227cc4c29d6a38d Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Wed, 17 Apr 2013 17:45:49 +0200 Subject: [PATCH 133/281] [ticket/11362] Move phpbb_clean_path into a simple filesystem service PHPBB3-11362 --- phpBB/config/services.yml | 4 ++ phpBB/includes/filesystem.php | 52 +++++++++++++++++++ phpBB/includes/functions.php | 30 ----------- .../clean_path_test.php | 20 ++++--- 4 files changed, 68 insertions(+), 38 deletions(-) create mode 100644 phpBB/includes/filesystem.php rename tests/{functions => filesystem}/clean_path_test.php (71%) diff --git a/phpBB/config/services.yml b/phpBB/config/services.yml index b9c71844dc..5febe76c49 100644 --- a/phpBB/config/services.yml +++ b/phpBB/config/services.yml @@ -142,9 +142,13 @@ services: - @ext.manager - %core.root_path% - @cache.driver + - @filesystem - .%core.php_ext% - _ext_finder + filesystem: + class: phpbb_filesystem + groupposition.legend: class: phpbb_groupposition_legend arguments: diff --git a/phpBB/includes/filesystem.php b/phpBB/includes/filesystem.php new file mode 100644 index 0000000000..27cab48fb0 --- /dev/null +++ b/phpBB/includes/filesystem.php @@ -0,0 +1,52 @@ +filesystem = new phpbb_filesystem(); + } + + public function clean_path_data() { return array( array('foo', 'foo'), @@ -33,12 +39,10 @@ class phpbb_clean_path_test extends phpbb_test_case } /** - * @dataProvider clean_path_test_data + * @dataProvider clean_path_data */ public function test_clean_path($input, $expected) { - $output = phpbb_clean_path($input); - - $this->assertEquals($expected, $output); + $this->assertEquals($expected, $this->filesystem->clean_path($input)); } } From 158bce02095b1fbff19955cbad19be3d1b1a3f80 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Wed, 17 Apr 2013 17:50:44 +0200 Subject: [PATCH 134/281] [ticket/11362] Use new filesystem class in finder PHPBB3-11362 --- phpBB/includes/extension/finder.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/phpBB/includes/extension/finder.php b/phpBB/includes/extension/finder.php index d9aacc38ff..02a9ebb8c3 100644 --- a/phpBB/includes/extension/finder.php +++ b/phpBB/includes/extension/finder.php @@ -23,6 +23,7 @@ if (!defined('IN_PHPBB')) class phpbb_extension_finder { protected $extension_manager; + protected $filesystem; protected $phpbb_root_path; protected $cache; protected $php_ext; @@ -54,15 +55,17 @@ class phpbb_extension_finder * @param phpbb_extension_manager $extension_manager An extension manager * instance that provides the finder with a list of active * extensions and their locations + * @param phpbb_filesystem $filesystem Filesystem instance * @param string $phpbb_root_path Path to the phpbb root directory * @param phpbb_cache_driver_interface $cache A cache instance or null * @param string $php_ext php file extension * @param string $cache_name The name of the cache variable, defaults to * _ext_finder */ - public function __construct(phpbb_extension_manager $extension_manager, $phpbb_root_path = '', phpbb_cache_driver_interface $cache = null, $php_ext = '.php', $cache_name = '_ext_finder') + public function __construct(phpbb_extension_manager $extension_manager, phpbb_filesystem $filesystem, $phpbb_root_path = '', phpbb_cache_driver_interface $cache = null, $php_ext = '.php', $cache_name = '_ext_finder') { $this->extension_manager = $extension_manager; + $this->filesystem = $filesystem; $this->phpbb_root_path = $phpbb_root_path; $this->cache = $cache; $this->php_ext = $php_ext; @@ -227,7 +230,7 @@ class phpbb_extension_finder */ protected function sanitise_directory($directory) { - $directory = phpbb_clean_path($directory); + $directory = $this->filesystem->clean_path($directory); $dir_len = strlen($directory); if ($dir_len > 1 && $directory[$dir_len - 1] === '/') From d7fb934a2f6fbce86563d692b9689eb5c76e31dd Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Wed, 17 Apr 2013 17:52:00 +0200 Subject: [PATCH 135/281] [ticket/11362] Replace other calls to phpbb_clean_path Need to instantiate the object manually here, as the container is not yet set up. PHPBB3-11362 --- phpBB/common.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/phpBB/common.php b/phpBB/common.php index c33e2cbb1f..6dd65739fc 100644 --- a/phpBB/common.php +++ b/phpBB/common.php @@ -44,8 +44,11 @@ if (!defined('PHPBB_INSTALLED')) // Replace any number of consecutive backslashes and/or slashes with a single slash // (could happen on some proxy setups and/or Windows servers) $script_path = preg_replace('#[\\\\/]{2,}#', '/', $script_path); + // Eliminate . and .. from the path - $script_path = phpbb_clean_path($script_path); + require($phpbb_root_path . 'includes/filesystem.' . $phpEx); + $phpbb_filesystem = new phpbb_filesystem(); + $script_path = $phpbb_filesystem->clean_path($script_path); $url = (($secure) ? 'https://' : 'http://') . $server_name; From 423b310e2acbbc72814a4278a4cccf2900114f85 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Wed, 17 Apr 2013 18:43:19 +0200 Subject: [PATCH 136/281] [ticket/11362] Extension manager depends on filesystem PHPBB3-11362 --- phpBB/config/services.yml | 1 + phpBB/includes/extension/manager.php | 6 ++++-- tests/dbal/migrator_test.php | 1 + tests/extension/finder_test.php | 3 ++- tests/extension/manager_test.php | 1 + tests/extension/metadata_manager_test.php | 1 + tests/mock/extension_manager.php | 1 + tests/test_framework/phpbb_functional_test_case.php | 1 + 8 files changed, 12 insertions(+), 3 deletions(-) diff --git a/phpBB/config/services.yml b/phpBB/config/services.yml index 5febe76c49..fb3e7aa964 100644 --- a/phpBB/config/services.yml +++ b/phpBB/config/services.yml @@ -131,6 +131,7 @@ services: - @dbal.conn - @config - @migrator + - @filesystem - %tables.ext% - %core.root_path% - .%core.php_ext% diff --git a/phpBB/includes/extension/manager.php b/phpBB/includes/extension/manager.php index 44a30c6280..de9a3937c3 100644 --- a/phpBB/includes/extension/manager.php +++ b/phpBB/includes/extension/manager.php @@ -44,13 +44,14 @@ class phpbb_extension_manager * @param phpbb_db_driver $db A database connection * @param phpbb_config $config phpbb_config * @param phpbb_db_migrator $migrator + * @param phpbb_filesystem $filesystem * @param string $extension_table The name of the table holding extensions * @param string $phpbb_root_path Path to the phpbb includes directory. * @param string $php_ext php file extension * @param phpbb_cache_driver_interface $cache A cache instance or null * @param string $cache_name The name of the cache variable, defaults to _ext */ - public function __construct(ContainerInterface $container, phpbb_db_driver $db, phpbb_config $config, phpbb_db_migrator $migrator, $extension_table, $phpbb_root_path, $php_ext = '.php', phpbb_cache_driver_interface $cache = null, $cache_name = '_ext') + public function __construct(ContainerInterface $container, phpbb_db_driver $db, phpbb_config $config, phpbb_db_migrator $migrator, phpbb_filesystem $filesystem, $extension_table, $phpbb_root_path, $php_ext = '.php', phpbb_cache_driver_interface $cache = null, $cache_name = '_ext') { $this->container = $container; $this->phpbb_root_path = $phpbb_root_path; @@ -58,6 +59,7 @@ class phpbb_extension_manager $this->config = $config; $this->migrator = $migrator; $this->cache = $cache; + $this->filesystem = $filesystem; $this->php_ext = $php_ext; $this->extension_table = $extension_table; $this->cache_name = $cache_name; @@ -510,7 +512,7 @@ class phpbb_extension_manager */ public function get_finder() { - return new phpbb_extension_finder($this, $this->phpbb_root_path, $this->cache, $this->php_ext, $this->cache_name . '_finder'); + return new phpbb_extension_finder($this, $this->filesystem, $this->phpbb_root_path, $this->cache, $this->php_ext, $this->cache_name . '_finder'); } /** diff --git a/tests/dbal/migrator_test.php b/tests/dbal/migrator_test.php index 89669b85ec..745d260b38 100644 --- a/tests/dbal/migrator_test.php +++ b/tests/dbal/migrator_test.php @@ -60,6 +60,7 @@ class phpbb_dbal_migrator_test extends phpbb_database_test_case $this->db, $this->config, $this->migrator, + new phpbb_filesystem(), 'phpbb_ext', dirname(__FILE__) . '/../../phpBB/', '.php', diff --git a/tests/extension/finder_test.php b/tests/extension/finder_test.php index 3781591b19..73c07ef79a 100644 --- a/tests/extension/finder_test.php +++ b/tests/extension/finder_test.php @@ -164,7 +164,7 @@ class phpbb_extension_finder_test extends phpbb_test_case public function test_get_classes_create_cache() { $cache = new phpbb_mock_cache; - $finder = new phpbb_extension_finder($this->extension_manager, dirname(__FILE__) . '/', $cache, '.php', '_custom_cache_name'); + $finder = new phpbb_extension_finder($this->extension_manager, new phpbb_filesystem(), dirname(__FILE__) . '/', $cache, '.php', '_custom_cache_name'); $files = $finder->suffix('_class.php')->get_files(); $expected_files = array( @@ -204,6 +204,7 @@ class phpbb_extension_finder_test extends phpbb_test_case $finder = new phpbb_extension_finder( $this->extension_manager, + new phpbb_filesystem(), dirname(__FILE__) . '/', new phpbb_mock_cache(array( '_ext_finder' => array( diff --git a/tests/extension/manager_test.php b/tests/extension/manager_test.php index 1f311116f4..d6bcb97586 100644 --- a/tests/extension/manager_test.php +++ b/tests/extension/manager_test.php @@ -112,6 +112,7 @@ class phpbb_extension_manager_test extends phpbb_database_test_case $db, $config, $migrator, + new phpbb_filesystem(), 'phpbb_ext', dirname(__FILE__) . '/', '.' . $php_ext, diff --git a/tests/extension/metadata_manager_test.php b/tests/extension/metadata_manager_test.php index 081a32e277..df7817b479 100644 --- a/tests/extension/metadata_manager_test.php +++ b/tests/extension/metadata_manager_test.php @@ -64,6 +64,7 @@ class metadata_manager_test extends phpbb_database_test_case $this->db, $this->config, $this->migrator, + new phpbb_filesystem(), 'phpbb_ext', $this->phpbb_root_path, $this->phpEx, diff --git a/tests/mock/extension_manager.php b/tests/mock/extension_manager.php index fdda4cbadc..954f2bf1c4 100644 --- a/tests/mock/extension_manager.php +++ b/tests/mock/extension_manager.php @@ -14,5 +14,6 @@ class phpbb_mock_extension_manager extends phpbb_extension_manager $this->phpbb_root_path = $phpbb_root_path; $this->php_ext = '.php'; $this->extensions = $extensions; + $this->filesystem = new phpbb_filesystem(); } } diff --git a/tests/test_framework/phpbb_functional_test_case.php b/tests/test_framework/phpbb_functional_test_case.php index 887dfea3b5..891fe237b3 100644 --- a/tests/test_framework/phpbb_functional_test_case.php +++ b/tests/test_framework/phpbb_functional_test_case.php @@ -153,6 +153,7 @@ class phpbb_functional_test_case extends phpbb_test_case $db, $config, $migrator, + new phpbb_filesystem(), self::$config['table_prefix'] . 'ext', dirname(__FILE__) . '/', '.' . $php_ext, From ffe9f2a93e7bb91378e462b44a786252bddbd0be Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Wed, 17 Apr 2013 20:25:30 +0200 Subject: [PATCH 137/281] [ticket/11362] Fix service description of finder PHPBB3-11362 --- phpBB/config/services.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/config/services.yml b/phpBB/config/services.yml index fb3e7aa964..19dfb3e23b 100644 --- a/phpBB/config/services.yml +++ b/phpBB/config/services.yml @@ -141,9 +141,9 @@ services: class: phpbb_extension_finder arguments: - @ext.manager + - @filesystem - %core.root_path% - @cache.driver - - @filesystem - .%core.php_ext% - _ext_finder From e2875a7e170770a92fa02db3a75f1552cc33005a Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Wed, 17 Apr 2013 21:23:47 +0200 Subject: [PATCH 138/281] [ticket/10966] Introduce MySQL base class PHPBB3-10966 --- phpBB/includes/db/driver/mysql.php | 124 +------------------- phpBB/includes/db/driver/mysql_base.php | 145 ++++++++++++++++++++++++ phpBB/includes/db/driver/mysqli.php | 125 +------------------- 3 files changed, 148 insertions(+), 246 deletions(-) create mode 100644 phpBB/includes/db/driver/mysql_base.php diff --git a/phpBB/includes/db/driver/mysql.php b/phpBB/includes/db/driver/mysql.php index 9de7283a42..f3744ac09d 100644 --- a/phpBB/includes/db/driver/mysql.php +++ b/phpBB/includes/db/driver/mysql.php @@ -24,7 +24,7 @@ if (!defined('IN_PHPBB')) * MySQL 5.0+ * @package dbal */ -class phpbb_db_driver_mysql extends phpbb_db_driver +class phpbb_db_driver_mysql extends phpbb_db_driver_mysql_base { var $multi_insert = true; var $connect_error = ''; @@ -135,14 +135,6 @@ class phpbb_db_driver_mysql extends phpbb_db_driver return ($raw) ? $this->sql_server_version : 'MySQL ' . $this->sql_server_version; } - /** - * {@inheritDoc} - */ - public function sql_concatenate($expr1, $expr2) - { - return 'CONCAT(' . $expr1 . ', ' . $expr2 . ')'; - } - /** * SQL Transaction * @access private @@ -226,25 +218,6 @@ class phpbb_db_driver_mysql extends phpbb_db_driver return $this->query_result; } - /** - * Build LIMIT query - */ - function _sql_query_limit($query, $total, $offset = 0, $cache_ttl = 0) - { - $this->query_result = false; - - // if $total is set to 0 we do not want to limit the number of rows - if ($total == 0) - { - // Having a value of -1 was always a bug - $total = '18446744073709551615'; - } - - $query .= "\n LIMIT " . ((!empty($offset)) ? $offset . ', ' . $total : $total); - - return $this->sql_query($query, $cache_ttl); - } - /** * Return number of affected rows */ @@ -341,101 +314,6 @@ class phpbb_db_driver_mysql extends phpbb_db_driver return @mysql_real_escape_string($msg, $this->db_connect_id); } - /** - * Gets the estimated number of rows in a specified table. - * - * @param string $table_name Table name - * - * @return string Number of rows in $table_name. - * Prefixed with ~ if estimated (otherwise exact). - * - * @access public - */ - function get_estimated_row_count($table_name) - { - $table_status = $this->get_table_status($table_name); - - if (isset($table_status['Engine'])) - { - if ($table_status['Engine'] === 'MyISAM') - { - return $table_status['Rows']; - } - else if ($table_status['Engine'] === 'InnoDB' && $table_status['Rows'] > 100000) - { - return '~' . $table_status['Rows']; - } - } - - return parent::get_row_count($table_name); - } - - /** - * Gets the exact number of rows in a specified table. - * - * @param string $table_name Table name - * - * @return string Exact number of rows in $table_name. - * - * @access public - */ - function get_row_count($table_name) - { - $table_status = $this->get_table_status($table_name); - - if (isset($table_status['Engine']) && $table_status['Engine'] === 'MyISAM') - { - return $table_status['Rows']; - } - - return parent::get_row_count($table_name); - } - - /** - * Gets some information about the specified table. - * - * @param string $table_name Table name - * - * @return array - * - * @access protected - */ - function get_table_status($table_name) - { - $sql = "SHOW TABLE STATUS - LIKE '" . $this->sql_escape($table_name) . "'"; - $result = $this->sql_query($sql); - $table_status = $this->sql_fetchrow($result); - $this->sql_freeresult($result); - - return $table_status; - } - - /** - * Build LIKE expression - * @access private - */ - function _sql_like_expression($expression) - { - return $expression; - } - - /** - * Build db-specific query data - * @access private - */ - function _sql_custom_build($stage, $data) - { - switch ($stage) - { - case 'FROM': - $data = '(' . $data . ')'; - break; - } - - return $data; - } - /** * return sql error array * @access private diff --git a/phpBB/includes/db/driver/mysql_base.php b/phpBB/includes/db/driver/mysql_base.php new file mode 100644 index 0000000000..ba44ea61aa --- /dev/null +++ b/phpBB/includes/db/driver/mysql_base.php @@ -0,0 +1,145 @@ +query_result = false; + + // if $total is set to 0 we do not want to limit the number of rows + if ($total == 0) + { + // MySQL 4.1+ no longer supports -1 in limit queries + $total = '18446744073709551615'; + } + + $query .= "\n LIMIT " . ((!empty($offset)) ? $offset . ', ' . $total : $total); + + return $this->sql_query($query, $cache_ttl); + } + + /** + * Gets the estimated number of rows in a specified table. + * + * @param string $table_name Table name + * + * @return string Number of rows in $table_name. + * Prefixed with ~ if estimated (otherwise exact). + * + * @access public + */ + function get_estimated_row_count($table_name) + { + $table_status = $this->get_table_status($table_name); + + if (isset($table_status['Engine'])) + { + if ($table_status['Engine'] === 'MyISAM') + { + return $table_status['Rows']; + } + else if ($table_status['Engine'] === 'InnoDB' && $table_status['Rows'] > 100000) + { + return '~' . $table_status['Rows']; + } + } + + return parent::get_row_count($table_name); + } + + /** + * Gets the exact number of rows in a specified table. + * + * @param string $table_name Table name + * + * @return string Exact number of rows in $table_name. + * + * @access public + */ + function get_row_count($table_name) + { + $table_status = $this->get_table_status($table_name); + + if (isset($table_status['Engine']) && $table_status['Engine'] === 'MyISAM') + { + return $table_status['Rows']; + } + + return parent::get_row_count($table_name); + } + + /** + * Gets some information about the specified table. + * + * @param string $table_name Table name + * + * @return array + * + * @access protected + */ + function get_table_status($table_name) + { + $sql = "SHOW TABLE STATUS + LIKE '" . $this->sql_escape($table_name) . "'"; + $result = $this->sql_query($sql); + $table_status = $this->sql_fetchrow($result); + $this->sql_freeresult($result); + + return $table_status; + } + + /** + * Build LIKE expression + * @access private + */ + function _sql_like_expression($expression) + { + return $expression; + } + + /** + * Build db-specific query data + * @access private + */ + function _sql_custom_build($stage, $data) + { + switch ($stage) + { + case 'FROM': + $data = '(' . $data . ')'; + break; + } + + return $data; + } +} diff --git a/phpBB/includes/db/driver/mysqli.php b/phpBB/includes/db/driver/mysqli.php index 7448bf1670..0f7a73ee6e 100644 --- a/phpBB/includes/db/driver/mysqli.php +++ b/phpBB/includes/db/driver/mysqli.php @@ -21,7 +21,7 @@ if (!defined('IN_PHPBB')) * MySQL 4.1+ or MySQL 5.0+ * @package dbal */ -class phpbb_db_driver_mysqli extends phpbb_db_driver +class phpbb_db_driver_mysqli extends phpbb_db_driver_mysql_base { var $multi_insert = true; var $connect_error = ''; @@ -103,6 +103,7 @@ class phpbb_db_driver_mysqli extends phpbb_db_driver /** * Version information about used database + * @param bool $raw if true, only return the fetched sql_server_version * @param bool $use_cache If true, it is safe to retrieve the value from the cache * @return string sql server version */ @@ -127,14 +128,6 @@ class phpbb_db_driver_mysqli extends phpbb_db_driver return ($raw) ? $this->sql_server_version : 'MySQL(i) ' . $this->sql_server_version; } - /** - * {@inheritDoc} - */ - public function sql_concatenate($expr1, $expr2) - { - return 'CONCAT(' . $expr1 . ', ' . $expr2 . ')'; - } - /** * SQL Transaction * @access private @@ -217,25 +210,6 @@ class phpbb_db_driver_mysqli extends phpbb_db_driver return $this->query_result; } - /** - * Build LIMIT query - */ - function _sql_query_limit($query, $total, $offset = 0, $cache_ttl = 0) - { - $this->query_result = false; - - // if $total is set to 0 we do not want to limit the number of rows - if ($total == 0) - { - // MySQL 4.1+ no longer supports -1 in limit queries - $total = '18446744073709551615'; - } - - $query .= "\n LIMIT " . ((!empty($offset)) ? $offset . ', ' . $total : $total); - - return $this->sql_query($query, $cache_ttl); - } - /** * Return number of affected rows */ @@ -327,101 +301,6 @@ class phpbb_db_driver_mysqli extends phpbb_db_driver return @mysqli_real_escape_string($this->db_connect_id, $msg); } - /** - * Gets the estimated number of rows in a specified table. - * - * @param string $table_name Table name - * - * @return string Number of rows in $table_name. - * Prefixed with ~ if estimated (otherwise exact). - * - * @access public - */ - function get_estimated_row_count($table_name) - { - $table_status = $this->get_table_status($table_name); - - if (isset($table_status['Engine'])) - { - if ($table_status['Engine'] === 'MyISAM') - { - return $table_status['Rows']; - } - else if ($table_status['Engine'] === 'InnoDB' && $table_status['Rows'] > 100000) - { - return '~' . $table_status['Rows']; - } - } - - return parent::get_row_count($table_name); - } - - /** - * Gets the exact number of rows in a specified table. - * - * @param string $table_name Table name - * - * @return string Exact number of rows in $table_name. - * - * @access public - */ - function get_row_count($table_name) - { - $table_status = $this->get_table_status($table_name); - - if (isset($table_status['Engine']) && $table_status['Engine'] === 'MyISAM') - { - return $table_status['Rows']; - } - - return parent::get_row_count($table_name); - } - - /** - * Gets some information about the specified table. - * - * @param string $table_name Table name - * - * @return array - * - * @access protected - */ - function get_table_status($table_name) - { - $sql = "SHOW TABLE STATUS - LIKE '" . $this->sql_escape($table_name) . "'"; - $result = $this->sql_query($sql); - $table_status = $this->sql_fetchrow($result); - $this->sql_freeresult($result); - - return $table_status; - } - - /** - * Build LIKE expression - * @access private - */ - function _sql_like_expression($expression) - { - return $expression; - } - - /** - * Build db-specific query data - * @access private - */ - function _sql_custom_build($stage, $data) - { - switch ($stage) - { - case 'FROM': - $data = '(' . $data . ')'; - break; - } - - return $data; - } - /** * return sql error array * @access private From f831e3c66efe79841a0bcc01cf0b2d37e6d4e65c Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Wed, 17 Apr 2013 22:52:17 +0200 Subject: [PATCH 139/281] [ticket/11495] Use unique properties for the column names PHPBB3-11495 --- phpBB/includes/nestedset/base.php | 186 ++++++++++++++--------------- phpBB/includes/nestedset/forum.php | 11 +- 2 files changed, 95 insertions(+), 102 deletions(-) diff --git a/phpBB/includes/nestedset/base.php b/phpBB/includes/nestedset/base.php index 7f4691b7e0..4dfe3e6203 100644 --- a/phpBB/includes/nestedset/base.php +++ b/phpBB/includes/nestedset/base.php @@ -28,15 +28,13 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface /** * Column names in the table - * @var array + * @var String */ - protected $table_columns = array( - 'item_id' => 'item_id', - 'left_id' => 'left_id', - 'right_id' => 'right_id', - 'parent_id' => 'parent_id', - 'item_parents' => 'item_parents', - ); + protected $columns_item_id = 'item_id'; + protected $columns_left_id = 'left_id'; + protected $columns_right_id = 'right_id'; + protected $columns_parent_id = 'parent_id'; + protected $columns_item_parents = 'item_parents'; /** * Additional SQL restrictions @@ -72,18 +70,18 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface public function insert(array $additional_data) { $item_data = array_merge($additional_data, array( - $this->table_columns['parent_id'] => 0, - $this->table_columns['left_id'] => 0, - $this->table_columns['right_id'] => 0, - $this->table_columns['item_parents'] => '', + $this->column_parent_id => 0, + $this->column_left_id => 0, + $this->column_right_id => 0, + $this->column_item_parents => '', )); - unset($item_data[$this->table_columns['item_id']]); + unset($item_data[$this->column_item_id]); $sql = 'INSERT INTO ' . $this->table_name . ' ' . $this->db->sql_build_array('INSERT', $item_data); $this->db->sql_query($sql); - $item_data[$this->table_columns['item_id']] = (int) $this->db->sql_nextid(); + $item_data[$this->column_item_id] = (int) $this->db->sql_nextid(); $item = new $this->item_class($item_data); @@ -95,23 +93,23 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface */ public function add(phpbb_nestedset_item_interface $item) { - $sql = 'SELECT MAX(' . $this->table_columns['right_id'] . ') AS ' . $this->table_columns['right_id'] . ' + $sql = 'SELECT MAX(' . $this->column_right_id . ') AS ' . $this->column_right_id . ' FROM ' . $this->table_name . ' ' . $this->get_sql_where('WHERE'); $result = $this->db->sql_query($sql); - $current_max_right_id = (int) $this->db->sql_fetchfield($this->table_columns['right_id']); + $current_max_right_id = (int) $this->db->sql_fetchfield($this->column_right_id); $this->db->sql_freeresult($result); $update_item_data = array( - $this->table_columns['parent_id'] => 0, - $this->table_columns['left_id'] => $current_max_right_id + 1, - $this->table_columns['right_id'] => $current_max_right_id + 2, - $this->table_columns['item_parents'] => '', + $this->column_parent_id => 0, + $this->column_left_id => $current_max_right_id + 1, + $this->column_right_id => $current_max_right_id + 2, + $this->column_item_parents => '', ); $sql = 'UPDATE ' . $this->table_name . ' SET ' . $this->db->sql_build_array('UPDATE', $update_item_data) . ' - WHERE ' . $this->table_columns['item_id'] . ' = ' . $item->get_item_id(); + WHERE ' . $this->column_item_id . ' = ' . $item->get_item_id(); $this->db->sql_query($sql); return $update_item_data; @@ -144,7 +142,7 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface $removed_items = $this->remove($item); $sql = 'DELETE FROM ' . $this->table_name . ' - WHERE ' . $this->db->sql_in_set($this->table_columns['item_id'], $removed_items) . ' + WHERE ' . $this->db->sql_in_set($this->column_item_id, $removed_items) . ' ' . $this->get_sql_where('AND'); $this->db->sql_query($sql); @@ -172,17 +170,17 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface */ $sql = 'SELECT ' . implode(', ', $this->table_columns) . ' FROM ' . $this->table_name . ' - WHERE ' . $this->table_columns['parent_id'] . ' = ' . $item->get_parent_id() . ' + WHERE ' . $this->column_parent_id . ' = ' . $item->get_parent_id() . ' ' . $this->get_sql_where() . ' AND '; if ($action == 'move_up') { - $sql .= $this->table_columns['right_id'] . ' < ' . $item->get_right_id() . ' ORDER BY ' . $this->table_columns['right_id'] . ' DESC'; + $sql .= $this->column_right_id . ' < ' . $item->get_right_id() . ' ORDER BY ' . $this->column_right_id . ' DESC'; } else { - $sql .= $this->table_columns['left_id'] . ' > ' . $item->get_left_id() . ' ORDER BY ' . $this->table_columns['left_id'] . ' ASC'; + $sql .= $this->column_left_id . ' > ' . $item->get_left_id() . ' ORDER BY ' . $this->column_left_id . ' ASC'; } $result = $this->db->sql_query_limit($sql, $delta); @@ -232,18 +230,18 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface // Now do the dirty job $sql = 'UPDATE ' . $this->table_name . ' - SET ' . $this->table_columns['left_id'] . ' = ' . $this->table_columns['left_id'] . ' + CASE - WHEN ' . $this->table_columns['left_id'] . " BETWEEN {$move_up_left} AND {$move_up_right} THEN -{$diff_up} + SET ' . $this->column_left_id . ' = ' . $this->column_left_id . ' + CASE + WHEN ' . $this->column_left_id . " BETWEEN {$move_up_left} AND {$move_up_right} THEN -{$diff_up} ELSE {$diff_down} END, - " . $this->table_columns['right_id'] . ' = ' . $this->table_columns['right_id'] . ' + CASE - WHEN ' . $this->table_columns['right_id'] . " BETWEEN {$move_up_left} AND {$move_up_right} THEN -{$diff_up} + " . $this->column_right_id . ' = ' . $this->column_right_id . ' + CASE + WHEN ' . $this->column_right_id . " BETWEEN {$move_up_left} AND {$move_up_right} THEN -{$diff_up} ELSE {$diff_down} END, - " . $this->table_columns['item_parents'] . " = '' + " . $this->column_item_parents . " = '' WHERE - " . $this->table_columns['left_id'] . " BETWEEN {$left_id} AND {$right_id} - AND " . $this->table_columns['right_id'] . " BETWEEN {$left_id} AND {$right_id} + " . $this->column_left_id . " BETWEEN {$left_id} AND {$right_id} + AND " . $this->column_right_id . " BETWEEN {$left_id} AND {$right_id} " . $this->get_sql_where(); $this->db->sql_query($sql); @@ -284,7 +282,7 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface } $diff = sizeof($move_items) * 2; - $sql_exclude_moved_items = $this->db->sql_in_set($this->table_columns['item_id'], $move_items, true); + $sql_exclude_moved_items = $this->db->sql_in_set($this->column_item_id, $move_items, true); $this->db->sql_transaction('begin'); @@ -295,7 +293,7 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface // Retrieve new-parent again, it may have been changed... $sql = 'SELECT * FROM ' . $this->table_name . ' - WHERE ' . $this->table_columns['item_id'] . ' = ' . $new_parent->get_item_id(); + WHERE ' . $this->column_item_id . ' = ' . $new_parent->get_item_id(); $result = $this->db->sql_query($sql); $parent_data = $this->db->sql_fetchrow($result); $this->db->sql_freeresult($result); @@ -321,7 +319,7 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface } else { - $sql = 'SELECT MAX(' . $this->table_columns['right_id'] . ') AS ' . $this->table_columns['right_id'] . ' + $sql = 'SELECT MAX(' . $this->column_right_id . ') AS ' . $this->column_right_id . ' FROM ' . $this->table_name . ' WHERE ' . $sql_exclude_moved_items . ' ' . $this->get_sql_where('AND'); @@ -329,15 +327,15 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface $row = $this->db->sql_fetchrow($result); $this->db->sql_freeresult($result); - $diff = ' + ' . ($row[$this->table_columns['right_id']] - $current_parent->get_left_id()); + $diff = ' + ' . ($row[$this->column_right_id] - $current_parent->get_left_id()); } $sql = 'UPDATE ' . $this->table_name . ' - SET ' . $this->table_columns['left_id'] . ' = ' . $this->table_columns['left_id'] . $diff . ', - ' . $this->table_columns['right_id'] . ' = ' . $this->table_columns['right_id'] . $diff . ', - ' . $this->table_columns['parent_id'] . ' = ' . $this->db->sql_case($this->table_columns['parent_id'] . ' = ' . $current_parent->get_item_id(), $new_parent->get_item_id(), $this->table_columns['parent_id']) . ', - ' . $this->table_columns['item_parents'] . " = '' - WHERE " . $this->db->sql_in_set($this->table_columns['item_id'], $move_items) . ' + SET ' . $this->column_left_id . ' = ' . $this->column_left_id . $diff . ', + ' . $this->column_right_id . ' = ' . $this->column_right_id . $diff . ', + ' . $this->column_parent_id . ' = ' . $this->db->sql_case($this->column_parent_id . ' = ' . $current_parent->get_item_id(), $new_parent->get_item_id(), $this->column_parent_id) . ', + ' . $this->column_item_parents . " = '' + WHERE " . $this->db->sql_in_set($this->column_item_id, $move_items) . ' ' . $this->get_sql_where('AND'); $this->db->sql_query($sql); @@ -359,7 +357,7 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface } $diff = sizeof($move_items) * 2; - $sql_exclude_moved_items = $this->db->sql_in_set($this->table_columns['item_id'], $move_items, true); + $sql_exclude_moved_items = $this->db->sql_in_set($this->column_item_id, $move_items, true); $this->db->sql_transaction('begin'); @@ -370,7 +368,7 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface // Retrieve new-parent again, it may have been changed... $sql = 'SELECT * FROM ' . $this->table_name . ' - WHERE ' . $this->table_columns['item_id'] . ' = ' . $new_parent->get_item_id(); + WHERE ' . $this->column_item_id . ' = ' . $new_parent->get_item_id(); $result = $this->db->sql_query($sql); $parent_data = $this->db->sql_fetchrow($result); $this->db->sql_freeresult($result); @@ -396,7 +394,7 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface } else { - $sql = 'SELECT MAX(' . $this->table_columns['right_id'] . ') AS ' . $this->table_columns['right_id'] . ' + $sql = 'SELECT MAX(' . $this->column_right_id . ') AS ' . $this->column_right_id . ' FROM ' . $this->table_name . ' WHERE ' . $sql_exclude_moved_items . ' ' . $this->get_sql_where('AND'); @@ -404,15 +402,15 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface $row = $this->db->sql_fetchrow($result); $this->db->sql_freeresult($result); - $diff = ' + ' . ($row[$this->table_columns['right_id']] - $item->get_left_id() + 1); + $diff = ' + ' . ($row[$this->column_right_id] - $item->get_left_id() + 1); } $sql = 'UPDATE ' . $this->table_name . ' - SET ' . $this->table_columns['left_id'] . ' = ' . $this->table_columns['left_id'] . $diff . ', - ' . $this->table_columns['right_id'] . ' = ' . $this->table_columns['right_id'] . $diff . ', - ' . $this->table_columns['parent_id'] . ' = ' . $this->db->sql_case($this->table_columns['item_id'] . ' = ' . $item->get_item_id(), $new_parent->get_item_id(), $this->table_columns['parent_id']) . ', - ' . $this->table_columns['item_parents'] . " = '' - WHERE " . $this->db->sql_in_set($this->table_columns['item_id'], $move_items) . ' + SET ' . $this->column_left_id . ' = ' . $this->column_left_id . $diff . ', + ' . $this->column_right_id . ' = ' . $this->column_right_id . $diff . ', + ' . $this->column_parent_id . ' = ' . $this->db->sql_case($this->column_item_id . ' = ' . $item->get_item_id(), $new_parent->get_item_id(), $this->column_parent_id) . ', + ' . $this->column_item_parents . " = '' + WHERE " . $this->db->sql_in_set($this->column_item_id, $move_items) . ' ' . $this->get_sql_where('AND'); $this->db->sql_query($sql); @@ -429,16 +427,16 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface switch ($type) { case 'parents': - $condition = 'i1.' . $this->table_columns['left_id'] . ' BETWEEN i2.' . $this->table_columns['left_id'] . ' AND i2.' . $this->table_columns['right_id'] . ''; + $condition = 'i1.' . $this->column_left_id . ' BETWEEN i2.' . $this->column_left_id . ' AND i2.' . $this->column_right_id . ''; break; case 'children': - $condition = 'i2.' . $this->table_columns['left_id'] . ' BETWEEN i1.' . $this->table_columns['left_id'] . ' AND i1.' . $this->table_columns['right_id'] . ''; + $condition = 'i2.' . $this->column_left_id . ' BETWEEN i1.' . $this->column_left_id . ' AND i1.' . $this->column_right_id . ''; break; default: - $condition = 'i2.' . $this->table_columns['left_id'] . ' BETWEEN i1.' . $this->table_columns['left_id'] . ' AND i1.' . $this->table_columns['right_id'] . ' - OR i1.' . $this->table_columns['left_id'] . ' BETWEEN i2.' . $this->table_columns['left_id'] . ' AND i2.' . $this->table_columns['right_id']; + $condition = 'i2.' . $this->column_left_id . ' BETWEEN i1.' . $this->column_left_id . ' AND i1.' . $this->column_right_id . ' + OR i1.' . $this->column_left_id . ' BETWEEN i2.' . $this->column_left_id . ' AND i2.' . $this->column_right_id; break; } @@ -448,19 +446,19 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface FROM ' . $this->table_name . ' i1 LEFT JOIN ' . $this->table_name . " i2 ON (($condition) " . $this->get_sql_where('AND', 'i2.') . ') - WHERE i1.' . $this->table_columns['item_id'] . ' = ' . $item->get_item_id() . ' + WHERE i1.' . $this->column_item_id . ' = ' . $item->get_item_id() . ' ' . $this->get_sql_where('AND', 'i1.') . ' - ORDER BY i2.' . $this->table_columns['left_id'] . ' ' . ($order_desc ? 'ASC' : 'DESC'); + ORDER BY i2.' . $this->column_left_id . ' ' . ($order_desc ? 'ASC' : 'DESC'); $result = $this->db->sql_query($sql); while ($row = $this->db->sql_fetchrow($result)) { - if (!$include_item && $item->get_item_id() === (int) $row[$this->table_columns['item_id']]) + if (!$include_item && $item->get_item_id() === (int) $row[$this->column_item_id]) { continue; } - $rows[$row[$this->table_columns['item_id']]] = $row; + $rows[$row[$this->column_item_id]] = $row; } $this->db->sql_freeresult($result); @@ -483,23 +481,23 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface { $sql = 'SELECT ' . implode(', ', $this->item_basic_data) . ' FROM ' . $this->table_name . ' - WHERE ' . $this->table_columns['left_id'] . ' < ' . $item->get_left_id() . ' - AND ' . $this->table_columns['right_id'] . ' > ' . $item->get_right_id() . ' + WHERE ' . $this->column_left_id . ' < ' . $item->get_left_id() . ' + AND ' . $this->column_right_id . ' > ' . $item->get_right_id() . ' ' . $this->get_sql_where('AND') . ' - ORDER BY ' . $this->table_columns['left_id'] . ' ASC'; + ORDER BY ' . $this->column_left_id . ' ASC'; $result = $this->db->sql_query($sql); while ($row = $this->db->sql_fetchrow($result)) { - $parents[$row[$this->table_columns['item_id']]] = $row; + $parents[$row[$this->column_item_id]] = $row; } $this->db->sql_freeresult($result); $item_parents = serialize($parents); $sql = 'UPDATE ' . $this->table_name . ' - SET ' . $this->table_columns['item_parents'] . " = '" . $this->db->sql_escape($item_parents) . "' - WHERE " . $this->table_columns['parent_id'] . ' = ' . $item->get_parent_id(); + SET ' . $this->column_item_parents . " = '" . $this->db->sql_escape($item_parents) . "' + WHERE " . $this->column_parent_id . ' = ' . $item->get_parent_id(); $this->db->sql_query($sql); } else @@ -522,16 +520,16 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface protected function remove_subset(array $subset_items, phpbb_nestedset_item_interface $bounding_item, $set_subset_zero = true) { $diff = sizeof($subset_items) * 2; - $sql_subset_items = $this->db->sql_in_set($this->table_columns['item_id'], $subset_items); - $sql_not_subset_items = $this->db->sql_in_set($this->table_columns['item_id'], $subset_items, true); + $sql_subset_items = $this->db->sql_in_set($this->column_item_id, $subset_items); + $sql_not_subset_items = $this->db->sql_in_set($this->column_item_id, $subset_items, true); - $sql_is_parent = $this->table_columns['left_id'] . ' <= ' . $bounding_item->get_right_id() . ' - AND ' . $this->table_columns['right_id'] . ' >= ' . $bounding_item->get_right_id(); + $sql_is_parent = $this->column_left_id . ' <= ' . $bounding_item->get_right_id() . ' + AND ' . $this->column_right_id . ' >= ' . $bounding_item->get_right_id(); - $sql_is_right = $this->table_columns['left_id'] . ' > ' . $bounding_item->get_right_id(); + $sql_is_right = $this->column_left_id . ' > ' . $bounding_item->get_right_id(); - $set_left_id = $this->db->sql_case($sql_is_right, $this->table_columns['left_id'] . ' - ' . $diff, $this->table_columns['left_id']); - $set_right_id = $this->db->sql_case($sql_is_parent . ' OR ' . $sql_is_right, $this->table_columns['right_id'] . ' - ' . $diff, $this->table_columns['right_id']); + $set_left_id = $this->db->sql_case($sql_is_right, $this->column_left_id . ' - ' . $diff, $this->column_left_id); + $set_right_id = $this->db->sql_case($sql_is_parent . ' OR ' . $sql_is_right, $this->column_right_id . ' - ' . $diff, $this->column_right_id); if ($set_subset_zero) { @@ -540,10 +538,10 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface } $sql = 'UPDATE ' . $this->table_name . ' - SET ' . $this->table_columns['left_id'] . ' = ' . $set_left_id . ', - ' . $this->table_columns['right_id'] . ' = ' . $set_right_id . ', - ' . (($set_subset_zero) ? $this->table_columns['parent_id'] . ' = ' . $this->db->sql_case($sql_subset_items, 0, $this->table_columns['parent_id']) . ',' : '') . ' - ' . $this->table_columns['item_parents'] . " = '' + SET ' . $this->column_left_id . ' = ' . $set_left_id . ', + ' . $this->column_right_id . ' = ' . $set_right_id . ', + ' . (($set_subset_zero) ? $this->column_parent_id . ' = ' . $this->db->sql_case($sql_subset_items, 0, $this->column_parent_id) . ',' : '') . ' + ' . $this->column_item_parents . " = '' " . ((!$set_subset_zero) ? ' WHERE ' . $sql_not_subset_items . ' ' . $this->get_sql_where('AND') : $this->get_sql_where('WHERE')); $this->db->sql_query($sql); } @@ -558,15 +556,15 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface protected function prepare_adding_subset(array $subset_items, phpbb_nestedset_item_interface $new_parent) { $diff = sizeof($subset_items) * 2; - $sql_not_subset_items = $this->db->sql_in_set($this->table_columns['item_id'], $subset_items, true); + $sql_not_subset_items = $this->db->sql_in_set($this->column_item_id, $subset_items, true); - $set_left_id = $this->db->sql_case($this->table_columns['left_id'] . ' > ' . $new_parent->get_right_id(), $this->table_columns['left_id'] . ' + ' . $diff, $this->table_columns['left_id']); - $set_right_id = $this->db->sql_case($this->table_columns['right_id'] . ' >= ' . $new_parent->get_right_id(), $this->table_columns['right_id'] . ' + ' . $diff, $this->table_columns['right_id']); + $set_left_id = $this->db->sql_case($this->column_left_id . ' > ' . $new_parent->get_right_id(), $this->column_left_id . ' + ' . $diff, $this->column_left_id); + $set_right_id = $this->db->sql_case($this->column_right_id . ' >= ' . $new_parent->get_right_id(), $this->column_right_id . ' + ' . $diff, $this->column_right_id); $sql = 'UPDATE ' . $this->table_name . ' - SET ' . $this->table_columns['left_id'] . ' = ' . $set_left_id . ', - ' . $this->table_columns['right_id'] . ' = ' . $set_right_id . ', - ' . $this->table_columns['item_parents'] . " = '' + SET ' . $this->column_left_id . ' = ' . $set_left_id . ', + ' . $this->column_right_id . ' = ' . $set_right_id . ', + ' . $this->column_item_parents . " = '' WHERE " . $sql_not_subset_items . ' ' . $this->get_sql_where('AND'); $this->db->sql_query($sql); @@ -583,9 +581,9 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface { $sql = 'UPDATE ' . $this->table_name . ' SET ' . $this->db->sql_build_array('UPDATE', array( - $this->table_columns['left_id'] => 0, - $this->table_columns['right_id'] => 0, - $this->table_columns['item_parents'] => '', + $this->column_left_id => 0, + $this->column_right_id => 0, + $this->column_item_parents => '', )) . ' ' . $this->get_sql_where('WHERE'); $this->db->sql_query($sql); @@ -593,34 +591,34 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface $sql = 'SELECT * FROM ' . $this->table_name . ' - WHERE ' . $this->table_columns['parent_id'] . ' = ' . (int) $parent_id . ' + WHERE ' . $this->column_parent_id . ' = ' . (int) $parent_id . ' ' . $this->get_sql_where('AND') . ' - ORDER BY ' . $this->table_columns['left_id'] . ', ' . $this->table_columns['item_id'] . ' ASC'; + ORDER BY ' . $this->column_left_id . ', ' . $this->column_item_id . ' ASC'; $result = $this->db->sql_query($sql); while ($row = $this->db->sql_fetchrow($result)) { // First we update the left_id for this module - if ($row[$this->table_columns['left_id']] != $new_id) + if ($row[$this->column_left_id] != $new_id) { $sql = 'UPDATE ' . $this->table_name . ' SET ' . $this->db->sql_build_array('UPDATE', array( - $this->table_columns['left_id'] => $new_id, - $this->table_columns['item_parents'] => '', + $this->column_left_id => $new_id, + $this->column_item_parents => '', )) . ' - WHERE ' . $this->table_columns['item_id'] . ' = ' . $row[$this->table_columns['item_id']]; + WHERE ' . $this->column_item_id . ' = ' . $row[$this->column_item_id]; $this->db->sql_query($sql); } $new_id++; // Then we go through any children and update their left/right id's - $new_id = $this->recalculate_nested_set($new_id, $row[$this->table_columns['item_id']]); + $new_id = $this->recalculate_nested_set($new_id, $row[$this->column_item_id]); // Then we come back and update the right_id for this module - if ($row[$this->table_columns['right_id']] != $new_id) + if ($row[$this->column_right_id] != $new_id) { $sql = 'UPDATE ' . $this->table_name . ' - SET ' . $this->db->sql_build_array('UPDATE', array($this->table_columns['right_id'] => $new_id)) . ' - WHERE ' . $this->table_columns['item_id'] . ' = ' . $row[$this->table_columns['item_id']]; + SET ' . $this->db->sql_build_array('UPDATE', array($this->column_right_id => $new_id)) . ' + WHERE ' . $this->column_item_id . ' = ' . $row[$this->column_item_id]; $this->db->sql_query($sql); } $new_id++; diff --git a/phpBB/includes/nestedset/forum.php b/phpBB/includes/nestedset/forum.php index 7ad4d2c85e..b1df3c7e45 100644 --- a/phpBB/includes/nestedset/forum.php +++ b/phpBB/includes/nestedset/forum.php @@ -31,15 +31,10 @@ class phpbb_nestedset_forum extends phpbb_nestedset_base /** * Column names in the table - * @var array + * @var String */ - protected $table_columns = array( - 'item_id' => 'forum_id', - 'left_id' => 'left_id', - 'right_id' => 'right_id', - 'parent_id' => 'parent_id', - 'item_parents' => 'forum_parents', - ); + protected $columns_item_id = 'forum_id'; + protected $columns_item_parents = 'forum_parents'; /** * Additional SQL restrictions From 5c379db085bab4ff0f807a9e7dfe6edb52ef25ab Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Wed, 17 Apr 2013 22:56:12 +0200 Subject: [PATCH 140/281] [ticket/11495] Fix description of get_sql_where PHPBB3-11495 --- phpBB/includes/nestedset/base.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/phpBB/includes/nestedset/base.php b/phpBB/includes/nestedset/base.php index 4dfe3e6203..ae6a77dc8d 100644 --- a/phpBB/includes/nestedset/base.php +++ b/phpBB/includes/nestedset/base.php @@ -50,9 +50,7 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface protected $item_basic_data = array('*'); /** - * Delete an item from the nested set (also deletes the rows form the table) - * - * Also deletes all subitems from the nested set + * Returns additional sql where restrictions * * @param string $operator SQL operator that needs to be prepended to sql_where, * if it is not empty. From 8c3443ba996c57a0420e4559022c97c2547404c0 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 18 Apr 2013 00:13:19 +0200 Subject: [PATCH 141/281] [ticket/11495] Use array directly instead of phpbb_nestedset_item_interface PHPBB3-11495 --- phpBB/includes/nestedset/base.php | 150 ++++++++++++------------- phpBB/includes/nestedset/forum.php | 4 +- phpBB/includes/nestedset/interface.php | 46 ++++---- 3 files changed, 97 insertions(+), 103 deletions(-) diff --git a/phpBB/includes/nestedset/base.php b/phpBB/includes/nestedset/base.php index ae6a77dc8d..56422f52a5 100644 --- a/phpBB/includes/nestedset/base.php +++ b/phpBB/includes/nestedset/base.php @@ -81,15 +81,13 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface $item_data[$this->column_item_id] = (int) $this->db->sql_nextid(); - $item = new $this->item_class($item_data); - - return array_merge($item_data, $this->add($item)); + return array_merge($item_data, $this->add($item_data)); } /** * @inheritdoc */ - public function add(phpbb_nestedset_item_interface $item) + public function add(array $item) { $sql = 'SELECT MAX(' . $this->column_right_id . ') AS ' . $this->column_right_id . ' FROM ' . $this->table_name . ' @@ -107,7 +105,7 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface $sql = 'UPDATE ' . $this->table_name . ' SET ' . $this->db->sql_build_array('UPDATE', $update_item_data) . ' - WHERE ' . $this->column_item_id . ' = ' . $item->get_item_id(); + WHERE ' . $this->column_item_id . ' = ' . (int) $item[$this->column_item_id]; $this->db->sql_query($sql); return $update_item_data; @@ -116,15 +114,15 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface /** * @inheritdoc */ - public function remove(phpbb_nestedset_item_interface $item) + public function remove(array $item) { - if ($item->has_children()) + if ($item[$this->column_right_id] - $item[$this->column_left_id] > 1) { $items = array_keys($this->get_branch_data($item, 'children')); } else { - $items = array($item->get_item_id()); + $items = array((int) $item[$this->column_item_id]); } $this->remove_subset($items, $item); @@ -135,7 +133,7 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface /** * @inheritdoc */ - public function delete(phpbb_nestedset_item_interface $item) + public function delete(array $item) { $removed_items = $this->remove($item); @@ -150,7 +148,7 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface /** * @inheritdoc */ - public function move(phpbb_nestedset_item_interface $item, $delta) + public function move(array $item, $delta) { if ($delta == 0) { @@ -168,17 +166,17 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface */ $sql = 'SELECT ' . implode(', ', $this->table_columns) . ' FROM ' . $this->table_name . ' - WHERE ' . $this->column_parent_id . ' = ' . $item->get_parent_id() . ' + WHERE ' . $this->column_parent_id . ' = ' . (int) $item[$this->column_parent_id] . ' ' . $this->get_sql_where() . ' AND '; if ($action == 'move_up') { - $sql .= $this->column_right_id . ' < ' . $item->get_right_id() . ' ORDER BY ' . $this->column_right_id . ' DESC'; + $sql .= $this->column_right_id . ' < ' . (int) $item[$this->column_right_id] . ' ORDER BY ' . $this->column_right_id . ' DESC'; } else { - $sql .= $this->column_left_id . ' > ' . $item->get_left_id() . ' ORDER BY ' . $this->column_left_id . ' ASC'; + $sql .= $this->column_left_id . ' > ' . (int) $item[$this->column_left_id] . ' ORDER BY ' . $this->column_left_id . ' ASC'; } $result = $this->db->sql_query_limit($sql, $delta); @@ -186,7 +184,7 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface $target = null; while ($row = $this->db->sql_fetchrow($result)) { - $target = new $this->item_class($row); + $target = $row; } $this->db->sql_freeresult($result); @@ -205,25 +203,25 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface */ if ($action == 'move_up') { - $left_id = $target->get_left_id(); - $right_id = $item->get_right_id(); + $left_id = $target[$this->column_left_id]; + $right_id = (int) $item[$this->column_right_id]; - $diff_up = $item->get_left_id() - $target->get_left_id(); - $diff_down = $item->get_right_id() + 1 - $item->get_left_id(); + $diff_up = (int) $item[$this->column_left_id] - $target[$this->column_left_id]; + $diff_down = (int) $item[$this->column_right_id] + 1 - (int) $item[$this->column_left_id]; - $move_up_left = $item->get_left_id(); - $move_up_right = $item->get_right_id(); + $move_up_left = (int) $item[$this->column_left_id]; + $move_up_right = (int) $item[$this->column_right_id]; } else { - $left_id = $item->get_left_id(); - $right_id = $target->get_right_id(); + $left_id = (int) $item[$this->column_left_id]; + $right_id = $target[$this->column_right_id]; - $diff_up = $item->get_right_id() + 1 - $item->get_left_id(); - $diff_down = $target->get_right_id() - $item->get_right_id(); + $diff_up = (int) $item[$this->column_right_id] + 1 - (int) $item[$this->column_left_id]; + $diff_down = $target[$this->column_right_id] - (int) $item[$this->column_right_id]; - $move_up_left = $item->get_right_id() + 1; - $move_up_right = $target->get_right_id(); + $move_up_left = (int) $item[$this->column_right_id] + 1; + $move_up_right = $target[$this->column_right_id]; } // Now do the dirty job @@ -249,7 +247,7 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface /** * @inheritdoc */ - public function move_down(phpbb_nestedset_item_interface $item) + public function move_down(array $item) { return $this->move($item, -1); } @@ -257,7 +255,7 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface /** * @inheritdoc */ - public function move_up(phpbb_nestedset_item_interface $item) + public function move_up(array $item) { return $this->move($item, 1); } @@ -265,16 +263,16 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface /** * @inheritdoc */ - public function move_children(phpbb_nestedset_item_interface $current_parent, phpbb_nestedset_item_interface $new_parent) + public function move_children(array $current_parent, array $new_parent) { - if (!$current_parent->has_children() || !$current_parent->get_item_id() || $current_parent->get_item_id() == $new_parent->get_item_id()) + if (($current_parent[$this->column_right_id] - $current_parent[$this->column_left_id]) <= 1 || !$current_parent[$this->column_item_id] || $current_parent[$this->column_item_id] == $new_parent[$this->column_item_id]) { return false; } $move_items = array_keys($this->get_branch_data($current_parent, 'children', true, false)); - if (in_array($new_parent->get_item_id(), $move_items)) + if (in_array($new_parent[$this->column_item_id], $move_items)) { throw new phpbb_nestedset_exception('INVALID_PARENT'); } @@ -286,33 +284,31 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface $this->remove_subset($move_items, $current_parent, false); - if ($new_parent->get_item_id()) + if ($new_parent[$this->column_item_id]) { // Retrieve new-parent again, it may have been changed... $sql = 'SELECT * FROM ' . $this->table_name . ' - WHERE ' . $this->column_item_id . ' = ' . $new_parent->get_item_id(); + WHERE ' . $this->column_item_id . ' = ' . (int) $new_parent[$this->column_item_id]; $result = $this->db->sql_query($sql); - $parent_data = $this->db->sql_fetchrow($result); + $new_parent = $this->db->sql_fetchrow($result); $this->db->sql_freeresult($result); - if (!$parent_data) + if (!$new_parent) { $this->db->sql_transaction('rollback'); throw new phpbb_nestedset_exception('INVALID_PARENT'); } - $new_parent = new $this->item_class($parent_data); - $new_right_id = $this->prepare_adding_subset($move_items, $new_parent); - if ($new_right_id > $current_parent->get_right_id()) + if ($new_right_id > $current_parent[$this->column_right_id]) { - $diff = ' + ' . ($new_right_id - $current_parent->get_right_id()); + $diff = ' + ' . ($new_right_id - $current_parent[$this->column_right_id]); } else { - $diff = ' - ' . abs($new_right_id - $current_parent->get_right_id()); + $diff = ' - ' . abs($new_right_id - $current_parent[$this->column_right_id]); } } else @@ -325,13 +321,13 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface $row = $this->db->sql_fetchrow($result); $this->db->sql_freeresult($result); - $diff = ' + ' . ($row[$this->column_right_id] - $current_parent->get_left_id()); + $diff = ' + ' . ($row[$this->column_right_id] - $current_parent[$this->column_left_id]); } $sql = 'UPDATE ' . $this->table_name . ' SET ' . $this->column_left_id . ' = ' . $this->column_left_id . $diff . ', ' . $this->column_right_id . ' = ' . $this->column_right_id . $diff . ', - ' . $this->column_parent_id . ' = ' . $this->db->sql_case($this->column_parent_id . ' = ' . $current_parent->get_item_id(), $new_parent->get_item_id(), $this->column_parent_id) . ', + ' . $this->column_parent_id . ' = ' . $this->db->sql_case($this->column_parent_id . ' = ' . (int) $current_parent[$this->column_item_id], (int) $new_parent[$this->column_item_id], $this->column_parent_id) . ', ' . $this->column_item_parents . " = '' WHERE " . $this->db->sql_in_set($this->column_item_id, $move_items) . ' ' . $this->get_sql_where('AND'); @@ -345,11 +341,11 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface /** * @inheritdoc */ - public function set_parent(phpbb_nestedset_item_interface $item, phpbb_nestedset_item_interface $new_parent) + public function set_parent(array $item, array $new_parent) { $move_items = array_keys($this->get_branch_data($item, 'children')); - if (in_array($new_parent->get_item_id(), $move_items)) + if (in_array($new_parent[$this->column_item_id], $move_items)) { throw new phpbb_nestedset_exception('INVALID_PARENT'); } @@ -361,33 +357,31 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface $this->remove_subset($move_items, $item, false); - if ($new_parent->get_item_id()) + if ($new_parent[$this->column_item_id]) { // Retrieve new-parent again, it may have been changed... $sql = 'SELECT * FROM ' . $this->table_name . ' - WHERE ' . $this->column_item_id . ' = ' . $new_parent->get_item_id(); + WHERE ' . $this->column_item_id . ' = ' . (int) $new_parent[$this->column_item_id]; $result = $this->db->sql_query($sql); - $parent_data = $this->db->sql_fetchrow($result); + $new_parent = $this->db->sql_fetchrow($result); $this->db->sql_freeresult($result); - if (!$parent_data) + if (!$new_parent) { $this->db->sql_transaction('rollback'); throw new phpbb_nestedset_exception('INVALID_PARENT'); } - $new_parent = new $this->item_class($parent_data); - $new_right_id = $this->prepare_adding_subset($move_items, $new_parent); - if ($new_right_id > $item->get_right_id()) + if ($new_right_id > (int) $item[$this->column_right_id]) { - $diff = ' + ' . ($new_right_id - $item->get_right_id() - 1); + $diff = ' + ' . ($new_right_id - (int) $item[$this->column_right_id] - 1); } else { - $diff = ' - ' . abs($new_right_id - $item->get_right_id() - 1); + $diff = ' - ' . abs($new_right_id - (int) $item[$this->column_right_id] - 1); } } else @@ -400,13 +394,13 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface $row = $this->db->sql_fetchrow($result); $this->db->sql_freeresult($result); - $diff = ' + ' . ($row[$this->column_right_id] - $item->get_left_id() + 1); + $diff = ' + ' . ($row[$this->column_right_id] - (int) $item[$this->column_left_id] + 1); } $sql = 'UPDATE ' . $this->table_name . ' SET ' . $this->column_left_id . ' = ' . $this->column_left_id . $diff . ', ' . $this->column_right_id . ' = ' . $this->column_right_id . $diff . ', - ' . $this->column_parent_id . ' = ' . $this->db->sql_case($this->column_item_id . ' = ' . $item->get_item_id(), $new_parent->get_item_id(), $this->column_parent_id) . ', + ' . $this->column_parent_id . ' = ' . $this->db->sql_case($this->column_item_id . ' = ' . (int) $item[$this->column_item_id], $new_parent[$this->column_item_id], $this->column_parent_id) . ', ' . $this->column_item_parents . " = '' WHERE " . $this->db->sql_in_set($this->column_item_id, $move_items) . ' ' . $this->get_sql_where('AND'); @@ -420,7 +414,7 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface /** * @inheritdoc */ - public function get_branch_data(phpbb_nestedset_item_interface $item, $type = 'all', $order_desc = true, $include_item = true) + public function get_branch_data(array $item, $type = 'all', $order_desc = true, $include_item = true) { switch ($type) { @@ -444,19 +438,19 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface FROM ' . $this->table_name . ' i1 LEFT JOIN ' . $this->table_name . " i2 ON (($condition) " . $this->get_sql_where('AND', 'i2.') . ') - WHERE i1.' . $this->column_item_id . ' = ' . $item->get_item_id() . ' + WHERE i1.' . $this->column_item_id . ' = ' . (int) $item[$this->column_item_id] . ' ' . $this->get_sql_where('AND', 'i1.') . ' ORDER BY i2.' . $this->column_left_id . ' ' . ($order_desc ? 'ASC' : 'DESC'); $result = $this->db->sql_query($sql); while ($row = $this->db->sql_fetchrow($result)) { - if (!$include_item && $item->get_item_id() === (int) $row[$this->column_item_id]) + if (!$include_item && $item[$this->column_item_id] == $row[$this->column_item_id]) { continue; } - $rows[$row[$this->column_item_id]] = $row; + $rows[(int) $row[$this->column_item_id]] = $row; } $this->db->sql_freeresult($result); @@ -470,17 +464,17 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface * * @inheritdoc */ - public function get_parent_data(phpbb_nestedset_item_interface $item) + public function get_parent_data(array $item) { $parents = array(); - if ($item->get_parent_id()) + if ((int) $item[$this->column_parent_id]) { - if (!$item->get_item_parents_data()) + if (!$item[$this->column_item_parents]) { $sql = 'SELECT ' . implode(', ', $this->item_basic_data) . ' FROM ' . $this->table_name . ' - WHERE ' . $this->column_left_id . ' < ' . $item->get_left_id() . ' - AND ' . $this->column_right_id . ' > ' . $item->get_right_id() . ' + WHERE ' . $this->column_left_id . ' < ' . (int) $item[$this->column_left_id] . ' + AND ' . $this->column_right_id . ' > ' . (int) $item[$this->column_right_id] . ' ' . $this->get_sql_where('AND') . ' ORDER BY ' . $this->column_left_id . ' ASC'; $result = $this->db->sql_query($sql); @@ -495,12 +489,12 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface $sql = 'UPDATE ' . $this->table_name . ' SET ' . $this->column_item_parents . " = '" . $this->db->sql_escape($item_parents) . "' - WHERE " . $this->column_parent_id . ' = ' . $item->get_parent_id(); + WHERE " . $this->column_parent_id . ' = ' . (int) $item[$this->column_parent_id]; $this->db->sql_query($sql); } else { - $parents = unserialize($item->get_item_parents_data()); + $parents = unserialize($item[$this->column_item_parents]); } } @@ -511,20 +505,20 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface * Remove a subset from the nested set * * @param array $subset_items Subset of items to remove - * @param phpbb_nestedset_item_interface $bounding_item Item containing the right bound of the subset + * @param array $bounding_item Item containing the right bound of the subset * @param bool $set_subset_zero Should the parent, left and right id of the item be set to 0, or kept unchanged? * @return null */ - protected function remove_subset(array $subset_items, phpbb_nestedset_item_interface $bounding_item, $set_subset_zero = true) + protected function remove_subset(array $subset_items, array $bounding_item, $set_subset_zero = true) { $diff = sizeof($subset_items) * 2; $sql_subset_items = $this->db->sql_in_set($this->column_item_id, $subset_items); $sql_not_subset_items = $this->db->sql_in_set($this->column_item_id, $subset_items, true); - $sql_is_parent = $this->column_left_id . ' <= ' . $bounding_item->get_right_id() . ' - AND ' . $this->column_right_id . ' >= ' . $bounding_item->get_right_id(); + $sql_is_parent = $this->column_left_id . ' <= ' . (int) $bounding_item[$this->column_right_id] . ' + AND ' . $this->column_right_id . ' >= ' . (int) $bounding_item[$this->column_right_id]; - $sql_is_right = $this->column_left_id . ' > ' . $bounding_item->get_right_id(); + $sql_is_right = $this->column_left_id . ' > ' . (int) $bounding_item[$this->column_right_id]; $set_left_id = $this->db->sql_case($sql_is_right, $this->column_left_id . ' - ' . $diff, $this->column_left_id); $set_right_id = $this->db->sql_case($sql_is_parent . ' OR ' . $sql_is_right, $this->column_right_id . ' - ' . $diff, $this->column_right_id); @@ -548,16 +542,16 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface * Add a subset to the nested set * * @param array $subset_items Subset of items to add - * @param phpbb_nestedset_item_interface $new_parent Item containing the right bound of the new parent + * @param array $new_parent Item containing the right bound of the new parent * @return int New right id of the parent item */ - protected function prepare_adding_subset(array $subset_items, phpbb_nestedset_item_interface $new_parent) + protected function prepare_adding_subset(array $subset_items, array $new_parent) { $diff = sizeof($subset_items) * 2; $sql_not_subset_items = $this->db->sql_in_set($this->column_item_id, $subset_items, true); - $set_left_id = $this->db->sql_case($this->column_left_id . ' > ' . $new_parent->get_right_id(), $this->column_left_id . ' + ' . $diff, $this->column_left_id); - $set_right_id = $this->db->sql_case($this->column_right_id . ' >= ' . $new_parent->get_right_id(), $this->column_right_id . ' + ' . $diff, $this->column_right_id); + $set_left_id = $this->db->sql_case($this->column_left_id . ' > ' . (int) $new_parent[$this->column_right_id], $this->column_left_id . ' + ' . $diff, $this->column_left_id); + $set_right_id = $this->db->sql_case($this->column_right_id . ' >= ' . (int) $new_parent[$this->column_right_id], $this->column_right_id . ' + ' . $diff, $this->column_right_id); $sql = 'UPDATE ' . $this->table_name . ' SET ' . $this->column_left_id . ' = ' . $set_left_id . ', @@ -567,7 +561,7 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface ' . $this->get_sql_where('AND'); $this->db->sql_query($sql); - return $new_parent->get_right_id() + $diff; + return $new_parent[$this->column_right_id] + $diff; } /** @@ -603,7 +597,7 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface $this->column_left_id => $new_id, $this->column_item_parents => '', )) . ' - WHERE ' . $this->column_item_id . ' = ' . $row[$this->column_item_id]; + WHERE ' . $this->column_item_id . ' = ' . (int) $row[$this->column_item_id]; $this->db->sql_query($sql); } $new_id++; @@ -616,7 +610,7 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface { $sql = 'UPDATE ' . $this->table_name . ' SET ' . $this->db->sql_build_array('UPDATE', array($this->column_right_id => $new_id)) . ' - WHERE ' . $this->column_item_id . ' = ' . $row[$this->column_item_id]; + WHERE ' . $this->column_item_id . ' = ' . (int) $row[$this->column_item_id]; $this->db->sql_query($sql); } $new_id++; diff --git a/phpBB/includes/nestedset/forum.php b/phpBB/includes/nestedset/forum.php index b1df3c7e45..e00754eb68 100644 --- a/phpBB/includes/nestedset/forum.php +++ b/phpBB/includes/nestedset/forum.php @@ -67,7 +67,7 @@ class phpbb_nestedset_forum extends phpbb_nestedset_base /** * @inheritdoc */ - public function move_children(phpbb_nestedset_item_interface $current_parent, phpbb_nestedset_item_interface $new_parent) + public function move_children(array $current_parent, array $new_parent) { while (!$this->lock->acquire()) { @@ -92,7 +92,7 @@ class phpbb_nestedset_forum extends phpbb_nestedset_base /** * @inheritdoc */ - public function set_parent(phpbb_nestedset_item_interface $item, phpbb_nestedset_item_interface $new_parent) + public function set_parent(array $item, array $new_parent) { while (!$this->lock->acquire()) { diff --git a/phpBB/includes/nestedset/interface.php b/phpBB/includes/nestedset/interface.php index 7ef6ff87bb..2d353544dd 100644 --- a/phpBB/includes/nestedset/interface.php +++ b/phpBB/includes/nestedset/interface.php @@ -20,7 +20,7 @@ interface phpbb_nestedset_interface /** * Insert an item into the nested set (also insert the rows into the table) * - * @param phpbb_nestedset_item_interface $item The item to be added + * @param array $item The item to be added * @return array Array with item data as set in the database */ public function insert(array $additional_data); @@ -28,96 +28,96 @@ interface phpbb_nestedset_interface /** * Add an item at the end of the nested set * - * @param phpbb_nestedset_item_interface $item The item to be added + * @param array $item The item to be added * @return bool True if the item was added */ - public function add(phpbb_nestedset_item_interface $item); + public function add(array $item); /** * Remove an item from the nested set * * Also removes all subitems from the nested set * - * @param phpbb_nestedset_item_interface $item The item to be removed + * @param array $item The item to be removed * @return array Items that have been removed */ - public function remove(phpbb_nestedset_item_interface $item); + public function remove(array $item); /** * Delete an item from the nested set (also deletes the rows form the table) * * Also deletes all subitems from the nested set * - * @param phpbb_nestedset_item_interface $item The item to be deleted + * @param array $item The item to be deleted * @return array Items that have been deleted */ - public function delete(phpbb_nestedset_item_interface $item); + public function delete(array $item); /** * Move an item by a given delta * - * @param phpbb_nestedset_item_interface $item The item to be moved + * @param array $item The item to be moved * @param int $delta Number of steps to move this item, < 0 => down, > 0 => up * @return bool True if the item was moved */ - public function move(phpbb_nestedset_item_interface $item, $delta); + public function move(array $item, $delta); /** * Move an item down by 1 * - * @param phpbb_nestedset_item_interface $item The item to be moved + * @param array $item The item to be moved * @return bool True if the item was moved */ - public function move_down(phpbb_nestedset_item_interface $item); + public function move_down(array $item); /** * Move an item up by 1 * - * @param phpbb_nestedset_item_interface $item The item to be moved + * @param array $item The item to be moved * @return bool True if the item was moved */ - public function move_up(phpbb_nestedset_item_interface $item); + public function move_up(array $item); /** * Moves all children of one item to another item * - * @param phpbb_nestedset_item_interface $current_parent The current parent item - * @param phpbb_nestedset_item_interface $new_parent The new parent item + * @param array $current_parent The current parent item + * @param array $new_parent The new parent item * @return bool True if any items where moved */ - public function move_children(phpbb_nestedset_item_interface $current_parent, phpbb_nestedset_item_interface $new_parent); + public function move_children(array $current_parent, array $new_parent); /** * Set the parent item * - * @param phpbb_nestedset_item_interface $item The item to be moved - * @param phpbb_nestedset_item_interface $new_parent The new parent item + * @param array $item The item to be moved + * @param array $new_parent The new parent item * @return bool True if the parent was set successfully */ - public function set_parent(phpbb_nestedset_item_interface $item, phpbb_nestedset_item_interface $new_parent); + public function set_parent(array $item, array $new_parent); /** * Get branch of the item * * This method can return all parents, children or both of the given item * - * @param phpbb_nestedset_item_interface $item The item to get the branch from + * @param array $item The item to get the branch from * @param string $type One of all|parent|children * @param bool $order_desc Order the items descending (most outer parent first) * @param bool $include_item Should the given item be included in the list aswell * @return array Array of items (containing all columns from the item table) * ID => Item data */ - public function get_branch_data(phpbb_nestedset_item_interface $item, $type, $order_desc, $include_item); + public function get_branch_data(array $item, $type, $order_desc, $include_item); /** * Get base information of parent items * - * @param phpbb_nestedset_item_interface $item The item to get the parents from + * @param array $item The item to get the parents from * @return array Array of items (containing basic columns from the item table) * ID => Item data */ - public function get_parent_data(phpbb_nestedset_item_interface $item); + public function get_parent_data(array $item); /** * Recalculate Nested Sets From 86937e03ec4af92b6467427d9ee69467139f8119 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 18 Apr 2013 00:15:02 +0200 Subject: [PATCH 142/281] [ticket/11495] Remove item classes PHPBB3-11495 --- phpBB/includes/nestedset/item/base.php | 82 --------------------- phpBB/includes/nestedset/item/forum.php | 28 ------- phpBB/includes/nestedset/item/interface.php | 61 --------------- 3 files changed, 171 deletions(-) delete mode 100644 phpBB/includes/nestedset/item/base.php delete mode 100644 phpBB/includes/nestedset/item/forum.php delete mode 100644 phpBB/includes/nestedset/item/interface.php diff --git a/phpBB/includes/nestedset/item/base.php b/phpBB/includes/nestedset/item/base.php deleted file mode 100644 index c3a7600827..0000000000 --- a/phpBB/includes/nestedset/item/base.php +++ /dev/null @@ -1,82 +0,0 @@ -item_id; - } - - /** - * @inheritdoc - */ - public function get_parent_id() - { - return (int) $this->parent_id; - } - - /** - * @inheritdoc - */ - public function get_item_parents_data() - { - return (string) $this->item_parents_data; - } - - /** - * @inheritdoc - */ - public function get_left_id() - { - return (int) $this->left_id; - } - - /** - * @inheritdoc - */ - public function get_right_id() - { - return (int) $this->right_id; - } - - /** - * @inheritdoc - */ - public function has_children() - { - return $this->right_id - $this->left_id > 1; - } -} diff --git a/phpBB/includes/nestedset/item/forum.php b/phpBB/includes/nestedset/item/forum.php deleted file mode 100644 index 9475517999..0000000000 --- a/phpBB/includes/nestedset/item/forum.php +++ /dev/null @@ -1,28 +0,0 @@ -item_id = (int) $forum_row['forum_id']; - $this->parent_id = (int) $forum_row['parent_id']; - $this->left_id = (int) $forum_row['left_id']; - $this->right_id = (int) $forum_row['right_id']; - $this->item_parents_data = (string) $forum_row['forum_parents']; - } -} diff --git a/phpBB/includes/nestedset/item/interface.php b/phpBB/includes/nestedset/item/interface.php deleted file mode 100644 index 18206d752e..0000000000 --- a/phpBB/includes/nestedset/item/interface.php +++ /dev/null @@ -1,61 +0,0 @@ - Date: Thu, 18 Apr 2013 00:33:48 +0200 Subject: [PATCH 143/281] [ticket/11495] Remove item class from unit tests PHPBB3-11495 --- tests/nestedset/item_forum_test.php | 31 ------------------ tests/nestedset/set_forum_add_remove_test.php | 17 +++++----- tests/nestedset/set_forum_get_data_test.php | 9 ++---- tests/nestedset/set_forum_move_test.php | 32 ++++--------------- 4 files changed, 18 insertions(+), 71 deletions(-) delete mode 100644 tests/nestedset/item_forum_test.php diff --git a/tests/nestedset/item_forum_test.php b/tests/nestedset/item_forum_test.php deleted file mode 100644 index 1ca89ebd2f..0000000000 --- a/tests/nestedset/item_forum_test.php +++ /dev/null @@ -1,31 +0,0 @@ - 1, - 'forum_id' => 5, - 'user_id' => 32, - 'left_id' => 2, - 'right_id' => 3, - 'forum_parents' => '', - ); - - $forum = new phpbb_nestedset_item_forum($forum_data); - - $this->assertEquals($forum->get_item_id(), $forum_data['forum_id']); - $this->assertEquals($forum->get_left_id(), $forum_data['left_id']); - $this->assertEquals($forum->get_right_id(), $forum_data['right_id']); - $this->assertEquals($forum->get_parent_id(), $forum_data['parent_id']); - $this->assertEquals($forum->get_item_parents_data(), $forum_data['forum_parents']); - } -} diff --git a/tests/nestedset/set_forum_add_remove_test.php b/tests/nestedset/set_forum_add_remove_test.php index f7d4980292..53fc23594a 100644 --- a/tests/nestedset/set_forum_add_remove_test.php +++ b/tests/nestedset/set_forum_add_remove_test.php @@ -78,9 +78,7 @@ class phpbb_tests_nestedset_set_forum_add_remove_test extends phpbb_tests_nested */ public function test_remove_add($forum_id, $expected_removed, $expected_remove_table, $expected_added, $expected_add_table) { - $forum = new phpbb_nestedset_item_forum($this->forum_data[$forum_id]); - - $removed_items = $this->set->remove($forum); + $removed_items = $this->set->remove($this->forum_data[$forum_id]); $this->assertEquals($expected_removed, $removed_items); @@ -92,8 +90,13 @@ class phpbb_tests_nestedset_set_forum_add_remove_test extends phpbb_tests_nested $added_items = array(); foreach ($removed_items as $item_id) { - $forum = new phpbb_nestedset_item_forum($this->forum_data[$item_id]); - $added_items[$item_id] = $this->set->add($forum); + $added_items[$item_id] = $this->set->add(array_merge($this->forum_data[$item_id], array( + 'forum_rules' => '', + 'forum_desc' => '', + 'parent_id' => 0, + 'left_id' => 0, + 'right_id' => 0, + ))); } $this->assertEquals($expected_added, $added_items); @@ -136,9 +139,7 @@ class phpbb_tests_nestedset_set_forum_add_remove_test extends phpbb_tests_nested */ public function test_delete($forum_id, $expected_deleted, $expected) { - $forum = new phpbb_nestedset_item_forum($this->forum_data[$forum_id]); - - $this->assertEquals($expected_deleted, $this->set->delete($forum)); + $this->assertEquals($expected_deleted, $this->set->delete($this->forum_data[$forum_id])); $result = $this->db->sql_query("SELECT forum_id, parent_id, left_id, right_id, forum_parents FROM phpbb_forums diff --git a/tests/nestedset/set_forum_get_data_test.php b/tests/nestedset/set_forum_get_data_test.php index b7314efd15..b537d0a062 100644 --- a/tests/nestedset/set_forum_get_data_test.php +++ b/tests/nestedset/set_forum_get_data_test.php @@ -66,9 +66,7 @@ class phpbb_tests_nestedset_set_forum_get_data_test extends phpbb_tests_nestedse */ public function test_get_branch_data($forum_id, $type, $order_desc, $include_item, $expected) { - $forum = new phpbb_nestedset_item_forum($this->forum_data[$forum_id]); - - $this->assertEquals($expected, array_keys($this->set->get_branch_data($forum, $type, $order_desc, $include_item))); + $this->assertEquals($expected, array_keys($this->set->get_branch_data($this->forum_data[$forum_id], $type, $order_desc, $include_item))); } public function get_parent_data_data() @@ -88,9 +86,6 @@ class phpbb_tests_nestedset_set_forum_get_data_test extends phpbb_tests_nestedse */ public function test_get_parent_data($forum_id, $forum_data, $expected) { - $data = array_merge($this->forum_data[$forum_id], $forum_data); - $forum = new phpbb_nestedset_item_forum($data); - - $this->assertEquals($expected, array_keys($this->set->get_parent_data($forum))); + $this->assertEquals($expected, array_keys($this->set->get_parent_data(array_merge($this->forum_data[$forum_id], $forum_data)))); } } diff --git a/tests/nestedset/set_forum_move_test.php b/tests/nestedset/set_forum_move_test.php index 7e1c03e60f..b90eaa12ad 100644 --- a/tests/nestedset/set_forum_move_test.php +++ b/tests/nestedset/set_forum_move_test.php @@ -120,9 +120,7 @@ class phpbb_tests_nestedset_set_forum_move_test extends phpbb_tests_nestedset_se */ public function test_move($explain, $forum_id, $delta, $expected_moved, $expected) { - $forum = new phpbb_nestedset_item_forum($this->forum_data[$forum_id]); - - $this->assertEquals($expected_moved, $this->set->move($forum, $delta)); + $this->assertEquals($expected_moved, $this->set->move($this->forum_data[$forum_id], $delta)); $result = $this->db->sql_query("SELECT forum_id, parent_id, left_id, right_id, forum_parents FROM phpbb_forums @@ -169,9 +167,7 @@ class phpbb_tests_nestedset_set_forum_move_test extends phpbb_tests_nestedset_se */ public function test_move_down($explain, $forum_id, $expected_moved, $expected) { - $forum = new phpbb_nestedset_item_forum($this->forum_data[$forum_id]); - - $this->assertEquals($expected_moved, $this->set->move_down($forum)); + $this->assertEquals($expected_moved, $this->set->move_down($this->forum_data[$forum_id])); $result = $this->db->sql_query("SELECT forum_id, parent_id, left_id, right_id, forum_parents FROM phpbb_forums @@ -218,9 +214,7 @@ class phpbb_tests_nestedset_set_forum_move_test extends phpbb_tests_nestedset_se */ public function test_move_up($explain, $forum_id, $expected_moved, $expected) { - $forum = new phpbb_nestedset_item_forum($this->forum_data[$forum_id]); - - $this->assertEquals($expected_moved, $this->set->move_up($forum)); + $this->assertEquals($expected_moved, $this->set->move_up($this->forum_data[$forum_id])); $result = $this->db->sql_query("SELECT forum_id, parent_id, left_id, right_id, forum_parents FROM phpbb_forums @@ -386,10 +380,7 @@ class phpbb_tests_nestedset_set_forum_move_test extends phpbb_tests_nestedset_se */ public function test_move_children($explain, $forum_id, $target_id, $expected_moved, $expected) { - $forum = new phpbb_nestedset_item_forum($this->forum_data[$forum_id]); - $target = new phpbb_nestedset_item_forum($this->forum_data[$target_id]); - - $this->assertEquals($expected_moved, $this->set->move_children($forum, $target)); + $this->assertEquals($expected_moved, $this->set->move_children($this->forum_data[$forum_id], $this->forum_data[$target_id])); $result = $this->db->sql_query("SELECT forum_id, parent_id, left_id, right_id, forum_parents FROM phpbb_forums @@ -414,10 +405,7 @@ class phpbb_tests_nestedset_set_forum_move_test extends phpbb_tests_nestedset_se */ public function test_move_children_throws($explain, $forum_id, $target_id) { - $forum = new phpbb_nestedset_item_forum($this->forum_data[$forum_id]); - $target = new phpbb_nestedset_item_forum($this->forum_data[$target_id]); - - $this->set->move_children($forum, $target); + $this->set->move_children($this->forum_data[$forum_id], $this->forum_data[$target_id]); } public function set_parent_data() @@ -529,10 +517,7 @@ class phpbb_tests_nestedset_set_forum_move_test extends phpbb_tests_nestedset_se */ public function test_set_parent($explain, $forum_id, $target_id, $expected_moved, $expected) { - $forum = new phpbb_nestedset_item_forum($this->forum_data[$forum_id]); - $target = new phpbb_nestedset_item_forum($this->forum_data[$target_id]); - - $this->assertEquals($expected_moved, $this->set->set_parent($forum, $target)); + $this->assertEquals($expected_moved, $this->set->set_parent($this->forum_data[$forum_id], $this->forum_data[$target_id])); $result = $this->db->sql_query("SELECT forum_id, parent_id, left_id, right_id, forum_parents FROM phpbb_forums @@ -557,9 +542,6 @@ class phpbb_tests_nestedset_set_forum_move_test extends phpbb_tests_nestedset_se */ public function test_set_parent_throws($explain, $forum_id, $target_id) { - $forum = new phpbb_nestedset_item_forum($this->forum_data[$forum_id]); - $target = new phpbb_nestedset_item_forum($this->forum_data[$target_id]); - - $this->set->set_parent($forum, $target); + $this->set->set_parent($this->forum_data[$forum_id], $this->forum_data[$target_id]); } } From e0393a3062c6bde9314ad061db781d8823cf5b97 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 18 Apr 2013 00:34:09 +0200 Subject: [PATCH 144/281] [ticket/11495] Fix column variable names PHPBB3-11495 --- phpBB/includes/nestedset/base.php | 10 +++++----- phpBB/includes/nestedset/forum.php | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/phpBB/includes/nestedset/base.php b/phpBB/includes/nestedset/base.php index 56422f52a5..630512d713 100644 --- a/phpBB/includes/nestedset/base.php +++ b/phpBB/includes/nestedset/base.php @@ -30,11 +30,11 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface * Column names in the table * @var String */ - protected $columns_item_id = 'item_id'; - protected $columns_left_id = 'left_id'; - protected $columns_right_id = 'right_id'; - protected $columns_parent_id = 'parent_id'; - protected $columns_item_parents = 'item_parents'; + protected $column_item_id = 'item_id'; + protected $column_left_id = 'left_id'; + protected $column_right_id = 'right_id'; + protected $column_parent_id = 'parent_id'; + protected $column_item_parents = 'item_parents'; /** * Additional SQL restrictions diff --git a/phpBB/includes/nestedset/forum.php b/phpBB/includes/nestedset/forum.php index e00754eb68..18936c1c55 100644 --- a/phpBB/includes/nestedset/forum.php +++ b/phpBB/includes/nestedset/forum.php @@ -33,8 +33,8 @@ class phpbb_nestedset_forum extends phpbb_nestedset_base * Column names in the table * @var String */ - protected $columns_item_id = 'forum_id'; - protected $columns_item_parents = 'forum_parents'; + protected $column_item_id = 'forum_id'; + protected $column_item_parents = 'forum_parents'; /** * Additional SQL restrictions From 514bcb2fac1a11a53e20c789ea95be6207c38e80 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 18 Apr 2013 00:50:30 +0200 Subject: [PATCH 145/281] [ticket/11495] Move nestedset default values to new method PHPBB3-11495 --- phpBB/includes/nestedset/base.php | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/phpBB/includes/nestedset/base.php b/phpBB/includes/nestedset/base.php index 630512d713..5673a913fc 100644 --- a/phpBB/includes/nestedset/base.php +++ b/phpBB/includes/nestedset/base.php @@ -67,14 +67,7 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface */ public function insert(array $additional_data) { - $item_data = array_merge($additional_data, array( - $this->column_parent_id => 0, - $this->column_left_id => 0, - $this->column_right_id => 0, - $this->column_item_parents => '', - )); - - unset($item_data[$this->column_item_id]); + $item_data = $this->reset_nestedset_values($additional_data); $sql = 'INSERT INTO ' . $this->table_name . ' ' . $this->db->sql_build_array('INSERT', $item_data); $this->db->sql_query($sql); @@ -564,6 +557,26 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface return $new_parent[$this->column_right_id] + $diff; } + /** + * Resets values required for the nested set system + * + * @param array $item Original item data + * @return array Original item data + nested set defaults + */ + protected function reset_nestedset_values(array $item) + { + $item_data = array_merge($item, array( + $this->column_parent_id => 0, + $this->column_left_id => 0, + $this->column_right_id => 0, + $this->column_item_parents => '', + )); + + unset($item_data[$this->column_item_id]); + + return $item_data; + } + /** * @inheritdoc */ From a183fc1118b5ec3b1654ab4fda9c56fa1144e4ce Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 18 Apr 2013 00:54:26 +0200 Subject: [PATCH 146/281] [ticket/11495] Manually specify the table columns PHPBB3-11495 --- phpBB/includes/nestedset/base.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/phpBB/includes/nestedset/base.php b/phpBB/includes/nestedset/base.php index 5673a913fc..7c1e7f631e 100644 --- a/phpBB/includes/nestedset/base.php +++ b/phpBB/includes/nestedset/base.php @@ -157,8 +157,8 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface * siblings between the current spot and the target then the * item will move as far as possible */ - $sql = 'SELECT ' . implode(', ', $this->table_columns) . ' - FROM ' . $this->table_name . ' + $sql = "SELECT {$this->column_item_id}, {$this->column_parent_id}, {$this->column_left_id}, {$this->column_right_id}, {$this->column_item_parents} + FROM " . $this->table_name . ' WHERE ' . $this->column_parent_id . ' = ' . (int) $item[$this->column_parent_id] . ' ' . $this->get_sql_where() . ' AND '; From ccd4a725da5269189cdb73a3d7048359a5d2cd4d Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 18 Apr 2013 09:53:02 +0200 Subject: [PATCH 147/281] [ticket/11362] Add compatibility function phpbb_clean_path() again The function first depends on the container, but also works without it and without autoload. The reason for this is, it might be used before that stuff is set up, like it has been in our common.php PHPBB3-11362 --- phpBB/includes/functions.php | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index 39a8dbc880..998c52b7c6 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -1046,6 +1046,38 @@ else } } +/** +* Eliminates useless . and .. components from specified path. +* +* Deprecated, use filesystem class instead +* +* @param string $path Path to clean +* @return string Cleaned path +* +* @deprecated +*/ +function phpbb_clean_path($path) +{ + global $phpbb_container; + + if ($phpbb_container) + { + $phpbb_filesystem = new phpbb_filesystem(); + } + else + { + // The container is not yet loaded, use a new instance + if (!class_exists('phpbb_filesystem')) + { + global $phpbb_root_path, $phpEx; + require($phpbb_root_path . 'includes/filesystem.' . $phpEx); + } + $phpbb_filesystem = new phpbb_filesystem(); + } + + return $phpbb_filesystem->clean_path($path); +} + // functions used for building option fields /** From 153b29c6c9dad621e03bf2296a93306c30ea23f0 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 18 Apr 2013 19:31:08 +0200 Subject: [PATCH 148/281] [ticket/11495] Remove item class as its no longer required PHPBB3-11495 --- phpBB/includes/nestedset/base.php | 3 --- phpBB/includes/nestedset/forum.php | 3 --- 2 files changed, 6 deletions(-) diff --git a/phpBB/includes/nestedset/base.php b/phpBB/includes/nestedset/base.php index 7c1e7f631e..d16e33a6db 100644 --- a/phpBB/includes/nestedset/base.php +++ b/phpBB/includes/nestedset/base.php @@ -23,9 +23,6 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface /** @var String */ protected $table_name; - /** @var String */ - protected $item_class = 'phpbb_nestedset_item_base'; - /** * Column names in the table * @var String diff --git a/phpBB/includes/nestedset/forum.php b/phpBB/includes/nestedset/forum.php index 18936c1c55..e723e3bf18 100644 --- a/phpBB/includes/nestedset/forum.php +++ b/phpBB/includes/nestedset/forum.php @@ -26,9 +26,6 @@ class phpbb_nestedset_forum extends phpbb_nestedset_base /** @var String */ protected $table_name; - /** @var String */ - protected $item_class = 'phpbb_nestedset_item_forum'; - /** * Column names in the table * @var String From b28180be1d911364e5c00e3e97e8dac9be6f3d6f Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 18 Apr 2013 22:16:14 +0200 Subject: [PATCH 149/281] [ticket/11495] Acquire locks for operations that manipulate the tree PHPBB3-11495 --- phpBB/includes/nestedset/base.php | 75 +++++++++++++++++++++++++++---- 1 file changed, 66 insertions(+), 9 deletions(-) diff --git a/phpBB/includes/nestedset/base.php b/phpBB/includes/nestedset/base.php index d16e33a6db..e36f45e689 100644 --- a/phpBB/includes/nestedset/base.php +++ b/phpBB/includes/nestedset/base.php @@ -20,9 +20,18 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface /** @var phpbb_db_driver*/ protected $db; + /** @var phpbb_lock_db */ + protected $lock; + /** @var String */ protected $table_name; + /** + * Prefix for the language keys returned by exceptions + * @var String + */ + protected $message_prefix = ''; + /** * Column names in the table * @var String @@ -145,6 +154,11 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface return false; } + if (!$this->lock->acquire()) + { + throw new phpbb_nestedset_exception($this->message_prefix . 'LOCK_FAILED_ACQUIRE'); + } + $action = ($delta > 0) ? 'move_up' : 'move_down'; $delta = abs($delta); @@ -180,6 +194,7 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface if (is_null($target)) { + $this->lock->release(); // The item is already on top or bottom return false; } @@ -231,6 +246,8 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface " . $this->get_sql_where(); $this->db->sql_query($sql); + $this->lock->release(); + return true; } @@ -260,11 +277,17 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface return false; } + if (!$this->lock->acquire()) + { + throw new phpbb_nestedset_exception($this->message_prefix . 'LOCK_FAILED_ACQUIRE'); + } + $move_items = array_keys($this->get_branch_data($current_parent, 'children', true, false)); if (in_array($new_parent[$this->column_item_id], $move_items)) { - throw new phpbb_nestedset_exception('INVALID_PARENT'); + $this->lock->release(); + throw new phpbb_nestedset_exception($this->message_prefix . 'INVALID_PARENT'); } $diff = sizeof($move_items) * 2; @@ -272,7 +295,7 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface $this->db->sql_transaction('begin'); - $this->remove_subset($move_items, $current_parent, false); + $this->remove_subset($move_items, $current_parent, false, true); if ($new_parent[$this->column_item_id]) { @@ -287,10 +310,11 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface if (!$new_parent) { $this->db->sql_transaction('rollback'); - throw new phpbb_nestedset_exception('INVALID_PARENT'); + $this->lock->release(); + throw new phpbb_nestedset_exception($this->message_prefix . 'INVALID_PARENT'); } - $new_right_id = $this->prepare_adding_subset($move_items, $new_parent); + $new_right_id = $this->prepare_adding_subset($move_items, $new_parent, true); if ($new_right_id > $current_parent[$this->column_right_id]) { @@ -324,6 +348,7 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface $this->db->sql_query($sql); $this->db->sql_transaction('commit'); + $this->lock->release(); return true; } @@ -333,11 +358,17 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface */ public function set_parent(array $item, array $new_parent) { + if (!$this->lock->acquire()) + { + throw new phpbb_nestedset_exception($this->message_prefix . 'LOCK_FAILED_ACQUIRE'); + } + $move_items = array_keys($this->get_branch_data($item, 'children')); if (in_array($new_parent[$this->column_item_id], $move_items)) { - throw new phpbb_nestedset_exception('INVALID_PARENT'); + $this->lock->release(); + throw new phpbb_nestedset_exception($this->message_prefix . 'INVALID_PARENT'); } $diff = sizeof($move_items) * 2; @@ -345,7 +376,7 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface $this->db->sql_transaction('begin'); - $this->remove_subset($move_items, $item, false); + $this->remove_subset($move_items, $item, false, true); if ($new_parent[$this->column_item_id]) { @@ -360,10 +391,11 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface if (!$new_parent) { $this->db->sql_transaction('rollback'); - throw new phpbb_nestedset_exception('INVALID_PARENT'); + $this->lock->release(); + throw new phpbb_nestedset_exception($this->message_prefix . 'INVALID_PARENT'); } - $new_right_id = $this->prepare_adding_subset($move_items, $new_parent); + $new_right_id = $this->prepare_adding_subset($move_items, $new_parent, true); if ($new_right_id > (int) $item[$this->column_right_id]) { @@ -397,6 +429,7 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface $this->db->sql_query($sql); $this->db->sql_transaction('commit'); + $this->lock->release(); return true; } @@ -497,10 +530,16 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface * @param array $subset_items Subset of items to remove * @param array $bounding_item Item containing the right bound of the subset * @param bool $set_subset_zero Should the parent, left and right id of the item be set to 0, or kept unchanged? + * @param bool $table_already_locked Is the table already locked, or should we acquire a new lock? * @return null */ - protected function remove_subset(array $subset_items, array $bounding_item, $set_subset_zero = true) + protected function remove_subset(array $subset_items, array $bounding_item, $set_subset_zero = true, $table_already_locked = false) { + if (!$table_already_locked && !$this->lock->acquire()) + { + throw new phpbb_nestedset_exception($this->message_prefix . 'LOCK_FAILED_ACQUIRE'); + } + $diff = sizeof($subset_items) * 2; $sql_subset_items = $this->db->sql_in_set($this->column_item_id, $subset_items); $sql_not_subset_items = $this->db->sql_in_set($this->column_item_id, $subset_items, true); @@ -526,6 +565,11 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface ' . $this->column_item_parents . " = '' " . ((!$set_subset_zero) ? ' WHERE ' . $sql_not_subset_items . ' ' . $this->get_sql_where('AND') : $this->get_sql_where('WHERE')); $this->db->sql_query($sql); + + if (!$table_already_locked) + { + $this->lock->release(); + } } /** @@ -581,6 +625,12 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface { if ($reset_ids) { + if (!$this->lock->acquire()) + { + throw new phpbb_nestedset_exception($this->message_prefix . 'LOCK_FAILED_ACQUIRE'); + } + $this->db->sql_transaction('begin'); + $sql = 'UPDATE ' . $this->table_name . ' SET ' . $this->db->sql_build_array('UPDATE', array( $this->column_left_id => 0, @@ -627,6 +677,13 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface } $this->db->sql_freeresult($result); + + if ($reset_ids) + { + $this->db->sql_transaction('commit'); + $this->lock->release(); + } + return $new_id; } } From 5cb7342dd3b7abd2366abbdb7c0ba11d3d27f922 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 18 Apr 2013 22:17:05 +0200 Subject: [PATCH 150/281] [ticket/11495] Remove acquire locks from forum implementation PHPBB3-11495 --- phpBB/includes/nestedset/forum.php | 65 +----------------------------- 1 file changed, 2 insertions(+), 63 deletions(-) diff --git a/phpBB/includes/nestedset/forum.php b/phpBB/includes/nestedset/forum.php index e723e3bf18..54a26772d5 100644 --- a/phpBB/includes/nestedset/forum.php +++ b/phpBB/includes/nestedset/forum.php @@ -17,15 +17,6 @@ if (!defined('IN_PHPBB')) class phpbb_nestedset_forum extends phpbb_nestedset_base { - /** @var phpbb_db_driver */ - protected $db; - - /** @var phpbb_lock_db */ - protected $lock; - - /** @var String */ - protected $table_name; - /** * Column names in the table * @var String @@ -34,12 +25,10 @@ class phpbb_nestedset_forum extends phpbb_nestedset_base protected $column_item_parents = 'forum_parents'; /** - * Additional SQL restrictions - * Allows to have multiple nestedsets in one table - * Columns must be prefixed with %1$s + * Prefix for the language keys returned by exceptions * @var String */ - protected $sql_where = ''; + protected $message_prefix = 'FORUM_NESTEDSET_'; /** * List of item properties to be cached in $item_parents @@ -60,54 +49,4 @@ class phpbb_nestedset_forum extends phpbb_nestedset_base $this->lock = $lock; $this->table_name = $table_name; } - - /** - * @inheritdoc - */ - public function move_children(array $current_parent, array $new_parent) - { - while (!$this->lock->acquire()) - { - // Retry after 0.2 seconds - usleep(200 * 1000); - } - - try - { - $return = parent::move_children($current_parent, $new_parent); - } - catch (phpbb_nestedset_exception $e) - { - $this->lock->release(); - throw new phpbb_nestedset_exception('FORUM_NESTEDSET_' . $e->getMessage()); - } - $this->lock->release(); - - return $return; - } - - /** - * @inheritdoc - */ - public function set_parent(array $item, array $new_parent) - { - while (!$this->lock->acquire()) - { - // Retry after 0.2 seconds - usleep(200 * 1000); - } - - try - { - $return = parent::set_parent($item, $new_parent); - } - catch (phpbb_nestedset_exception $e) - { - $this->lock->release(); - throw new phpbb_nestedset_exception('FORUM_NESTEDSET_' . $e->getMessage()); - } - $this->lock->release(); - - return $return; - } } From f3ff8b36be01bf6414268d9dca0500b6c7d4f47f Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 19 Apr 2013 01:14:38 +0200 Subject: [PATCH 151/281] [ticket/11495] Fix Spacing and lowercase on docs PHPBB3-11495 --- phpBB/includes/nestedset/base.php | 10 +++++----- phpBB/includes/nestedset/forum.php | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/phpBB/includes/nestedset/base.php b/phpBB/includes/nestedset/base.php index e36f45e689..3383fd90c4 100644 --- a/phpBB/includes/nestedset/base.php +++ b/phpBB/includes/nestedset/base.php @@ -17,24 +17,24 @@ if (!defined('IN_PHPBB')) abstract class phpbb_nestedset_base implements phpbb_nestedset_interface { - /** @var phpbb_db_driver*/ + /** @var phpbb_db_driver */ protected $db; /** @var phpbb_lock_db */ protected $lock; - /** @var String */ + /** @var string */ protected $table_name; /** * Prefix for the language keys returned by exceptions - * @var String + * @var string */ protected $message_prefix = ''; /** * Column names in the table - * @var String + * @var string */ protected $column_item_id = 'item_id'; protected $column_left_id = 'left_id'; @@ -45,7 +45,7 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface /** * Additional SQL restrictions * Allows to have multiple nested sets in one table - * @var String + * @var string */ protected $sql_where = ''; diff --git a/phpBB/includes/nestedset/forum.php b/phpBB/includes/nestedset/forum.php index 54a26772d5..dbf0e70202 100644 --- a/phpBB/includes/nestedset/forum.php +++ b/phpBB/includes/nestedset/forum.php @@ -19,14 +19,14 @@ class phpbb_nestedset_forum extends phpbb_nestedset_base { /** * Column names in the table - * @var String + * @var string */ protected $column_item_id = 'forum_id'; protected $column_item_parents = 'forum_parents'; /** * Prefix for the language keys returned by exceptions - * @var String + * @var string */ protected $message_prefix = 'FORUM_NESTEDSET_'; From 845832820ba89a0f33e264a34639a05045783397 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 19 Apr 2013 01:48:31 +0200 Subject: [PATCH 152/281] [ticket/11501] Assert the variables instead of fail() with the condition PHPBB3-11501 --- tests/dbal/migrator_test.php | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/tests/dbal/migrator_test.php b/tests/dbal/migrator_test.php index 89669b85ec..0d7fc2f839 100644 --- a/tests/dbal/migrator_test.php +++ b/tests/dbal/migrator_test.php @@ -144,15 +144,8 @@ class phpbb_dbal_migrator_test extends phpbb_database_test_case $this->migrator->update(); } - if ($migrator_test_if_true_failed) - { - $this->fail('True test failed'); - } - - if ($migrator_test_if_false_failed) - { - $this->fail('False test failed'); - } + $this->assertFalse($migrator_test_if_true_failed, 'True test failed'); + $this->assertFalse($migrator_test_if_false_failed, 'False test failed'); } public function test_recall() From 1431a027563b717183937751970f52cc0a4c94fe Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 19 Apr 2013 01:49:35 +0200 Subject: [PATCH 153/281] [ticket/11501] Remove test_ prefix from data provider methods PHPBB3-11501 --- tests/log/function_add_log_test.php | 4 ++-- tests/log/function_view_log_test.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/log/function_add_log_test.php b/tests/log/function_add_log_test.php index 864b364862..7aa42be6df 100644 --- a/tests/log/function_add_log_test.php +++ b/tests/log/function_add_log_test.php @@ -16,7 +16,7 @@ class phpbb_log_function_add_log_test extends phpbb_database_test_case return $this->createXMLDataSet(dirname(__FILE__) . '/fixtures/empty_log.xml'); } - public static function test_add_log_function_data() + public static function add_log_function_data() { return array( /** @@ -138,7 +138,7 @@ class phpbb_log_function_add_log_test extends phpbb_database_test_case } /** - * @dataProvider test_add_log_function_data + * @dataProvider add_log_function_data */ public function test_add_log_function($expected, $user_id, $mode, $required1, $additional1 = null, $additional2 = null, $additional3 = null) { diff --git a/tests/log/function_view_log_test.php b/tests/log/function_view_log_test.php index 2ecf77aeb8..1ab9488568 100644 --- a/tests/log/function_view_log_test.php +++ b/tests/log/function_view_log_test.php @@ -22,7 +22,7 @@ class phpbb_log_function_view_log_test extends phpbb_database_test_case return $this->createXMLDataSet(dirname(__FILE__) . '/fixtures/full_log.xml'); } - public static function test_view_log_function_data() + public static function view_log_function_data() { global $phpEx, $phpbb_dispatcher; $phpbb_dispatcher = new phpbb_mock_event_dispatcher(); @@ -296,7 +296,7 @@ class phpbb_log_function_view_log_test extends phpbb_database_test_case } /** - * @dataProvider test_view_log_function_data + * @dataProvider view_log_function_data */ public function test_view_log_function($expected, $expected_returned, $mode, $log_count, $limit = 5, $offset = 0, $forum_id = 0, $topic_id = 0, $user_id = 0, $limit_days = 0, $sort_by = 'l.log_id ASC', $keywords = '') { From d24ff2329fe145864712cb37ec19183bd4e21a42 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 19 Apr 2013 16:18:03 +0200 Subject: [PATCH 154/281] [ticket/11495] Use item_id only as parameter for get_branch_data() PHPBB3-11495 --- phpBB/includes/nestedset/base.php | 19 ++++++------------- phpBB/includes/nestedset/interface.php | 6 +++--- tests/nestedset/set_forum_get_data_test.php | 2 +- 3 files changed, 10 insertions(+), 17 deletions(-) diff --git a/phpBB/includes/nestedset/base.php b/phpBB/includes/nestedset/base.php index 3383fd90c4..a3c878a47e 100644 --- a/phpBB/includes/nestedset/base.php +++ b/phpBB/includes/nestedset/base.php @@ -115,14 +115,7 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface */ public function remove(array $item) { - if ($item[$this->column_right_id] - $item[$this->column_left_id] > 1) - { - $items = array_keys($this->get_branch_data($item, 'children')); - } - else - { - $items = array((int) $item[$this->column_item_id]); - } + $items = array_keys($this->get_branch_data($item[$this->column_item_id], 'children')); $this->remove_subset($items, $item); @@ -282,7 +275,7 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface throw new phpbb_nestedset_exception($this->message_prefix . 'LOCK_FAILED_ACQUIRE'); } - $move_items = array_keys($this->get_branch_data($current_parent, 'children', true, false)); + $move_items = array_keys($this->get_branch_data((int) $current_parent[$this->column_item_id], 'children', true, false)); if (in_array($new_parent[$this->column_item_id], $move_items)) { @@ -363,7 +356,7 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface throw new phpbb_nestedset_exception($this->message_prefix . 'LOCK_FAILED_ACQUIRE'); } - $move_items = array_keys($this->get_branch_data($item, 'children')); + $move_items = array_keys($this->get_branch_data((int) $item[$this->column_item_id], 'children')); if (in_array($new_parent[$this->column_item_id], $move_items)) { @@ -437,7 +430,7 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface /** * @inheritdoc */ - public function get_branch_data(array $item, $type = 'all', $order_desc = true, $include_item = true) + public function get_branch_data($item_id, $type = 'all', $order_desc = true, $include_item = true) { switch ($type) { @@ -461,14 +454,14 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface FROM ' . $this->table_name . ' i1 LEFT JOIN ' . $this->table_name . " i2 ON (($condition) " . $this->get_sql_where('AND', 'i2.') . ') - WHERE i1.' . $this->column_item_id . ' = ' . (int) $item[$this->column_item_id] . ' + WHERE i1.' . $this->column_item_id . ' = ' . (int) $item_id . ' ' . $this->get_sql_where('AND', 'i1.') . ' ORDER BY i2.' . $this->column_left_id . ' ' . ($order_desc ? 'ASC' : 'DESC'); $result = $this->db->sql_query($sql); while ($row = $this->db->sql_fetchrow($result)) { - if (!$include_item && $item[$this->column_item_id] == $row[$this->column_item_id]) + if (!$include_item && $item_id == $row[$this->column_item_id]) { continue; } diff --git a/phpBB/includes/nestedset/interface.php b/phpBB/includes/nestedset/interface.php index 2d353544dd..c632c09dbf 100644 --- a/phpBB/includes/nestedset/interface.php +++ b/phpBB/includes/nestedset/interface.php @@ -101,19 +101,19 @@ interface phpbb_nestedset_interface * * This method can return all parents, children or both of the given item * - * @param array $item The item to get the branch from + * @param int $item_id The item id to get the parents from * @param string $type One of all|parent|children * @param bool $order_desc Order the items descending (most outer parent first) * @param bool $include_item Should the given item be included in the list aswell * @return array Array of items (containing all columns from the item table) * ID => Item data */ - public function get_branch_data(array $item, $type, $order_desc, $include_item); + public function get_branch_data($item_id, $type, $order_desc, $include_item); /** * Get base information of parent items * - * @param array $item The item to get the parents from + * @param array $item The item to get the branch from * @return array Array of items (containing basic columns from the item table) * ID => Item data */ diff --git a/tests/nestedset/set_forum_get_data_test.php b/tests/nestedset/set_forum_get_data_test.php index b537d0a062..2c8889d1a5 100644 --- a/tests/nestedset/set_forum_get_data_test.php +++ b/tests/nestedset/set_forum_get_data_test.php @@ -66,7 +66,7 @@ class phpbb_tests_nestedset_set_forum_get_data_test extends phpbb_tests_nestedse */ public function test_get_branch_data($forum_id, $type, $order_desc, $include_item, $expected) { - $this->assertEquals($expected, array_keys($this->set->get_branch_data($this->forum_data[$forum_id], $type, $order_desc, $include_item))); + $this->assertEquals($expected, array_keys($this->set->get_branch_data($forum_id, $type, $order_desc, $include_item))); } public function get_parent_data_data() From 3d54a81ed9394f13aff4c40d524ed7cff0546604 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 19 Apr 2013 16:19:01 +0200 Subject: [PATCH 155/281] [ticket/11495] Use item_id only as parameter for delete() and remove() The data is acquired again anyway PHPBB3-11495 --- phpBB/includes/nestedset/base.php | 13 +++++++------ phpBB/includes/nestedset/interface.php | 12 ++++++------ tests/nestedset/set_forum_add_remove_test.php | 4 ++-- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/phpBB/includes/nestedset/base.php b/phpBB/includes/nestedset/base.php index a3c878a47e..c1feb48534 100644 --- a/phpBB/includes/nestedset/base.php +++ b/phpBB/includes/nestedset/base.php @@ -113,21 +113,22 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface /** * @inheritdoc */ - public function remove(array $item) + public function remove($item_id) { - $items = array_keys($this->get_branch_data($item[$this->column_item_id], 'children')); + $items = $this->get_branch_data($item_id, 'children'); + $item_ids = array_keys($items); - $this->remove_subset($items, $item); + $this->remove_subset($item_ids, $items[$item_id]); - return $items; + return $item_ids; } /** * @inheritdoc */ - public function delete(array $item) + public function delete($item_id) { - $removed_items = $this->remove($item); + $removed_items = $this->remove($item_id); $sql = 'DELETE FROM ' . $this->table_name . ' WHERE ' . $this->db->sql_in_set($this->column_item_id, $removed_items) . ' diff --git a/phpBB/includes/nestedset/interface.php b/phpBB/includes/nestedset/interface.php index c632c09dbf..1a6b09f975 100644 --- a/phpBB/includes/nestedset/interface.php +++ b/phpBB/includes/nestedset/interface.php @@ -38,20 +38,20 @@ interface phpbb_nestedset_interface * * Also removes all subitems from the nested set * - * @param array $item The item to be removed - * @return array Items that have been removed + * @param int $item_id The item to be deleted + * @return array Item ids that have been removed */ - public function remove(array $item); + public function remove($item); /** * Delete an item from the nested set (also deletes the rows form the table) * * Also deletes all subitems from the nested set * - * @param array $item The item to be deleted - * @return array Items that have been deleted + * @param int $item_id The item to be deleted + * @return array Item ids that have been deleted */ - public function delete(array $item); + public function delete($item); /** * Move an item by a given delta diff --git a/tests/nestedset/set_forum_add_remove_test.php b/tests/nestedset/set_forum_add_remove_test.php index 53fc23594a..97b6348d67 100644 --- a/tests/nestedset/set_forum_add_remove_test.php +++ b/tests/nestedset/set_forum_add_remove_test.php @@ -78,7 +78,7 @@ class phpbb_tests_nestedset_set_forum_add_remove_test extends phpbb_tests_nested */ public function test_remove_add($forum_id, $expected_removed, $expected_remove_table, $expected_added, $expected_add_table) { - $removed_items = $this->set->remove($this->forum_data[$forum_id]); + $removed_items = $this->set->remove($forum_id); $this->assertEquals($expected_removed, $removed_items); @@ -139,7 +139,7 @@ class phpbb_tests_nestedset_set_forum_add_remove_test extends phpbb_tests_nested */ public function test_delete($forum_id, $expected_deleted, $expected) { - $this->assertEquals($expected_deleted, $this->set->delete($this->forum_data[$forum_id])); + $this->assertEquals($expected_deleted, $this->set->delete($forum_id)); $result = $this->db->sql_query("SELECT forum_id, parent_id, left_id, right_id, forum_parents FROM phpbb_forums From f66b5323a75db084686d9a16c7090b15c5c13e54 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 19 Apr 2013 19:09:22 +0200 Subject: [PATCH 156/281] [ticket/11495] Cast some values to int PHPBB3-11495 --- phpBB/includes/nestedset/base.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/phpBB/includes/nestedset/base.php b/phpBB/includes/nestedset/base.php index c1feb48534..bb7acca0fb 100644 --- a/phpBB/includes/nestedset/base.php +++ b/phpBB/includes/nestedset/base.php @@ -202,10 +202,10 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface */ if ($action == 'move_up') { - $left_id = $target[$this->column_left_id]; + $left_id = (int) $target[$this->column_left_id]; $right_id = (int) $item[$this->column_right_id]; - $diff_up = (int) $item[$this->column_left_id] - $target[$this->column_left_id]; + $diff_up = (int) $item[$this->column_left_id] - (int) $target[$this->column_left_id]; $diff_down = (int) $item[$this->column_right_id] + 1 - (int) $item[$this->column_left_id]; $move_up_left = (int) $item[$this->column_left_id]; @@ -214,13 +214,13 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface else { $left_id = (int) $item[$this->column_left_id]; - $right_id = $target[$this->column_right_id]; + $right_id = (int) $target[$this->column_right_id]; $diff_up = (int) $item[$this->column_right_id] + 1 - (int) $item[$this->column_left_id]; - $diff_down = $target[$this->column_right_id] - (int) $item[$this->column_right_id]; + $diff_down = (int) $target[$this->column_right_id] - (int) $item[$this->column_right_id]; $move_up_left = (int) $item[$this->column_right_id] + 1; - $move_up_right = $target[$this->column_right_id]; + $move_up_right = (int) $target[$this->column_right_id]; } // Now do the dirty job From db5df5b6ac025f360cdc97182678536d88c0dccb Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 19 Apr 2013 10:15:03 +0200 Subject: [PATCH 157/281] [ticket/10966] Introduce MSSQL base class for native and ODBC PHPBB3-10966 --- phpBB/includes/db/driver/mssql_base.php | 65 ++++++++++++++++++++++++ phpBB/includes/db/driver/mssql_odbc.php | 44 +--------------- phpBB/includes/db/driver/mssqlnative.php | 44 +--------------- 3 files changed, 67 insertions(+), 86 deletions(-) create mode 100644 phpBB/includes/db/driver/mssql_base.php diff --git a/phpBB/includes/db/driver/mssql_base.php b/phpBB/includes/db/driver/mssql_base.php new file mode 100644 index 0000000000..56c111c871 --- /dev/null +++ b/phpBB/includes/db/driver/mssql_base.php @@ -0,0 +1,65 @@ +sql_server_version) ? 'MSSQL (ODBC)
    ' . $this->sql_server_version : 'MSSQL (ODBC)'; } - /** - * {@inheritDoc} - */ - public function sql_concatenate($expr1, $expr2) - { - return $expr1 . ' + ' . $expr2; - } - /** * SQL Transaction * @access private @@ -325,40 +317,6 @@ class phpbb_db_driver_mssql_odbc extends phpbb_db_driver return false; } - /** - * Escape string used in sql query - */ - function sql_escape($msg) - { - return str_replace(array("'", "\0"), array("''", ''), $msg); - } - - /** - * {@inheritDoc} - */ - function sql_lower_text($column_name) - { - return "LOWER(SUBSTRING($column_name, 1, DATALENGTH($column_name)))"; - } - - /** - * Build LIKE expression - * @access private - */ - function _sql_like_expression($expression) - { - return $expression . " ESCAPE '\\'"; - } - - /** - * Build db-specific query data - * @access private - */ - function _sql_custom_build($stage, $data) - { - return $data; - } - /** * return sql error array * @access private diff --git a/phpBB/includes/db/driver/mssqlnative.php b/phpBB/includes/db/driver/mssqlnative.php index 656cbd2437..6f433e10cf 100644 --- a/phpBB/includes/db/driver/mssqlnative.php +++ b/phpBB/includes/db/driver/mssqlnative.php @@ -191,7 +191,7 @@ class result_mssqlnative /** * @package dbal */ -class phpbb_db_driver_mssqlnative extends phpbb_db_driver +class phpbb_db_driver_mssqlnative extends phpbb_db_driver_mssql_base { var $m_insert_id = NULL; var $last_query_text = ''; @@ -256,14 +256,6 @@ class phpbb_db_driver_mssqlnative extends phpbb_db_driver return ($this->sql_server_version) ? 'MSSQL
    ' . $this->sql_server_version : 'MSSQL'; } - /** - * {@inheritDoc} - */ - public function sql_concatenate($expr1, $expr2) - { - return $expr1 . ' + ' . $expr2; - } - /** * {@inheritDoc} */ @@ -490,31 +482,6 @@ class phpbb_db_driver_mssqlnative extends phpbb_db_driver return false; } - /** - * Escape string used in sql query - */ - function sql_escape($msg) - { - return str_replace(array("'", "\0"), array("''", ''), $msg); - } - - /** - * {@inheritDoc} - */ - function sql_lower_text($column_name) - { - return "LOWER(SUBSTRING($column_name, 1, DATALENGTH($column_name)))"; - } - - /** - * Build LIKE expression - * @access private - */ - function _sql_like_expression($expression) - { - return $expression . " ESCAPE '\\'"; - } - /** * return sql error array * @access private @@ -560,15 +527,6 @@ class phpbb_db_driver_mssqlnative extends phpbb_db_driver return $error; } - /** - * Build db-specific query data - * @access private - */ - function _sql_custom_build($stage, $data) - { - return $data; - } - /** * Close sql connection * @access private From 87dc3b1e55bcfcade98eedfaa07e77c454dd7d4f Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 19 Apr 2013 21:07:42 +0200 Subject: [PATCH 158/281] [ticket/11495] Use item ids instead of requiring all data The data is grabbed again in most cases anyway, so it just makes the system easier to use. PHPBB3-11495 --- phpBB/includes/nestedset/base.php | 95 ++++++++++++++++++++----- phpBB/includes/nestedset/interface.php | 26 +++---- tests/nestedset/set_forum_move_test.php | 80 +++++++++++++-------- 3 files changed, 141 insertions(+), 60 deletions(-) diff --git a/phpBB/includes/nestedset/base.php b/phpBB/includes/nestedset/base.php index bb7acca0fb..f3bdfe1c7d 100644 --- a/phpBB/includes/nestedset/base.php +++ b/phpBB/includes/nestedset/base.php @@ -141,7 +141,7 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface /** * @inheritdoc */ - public function move(array $item, $delta) + public function move($item_id, $delta) { if ($delta == 0) { @@ -156,6 +156,21 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface $action = ($delta > 0) ? 'move_up' : 'move_down'; $delta = abs($delta); + // Keep $this->get_sql_where() here, to ensure we are in the right tree. + $sql = 'SELECT * + FROM ' . $this->table_name . ' + WHERE ' . $this->column_item_id . ' = ' . (int) $item_id . ' + ' . $this->get_sql_where(); + $result = $this->db->sql_query_limit($sql, $delta); + $item = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + if (!$item) + { + $this->lock->release(); + throw new phpbb_nestedset_exception($this->message_prefix . 'INVALID_ITEM'); + } + /** * Fetch all the siblings between the item's current spot * and where we want to move it to. If there are less than $delta @@ -248,37 +263,60 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface /** * @inheritdoc */ - public function move_down(array $item) + public function move_down($item_id) { - return $this->move($item, -1); + return $this->move($item_id, -1); } /** * @inheritdoc */ - public function move_up(array $item) + public function move_up($item_id) { - return $this->move($item, 1); + return $this->move($item_id, 1); } /** * @inheritdoc */ - public function move_children(array $current_parent, array $new_parent) + public function move_children($current_parent_id, $new_parent_id) { - if (($current_parent[$this->column_right_id] - $current_parent[$this->column_left_id]) <= 1 || !$current_parent[$this->column_item_id] || $current_parent[$this->column_item_id] == $new_parent[$this->column_item_id]) + $current_parent_id = (int) $current_parent_id; + $new_parent_id = (int) $new_parent_id; + + if ($current_parent_id == $new_parent_id) { return false; } + if (!$current_parent_id) + { + throw new phpbb_nestedset_exception($this->message_prefix . 'INVALID_ITEM'); + } + if (!$this->lock->acquire()) { throw new phpbb_nestedset_exception($this->message_prefix . 'LOCK_FAILED_ACQUIRE'); } - $move_items = array_keys($this->get_branch_data((int) $current_parent[$this->column_item_id], 'children', true, false)); + $item_data = $this->get_branch_data($current_parent_id, 'children'); + if (!isset($item_data[$current_parent_id])) + { + $this->lock->release(); + throw new phpbb_nestedset_exception($this->message_prefix . 'INVALID_ITEM'); + } - if (in_array($new_parent[$this->column_item_id], $move_items)) + $current_parent = $item_data[$current_parent_id]; + unset($item_data[$current_parent_id]); + $move_items = array_keys($item_data); + + if (($current_parent[$this->column_right_id] - $current_parent[$this->column_left_id]) <= 1) + { + $this->lock->release(); + return false; + } + + if (in_array($new_parent_id, $move_items)) { $this->lock->release(); throw new phpbb_nestedset_exception($this->message_prefix . 'INVALID_PARENT'); @@ -291,12 +329,12 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface $this->remove_subset($move_items, $current_parent, false, true); - if ($new_parent[$this->column_item_id]) + if ($new_parent_id) { // Retrieve new-parent again, it may have been changed... $sql = 'SELECT * FROM ' . $this->table_name . ' - WHERE ' . $this->column_item_id . ' = ' . (int) $new_parent[$this->column_item_id]; + WHERE ' . $this->column_item_id . ' = ' . $new_parent_id; $result = $this->db->sql_query($sql); $new_parent = $this->db->sql_fetchrow($result); $this->db->sql_freeresult($result); @@ -335,7 +373,7 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface $sql = 'UPDATE ' . $this->table_name . ' SET ' . $this->column_left_id . ' = ' . $this->column_left_id . $diff . ', ' . $this->column_right_id . ' = ' . $this->column_right_id . $diff . ', - ' . $this->column_parent_id . ' = ' . $this->db->sql_case($this->column_parent_id . ' = ' . (int) $current_parent[$this->column_item_id], (int) $new_parent[$this->column_item_id], $this->column_parent_id) . ', + ' . $this->column_parent_id . ' = ' . $this->db->sql_case($this->column_parent_id . ' = ' . $current_parent_id, $new_parent_id, $this->column_parent_id) . ', ' . $this->column_item_parents . " = '' WHERE " . $this->db->sql_in_set($this->column_item_id, $move_items) . ' ' . $this->get_sql_where('AND'); @@ -350,16 +388,37 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface /** * @inheritdoc */ - public function set_parent(array $item, array $new_parent) + public function set_parent($item_id, $new_parent_id) { + $item_id = (int) $item_id; + $new_parent_id = (int) $new_parent_id; + + if ($item_id == $new_parent_id) + { + return false; + } + + if (!$item_id) + { + throw new phpbb_nestedset_exception($this->message_prefix . 'INVALID_ITEM'); + } + if (!$this->lock->acquire()) { throw new phpbb_nestedset_exception($this->message_prefix . 'LOCK_FAILED_ACQUIRE'); } - $move_items = array_keys($this->get_branch_data((int) $item[$this->column_item_id], 'children')); + $item_data = $this->get_branch_data($item_id, 'children'); + if (!isset($item_data[$item_id])) + { + $this->lock->release(); + throw new phpbb_nestedset_exception($this->message_prefix . 'INVALID_ITEM'); + } - if (in_array($new_parent[$this->column_item_id], $move_items)) + $item = $item_data[$item_id]; + $move_items = array_keys($item_data); + + if (in_array($new_parent_id, $move_items)) { $this->lock->release(); throw new phpbb_nestedset_exception($this->message_prefix . 'INVALID_PARENT'); @@ -372,12 +431,12 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface $this->remove_subset($move_items, $item, false, true); - if ($new_parent[$this->column_item_id]) + if ($new_parent_id) { // Retrieve new-parent again, it may have been changed... $sql = 'SELECT * FROM ' . $this->table_name . ' - WHERE ' . $this->column_item_id . ' = ' . (int) $new_parent[$this->column_item_id]; + WHERE ' . $this->column_item_id . ' = ' . $new_parent_id; $result = $this->db->sql_query($sql); $new_parent = $this->db->sql_fetchrow($result); $this->db->sql_freeresult($result); @@ -416,7 +475,7 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface $sql = 'UPDATE ' . $this->table_name . ' SET ' . $this->column_left_id . ' = ' . $this->column_left_id . $diff . ', ' . $this->column_right_id . ' = ' . $this->column_right_id . $diff . ', - ' . $this->column_parent_id . ' = ' . $this->db->sql_case($this->column_item_id . ' = ' . (int) $item[$this->column_item_id], $new_parent[$this->column_item_id], $this->column_parent_id) . ', + ' . $this->column_parent_id . ' = ' . $this->db->sql_case($this->column_item_id . ' = ' . $item_id, $new_parent_id, $this->column_parent_id) . ', ' . $this->column_item_parents . " = '' WHERE " . $this->db->sql_in_set($this->column_item_id, $move_items) . ' ' . $this->get_sql_where('AND'); diff --git a/phpBB/includes/nestedset/interface.php b/phpBB/includes/nestedset/interface.php index 1a6b09f975..aedd57821a 100644 --- a/phpBB/includes/nestedset/interface.php +++ b/phpBB/includes/nestedset/interface.php @@ -56,45 +56,45 @@ interface phpbb_nestedset_interface /** * Move an item by a given delta * - * @param array $item The item to be moved - * @param int $delta Number of steps to move this item, < 0 => down, > 0 => up + * @param int $item_id The item to be moved + * @param int $delta Number of steps to move this item, < 0 => down, > 0 => up * @return bool True if the item was moved */ - public function move(array $item, $delta); + public function move($item_id, $delta); /** * Move an item down by 1 * - * @param array $item The item to be moved + * @param int $item_id The item to be moved * @return bool True if the item was moved */ - public function move_down(array $item); + public function move_down($item_id); /** * Move an item up by 1 * - * @param array $item The item to be moved + * @param int $item_id The item to be moved * @return bool True if the item was moved */ - public function move_up(array $item); + public function move_up($item_id); /** * Moves all children of one item to another item * - * @param array $current_parent The current parent item - * @param array $new_parent The new parent item + * @param int $current_parent_id The current parent item + * @param int $new_parent_id The new parent item * @return bool True if any items where moved */ - public function move_children(array $current_parent, array $new_parent); + public function move_children($current_parent_id, $new_parent_id); /** * Set the parent item * - * @param array $item The item to be moved - * @param array $new_parent The new parent item + * @param int $item_id The item to be moved + * @param int $new_parent_id The new parent item * @return bool True if the parent was set successfully */ - public function set_parent(array $item, array $new_parent); + public function set_parent($item, $new_parent_id); /** * Get branch of the item diff --git a/tests/nestedset/set_forum_move_test.php b/tests/nestedset/set_forum_move_test.php index b90eaa12ad..9a19d18476 100644 --- a/tests/nestedset/set_forum_move_test.php +++ b/tests/nestedset/set_forum_move_test.php @@ -120,7 +120,7 @@ class phpbb_tests_nestedset_set_forum_move_test extends phpbb_tests_nestedset_se */ public function test_move($explain, $forum_id, $delta, $expected_moved, $expected) { - $this->assertEquals($expected_moved, $this->set->move($this->forum_data[$forum_id], $delta)); + $this->assertEquals($expected_moved, $this->set->move($forum_id, $delta)); $result = $this->db->sql_query("SELECT forum_id, parent_id, left_id, right_id, forum_parents FROM phpbb_forums @@ -167,7 +167,7 @@ class phpbb_tests_nestedset_set_forum_move_test extends phpbb_tests_nestedset_se */ public function test_move_down($explain, $forum_id, $expected_moved, $expected) { - $this->assertEquals($expected_moved, $this->set->move_down($this->forum_data[$forum_id])); + $this->assertEquals($expected_moved, $this->set->move_down($forum_id)); $result = $this->db->sql_query("SELECT forum_id, parent_id, left_id, right_id, forum_parents FROM phpbb_forums @@ -214,7 +214,7 @@ class phpbb_tests_nestedset_set_forum_move_test extends phpbb_tests_nestedset_se */ public function test_move_up($explain, $forum_id, $expected_moved, $expected) { - $this->assertEquals($expected_moved, $this->set->move_up($this->forum_data[$forum_id])); + $this->assertEquals($expected_moved, $this->set->move_up($forum_id)); $result = $this->db->sql_query("SELECT forum_id, parent_id, left_id, right_id, forum_parents FROM phpbb_forums @@ -257,22 +257,6 @@ class phpbb_tests_nestedset_set_forum_move_test extends phpbb_tests_nestedset_se array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => ''), array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => ''), )), - array('Parent is 0', - 0, 1, false, array( - array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => ''), - array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => ''), - array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => ''), - - array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12, 'forum_parents' => ''), - array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 8, 'right_id' => 11, 'forum_parents' => ''), - array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 9, 'right_id' => 10, 'forum_parents' => ''), - - array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => ''), - array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => ''), - array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => ''), - array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => ''), - array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => ''), - )), array('Move single child up', 5, 1, true, array( array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 8, 'forum_parents' => ''), @@ -380,7 +364,7 @@ class phpbb_tests_nestedset_set_forum_move_test extends phpbb_tests_nestedset_se */ public function test_move_children($explain, $forum_id, $target_id, $expected_moved, $expected) { - $this->assertEquals($expected_moved, $this->set->move_children($this->forum_data[$forum_id], $this->forum_data[$target_id])); + $this->assertEquals($expected_moved, $this->set->move_children($forum_id, $target_id)); $result = $this->db->sql_query("SELECT forum_id, parent_id, left_id, right_id, forum_parents FROM phpbb_forums @@ -388,7 +372,26 @@ class phpbb_tests_nestedset_set_forum_move_test extends phpbb_tests_nestedset_se $this->assertEquals($expected, $this->db->sql_fetchrowset($result)); } - public function move_children_throws_data() + public function move_children_throws_item_data() + { + return array( + array('Item 0 does not exist', 0, 5), + array('Item does not exist', 200, 5), + ); + } + + /** + * @dataProvider move_children_throws_item_data + * + * @expectedException phpbb_nestedset_exception + * @expectedExceptionMessage FORUM_NESTEDSET_INVALID_ITEM + */ + public function test_move_children_throws_item($explain, $forum_id, $target_id) + { + $this->set->move_children($forum_id, $target_id); + } + + public function move_children_throws_parent_data() { return array( array('New parent is child', 4, 5), @@ -398,14 +401,14 @@ class phpbb_tests_nestedset_set_forum_move_test extends phpbb_tests_nestedset_se } /** - * @dataProvider move_children_throws_data + * @dataProvider move_children_throws_parent_data * * @expectedException phpbb_nestedset_exception * @expectedExceptionMessage FORUM_NESTEDSET_INVALID_PARENT */ - public function test_move_children_throws($explain, $forum_id, $target_id) + public function test_move_children_throws_parent($explain, $forum_id, $target_id) { - $this->set->move_children($this->forum_data[$forum_id], $this->forum_data[$target_id]); + $this->set->move_children($forum_id, $target_id); } public function set_parent_data() @@ -517,7 +520,7 @@ class phpbb_tests_nestedset_set_forum_move_test extends phpbb_tests_nestedset_se */ public function test_set_parent($explain, $forum_id, $target_id, $expected_moved, $expected) { - $this->assertEquals($expected_moved, $this->set->set_parent($this->forum_data[$forum_id], $this->forum_data[$target_id])); + $this->assertEquals($expected_moved, $this->set->set_parent($forum_id, $target_id)); $result = $this->db->sql_query("SELECT forum_id, parent_id, left_id, right_id, forum_parents FROM phpbb_forums @@ -525,7 +528,26 @@ class phpbb_tests_nestedset_set_forum_move_test extends phpbb_tests_nestedset_se $this->assertEquals($expected, $this->db->sql_fetchrowset($result)); } - public function set_parent_throws_data() + public function set_parent_throws_item_data() + { + return array( + array('Item 0 does not exist', 0, 5), + array('Item does not exist', 200, 5), + ); + } + + /** + * @dataProvider set_parent_throws_item_data + * + * @expectedException phpbb_nestedset_exception + * @expectedExceptionMessage FORUM_NESTEDSET_INVALID_ITEM + */ + public function test_set_parent_throws_item($explain, $forum_id, $target_id) + { + $this->set->set_parent($forum_id, $target_id); + } + + public function set_parent_throws_parent_data() { return array( array('New parent is child', 4, 5), @@ -535,13 +557,13 @@ class phpbb_tests_nestedset_set_forum_move_test extends phpbb_tests_nestedset_se } /** - * @dataProvider set_parent_throws_data + * @dataProvider set_parent_throws_parent_data * * @expectedException phpbb_nestedset_exception * @expectedExceptionMessage FORUM_NESTEDSET_INVALID_PARENT */ - public function test_set_parent_throws($explain, $forum_id, $target_id) + public function test_set_parent_throws_parent($explain, $forum_id, $target_id) { - $this->set->set_parent($this->forum_data[$forum_id], $this->forum_data[$target_id]); + $this->set->set_parent($forum_id, $target_id); } } From 802fbbb444a580698b130fa54754d26c12321c00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Muller?= Date: Sun, 21 Apr 2013 16:14:33 +0200 Subject: [PATCH 159/281] [ticket/9975] Translate missing style error message The error message about missing style data was not translated PHPBB3-9975 --- phpBB/includes/session.php | 2 +- phpBB/language/en/common.php | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/phpBB/includes/session.php b/phpBB/includes/session.php index b93f2ff65e..fe5357f32e 100644 --- a/phpBB/includes/session.php +++ b/phpBB/includes/session.php @@ -1661,7 +1661,7 @@ class user extends session if (!$this->theme) { - trigger_error('Could not get style data', E_USER_ERROR); + trigger_error('NO_STYLE_DATA', E_USER_ERROR); } // Now parse the cfg file and cache it diff --git a/phpBB/language/en/common.php b/phpBB/language/en/common.php index 6dd390ed24..baf398b146 100644 --- a/phpBB/language/en/common.php +++ b/phpBB/language/en/common.php @@ -391,6 +391,7 @@ $lang = array_merge($lang, array( 'NO_POSTS_TIME_FRAME' => 'No posts exist inside this topic for the selected time frame.', 'NO_FEED_ENABLED' => 'Feeds are not available on this board.', 'NO_FEED' => 'The requested feed is not available.', + 'NO_STYLE_DATA' => 'Could not get style data', 'NO_SUBJECT' => 'No subject specified', // Used for posts having no subject defined but displayed within management pages. 'NO_SUCH_SEARCH_MODULE' => 'The specified search backend doesn’t exist.', 'NO_SUPPORTED_AUTH_METHODS' => 'No supported authentication methods.', From 12c432c5230db49b659498ea4fc3ff8766a0e87f Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Mon, 22 Apr 2013 00:23:49 +0200 Subject: [PATCH 160/281] [ticket/10844] Add extension template file to locate PHPBB3-10844 --- .../extension/ext/bar/styles/prosilver/template/foobar_body.html | 1 + 1 file changed, 1 insertion(+) create mode 100644 tests/extension/ext/bar/styles/prosilver/template/foobar_body.html diff --git a/tests/extension/ext/bar/styles/prosilver/template/foobar_body.html b/tests/extension/ext/bar/styles/prosilver/template/foobar_body.html new file mode 100644 index 0000000000..00c2a84a18 --- /dev/null +++ b/tests/extension/ext/bar/styles/prosilver/template/foobar_body.html @@ -0,0 +1 @@ +bertie rules! From 10781ce9ae74efd4f04063c78235f4be031b414a Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Mon, 22 Apr 2013 00:24:30 +0200 Subject: [PATCH 161/281] [ticket/10844] Increase prefix to not match template/ in finder test PHPBB3-10844 --- tests/extension/finder_test.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/extension/finder_test.php b/tests/extension/finder_test.php index c96b11a73c..c2ac88a76a 100644 --- a/tests/extension/finder_test.php +++ b/tests/extension/finder_test.php @@ -66,7 +66,7 @@ class phpbb_extension_finder_test extends phpbb_test_case public function test_prefix_get_directories() { $dirs = $this->finder - ->prefix('t') + ->prefix('ty') ->get_directories(); sort($dirs); From 16e70fa08610227d96e149eba2019803ad37c85f Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Mon, 22 Apr 2013 00:49:41 +0200 Subject: [PATCH 162/281] [ticket/11362] Use container when available instead of creating a new instance PHPBB3-11362 --- phpBB/includes/functions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index 998c52b7c6..231825525f 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -1062,7 +1062,7 @@ function phpbb_clean_path($path) if ($phpbb_container) { - $phpbb_filesystem = new phpbb_filesystem(); + $phpbb_filesystem = $phpbb_container->get('filesystem'); } else { From 9f545a7f6ba7ddd54fae083563b5b582e05f5c1c Mon Sep 17 00:00:00 2001 From: asperous Date: Tue, 23 Apr 2013 09:55:36 -0700 Subject: [PATCH 163/281] [ticket/9975] Moved a few E_USER_ERROR errors to /language There were a few error messages that a user could experience that would, previously, be without any the ability to be localized. There are some more E_USER_ERRORs that I did not change to a constant, for example the error message that is displayed if there aren't any folders in /language. PHPBB3-9975 --- phpBB/includes/captcha/plugins/phpbb_recaptcha_plugin.php | 2 +- phpBB/includes/functions.php | 6 +++--- phpBB/includes/user.php | 2 +- phpBB/language/en/captcha_recaptcha.php | 1 + phpBB/language/en/common.php | 2 ++ phpBB/language/en/mcp.php | 2 ++ phpBB/mcp.php | 2 +- tests/security/redirect_test.php | 6 +++--- 8 files changed, 14 insertions(+), 9 deletions(-) diff --git a/phpBB/includes/captcha/plugins/phpbb_recaptcha_plugin.php b/phpBB/includes/captcha/plugins/phpbb_recaptcha_plugin.php index 83d40bbba7..cb21b04ec5 100644 --- a/phpBB/includes/captcha/plugins/phpbb_recaptcha_plugin.php +++ b/phpBB/includes/captcha/plugins/phpbb_recaptcha_plugin.php @@ -270,7 +270,7 @@ class phpbb_recaptcha extends phpbb_default_captcha $response = ''; if (false == ($fs = @fsockopen($host, $port, $errno, $errstr, 10))) { - trigger_error('Could not open socket', E_USER_ERROR); + trigger_error('RECAPTCHA_SOCKET_ERROR', E_USER_ERROR); } fwrite($fs, $http_request); diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index 58d2ad4760..6b5d7bd1df 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -2731,7 +2731,7 @@ function redirect($url, $return = false, $disable_cd_check = false) // Make sure no linebreaks are there... to prevent http response splitting for PHP < 4.4.2 if (strpos(urldecode($url), "\n") !== false || strpos(urldecode($url), "\r") !== false || strpos($url, ';') !== false) { - trigger_error('Tried to redirect to potentially insecure url.', E_USER_ERROR); + trigger_error('INSECURE_REDIRECT', E_USER_ERROR); } // Now, also check the protocol and for a valid url the last time... @@ -2740,7 +2740,7 @@ function redirect($url, $return = false, $disable_cd_check = false) if ($url_parts === false || empty($url_parts['scheme']) || !in_array($url_parts['scheme'], $allowed_protocols)) { - trigger_error('Tried to redirect to potentially insecure url.', E_USER_ERROR); + trigger_error('INSECURE_REDIRECT', E_USER_ERROR); } if ($return) @@ -4182,7 +4182,7 @@ function phpbb_checkdnsrr($host, $type = 'MX') // Handler, header and footer /** -* Error and message handler, call with trigger_error if reqd +* Error and message handler, call with trigger_error if read */ function msg_handler($errno, $msg_text, $errfile, $errline) { diff --git a/phpBB/includes/user.php b/phpBB/includes/user.php index 9ddd806b27..4477c98097 100644 --- a/phpBB/includes/user.php +++ b/phpBB/includes/user.php @@ -215,7 +215,7 @@ class phpbb_user extends phpbb_session if (!$this->style) { - trigger_error('Could not get style data', E_USER_ERROR); + trigger_error('STYLE_NOT_FOUND', E_USER_ERROR); } // Now parse the cfg file and cache it diff --git a/phpBB/language/en/captcha_recaptcha.php b/phpBB/language/en/captcha_recaptcha.php index c72957ca16..3d91a9d110 100644 --- a/phpBB/language/en/captcha_recaptcha.php +++ b/phpBB/language/en/captcha_recaptcha.php @@ -46,4 +46,5 @@ $lang = array_merge($lang, array( 'RECAPTCHA_PRIVATE_EXPLAIN' => 'Your private reCaptcha key. Keys can be obtained on www.google.com/recaptcha.', 'RECAPTCHA_EXPLAIN' => 'In an effort to prevent automatic submissions, we require that you enter both of the words displayed into the text field underneath.', + 'RECAPTCHA_SOCKET_ERROR' => 'There was a problem connecting to the RECAPTCHA service: could not open socket. Try again later.', )); diff --git a/phpBB/language/en/common.php b/phpBB/language/en/common.php index 5d6fe03b5f..c2db496437 100644 --- a/phpBB/language/en/common.php +++ b/phpBB/language/en/common.php @@ -313,6 +313,7 @@ $lang = array_merge($lang, array( 'IN' => 'in', 'INDEX' => 'Index page', 'INFORMATION' => 'Information', + 'INSECURE_REDIRECT' => 'Tried to redirect to potentially insecure url.', 'INTERESTS' => 'Interests', 'INVALID_DIGEST_CHALLENGE' => 'Invalid digest challenge.', 'INVALID_EMAIL_LOG' => '%s possibly an invalid email address?', @@ -638,6 +639,7 @@ $lang = array_merge($lang, array( 'STATISTICS' => 'Statistics', 'START_WATCHING_FORUM' => 'Subscribe forum', 'START_WATCHING_TOPIC' => 'Subscribe topic', + 'STYLE_NOT_FOUND' => 'Could not get style data', 'STOP_WATCHING_FORUM' => 'Unsubscribe forum', 'STOP_WATCHING_TOPIC' => 'Unsubscribe topic', 'SUBFORUM' => 'Subforum', diff --git a/phpBB/language/en/mcp.php b/phpBB/language/en/mcp.php index eaa2d7e3a5..29f418183f 100644 --- a/phpBB/language/en/mcp.php +++ b/phpBB/language/en/mcp.php @@ -250,6 +250,8 @@ $lang = array_merge($lang, array( 'ONLY_TOPIC' => 'Only topic “%s”', 'OTHER_USERS' => 'Other users posting from this IP', + 'QUICKMOD_ACTION_NOT_ALLOWED' => "%s not allowed as quickmod", + 'PM_REPORT_CLOSED_SUCCESS' => 'The selected PM report has been closed successfully.', 'PM_REPORT_DELETED_SUCCESS' => 'The selected PM report has been deleted successfully.', 'PM_REPORTED_SUCCESS' => 'This private message has been successfully reported.', diff --git a/phpBB/mcp.php b/phpBB/mcp.php index d04a297cf9..c36faad74b 100644 --- a/phpBB/mcp.php +++ b/phpBB/mcp.php @@ -182,7 +182,7 @@ if ($quickmod) break; default: - trigger_error("$action not allowed as quickmod", E_USER_ERROR); + trigger_error($user->lang('QUICKMOD_ACTION_NOT_ALLOWED', $action), E_USER_ERROR); break; } } diff --git a/tests/security/redirect_test.php b/tests/security/redirect_test.php index 1325466137..8e36780ca4 100644 --- a/tests/security/redirect_test.php +++ b/tests/security/redirect_test.php @@ -18,11 +18,11 @@ class phpbb_security_redirect_test extends phpbb_security_test_base // array(Input -> redirect(), expected triggered error (else false), expected returned result url (else false)) return array( array('data://x', false, 'http://localhost/phpBB'), - array('bad://localhost/phpBB/index.php', 'Tried to redirect to potentially insecure url.', false), + array('bad://localhost/phpBB/index.php', 'INSECURE_REDIRECT', false), array('http://www.otherdomain.com/somescript.php', false, 'http://localhost/phpBB'), - array("http://localhost/phpBB/memberlist.php\n\rConnection: close", 'Tried to redirect to potentially insecure url.', false), + array("http://localhost/phpBB/memberlist.php\n\rConnection: close", 'INSECURE_REDIRECT', false), array('javascript:test', false, 'http://localhost/phpBB/../javascript:test'), - array('http://localhost/phpBB/index.php;url=', 'Tried to redirect to potentially insecure url.', false), + array('http://localhost/phpBB/index.php;url=', 'INSECURE_REDIRECT', false), ); } From 51a869b13abbe3a93d91e5cc7e14a71bbede1b0e Mon Sep 17 00:00:00 2001 From: asperous Date: Tue, 23 Apr 2013 11:27:36 -0700 Subject: [PATCH 164/281] [ticket/11129] Added headers to empty subscription state "You are not subscribed to any forums". While correct, could lead to confusion. What's missing is a header right above the message that says "Watched Topics" to match the "Watched Forums" header above. This will assert the idea that there are two separate watchable sections. As is, it looks like that message is talking about the "Watched Forums" section, since it's listed under that header. PHPBB3-11129 --- .../template/ucp_main_subscribed.html | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/phpBB/styles/prosilver/template/ucp_main_subscribed.html b/phpBB/styles/prosilver/template/ucp_main_subscribed.html index 11957aa90d..84d1d897d4 100644 --- a/phpBB/styles/prosilver/template/ucp_main_subscribed.html +++ b/phpBB/styles/prosilver/template/ucp_main_subscribed.html @@ -34,6 +34,13 @@ +
      +
    • +
      +
      {L_WATCHED_FORUMS}
      +
      +
    • +

    {L_NO_WATCHED_FORUMS}

    @@ -83,14 +90,21 @@ +
      +
    • +
      +
      {L_WATCHED_TOPICS}
      +
      +
    • +

    {L_NO_WATCHED_TOPICS}

    From 0f41cc34dd83228429824547005e488f0076d0de Mon Sep 17 00:00:00 2001 From: asperous Date: Tue, 23 Apr 2013 15:00:27 -0700 Subject: [PATCH 165/281] [ticket/11129] Added headers to empty subscription state Added a newline to better seperate the two headers. PHPBB3-11129 --- phpBB/styles/prosilver/template/ucp_main_subscribed.html | 1 + 1 file changed, 1 insertion(+) mode change 100644 => 100755 phpBB/styles/prosilver/template/ucp_main_subscribed.html diff --git a/phpBB/styles/prosilver/template/ucp_main_subscribed.html b/phpBB/styles/prosilver/template/ucp_main_subscribed.html old mode 100644 new mode 100755 index 84d1d897d4..d5097a2191 --- a/phpBB/styles/prosilver/template/ucp_main_subscribed.html +++ b/phpBB/styles/prosilver/template/ucp_main_subscribed.html @@ -43,6 +43,7 @@

    {L_NO_WATCHED_FORUMS}

    +
      From 212971a3a6c7d2b336408f6432218ced55ac36a0 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Wed, 24 Apr 2013 10:37:53 -0500 Subject: [PATCH 166/281] [ticket/11454] Correct jabber global available check Copied from msg_jabber() PBPBB3-11454 --- phpBB/includes/notification/method/jabber.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/phpBB/includes/notification/method/jabber.php b/phpBB/includes/notification/method/jabber.php index debffa8ce5..d3b756d020 100644 --- a/phpBB/includes/notification/method/jabber.php +++ b/phpBB/includes/notification/method/jabber.php @@ -48,7 +48,13 @@ class phpbb_notification_method_jabber extends phpbb_notification_method_messeng */ public function global_available() { - return ($this->config['jab_enable'] && @extension_loaded('xml')); + return !( + empty($this->config['jab_enable']) || + empty($this->config['jab_host']) || + empty($this->config['jab_username']) || + empty($this->config['jab_password']) || + !@extension_loaded('xml') + ); } public function notify() From cc902ddee09c3d516a27c26fbf19af8f772814e6 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Wed, 24 Apr 2013 11:26:13 -0500 Subject: [PATCH 167/281] [ticket/11479] Fix install/update (rebuild container) Code copied from fix in 11305 PHPBB3-11479 --- phpBB/install/install_update.php | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/phpBB/install/install_update.php b/phpBB/install/install_update.php index bfceed6b17..cf800aefd4 100644 --- a/phpBB/install/install_update.php +++ b/phpBB/install/install_update.php @@ -72,7 +72,24 @@ class install_update extends module function main($mode, $sub) { global $phpbb_style, $template, $phpEx, $phpbb_root_path, $user, $db, $config, $cache, $auth, $language; - global $request, $phpbb_admin_path, $phpbb_adm_relative_path; + global $request, $phpbb_admin_path, $phpbb_adm_relative_path, $phpbb_container; + + // Create a normal container now + $phpbb_container = phpbb_create_dumped_container_unless_debug( + array( + new phpbb_di_extension_config($phpbb_root_path . 'config.' . $phpEx), + new phpbb_di_extension_core($phpbb_root_path), + ), + array( + new phpbb_di_pass_collection_pass(), + new phpbb_di_pass_kernel_pass(), + ), + $phpbb_root_path, + $phpEx + ); + + // Writes into global $cache + $cache = $phpbb_container->get('cache'); $this->tpl_name = 'install_update'; $this->page_title = 'UPDATE_INSTALLATION'; From 1f6f2435d0d4c18bd0b7586a32534f030710c929 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Muller?= Date: Mon, 22 Apr 2013 20:57:19 +0200 Subject: [PATCH 168/281] [ticket/11471] Unrelated text in e-mail templates Some e-mail templates contain text unrelated with the subject of the e-mail PHPBB3-11471 --- phpBB/language/en/email/post_approved.txt | 1 - phpBB/language/en/email/post_disapproved.txt | 1 - phpBB/language/en/email/post_in_queue.txt | 6 +----- phpBB/language/en/email/report_closed.txt | 3 +-- phpBB/language/en/email/report_deleted.txt | 3 +-- phpBB/language/en/email/report_pm.txt | 6 +----- phpBB/language/en/email/report_post.txt | 6 +----- phpBB/language/en/email/short/post_approved.txt | 1 - phpBB/language/en/email/short/post_disapproved.txt | 1 - phpBB/language/en/email/short/post_in_queue.txt | 6 +----- phpBB/language/en/email/short/report_pm.txt | 6 +----- phpBB/language/en/email/short/report_post.txt | 6 +----- phpBB/language/en/email/short/topic_approved.txt | 1 - phpBB/language/en/email/short/topic_disapproved.txt | 1 - phpBB/language/en/email/short/topic_in_queue.txt | 6 +----- phpBB/language/en/email/topic_approved.txt | 1 - phpBB/language/en/email/topic_disapproved.txt | 1 - phpBB/language/en/email/topic_in_queue.txt | 6 +----- phpBB/language/en/email/user_reactivate_account.txt | 1 - phpBB/language/en/email/user_resend_inactive.txt | 1 - 20 files changed, 10 insertions(+), 54 deletions(-) diff --git a/phpBB/language/en/email/post_approved.txt b/phpBB/language/en/email/post_approved.txt index e715b54026..a02dba142a 100644 --- a/phpBB/language/en/email/post_approved.txt +++ b/phpBB/language/en/email/post_approved.txt @@ -10,5 +10,4 @@ If you want to view the post, click the following link: If you want to view the topic, click the following link: {U_VIEW_TOPIC} - {EMAIL_SIG} \ No newline at end of file diff --git a/phpBB/language/en/email/post_disapproved.txt b/phpBB/language/en/email/post_disapproved.txt index 2f8a8381cb..9b2ee643ff 100644 --- a/phpBB/language/en/email/post_disapproved.txt +++ b/phpBB/language/en/email/post_disapproved.txt @@ -8,5 +8,4 @@ The following reason was given for the disapproval: {REASON} - {EMAIL_SIG} diff --git a/phpBB/language/en/email/post_in_queue.txt b/phpBB/language/en/email/post_in_queue.txt index 8d56ce6c4d..941f070d37 100644 --- a/phpBB/language/en/email/post_in_queue.txt +++ b/phpBB/language/en/email/post_in_queue.txt @@ -1,4 +1,4 @@ -Subject: Topic reply notification - "{TOPIC_TITLE}" +Subject: Post moderation notification - "{TOPIC_TITLE}" Hello {USERNAME}, @@ -10,8 +10,4 @@ If you want to view the post, click the following link: If you want to view the topic, click the following link: {U_TOPIC} -If you no longer wish to receive updates about replies to bookmarks, please update your notification settings here: - -{U_NOTIFICATION_SETTINGS} - {EMAIL_SIG} diff --git a/phpBB/language/en/email/report_closed.txt b/phpBB/language/en/email/report_closed.txt index eb7ef22b5e..f248018f9a 100644 --- a/phpBB/language/en/email/report_closed.txt +++ b/phpBB/language/en/email/report_closed.txt @@ -4,5 +4,4 @@ Hello {USERNAME}, You are receiving this notification because the report you filed on the post "{POST_SUBJECT}" in "{TOPIC_TITLE}" at "{SITENAME}" was handled by a moderator or by an administrator. The report was afterwards closed. If you have further questions contact {CLOSER_NAME} with a personal message. - -{EMAIL_SIG} \ No newline at end of file +{EMAIL_SIG} diff --git a/phpBB/language/en/email/report_deleted.txt b/phpBB/language/en/email/report_deleted.txt index 4292ca2239..9a30ea2ddd 100644 --- a/phpBB/language/en/email/report_deleted.txt +++ b/phpBB/language/en/email/report_deleted.txt @@ -4,5 +4,4 @@ Hello {USERNAME}, You are receiving this notification because the report you filed on the post "{POST_SUBJECT}" in "{TOPIC_TITLE}" at "{SITENAME}" was deleted by a moderator or by an administrator. - -{EMAIL_SIG} \ No newline at end of file +{EMAIL_SIG} diff --git a/phpBB/language/en/email/report_pm.txt b/phpBB/language/en/email/report_pm.txt index 66ae82d074..a101a014ff 100644 --- a/phpBB/language/en/email/report_pm.txt +++ b/phpBB/language/en/email/report_pm.txt @@ -1,4 +1,4 @@ -Subject: Topic reply notification - "{TOPIC_TITLE}" +Subject: Private Message report - "{TOPIC_TITLE}" Hello {USERNAME}, @@ -7,8 +7,4 @@ You are receiving this notification because a Private Message titled "{SUBJECT}" If you want to view the report, click the following link: {U_VIEW_REPORT} -If you no longer wish to receive updates about replies to bookmarks, please update your notification settings here: - -{U_NOTIFICATION_SETTINGS} - {EMAIL_SIG} diff --git a/phpBB/language/en/email/report_post.txt b/phpBB/language/en/email/report_post.txt index 46983be1ed..8eb24ec6af 100644 --- a/phpBB/language/en/email/report_post.txt +++ b/phpBB/language/en/email/report_post.txt @@ -1,4 +1,4 @@ -Subject: Topic reply notification - "{TOPIC_TITLE}" +Subject: Post report - "{TOPIC_TITLE}" Hello {USERNAME}, @@ -10,8 +10,4 @@ If you want to view the report, click the following link: If you want to view the post, click the following link: {U_VIEW_POST} -If you no longer wish to receive updates about replies to bookmarks, please update your notification settings here: - -{U_NOTIFICATION_SETTINGS} - {EMAIL_SIG} diff --git a/phpBB/language/en/email/short/post_approved.txt b/phpBB/language/en/email/short/post_approved.txt index e715b54026..a02dba142a 100644 --- a/phpBB/language/en/email/short/post_approved.txt +++ b/phpBB/language/en/email/short/post_approved.txt @@ -10,5 +10,4 @@ If you want to view the post, click the following link: If you want to view the topic, click the following link: {U_VIEW_TOPIC} - {EMAIL_SIG} \ No newline at end of file diff --git a/phpBB/language/en/email/short/post_disapproved.txt b/phpBB/language/en/email/short/post_disapproved.txt index 2f8a8381cb..9b2ee643ff 100644 --- a/phpBB/language/en/email/short/post_disapproved.txt +++ b/phpBB/language/en/email/short/post_disapproved.txt @@ -8,5 +8,4 @@ The following reason was given for the disapproval: {REASON} - {EMAIL_SIG} diff --git a/phpBB/language/en/email/short/post_in_queue.txt b/phpBB/language/en/email/short/post_in_queue.txt index 8d56ce6c4d..941f070d37 100644 --- a/phpBB/language/en/email/short/post_in_queue.txt +++ b/phpBB/language/en/email/short/post_in_queue.txt @@ -1,4 +1,4 @@ -Subject: Topic reply notification - "{TOPIC_TITLE}" +Subject: Post moderation notification - "{TOPIC_TITLE}" Hello {USERNAME}, @@ -10,8 +10,4 @@ If you want to view the post, click the following link: If you want to view the topic, click the following link: {U_TOPIC} -If you no longer wish to receive updates about replies to bookmarks, please update your notification settings here: - -{U_NOTIFICATION_SETTINGS} - {EMAIL_SIG} diff --git a/phpBB/language/en/email/short/report_pm.txt b/phpBB/language/en/email/short/report_pm.txt index 66ae82d074..a101a014ff 100644 --- a/phpBB/language/en/email/short/report_pm.txt +++ b/phpBB/language/en/email/short/report_pm.txt @@ -1,4 +1,4 @@ -Subject: Topic reply notification - "{TOPIC_TITLE}" +Subject: Private Message report - "{TOPIC_TITLE}" Hello {USERNAME}, @@ -7,8 +7,4 @@ You are receiving this notification because a Private Message titled "{SUBJECT}" If you want to view the report, click the following link: {U_VIEW_REPORT} -If you no longer wish to receive updates about replies to bookmarks, please update your notification settings here: - -{U_NOTIFICATION_SETTINGS} - {EMAIL_SIG} diff --git a/phpBB/language/en/email/short/report_post.txt b/phpBB/language/en/email/short/report_post.txt index 46983be1ed..8eb24ec6af 100644 --- a/phpBB/language/en/email/short/report_post.txt +++ b/phpBB/language/en/email/short/report_post.txt @@ -1,4 +1,4 @@ -Subject: Topic reply notification - "{TOPIC_TITLE}" +Subject: Post report - "{TOPIC_TITLE}" Hello {USERNAME}, @@ -10,8 +10,4 @@ If you want to view the report, click the following link: If you want to view the post, click the following link: {U_VIEW_POST} -If you no longer wish to receive updates about replies to bookmarks, please update your notification settings here: - -{U_NOTIFICATION_SETTINGS} - {EMAIL_SIG} diff --git a/phpBB/language/en/email/short/topic_approved.txt b/phpBB/language/en/email/short/topic_approved.txt index 0b09918b89..60c7ef4c09 100644 --- a/phpBB/language/en/email/short/topic_approved.txt +++ b/phpBB/language/en/email/short/topic_approved.txt @@ -7,5 +7,4 @@ You are receiving this notification because your topic "{TOPIC_TITLE}" at "{SITE If you want to view the topic, click the following link: {U_VIEW_TOPIC} - {EMAIL_SIG} diff --git a/phpBB/language/en/email/short/topic_disapproved.txt b/phpBB/language/en/email/short/topic_disapproved.txt index a4bd9c151e..9c821e2bba 100644 --- a/phpBB/language/en/email/short/topic_disapproved.txt +++ b/phpBB/language/en/email/short/topic_disapproved.txt @@ -8,5 +8,4 @@ The following reason was given for the disapproval: {REASON} - {EMAIL_SIG} diff --git a/phpBB/language/en/email/short/topic_in_queue.txt b/phpBB/language/en/email/short/topic_in_queue.txt index ae8f9e2484..706dddf64f 100644 --- a/phpBB/language/en/email/short/topic_in_queue.txt +++ b/phpBB/language/en/email/short/topic_in_queue.txt @@ -1,4 +1,4 @@ -Subject: Topic reply notification - "{TOPIC_TITLE}" +Subject: Topic moderation notification - "{TOPIC_TITLE}" Hello {USERNAME}, @@ -10,8 +10,4 @@ If you want to view the topic, click the following link: If you want to view the forum, click the following link: {U_FORUM} -If you no longer wish to receive updates about replies to bookmarks, please update your notification settings here: - -{U_NOTIFICATION_SETTINGS} - {EMAIL_SIG} diff --git a/phpBB/language/en/email/topic_approved.txt b/phpBB/language/en/email/topic_approved.txt index 0b09918b89..60c7ef4c09 100644 --- a/phpBB/language/en/email/topic_approved.txt +++ b/phpBB/language/en/email/topic_approved.txt @@ -7,5 +7,4 @@ You are receiving this notification because your topic "{TOPIC_TITLE}" at "{SITE If you want to view the topic, click the following link: {U_VIEW_TOPIC} - {EMAIL_SIG} diff --git a/phpBB/language/en/email/topic_disapproved.txt b/phpBB/language/en/email/topic_disapproved.txt index a4bd9c151e..9c821e2bba 100644 --- a/phpBB/language/en/email/topic_disapproved.txt +++ b/phpBB/language/en/email/topic_disapproved.txt @@ -8,5 +8,4 @@ The following reason was given for the disapproval: {REASON} - {EMAIL_SIG} diff --git a/phpBB/language/en/email/topic_in_queue.txt b/phpBB/language/en/email/topic_in_queue.txt index ae8f9e2484..706dddf64f 100644 --- a/phpBB/language/en/email/topic_in_queue.txt +++ b/phpBB/language/en/email/topic_in_queue.txt @@ -1,4 +1,4 @@ -Subject: Topic reply notification - "{TOPIC_TITLE}" +Subject: Topic moderation notification - "{TOPIC_TITLE}" Hello {USERNAME}, @@ -10,8 +10,4 @@ If you want to view the topic, click the following link: If you want to view the forum, click the following link: {U_FORUM} -If you no longer wish to receive updates about replies to bookmarks, please update your notification settings here: - -{U_NOTIFICATION_SETTINGS} - {EMAIL_SIG} diff --git a/phpBB/language/en/email/user_reactivate_account.txt b/phpBB/language/en/email/user_reactivate_account.txt index 7e25018f4d..385c09f4c5 100644 --- a/phpBB/language/en/email/user_reactivate_account.txt +++ b/phpBB/language/en/email/user_reactivate_account.txt @@ -15,5 +15,4 @@ Please visit the following link to reactivate your account: {U_ACTIVATE} - {EMAIL_SIG} \ No newline at end of file diff --git a/phpBB/language/en/email/user_resend_inactive.txt b/phpBB/language/en/email/user_resend_inactive.txt index 7879b914b9..b9b95ce9e5 100644 --- a/phpBB/language/en/email/user_resend_inactive.txt +++ b/phpBB/language/en/email/user_resend_inactive.txt @@ -14,7 +14,6 @@ Please visit the following link in order to activate your account: {U_ACTIVATE} - Thank you for registering. {EMAIL_SIG} \ No newline at end of file From 4becf85f5274bbe861da05917ab466eb072ea600 Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Wed, 24 Apr 2013 14:58:27 -0500 Subject: [PATCH 169/281] [ticket/11479] Use phpbb_create_default_container PHPBB3-11479 --- phpBB/install/install_update.php | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/phpBB/install/install_update.php b/phpBB/install/install_update.php index cf800aefd4..aa1bd0fa35 100644 --- a/phpBB/install/install_update.php +++ b/phpBB/install/install_update.php @@ -75,18 +75,7 @@ class install_update extends module global $request, $phpbb_admin_path, $phpbb_adm_relative_path, $phpbb_container; // Create a normal container now - $phpbb_container = phpbb_create_dumped_container_unless_debug( - array( - new phpbb_di_extension_config($phpbb_root_path . 'config.' . $phpEx), - new phpbb_di_extension_core($phpbb_root_path), - ), - array( - new phpbb_di_pass_collection_pass(), - new phpbb_di_pass_kernel_pass(), - ), - $phpbb_root_path, - $phpEx - ); + $phpbb_container = phpbb_create_default_container($phpbb_root_path, $phpEx); // Writes into global $cache $cache = $phpbb_container->get('cache'); From ebb5169a463db9a2e7c552abf87eaf1ac8d086a2 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Wed, 24 Apr 2013 10:38:57 -0500 Subject: [PATCH 170/281] [ticket/11454] Add messenger function set_addresses Automatically fills to/im from a user row Send messenger the Jabber address if using Jabber notifications PHPBB3-11454 --- phpBB/includes/functions_messenger.php | 18 ++++++++++++++++++ .../notification/method/messenger_base.php | 2 +- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/phpBB/includes/functions_messenger.php b/phpBB/includes/functions_messenger.php index 821f0d970d..5c0c182f4f 100644 --- a/phpBB/includes/functions_messenger.php +++ b/phpBB/includes/functions_messenger.php @@ -55,6 +55,24 @@ class messenger $this->vars = $this->msg = $this->replyto = $this->from = ''; $this->mail_priority = MAIL_NORMAL_PRIORITY; } + + /** + * Set addresses for to/im as available + * + * @param array $user User row + */ + function set_addresses($user) + { + if ($user['user_email']) + { + $this->to($user['user_email'], ($user['username']) ?: ''); + } + + if ($user['user_jabber']) + { + $this->im($user['user_jabber'], ($user['username']) ?: ''); + } + } /** * Sets an email address to send to diff --git a/phpBB/includes/notification/method/messenger_base.php b/phpBB/includes/notification/method/messenger_base.php index 2f9073e80b..4966aa94bc 100644 --- a/phpBB/includes/notification/method/messenger_base.php +++ b/phpBB/includes/notification/method/messenger_base.php @@ -80,7 +80,7 @@ abstract class phpbb_notification_method_messenger_base extends phpbb_notificati $messenger->template($template_dir_prefix . $notification->get_email_template(), $user['user_lang']); - $messenger->to($user['user_email'], $user['username']); + $messenger->set_addresses($user); $messenger->assign_vars(array_merge(array( 'USERNAME' => $user['username'], From fcdfe748b89426ed9d29c9e589fc5b98ed53a797 Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Wed, 24 Apr 2013 15:34:12 -0500 Subject: [PATCH 171/281] [ticket/11454] Use set_addresses in other applicable areas This should fix some other bugs that may not have yet been recognized--some areas only set to(), but sent according to user_notify_type, which is not necessarily email. PHPBB3-11454 --- phpBB/includes/acp/acp_inactive.php | 5 ++--- phpBB/includes/acp/acp_users.php | 4 ++-- phpBB/includes/functions_user.php | 3 +-- phpBB/includes/ucp/ucp_activate.php | 2 +- phpBB/includes/ucp/ucp_groups.php | 3 +-- phpBB/includes/ucp/ucp_profile.php | 3 +-- phpBB/includes/ucp/ucp_register.php | 3 +-- phpBB/includes/ucp/ucp_remind.php | 3 +-- phpBB/includes/ucp/ucp_resend.php | 5 ++--- phpBB/memberlist.php | 2 +- 10 files changed, 13 insertions(+), 20 deletions(-) diff --git a/phpBB/includes/acp/acp_inactive.php b/phpBB/includes/acp/acp_inactive.php index e61115f681..de4679b58d 100644 --- a/phpBB/includes/acp/acp_inactive.php +++ b/phpBB/includes/acp/acp_inactive.php @@ -115,7 +115,7 @@ class acp_inactive { $messenger->template('admin_welcome_activated', $row['user_lang']); - $messenger->to($row['user_email'], $row['username']); + $messenger->set_addresses($row); $messenger->anti_abuse_headers($config, $user); @@ -203,8 +203,7 @@ class acp_inactive { $messenger->template('user_remind_inactive', $row['user_lang']); - $messenger->to($row['user_email'], $row['username']); - $messenger->im($row['user_jabber'], $row['username']); + $messenger->set_addresses($row); $messenger->anti_abuse_headers($config, $user); diff --git a/phpBB/includes/acp/acp_users.php b/phpBB/includes/acp/acp_users.php index 8f4a22b61f..c8542ddbe7 100644 --- a/phpBB/includes/acp/acp_users.php +++ b/phpBB/includes/acp/acp_users.php @@ -347,7 +347,7 @@ class acp_users $messenger->template($email_template, $user_row['user_lang']); - $messenger->to($user_row['user_email'], $user_row['username']); + $messenger->set_addresses($user_row); $messenger->anti_abuse_headers($config, $user); @@ -402,7 +402,7 @@ class acp_users $messenger->template('admin_welcome_activated', $user_row['user_lang']); - $messenger->to($user_row['user_email'], $user_row['username']); + $messenger->set_addresses($user_row); $messenger->anti_abuse_headers($config, $user); diff --git a/phpBB/includes/functions_user.php b/phpBB/includes/functions_user.php index bc636acabb..599cb24f75 100644 --- a/phpBB/includes/functions_user.php +++ b/phpBB/includes/functions_user.php @@ -2924,8 +2924,7 @@ function group_user_attributes($action, $group_id, $user_id_ary = false, $userna { $messenger->template('group_approved', $row['user_lang']); - $messenger->to($row['user_email'], $row['username']); - $messenger->im($row['user_jabber'], $row['username']); + $messenger->set_addresses($row); $messenger->assign_vars(array( 'USERNAME' => htmlspecialchars_decode($row['username']), diff --git a/phpBB/includes/ucp/ucp_activate.php b/phpBB/includes/ucp/ucp_activate.php index 577761dfde..898dacd831 100644 --- a/phpBB/includes/ucp/ucp_activate.php +++ b/phpBB/includes/ucp/ucp_activate.php @@ -114,7 +114,7 @@ class ucp_activate $messenger->template('admin_welcome_activated', $user_row['user_lang']); - $messenger->to($user_row['user_email'], $user_row['username']); + $messenger->set_addresses($user_row); $messenger->anti_abuse_headers($config, $user); diff --git a/phpBB/includes/ucp/ucp_groups.php b/phpBB/includes/ucp/ucp_groups.php index 8516682633..50d13e00b1 100644 --- a/phpBB/includes/ucp/ucp_groups.php +++ b/phpBB/includes/ucp/ucp_groups.php @@ -212,8 +212,7 @@ class ucp_groups { $messenger->template('group_request', $row['user_lang']); - $messenger->to($row['user_email'], $row['username']); - $messenger->im($row['user_jabber'], $row['username']); + $messenger->set_addresses($row); $messenger->assign_vars(array( 'USERNAME' => htmlspecialchars_decode($row['username']), diff --git a/phpBB/includes/ucp/ucp_profile.php b/phpBB/includes/ucp/ucp_profile.php index d2507e5dbd..55df5f610c 100644 --- a/phpBB/includes/ucp/ucp_profile.php +++ b/phpBB/includes/ucp/ucp_profile.php @@ -175,8 +175,7 @@ class ucp_profile while ($row = $db->sql_fetchrow($result)) { $messenger->template('admin_activate', $row['user_lang']); - $messenger->to($row['user_email'], $row['username']); - $messenger->im($row['user_jabber'], $row['username']); + $messenger->set_addresses($row); $messenger->assign_vars(array( 'USERNAME' => htmlspecialchars_decode($data['username']), diff --git a/phpBB/includes/ucp/ucp_register.php b/phpBB/includes/ucp/ucp_register.php index 1de38fddb7..70fbfe46fb 100644 --- a/phpBB/includes/ucp/ucp_register.php +++ b/phpBB/includes/ucp/ucp_register.php @@ -384,8 +384,7 @@ class ucp_register while ($row = $db->sql_fetchrow($result)) { $messenger->template('admin_activate', $row['user_lang']); - $messenger->to($row['user_email'], $row['username']); - $messenger->im($row['user_jabber'], $row['username']); + $messenger->set_addresses($row); $messenger->assign_vars(array( 'USERNAME' => htmlspecialchars_decode($data['username']), diff --git a/phpBB/includes/ucp/ucp_remind.php b/phpBB/includes/ucp/ucp_remind.php index 4f65ed1866..8a7ba5d0ca 100644 --- a/phpBB/includes/ucp/ucp_remind.php +++ b/phpBB/includes/ucp/ucp_remind.php @@ -94,8 +94,7 @@ class ucp_remind $messenger->template('user_activate_passwd', $user_row['user_lang']); - $messenger->to($user_row['user_email'], $user_row['username']); - $messenger->im($user_row['user_jabber'], $user_row['username']); + $messenger->set_addresses($user_row); $messenger->assign_vars(array( 'USERNAME' => htmlspecialchars_decode($user_row['username']), diff --git a/phpBB/includes/ucp/ucp_resend.php b/phpBB/includes/ucp/ucp_resend.php index 5f1e3a92c3..ab396cdec9 100644 --- a/phpBB/includes/ucp/ucp_resend.php +++ b/phpBB/includes/ucp/ucp_resend.php @@ -91,7 +91,7 @@ class ucp_resend if ($config['require_activation'] == USER_ACTIVATION_SELF || $coppa) { $messenger->template(($coppa) ? 'coppa_resend_inactive' : 'user_resend_inactive', $user_row['user_lang']); - $messenger->to($user_row['user_email'], $user_row['username']); + $messenger->set_addresses($user_row); $messenger->anti_abuse_headers($config, $user); @@ -126,8 +126,7 @@ class ucp_resend while ($row = $db->sql_fetchrow($result)) { $messenger->template('admin_activate', $row['user_lang']); - $messenger->to($row['user_email'], $row['username']); - $messenger->im($row['user_jabber'], $row['username']); + $messenger->set_addresses($row); $messenger->anti_abuse_headers($config, $user); diff --git a/phpBB/memberlist.php b/phpBB/memberlist.php index e6045b151a..7ecf332720 100644 --- a/phpBB/memberlist.php +++ b/phpBB/memberlist.php @@ -376,7 +376,7 @@ switch ($mode) $messenger->subject(htmlspecialchars_decode($subject)); $messenger->replyto($user->data['user_email']); - $messenger->im($row['user_jabber'], $row['username']); + $messenger->set_addresses($row); $messenger->assign_vars(array( 'BOARD_CONTACT' => $config['board_contact'], From e870c04067772d227c4254533826f01252608f26 Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Wed, 24 Apr 2013 17:07:30 -0500 Subject: [PATCH 172/281] [ticket/11335] (class loader) Make php_ext 'php' not '.php' PHPBB3-11335 --- phpBB/config/services.yml | 4 ++-- phpBB/includes/class_loader.php | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/phpBB/config/services.yml b/phpBB/config/services.yml index 3b60f0e83e..502a3c418f 100644 --- a/phpBB/config/services.yml +++ b/phpBB/config/services.yml @@ -36,7 +36,7 @@ services: arguments: - phpbb_ - %core.root_path%includes/ - - .%core.php_ext% + - %core.php_ext% calls: - [register, []] - [set_cache, [@cache.driver]] @@ -46,7 +46,7 @@ services: arguments: - phpbb_ext_ - %core.root_path%ext/ - - .%core.php_ext% + - %core.php_ext% calls: - [register, []] - [set_cache, [@cache.driver]] diff --git a/phpBB/includes/class_loader.php b/phpBB/includes/class_loader.php index 6082800908..02a2d584dc 100644 --- a/phpBB/includes/class_loader.php +++ b/phpBB/includes/class_loader.php @@ -52,7 +52,7 @@ class phpbb_class_loader * @param string $php_ext The file extension for PHP files * @param phpbb_cache_driver_interface $cache An implementation of the phpBB cache interface. */ - public function __construct($prefix, $path, $php_ext = '.php', phpbb_cache_driver_interface $cache = null) + public function __construct($prefix, $path, $php_ext = 'php', phpbb_cache_driver_interface $cache = null) { $this->prefix = $prefix; $this->path = $path; @@ -111,7 +111,7 @@ class phpbb_class_loader { if (isset($this->cached_paths[$class])) { - return $this->path . $this->cached_paths[$class] . $this->php_ext; + return $this->path . $this->cached_paths[$class] . '.' . $this->php_ext; } if (!preg_match('/^' . $this->prefix . '[a-zA-Z0-9_]+$/', $class)) @@ -136,7 +136,7 @@ class phpbb_class_loader $relative_path = $dirs . implode(array_slice($parts, $i, sizeof($parts) - $i), '_'); - if (!file_exists($this->path . $relative_path . $this->php_ext)) + if (!file_exists($this->path . $relative_path . '.' . $this->php_ext)) { return false; } @@ -147,7 +147,7 @@ class phpbb_class_loader $this->cache->put('class_loader_' . $this->prefix, $this->cached_paths); } - return $this->path . $relative_path . $this->php_ext; + return $this->path . $relative_path . '.' . $this->php_ext; } /** From 6ef363547abf98445d20db61ffa5bac66b260603 Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Wed, 24 Apr 2013 17:10:17 -0500 Subject: [PATCH 173/281] [ticket/11335] (controller/helper.php) Make php_ext 'php' not '.php' PHPBB3-11335 --- phpBB/config/services.yml | 2 +- phpBB/includes/controller/helper.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/phpBB/config/services.yml b/phpBB/config/services.yml index 502a3c418f..949f89b946 100644 --- a/phpBB/config/services.yml +++ b/phpBB/config/services.yml @@ -70,7 +70,7 @@ services: - @template - @user - %core.root_path% - - .%core.php_ext% + - %core.php_ext% controller.resolver: class: phpbb_controller_resolver diff --git a/phpBB/includes/controller/helper.php b/phpBB/includes/controller/helper.php index 46c6307cb4..74410ddfd1 100644 --- a/phpBB/includes/controller/helper.php +++ b/phpBB/includes/controller/helper.php @@ -117,7 +117,7 @@ class phpbb_controller_helper $params = array('controller' => $route); } - return append_sid($this->phpbb_root_path . 'app' . $this->php_ext . $route_params, $params, $is_amp, $session_id); + return append_sid($this->phpbb_root_path . 'app.' . $this->php_ext . $route_params, $params, $is_amp, $session_id); } /** From ce230f8dea4afb585e7aca5a1763c547b2c39e81 Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Wed, 24 Apr 2013 17:15:28 -0500 Subject: [PATCH 174/281] [ticket/11335] (extension manager/finder) Make php_ext 'php' not '.php' PHPBB3-11335 --- phpBB/config/services.yml | 4 ++-- phpBB/includes/extension/finder.php | 8 ++++---- phpBB/includes/extension/manager.php | 4 ++-- phpBB/includes/extension/metadata_manager.php | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/phpBB/config/services.yml b/phpBB/config/services.yml index 949f89b946..8f58d23fd9 100644 --- a/phpBB/config/services.yml +++ b/phpBB/config/services.yml @@ -134,7 +134,7 @@ services: - @filesystem - %tables.ext% - %core.root_path% - - .%core.php_ext% + - %core.php_ext% - @cache.driver ext.finder: @@ -144,7 +144,7 @@ services: - @filesystem - %core.root_path% - @cache.driver - - .%core.php_ext% + - %core.php_ext% - _ext_finder filesystem: diff --git a/phpBB/includes/extension/finder.php b/phpBB/includes/extension/finder.php index 02a9ebb8c3..766b9e9b63 100644 --- a/phpBB/includes/extension/finder.php +++ b/phpBB/includes/extension/finder.php @@ -62,7 +62,7 @@ class phpbb_extension_finder * @param string $cache_name The name of the cache variable, defaults to * _ext_finder */ - public function __construct(phpbb_extension_manager $extension_manager, phpbb_filesystem $filesystem, $phpbb_root_path = '', phpbb_cache_driver_interface $cache = null, $php_ext = '.php', $cache_name = '_ext_finder') + public function __construct(phpbb_extension_manager $extension_manager, phpbb_filesystem $filesystem, $phpbb_root_path = '', phpbb_cache_driver_interface $cache = null, $php_ext = 'php', $cache_name = '_ext_finder') { $this->extension_manager = $extension_manager; $this->filesystem = $filesystem; @@ -256,8 +256,8 @@ class phpbb_extension_finder */ public function get_classes($cache = true, $use_all_available = false) { - $this->query['extension_suffix'] .= $this->php_ext; - $this->query['core_suffix'] .= $this->php_ext; + $this->query['extension_suffix'] .= '.' . $this->php_ext; + $this->query['core_suffix'] .= '.' . $this->php_ext; $files = $this->find($cache, false, $use_all_available); @@ -277,7 +277,7 @@ class phpbb_extension_finder { $file = preg_replace('#^includes/#', '', $file); - $classes[] = 'phpbb_' . str_replace('/', '_', substr($file, 0, -strlen($this->php_ext))); + $classes[] = 'phpbb_' . str_replace('/', '_', substr($file, 0, -strlen('.' . $this->php_ext))); } return $classes; } diff --git a/phpBB/includes/extension/manager.php b/phpBB/includes/extension/manager.php index de9a3937c3..a1022762b8 100644 --- a/phpBB/includes/extension/manager.php +++ b/phpBB/includes/extension/manager.php @@ -51,7 +51,7 @@ class phpbb_extension_manager * @param phpbb_cache_driver_interface $cache A cache instance or null * @param string $cache_name The name of the cache variable, defaults to _ext */ - public function __construct(ContainerInterface $container, phpbb_db_driver $db, phpbb_config $config, phpbb_db_migrator $migrator, phpbb_filesystem $filesystem, $extension_table, $phpbb_root_path, $php_ext = '.php', phpbb_cache_driver_interface $cache = null, $cache_name = '_ext') + public function __construct(ContainerInterface $container, phpbb_db_driver $db, phpbb_config $config, phpbb_db_migrator $migrator, phpbb_filesystem $filesystem, $extension_table, $phpbb_root_path, $php_ext = 'php', phpbb_cache_driver_interface $cache = null, $cache_name = '_ext') { $this->container = $container; $this->phpbb_root_path = $phpbb_root_path; @@ -412,7 +412,7 @@ class phpbb_extension_manager RecursiveIteratorIterator::SELF_FIRST); foreach ($iterator as $file_info) { - if ($file_info->isFile() && $file_info->getFilename() == 'ext' . $this->php_ext) + if ($file_info->isFile() && $file_info->getFilename() == 'ext.' . $this->php_ext) { $ext_name = $iterator->getInnerIterator()->getSubPath(); diff --git a/phpBB/includes/extension/metadata_manager.php b/phpBB/includes/extension/metadata_manager.php index 36b0f8b184..1637abd340 100644 --- a/phpBB/includes/extension/metadata_manager.php +++ b/phpBB/includes/extension/metadata_manager.php @@ -39,7 +39,7 @@ class phpbb_extension_metadata_manager * @param string $phpbb_root_path Path to the phpbb includes directory. * @param string $phpEx php file extension */ - public function __construct($ext_name, phpbb_db_driver $db, phpbb_extension_manager $extension_manager, $phpbb_root_path, $phpEx = '.php', phpbb_template $template, phpbb_config $config) + public function __construct($ext_name, phpbb_db_driver $db, phpbb_extension_manager $extension_manager, $phpbb_root_path, $phpEx = 'php', phpbb_template $template, phpbb_config $config) { $this->phpbb_root_path = $phpbb_root_path; $this->db = $db; From fe89e566869e91a582129b1174c1831b8ee2f865 Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Wed, 24 Apr 2013 17:17:53 -0500 Subject: [PATCH 175/281] [ticket/11335] (hook finder) Make php_ext 'php' not '.php' PHPBB3-11335 --- phpBB/config/services.yml | 2 +- phpBB/includes/hook/finder.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/phpBB/config/services.yml b/phpBB/config/services.yml index 8f58d23fd9..dc293c83a2 100644 --- a/phpBB/config/services.yml +++ b/phpBB/config/services.yml @@ -173,7 +173,7 @@ services: class: phpbb_hook_finder arguments: - %core.root_path% - - .%core.php_ext% + - %core.php_ext% - @cache.driver kernel_request_subscriber: diff --git a/phpBB/includes/hook/finder.php b/phpBB/includes/hook/finder.php index 065e685514..7b0412f733 100644 --- a/phpBB/includes/hook/finder.php +++ b/phpBB/includes/hook/finder.php @@ -66,7 +66,7 @@ class phpbb_hook_finder { while (($file = readdir($dh)) !== false) { - if (strpos($file, 'hook_') === 0 && substr($file, -(strlen($this->php_ext) + 1)) === '.' . $this->php_ext) + if (strpos($file, 'hook_') === 0 && substr($file, -strlen('.' . $this->php_ext)) === '.' . $this->php_ext) { $hook_files[] = substr($file, 0, -(strlen($this->php_ext) + 1)); } From df70b6ebe6590f3b8de32f6f4c6dbdcce1e2db34 Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Wed, 24 Apr 2013 17:19:48 -0500 Subject: [PATCH 176/281] [ticket/11335] (kernel request subscriber) Make php_ext 'php' not '.php' PHPBB3-11335 --- phpBB/config/services.yml | 2 +- phpBB/includes/functions_url_matcher.php | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/phpBB/config/services.yml b/phpBB/config/services.yml index dc293c83a2..7923c94a3f 100644 --- a/phpBB/config/services.yml +++ b/phpBB/config/services.yml @@ -181,7 +181,7 @@ services: arguments: - @ext.finder - %core.root_path% - - .%core.php_ext% + - %core.php_ext% tags: - { name: kernel.event_subscriber } diff --git a/phpBB/includes/functions_url_matcher.php b/phpBB/includes/functions_url_matcher.php index 7280cb74eb..a89ab7b126 100644 --- a/phpBB/includes/functions_url_matcher.php +++ b/phpBB/includes/functions_url_matcher.php @@ -60,7 +60,7 @@ function phpbb_create_dumped_url_matcher(phpbb_extension_finder $finder, $root_p 'class' => 'phpbb_url_matcher', )); - file_put_contents($root_path . 'cache/url_matcher' . $php_ext, $cached_url_matcher_dump); + file_put_contents($root_path . 'cache/url_matcher.' . $php_ext, $cached_url_matcher_dump); } /** @@ -87,7 +87,7 @@ function phpbb_create_url_matcher(phpbb_extension_finder $finder, RequestContext */ function phpbb_load_url_matcher(RequestContext $context, $root_path, $php_ext) { - require($root_path . 'cache/url_matcher' . $php_ext); + require($root_path . 'cache/url_matcher.' . $php_ext); return new phpbb_url_matcher($context); } @@ -102,5 +102,5 @@ function phpbb_load_url_matcher(RequestContext $context, $root_path, $php_ext) */ function phpbb_url_matcher_dumped($root_path, $php_ext) { - return file_exists($root_path . 'cache/url_matcher' . $php_ext); + return file_exists($root_path . 'cache/url_matcher.' . $php_ext); } From 14f1340903ce76fd4d72dfaf041a0e03b4272f1a Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Wed, 24 Apr 2013 17:22:58 -0500 Subject: [PATCH 177/281] [ticket/11335] (avatars) Make php_ext 'php' not '.php' PHPBB3-11335 --- phpBB/config/avatars.yml | 8 ++++---- phpBB/includes/avatar/driver/gravatar.php | 2 +- phpBB/includes/avatar/driver/remote.php | 4 ++-- phpBB/includes/avatar/driver/upload.php | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/phpBB/config/avatars.yml b/phpBB/config/avatars.yml index fa0f07372a..0aad08bac9 100644 --- a/phpBB/config/avatars.yml +++ b/phpBB/config/avatars.yml @@ -4,7 +4,7 @@ services: arguments: - @config - %core.root_path% - - .%core.php_ext% + - %core.php_ext% - @cache.driver calls: - [set_name, [avatar.driver.gravatar]] @@ -16,7 +16,7 @@ services: arguments: - @config - %core.root_path% - - .%core.php_ext% + - %core.php_ext% - @cache.driver calls: - [set_name, [avatar.driver.local]] @@ -28,7 +28,7 @@ services: arguments: - @config - %core.root_path% - - .%core.php_ext% + - %core.php_ext% - @cache.driver calls: - [set_name, [avatar.driver.remote]] @@ -40,7 +40,7 @@ services: arguments: - @config - %core.root_path% - - .%core.php_ext% + - %core.php_ext% - @cache.driver calls: - [set_name, [avatar.driver.upload]] diff --git a/phpBB/includes/avatar/driver/gravatar.php b/phpBB/includes/avatar/driver/gravatar.php index 2e2ae2071f..d559da1c0d 100644 --- a/phpBB/includes/avatar/driver/gravatar.php +++ b/phpBB/includes/avatar/driver/gravatar.php @@ -74,7 +74,7 @@ class phpbb_avatar_driver_gravatar extends phpbb_avatar_driver if (!function_exists('validate_data')) { - require($this->phpbb_root_path . 'includes/functions_user' . $this->php_ext); + require($this->phpbb_root_path . 'includes/functions_user.' . $this->php_ext); } $validate_array = validate_data( diff --git a/phpBB/includes/avatar/driver/remote.php b/phpBB/includes/avatar/driver/remote.php index 3661e16160..7da58107a1 100644 --- a/phpBB/includes/avatar/driver/remote.php +++ b/phpBB/includes/avatar/driver/remote.php @@ -63,7 +63,7 @@ class phpbb_avatar_driver_remote extends phpbb_avatar_driver if (!function_exists('validate_data')) { - require($this->phpbb_root_path . 'includes/functions_user' . $this->php_ext); + require($this->phpbb_root_path . 'includes/functions_user.' . $this->php_ext); } $validate_array = validate_data( @@ -117,7 +117,7 @@ class phpbb_avatar_driver_remote extends phpbb_avatar_driver if (!class_exists('fileupload')) { - include($this->phpbb_root_path . 'includes/functions_upload' . $this->php_ext); + include($this->phpbb_root_path . 'includes/functions_upload.' . $this->php_ext); } $types = fileupload::image_types(); diff --git a/phpBB/includes/avatar/driver/upload.php b/phpBB/includes/avatar/driver/upload.php index f91d170d7c..19737693fd 100644 --- a/phpBB/includes/avatar/driver/upload.php +++ b/phpBB/includes/avatar/driver/upload.php @@ -27,7 +27,7 @@ class phpbb_avatar_driver_upload extends phpbb_avatar_driver public function get_data($row, $ignore_config = false) { return array( - 'src' => $this->phpbb_root_path . 'download/file' . $this->php_ext . '?avatar=' . $row['avatar'], + 'src' => $this->phpbb_root_path . 'download/file.' . $this->php_ext . '?avatar=' . $row['avatar'], 'width' => $row['avatar_width'], 'height' => $row['avatar_height'], ); @@ -63,7 +63,7 @@ class phpbb_avatar_driver_upload extends phpbb_avatar_driver if (!class_exists('fileupload')) { - include($this->phpbb_root_path . 'includes/functions_upload' . $this->php_ext); + include($this->phpbb_root_path . 'includes/functions_upload.' . $this->php_ext); } $upload = new fileupload('AVATAR_', $this->allowed_extensions, $this->config['avatar_filesize'], $this->config['avatar_min_width'], $this->config['avatar_min_height'], $this->config['avatar_max_width'], $this->config['avatar_max_height'], (isset($this->config['mime_triggers']) ? explode('|', $this->config['mime_triggers']) : false)); From df518ac131bb022aa14c207e0c1408751dd9e1ef Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Wed, 24 Apr 2013 17:27:24 -0500 Subject: [PATCH 178/281] [ticket/11335] (tests) Make php_ext 'php' not '.php' PHPBB3-11335 --- tests/class_loader/class_loader_test.php | 4 ++-- tests/controller/helper_url_test.php | 2 +- tests/dbal/migrator_test.php | 2 +- tests/extension/finder_test.php | 2 +- tests/extension/metadata_manager_test.php | 2 +- tests/mock/extension_manager.php | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/class_loader/class_loader_test.php b/tests/class_loader/class_loader_test.php index 76af4dde37..bf27c7c217 100644 --- a/tests/class_loader/class_loader_test.php +++ b/tests/class_loader/class_loader_test.php @@ -71,8 +71,8 @@ class phpbb_class_loader_test extends PHPUnit_Framework_TestCase $cache = new phpbb_mock_cache($cache_map); $prefix = dirname(__FILE__) . '/'; - $class_loader = new phpbb_class_loader('phpbb_', $prefix . 'includes/', '.php', $cache); - $class_loader_ext = new phpbb_class_loader('phpbb_ext_', $prefix . 'includes/', '.php', $cache); + $class_loader = new phpbb_class_loader('phpbb_', $prefix . 'includes/', 'php', $cache); + $class_loader_ext = new phpbb_class_loader('phpbb_ext_', $prefix . 'includes/', 'php', $cache); $prefix .= 'includes/'; diff --git a/tests/controller/helper_url_test.php b/tests/controller/helper_url_test.php index 195f48d8a9..2c22700ca6 100644 --- a/tests/controller/helper_url_test.php +++ b/tests/controller/helper_url_test.php @@ -52,7 +52,7 @@ class phpbb_controller_helper_url_test extends phpbb_test_case $this->user = $this->getMock('phpbb_user'); $this->template = new phpbb_template($phpbb_root_path, $phpEx, $config, $this->user, $this->style_resource_locator, new phpbb_template_context()); - $helper = new phpbb_controller_helper($this->template, $this->user, '', '.php'); + $helper = new phpbb_controller_helper($this->template, $this->user, '', 'php'); $this->assertEquals($helper->url($route, $params, $is_amp, $session_id), $expected); } } diff --git a/tests/dbal/migrator_test.php b/tests/dbal/migrator_test.php index ae4099e6f8..6390d6a715 100644 --- a/tests/dbal/migrator_test.php +++ b/tests/dbal/migrator_test.php @@ -63,7 +63,7 @@ class phpbb_dbal_migrator_test extends phpbb_database_test_case new phpbb_filesystem(), 'phpbb_ext', dirname(__FILE__) . '/../../phpBB/', - '.php', + 'php', null ); } diff --git a/tests/extension/finder_test.php b/tests/extension/finder_test.php index 4c99ba6343..dc3e26be02 100644 --- a/tests/extension/finder_test.php +++ b/tests/extension/finder_test.php @@ -164,7 +164,7 @@ class phpbb_extension_finder_test extends phpbb_test_case public function test_get_classes_create_cache() { $cache = new phpbb_mock_cache; - $finder = new phpbb_extension_finder($this->extension_manager, new phpbb_filesystem(), dirname(__FILE__) . '/', $cache, '.php', '_custom_cache_name'); + $finder = new phpbb_extension_finder($this->extension_manager, new phpbb_filesystem(), dirname(__FILE__) . '/', $cache, 'php', '_custom_cache_name'); $files = $finder->suffix('_class.php')->get_files(); $expected_files = array( diff --git a/tests/extension/metadata_manager_test.php b/tests/extension/metadata_manager_test.php index df7817b479..05d1cbccc3 100644 --- a/tests/extension/metadata_manager_test.php +++ b/tests/extension/metadata_manager_test.php @@ -36,7 +36,7 @@ class metadata_manager_test extends phpbb_database_test_case $this->db = $this->new_dbal(); $this->db_tools = new phpbb_db_tools($this->db); $this->phpbb_root_path = dirname(__FILE__) . '/'; - $this->phpEx = '.php'; + $this->phpEx = 'php'; $this->user = new phpbb_user(); $this->table_prefix = 'phpbb_'; diff --git a/tests/mock/extension_manager.php b/tests/mock/extension_manager.php index 954f2bf1c4..10b3595206 100644 --- a/tests/mock/extension_manager.php +++ b/tests/mock/extension_manager.php @@ -12,7 +12,7 @@ class phpbb_mock_extension_manager extends phpbb_extension_manager public function __construct($phpbb_root_path, $extensions = array()) { $this->phpbb_root_path = $phpbb_root_path; - $this->php_ext = '.php'; + $this->php_ext = 'php'; $this->extensions = $extensions; $this->filesystem = new phpbb_filesystem(); } From e5d032ca2112ba2c6156718b3fe42128e444a6fd Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Wed, 24 Apr 2013 17:37:05 -0500 Subject: [PATCH 179/281] [ticket/11335] (more class loader) Make php_ext 'php' not '.php' PHPBB3-11335 --- phpBB/common.php | 4 ++-- phpBB/download/file.php | 4 ++-- phpBB/install/database_update.php | 2 +- phpBB/install/index.php | 4 ++-- tests/bootstrap.php | 6 +++--- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/phpBB/common.php b/phpBB/common.php index 6dd65739fc..3708b63bf9 100644 --- a/phpBB/common.php +++ b/phpBB/common.php @@ -85,9 +85,9 @@ require($phpbb_root_path . 'includes/utf/utf_tools.' . $phpEx); set_error_handler(defined('PHPBB_MSG_HANDLER') ? PHPBB_MSG_HANDLER : 'msg_handler'); // Setup class loader first -$phpbb_class_loader = new phpbb_class_loader('phpbb_', "{$phpbb_root_path}includes/", ".$phpEx"); +$phpbb_class_loader = new phpbb_class_loader('phpbb_', "{$phpbb_root_path}includes/", "$phpEx"); $phpbb_class_loader->register(); -$phpbb_class_loader_ext = new phpbb_class_loader('phpbb_ext_', "{$phpbb_root_path}ext/", ".$phpEx"); +$phpbb_class_loader_ext = new phpbb_class_loader('phpbb_ext_', "{$phpbb_root_path}ext/", "$phpEx"); $phpbb_class_loader_ext->register(); // Set up container diff --git a/phpBB/download/file.php b/phpBB/download/file.php index 91c05586a5..ac37737184 100644 --- a/phpBB/download/file.php +++ b/phpBB/download/file.php @@ -50,9 +50,9 @@ if (isset($_GET['avatar'])) require($phpbb_root_path . 'includes/utf/utf_tools.' . $phpEx); // Setup class loader first - $phpbb_class_loader = new phpbb_class_loader('phpbb_', "{$phpbb_root_path}includes/", ".$phpEx"); + $phpbb_class_loader = new phpbb_class_loader('phpbb_', "{$phpbb_root_path}includes/", "$phpEx"); $phpbb_class_loader->register(); - $phpbb_class_loader_ext = new phpbb_class_loader('phpbb_ext_', "{$phpbb_root_path}ext/", ".$phpEx"); + $phpbb_class_loader_ext = new phpbb_class_loader('phpbb_ext_', "{$phpbb_root_path}ext/", "$phpEx"); $phpbb_class_loader_ext->register(); // Set up container diff --git a/phpBB/install/database_update.php b/phpBB/install/database_update.php index 867235e607..c2b31b4ecd 100644 --- a/phpBB/install/database_update.php +++ b/phpBB/install/database_update.php @@ -95,7 +95,7 @@ require($phpbb_root_path . 'includes/utf/utf_tools.' . $phpEx); set_error_handler(defined('PHPBB_MSG_HANDLER') ? PHPBB_MSG_HANDLER : 'msg_handler'); // Setup class loader first -$phpbb_class_loader = new phpbb_class_loader('phpbb_', "{$phpbb_root_path}includes/", ".$phpEx"); +$phpbb_class_loader = new phpbb_class_loader('phpbb_', "{$phpbb_root_path}includes/", "$phpEx"); $phpbb_class_loader->register(); // Set up container (must be done here because extensions table may not exist) diff --git a/phpBB/install/index.php b/phpBB/install/index.php index a03fda6395..4009db4794 100644 --- a/phpBB/install/index.php +++ b/phpBB/install/index.php @@ -90,9 +90,9 @@ include($phpbb_root_path . 'includes/utf/utf_tools.' . $phpEx); require($phpbb_root_path . 'includes/functions_install.' . $phpEx); // Setup class loader first -$phpbb_class_loader = new phpbb_class_loader('phpbb_', "{$phpbb_root_path}includes/", ".$phpEx"); +$phpbb_class_loader = new phpbb_class_loader('phpbb_', "{$phpbb_root_path}includes/", "$phpEx"); $phpbb_class_loader->register(); -$phpbb_class_loader_ext = new phpbb_class_loader('phpbb_ext_', "{$phpbb_root_path}ext/", ".$phpEx"); +$phpbb_class_loader_ext = new phpbb_class_loader('phpbb_ext_', "{$phpbb_root_path}ext/", "$phpEx"); $phpbb_class_loader_ext->register(); // Set up container diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 1017e0c72f..a38740c82d 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -16,11 +16,11 @@ $table_prefix = 'phpbb_'; require_once $phpbb_root_path . 'includes/constants.php'; require_once $phpbb_root_path . 'includes/class_loader.' . $phpEx; -$phpbb_class_loader_mock = new phpbb_class_loader('phpbb_mock_', $phpbb_root_path . '../tests/mock/', ".php"); +$phpbb_class_loader_mock = new phpbb_class_loader('phpbb_mock_', $phpbb_root_path . '../tests/mock/', "php"); $phpbb_class_loader_mock->register(); -$phpbb_class_loader_ext = new phpbb_class_loader('phpbb_ext_', $phpbb_root_path . 'ext/', ".php"); +$phpbb_class_loader_ext = new phpbb_class_loader('phpbb_ext_', $phpbb_root_path . 'ext/', "php"); $phpbb_class_loader_ext->register(); -$phpbb_class_loader = new phpbb_class_loader('phpbb_', $phpbb_root_path . 'includes/', ".php"); +$phpbb_class_loader = new phpbb_class_loader('phpbb_', $phpbb_root_path . 'includes/', "php"); $phpbb_class_loader->register(); require_once 'test_framework/phpbb_test_case_helpers.php'; From c870b9f43be073a766e4380857415e011b5ed7ef Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Wed, 24 Apr 2013 17:37:25 -0500 Subject: [PATCH 180/281] [ticket/11335] (more tests) Make php_ext 'php' not '.php' PHPBB3-11335 --- tests/notification/submit_post_base.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/notification/submit_post_base.php b/tests/notification/submit_post_base.php index c5b2450e1c..953bedac80 100644 --- a/tests/notification/submit_post_base.php +++ b/tests/notification/submit_post_base.php @@ -92,12 +92,12 @@ class phpbb_notification_submit_post_base extends phpbb_database_test_case // Container $phpbb_container = new phpbb_mock_container_builder(); - $user_loader = new phpbb_user_loader($db, $phpbb_root_path, '.' . $phpEx, USERS_TABLE); + $user_loader = new phpbb_user_loader($db, $phpbb_root_path, $phpEx, USERS_TABLE); // Notification Manager $phpbb_notifications = new phpbb_notification_manager(array(), array(), $phpbb_container, $user_loader, $db, $user, - $phpbb_root_path, '.' . $phpEx, + $phpbb_root_path, $phpEx, NOTIFICATION_TYPES_TABLE, NOTIFICATIONS_TABLE, USER_NOTIFICATIONS_TABLE); $phpbb_container->set('notification_manager', $phpbb_notifications); @@ -108,7 +108,7 @@ class phpbb_notification_submit_post_base extends phpbb_database_test_case $class_name = 'phpbb_notification_type_' . $type; $phpbb_container->set('notification.type.' . $type, new $class_name( $user_loader, $db, $cache, $user, $auth, $config, - $phpbb_root_path, '.' . $phpEx, + $phpbb_root_path, $phpEx, NOTIFICATION_TYPES_TABLE, NOTIFICATIONS_TABLE, USER_NOTIFICATIONS_TABLE)); } } From f49993766e2bcf4efe346e29972f3721b1b1438a Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Wed, 24 Apr 2013 17:41:27 -0500 Subject: [PATCH 181/281] [ticket/11335] (more) Make php_ext 'php' not '.php' PHPBB3-11335 --- phpBB/includes/acp/acp_extensions.php | 2 +- tests/extension/manager_test.php | 2 +- tests/test_framework/phpbb_functional_test_case.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/phpBB/includes/acp/acp_extensions.php b/phpBB/includes/acp/acp_extensions.php index e4f8059b45..9b5a8da3aa 100644 --- a/phpBB/includes/acp/acp_extensions.php +++ b/phpBB/includes/acp/acp_extensions.php @@ -54,7 +54,7 @@ class acp_extensions // If they've specified an extension, let's load the metadata manager and validate it. if ($ext_name) { - $md_manager = new phpbb_extension_metadata_manager($ext_name, $db, $phpbb_extension_manager, $phpbb_root_path, ".$phpEx", $template, $config); + $md_manager = new phpbb_extension_metadata_manager($ext_name, $db, $phpbb_extension_manager, $phpbb_root_path, "$phpEx", $template, $config); try { diff --git a/tests/extension/manager_test.php b/tests/extension/manager_test.php index d6bcb97586..106f078691 100644 --- a/tests/extension/manager_test.php +++ b/tests/extension/manager_test.php @@ -115,7 +115,7 @@ class phpbb_extension_manager_test extends phpbb_database_test_case new phpbb_filesystem(), 'phpbb_ext', dirname(__FILE__) . '/', - '.' . $php_ext, + $php_ext, ($with_cache) ? new phpbb_mock_cache() : null ); } diff --git a/tests/test_framework/phpbb_functional_test_case.php b/tests/test_framework/phpbb_functional_test_case.php index b9647e4742..5534de89c9 100644 --- a/tests/test_framework/phpbb_functional_test_case.php +++ b/tests/test_framework/phpbb_functional_test_case.php @@ -156,7 +156,7 @@ class phpbb_functional_test_case extends phpbb_test_case new phpbb_filesystem(), self::$config['table_prefix'] . 'ext', dirname(__FILE__) . '/', - '.' . $php_ext, + $php_ext, $this->get_cache_driver() ); From 0d2d72e8ee5cca9e6bc9048cfa1c3ad81ef51949 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Wed, 24 Apr 2013 20:28:35 -0500 Subject: [PATCH 182/281] [ticket/11454] Check if the fields are set PHPBB3-11454 --- phpBB/includes/functions_messenger.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/phpBB/includes/functions_messenger.php b/phpBB/includes/functions_messenger.php index 5c0c182f4f..f24a4c1eac 100644 --- a/phpBB/includes/functions_messenger.php +++ b/phpBB/includes/functions_messenger.php @@ -63,14 +63,14 @@ class messenger */ function set_addresses($user) { - if ($user['user_email']) + if (isset($user['user_email']) && $user['user_email']) { - $this->to($user['user_email'], ($user['username']) ?: ''); + $this->to($user['user_email'], (isset($user['username']) ? $user['username'] : '')); } - if ($user['user_jabber']) + if (isset($user['user_jabber']) && $user['user_jabber']) { - $this->im($user['user_jabber'], ($user['username']) ?: ''); + $this->im($user['user_jabber'], (isset($user['username']) ? $user['username'] : '')); } } From 9c4553c41f0e0f2c28fb95b5e56886f77cb759ba Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Wed, 24 Apr 2013 20:39:24 -0500 Subject: [PATCH 183/281] [ticket/11335] Replace "$phpEx" with $phpEx PHPBB3-11335 --- phpBB/common.php | 4 ++-- phpBB/download/file.php | 4 ++-- phpBB/includes/acp/acp_extensions.php | 2 +- phpBB/install/database_update.php | 2 +- phpBB/install/index.php | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/phpBB/common.php b/phpBB/common.php index 3708b63bf9..f6f109c3de 100644 --- a/phpBB/common.php +++ b/phpBB/common.php @@ -85,9 +85,9 @@ require($phpbb_root_path . 'includes/utf/utf_tools.' . $phpEx); set_error_handler(defined('PHPBB_MSG_HANDLER') ? PHPBB_MSG_HANDLER : 'msg_handler'); // Setup class loader first -$phpbb_class_loader = new phpbb_class_loader('phpbb_', "{$phpbb_root_path}includes/", "$phpEx"); +$phpbb_class_loader = new phpbb_class_loader('phpbb_', "{$phpbb_root_path}includes/", $phpEx); $phpbb_class_loader->register(); -$phpbb_class_loader_ext = new phpbb_class_loader('phpbb_ext_', "{$phpbb_root_path}ext/", "$phpEx"); +$phpbb_class_loader_ext = new phpbb_class_loader('phpbb_ext_', "{$phpbb_root_path}ext/", $phpEx); $phpbb_class_loader_ext->register(); // Set up container diff --git a/phpBB/download/file.php b/phpBB/download/file.php index ac37737184..eee2090da0 100644 --- a/phpBB/download/file.php +++ b/phpBB/download/file.php @@ -50,9 +50,9 @@ if (isset($_GET['avatar'])) require($phpbb_root_path . 'includes/utf/utf_tools.' . $phpEx); // Setup class loader first - $phpbb_class_loader = new phpbb_class_loader('phpbb_', "{$phpbb_root_path}includes/", "$phpEx"); + $phpbb_class_loader = new phpbb_class_loader('phpbb_', "{$phpbb_root_path}includes/", $phpEx); $phpbb_class_loader->register(); - $phpbb_class_loader_ext = new phpbb_class_loader('phpbb_ext_', "{$phpbb_root_path}ext/", "$phpEx"); + $phpbb_class_loader_ext = new phpbb_class_loader('phpbb_ext_', "{$phpbb_root_path}ext/", $phpEx); $phpbb_class_loader_ext->register(); // Set up container diff --git a/phpBB/includes/acp/acp_extensions.php b/phpBB/includes/acp/acp_extensions.php index 9b5a8da3aa..e4defa0400 100644 --- a/phpBB/includes/acp/acp_extensions.php +++ b/phpBB/includes/acp/acp_extensions.php @@ -54,7 +54,7 @@ class acp_extensions // If they've specified an extension, let's load the metadata manager and validate it. if ($ext_name) { - $md_manager = new phpbb_extension_metadata_manager($ext_name, $db, $phpbb_extension_manager, $phpbb_root_path, "$phpEx", $template, $config); + $md_manager = new phpbb_extension_metadata_manager($ext_name, $db, $phpbb_extension_manager, $phpbb_root_path, $phpEx, $template, $config); try { diff --git a/phpBB/install/database_update.php b/phpBB/install/database_update.php index c2b31b4ecd..5ea950bfad 100644 --- a/phpBB/install/database_update.php +++ b/phpBB/install/database_update.php @@ -95,7 +95,7 @@ require($phpbb_root_path . 'includes/utf/utf_tools.' . $phpEx); set_error_handler(defined('PHPBB_MSG_HANDLER') ? PHPBB_MSG_HANDLER : 'msg_handler'); // Setup class loader first -$phpbb_class_loader = new phpbb_class_loader('phpbb_', "{$phpbb_root_path}includes/", "$phpEx"); +$phpbb_class_loader = new phpbb_class_loader('phpbb_', "{$phpbb_root_path}includes/", $phpEx); $phpbb_class_loader->register(); // Set up container (must be done here because extensions table may not exist) diff --git a/phpBB/install/index.php b/phpBB/install/index.php index 4009db4794..57bcdaffc1 100644 --- a/phpBB/install/index.php +++ b/phpBB/install/index.php @@ -90,9 +90,9 @@ include($phpbb_root_path . 'includes/utf/utf_tools.' . $phpEx); require($phpbb_root_path . 'includes/functions_install.' . $phpEx); // Setup class loader first -$phpbb_class_loader = new phpbb_class_loader('phpbb_', "{$phpbb_root_path}includes/", "$phpEx"); +$phpbb_class_loader = new phpbb_class_loader('phpbb_', "{$phpbb_root_path}includes/", $phpEx); $phpbb_class_loader->register(); -$phpbb_class_loader_ext = new phpbb_class_loader('phpbb_ext_', "{$phpbb_root_path}ext/", "$phpEx"); +$phpbb_class_loader_ext = new phpbb_class_loader('phpbb_ext_', "{$phpbb_root_path}ext/", $phpEx); $phpbb_class_loader_ext->register(); // Set up container From e8b192fa32a4e7bba6d772075eb430424d0c4750 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 25 Apr 2013 12:57:21 +0200 Subject: [PATCH 184/281] [ticket/11495] Do not compare to null anymore (left over from item class) PHPBB3-11495 --- phpBB/includes/nestedset/base.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/phpBB/includes/nestedset/base.php b/phpBB/includes/nestedset/base.php index f3bdfe1c7d..9f83bd757c 100644 --- a/phpBB/includes/nestedset/base.php +++ b/phpBB/includes/nestedset/base.php @@ -194,14 +194,14 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface $result = $this->db->sql_query_limit($sql, $delta); - $target = null; + $target = false; while ($row = $this->db->sql_fetchrow($result)) { $target = $row; } $this->db->sql_freeresult($result); - if (is_null($target)) + if (!$target) { $this->lock->release(); // The item is already on top or bottom From 61e72d3a1000c48146466305c6693595324f5282 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 25 Apr 2013 13:09:00 +0200 Subject: [PATCH 185/281] [ticket/11495] Explain move() more An item is only moved up/down within the same parent. If the delta is larger then the number of children, the item is moved to the top/bottom of the list of children within this parent. PHPBB3-11495 --- phpBB/includes/nestedset/interface.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/phpBB/includes/nestedset/interface.php b/phpBB/includes/nestedset/interface.php index aedd57821a..b8a2e4b239 100644 --- a/phpBB/includes/nestedset/interface.php +++ b/phpBB/includes/nestedset/interface.php @@ -56,6 +56,10 @@ interface phpbb_nestedset_interface /** * Move an item by a given delta * + * An item is only moved up/down within the same parent. If the delta is + * larger then the number of children, the item is moved to the top/bottom + * of the list of children within this parent. + * * @param int $item_id The item to be moved * @param int $delta Number of steps to move this item, < 0 => down, > 0 => up * @return bool True if the item was moved From 4bff28a0eeaf44eae9e99725ead6ff2cf770b857 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 25 Apr 2013 13:40:25 +0200 Subject: [PATCH 186/281] [ticket/11495] Rename fix function to regenerate_left_right_ids() This method regenerates the left/right ids for the nested set based on the parent/child relations. This function executes three queries per item, so it should only be called, when the set has one of the following problems: - The set has a duplicated value inside the left/right id chain - The set has a missing value inside the left/right id chain - The set has items that do not have a left/right is set When regenerating the items, the items are sorted by parent id and their current left id, so the current child/parent relationships are kept and running the function on a working set will not change any orders. PHPBB3-11495 --- phpBB/includes/nestedset/base.php | 4 ++-- phpBB/includes/nestedset/interface.php | 16 ++++++++++++++-- ...te_test.php => set_forum_regenerate_test.php} | 10 +++++----- 3 files changed, 21 insertions(+), 9 deletions(-) rename tests/nestedset/{set_forum_recalculate_test.php => set_forum_regenerate_test.php} (86%) diff --git a/phpBB/includes/nestedset/base.php b/phpBB/includes/nestedset/base.php index 9f83bd757c..1a6b578e79 100644 --- a/phpBB/includes/nestedset/base.php +++ b/phpBB/includes/nestedset/base.php @@ -674,7 +674,7 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface /** * @inheritdoc */ - public function recalculate_nested_set($new_id, $parent_id = 0, $reset_ids = false) + public function regenerate_left_right_ids($new_id, $parent_id = 0, $reset_ids = false) { if ($reset_ids) { @@ -716,7 +716,7 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface $new_id++; // Then we go through any children and update their left/right id's - $new_id = $this->recalculate_nested_set($new_id, $row[$this->column_item_id]); + $new_id = $this->regenerate_left_right_ids($new_id, $row[$this->column_item_id]); // Then we come back and update the right_id for this module if ($row[$this->column_right_id] != $new_id) diff --git a/phpBB/includes/nestedset/interface.php b/phpBB/includes/nestedset/interface.php index b8a2e4b239..9948ccf019 100644 --- a/phpBB/includes/nestedset/interface.php +++ b/phpBB/includes/nestedset/interface.php @@ -124,12 +124,24 @@ interface phpbb_nestedset_interface public function get_parent_data(array $item); /** - * Recalculate Nested Sets + * Regenerate left/right ids from parent/child relationship + * + * This method regenerates the left/right ids for the nested set based on + * the parent/child relations. This function executes three queries per + * item, so it should only be called, when the set has one of the following + * problems: + * - The set has a duplicated value inside the left/right id chain + * - The set has a missing value inside the left/right id chain + * - The set has items that do not have a left/right is set + * + * When regenerating the items, the items are sorted by parent id and their + * current left id, so the current child/parent relationships are kept + * and running the function on a working set will not change any orders. * * @param int $new_id First left_id to be used (should start with 1) * @param int $parent_id parent_id of the current set (default = 0) * @param bool $reset_ids Should we reset all left_id/right_id on the first call? * @return int $new_id The next left_id/right_id that should be used */ - public function recalculate_nested_set($new_id, $parent_id = 0, $reset_ids = false); + public function regenerate_left_right_ids($new_id, $parent_id = 0, $reset_ids = false); } diff --git a/tests/nestedset/set_forum_recalculate_test.php b/tests/nestedset/set_forum_regenerate_test.php similarity index 86% rename from tests/nestedset/set_forum_recalculate_test.php rename to tests/nestedset/set_forum_regenerate_test.php index 6ff7a372a4..0e3a2123a0 100644 --- a/tests/nestedset/set_forum_recalculate_test.php +++ b/tests/nestedset/set_forum_regenerate_test.php @@ -9,7 +9,7 @@ require_once dirname(__FILE__) . '/set_forum_base.php'; -class phpbb_tests_nestedset_set_forum_recalculate_test extends phpbb_tests_nestedset_set_forum_base +class phpbb_tests_nestedset_set_forum_regenerate_test extends phpbb_tests_nestedset_set_forum_base { protected $fixed_set = array( array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => ''), @@ -27,7 +27,7 @@ class phpbb_tests_nestedset_set_forum_recalculate_test extends phpbb_tests_neste array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => ''), ); - public function recalculate_nested_set_data() + public function regenerate_left_right_ids_data() { return array( array('UPDATE phpbb_forums @@ -56,13 +56,13 @@ class phpbb_tests_nestedset_set_forum_recalculate_test extends phpbb_tests_neste } /** - * @dataProvider recalculate_nested_set_data + * @dataProvider regenerate_left_right_ids_data */ - public function test_recalculate_nested_set($breaking_query, $reset_ids) + public function test_regenerate_left_right_ids($breaking_query, $reset_ids) { $result = $this->db->sql_query($breaking_query); - $this->assertEquals(23, $this->set->recalculate_nested_set(1, 0, $reset_ids)); + $this->assertEquals(23, $this->set->regenerate_left_right_ids(1, 0, $reset_ids)); $result = $this->db->sql_query('SELECT forum_id, parent_id, left_id, right_id, forum_parents FROM phpbb_forums From 3efae6d8af6dfe22c0790d3004fdbf20eb16a292 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 25 Apr 2013 13:44:52 +0200 Subject: [PATCH 187/281] [ticket/11495] Explain whether move_children prepends/appends/overwrittes PHPBB3-11495 --- phpBB/includes/nestedset/interface.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/phpBB/includes/nestedset/interface.php b/phpBB/includes/nestedset/interface.php index 9948ccf019..9a8f9c4eea 100644 --- a/phpBB/includes/nestedset/interface.php +++ b/phpBB/includes/nestedset/interface.php @@ -85,6 +85,9 @@ interface phpbb_nestedset_interface /** * Moves all children of one item to another item * + * If the new parent already has children, the new children are appended + * to the list. + * * @param int $current_parent_id The current parent item * @param int $new_parent_id The new parent item * @return bool True if any items where moved From ab7054445fbf397ae5bf4c13eb44a2019d71cc2d Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 25 Apr 2013 13:48:19 +0200 Subject: [PATCH 188/281] [ticket/11495] Rename set_parent to change_parent() PHPBB3-11495 --- phpBB/includes/nestedset/base.php | 2 +- phpBB/includes/nestedset/interface.php | 6 ++++-- tests/nestedset/set_forum_move_test.php | 24 ++++++++++++------------ 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/phpBB/includes/nestedset/base.php b/phpBB/includes/nestedset/base.php index 1a6b578e79..3817a6d217 100644 --- a/phpBB/includes/nestedset/base.php +++ b/phpBB/includes/nestedset/base.php @@ -388,7 +388,7 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface /** * @inheritdoc */ - public function set_parent($item_id, $new_parent_id) + public function change_parent($item_id, $new_parent_id) { $item_id = (int) $item_id; $new_parent_id = (int) $new_parent_id; diff --git a/phpBB/includes/nestedset/interface.php b/phpBB/includes/nestedset/interface.php index 9a8f9c4eea..a2dbc55c7d 100644 --- a/phpBB/includes/nestedset/interface.php +++ b/phpBB/includes/nestedset/interface.php @@ -95,13 +95,15 @@ interface phpbb_nestedset_interface public function move_children($current_parent_id, $new_parent_id); /** - * Set the parent item + * Change parent item + * + * Moves the item to the bottom of the new parent's list of children * * @param int $item_id The item to be moved * @param int $new_parent_id The new parent item * @return bool True if the parent was set successfully */ - public function set_parent($item, $new_parent_id); + public function change_parent($item, $new_parent_id); /** * Get branch of the item diff --git a/tests/nestedset/set_forum_move_test.php b/tests/nestedset/set_forum_move_test.php index 9a19d18476..166fe666f2 100644 --- a/tests/nestedset/set_forum_move_test.php +++ b/tests/nestedset/set_forum_move_test.php @@ -411,7 +411,7 @@ class phpbb_tests_nestedset_set_forum_move_test extends phpbb_tests_nestedset_se $this->set->move_children($forum_id, $target_id); } - public function set_parent_data() + public function change_parent_data() { return array( array('Move single child up', @@ -516,11 +516,11 @@ class phpbb_tests_nestedset_set_forum_move_test extends phpbb_tests_nestedset_se } /** - * @dataProvider set_parent_data + * @dataProvider change_parent_data */ - public function test_set_parent($explain, $forum_id, $target_id, $expected_moved, $expected) + public function test_change_parent($explain, $forum_id, $target_id, $expected_moved, $expected) { - $this->assertEquals($expected_moved, $this->set->set_parent($forum_id, $target_id)); + $this->assertEquals($expected_moved, $this->set->change_parent($forum_id, $target_id)); $result = $this->db->sql_query("SELECT forum_id, parent_id, left_id, right_id, forum_parents FROM phpbb_forums @@ -528,7 +528,7 @@ class phpbb_tests_nestedset_set_forum_move_test extends phpbb_tests_nestedset_se $this->assertEquals($expected, $this->db->sql_fetchrowset($result)); } - public function set_parent_throws_item_data() + public function change_parent_throws_item_data() { return array( array('Item 0 does not exist', 0, 5), @@ -537,17 +537,17 @@ class phpbb_tests_nestedset_set_forum_move_test extends phpbb_tests_nestedset_se } /** - * @dataProvider set_parent_throws_item_data + * @dataProvider change_parent_throws_item_data * * @expectedException phpbb_nestedset_exception * @expectedExceptionMessage FORUM_NESTEDSET_INVALID_ITEM */ - public function test_set_parent_throws_item($explain, $forum_id, $target_id) + public function test_change_parent_throws_item($explain, $forum_id, $target_id) { - $this->set->set_parent($forum_id, $target_id); + $this->set->change_parent($forum_id, $target_id); } - public function set_parent_throws_parent_data() + public function change_parent_throws_parent_data() { return array( array('New parent is child', 4, 5), @@ -557,13 +557,13 @@ class phpbb_tests_nestedset_set_forum_move_test extends phpbb_tests_nestedset_se } /** - * @dataProvider set_parent_throws_parent_data + * @dataProvider change_parent_throws_parent_data * * @expectedException phpbb_nestedset_exception * @expectedExceptionMessage FORUM_NESTEDSET_INVALID_PARENT */ - public function test_set_parent_throws_parent($explain, $forum_id, $target_id) + public function test_change_parent_throws_parent($explain, $forum_id, $target_id) { - $this->set->set_parent($forum_id, $target_id); + $this->set->change_parent($forum_id, $target_id); } } From fe97915fc91e4fbfb211e3eb6038dd1b482553dd Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 25 Apr 2013 14:05:41 +0200 Subject: [PATCH 189/281] [ticket/11495] Split get_branch_data into multiple methods PHPBB3-11495 --- phpBB/includes/nestedset/base.php | 56 +++++++--- phpBB/includes/nestedset/interface.php | 31 ++++- tests/nestedset/set_forum_get_data_test.php | 118 ++++++++++++-------- 3 files changed, 136 insertions(+), 69 deletions(-) diff --git a/phpBB/includes/nestedset/base.php b/phpBB/includes/nestedset/base.php index 3817a6d217..fe6318304d 100644 --- a/phpBB/includes/nestedset/base.php +++ b/phpBB/includes/nestedset/base.php @@ -115,7 +115,7 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface */ public function remove($item_id) { - $items = $this->get_branch_data($item_id, 'children'); + $items = $this->get_children_branch_data($item_id); $item_ids = array_keys($items); $this->remove_subset($item_ids, $items[$item_id]); @@ -299,7 +299,7 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface throw new phpbb_nestedset_exception($this->message_prefix . 'LOCK_FAILED_ACQUIRE'); } - $item_data = $this->get_branch_data($current_parent_id, 'children'); + $item_data = $this->get_children_branch_data($current_parent_id); if (!isset($item_data[$current_parent_id])) { $this->lock->release(); @@ -408,7 +408,7 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface throw new phpbb_nestedset_exception($this->message_prefix . 'LOCK_FAILED_ACQUIRE'); } - $item_data = $this->get_branch_data($item_id, 'children'); + $item_data = $this->get_children_branch_data($item_id); if (!isset($item_data[$item_id])) { $this->lock->release(); @@ -490,24 +490,46 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface /** * @inheritdoc */ - public function get_branch_data($item_id, $type = 'all', $order_desc = true, $include_item = true) + public function get_full_branch_data($item_id, $order_desc = true, $include_item = true) { - switch ($type) - { - case 'parents': - $condition = 'i1.' . $this->column_left_id . ' BETWEEN i2.' . $this->column_left_id . ' AND i2.' . $this->column_right_id . ''; - break; + $condition = 'i2.' . $this->column_left_id . ' BETWEEN i1.' . $this->column_left_id . ' AND i1.' . $this->column_right_id . ' + OR i1.' . $this->column_left_id . ' BETWEEN i2.' . $this->column_left_id . ' AND i2.' . $this->column_right_id; - case 'children': - $condition = 'i2.' . $this->column_left_id . ' BETWEEN i1.' . $this->column_left_id . ' AND i1.' . $this->column_right_id . ''; - break; + return $this->get_branch_data($item_id, $condition, $order_desc, $include_item); + } - default: - $condition = 'i2.' . $this->column_left_id . ' BETWEEN i1.' . $this->column_left_id . ' AND i1.' . $this->column_right_id . ' - OR i1.' . $this->column_left_id . ' BETWEEN i2.' . $this->column_left_id . ' AND i2.' . $this->column_right_id; - break; - } + /** + * @inheritdoc + */ + public function get_parent_branch_data($item_id, $order_desc = true, $include_item = true) + { + $condition = 'i1.' . $this->column_left_id . ' BETWEEN i2.' . $this->column_left_id . ' AND i2.' . $this->column_right_id . ''; + return $this->get_branch_data($item_id, $condition, $order_desc, $include_item); + } + + /** + * @inheritdoc + */ + public function get_children_branch_data($item_id, $order_desc = true, $include_item = true) + { + $condition = 'i2.' . $this->column_left_id . ' BETWEEN i1.' . $this->column_left_id . ' AND i1.' . $this->column_right_id . ''; + + return $this->get_branch_data($item_id, $condition, $order_desc, $include_item); + } + + /** + * Get children and parent branch of the item + * + * @param int $item_id The item id to get the parents/children from + * @param string $condition Query string restricting the item list + * @param bool $order_desc Order the items descending (most outer parent first) + * @param bool $include_item Should the given item be included in the list aswell + * @return array Array of items (containing all columns from the item table) + * ID => Item data + */ + protected function get_branch_data($item_id, $condition, $order_desc = true, $include_item = true) + { $rows = array(); $sql = 'SELECT i2.* diff --git a/phpBB/includes/nestedset/interface.php b/phpBB/includes/nestedset/interface.php index a2dbc55c7d..ee78016425 100644 --- a/phpBB/includes/nestedset/interface.php +++ b/phpBB/includes/nestedset/interface.php @@ -106,18 +106,37 @@ interface phpbb_nestedset_interface public function change_parent($item, $new_parent_id); /** - * Get branch of the item + * Get children and parent branch of the item * - * This method can return all parents, children or both of the given item - * - * @param int $item_id The item id to get the parents from - * @param string $type One of all|parent|children + * @param int $item_id The item id to get the parents/children from * @param bool $order_desc Order the items descending (most outer parent first) * @param bool $include_item Should the given item be included in the list aswell * @return array Array of items (containing all columns from the item table) * ID => Item data */ - public function get_branch_data($item_id, $type, $order_desc, $include_item); + public function get_full_branch_data($item_id, $order_desc, $include_item); + + /** + * Get parent branch of the item + * + * @param int $item_id The item id to get the parents from + * @param bool $order_desc Order the items descending (most outer parent first) + * @param bool $include_item Should the given item be included in the list aswell + * @return array Array of items (containing all columns from the item table) + * ID => Item data + */ + public function get_parent_branch_data($item_id, $order_desc, $include_item); + + /** + * Get children branch of the item + * + * @param int $item_id The item id to get the children from + * @param bool $order_desc Order the items descending (most outer parent first) + * @param bool $include_item Should the given item be included in the list aswell + * @return array Array of items (containing all columns from the item table) + * ID => Item data + */ + public function get_children_branch_data($item_id, $order_desc, $include_item); /** * Get base information of parent items diff --git a/tests/nestedset/set_forum_get_data_test.php b/tests/nestedset/set_forum_get_data_test.php index 2c8889d1a5..a0e255b9b8 100644 --- a/tests/nestedset/set_forum_get_data_test.php +++ b/tests/nestedset/set_forum_get_data_test.php @@ -11,62 +11,88 @@ require_once dirname(__FILE__) . '/set_forum_base.php'; class phpbb_tests_nestedset_set_forum_get_data_test extends phpbb_tests_nestedset_set_forum_base { - public function get_branch_data_data() + public function get_full_branch_data_data() { return array( - array(1, 'all', true, true, array(1, 2, 3)), - array(1, 'all', true, false, array(2, 3)), - array(1, 'all', false, true, array(3, 2, 1)), - array(1, 'all', false, false, array(3, 2)), + array(1, true, true, array(1, 2, 3)), + array(1, true, false, array(2, 3)), + array(1, false, true, array(3, 2, 1)), + array(1, false, false, array(3, 2)), - array(1, 'parents', true, true, array(1)), - array(1, 'parents', true, false, array()), - array(1, 'parents', false, true, array(1)), - array(1, 'parents', false, false, array()), + array(2, true, true, array(1, 2)), + array(2, true, false, array(1)), + array(2, false, true, array(2, 1)), + array(2, false, false, array(1)), - array(1, 'children', true, true, array(1, 2, 3)), - array(1, 'children', true, false, array(2, 3)), - array(1, 'children', false, true, array(3, 2, 1)), - array(1, 'children', false, false, array(3, 2)), - - array(2, 'all', true, true, array(1, 2)), - array(2, 'all', true, false, array(1)), - array(2, 'all', false, true, array(2, 1)), - array(2, 'all', false, false, array(1)), - - array(2, 'parents', true, true, array(1, 2)), - array(2, 'parents', true, false, array(1)), - array(2, 'parents', false, true, array(2, 1)), - array(2, 'parents', false, false, array(1)), - - array(2, 'children', true, true, array(2)), - array(2, 'children', true, false, array()), - array(2, 'children', false, true, array(2)), - array(2, 'children', false, false, array()), - - array(5, 'all', true, true, array(4, 5, 6)), - array(5, 'all', true, false, array(4, 6)), - array(5, 'all', false, true, array(6, 5, 4)), - array(5, 'all', false, false, array(6, 4)), - - array(5, 'parents', true, true, array(4, 5)), - array(5, 'parents', true, false, array(4)), - array(5, 'parents', false, true, array(5, 4)), - array(5, 'parents', false, false, array(4)), - - array(5, 'children', true, true, array(5, 6)), - array(5, 'children', true, false, array(6)), - array(5, 'children', false, true, array(6, 5)), - array(5, 'children', false, false, array(6)), + array(5, true, true, array(4, 5, 6)), + array(5, true, false, array(4, 6)), + array(5, false, true, array(6, 5, 4)), + array(5, false, false, array(6, 4)), ); } /** - * @dataProvider get_branch_data_data + * @dataProvider get_full_branch_data_data */ - public function test_get_branch_data($forum_id, $type, $order_desc, $include_item, $expected) + public function test_get_full_branch_data($forum_id, $order_desc, $include_item, $expected) { - $this->assertEquals($expected, array_keys($this->set->get_branch_data($forum_id, $type, $order_desc, $include_item))); + $this->assertEquals($expected, array_keys($this->set->get_full_branch_data($forum_id, $order_desc, $include_item))); + } + + public function get_parent_branch_data_data() + { + return array( + array(1, true, true, array(1)), + array(1, true, false, array()), + array(1, false, true, array(1)), + array(1, false, false, array()), + + array(2, true, true, array(1, 2)), + array(2, true, false, array(1)), + array(2, false, true, array(2, 1)), + array(2, false, false, array(1)), + + array(5, true, true, array(4, 5)), + array(5, true, false, array(4)), + array(5, false, true, array(5, 4)), + array(5, false, false, array(4)), + ); + } + + /** + * @dataProvider get_parent_branch_data_data + */ + public function test_get_parent_branch_data($forum_id, $order_desc, $include_item, $expected) + { + $this->assertEquals($expected, array_keys($this->set->get_parent_branch_data($forum_id, $order_desc, $include_item))); + } + + public function get_children_branch_data_data() + { + return array( + array(1, true, true, array(1, 2, 3)), + array(1, true, false, array(2, 3)), + array(1, false, true, array(3, 2, 1)), + array(1, false, false, array(3, 2)), + + array(2, true, true, array(2)), + array(2, true, false, array()), + array(2, false, true, array(2)), + array(2, false, false, array()), + + array(5, true, true, array(5, 6)), + array(5, true, false, array(6)), + array(5, false, true, array(6, 5)), + array(5, false, false, array(6)), + ); + } + + /** + * @dataProvider get_children_branch_data_data + */ + public function test_get_children_branch_data($forum_id, $order_desc, $include_item, $expected) + { + $this->assertEquals($expected, array_keys($this->set->get_children_branch_data($forum_id, $order_desc, $include_item))); } public function get_parent_data_data() From 9d7d962c0db3425e9448eb07649c6709664a56bd Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 25 Apr 2013 14:08:06 +0200 Subject: [PATCH 190/281] [ticket/11495] Explain what "given item" means PHPBB3-11495 --- phpBB/includes/nestedset/base.php | 2 +- phpBB/includes/nestedset/interface.php | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/phpBB/includes/nestedset/base.php b/phpBB/includes/nestedset/base.php index fe6318304d..328621a68d 100644 --- a/phpBB/includes/nestedset/base.php +++ b/phpBB/includes/nestedset/base.php @@ -524,7 +524,7 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface * @param int $item_id The item id to get the parents/children from * @param string $condition Query string restricting the item list * @param bool $order_desc Order the items descending (most outer parent first) - * @param bool $include_item Should the given item be included in the list aswell + * @param bool $include_item Should the item (matching the given item id) be included in the list aswell * @return array Array of items (containing all columns from the item table) * ID => Item data */ diff --git a/phpBB/includes/nestedset/interface.php b/phpBB/includes/nestedset/interface.php index ee78016425..eadc9083b1 100644 --- a/phpBB/includes/nestedset/interface.php +++ b/phpBB/includes/nestedset/interface.php @@ -110,7 +110,7 @@ interface phpbb_nestedset_interface * * @param int $item_id The item id to get the parents/children from * @param bool $order_desc Order the items descending (most outer parent first) - * @param bool $include_item Should the given item be included in the list aswell + * @param bool $include_item Should the item (matching the given item id) be included in the list aswell * @return array Array of items (containing all columns from the item table) * ID => Item data */ @@ -121,7 +121,7 @@ interface phpbb_nestedset_interface * * @param int $item_id The item id to get the parents from * @param bool $order_desc Order the items descending (most outer parent first) - * @param bool $include_item Should the given item be included in the list aswell + * @param bool $include_item Should the item (matching the given item id) be included in the list aswell * @return array Array of items (containing all columns from the item table) * ID => Item data */ @@ -132,7 +132,7 @@ interface phpbb_nestedset_interface * * @param int $item_id The item id to get the children from * @param bool $order_desc Order the items descending (most outer parent first) - * @param bool $include_item Should the given item be included in the list aswell + * @param bool $include_item Should the item (matching the given item id) be included in the list aswell * @return array Array of items (containing all columns from the item table) * ID => Item data */ From 804f139be0534691fc1c8f6ddaf7ebc68a7d0a1c Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 25 Apr 2013 16:17:58 +0200 Subject: [PATCH 191/281] [ticket/11495] Use default exceptions PHPBB3-11495 --- phpBB/includes/nestedset/base.php | 28 ++++++++++++------------- phpBB/includes/nestedset/exception.php | 20 ------------------ tests/nestedset/set_forum_move_test.php | 8 +++---- 3 files changed, 18 insertions(+), 38 deletions(-) delete mode 100644 phpBB/includes/nestedset/exception.php diff --git a/phpBB/includes/nestedset/base.php b/phpBB/includes/nestedset/base.php index 328621a68d..da6c056313 100644 --- a/phpBB/includes/nestedset/base.php +++ b/phpBB/includes/nestedset/base.php @@ -150,7 +150,7 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface if (!$this->lock->acquire()) { - throw new phpbb_nestedset_exception($this->message_prefix . 'LOCK_FAILED_ACQUIRE'); + throw new RuntimeException($this->message_prefix . 'LOCK_FAILED_ACQUIRE'); } $action = ($delta > 0) ? 'move_up' : 'move_down'; @@ -168,7 +168,7 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface if (!$item) { $this->lock->release(); - throw new phpbb_nestedset_exception($this->message_prefix . 'INVALID_ITEM'); + throw new OutOfBoundsException($this->message_prefix . 'INVALID_ITEM'); } /** @@ -291,19 +291,19 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface if (!$current_parent_id) { - throw new phpbb_nestedset_exception($this->message_prefix . 'INVALID_ITEM'); + throw new OutOfBoundsException($this->message_prefix . 'INVALID_ITEM'); } if (!$this->lock->acquire()) { - throw new phpbb_nestedset_exception($this->message_prefix . 'LOCK_FAILED_ACQUIRE'); + throw new RuntimeException($this->message_prefix . 'LOCK_FAILED_ACQUIRE'); } $item_data = $this->get_children_branch_data($current_parent_id); if (!isset($item_data[$current_parent_id])) { $this->lock->release(); - throw new phpbb_nestedset_exception($this->message_prefix . 'INVALID_ITEM'); + throw new OutOfBoundsException($this->message_prefix . 'INVALID_ITEM'); } $current_parent = $item_data[$current_parent_id]; @@ -319,7 +319,7 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface if (in_array($new_parent_id, $move_items)) { $this->lock->release(); - throw new phpbb_nestedset_exception($this->message_prefix . 'INVALID_PARENT'); + throw new OutOfBoundsException($this->message_prefix . 'INVALID_PARENT'); } $diff = sizeof($move_items) * 2; @@ -343,7 +343,7 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface { $this->db->sql_transaction('rollback'); $this->lock->release(); - throw new phpbb_nestedset_exception($this->message_prefix . 'INVALID_PARENT'); + throw new OutOfBoundsException($this->message_prefix . 'INVALID_PARENT'); } $new_right_id = $this->prepare_adding_subset($move_items, $new_parent, true); @@ -400,19 +400,19 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface if (!$item_id) { - throw new phpbb_nestedset_exception($this->message_prefix . 'INVALID_ITEM'); + throw new OutOfBoundsException($this->message_prefix . 'INVALID_ITEM'); } if (!$this->lock->acquire()) { - throw new phpbb_nestedset_exception($this->message_prefix . 'LOCK_FAILED_ACQUIRE'); + throw new RuntimeException($this->message_prefix . 'LOCK_FAILED_ACQUIRE'); } $item_data = $this->get_children_branch_data($item_id); if (!isset($item_data[$item_id])) { $this->lock->release(); - throw new phpbb_nestedset_exception($this->message_prefix . 'INVALID_ITEM'); + throw new OutOfBoundsException($this->message_prefix . 'INVALID_ITEM'); } $item = $item_data[$item_id]; @@ -421,7 +421,7 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface if (in_array($new_parent_id, $move_items)) { $this->lock->release(); - throw new phpbb_nestedset_exception($this->message_prefix . 'INVALID_PARENT'); + throw new OutOfBoundsException($this->message_prefix . 'INVALID_PARENT'); } $diff = sizeof($move_items) * 2; @@ -445,7 +445,7 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface { $this->db->sql_transaction('rollback'); $this->lock->release(); - throw new phpbb_nestedset_exception($this->message_prefix . 'INVALID_PARENT'); + throw new OutOfBoundsException($this->message_prefix . 'INVALID_PARENT'); } $new_right_id = $this->prepare_adding_subset($move_items, $new_parent, true); @@ -612,7 +612,7 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface { if (!$table_already_locked && !$this->lock->acquire()) { - throw new phpbb_nestedset_exception($this->message_prefix . 'LOCK_FAILED_ACQUIRE'); + throw new RuntimeException($this->message_prefix . 'LOCK_FAILED_ACQUIRE'); } $diff = sizeof($subset_items) * 2; @@ -702,7 +702,7 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface { if (!$this->lock->acquire()) { - throw new phpbb_nestedset_exception($this->message_prefix . 'LOCK_FAILED_ACQUIRE'); + throw new RuntimeException($this->message_prefix . 'LOCK_FAILED_ACQUIRE'); } $this->db->sql_transaction('begin'); diff --git a/phpBB/includes/nestedset/exception.php b/phpBB/includes/nestedset/exception.php deleted file mode 100644 index 10937d0b29..0000000000 --- a/phpBB/includes/nestedset/exception.php +++ /dev/null @@ -1,20 +0,0 @@ - Date: Thu, 25 Apr 2013 16:23:47 +0200 Subject: [PATCH 192/281] [ticket/11495] Explain use of set_subset_zero on remove_subset() PHPBB3-11495 --- phpBB/includes/nestedset/base.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/phpBB/includes/nestedset/base.php b/phpBB/includes/nestedset/base.php index da6c056313..cb06a0dabe 100644 --- a/phpBB/includes/nestedset/base.php +++ b/phpBB/includes/nestedset/base.php @@ -603,8 +603,10 @@ abstract class phpbb_nestedset_base implements phpbb_nestedset_interface * Remove a subset from the nested set * * @param array $subset_items Subset of items to remove - * @param array $bounding_item Item containing the right bound of the subset - * @param bool $set_subset_zero Should the parent, left and right id of the item be set to 0, or kept unchanged? + * @param array $bounding_item Item containing the right bound of the subset + * @param bool $set_subset_zero Should the parent, left and right id of the items be set to 0, or kept unchanged? + * In case of removing an item from the tree, we should the values to 0 + * In case of moving an item, we shouldkeep the original values, in order to allow "+ diff" later * @param bool $table_already_locked Is the table already locked, or should we acquire a new lock? * @return null */ From 94dee77647a7ae1a263632a156b5afc14722ad6a Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 25 Apr 2013 16:50:11 +0200 Subject: [PATCH 193/281] [ticket/11495] Replace fixtures content with manual calls Should be easier to maintain PHPBB3-11495 --- tests/nestedset/fixtures/phpbb_forums.xml | 110 ---------------------- tests/nestedset/set_forum_base.php | 25 +++++ 2 files changed, 25 insertions(+), 110 deletions(-) diff --git a/tests/nestedset/fixtures/phpbb_forums.xml b/tests/nestedset/fixtures/phpbb_forums.xml index 016c8ea7c5..8f133078a9 100644 --- a/tests/nestedset/fixtures/phpbb_forums.xml +++ b/tests/nestedset/fixtures/phpbb_forums.xml @@ -9,115 +9,5 @@ forum_name forum_desc forum_rules - - 1 - 0 - 1 - 6 - - Parent with two flat children - - - - - 2 - 1 - 2 - 3 - - Flat child #1 - - - - - 3 - 1 - 4 - 5 - - Flat child #2 - - - - - 4 - 0 - 7 - 12 - - Parent with two nested children - - - - - 5 - 4 - 8 - 11 - - Nested child #1 - - - - - 6 - 5 - 9 - 10 - - Nested child #2 - - - - - 7 - 0 - 13 - 22 - - Parent with flat and nested children - - - - - 8 - 7 - 14 - 15 - - Mixed child #1 - - - - - 9 - 7 - 16 - 19 - - Mixed child #2 - - - - - 10 - 9 - 17 - 18 - - Nested child #1 of Mixed child #2 - - - - - 11 - 7 - 20 - 21 - - Mixed child #3 - - - diff --git a/tests/nestedset/set_forum_base.php b/tests/nestedset/set_forum_base.php index 4523f12897..93d4dc3522 100644 --- a/tests/nestedset/set_forum_base.php +++ b/tests/nestedset/set_forum_base.php @@ -57,5 +57,30 @@ class phpbb_tests_nestedset_set_forum_base extends phpbb_database_test_case $this->lock = new phpbb_lock_db('nestedset_forum_lock', $this->config, $this->db); $this->set = new phpbb_nestedset_forum($this->db, $this->lock, 'phpbb_forums'); + + $this->set_up_forums(); + } + + protected function set_up_forums() + { + $this->create_forum('Parent with two flat children'); + $this->create_forum('Flat child #1', 1); + $this->create_forum('Flat child #2', 1); + + $this->create_forum('Parent with two nested children'); + $this->create_forum('Nested child #1', 4); + $this->create_forum('Nested child #2', 5); + + $this->create_forum('Parent with flat and nested children'); + $this->create_forum('Mixed child #1', 7); + $this->create_forum('Mixed child #2', 7); + $this->create_forum('Nested child #1 of Mixed child #2', 9); + $this->create_forum('Mixed child #3', 7); + } + + protected function create_forum($name, $parent_id = 0) + { + $forum = $this->set->insert(array('forum_name' => $name, 'forum_desc' => '', 'forum_rules' => '')); + $this->set->change_parent($forum['forum_id'], $parent_id); } } From b334a2ce0fe3ae196da9686028667c430eb411d1 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 25 Apr 2013 17:04:37 +0200 Subject: [PATCH 194/281] [ticket/11495] Move classes to tree/ as they all implement a tree PHPBB3-11495 --- phpBB/includes/{nestedset => tree}/interface.php | 4 ++-- phpBB/includes/{nestedset/base.php => tree/nestedset.php} | 4 ++-- .../{nestedset/forum.php => tree/nestedset_forum.php} | 4 ++-- tests/nestedset/set_forum_base.php | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) rename phpBB/includes/{nestedset => tree}/interface.php (98%) rename phpBB/includes/{nestedset/base.php => tree/nestedset.php} (99%) rename phpBB/includes/{nestedset/forum.php => tree/nestedset_forum.php} (91%) diff --git a/phpBB/includes/nestedset/interface.php b/phpBB/includes/tree/interface.php similarity index 98% rename from phpBB/includes/nestedset/interface.php rename to phpBB/includes/tree/interface.php index eadc9083b1..fd10bd357f 100644 --- a/phpBB/includes/nestedset/interface.php +++ b/phpBB/includes/tree/interface.php @@ -1,7 +1,7 @@ config); $this->lock = new phpbb_lock_db('nestedset_forum_lock', $this->config, $this->db); - $this->set = new phpbb_nestedset_forum($this->db, $this->lock, 'phpbb_forums'); + $this->set = new phpbb_tree_nestedset_forum($this->db, $this->lock, 'phpbb_forums'); $this->set_up_forums(); } From 5de14b940e71941853d3bb279779631ae75b9b6f Mon Sep 17 00:00:00 2001 From: Dhruv Date: Sat, 26 Jan 2013 00:22:56 +0530 Subject: [PATCH 195/281] [ticket/10325] add allow forgot password option in acp PHPBB3-10325 --- phpBB/includes/acp/acp_board.php | 1 + phpBB/language/en/acp/board.php | 2 ++ 2 files changed, 3 insertions(+) diff --git a/phpBB/includes/acp/acp_board.php b/phpBB/includes/acp/acp_board.php index bacf0d6e57..1956ade31a 100644 --- a/phpBB/includes/acp/acp_board.php +++ b/phpBB/includes/acp/acp_board.php @@ -398,6 +398,7 @@ class acp_board 'vars' => array( 'legend1' => 'ACP_SECURITY_SETTINGS', 'allow_autologin' => array('lang' => 'ALLOW_AUTOLOGIN', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), + 'allow_forgot_password' => array('lang' => 'ALLOW_FORGOT_PASSWORD', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'max_autologin_time' => array('lang' => 'AUTOLOGIN_LENGTH', 'validate' => 'int:0', 'type' => 'text:5:5', 'explain' => true, 'append' => ' ' . $user->lang['DAYS']), 'ip_check' => array('lang' => 'IP_VALID', 'validate' => 'int', 'type' => 'custom', 'method' => 'select_ip_check', 'explain' => true), 'browser_check' => array('lang' => 'BROWSER_VALID', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), diff --git a/phpBB/language/en/acp/board.php b/phpBB/language/en/acp/board.php index f387158a0b..4b2020b894 100644 --- a/phpBB/language/en/acp/board.php +++ b/phpBB/language/en/acp/board.php @@ -454,6 +454,8 @@ $lang = array_merge($lang, array( 'ALL' => 'All', 'ALLOW_AUTOLOGIN' => 'Allow "Remember Me" logins', 'ALLOW_AUTOLOGIN_EXPLAIN' => 'Determines whether users are given "Remember Me" option when they visit the board.', + 'ALLOW_FORGOT_PASSWORD' => 'Allow "forgot password"', + 'ALLOW_FORGOT_PASSWORD_EXPLAIN' => 'Determines whether users can use the "forgot password" option to recover their account', 'AUTOLOGIN_LENGTH' => '"Remember Me" login key expiration length (in days)', 'AUTOLOGIN_LENGTH_EXPLAIN' => 'Number of days after which "Remember Me" login keys are removed or zero to disable.', 'BROWSER_VALID' => 'Validate browser', From c6e9bd13a75441e9b35a1bfa5d2a08cc38ff1fa5 Mon Sep 17 00:00:00 2001 From: Dhruv Date: Sat, 26 Jan 2013 01:01:57 +0530 Subject: [PATCH 196/281] [ticket/10325] trigger error if forgot password option disabled PHPBB3-10325 --- phpBB/includes/ucp/ucp_remind.php | 5 +++++ phpBB/language/en/ucp.php | 1 + 2 files changed, 6 insertions(+) diff --git a/phpBB/includes/ucp/ucp_remind.php b/phpBB/includes/ucp/ucp_remind.php index 8a7ba5d0ca..dd95c29def 100644 --- a/phpBB/includes/ucp/ucp_remind.php +++ b/phpBB/includes/ucp/ucp_remind.php @@ -29,6 +29,11 @@ class ucp_remind global $config, $phpbb_root_path, $phpEx; global $db, $user, $auth, $template; + if (!$config['allow_forgot_password']) + { + trigger_error('UCP_FORGOT_PASSWORD_DISABLE'); + } + $username = request_var('username', '', true); $email = strtolower(request_var('email', '')); $submit = (isset($_POST['submit'])) ? true : false; diff --git a/phpBB/language/en/ucp.php b/phpBB/language/en/ucp.php index 3e090a8aec..a98dc6f11e 100644 --- a/phpBB/language/en/ucp.php +++ b/phpBB/language/en/ucp.php @@ -521,6 +521,7 @@ $lang = array_merge($lang, array( 'UCP_USERGROUPS_MEMBER' => 'Edit memberships', 'UCP_USERGROUPS_MANAGE' => 'Manage groups', + 'UCP_FORGOT_PASSWORD_DISABLE' => 'Function has been disabled.', 'UCP_REGISTER_DISABLE' => 'Creating a new account is currently not possible.', 'UCP_REMIND' => 'Send password', 'UCP_RESEND' => 'Send activation email', From 499dd3a833912d07fe677ae721e99678708bddcd Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 25 Apr 2013 17:13:21 +0200 Subject: [PATCH 197/281] [ticket/11495] Move tests to tree/ directory PHPBB3-11495 --- tests/{nestedset => tree}/fixtures/phpbb_forums.xml | 0 .../nestedset_forum_add_remove_test.php} | 4 ++-- .../set_forum_base.php => tree/nestedset_forum_base.php} | 4 ++-- .../nestedset_forum_get_data_test.php} | 4 ++-- .../nestedset_forum_move_test.php} | 4 ++-- .../nestedset_forum_regenerate_test.php} | 4 ++-- .../set_forum_test.php => tree/nestedset_forum_test.php} | 4 ++-- 7 files changed, 12 insertions(+), 12 deletions(-) rename tests/{nestedset => tree}/fixtures/phpbb_forums.xml (100%) rename tests/{nestedset/set_forum_add_remove_test.php => tree/nestedset_forum_add_remove_test.php} (98%) rename tests/{nestedset/set_forum_base.php => tree/nestedset_forum_base.php} (96%) rename tests/{nestedset/set_forum_get_data_test.php => tree/nestedset_forum_get_data_test.php} (96%) rename tests/{nestedset/set_forum_move_test.php => tree/nestedset_forum_move_test.php} (99%) rename tests/{nestedset/set_forum_regenerate_test.php => tree/nestedset_forum_regenerate_test.php} (95%) rename tests/{nestedset/set_forum_test.php => tree/nestedset_forum_test.php} (97%) diff --git a/tests/nestedset/fixtures/phpbb_forums.xml b/tests/tree/fixtures/phpbb_forums.xml similarity index 100% rename from tests/nestedset/fixtures/phpbb_forums.xml rename to tests/tree/fixtures/phpbb_forums.xml diff --git a/tests/nestedset/set_forum_add_remove_test.php b/tests/tree/nestedset_forum_add_remove_test.php similarity index 98% rename from tests/nestedset/set_forum_add_remove_test.php rename to tests/tree/nestedset_forum_add_remove_test.php index 97b6348d67..623cb2bbf3 100644 --- a/tests/nestedset/set_forum_add_remove_test.php +++ b/tests/tree/nestedset_forum_add_remove_test.php @@ -1,7 +1,7 @@ 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => ''), diff --git a/tests/nestedset/set_forum_test.php b/tests/tree/nestedset_forum_test.php similarity index 97% rename from tests/nestedset/set_forum_test.php rename to tests/tree/nestedset_forum_test.php index ab4da1ff1e..ac02886e95 100644 --- a/tests/nestedset/set_forum_test.php +++ b/tests/tree/nestedset_forum_test.php @@ -1,7 +1,7 @@ Date: Thu, 25 Apr 2013 17:19:21 +0200 Subject: [PATCH 198/281] [ticket/11495] Remove tests for add/remove we make them protected later PHPBB3-11495 --- .../tree/nestedset_forum_add_remove_test.php | 196 ------------------ .../nestedset_forum_insert_delete_test.php | 101 +++++++++ 2 files changed, 101 insertions(+), 196 deletions(-) delete mode 100644 tests/tree/nestedset_forum_add_remove_test.php create mode 100644 tests/tree/nestedset_forum_insert_delete_test.php diff --git a/tests/tree/nestedset_forum_add_remove_test.php b/tests/tree/nestedset_forum_add_remove_test.php deleted file mode 100644 index 623cb2bbf3..0000000000 --- a/tests/tree/nestedset_forum_add_remove_test.php +++ /dev/null @@ -1,196 +0,0 @@ - 1, 'parent_id' => 0, 'left_id' => 0, 'right_id' => 0, 'forum_parents' => ''), - array('forum_id' => 2, 'parent_id' => 0, 'left_id' => 0, 'right_id' => 0, 'forum_parents' => ''), - array('forum_id' => 3, 'parent_id' => 0, 'left_id' => 0, 'right_id' => 0, 'forum_parents' => ''), - array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => ''), - array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 2, 'right_id' => 5, 'forum_parents' => ''), - array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 3, 'right_id' => 4, 'forum_parents' => ''), - array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 16, 'forum_parents' => ''), - array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 8, 'right_id' => 9, 'forum_parents' => ''), - array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 10, 'right_id' => 13, 'forum_parents' => ''), - array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 11, 'right_id' => 12, 'forum_parents' => ''), - array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => ''), - ), array( - 1 => array('parent_id' => 0, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => ''), - 2 => array('parent_id' => 0, 'left_id' => 19, 'right_id' => 20, 'forum_parents' => ''), - 3 => array('parent_id' => 0, 'left_id' => 21, 'right_id' => 22, 'forum_parents' => ''), - ), array( - array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => ''), - array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 2, 'right_id' => 5, 'forum_parents' => ''), - array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 3, 'right_id' => 4, 'forum_parents' => ''), - array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 16, 'forum_parents' => ''), - array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 8, 'right_id' => 9, 'forum_parents' => ''), - array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 10, 'right_id' => 13, 'forum_parents' => ''), - array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 11, 'right_id' => 12, 'forum_parents' => ''), - array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => ''), - array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => ''), - array('forum_id' => 2, 'parent_id' => 0, 'left_id' => 19, 'right_id' => 20, 'forum_parents' => ''), - array('forum_id' => 3, 'parent_id' => 0, 'left_id' => 21, 'right_id' => 22, 'forum_parents' => ''), - )), - array(2, array(2), array( - array('forum_id' => 2, 'parent_id' => 0, 'left_id' => 0, 'right_id' => 0, 'forum_parents' => ''), - array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 4, 'forum_parents' => ''), - array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => ''), - array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 5, 'right_id' => 10, 'forum_parents' => ''), - array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 6, 'right_id' => 9, 'forum_parents' => ''), - array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 7, 'right_id' => 8, 'forum_parents' => ''), - array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 11, 'right_id' => 20, 'forum_parents' => ''), - array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 12, 'right_id' => 13, 'forum_parents' => ''), - array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 17, 'forum_parents' => ''), - array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 15, 'right_id' => 16, 'forum_parents' => ''), - array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 18, 'right_id' => 19, 'forum_parents' => ''), - ), array( - 2 => array('parent_id' => 0, 'left_id' => 21, 'right_id' => 22, 'forum_parents' => '') - ), array( - array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 4, 'forum_parents' => ''), - array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => ''), - array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 5, 'right_id' => 10, 'forum_parents' => ''), - array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 6, 'right_id' => 9, 'forum_parents' => ''), - array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 7, 'right_id' => 8, 'forum_parents' => ''), - array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 11, 'right_id' => 20, 'forum_parents' => ''), - array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 12, 'right_id' => 13, 'forum_parents' => ''), - array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 17, 'forum_parents' => ''), - array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 15, 'right_id' => 16, 'forum_parents' => ''), - array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 18, 'right_id' => 19, 'forum_parents' => ''), - array('forum_id' => 2, 'parent_id' => 0, 'left_id' => 21, 'right_id' => 22, 'forum_parents' => ''), - )), - ); - } - - /** - * @dataProvider remove_add_data - */ - public function test_remove_add($forum_id, $expected_removed, $expected_remove_table, $expected_added, $expected_add_table) - { - $removed_items = $this->set->remove($forum_id); - - $this->assertEquals($expected_removed, $removed_items); - - $result = $this->db->sql_query("SELECT forum_id, parent_id, left_id, right_id, forum_parents - FROM phpbb_forums - ORDER BY left_id, forum_id ASC"); - $this->assertEquals($expected_remove_table, $this->db->sql_fetchrowset($result)); - - $added_items = array(); - foreach ($removed_items as $item_id) - { - $added_items[$item_id] = $this->set->add(array_merge($this->forum_data[$item_id], array( - 'forum_rules' => '', - 'forum_desc' => '', - 'parent_id' => 0, - 'left_id' => 0, - 'right_id' => 0, - ))); - } - $this->assertEquals($expected_added, $added_items); - - $result = $this->db->sql_query("SELECT forum_id, parent_id, left_id, right_id, forum_parents - FROM phpbb_forums - ORDER BY left_id, forum_id ASC"); - $this->assertEquals($expected_add_table, $this->db->sql_fetchrowset($result)); - } - - public function delete_data() - { - return array( - array(1, array(1, 2, 3), array( - array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => ''), - array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 2, 'right_id' => 5, 'forum_parents' => ''), - array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 3, 'right_id' => 4, 'forum_parents' => ''), - array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 16, 'forum_parents' => ''), - array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 8, 'right_id' => 9, 'forum_parents' => ''), - array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 10, 'right_id' => 13, 'forum_parents' => ''), - array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 11, 'right_id' => 12, 'forum_parents' => ''), - array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => ''), - )), - array(2, array(2), array( - array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 4, 'forum_parents' => ''), - array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => ''), - array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 5, 'right_id' => 10, 'forum_parents' => ''), - array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 6, 'right_id' => 9, 'forum_parents' => ''), - array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 7, 'right_id' => 8, 'forum_parents' => ''), - array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 11, 'right_id' => 20, 'forum_parents' => ''), - array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 12, 'right_id' => 13, 'forum_parents' => ''), - array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 17, 'forum_parents' => ''), - array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 15, 'right_id' => 16, 'forum_parents' => ''), - array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 18, 'right_id' => 19, 'forum_parents' => ''), - )), - ); - } - - /** - * @dataProvider delete_data - */ - public function test_delete($forum_id, $expected_deleted, $expected) - { - $this->assertEquals($expected_deleted, $this->set->delete($forum_id)); - - $result = $this->db->sql_query("SELECT forum_id, parent_id, left_id, right_id, forum_parents - FROM phpbb_forums - ORDER BY left_id, forum_id ASC"); - $this->assertEquals($expected, $this->db->sql_fetchrowset($result)); - } - - public function insert_data() - { - return array( - array(array( - 'forum_desc' => '', - 'forum_rules' => '', - 'forum_id' => 12, - 'parent_id' => 0, - 'left_id' => 23, - 'right_id' => 24, - 'forum_parents' => '', - ), array( - array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => ''), - array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => ''), - array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => ''), - - array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12, 'forum_parents' => ''), - array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 8, 'right_id' => 11, 'forum_parents' => ''), - array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 9, 'right_id' => 10, 'forum_parents' => ''), - - array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => ''), - array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => ''), - array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => ''), - array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => ''), - array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => ''), - - array('forum_id' => 12, 'parent_id' => 0, 'left_id' => 23, 'right_id' => 24, 'forum_parents' => ''), - )), - ); - } - - /** - * @dataProvider insert_data - */ - public function test_insert($expected_data, $expected) - { - $this->assertEquals($expected_data, $this->set->insert(array( - 'forum_desc' => '', - 'forum_rules' => '', - ))); - - $result = $this->db->sql_query('SELECT forum_id, parent_id, left_id, right_id, forum_parents - FROM phpbb_forums - ORDER BY left_id, forum_id ASC'); - $this->assertEquals($expected, $this->db->sql_fetchrowset($result)); - } -} diff --git a/tests/tree/nestedset_forum_insert_delete_test.php b/tests/tree/nestedset_forum_insert_delete_test.php new file mode 100644 index 0000000000..02259f9091 --- /dev/null +++ b/tests/tree/nestedset_forum_insert_delete_test.php @@ -0,0 +1,101 @@ + 4, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => ''), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 2, 'right_id' => 5, 'forum_parents' => ''), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 3, 'right_id' => 4, 'forum_parents' => ''), + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 16, 'forum_parents' => ''), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 8, 'right_id' => 9, 'forum_parents' => ''), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 10, 'right_id' => 13, 'forum_parents' => ''), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 11, 'right_id' => 12, 'forum_parents' => ''), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => ''), + )), + array(2, array(2), array( + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 4, 'forum_parents' => ''), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => ''), + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 5, 'right_id' => 10, 'forum_parents' => ''), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 6, 'right_id' => 9, 'forum_parents' => ''), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 7, 'right_id' => 8, 'forum_parents' => ''), + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 11, 'right_id' => 20, 'forum_parents' => ''), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 12, 'right_id' => 13, 'forum_parents' => ''), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 17, 'forum_parents' => ''), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 15, 'right_id' => 16, 'forum_parents' => ''), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 18, 'right_id' => 19, 'forum_parents' => ''), + )), + ); + } + + /** + * @dataProvider delete_data + */ + public function test_delete($forum_id, $expected_deleted, $expected) + { + $this->assertEquals($expected_deleted, $this->set->delete($forum_id)); + + $result = $this->db->sql_query("SELECT forum_id, parent_id, left_id, right_id, forum_parents + FROM phpbb_forums + ORDER BY left_id, forum_id ASC"); + $this->assertEquals($expected, $this->db->sql_fetchrowset($result)); + } + + public function insert_data() + { + return array( + array(array( + 'forum_desc' => '', + 'forum_rules' => '', + 'forum_id' => 12, + 'parent_id' => 0, + 'left_id' => 23, + 'right_id' => 24, + 'forum_parents' => '', + ), array( + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => ''), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => ''), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => ''), + + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12, 'forum_parents' => ''), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 8, 'right_id' => 11, 'forum_parents' => ''), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 9, 'right_id' => 10, 'forum_parents' => ''), + + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => ''), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => ''), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => ''), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => ''), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => ''), + + array('forum_id' => 12, 'parent_id' => 0, 'left_id' => 23, 'right_id' => 24, 'forum_parents' => ''), + )), + ); + } + + /** + * @dataProvider insert_data + */ + public function test_insert($expected_data, $expected) + { + $this->assertEquals($expected_data, $this->set->insert(array( + 'forum_desc' => '', + 'forum_rules' => '', + ))); + + $result = $this->db->sql_query('SELECT forum_id, parent_id, left_id, right_id, forum_parents + FROM phpbb_forums + ORDER BY left_id, forum_id ASC'); + $this->assertEquals($expected, $this->db->sql_fetchrowset($result)); + } +} From 73d873548400f18b02167ef49195a50a11970c24 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 25 Apr 2013 17:19:52 +0200 Subject: [PATCH 199/281] [ticket/11495] Remove fixing function from tree interface The fixing function is implementation dependent. PHPBB3-11495 --- phpBB/includes/tree/interface.php | 34 ++++++------------------------- phpBB/includes/tree/nestedset.php | 19 ++++++++++++++++- 2 files changed, 24 insertions(+), 29 deletions(-) diff --git a/phpBB/includes/tree/interface.php b/phpBB/includes/tree/interface.php index fd10bd357f..babd0ad03d 100644 --- a/phpBB/includes/tree/interface.php +++ b/phpBB/includes/tree/interface.php @@ -18,7 +18,7 @@ if (!defined('IN_PHPBB')) interface phpbb_tree_interface { /** - * Insert an item into the nested set (also insert the rows into the table) + * Insert an item into the tree (also insert the rows into the table) * * @param array $item The item to be added * @return array Array with item data as set in the database @@ -26,7 +26,7 @@ interface phpbb_tree_interface public function insert(array $additional_data); /** - * Add an item at the end of the nested set + * Add an item at the end of the tree * * @param array $item The item to be added * @return bool True if the item was added @@ -34,9 +34,9 @@ interface phpbb_tree_interface public function add(array $item); /** - * Remove an item from the nested set + * Remove an item from the tree * - * Also removes all subitems from the nested set + * Also removes all subitems from the tree * * @param int $item_id The item to be deleted * @return array Item ids that have been removed @@ -44,9 +44,9 @@ interface phpbb_tree_interface public function remove($item); /** - * Delete an item from the nested set (also deletes the rows form the table) + * Delete an item from the tree * - * Also deletes all subitems from the nested set + * Also deletes all subitems from the tree * * @param int $item_id The item to be deleted * @return array Item ids that have been deleted @@ -146,26 +146,4 @@ interface phpbb_tree_interface * ID => Item data */ public function get_parent_data(array $item); - - /** - * Regenerate left/right ids from parent/child relationship - * - * This method regenerates the left/right ids for the nested set based on - * the parent/child relations. This function executes three queries per - * item, so it should only be called, when the set has one of the following - * problems: - * - The set has a duplicated value inside the left/right id chain - * - The set has a missing value inside the left/right id chain - * - The set has items that do not have a left/right is set - * - * When regenerating the items, the items are sorted by parent id and their - * current left id, so the current child/parent relationships are kept - * and running the function on a working set will not change any orders. - * - * @param int $new_id First left_id to be used (should start with 1) - * @param int $parent_id parent_id of the current set (default = 0) - * @param bool $reset_ids Should we reset all left_id/right_id on the first call? - * @return int $new_id The next left_id/right_id that should be used - */ - public function regenerate_left_right_ids($new_id, $parent_id = 0, $reset_ids = false); } diff --git a/phpBB/includes/tree/nestedset.php b/phpBB/includes/tree/nestedset.php index 2110e1a6d2..72e3aa4d71 100644 --- a/phpBB/includes/tree/nestedset.php +++ b/phpBB/includes/tree/nestedset.php @@ -696,7 +696,24 @@ abstract class phpbb_tree_nestedset implements phpbb_tree_interface } /** - * @inheritdoc + * Regenerate left/right ids from parent/child relationship + * + * This method regenerates the left/right ids for the tree based on + * the parent/child relations. This function executes three queries per + * item, so it should only be called, when the set has one of the following + * problems: + * - The set has a duplicated value inside the left/right id chain + * - The set has a missing value inside the left/right id chain + * - The set has items that do not have a left/right is set + * + * When regenerating the items, the items are sorted by parent id and their + * current left id, so the current child/parent relationships are kept + * and running the function on a working set will not change any orders. + * + * @param int $new_id First left_id to be used (should start with 1) + * @param int $parent_id parent_id of the current set (default = 0) + * @param bool $reset_ids Should we reset all left_id/right_id on the first call? + * @return int $new_id The next left_id/right_id that should be used */ public function regenerate_left_right_ids($new_id, $parent_id = 0, $reset_ids = false) { From abfb7bc51fa254edd6274e39625eb8a4edec32be Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 25 Apr 2013 17:24:18 +0200 Subject: [PATCH 200/281] [ticket/11495] Remove add/remove from the interface PHPBB3-11495 --- phpBB/includes/tree/interface.php | 20 +------------------- phpBB/includes/tree/nestedset.php | 16 ++++++++++++---- 2 files changed, 13 insertions(+), 23 deletions(-) diff --git a/phpBB/includes/tree/interface.php b/phpBB/includes/tree/interface.php index babd0ad03d..3f03363151 100644 --- a/phpBB/includes/tree/interface.php +++ b/phpBB/includes/tree/interface.php @@ -18,31 +18,13 @@ if (!defined('IN_PHPBB')) interface phpbb_tree_interface { /** - * Insert an item into the tree (also insert the rows into the table) + * Insert an item into the tree * * @param array $item The item to be added * @return array Array with item data as set in the database */ public function insert(array $additional_data); - /** - * Add an item at the end of the tree - * - * @param array $item The item to be added - * @return bool True if the item was added - */ - public function add(array $item); - - /** - * Remove an item from the tree - * - * Also removes all subitems from the tree - * - * @param int $item_id The item to be deleted - * @return array Item ids that have been removed - */ - public function remove($item); - /** * Delete an item from the tree * diff --git a/phpBB/includes/tree/nestedset.php b/phpBB/includes/tree/nestedset.php index 72e3aa4d71..8f73b9181e 100644 --- a/phpBB/includes/tree/nestedset.php +++ b/phpBB/includes/tree/nestedset.php @@ -84,9 +84,12 @@ abstract class phpbb_tree_nestedset implements phpbb_tree_interface } /** - * @inheritdoc + * Add an existing item at the end of the tree + * + * @param array $item The item to be added + * @return bool True if the item was added */ - public function add(array $item) + protected function add(array $item) { $sql = 'SELECT MAX(' . $this->column_right_id . ') AS ' . $this->column_right_id . ' FROM ' . $this->table_name . ' @@ -111,9 +114,14 @@ abstract class phpbb_tree_nestedset implements phpbb_tree_interface } /** - * @inheritdoc + * Remove an item from the tree WITHOUT removing the items from the table + * + * Also removes all subitems from the tree + * + * @param int $item_id The item to be deleted + * @return array Item ids that have been removed */ - public function remove($item_id) + protected function remove($item_id) { $items = $this->get_children_branch_data($item_id); $item_ids = array_keys($items); From ce07b2776577d1ed3987b38e231a367cfef21db6 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 25 Apr 2013 17:27:33 +0200 Subject: [PATCH 201/281] [ticket/11495] Fix failing unit tests PHPBB3-11495 --- tests/tree/nestedset_forum_get_data_test.php | 2 +- tests/tree/nestedset_forum_insert_delete_test.php | 2 +- tests/tree/nestedset_forum_move_test.php | 2 +- tests/tree/nestedset_forum_regenerate_test.php | 2 +- tests/tree/nestedset_forum_test.php | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/tree/nestedset_forum_get_data_test.php b/tests/tree/nestedset_forum_get_data_test.php index 4ce679f05d..24ada93409 100644 --- a/tests/tree/nestedset_forum_get_data_test.php +++ b/tests/tree/nestedset_forum_get_data_test.php @@ -7,7 +7,7 @@ * */ -require_once dirname(__FILE__) . '/set_forum_base.php'; +require_once dirname(__FILE__) . '/nestedset_forum_base.php'; class phpbb_tests_tree_nestedset_forum_get_data_test extends phpbb_tests_tree_nestedset_forum_base { diff --git a/tests/tree/nestedset_forum_insert_delete_test.php b/tests/tree/nestedset_forum_insert_delete_test.php index 02259f9091..67692d2b7e 100644 --- a/tests/tree/nestedset_forum_insert_delete_test.php +++ b/tests/tree/nestedset_forum_insert_delete_test.php @@ -7,7 +7,7 @@ * */ -require_once dirname(__FILE__) . '/set_forum_base.php'; +require_once dirname(__FILE__) . '/nestedset_forum_base.php'; class phpbb_tests_tree_nestedset_forum_add_remove_test extends phpbb_tests_tree_nestedset_forum_base { diff --git a/tests/tree/nestedset_forum_move_test.php b/tests/tree/nestedset_forum_move_test.php index 29af693374..9561089378 100644 --- a/tests/tree/nestedset_forum_move_test.php +++ b/tests/tree/nestedset_forum_move_test.php @@ -7,7 +7,7 @@ * */ -require_once dirname(__FILE__) . '/set_forum_base.php'; +require_once dirname(__FILE__) . '/nestedset_forum_base.php'; class phpbb_tests_tree_nestedset_forum_move_test extends phpbb_tests_tree_nestedset_forum_base { diff --git a/tests/tree/nestedset_forum_regenerate_test.php b/tests/tree/nestedset_forum_regenerate_test.php index 3bd272370a..6b1759d1cc 100644 --- a/tests/tree/nestedset_forum_regenerate_test.php +++ b/tests/tree/nestedset_forum_regenerate_test.php @@ -7,7 +7,7 @@ * */ -require_once dirname(__FILE__) . '/set_forum_base.php'; +require_once dirname(__FILE__) . '/nestedset_forum_base.php'; class phpbb_tests_tree_nestedset_forum_regenerate_test extends phpbb_tests_tree_nestedset_forum_base { diff --git a/tests/tree/nestedset_forum_test.php b/tests/tree/nestedset_forum_test.php index ac02886e95..5e6d912596 100644 --- a/tests/tree/nestedset_forum_test.php +++ b/tests/tree/nestedset_forum_test.php @@ -7,7 +7,7 @@ * */ -require_once dirname(__FILE__) . '/set_forum_base.php'; +require_once dirname(__FILE__) . '/nestedset_forum_base.php'; class pphpbb_tests_tree_nestedset_forum_test extends phpbb_tests_tree_nestedset_forum_base { From 2dbe3b3c975d61b84310f7da27b8d525a22d1723 Mon Sep 17 00:00:00 2001 From: Dhruv Date: Sat, 26 Jan 2013 01:09:30 +0530 Subject: [PATCH 202/281] [ticket/10325] add new config value to database PHPBB3-10325 --- phpBB/includes/db/migration/data/310/dev.php | 2 ++ phpBB/install/schemas/schema_data.sql | 1 + 2 files changed, 3 insertions(+) diff --git a/phpBB/includes/db/migration/data/310/dev.php b/phpBB/includes/db/migration/data/310/dev.php index 13b36bbf30..d3f3a341b2 100644 --- a/phpBB/includes/db/migration/data/310/dev.php +++ b/phpBB/includes/db/migration/data/310/dev.php @@ -84,6 +84,8 @@ class phpbb_db_migration_data_310_dev extends phpbb_db_migration return array( array('config.update', array('search_type', 'phpbb_search_' . $this->config['search_type'])), + array('config.add', array('allow_forgot_password', 1)), + array('config.add', array('fulltext_postgres_ts_name', 'simple')), array('config.add', array('fulltext_postgres_min_word_len', 4)), array('config.add', array('fulltext_postgres_max_word_len', 254)), diff --git a/phpBB/install/schemas/schema_data.sql b/phpBB/install/schemas/schema_data.sql index 8a8740a220..d9ba09ff4d 100644 --- a/phpBB/install/schemas/schema_data.sql +++ b/phpBB/install/schemas/schema_data.sql @@ -18,6 +18,7 @@ INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_bbcode', '1' INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_birthdays', '1'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_bookmarks', '1'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_emailreuse', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_forgot_password', '1'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_forum_notify', '1'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_mass_pm', '1'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_name_chars', 'USERNAME_CHARS_ANY'); From f8012cc239d8b442e78bbbb8a5cc5856d2a714a0 Mon Sep 17 00:00:00 2001 From: Dhruv Date: Sat, 26 Jan 2013 11:10:17 +0530 Subject: [PATCH 203/281] [ticket/10325] fix language PHPBB3-10325 --- phpBB/includes/ucp/ucp_remind.php | 2 +- phpBB/language/en/ucp.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/phpBB/includes/ucp/ucp_remind.php b/phpBB/includes/ucp/ucp_remind.php index dd95c29def..a25d7da91a 100644 --- a/phpBB/includes/ucp/ucp_remind.php +++ b/phpBB/includes/ucp/ucp_remind.php @@ -31,7 +31,7 @@ class ucp_remind if (!$config['allow_forgot_password']) { - trigger_error('UCP_FORGOT_PASSWORD_DISABLE'); + trigger_error($user->lang('UCP_FORGOT_PASSWORD_DISABLE', '', '')); } $username = request_var('username', '', true); diff --git a/phpBB/language/en/ucp.php b/phpBB/language/en/ucp.php index a98dc6f11e..ce93c7bcf8 100644 --- a/phpBB/language/en/ucp.php +++ b/phpBB/language/en/ucp.php @@ -521,7 +521,7 @@ $lang = array_merge($lang, array( 'UCP_USERGROUPS_MEMBER' => 'Edit memberships', 'UCP_USERGROUPS_MANAGE' => 'Manage groups', - 'UCP_FORGOT_PASSWORD_DISABLE' => 'Function has been disabled.', + 'UCP_FORGOT_PASSWORD_DISABLE' => 'The administrator has disabled the password reset ability. If you need help accessing your account, please contact the %sBoard Administrator%s', 'UCP_REGISTER_DISABLE' => 'Creating a new account is currently not possible.', 'UCP_REMIND' => 'Send password', 'UCP_RESEND' => 'Send activation email', From 1a51abcca293b0e2bd836af0dcb9d77054c1d401 Mon Sep 17 00:00:00 2001 From: Dhruv Date: Sun, 27 Jan 2013 03:07:52 +0530 Subject: [PATCH 204/281] [ticket/10325] change language var PHPBB3-10325 --- phpBB/includes/acp/acp_board.php | 2 +- phpBB/includes/db/migration/data/310/dev.php | 2 +- phpBB/includes/ucp/ucp_remind.php | 2 +- phpBB/install/schemas/schema_data.sql | 2 +- phpBB/language/en/acp/board.php | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/phpBB/includes/acp/acp_board.php b/phpBB/includes/acp/acp_board.php index 1956ade31a..ab44920f0a 100644 --- a/phpBB/includes/acp/acp_board.php +++ b/phpBB/includes/acp/acp_board.php @@ -398,7 +398,7 @@ class acp_board 'vars' => array( 'legend1' => 'ACP_SECURITY_SETTINGS', 'allow_autologin' => array('lang' => 'ALLOW_AUTOLOGIN', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), - 'allow_forgot_password' => array('lang' => 'ALLOW_FORGOT_PASSWORD', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), + 'allow_password_reset' => array('lang' => 'ALLOW_PASSWORD_RESET', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'max_autologin_time' => array('lang' => 'AUTOLOGIN_LENGTH', 'validate' => 'int:0', 'type' => 'text:5:5', 'explain' => true, 'append' => ' ' . $user->lang['DAYS']), 'ip_check' => array('lang' => 'IP_VALID', 'validate' => 'int', 'type' => 'custom', 'method' => 'select_ip_check', 'explain' => true), 'browser_check' => array('lang' => 'BROWSER_VALID', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), diff --git a/phpBB/includes/db/migration/data/310/dev.php b/phpBB/includes/db/migration/data/310/dev.php index d3f3a341b2..0794567f1b 100644 --- a/phpBB/includes/db/migration/data/310/dev.php +++ b/phpBB/includes/db/migration/data/310/dev.php @@ -84,7 +84,7 @@ class phpbb_db_migration_data_310_dev extends phpbb_db_migration return array( array('config.update', array('search_type', 'phpbb_search_' . $this->config['search_type'])), - array('config.add', array('allow_forgot_password', 1)), + array('config.add', array('allow_password_reset', 1)), array('config.add', array('fulltext_postgres_ts_name', 'simple')), array('config.add', array('fulltext_postgres_min_word_len', 4)), diff --git a/phpBB/includes/ucp/ucp_remind.php b/phpBB/includes/ucp/ucp_remind.php index a25d7da91a..4a2d06e99a 100644 --- a/phpBB/includes/ucp/ucp_remind.php +++ b/phpBB/includes/ucp/ucp_remind.php @@ -29,7 +29,7 @@ class ucp_remind global $config, $phpbb_root_path, $phpEx; global $db, $user, $auth, $template; - if (!$config['allow_forgot_password']) + if (!$config['allow_password_reset']) { trigger_error($user->lang('UCP_FORGOT_PASSWORD_DISABLE', '', '')); } diff --git a/phpBB/install/schemas/schema_data.sql b/phpBB/install/schemas/schema_data.sql index d9ba09ff4d..9690ec14b8 100644 --- a/phpBB/install/schemas/schema_data.sql +++ b/phpBB/install/schemas/schema_data.sql @@ -18,7 +18,7 @@ INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_bbcode', '1' INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_birthdays', '1'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_bookmarks', '1'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_emailreuse', '0'); -INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_forgot_password', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_password_reset', '1'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_forum_notify', '1'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_mass_pm', '1'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_name_chars', 'USERNAME_CHARS_ANY'); diff --git a/phpBB/language/en/acp/board.php b/phpBB/language/en/acp/board.php index 4b2020b894..c0f6153788 100644 --- a/phpBB/language/en/acp/board.php +++ b/phpBB/language/en/acp/board.php @@ -454,8 +454,8 @@ $lang = array_merge($lang, array( 'ALL' => 'All', 'ALLOW_AUTOLOGIN' => 'Allow "Remember Me" logins', 'ALLOW_AUTOLOGIN_EXPLAIN' => 'Determines whether users are given "Remember Me" option when they visit the board.', - 'ALLOW_FORGOT_PASSWORD' => 'Allow "forgot password"', - 'ALLOW_FORGOT_PASSWORD_EXPLAIN' => 'Determines whether users can use the "forgot password" option to recover their account', + 'ALLOW_PASSWORD_RESET' => 'Allow "forgot password"', + 'ALLOW_PASSWORD_RESET_EXPLAIN' => 'Determines whether users can use the "forgot password" option to recover their account', 'AUTOLOGIN_LENGTH' => '"Remember Me" login key expiration length (in days)', 'AUTOLOGIN_LENGTH_EXPLAIN' => 'Number of days after which "Remember Me" login keys are removed or zero to disable.', 'BROWSER_VALID' => 'Validate browser', From f1e615c4297a509325b764e1966118fe171ebbb5 Mon Sep 17 00:00:00 2001 From: Dhruv Date: Sun, 27 Jan 2013 03:09:52 +0530 Subject: [PATCH 205/281] [ticket/10325] fix language variable PHPBB3-10325 --- phpBB/includes/ucp/ucp_remind.php | 2 +- phpBB/language/en/ucp.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/phpBB/includes/ucp/ucp_remind.php b/phpBB/includes/ucp/ucp_remind.php index 4a2d06e99a..cd4d13c8a7 100644 --- a/phpBB/includes/ucp/ucp_remind.php +++ b/phpBB/includes/ucp/ucp_remind.php @@ -31,7 +31,7 @@ class ucp_remind if (!$config['allow_password_reset']) { - trigger_error($user->lang('UCP_FORGOT_PASSWORD_DISABLE', '', '')); + trigger_error($user->lang('UCP_FORGOT_PASSWORD_DISABLED', '', '')); } $username = request_var('username', '', true); diff --git a/phpBB/language/en/ucp.php b/phpBB/language/en/ucp.php index ce93c7bcf8..3864414af0 100644 --- a/phpBB/language/en/ucp.php +++ b/phpBB/language/en/ucp.php @@ -521,7 +521,7 @@ $lang = array_merge($lang, array( 'UCP_USERGROUPS_MEMBER' => 'Edit memberships', 'UCP_USERGROUPS_MANAGE' => 'Manage groups', - 'UCP_FORGOT_PASSWORD_DISABLE' => 'The administrator has disabled the password reset ability. If you need help accessing your account, please contact the %sBoard Administrator%s', + 'UCP_FORGOT_PASSWORD_DISABLED' => 'The administrator has disabled the password reset ability. If you need help accessing your account, please contact the %sBoard Administrator%s', 'UCP_REGISTER_DISABLE' => 'Creating a new account is currently not possible.', 'UCP_REMIND' => 'Send password', 'UCP_RESEND' => 'Send activation email', From c048067bbd45b51595cc243cc4edde1d84eda405 Mon Sep 17 00:00:00 2001 From: Dhruv Date: Sun, 27 Jan 2013 11:27:28 +0530 Subject: [PATCH 206/281] [ticket/10325] fix language key PHPBB3-10325 --- phpBB/includes/ucp/ucp_remind.php | 2 +- phpBB/language/en/ucp.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/phpBB/includes/ucp/ucp_remind.php b/phpBB/includes/ucp/ucp_remind.php index cd4d13c8a7..ff7ab53736 100644 --- a/phpBB/includes/ucp/ucp_remind.php +++ b/phpBB/includes/ucp/ucp_remind.php @@ -31,7 +31,7 @@ class ucp_remind if (!$config['allow_password_reset']) { - trigger_error($user->lang('UCP_FORGOT_PASSWORD_DISABLED', '', '')); + trigger_error($user->lang('UCP_PASSWORD_RESET_DISABLED', '', '')); } $username = request_var('username', '', true); diff --git a/phpBB/language/en/ucp.php b/phpBB/language/en/ucp.php index 3864414af0..920dfaf176 100644 --- a/phpBB/language/en/ucp.php +++ b/phpBB/language/en/ucp.php @@ -521,7 +521,7 @@ $lang = array_merge($lang, array( 'UCP_USERGROUPS_MEMBER' => 'Edit memberships', 'UCP_USERGROUPS_MANAGE' => 'Manage groups', - 'UCP_FORGOT_PASSWORD_DISABLED' => 'The administrator has disabled the password reset ability. If you need help accessing your account, please contact the %sBoard Administrator%s', + 'UCP_PASSWORD_RESET_DISABLED' => 'The administrator has disabled the password reset ability. If you need help accessing your account, please contact the %sBoard Administrator%s', 'UCP_REGISTER_DISABLE' => 'Creating a new account is currently not possible.', 'UCP_REMIND' => 'Send password', 'UCP_RESEND' => 'Send activation email', From 419aaa402f025d16e8b823586e32917d1d036599 Mon Sep 17 00:00:00 2001 From: Dhruv Date: Mon, 28 Jan 2013 01:05:04 +0530 Subject: [PATCH 207/281] [ticket/10325] improve acp option language PHPBB3-10325 --- phpBB/language/en/acp/board.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/language/en/acp/board.php b/phpBB/language/en/acp/board.php index c0f6153788..c084779a26 100644 --- a/phpBB/language/en/acp/board.php +++ b/phpBB/language/en/acp/board.php @@ -455,7 +455,7 @@ $lang = array_merge($lang, array( 'ALLOW_AUTOLOGIN' => 'Allow "Remember Me" logins', 'ALLOW_AUTOLOGIN_EXPLAIN' => 'Determines whether users are given "Remember Me" option when they visit the board.', 'ALLOW_PASSWORD_RESET' => 'Allow "forgot password"', - 'ALLOW_PASSWORD_RESET_EXPLAIN' => 'Determines whether users can use the "forgot password" option to recover their account', + 'ALLOW_PASSWORD_RESET_EXPLAIN' => 'Determines whether or not users are able to use the "I forgot my password" link on the login page to recover their account. This feature can be disabled when using an external authentication plugin.', 'AUTOLOGIN_LENGTH' => '"Remember Me" login key expiration length (in days)', 'AUTOLOGIN_LENGTH_EXPLAIN' => 'Number of days after which "Remember Me" login keys are removed or zero to disable.', 'BROWSER_VALID' => 'Validate browser', From d242b7a1a5c9b6ecc8bc21027a33bc344501a0ce Mon Sep 17 00:00:00 2001 From: Dhruv Date: Thu, 25 Apr 2013 21:05:02 +0530 Subject: [PATCH 208/281] [ticket/10325] fix language in acp and ucp PHPBB3-10325 --- phpBB/language/en/acp/board.php | 2 +- phpBB/language/en/ucp.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/phpBB/language/en/acp/board.php b/phpBB/language/en/acp/board.php index c084779a26..39ad5b78bb 100644 --- a/phpBB/language/en/acp/board.php +++ b/phpBB/language/en/acp/board.php @@ -455,7 +455,7 @@ $lang = array_merge($lang, array( 'ALLOW_AUTOLOGIN' => 'Allow "Remember Me" logins', 'ALLOW_AUTOLOGIN_EXPLAIN' => 'Determines whether users are given "Remember Me" option when they visit the board.', 'ALLOW_PASSWORD_RESET' => 'Allow "forgot password"', - 'ALLOW_PASSWORD_RESET_EXPLAIN' => 'Determines whether or not users are able to use the "I forgot my password" link on the login page to recover their account. This feature can be disabled when using an external authentication plugin.', + 'ALLOW_PASSWORD_RESET_EXPLAIN' => 'Determines whether or not users are able to use the "I forgot my password" link on the login page to recover their account. If you use an external authentication mechanism you may wish to disable this feature.', 'AUTOLOGIN_LENGTH' => '"Remember Me" login key expiration length (in days)', 'AUTOLOGIN_LENGTH_EXPLAIN' => 'Number of days after which "Remember Me" login keys are removed or zero to disable.', 'BROWSER_VALID' => 'Validate browser', diff --git a/phpBB/language/en/ucp.php b/phpBB/language/en/ucp.php index 920dfaf176..372e44a94d 100644 --- a/phpBB/language/en/ucp.php +++ b/phpBB/language/en/ucp.php @@ -521,7 +521,7 @@ $lang = array_merge($lang, array( 'UCP_USERGROUPS_MEMBER' => 'Edit memberships', 'UCP_USERGROUPS_MANAGE' => 'Manage groups', - 'UCP_PASSWORD_RESET_DISABLED' => 'The administrator has disabled the password reset ability. If you need help accessing your account, please contact the %sBoard Administrator%s', + 'UCP_PASSWORD_RESET_DISABLED' => 'The administrator has disabled the password reset functionality. If you need help accessing your account, please contact the %sBoard Administrator%s', 'UCP_REGISTER_DISABLE' => 'Creating a new account is currently not possible.', 'UCP_REMIND' => 'Send password', 'UCP_RESEND' => 'Send activation email', From 42cfb7264dec3a1e8f141ff40b17b841e5c998cc Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Thu, 25 Apr 2013 10:58:48 -0500 Subject: [PATCH 209/281] [ticket/11237] Fix PHP error in acp_prune.php Also making the code a bit more efficient (removing one SQL query) PHPBB3-11237 --- phpBB/includes/acp/acp_prune.php | 36 +++++++++++++------------------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/phpBB/includes/acp/acp_prune.php b/phpBB/includes/acp/acp_prune.php index a5dc02849a..54ffe24594 100644 --- a/phpBB/includes/acp/acp_prune.php +++ b/phpBB/includes/acp/acp_prune.php @@ -491,11 +491,12 @@ class acp_prune if ($group_id) { - $sql = 'SELECT user_id - FROM ' . USER_GROUP_TABLE . ' - WHERE group_id = ' . (int) $group_id . ' - AND user_pending = 0 - AND ' . $db->sql_in_set('user_id', $user_ids, false, true); + $sql = 'SELECT u.user_id, u.username + FROM ' . USER_GROUP_TABLE . ' ug, ' . USERS_TABLE . ' u + WHERE ug.group_id = ' . (int) $group_id . ' + AND ug.user_pending = 0 + AND ' . $db->sql_in_set('ug.user_id', $user_ids, false, true) . ' + AND u.user_id = ug.user_id'; $result = $db->sql_query($sql); // we're performing an intersection operation, so all the relevant users @@ -504,24 +505,19 @@ class acp_prune $user_ids = $usernames = array(); while ($row = $db->sql_fetchrow($result)) { - $user_ids[] = $row['poster_id']; + $user_ids[] = $row['user_id']; + $usernames[$row['user_id']] = $row['username']; } $db->sql_freeresult($result); - - // only get usernames if they are needed (not part of some later query) - if (!$posts_on_queue) - { - // this is an additional query aginst the users table - user_get_id_name($user_ids, $usernames); - } } if ($posts_on_queue) { - $sql = 'SELECT poster_id, COUNT(post_id) AS queue_posts - FROM ' . POSTS_TABLE . ' - WHERE ' . $db->sql_in_set('poster_id', $user_ids, false, true) . ' - GROUP BY poster_id + $sql = 'SELECT u.user_id, u.username, COUNT(p.post_id) AS queue_posts + FROM ' . POSTS_TABLE . ' p, ' . USERS_TABLE . ' u + WHERE ' . $db->sql_in_set('p.poster_id', $user_ids, false, true) . ' + AND u.user_id = p.poster_id + GROUP BY p.poster_id HAVING queue_posts ' . $key_match[$queue_select] . ' ' . $posts_on_queue; $result = $db->sql_query($result); @@ -529,12 +525,10 @@ class acp_prune $user_ids = $usernames = array(); while ($row = $db->sql_fetchrow($result)) { - $user_ids[] = $row['poster_id']; + $user_ids[] = $row['user_id']; + $usernames[$row['user_id']] = $row['username']; } $db->sql_freeresult($result); - - // do an additional query to get the correct set of usernames - user_get_id_name($user_ids, $usernames); } } } From 0def8b7d9cb06cd2abf462f18f1404fc119861bd Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 25 Apr 2013 18:09:21 +0200 Subject: [PATCH 210/281] [ticket/11495] Use constructor arguments over properties in implementation PHPBB3-11495 --- phpBB/includes/tree/nestedset.php | 31 ++++++++++++++++++++ phpBB/includes/tree/nestedset_forum.php | 38 +++++++++++-------------- 2 files changed, 47 insertions(+), 22 deletions(-) diff --git a/phpBB/includes/tree/nestedset.php b/phpBB/includes/tree/nestedset.php index 8f73b9181e..245a8165ef 100644 --- a/phpBB/includes/tree/nestedset.php +++ b/phpBB/includes/tree/nestedset.php @@ -55,6 +55,37 @@ abstract class phpbb_tree_nestedset implements phpbb_tree_interface */ protected $item_basic_data = array('*'); + /** + * Construct + * + * @param phpbb_db_driver $db Database connection + * @param phpbb_lock_db $lock Lock class used to lock the table when moving forums around + * @param string $table_name Table name + * @param string $message_prefix Prefix for the messages thrown by exceptions + * @param string $sql_where Additional SQL restrictions for the queries + * @param array $item_basic_data Array with basic item data that is stored in item_parents + * @param array $columns Array with column names to overwrite + */ + public function __construct(phpbb_db_driver $db, phpbb_lock_db $lock, $table_name, $message_prefix = '', $sql_where = '', $item_basic_data = array(), $columns = array()) + { + $this->db = $db; + $this->lock = $lock; + + $this->table_name = $table_name; + $this->message_prefix = $message_prefix; + $this->sql_where = $sql_where; + $this->item_basic_data = (!empty($item_basic_data)) ? $item_basic_data : array('*'); + + if (!empty($columns)) + { + foreach ($columns as $column => $name) + { + $column_name = 'column_' . $column; + $this->$column_name = $name; + } + } + } + /** * Returns additional sql where restrictions * diff --git a/phpBB/includes/tree/nestedset_forum.php b/phpBB/includes/tree/nestedset_forum.php index 0a66e68915..7dcb12331c 100644 --- a/phpBB/includes/tree/nestedset_forum.php +++ b/phpBB/includes/tree/nestedset_forum.php @@ -17,25 +17,6 @@ if (!defined('IN_PHPBB')) class phpbb_tree_nestedset_forum extends phpbb_tree_nestedset { - /** - * Column names in the table - * @var string - */ - protected $column_item_id = 'forum_id'; - protected $column_item_parents = 'forum_parents'; - - /** - * Prefix for the language keys returned by exceptions - * @var string - */ - protected $message_prefix = 'FORUM_NESTEDSET_'; - - /** - * List of item properties to be cached in $item_parents - * @var array - */ - protected $item_basic_data = array('forum_id', 'forum_name', 'forum_type'); - /** * Construct * @@ -45,8 +26,21 @@ class phpbb_tree_nestedset_forum extends phpbb_tree_nestedset */ public function __construct(phpbb_db_driver $db, phpbb_lock_db $lock, $table_name) { - $this->db = $db; - $this->lock = $lock; - $this->table_name = $table_name; + parent::__construct( + $db, + $lock, + $table_name, + 'FORUM_NESTEDSET_', + '', + array( + 'forum_id', + 'forum_name', + 'forum_type', + ), + array( + 'item_id' => 'forum_id', + 'item_parents' => 'forum_parents', + ) + ); } } From ee457e584c66938cc521eecf0ec303a81c536896 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Thu, 25 Apr 2013 11:16:00 -0500 Subject: [PATCH 211/281] [ticket/11236] Correct HTML PHPBB3-11236 --- phpBB/includes/acp/acp_prune.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/includes/acp/acp_prune.php b/phpBB/includes/acp/acp_prune.php index a5dc02849a..e43f1558b1 100644 --- a/phpBB/includes/acp/acp_prune.php +++ b/phpBB/includes/acp/acp_prune.php @@ -340,7 +340,7 @@ class acp_prune while ($row = $db->sql_fetchrow($result)) { - $s_group_list .= ''; } $db->sql_freeresult($result); From 1a16ee4cb270f81ebeb8697e4bffaaa305010116 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Thu, 25 Apr 2013 11:20:13 -0500 Subject: [PATCH 212/281] [ticket/11236] Do not require group selection in prune users PHPBB3-11236 --- phpBB/includes/acp/acp_prune.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/includes/acp/acp_prune.php b/phpBB/includes/acp/acp_prune.php index e43f1558b1..dc0f9a345f 100644 --- a/phpBB/includes/acp/acp_prune.php +++ b/phpBB/includes/acp/acp_prune.php @@ -331,7 +331,7 @@ class acp_prune $s_find_active_time .= ''; } - $s_group_list = ''; + $s_group_list = ''; $sql = 'SELECT group_id, group_name FROM ' . GROUPS_TABLE . ' WHERE group_type <> ' . GROUP_SPECIAL . ' From e7cb0f687df93120b003ad205fc6cb3315379c80 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Thu, 25 Apr 2013 11:23:09 -0500 Subject: [PATCH 213/281] [ticket/11236] Change PRUNE_USERS_GROUP_EXPLAIN language PHPBB3-11236 --- phpBB/language/en/acp/prune.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/language/en/acp/prune.php b/phpBB/language/en/acp/prune.php index fcc085205b..3e890182c0 100644 --- a/phpBB/language/en/acp/prune.php +++ b/phpBB/language/en/acp/prune.php @@ -51,7 +51,7 @@ $lang = array_merge($lang, array( 'LAST_ACTIVE_EXPLAIN' => 'Enter a date in YYYY-MM-DD format. Enter 0000-00-00 to prune users who never logged in, Before and After conditions will be ignored.', 'POSTS_ON_QUEUE' => 'Posts Awaiting Approval', - 'PRUNE_USERS_GROUP_EXPLAIN' => 'Selects all members of the group for pruning.', + 'PRUNE_USERS_GROUP_EXPLAIN' => 'Limit to users within the selected group.', 'PRUNE_USERS_LIST' => 'Users to be pruned', 'PRUNE_USERS_LIST_DELETE' => 'With the selected critera for pruning users the following accounts will be removed. You can remove individual users from the deletion list by unchecking the box next to their username.', 'PRUNE_USERS_LIST_DEACTIVATE' => 'With the selected critera for pruning users the following accounts will be deactivated. You can remove individual users from the deactivation list by unchecking the box next to their username.', From 2fa5f9591e06e82ca76e7ac7e653d8ad4494eb67 Mon Sep 17 00:00:00 2001 From: Dhruv Date: Thu, 25 Apr 2013 22:52:40 +0530 Subject: [PATCH 214/281] [ticket/10325] add logout function in functional_test_case PHPBB3-10325 --- tests/test_framework/phpbb_functional_test_case.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/test_framework/phpbb_functional_test_case.php b/tests/test_framework/phpbb_functional_test_case.php index 5534de89c9..dae37f336d 100644 --- a/tests/test_framework/phpbb_functional_test_case.php +++ b/tests/test_framework/phpbb_functional_test_case.php @@ -425,6 +425,17 @@ class phpbb_functional_test_case extends phpbb_test_case } } + protected function logout() + { + $this->add_lang('ucp'); + + $crawler = $this->request('GET', 'ucp.php?sid=' . $this->sid . '&mode=logout'); + $this->assert_response_success(); + $this->assertContains($this->lang('LOGOUT_REDIRECT'), $crawler->filter('#message')->text()); + unset($this->sid); + + } + /** * Login to the ACP * You must run login() before calling this. From 27aa5e7b713b58eb0afb8d92e684a6868eb080ce Mon Sep 17 00:00:00 2001 From: Dhruv Date: Thu, 25 Apr 2013 22:58:03 +0530 Subject: [PATCH 215/281] [ticket/10325] functional tests for forgot password functionality PHPBB3-10325 --- tests/functional/forgot_password_test.php | 45 +++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 tests/functional/forgot_password_test.php diff --git a/tests/functional/forgot_password_test.php b/tests/functional/forgot_password_test.php new file mode 100644 index 0000000000..3ae74ed1e9 --- /dev/null +++ b/tests/functional/forgot_password_test.php @@ -0,0 +1,45 @@ +add_lang('ucp'); + $crawler = $this->request('GET', 'ucp.php?mode=sendpassword'); + $this->assertEquals($this->lang('SEND_PASSWORD'), $crawler->filter('h2')->text()); + } + + public function test_forgot_password_disabled() + { + $this->login(); + $this->admin_login(); + $this->add_lang('ucp'); + $crawler = $this->request('GET', 'adm/index.php?sid=' . $this->sid . '&i=acp_board&mode=security'); + + $form = $crawler->selectButton('Submit')->form(); + $values = $form->getValues(); + + $values["config[allow_password_reset]"] = 0; + $form->setValues($values); + $crawler = $this->client->submit($form); + + $this->logout(); + + $crawler = $this->request('GET', 'ucp.php?mode=sendpassword'); + + $this->assertContains($this->lang('UCP_PASSWORD_RESET_DISABLED', '', ''), $crawler->text()); + + } + +} From 6801e36defcd9628a7feeebd01c6f34366b70542 Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Thu, 25 Apr 2013 14:13:21 -0500 Subject: [PATCH 216/281] [ticket/11435] Fix comments in events test PHPBB3-11435 --- tests/template/template_events_test.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/template/template_events_test.php b/tests/template/template_events_test.php index 6cea9b92e3..0ac50c7f2b 100644 --- a/tests/template/template_events_test.php +++ b/tests/template/template_events_test.php @@ -16,9 +16,10 @@ class phpbb_template_template_events_test extends phpbb_template_template_test_c return array( /* array( - '', // file + '', // Description '', // dataset array(), // style names + '', // file array(), // vars array(), // block vars array(), // destroy From ab87fe7982b185e9c08a3fd7248214004b23a58b Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Thu, 25 Apr 2013 14:15:04 -0500 Subject: [PATCH 217/281] [ticket/11435] Create test to make sure template/event output is equal PHPBB3-11435 --- .../styles/all/template/variable_spacing.html | 6 ++ .../silver/template/variable_spacing.html | 1 + tests/template/template_spacing_test.php | 87 +++++++++++++++++++ .../template/templates/variable_spacing.html | 6 ++ 4 files changed, 100 insertions(+) create mode 100644 tests/template/datasets/ext_trivial/ext/trivial/styles/all/template/variable_spacing.html create mode 100644 tests/template/datasets/ext_trivial/styles/silver/template/variable_spacing.html create mode 100644 tests/template/template_spacing_test.php create mode 100644 tests/template/templates/variable_spacing.html diff --git a/tests/template/datasets/ext_trivial/ext/trivial/styles/all/template/variable_spacing.html b/tests/template/datasets/ext_trivial/ext/trivial/styles/all/template/variable_spacing.html new file mode 100644 index 0000000000..2909e1c136 --- /dev/null +++ b/tests/template/datasets/ext_trivial/ext/trivial/styles/all/template/variable_spacing.html @@ -0,0 +1,6 @@ +|{VARIABLE}| +{VARIABLE}|{VARIABLE}| + +|{VARIABLE} + +
      test
      \ No newline at end of file diff --git a/tests/template/datasets/ext_trivial/styles/silver/template/variable_spacing.html b/tests/template/datasets/ext_trivial/styles/silver/template/variable_spacing.html new file mode 100644 index 0000000000..c11ae9cb40 --- /dev/null +++ b/tests/template/datasets/ext_trivial/styles/silver/template/variable_spacing.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/tests/template/template_spacing_test.php b/tests/template/template_spacing_test.php new file mode 100644 index 0000000000..83f8711b38 --- /dev/null +++ b/tests/template/template_spacing_test.php @@ -0,0 +1,87 @@ + '{}', + ), + array(), + array(), + '|{}| +{}|{}| +|{} +
      test
      ', + ), + ); + } + + /** + * @dataProvider template_data + */ + public function test_template($desc, $dataset, $style_names, $file, array $vars, array $block_vars, array $destroy, $expected) + { + // Run test + $cache_file = $this->template->cachepath . str_replace('/', '.', $file) . '.php'; + $this->run_template($file, $vars, $block_vars, $destroy, $expected, $cache_file); + } + + /** + * @dataProvider template_data + */ + public function test_event($desc, $dataset, $style_names, $file, array $vars, array $block_vars, array $destroy, $expected) + { + // Reset the engine state + $this->setup_engine_for_events($dataset, $style_names); + + // Run test + $cache_file = $this->template->cachepath . str_replace('/', '.', $file) . '.php'; + $this->run_template($file, $vars, $block_vars, $destroy, $expected, $cache_file); + } + + protected function setup_engine_for_events($dataset, $style_names, array $new_config = array()) + { + global $phpbb_root_path, $phpEx, $user; + + $defaults = $this->config_defaults(); + $config = new phpbb_config(array_merge($defaults, $new_config)); + + $this->template_path = dirname(__FILE__) . "/datasets/$dataset/styles/silver/template"; + $this->style_resource_locator = new phpbb_style_resource_locator(); + $this->extension_manager = new phpbb_mock_filesystem_extension_manager( + dirname(__FILE__) . "/datasets/$dataset/" + ); + $this->template = new phpbb_template($phpbb_root_path, $phpEx, $config, $user, $this->style_resource_locator, new phpbb_template_context, $this->extension_manager); + $this->style_provider = new phpbb_style_path_provider(); + $this->style = new phpbb_style($phpbb_root_path, $phpEx, $config, $user, $this->style_resource_locator, $this->style_provider, $this->template); + $this->style->set_custom_style('silver', array($this->template_path), $style_names, ''); + } +} diff --git a/tests/template/templates/variable_spacing.html b/tests/template/templates/variable_spacing.html new file mode 100644 index 0000000000..2909e1c136 --- /dev/null +++ b/tests/template/templates/variable_spacing.html @@ -0,0 +1,6 @@ +|{VARIABLE}| +{VARIABLE}|{VARIABLE}| + +|{VARIABLE} + +
      test
      \ No newline at end of file From baff4287e5a7142b7af41e56c29b064bb56fd7fb Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 25 Apr 2013 22:39:24 +0200 Subject: [PATCH 218/281] [ticket/11495] Fix comments and package docs PHPBB3-11495 --- phpBB/includes/tree/interface.php | 6 +++--- phpBB/includes/tree/nestedset.php | 2 +- phpBB/includes/tree/nestedset_forum.php | 2 +- tests/tree/nestedset_forum_base.php | 2 +- tests/tree/nestedset_forum_get_data_test.php | 2 +- tests/tree/nestedset_forum_insert_delete_test.php | 2 +- tests/tree/nestedset_forum_move_test.php | 2 +- tests/tree/nestedset_forum_regenerate_test.php | 2 +- tests/tree/nestedset_forum_test.php | 2 +- 9 files changed, 11 insertions(+), 11 deletions(-) diff --git a/phpBB/includes/tree/interface.php b/phpBB/includes/tree/interface.php index 3f03363151..4e22e322f3 100644 --- a/phpBB/includes/tree/interface.php +++ b/phpBB/includes/tree/interface.php @@ -1,7 +1,7 @@ Date: Fri, 26 Apr 2013 00:04:58 +0200 Subject: [PATCH 219/281] [ticket/11495] Make method names for add/remove more descriptive PHPBB3-11495 --- phpBB/includes/tree/nestedset.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/phpBB/includes/tree/nestedset.php b/phpBB/includes/tree/nestedset.php index ffe8687e54..ab6a9d6bb4 100644 --- a/phpBB/includes/tree/nestedset.php +++ b/phpBB/includes/tree/nestedset.php @@ -111,7 +111,7 @@ abstract class phpbb_tree_nestedset implements phpbb_tree_interface $item_data[$this->column_item_id] = (int) $this->db->sql_nextid(); - return array_merge($item_data, $this->add($item_data)); + return array_merge($item_data, $this->add_item_to_nestedset($item_data)); } /** @@ -120,7 +120,7 @@ abstract class phpbb_tree_nestedset implements phpbb_tree_interface * @param array $item The item to be added * @return bool True if the item was added */ - protected function add(array $item) + protected function add_item_to_nestedset(array $item) { $sql = 'SELECT MAX(' . $this->column_right_id . ') AS ' . $this->column_right_id . ' FROM ' . $this->table_name . ' @@ -152,7 +152,7 @@ abstract class phpbb_tree_nestedset implements phpbb_tree_interface * @param int $item_id The item to be deleted * @return array Item ids that have been removed */ - protected function remove($item_id) + protected function remove_item_from_nestedset($item_id) { $items = $this->get_children_branch_data($item_id); $item_ids = array_keys($items); @@ -167,7 +167,7 @@ abstract class phpbb_tree_nestedset implements phpbb_tree_interface */ public function delete($item_id) { - $removed_items = $this->remove($item_id); + $removed_items = $this->remove_item_from_nestedset($item_id); $sql = 'DELETE FROM ' . $this->table_name . ' WHERE ' . $this->db->sql_in_set($this->column_item_id, $removed_items) . ' From 2afa6730232cc2e92ae6543852d031a29c8a361f Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 26 Apr 2013 08:42:44 +0200 Subject: [PATCH 220/281] [ticket/11495] Fix doc blocks once more PHPBB3-11495 --- phpBB/includes/tree/interface.php | 6 +++--- phpBB/includes/tree/nestedset.php | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/phpBB/includes/tree/interface.php b/phpBB/includes/tree/interface.php index 4e22e322f3..ed0ccca3f1 100644 --- a/phpBB/includes/tree/interface.php +++ b/phpBB/includes/tree/interface.php @@ -18,7 +18,7 @@ if (!defined('IN_PHPBB')) interface phpbb_tree_interface { /** - * Insert an item into the tree (also insert the rows into the table) + * Inserts an item into the database table and into the tree. * * @param array $item The item to be added * @return array Array with item data as set in the database @@ -26,9 +26,9 @@ interface phpbb_tree_interface public function insert(array $additional_data); /** - * Delete an item from the tree (also deletes the rows form the table) + * Delete an item from the tree and from the database table * - * Also deletes all subitems from the tree + * Also deletes all subitems from the tree and from the database table * * @param int $item_id The item to be deleted * @return array Item ids that have been deleted diff --git a/phpBB/includes/tree/nestedset.php b/phpBB/includes/tree/nestedset.php index ab6a9d6bb4..9655a08aa5 100644 --- a/phpBB/includes/tree/nestedset.php +++ b/phpBB/includes/tree/nestedset.php @@ -115,7 +115,7 @@ abstract class phpbb_tree_nestedset implements phpbb_tree_interface } /** - * Add an existing item at the end of the tree + * Add an item which already has a database row at the end of the tree * * @param array $item The item to be added * @return bool True if the item was added @@ -145,9 +145,9 @@ abstract class phpbb_tree_nestedset implements phpbb_tree_interface } /** - * Remove an item from the tree WITHOUT removing the items from the table + * Remove an item from the tree without deleting it from the database * - * Also removes all subitems from the tree + * Also removes all subitems from the tree without deleting them from the database either * * @param int $item_id The item to be deleted * @return array Item ids that have been removed From cb13add269b78e1a9ac84a80c78557bb7695df09 Mon Sep 17 00:00:00 2001 From: marc1706 Date: Sun, 28 Apr 2013 22:54:48 +0200 Subject: [PATCH 221/281] [ticket/11442] Use correct button class for ajaxified confirm_box In commit 001572f the HTML code for the ajaxified confirm_box was moved from overall_footer.html to confirm_body.html. While copying, the CSS class of the "Yes" button was changed from button1 to button2. Due to the fact that the phpbb.confirm() method uses the class button1 to check if "Yes" was clicked, this broke the ajaxified confirm box in the ACP. With this small patch the confirm boxes in the ACP should work properly again. PHPBB3-11442 --- phpBB/adm/style/confirm_body.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/adm/style/confirm_body.html b/phpBB/adm/style/confirm_body.html index d0360d1b3a..fa3f1e6c64 100644 --- a/phpBB/adm/style/confirm_body.html +++ b/phpBB/adm/style/confirm_body.html @@ -4,7 +4,7 @@

      {MESSAGE_TEXT}

      -   +  
      From 947550df8f5e2ba624adc26ddd22c7fe74e4f602 Mon Sep 17 00:00:00 2001 From: Vjacheslav Trushkin Date: Tue, 30 Apr 2013 11:27:43 +0300 Subject: [PATCH 222/281] [ticket/10741] Docblock for phpbb.resizeTextArea Better description of phpBB.resizeTextArea with detailed explanation of all optional parameters. Removed unnecessary semicolons PHPBB3-10741 --- phpBB/assets/javascript/core.js | 41 +++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/phpBB/assets/javascript/core.js b/phpBB/assets/javascript/core.js index 827ed2e34a..bb1fef253e 100644 --- a/phpBB/assets/javascript/core.js +++ b/phpBB/assets/javascript/core.js @@ -571,28 +571,39 @@ phpbb.addAjaxCallback('toggle_link', function() { /** * Automatically resize textarea * -* This function automatically resizes textarea elements when user +* This function automatically resizes textarea elements when user * types text. * -* @param jQuery item jQuery object to resize -* @param object options Optional parameter that adjusts default +* @param {jQuery} items jQuery object(s) to resize +* @param {object} options Optional parameter that adjusts default * configuration. See configuration variable +* +* Optional parameters: +* minWindowHeight {number} Minimum browser window height when textareas are resized. Default = 500 +* minHeight {number} Minimum height of textarea. Default = 200 +* maxHeight {number} Maximum height of textarea. Default = 500 +* heightDiff {number} Minimum difference between window and textarea height. Default = 200 +* resizeCallback {function} Function to call after resizing textarea +* resetCallback {function} Function to call when resize has been canceled + +* Callback function format: function(item) {} +* this points to DOM object +* item is a jQuery object, same as this */ -phpbb.resizeTextArea = function(items) { +phpbb.resizeTextArea = function(items, options) { // Configuration var configuration = { - minWindowHeight: 500, // Minimum browser window height when textareas are resized - minHeight: 200, // Minimum height of textarea - maxHeight: 500, // Maximum height of textarea - heightDiff: 200, // Minimum difference between window and textarea height - // In following callbacks parameter "item" is jQuery object. "this" points to DOM object - resizeCallback: function(item) { }, // Function to call after resizing textarea. - resetCallback: function(item) { } // Function to call when resize has been canceled - } + minWindowHeight: 500, + minHeight: 200, + maxHeight: 500, + heightDiff: 200, + resizeCallback: function(item) { }, + resetCallback: function(item) { } + }; if (arguments.length > 1) { - configuration = $.extend(configuration, arguments[1]); + configuration = $.extend(configuration, options); } function resetAutoResize(item) @@ -603,7 +614,7 @@ phpbb.resizeTextArea = function(items) { $(item).css({height: '', resize: ''}).removeClass('auto-resized'); configuration.resetCallback.call(item, $item); } - }; + } function autoResize(item) { @@ -634,7 +645,7 @@ phpbb.resizeTextArea = function(items) { { setHeight(Math.min(maxHeight, scrollHeight)); } - }; + } items.bind('focus change keyup', function() { $(this).each(function() { From 8a4260703fa76bb92f144b527b3d55289568db74 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 30 Apr 2013 10:32:01 +0200 Subject: [PATCH 223/281] [ticket/11495] Fix some docs and replace branch with other terms PHPBB3-11495 --- phpBB/includes/tree/interface.php | 20 ++++++++-------- phpBB/includes/tree/nestedset.php | 24 ++++++++++---------- tests/tree/nestedset_forum_get_data_test.php | 24 ++++++++++---------- 3 files changed, 34 insertions(+), 34 deletions(-) diff --git a/phpBB/includes/tree/interface.php b/phpBB/includes/tree/interface.php index ed0ccca3f1..1b462768a0 100644 --- a/phpBB/includes/tree/interface.php +++ b/phpBB/includes/tree/interface.php @@ -28,12 +28,12 @@ interface phpbb_tree_interface /** * Delete an item from the tree and from the database table * - * Also deletes all subitems from the tree and from the database table + * Also deletes the subtree from the tree and from the database table * * @param int $item_id The item to be deleted * @return array Item ids that have been deleted */ - public function delete($item); + public function delete($item_id); /** * Move an item by a given delta @@ -79,16 +79,16 @@ interface phpbb_tree_interface /** * Change parent item * - * Moves the item to the bottom of the new parent's list of children + * Moves the item to the bottom of the new parent's subtree * * @param int $item_id The item to be moved * @param int $new_parent_id The new parent item * @return bool True if the parent was set successfully */ - public function change_parent($item, $new_parent_id); + public function change_parent($item_id, $new_parent_id); /** - * Get children and parent branch of the item + * Get all items that are either a parent or part of the subtree of the item * * @param int $item_id The item id to get the parents/children from * @param bool $order_desc Order the items descending (most outer parent first) @@ -96,10 +96,10 @@ interface phpbb_tree_interface * @return array Array of items (containing all columns from the item table) * ID => Item data */ - public function get_full_branch_data($item_id, $order_desc, $include_item); + public function get_path_and_subtree_data($item_id, $order_desc, $include_item); /** - * Get parent branch of the item + * Get all parent items of the item * * @param int $item_id The item id to get the parents from * @param bool $order_desc Order the items descending (most outer parent first) @@ -107,10 +107,10 @@ interface phpbb_tree_interface * @return array Array of items (containing all columns from the item table) * ID => Item data */ - public function get_parent_branch_data($item_id, $order_desc, $include_item); + public function get_path_data($item_id, $order_desc, $include_item); /** - * Get children branch of the item + * Get all items of the item's subtree * * @param int $item_id The item id to get the children from * @param bool $order_desc Order the items descending (most outer parent first) @@ -118,7 +118,7 @@ interface phpbb_tree_interface * @return array Array of items (containing all columns from the item table) * ID => Item data */ - public function get_children_branch_data($item_id, $order_desc, $include_item); + public function get_subtree_data($item_id, $order_desc, $include_item); /** * Get base information of parent items diff --git a/phpBB/includes/tree/nestedset.php b/phpBB/includes/tree/nestedset.php index 9655a08aa5..10ab6a86e3 100644 --- a/phpBB/includes/tree/nestedset.php +++ b/phpBB/includes/tree/nestedset.php @@ -154,7 +154,7 @@ abstract class phpbb_tree_nestedset implements phpbb_tree_interface */ protected function remove_item_from_nestedset($item_id) { - $items = $this->get_children_branch_data($item_id); + $items = $this->get_subtree_data($item_id); $item_ids = array_keys($items); $this->remove_subset($item_ids, $items[$item_id]); @@ -338,7 +338,7 @@ abstract class phpbb_tree_nestedset implements phpbb_tree_interface throw new RuntimeException($this->message_prefix . 'LOCK_FAILED_ACQUIRE'); } - $item_data = $this->get_children_branch_data($current_parent_id); + $item_data = $this->get_subtree_data($current_parent_id); if (!isset($item_data[$current_parent_id])) { $this->lock->release(); @@ -447,7 +447,7 @@ abstract class phpbb_tree_nestedset implements phpbb_tree_interface throw new RuntimeException($this->message_prefix . 'LOCK_FAILED_ACQUIRE'); } - $item_data = $this->get_children_branch_data($item_id); + $item_data = $this->get_subtree_data($item_id); if (!isset($item_data[$item_id])) { $this->lock->release(); @@ -529,45 +529,45 @@ abstract class phpbb_tree_nestedset implements phpbb_tree_interface /** * @inheritdoc */ - public function get_full_branch_data($item_id, $order_desc = true, $include_item = true) + public function get_path_and_subtree_data($item_id, $order_desc = true, $include_item = true) { $condition = 'i2.' . $this->column_left_id . ' BETWEEN i1.' . $this->column_left_id . ' AND i1.' . $this->column_right_id . ' OR i1.' . $this->column_left_id . ' BETWEEN i2.' . $this->column_left_id . ' AND i2.' . $this->column_right_id; - return $this->get_branch_data($item_id, $condition, $order_desc, $include_item); + return $this->get_set_of_nodes_data($item_id, $condition, $order_desc, $include_item); } /** * @inheritdoc */ - public function get_parent_branch_data($item_id, $order_desc = true, $include_item = true) + public function get_path_data($item_id, $order_desc = true, $include_item = true) { $condition = 'i1.' . $this->column_left_id . ' BETWEEN i2.' . $this->column_left_id . ' AND i2.' . $this->column_right_id . ''; - return $this->get_branch_data($item_id, $condition, $order_desc, $include_item); + return $this->get_set_of_nodes_data($item_id, $condition, $order_desc, $include_item); } /** * @inheritdoc */ - public function get_children_branch_data($item_id, $order_desc = true, $include_item = true) + public function get_subtree_data($item_id, $order_desc = true, $include_item = true) { $condition = 'i2.' . $this->column_left_id . ' BETWEEN i1.' . $this->column_left_id . ' AND i1.' . $this->column_right_id . ''; - return $this->get_branch_data($item_id, $condition, $order_desc, $include_item); + return $this->get_set_of_nodes_data($item_id, $condition, $order_desc, $include_item); } /** - * Get children and parent branch of the item + * Get items that are related to the given item by the condition * - * @param int $item_id The item id to get the parents/children from + * @param int $item_id The item id to get the node set from * @param string $condition Query string restricting the item list * @param bool $order_desc Order the items descending (most outer parent first) * @param bool $include_item Should the item (matching the given item id) be included in the list aswell * @return array Array of items (containing all columns from the item table) * ID => Item data */ - protected function get_branch_data($item_id, $condition, $order_desc = true, $include_item = true) + protected function get_set_of_nodes_data($item_id, $condition, $order_desc = true, $include_item = true) { $rows = array(); diff --git a/tests/tree/nestedset_forum_get_data_test.php b/tests/tree/nestedset_forum_get_data_test.php index 71c1d8bf8a..300bbc6bfa 100644 --- a/tests/tree/nestedset_forum_get_data_test.php +++ b/tests/tree/nestedset_forum_get_data_test.php @@ -11,7 +11,7 @@ require_once dirname(__FILE__) . '/nestedset_forum_base.php'; class phpbb_tests_tree_nestedset_forum_get_data_test extends phpbb_tests_tree_nestedset_forum_base { - public function get_full_branch_data_data() + public function get_path_and_subtree_data_data() { return array( array(1, true, true, array(1, 2, 3)), @@ -32,14 +32,14 @@ class phpbb_tests_tree_nestedset_forum_get_data_test extends phpbb_tests_tree_ne } /** - * @dataProvider get_full_branch_data_data + * @dataProvider get_path_and_subtree_data_data */ - public function test_get_full_branch_data($forum_id, $order_desc, $include_item, $expected) + public function test_get_path_and_subtree_data($forum_id, $order_desc, $include_item, $expected) { - $this->assertEquals($expected, array_keys($this->set->get_full_branch_data($forum_id, $order_desc, $include_item))); + $this->assertEquals($expected, array_keys($this->set->get_path_and_subtree_data($forum_id, $order_desc, $include_item))); } - public function get_parent_branch_data_data() + public function get_path_data_data() { return array( array(1, true, true, array(1)), @@ -60,14 +60,14 @@ class phpbb_tests_tree_nestedset_forum_get_data_test extends phpbb_tests_tree_ne } /** - * @dataProvider get_parent_branch_data_data + * @dataProvider get_path_data_data */ - public function test_get_parent_branch_data($forum_id, $order_desc, $include_item, $expected) + public function test_get_path_data($forum_id, $order_desc, $include_item, $expected) { - $this->assertEquals($expected, array_keys($this->set->get_parent_branch_data($forum_id, $order_desc, $include_item))); + $this->assertEquals($expected, array_keys($this->set->get_path_data($forum_id, $order_desc, $include_item))); } - public function get_children_branch_data_data() + public function get_subtree_data_data() { return array( array(1, true, true, array(1, 2, 3)), @@ -88,11 +88,11 @@ class phpbb_tests_tree_nestedset_forum_get_data_test extends phpbb_tests_tree_ne } /** - * @dataProvider get_children_branch_data_data + * @dataProvider get_subtree_data_data */ - public function test_get_children_branch_data($forum_id, $order_desc, $include_item, $expected) + public function test_get_subtree_data($forum_id, $order_desc, $include_item, $expected) { - $this->assertEquals($expected, array_keys($this->set->get_children_branch_data($forum_id, $order_desc, $include_item))); + $this->assertEquals($expected, array_keys($this->set->get_subtree_data($forum_id, $order_desc, $include_item))); } public function get_parent_data_data() From 4810c61fd7b912ea2914b99f7db502b6f503068f Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 30 Apr 2013 10:37:59 +0200 Subject: [PATCH 224/281] [ticket/11495] Remove get_parent_data from interface and rename it The method is implementation specific and has no use, apart from cache, that is not covered by get_path_data(). PHPBB3-11495 --- phpBB/includes/tree/interface.php | 9 --------- phpBB/includes/tree/nestedset.php | 9 ++++++--- tests/tree/nestedset_forum_get_data_test.php | 8 ++++---- 3 files changed, 10 insertions(+), 16 deletions(-) diff --git a/phpBB/includes/tree/interface.php b/phpBB/includes/tree/interface.php index 1b462768a0..bd8181beb2 100644 --- a/phpBB/includes/tree/interface.php +++ b/phpBB/includes/tree/interface.php @@ -119,13 +119,4 @@ interface phpbb_tree_interface * ID => Item data */ public function get_subtree_data($item_id, $order_desc, $include_item); - - /** - * Get base information of parent items - * - * @param array $item The item to get the branch from - * @return array Array of items (containing basic columns from the item table) - * ID => Item data - */ - public function get_parent_data(array $item); } diff --git a/phpBB/includes/tree/nestedset.php b/phpBB/includes/tree/nestedset.php index 10ab6a86e3..89a91ccb16 100644 --- a/phpBB/includes/tree/nestedset.php +++ b/phpBB/includes/tree/nestedset.php @@ -595,13 +595,16 @@ abstract class phpbb_tree_nestedset implements phpbb_tree_interface } /** - * Get base information of parent items + * Get basic data of all parent items * + * Basic data is defined in the $item_basic_data property. * Data is cached in the item_parents column in the item table * - * @inheritdoc + * @param array $item The item to get the path from + * @return array Array of items (containing basic columns from the item table) + * ID => Item data */ - public function get_parent_data(array $item) + public function get_path_basic_data(array $item) { $parents = array(); if ((int) $item[$this->column_parent_id]) diff --git a/tests/tree/nestedset_forum_get_data_test.php b/tests/tree/nestedset_forum_get_data_test.php index 300bbc6bfa..7a4fada880 100644 --- a/tests/tree/nestedset_forum_get_data_test.php +++ b/tests/tree/nestedset_forum_get_data_test.php @@ -95,7 +95,7 @@ class phpbb_tests_tree_nestedset_forum_get_data_test extends phpbb_tests_tree_ne $this->assertEquals($expected, array_keys($this->set->get_subtree_data($forum_id, $order_desc, $include_item))); } - public function get_parent_data_data() + public function get_path_basic_data_data() { return array( array(1, array(), array()), @@ -108,10 +108,10 @@ class phpbb_tests_tree_nestedset_forum_get_data_test extends phpbb_tests_tree_ne } /** - * @dataProvider get_parent_data_data + * @dataProvider get_path_basic_data_data */ - public function test_get_parent_data($forum_id, $forum_data, $expected) + public function test_get_path_basic_data($forum_id, $forum_data, $expected) { - $this->assertEquals($expected, array_keys($this->set->get_parent_data(array_merge($this->forum_data[$forum_id], $forum_data)))); + $this->assertEquals($expected, array_keys($this->set->get_path_basic_data(array_merge($this->forum_data[$forum_id], $forum_data)))); } } From 67f2edae170576104e619ffb38672cabf44e20fa Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 30 Apr 2013 13:54:50 +0200 Subject: [PATCH 225/281] [ticket/11495] Use descendants and ancestors instead of parents/children PHPBB3-11495 --- phpBB/includes/tree/interface.php | 28 ++++++++++---------- phpBB/includes/tree/nestedset.php | 18 ++++++------- tests/tree/nestedset_forum_get_data_test.php | 12 ++++----- 3 files changed, 29 insertions(+), 29 deletions(-) diff --git a/phpBB/includes/tree/interface.php b/phpBB/includes/tree/interface.php index bd8181beb2..e09fcea4fa 100644 --- a/phpBB/includes/tree/interface.php +++ b/phpBB/includes/tree/interface.php @@ -65,9 +65,9 @@ interface phpbb_tree_interface public function move_up($item_id); /** - * Moves all children of one item to another item + * Moves all descendants of one item to another item * - * If the new parent already has children, the new children are appended + * If the new parent already has descendants, the new descendants are appended * to the list. * * @param int $current_parent_id The current parent item @@ -88,35 +88,35 @@ interface phpbb_tree_interface public function change_parent($item_id, $new_parent_id); /** - * Get all items that are either a parent or part of the subtree of the item + * Get all items that are either an ancestors or descendants of the item * - * @param int $item_id The item id to get the parents/children from - * @param bool $order_desc Order the items descending (most outer parent first) + * @param int $item_id The item to get the ancestors/descendants from + * @param bool $order_asc Order the items ascending (most outer ancestor first) * @param bool $include_item Should the item (matching the given item id) be included in the list aswell * @return array Array of items (containing all columns from the item table) * ID => Item data */ - public function get_path_and_subtree_data($item_id, $order_desc, $include_item); + public function get_path_and_subtree_data($item_id, $order_asc, $include_item); /** - * Get all parent items of the item + * Get all ancestors items of the item * - * @param int $item_id The item id to get the parents from - * @param bool $order_desc Order the items descending (most outer parent first) + * @param int $item_id The item id to get the ancestors from + * @param bool $order_asc Order the items ascending (most outer ancestor first) * @param bool $include_item Should the item (matching the given item id) be included in the list aswell * @return array Array of items (containing all columns from the item table) * ID => Item data */ - public function get_path_data($item_id, $order_desc, $include_item); + public function get_path_data($item_id, $order_asc, $include_item); /** - * Get all items of the item's subtree + * Get all descendants of the item * - * @param int $item_id The item id to get the children from - * @param bool $order_desc Order the items descending (most outer parent first) + * @param int $item_id The item id to get the descendants from + * @param bool $order_asc Order the items ascending * @param bool $include_item Should the item (matching the given item id) be included in the list aswell * @return array Array of items (containing all columns from the item table) * ID => Item data */ - public function get_subtree_data($item_id, $order_desc, $include_item); + public function get_subtree_data($item_id, $order_asc, $include_item); } diff --git a/phpBB/includes/tree/nestedset.php b/phpBB/includes/tree/nestedset.php index 89a91ccb16..7710895a25 100644 --- a/phpBB/includes/tree/nestedset.php +++ b/phpBB/includes/tree/nestedset.php @@ -529,32 +529,32 @@ abstract class phpbb_tree_nestedset implements phpbb_tree_interface /** * @inheritdoc */ - public function get_path_and_subtree_data($item_id, $order_desc = true, $include_item = true) + public function get_path_and_subtree_data($item_id, $order_asc = true, $include_item = true) { $condition = 'i2.' . $this->column_left_id . ' BETWEEN i1.' . $this->column_left_id . ' AND i1.' . $this->column_right_id . ' OR i1.' . $this->column_left_id . ' BETWEEN i2.' . $this->column_left_id . ' AND i2.' . $this->column_right_id; - return $this->get_set_of_nodes_data($item_id, $condition, $order_desc, $include_item); + return $this->get_set_of_nodes_data($item_id, $condition, $order_asc, $include_item); } /** * @inheritdoc */ - public function get_path_data($item_id, $order_desc = true, $include_item = true) + public function get_path_data($item_id, $order_asc = true, $include_item = true) { $condition = 'i1.' . $this->column_left_id . ' BETWEEN i2.' . $this->column_left_id . ' AND i2.' . $this->column_right_id . ''; - return $this->get_set_of_nodes_data($item_id, $condition, $order_desc, $include_item); + return $this->get_set_of_nodes_data($item_id, $condition, $order_asc, $include_item); } /** * @inheritdoc */ - public function get_subtree_data($item_id, $order_desc = true, $include_item = true) + public function get_subtree_data($item_id, $order_asc = true, $include_item = true) { $condition = 'i2.' . $this->column_left_id . ' BETWEEN i1.' . $this->column_left_id . ' AND i1.' . $this->column_right_id . ''; - return $this->get_set_of_nodes_data($item_id, $condition, $order_desc, $include_item); + return $this->get_set_of_nodes_data($item_id, $condition, $order_asc, $include_item); } /** @@ -562,12 +562,12 @@ abstract class phpbb_tree_nestedset implements phpbb_tree_interface * * @param int $item_id The item id to get the node set from * @param string $condition Query string restricting the item list - * @param bool $order_desc Order the items descending (most outer parent first) + * @param bool $order_asc Order the items ascending by their left_id * @param bool $include_item Should the item (matching the given item id) be included in the list aswell * @return array Array of items (containing all columns from the item table) * ID => Item data */ - protected function get_set_of_nodes_data($item_id, $condition, $order_desc = true, $include_item = true) + protected function get_set_of_nodes_data($item_id, $condition, $order_asc = true, $include_item = true) { $rows = array(); @@ -577,7 +577,7 @@ abstract class phpbb_tree_nestedset implements phpbb_tree_interface ON (($condition) " . $this->get_sql_where('AND', 'i2.') . ') WHERE i1.' . $this->column_item_id . ' = ' . (int) $item_id . ' ' . $this->get_sql_where('AND', 'i1.') . ' - ORDER BY i2.' . $this->column_left_id . ' ' . ($order_desc ? 'ASC' : 'DESC'); + ORDER BY i2.' . $this->column_left_id . ' ' . ($order_asc ? 'ASC' : 'DESC'); $result = $this->db->sql_query($sql); while ($row = $this->db->sql_fetchrow($result)) diff --git a/tests/tree/nestedset_forum_get_data_test.php b/tests/tree/nestedset_forum_get_data_test.php index 7a4fada880..49586fbade 100644 --- a/tests/tree/nestedset_forum_get_data_test.php +++ b/tests/tree/nestedset_forum_get_data_test.php @@ -34,9 +34,9 @@ class phpbb_tests_tree_nestedset_forum_get_data_test extends phpbb_tests_tree_ne /** * @dataProvider get_path_and_subtree_data_data */ - public function test_get_path_and_subtree_data($forum_id, $order_desc, $include_item, $expected) + public function test_get_path_and_subtree_data($forum_id, $order_asc, $include_item, $expected) { - $this->assertEquals($expected, array_keys($this->set->get_path_and_subtree_data($forum_id, $order_desc, $include_item))); + $this->assertEquals($expected, array_keys($this->set->get_path_and_subtree_data($forum_id, $order_asc, $include_item))); } public function get_path_data_data() @@ -62,9 +62,9 @@ class phpbb_tests_tree_nestedset_forum_get_data_test extends phpbb_tests_tree_ne /** * @dataProvider get_path_data_data */ - public function test_get_path_data($forum_id, $order_desc, $include_item, $expected) + public function test_get_path_data($forum_id, $order_asc, $include_item, $expected) { - $this->assertEquals($expected, array_keys($this->set->get_path_data($forum_id, $order_desc, $include_item))); + $this->assertEquals($expected, array_keys($this->set->get_path_data($forum_id, $order_asc, $include_item))); } public function get_subtree_data_data() @@ -90,9 +90,9 @@ class phpbb_tests_tree_nestedset_forum_get_data_test extends phpbb_tests_tree_ne /** * @dataProvider get_subtree_data_data */ - public function test_get_subtree_data($forum_id, $order_desc, $include_item, $expected) + public function test_get_subtree_data($forum_id, $order_asc, $include_item, $expected) { - $this->assertEquals($expected, array_keys($this->set->get_subtree_data($forum_id, $order_desc, $include_item))); + $this->assertEquals($expected, array_keys($this->set->get_subtree_data($forum_id, $order_asc, $include_item))); } public function get_path_basic_data_data() From 87e8e60d3c09c96a4495dda748673fb8b9078a3e Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 30 Apr 2013 14:12:45 +0200 Subject: [PATCH 226/281] [ticket/11495] Correctly distinguish between children and descendants PHPBB3-11495 --- phpBB/includes/tree/interface.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/phpBB/includes/tree/interface.php b/phpBB/includes/tree/interface.php index e09fcea4fa..5e43478e22 100644 --- a/phpBB/includes/tree/interface.php +++ b/phpBB/includes/tree/interface.php @@ -65,9 +65,9 @@ interface phpbb_tree_interface public function move_up($item_id); /** - * Moves all descendants of one item to another item + * Moves all children of one item to another item * - * If the new parent already has descendants, the new descendants are appended + * If the new parent already has children, the new children are appended * to the list. * * @param int $current_parent_id The current parent item @@ -79,7 +79,7 @@ interface phpbb_tree_interface /** * Change parent item * - * Moves the item to the bottom of the new parent's subtree + * Moves the item to the bottom of the new parent's list of children * * @param int $item_id The item to be moved * @param int $new_parent_id The new parent item @@ -88,7 +88,7 @@ interface phpbb_tree_interface public function change_parent($item_id, $new_parent_id); /** - * Get all items that are either an ancestors or descendants of the item + * Get all items that are either ancestors or descendants of the item * * @param int $item_id The item to get the ancestors/descendants from * @param bool $order_asc Order the items ascending (most outer ancestor first) From 863d0c7687cc926dfda0ddd20b34e7942748fb2e Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 30 Apr 2013 14:36:26 +0200 Subject: [PATCH 227/281] [ticket/11495] Fix some more comments and the package tag PHPBB3-11495 --- phpBB/includes/tree/interface.php | 2 +- phpBB/includes/tree/nestedset.php | 8 ++++---- phpBB/includes/tree/nestedset_forum.php | 2 +- tests/tree/nestedset_forum_base.php | 2 +- tests/tree/nestedset_forum_get_data_test.php | 2 +- tests/tree/nestedset_forum_insert_delete_test.php | 2 +- tests/tree/nestedset_forum_move_test.php | 2 +- tests/tree/nestedset_forum_regenerate_test.php | 2 +- tests/tree/nestedset_forum_test.php | 2 +- 9 files changed, 12 insertions(+), 12 deletions(-) diff --git a/phpBB/includes/tree/interface.php b/phpBB/includes/tree/interface.php index 5e43478e22..9bd633a5eb 100644 --- a/phpBB/includes/tree/interface.php +++ b/phpBB/includes/tree/interface.php @@ -99,7 +99,7 @@ interface phpbb_tree_interface public function get_path_and_subtree_data($item_id, $order_asc, $include_item); /** - * Get all ancestors items of the item + * Get all ancestors of the item * * @param int $item_id The item id to get the ancestors from * @param bool $order_asc Order the items ascending (most outer ancestor first) diff --git a/phpBB/includes/tree/nestedset.php b/phpBB/includes/tree/nestedset.php index 7710895a25..ae9805aa45 100644 --- a/phpBB/includes/tree/nestedset.php +++ b/phpBB/includes/tree/nestedset.php @@ -1,7 +1,7 @@ Date: Tue, 30 Apr 2013 14:45:22 +0200 Subject: [PATCH 228/281] [ticket/11495] Fix docs of add_item_to_nestedset() and take id as argument PHPBB3-11495 --- phpBB/includes/tree/nestedset.php | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/phpBB/includes/tree/nestedset.php b/phpBB/includes/tree/nestedset.php index ae9805aa45..934eb933e0 100644 --- a/phpBB/includes/tree/nestedset.php +++ b/phpBB/includes/tree/nestedset.php @@ -111,16 +111,17 @@ abstract class phpbb_tree_nestedset implements phpbb_tree_interface $item_data[$this->column_item_id] = (int) $this->db->sql_nextid(); - return array_merge($item_data, $this->add_item_to_nestedset($item_data)); + return array_merge($item_data, $this->add_item_to_nestedset($item_data[$this->column_item_id])); } /** * Add an item which already has a database row at the end of the tree * - * @param array $item The item to be added - * @return bool True if the item was added + * @param int $item_id The item to be added + * @return array Array with updated data, if the item was added successfully + * Empty array otherwise */ - protected function add_item_to_nestedset(array $item) + protected function add_item_to_nestedset($item_id) { $sql = 'SELECT MAX(' . $this->column_right_id . ') AS ' . $this->column_right_id . ' FROM ' . $this->table_name . ' @@ -138,10 +139,13 @@ abstract class phpbb_tree_nestedset implements phpbb_tree_interface $sql = 'UPDATE ' . $this->table_name . ' SET ' . $this->db->sql_build_array('UPDATE', $update_item_data) . ' - WHERE ' . $this->column_item_id . ' = ' . (int) $item[$this->column_item_id]; + WHERE ' . $this->column_item_id . ' = ' . (int) $item_id . ' + AND ' . $this->column_parent_id . ' = 0 + AND ' . $this->column_left_id . ' = 0 + AND ' . $this->column_right_id . ' = 0'; $this->db->sql_query($sql); - return $update_item_data; + return ($this->db->sql_affectedrows() == 1) ? $update_item_data : array(); } /** From 529e4c00fbb78ba513afbbacfb3d5465efbd82ef Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 30 Apr 2013 15:07:56 +0200 Subject: [PATCH 229/281] [ticket/11495] Move lock code into two methods to allow easier handling This also allows to simply remove the lock handling by overwriting the two methods acquire_lock() and release_lock(). PHPBB3-11495 --- phpBB/includes/tree/nestedset.php | 113 +++++++++++++++++++----------- 1 file changed, 72 insertions(+), 41 deletions(-) diff --git a/phpBB/includes/tree/nestedset.php b/phpBB/includes/tree/nestedset.php index 934eb933e0..85e04cd1cf 100644 --- a/phpBB/includes/tree/nestedset.php +++ b/phpBB/includes/tree/nestedset.php @@ -55,6 +55,12 @@ abstract class phpbb_tree_nestedset implements phpbb_tree_interface */ protected $item_basic_data = array('*'); + /** + * Does the class currently have a lock on the item table? + * @var bool + */ + protected $lock_acquired = false; + /** * Construct * @@ -99,6 +105,46 @@ abstract class phpbb_tree_nestedset implements phpbb_tree_interface return (!$this->sql_where) ? '' : $operator . ' ' . sprintf($this->sql_where, $column_prefix); } + /** + * Acquires a lock on the item table + * + * @return bool True if the lock was acquired, false if it has been acquired previously + * + * @throws RuntimeException If the lock could not be acquired + */ + protected function acquire_lock() + { + if ($this->lock_acquired) + { + return false; + } + + if (!$this->lock->acquire()) + { + throw new RuntimeException($this->message_prefix . 'LOCK_FAILED_ACQUIRE'); + } + + $this->lock_acquired = true; + return true; + } + + /** + * Releases the lock on the item table + * + * @return bool False, if there was no lock to release, true otherwise + */ + protected function release_lock() + { + if (!$this->lock_acquired) + { + return false; + } + + $this->lock->release(); + $this->lock_acquired = false; + return true; + } + /** * @inheritdoc */ @@ -191,10 +237,7 @@ abstract class phpbb_tree_nestedset implements phpbb_tree_interface return false; } - if (!$this->lock->acquire()) - { - throw new RuntimeException($this->message_prefix . 'LOCK_FAILED_ACQUIRE'); - } + $this->acquire_lock(); $action = ($delta > 0) ? 'move_up' : 'move_down'; $delta = abs($delta); @@ -210,7 +253,7 @@ abstract class phpbb_tree_nestedset implements phpbb_tree_interface if (!$item) { - $this->lock->release(); + $this->release_lock(); throw new OutOfBoundsException($this->message_prefix . 'INVALID_ITEM'); } @@ -246,7 +289,7 @@ abstract class phpbb_tree_nestedset implements phpbb_tree_interface if (!$target) { - $this->lock->release(); + $this->release_lock(); // The item is already on top or bottom return false; } @@ -298,7 +341,7 @@ abstract class phpbb_tree_nestedset implements phpbb_tree_interface " . $this->get_sql_where(); $this->db->sql_query($sql); - $this->lock->release(); + $this->release_lock(); return true; } @@ -337,15 +380,12 @@ abstract class phpbb_tree_nestedset implements phpbb_tree_interface throw new OutOfBoundsException($this->message_prefix . 'INVALID_ITEM'); } - if (!$this->lock->acquire()) - { - throw new RuntimeException($this->message_prefix . 'LOCK_FAILED_ACQUIRE'); - } + $this->acquire_lock(); $item_data = $this->get_subtree_data($current_parent_id); if (!isset($item_data[$current_parent_id])) { - $this->lock->release(); + $this->release_lock(); throw new OutOfBoundsException($this->message_prefix . 'INVALID_ITEM'); } @@ -355,13 +395,13 @@ abstract class phpbb_tree_nestedset implements phpbb_tree_interface if (($current_parent[$this->column_right_id] - $current_parent[$this->column_left_id]) <= 1) { - $this->lock->release(); + $this->release_lock(); return false; } if (in_array($new_parent_id, $move_items)) { - $this->lock->release(); + $this->release_lock(); throw new OutOfBoundsException($this->message_prefix . 'INVALID_PARENT'); } @@ -385,7 +425,7 @@ abstract class phpbb_tree_nestedset implements phpbb_tree_interface if (!$new_parent) { $this->db->sql_transaction('rollback'); - $this->lock->release(); + $this->release_lock(); throw new OutOfBoundsException($this->message_prefix . 'INVALID_PARENT'); } @@ -423,7 +463,7 @@ abstract class phpbb_tree_nestedset implements phpbb_tree_interface $this->db->sql_query($sql); $this->db->sql_transaction('commit'); - $this->lock->release(); + $this->release_lock(); return true; } @@ -446,15 +486,12 @@ abstract class phpbb_tree_nestedset implements phpbb_tree_interface throw new OutOfBoundsException($this->message_prefix . 'INVALID_ITEM'); } - if (!$this->lock->acquire()) - { - throw new RuntimeException($this->message_prefix . 'LOCK_FAILED_ACQUIRE'); - } + $this->acquire_lock(); $item_data = $this->get_subtree_data($item_id); if (!isset($item_data[$item_id])) { - $this->lock->release(); + $this->release_lock(); throw new OutOfBoundsException($this->message_prefix . 'INVALID_ITEM'); } @@ -463,7 +500,7 @@ abstract class phpbb_tree_nestedset implements phpbb_tree_interface if (in_array($new_parent_id, $move_items)) { - $this->lock->release(); + $this->release_lock(); throw new OutOfBoundsException($this->message_prefix . 'INVALID_PARENT'); } @@ -487,7 +524,7 @@ abstract class phpbb_tree_nestedset implements phpbb_tree_interface if (!$new_parent) { $this->db->sql_transaction('rollback'); - $this->lock->release(); + $this->release_lock(); throw new OutOfBoundsException($this->message_prefix . 'INVALID_PARENT'); } @@ -525,7 +562,7 @@ abstract class phpbb_tree_nestedset implements phpbb_tree_interface $this->db->sql_query($sql); $this->db->sql_transaction('commit'); - $this->lock->release(); + $this->release_lock(); return true; } @@ -653,15 +690,11 @@ abstract class phpbb_tree_nestedset implements phpbb_tree_interface * @param bool $set_subset_zero Should the parent, left and right id of the items be set to 0, or kept unchanged? * In case of removing an item from the tree, we should the values to 0 * In case of moving an item, we shouldkeep the original values, in order to allow "+ diff" later - * @param bool $table_already_locked Is the table already locked, or should we acquire a new lock? * @return null */ - protected function remove_subset(array $subset_items, array $bounding_item, $set_subset_zero = true, $table_already_locked = false) + protected function remove_subset(array $subset_items, array $bounding_item, $set_subset_zero = true) { - if (!$table_already_locked && !$this->lock->acquire()) - { - throw new RuntimeException($this->message_prefix . 'LOCK_FAILED_ACQUIRE'); - } + $acquired_new_lock = $this->acquire_lock(); $diff = sizeof($subset_items) * 2; $sql_subset_items = $this->db->sql_in_set($this->column_item_id, $subset_items); @@ -689,9 +722,9 @@ abstract class phpbb_tree_nestedset implements phpbb_tree_interface " . ((!$set_subset_zero) ? ' WHERE ' . $sql_not_subset_items . ' ' . $this->get_sql_where('AND') : $this->get_sql_where('WHERE')); $this->db->sql_query($sql); - if (!$table_already_locked) + if ($acquired_new_lock) { - $this->lock->release(); + $this->release_lock(); } } @@ -763,14 +796,13 @@ abstract class phpbb_tree_nestedset implements phpbb_tree_interface */ public function regenerate_left_right_ids($new_id, $parent_id = 0, $reset_ids = false) { + if ($acquired_new_lock = $this->acquire_lock()) + { + $this->db->sql_transaction('begin'); + } + if ($reset_ids) { - if (!$this->lock->acquire()) - { - throw new RuntimeException($this->message_prefix . 'LOCK_FAILED_ACQUIRE'); - } - $this->db->sql_transaction('begin'); - $sql = 'UPDATE ' . $this->table_name . ' SET ' . $this->db->sql_build_array('UPDATE', array( $this->column_left_id => 0, @@ -817,11 +849,10 @@ abstract class phpbb_tree_nestedset implements phpbb_tree_interface } $this->db->sql_freeresult($result); - - if ($reset_ids) + if ($acquired_new_lock) { $this->db->sql_transaction('commit'); - $this->lock->release(); + $this->release_lock(); } return $new_id; From 055ee41065fb0b7c08c66daff196eb2d3460b0cc Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 30 Apr 2013 15:16:41 +0200 Subject: [PATCH 230/281] [ticket/11495] Remove useless cast PHPBB3-11495 --- phpBB/includes/tree/nestedset.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/includes/tree/nestedset.php b/phpBB/includes/tree/nestedset.php index 85e04cd1cf..6819f9791b 100644 --- a/phpBB/includes/tree/nestedset.php +++ b/phpBB/includes/tree/nestedset.php @@ -648,7 +648,7 @@ abstract class phpbb_tree_nestedset implements phpbb_tree_interface public function get_path_basic_data(array $item) { $parents = array(); - if ((int) $item[$this->column_parent_id]) + if ($item[$this->column_parent_id]) { if (!$item[$this->column_item_parents]) { From 714092ab4e52dc039536a05846b50f4d4d488799 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 30 Apr 2013 15:48:29 +0200 Subject: [PATCH 231/281] [ticket/11495] Add owns_lock() method to lock classes PHPBB3-11495 --- phpBB/includes/lock/db.php | 11 +++++++++++ phpBB/includes/lock/flock.php | 11 +++++++++++ tests/lock/db_test.php | 14 ++++++++++++++ tests/lock/flock_test.php | 11 +++++++++++ 4 files changed, 47 insertions(+) diff --git a/phpBB/includes/lock/db.php b/phpBB/includes/lock/db.php index ccdaed0b28..5cc0821aa0 100644 --- a/phpBB/includes/lock/db.php +++ b/phpBB/includes/lock/db.php @@ -116,6 +116,17 @@ class phpbb_lock_db return $this->locked; } + /** + * Does this process own the lock? + * + * @return bool true if lock is owned + * false otherwise + */ + public function owns_lock() + { + return (bool) $this->locked; + } + /** * Releases the lock. * diff --git a/phpBB/includes/lock/flock.php b/phpBB/includes/lock/flock.php index 97bc7dd2b9..17de0847c0 100644 --- a/phpBB/includes/lock/flock.php +++ b/phpBB/includes/lock/flock.php @@ -110,6 +110,17 @@ class phpbb_lock_flock return (bool) $this->lock_fp; } + /** + * Does this process own the lock? + * + * @return bool true if lock is owned + * false otherwise + */ + public function owns_lock() + { + return (bool) $this->lock_fp; + } + /** * Releases the lock. * diff --git a/tests/lock/db_test.php b/tests/lock/db_test.php index f7b1557a0c..de7a23fd05 100644 --- a/tests/lock/db_test.php +++ b/tests/lock/db_test.php @@ -32,13 +32,18 @@ class phpbb_lock_db_test extends phpbb_database_test_case public function test_new_lock() { + $this->assertFalse($this->lock->owns_lock()); + $this->assertTrue($this->lock->acquire()); + $this->assertTrue($this->lock->owns_lock()); $this->assertTrue(isset($this->config['test_lock']), 'Lock was created'); $lock2 = new phpbb_lock_db('test_lock', $this->config, $this->db); $this->assertFalse($lock2->acquire()); + $this->assertFalse($lock2->owns_lock()); $this->lock->release(); + $this->assertFalse($this->lock->owns_lock()); $this->assertEquals('0', $this->config['test_lock'], 'Lock was released'); } @@ -50,31 +55,40 @@ class phpbb_lock_db_test extends phpbb_database_test_case public function test_double_lock() { + $this->assertFalse($this->lock->owns_lock()); + $this->assertTrue($this->lock->acquire()); + $this->assertTrue($this->lock->owns_lock()); $this->assertTrue(isset($this->config['test_lock']), 'Lock was created'); $value = $this->config['test_lock']; $this->assertFalse($this->lock->acquire()); + $this->assertTrue($this->lock->owns_lock()); $this->assertEquals($value, $this->config['test_lock'], 'Second lock failed'); $this->lock->release(); + $this->assertFalse($this->lock->owns_lock()); $this->assertEquals('0', $this->config['test_lock'], 'Lock was released'); } public function test_double_unlock() { $this->assertTrue($this->lock->acquire()); + $this->assertTrue($this->lock->owns_lock()); $this->assertFalse(empty($this->config['test_lock']), 'First lock is acquired'); $this->lock->release(); + $this->assertFalse($this->lock->owns_lock()); $this->assertEquals('0', $this->config['test_lock'], 'First lock is released'); $lock2 = new phpbb_lock_db('test_lock', $this->config, $this->db); $this->assertTrue($lock2->acquire()); + $this->assertTrue($lock2->owns_lock()); $this->assertFalse(empty($this->config['test_lock']), 'Second lock is acquired'); $this->lock->release(); + $this->assertTrue($lock2->owns_lock()); $this->assertFalse(empty($this->config['test_lock']), 'Double release of first lock is ignored'); $lock2->release(); diff --git a/tests/lock/flock_test.php b/tests/lock/flock_test.php index 1edc96b3a4..8f0b866ab3 100644 --- a/tests/lock/flock_test.php +++ b/tests/lock/flock_test.php @@ -26,15 +26,21 @@ class phpbb_lock_flock_test extends phpbb_test_case $lock = new phpbb_lock_flock($path); $ok = $lock->acquire(); $this->assertTrue($ok); + $this->assertTrue($lock->owns_lock()); $lock->release(); + $this->assertFalse($lock->owns_lock()); $ok = $lock->acquire(); $this->assertTrue($ok); + $this->assertTrue($lock->owns_lock()); $lock->release(); + $this->assertFalse($lock->owns_lock()); $ok = $lock->acquire(); $this->assertTrue($ok); + $this->assertTrue($lock->owns_lock()); $lock->release(); + $this->assertFalse($lock->owns_lock()); } /* This hangs the process. @@ -77,15 +83,18 @@ class phpbb_lock_flock_test extends phpbb_test_case $ok = $lock->acquire(); $delta = time() - $start; $this->assertTrue($ok); + $this->assertTrue($lock->owns_lock()); $this->assertGreaterThan(0.5, $delta, 'First lock acquired too soon'); $lock->release(); + $this->assertFalse($lock->owns_lock()); // acquire again, this should be instantaneous $start = time(); $ok = $lock->acquire(); $delta = time() - $start; $this->assertTrue($ok); + $this->assertTrue($lock->owns_lock()); $this->assertLessThan(0.1, $delta, 'Second lock not acquired instantaneously'); // reap the child @@ -99,8 +108,10 @@ class phpbb_lock_flock_test extends phpbb_test_case $lock = new phpbb_lock_flock($path); $ok = $lock->acquire(); $this->assertTrue($ok); + $this->assertTrue($lock->owns_lock()); sleep(2); $lock->release(); + $this->assertFalse($lock->owns_lock()); // and go away silently pcntl_exec('/usr/bin/env', array('true')); From 78b0d3e723ab57c2e32b95a66159861fe461d77f Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 30 Apr 2013 15:50:14 +0200 Subject: [PATCH 232/281] [ticket/11495] Use $lock->owns_lock() instead of own property PHPBB3-11495 --- phpBB/includes/tree/nestedset.php | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/phpBB/includes/tree/nestedset.php b/phpBB/includes/tree/nestedset.php index 6819f9791b..26152e6c10 100644 --- a/phpBB/includes/tree/nestedset.php +++ b/phpBB/includes/tree/nestedset.php @@ -55,12 +55,6 @@ abstract class phpbb_tree_nestedset implements phpbb_tree_interface */ protected $item_basic_data = array('*'); - /** - * Does the class currently have a lock on the item table? - * @var bool - */ - protected $lock_acquired = false; - /** * Construct * @@ -114,7 +108,7 @@ abstract class phpbb_tree_nestedset implements phpbb_tree_interface */ protected function acquire_lock() { - if ($this->lock_acquired) + if ($this->lock->owns_lock()) { return false; } @@ -124,25 +118,17 @@ abstract class phpbb_tree_nestedset implements phpbb_tree_interface throw new RuntimeException($this->message_prefix . 'LOCK_FAILED_ACQUIRE'); } - $this->lock_acquired = true; return true; } /** * Releases the lock on the item table * - * @return bool False, if there was no lock to release, true otherwise + * @return null */ protected function release_lock() { - if (!$this->lock_acquired) - { - return false; - } - $this->lock->release(); - $this->lock_acquired = false; - return true; } /** From 6055a3cc7ed76cfe458ea524bfad66f475f35ce8 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 30 Apr 2013 16:19:25 +0200 Subject: [PATCH 233/281] [ticket/11495] Remove useless release_lock() method PHPBB3-11495 --- phpBB/includes/tree/nestedset.php | 38 ++++++++++++------------------- 1 file changed, 14 insertions(+), 24 deletions(-) diff --git a/phpBB/includes/tree/nestedset.php b/phpBB/includes/tree/nestedset.php index 26152e6c10..f92606a4c4 100644 --- a/phpBB/includes/tree/nestedset.php +++ b/phpBB/includes/tree/nestedset.php @@ -121,16 +121,6 @@ abstract class phpbb_tree_nestedset implements phpbb_tree_interface return true; } - /** - * Releases the lock on the item table - * - * @return null - */ - protected function release_lock() - { - $this->lock->release(); - } - /** * @inheritdoc */ @@ -239,7 +229,7 @@ abstract class phpbb_tree_nestedset implements phpbb_tree_interface if (!$item) { - $this->release_lock(); + $this->lock->release(); throw new OutOfBoundsException($this->message_prefix . 'INVALID_ITEM'); } @@ -275,7 +265,7 @@ abstract class phpbb_tree_nestedset implements phpbb_tree_interface if (!$target) { - $this->release_lock(); + $this->lock->release(); // The item is already on top or bottom return false; } @@ -327,7 +317,7 @@ abstract class phpbb_tree_nestedset implements phpbb_tree_interface " . $this->get_sql_where(); $this->db->sql_query($sql); - $this->release_lock(); + $this->lock->release(); return true; } @@ -371,7 +361,7 @@ abstract class phpbb_tree_nestedset implements phpbb_tree_interface $item_data = $this->get_subtree_data($current_parent_id); if (!isset($item_data[$current_parent_id])) { - $this->release_lock(); + $this->lock->release(); throw new OutOfBoundsException($this->message_prefix . 'INVALID_ITEM'); } @@ -381,13 +371,13 @@ abstract class phpbb_tree_nestedset implements phpbb_tree_interface if (($current_parent[$this->column_right_id] - $current_parent[$this->column_left_id]) <= 1) { - $this->release_lock(); + $this->lock->release(); return false; } if (in_array($new_parent_id, $move_items)) { - $this->release_lock(); + $this->lock->release(); throw new OutOfBoundsException($this->message_prefix . 'INVALID_PARENT'); } @@ -411,7 +401,7 @@ abstract class phpbb_tree_nestedset implements phpbb_tree_interface if (!$new_parent) { $this->db->sql_transaction('rollback'); - $this->release_lock(); + $this->lock->release(); throw new OutOfBoundsException($this->message_prefix . 'INVALID_PARENT'); } @@ -449,7 +439,7 @@ abstract class phpbb_tree_nestedset implements phpbb_tree_interface $this->db->sql_query($sql); $this->db->sql_transaction('commit'); - $this->release_lock(); + $this->lock->release(); return true; } @@ -477,7 +467,7 @@ abstract class phpbb_tree_nestedset implements phpbb_tree_interface $item_data = $this->get_subtree_data($item_id); if (!isset($item_data[$item_id])) { - $this->release_lock(); + $this->lock->release(); throw new OutOfBoundsException($this->message_prefix . 'INVALID_ITEM'); } @@ -486,7 +476,7 @@ abstract class phpbb_tree_nestedset implements phpbb_tree_interface if (in_array($new_parent_id, $move_items)) { - $this->release_lock(); + $this->lock->release(); throw new OutOfBoundsException($this->message_prefix . 'INVALID_PARENT'); } @@ -510,7 +500,7 @@ abstract class phpbb_tree_nestedset implements phpbb_tree_interface if (!$new_parent) { $this->db->sql_transaction('rollback'); - $this->release_lock(); + $this->lock->release(); throw new OutOfBoundsException($this->message_prefix . 'INVALID_PARENT'); } @@ -548,7 +538,7 @@ abstract class phpbb_tree_nestedset implements phpbb_tree_interface $this->db->sql_query($sql); $this->db->sql_transaction('commit'); - $this->release_lock(); + $this->lock->release(); return true; } @@ -710,7 +700,7 @@ abstract class phpbb_tree_nestedset implements phpbb_tree_interface if ($acquired_new_lock) { - $this->release_lock(); + $this->lock->release(); } } @@ -838,7 +828,7 @@ abstract class phpbb_tree_nestedset implements phpbb_tree_interface if ($acquired_new_lock) { $this->db->sql_transaction('commit'); - $this->release_lock(); + $this->lock->release(); } return $new_id; From f3f7be4cd1a0495cf44787c713480d5aceb1bae1 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 30 Apr 2013 17:11:55 +0200 Subject: [PATCH 234/281] [ticket/11495] Fix @return doc of get_sql_where() PHPBB3-11495 --- phpBB/includes/tree/nestedset.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/phpBB/includes/tree/nestedset.php b/phpBB/includes/tree/nestedset.php index f92606a4c4..5a12afdfe9 100644 --- a/phpBB/includes/tree/nestedset.php +++ b/phpBB/includes/tree/nestedset.php @@ -92,7 +92,8 @@ abstract class phpbb_tree_nestedset implements phpbb_tree_interface * @param string $operator SQL operator that needs to be prepended to sql_where, * if it is not empty. * @param string $column_prefix Prefix that needs to be prepended to column names - * @return bool True if the item was deleted + * @return string Returns additional where statements to narrow down the tree, + * prefixed with operator and prepended column_prefix to column names */ public function get_sql_where($operator = 'AND', $column_prefix = '') { From 39ff3ed15fc77215153a47a870e8cde5436674ae Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 30 Apr 2013 18:05:44 +0200 Subject: [PATCH 235/281] [ticket/11495] Add proper testing of item_parent to tests PHPBB3-11495 --- tests/tree/nestedset_forum_base.php | 30 +- tests/tree/nestedset_forum_get_data_test.php | 18 +- .../nestedset_forum_insert_delete_test.php | 58 +- tests/tree/nestedset_forum_move_test.php | 514 +++++++++--------- tests/tree/nestedset_forum_test.php | 78 +-- 5 files changed, 352 insertions(+), 346 deletions(-) diff --git a/tests/tree/nestedset_forum_base.php b/tests/tree/nestedset_forum_base.php index 2b617fcc53..b9d42fb51d 100644 --- a/tests/tree/nestedset_forum_base.php +++ b/tests/tree/nestedset_forum_base.php @@ -16,27 +16,27 @@ class phpbb_tests_tree_nestedset_forum_base extends phpbb_database_test_case protected $forum_data = array( // \__/ - 1 => array('forum_id' => 1, 'parent_id' => 0, 'user_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => ''), - 2 => array('forum_id' => 2, 'parent_id' => 1, 'user_id' => 0, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => ''), - 3 => array('forum_id' => 3, 'parent_id' => 1, 'user_id' => 0, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => ''), + 1 => array('forum_id' => 1, 'parent_id' => 0, 'user_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => 'a:0:{}'), + 2 => array('forum_id' => 2, 'parent_id' => 1, 'user_id' => 0, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => 'a:0:{}'), + 3 => array('forum_id' => 3, 'parent_id' => 1, 'user_id' => 0, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => 'a:0:{}'), // \ / // \/ - 4 => array('forum_id' => 4, 'parent_id' => 0, 'user_id' => 0, 'left_id' => 7, 'right_id' => 12, 'forum_parents' => ''), - 5 => array('forum_id' => 5, 'parent_id' => 4, 'user_id' => 0, 'left_id' => 8, 'right_id' => 11, 'forum_parents' => ''), - 6 => array('forum_id' => 6, 'parent_id' => 5, 'user_id' => 0, 'left_id' => 9, 'right_id' => 10, 'forum_parents' => ''), + 4 => array('forum_id' => 4, 'parent_id' => 0, 'user_id' => 0, 'left_id' => 7, 'right_id' => 12, 'forum_parents' => 'a:0:{}'), + 5 => array('forum_id' => 5, 'parent_id' => 4, 'user_id' => 0, 'left_id' => 8, 'right_id' => 11, 'forum_parents' => 'a:0:{}'), + 6 => array('forum_id' => 6, 'parent_id' => 5, 'user_id' => 0, 'left_id' => 9, 'right_id' => 10, 'forum_parents' => 'a:0:{}'), // \_ _/ // \/ - 7 => array('forum_id' => 7, 'parent_id' => 0, 'user_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => ''), - 8 => array('forum_id' => 8, 'parent_id' => 7, 'user_id' => 0, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => ''), - 9 => array('forum_id' => 9, 'parent_id' => 7, 'user_id' => 0, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => ''), - 10 => array('forum_id' => 10, 'parent_id' => 9, 'user_id' => 0, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => ''), - 11 => array('forum_id' => 11, 'parent_id' => 7, 'user_id' => 0, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => ''), + 7 => array('forum_id' => 7, 'parent_id' => 0, 'user_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => 'a:0:{}'), + 8 => array('forum_id' => 8, 'parent_id' => 7, 'user_id' => 0, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => 'a:0:{}'), + 9 => array('forum_id' => 9, 'parent_id' => 7, 'user_id' => 0, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => 'a:0:{}'), + 10 => array('forum_id' => 10, 'parent_id' => 9, 'user_id' => 0, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => 'a:0:{}'), + 11 => array('forum_id' => 11, 'parent_id' => 7, 'user_id' => 0, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => 'a:0:{}'), // Unexisting forums - 0 => array('forum_id' => 0, 'parent_id' => 0, 'user_id' => 0, 'left_id' => 0, 'right_id' => 0, 'forum_parents' => ''), - 200 => array('forum_id' => 200, 'parent_id' => 0, 'user_id' => 0, 'left_id' => 0, 'right_id' => 0, 'forum_parents' => ''), + 0 => array('forum_id' => 0, 'parent_id' => 0, 'user_id' => 0, 'left_id' => 0, 'right_id' => 0, 'forum_parents' => 'a:0:{}'), + 200 => array('forum_id' => 200, 'parent_id' => 0, 'user_id' => 0, 'left_id' => 0, 'right_id' => 0, 'forum_parents' => 'a:0:{}'), ); protected $set, @@ -59,6 +59,10 @@ class phpbb_tests_tree_nestedset_forum_base extends phpbb_database_test_case $this->set = new phpbb_tree_nestedset_forum($this->db, $this->lock, 'phpbb_forums'); $this->set_up_forums(); + + $sql = "UPDATE phpbb_forums + SET forum_parents = 'a:0:{}'"; + $this->db->sql_query($sql); } protected function set_up_forums() diff --git a/tests/tree/nestedset_forum_get_data_test.php b/tests/tree/nestedset_forum_get_data_test.php index 76c99650aa..ca1863e55e 100644 --- a/tests/tree/nestedset_forum_get_data_test.php +++ b/tests/tree/nestedset_forum_get_data_test.php @@ -98,20 +98,22 @@ class phpbb_tests_tree_nestedset_forum_get_data_test extends phpbb_tests_tree_ne public function get_path_basic_data_data() { return array( - array(1, array(), array()), - array(1, array('forum_parents' => serialize(array())), array()), - array(2, array(), array(1)), - array(2, array('forum_parents' => serialize(array(1 => array()))), array(1)), - array(10, array(), array(7, 9)), - array(10, array('forum_parents' => serialize(array(7 => array(), 9 => array()))), array(7, 9)), + array(1, '', array()), + array(1, serialize(array()), array()), + array(2, '', array(1)), + array(2, serialize(array(1 => array())), array(1)), + array(10, '', array(7, 9)), + array(10, serialize(array(7 => array(), 9 => array())), array(7, 9)), ); } /** * @dataProvider get_path_basic_data_data */ - public function test_get_path_basic_data($forum_id, $forum_data, $expected) + public function test_get_path_basic_data($forum_id, $forum_parents, $expected) { - $this->assertEquals($expected, array_keys($this->set->get_path_basic_data(array_merge($this->forum_data[$forum_id], $forum_data)))); + $forum_data = $this->forum_data[$forum_id]; + $forum_data['forum_parents'] = $forum_parents; + $this->assertEquals($expected, array_keys($this->set->get_path_basic_data($forum_data))); } } diff --git a/tests/tree/nestedset_forum_insert_delete_test.php b/tests/tree/nestedset_forum_insert_delete_test.php index d11180ca78..34aac19270 100644 --- a/tests/tree/nestedset_forum_insert_delete_test.php +++ b/tests/tree/nestedset_forum_insert_delete_test.php @@ -15,26 +15,26 @@ class phpbb_tests_tree_nestedset_forum_add_remove_test extends phpbb_tests_tree_ { return array( array(1, array(1, 2, 3), array( - array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => ''), - array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 2, 'right_id' => 5, 'forum_parents' => ''), - array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 3, 'right_id' => 4, 'forum_parents' => ''), - array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 16, 'forum_parents' => ''), - array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 8, 'right_id' => 9, 'forum_parents' => ''), - array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 10, 'right_id' => 13, 'forum_parents' => ''), - array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 11, 'right_id' => 12, 'forum_parents' => ''), - array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => ''), + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 2, 'right_id' => 5, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 3, 'right_id' => 4, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 16, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 8, 'right_id' => 9, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 10, 'right_id' => 13, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 11, 'right_id' => 12, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => 'a:0:{}'), )), array(2, array(2), array( - array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 4, 'forum_parents' => ''), - array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => ''), - array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 5, 'right_id' => 10, 'forum_parents' => ''), - array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 6, 'right_id' => 9, 'forum_parents' => ''), - array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 7, 'right_id' => 8, 'forum_parents' => ''), - array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 11, 'right_id' => 20, 'forum_parents' => ''), - array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 12, 'right_id' => 13, 'forum_parents' => ''), - array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 17, 'forum_parents' => ''), - array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 15, 'right_id' => 16, 'forum_parents' => ''), - array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 18, 'right_id' => 19, 'forum_parents' => ''), + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 4, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 5, 'right_id' => 10, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 6, 'right_id' => 9, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 7, 'right_id' => 8, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 11, 'right_id' => 20, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 12, 'right_id' => 13, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 17, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 15, 'right_id' => 16, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 18, 'right_id' => 19, 'forum_parents' => 'a:0:{}'), )), ); } @@ -64,19 +64,19 @@ class phpbb_tests_tree_nestedset_forum_add_remove_test extends phpbb_tests_tree_ 'right_id' => 24, 'forum_parents' => '', ), array( - array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => ''), - array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => ''), - array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => ''), + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12, 'forum_parents' => ''), - array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 8, 'right_id' => 11, 'forum_parents' => ''), - array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 9, 'right_id' => 10, 'forum_parents' => ''), + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 8, 'right_id' => 11, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 9, 'right_id' => 10, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => ''), - array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => ''), - array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => ''), - array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => ''), - array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => ''), + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => 'a:0:{}'), array('forum_id' => 12, 'parent_id' => 0, 'left_id' => 23, 'right_id' => 24, 'forum_parents' => ''), )), diff --git a/tests/tree/nestedset_forum_move_test.php b/tests/tree/nestedset_forum_move_test.php index 2407a43ab6..0901082926 100644 --- a/tests/tree/nestedset_forum_move_test.php +++ b/tests/tree/nestedset_forum_move_test.php @@ -16,101 +16,101 @@ class phpbb_tests_tree_nestedset_forum_move_test extends phpbb_tests_tree_nested return array( array('Move first item up', 1, 1, false, array( - array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => ''), - array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => ''), - array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => ''), - array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12, 'forum_parents' => ''), - array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 8, 'right_id' => 11, 'forum_parents' => ''), - array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 9, 'right_id' => 10, 'forum_parents' => ''), - array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => ''), - array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => ''), - array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => ''), - array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => ''), - array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => ''), + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 8, 'right_id' => 11, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 9, 'right_id' => 10, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => 'a:0:{}'), )), array('Move last item down', 7, -1, false, array( - array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => ''), - array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => ''), - array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => ''), - array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12, 'forum_parents' => ''), - array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 8, 'right_id' => 11, 'forum_parents' => ''), - array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 9, 'right_id' => 10, 'forum_parents' => ''), - array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => ''), - array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => ''), - array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => ''), - array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => ''), - array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => ''), + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 8, 'right_id' => 11, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 9, 'right_id' => 10, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => 'a:0:{}'), )), array('Move first item down', 1, -1, true, array( - array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => ''), - array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 2, 'right_id' => 5, 'forum_parents' => ''), - array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 3, 'right_id' => 4, 'forum_parents' => ''), - array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12, 'forum_parents' => ''), - array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 8, 'right_id' => 9, 'forum_parents' => ''), - array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 10, 'right_id' => 11, 'forum_parents' => ''), - array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => ''), - array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => ''), - array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => ''), - array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => ''), - array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => ''), + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 2, 'right_id' => 5, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 3, 'right_id' => 4, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 8, 'right_id' => 9, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 10, 'right_id' => 11, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => 'a:0:{}'), )), array('Move second item up', 4, 1, true, array( - array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => ''), - array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 2, 'right_id' => 5, 'forum_parents' => ''), - array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 3, 'right_id' => 4, 'forum_parents' => ''), - array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12, 'forum_parents' => ''), - array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 8, 'right_id' => 9, 'forum_parents' => ''), - array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 10, 'right_id' => 11, 'forum_parents' => ''), - array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => ''), - array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => ''), - array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => ''), - array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => ''), - array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => ''), + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 2, 'right_id' => 5, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 3, 'right_id' => 4, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 8, 'right_id' => 9, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 10, 'right_id' => 11, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => 'a:0:{}'), )), array('Move last item up', 7, 1, true, array( - array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => ''), - array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => ''), - array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => ''), - array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 16, 'forum_parents' => ''), - array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 8, 'right_id' => 9, 'forum_parents' => ''), - array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 10, 'right_id' => 13, 'forum_parents' => ''), - array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 11, 'right_id' => 12, 'forum_parents' => ''), - array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => ''), - array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 17, 'right_id' => 22, 'forum_parents' => ''), - array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 18, 'right_id' => 21, 'forum_parents' => ''), - array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 19, 'right_id' => 20, 'forum_parents' => ''), + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 16, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 8, 'right_id' => 9, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 10, 'right_id' => 13, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 11, 'right_id' => 12, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 17, 'right_id' => 22, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 18, 'right_id' => 21, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 19, 'right_id' => 20, 'forum_parents' => 'a:0:{}'), )), array('Move last item up by 2', 7, 2, true, array( - array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 10, 'forum_parents' => ''), - array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => ''), - array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 4, 'right_id' => 7, 'forum_parents' => ''), - array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 5, 'right_id' => 6, 'forum_parents' => ''), - array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 8, 'right_id' => 9, 'forum_parents' => ''), - array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 11, 'right_id' => 16, 'forum_parents' => ''), - array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 12, 'right_id' => 13, 'forum_parents' => ''), - array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => ''), - array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 17, 'right_id' => 22, 'forum_parents' => ''), - array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 18, 'right_id' => 21, 'forum_parents' => ''), - array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 19, 'right_id' => 20, 'forum_parents' => ''), + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 10, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 4, 'right_id' => 7, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 5, 'right_id' => 6, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 8, 'right_id' => 9, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 11, 'right_id' => 16, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 12, 'right_id' => 13, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 17, 'right_id' => 22, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 18, 'right_id' => 21, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 19, 'right_id' => 20, 'forum_parents' => 'a:0:{}'), )), array('Move last item up by 100', 7, 100, true, array( - array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 10, 'forum_parents' => ''), - array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => ''), - array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 4, 'right_id' => 7, 'forum_parents' => ''), - array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 5, 'right_id' => 6, 'forum_parents' => ''), - array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 8, 'right_id' => 9, 'forum_parents' => ''), - array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 11, 'right_id' => 16, 'forum_parents' => ''), - array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 12, 'right_id' => 13, 'forum_parents' => ''), - array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => ''), - array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 17, 'right_id' => 22, 'forum_parents' => ''), - array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 18, 'right_id' => 21, 'forum_parents' => ''), - array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 19, 'right_id' => 20, 'forum_parents' => ''), + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 10, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 4, 'right_id' => 7, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 5, 'right_id' => 6, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 8, 'right_id' => 9, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 11, 'right_id' => 16, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 12, 'right_id' => 13, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 17, 'right_id' => 22, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 18, 'right_id' => 21, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 19, 'right_id' => 20, 'forum_parents' => 'a:0:{}'), )), ); } @@ -133,31 +133,31 @@ class phpbb_tests_tree_nestedset_forum_move_test extends phpbb_tests_tree_nested return array( array('Move last item down', 7, false, array( - array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => ''), - array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => ''), - array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => ''), - array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12, 'forum_parents' => ''), - array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 8, 'right_id' => 11, 'forum_parents' => ''), - array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 9, 'right_id' => 10, 'forum_parents' => ''), - array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => ''), - array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => ''), - array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => ''), - array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => ''), - array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => ''), + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 8, 'right_id' => 11, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 9, 'right_id' => 10, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => 'a:0:{}'), )), array('Move first item down', 1, true, array( - array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => ''), - array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 2, 'right_id' => 5, 'forum_parents' => ''), - array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 3, 'right_id' => 4, 'forum_parents' => ''), - array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12, 'forum_parents' => ''), - array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 8, 'right_id' => 9, 'forum_parents' => ''), - array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 10, 'right_id' => 11, 'forum_parents' => ''), - array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => ''), - array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => ''), - array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => ''), - array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => ''), - array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => ''), + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 2, 'right_id' => 5, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 3, 'right_id' => 4, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 8, 'right_id' => 9, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 10, 'right_id' => 11, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => 'a:0:{}'), )), ); } @@ -180,31 +180,31 @@ class phpbb_tests_tree_nestedset_forum_move_test extends phpbb_tests_tree_nested return array( array('Move first item up', 1, false, array( - array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => ''), - array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => ''), - array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => ''), - array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12, 'forum_parents' => ''), - array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 8, 'right_id' => 11, 'forum_parents' => ''), - array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 9, 'right_id' => 10, 'forum_parents' => ''), - array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => ''), - array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => ''), - array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => ''), - array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => ''), - array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => ''), + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 8, 'right_id' => 11, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 9, 'right_id' => 10, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => 'a:0:{}'), )), array('Move second item up', 4, true, array( - array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => ''), - array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 2, 'right_id' => 5, 'forum_parents' => ''), - array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 3, 'right_id' => 4, 'forum_parents' => ''), - array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12, 'forum_parents' => ''), - array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 8, 'right_id' => 9, 'forum_parents' => ''), - array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 10, 'right_id' => 11, 'forum_parents' => ''), - array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => ''), - array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => ''), - array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => ''), - array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => ''), - array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => ''), + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 2, 'right_id' => 5, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 3, 'right_id' => 4, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 8, 'right_id' => 9, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 10, 'right_id' => 11, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => 'a:0:{}'), )), ); } @@ -227,131 +227,131 @@ class phpbb_tests_tree_nestedset_forum_move_test extends phpbb_tests_tree_nested return array( array('Item has no children', 2, 1, false, array( - array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => ''), - array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => ''), - array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => ''), + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12, 'forum_parents' => ''), - array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 8, 'right_id' => 11, 'forum_parents' => ''), - array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 9, 'right_id' => 10, 'forum_parents' => ''), + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 8, 'right_id' => 11, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 9, 'right_id' => 10, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => ''), - array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => ''), - array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => ''), - array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => ''), - array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => ''), + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => 'a:0:{}'), )), array('Move to same parent', 4, 4, false, array( - array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => ''), - array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => ''), - array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => ''), + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12, 'forum_parents' => ''), - array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 8, 'right_id' => 11, 'forum_parents' => ''), - array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 9, 'right_id' => 10, 'forum_parents' => ''), + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 8, 'right_id' => 11, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 9, 'right_id' => 10, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => ''), - array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => ''), - array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => ''), - array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => ''), - array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => ''), + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => 'a:0:{}'), )), array('Move single child up', 5, 1, true, array( - array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 8, 'forum_parents' => ''), - array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => ''), - array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => ''), + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 8, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => 'a:0:{}'), array('forum_id' => 6, 'parent_id' => 1, 'left_id' => 6, 'right_id' => 7, 'forum_parents' => ''), - array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 9, 'right_id' => 12, 'forum_parents' => ''), - array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 10, 'right_id' => 11, 'forum_parents' => ''), + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 9, 'right_id' => 12, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 10, 'right_id' => 11, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => ''), - array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => ''), - array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => ''), - array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => ''), - array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => ''), + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => 'a:0:{}'), )), array('Move nested children up', 4, 1, true, array( - array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 10, 'forum_parents' => ''), - array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => ''), - array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => ''), + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 10, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => 'a:0:{}'), array('forum_id' => 5, 'parent_id' => 1, 'left_id' => 6, 'right_id' => 9, 'forum_parents' => ''), array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 7, 'right_id' => 8, 'forum_parents' => ''), - array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 11, 'right_id' => 12, 'forum_parents' => ''), + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 11, 'right_id' => 12, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => ''), - array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => ''), - array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => ''), - array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => ''), - array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => ''), + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => 'a:0:{}'), )), array('Move single child down', 5, 7, true, array( - array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => ''), - array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => ''), - array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => ''), + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 10, 'forum_parents' => ''), - array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 8, 'right_id' => 9, 'forum_parents' => ''), + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 10, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 8, 'right_id' => 9, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 11, 'right_id' => 22, 'forum_parents' => ''), - array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 12, 'right_id' => 13, 'forum_parents' => ''), - array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 17, 'forum_parents' => ''), - array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 15, 'right_id' => 16, 'forum_parents' => ''), - array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 18, 'right_id' => 19, 'forum_parents' => ''), + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 11, 'right_id' => 22, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 12, 'right_id' => 13, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 17, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 15, 'right_id' => 16, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 18, 'right_id' => 19, 'forum_parents' => 'a:0:{}'), array('forum_id' => 6, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => ''), )), array('Move nested children down', 4, 7, true, array( - array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => ''), - array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => ''), - array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => ''), + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 8, 'forum_parents' => ''), + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 8, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 9, 'right_id' => 22, 'forum_parents' => ''), - array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 10, 'right_id' => 11, 'forum_parents' => ''), - array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 12, 'right_id' => 15, 'forum_parents' => ''), - array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 13, 'right_id' => 14, 'forum_parents' => ''), - array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 17, 'forum_parents' => ''), + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 9, 'right_id' => 22, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 10, 'right_id' => 11, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 12, 'right_id' => 15, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 13, 'right_id' => 14, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 17, 'forum_parents' => 'a:0:{}'), array('forum_id' => 5, 'parent_id' => 7, 'left_id' => 18, 'right_id' => 21, 'forum_parents' => ''), array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 19, 'right_id' => 20, 'forum_parents' => ''), )), array('Move single child to parent 0', 5, 0, true, array( - array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => ''), - array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => ''), - array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => ''), + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 10, 'forum_parents' => ''), - array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 8, 'right_id' => 9, 'forum_parents' => ''), + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 10, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 8, 'right_id' => 9, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 11, 'right_id' => 20, 'forum_parents' => ''), - array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 12, 'right_id' => 13, 'forum_parents' => ''), - array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 17, 'forum_parents' => ''), - array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 15, 'right_id' => 16, 'forum_parents' => ''), - array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 18, 'right_id' => 19, 'forum_parents' => ''), + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 11, 'right_id' => 20, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 12, 'right_id' => 13, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 17, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 15, 'right_id' => 16, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 18, 'right_id' => 19, 'forum_parents' => 'a:0:{}'), array('forum_id' => 6, 'parent_id' => 0, 'left_id' => 21, 'right_id' => 22, 'forum_parents' => ''), )), array('Move nested children to parent 0', 4, 0, true, array( - array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => ''), - array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => ''), - array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => ''), + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 8, 'forum_parents' => ''), + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 8, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 9, 'right_id' => 18, 'forum_parents' => ''), - array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 10, 'right_id' => 11, 'forum_parents' => ''), - array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 12, 'right_id' => 15, 'forum_parents' => ''), - array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 13, 'right_id' => 14, 'forum_parents' => ''), - array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 17, 'forum_parents' => ''), + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 9, 'right_id' => 18, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 10, 'right_id' => 11, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 12, 'right_id' => 15, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 13, 'right_id' => 14, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 17, 'forum_parents' => 'a:0:{}'), array('forum_id' => 5, 'parent_id' => 0, 'left_id' => 19, 'right_id' => 22, 'forum_parents' => ''), array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => ''), @@ -416,98 +416,98 @@ class phpbb_tests_tree_nestedset_forum_move_test extends phpbb_tests_tree_nested return array( array('Move single child up', 6, 1, true, array( - array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 8, 'forum_parents' => ''), - array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => ''), - array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => ''), + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 8, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => 'a:0:{}'), array('forum_id' => 6, 'parent_id' => 1, 'left_id' => 6, 'right_id' => 7, 'forum_parents' => ''), - array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 9, 'right_id' => 12, 'forum_parents' => ''), - array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 10, 'right_id' => 11, 'forum_parents' => ''), + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 9, 'right_id' => 12, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 10, 'right_id' => 11, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => ''), - array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => ''), - array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => ''), - array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => ''), - array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => ''), + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => 'a:0:{}'), )), array('Move nested children up', 5, 1, true, array( - array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 10, 'forum_parents' => ''), - array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => ''), - array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => ''), + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 10, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => 'a:0:{}'), array('forum_id' => 5, 'parent_id' => 1, 'left_id' => 6, 'right_id' => 9, 'forum_parents' => ''), array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 7, 'right_id' => 8, 'forum_parents' => ''), - array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 11, 'right_id' => 12, 'forum_parents' => ''), + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 11, 'right_id' => 12, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => ''), - array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => ''), - array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => ''), - array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => ''), - array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => ''), + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => 'a:0:{}'), )), array('Move single child down', 6, 7, true, array( - array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => ''), - array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => ''), - array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => ''), + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 10, 'forum_parents' => ''), - array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 8, 'right_id' => 9, 'forum_parents' => ''), + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 10, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 8, 'right_id' => 9, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 11, 'right_id' => 22, 'forum_parents' => ''), - array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 12, 'right_id' => 13, 'forum_parents' => ''), - array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 17, 'forum_parents' => ''), - array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 15, 'right_id' => 16, 'forum_parents' => ''), - array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 18, 'right_id' => 19, 'forum_parents' => ''), + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 11, 'right_id' => 22, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 12, 'right_id' => 13, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 17, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 15, 'right_id' => 16, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 18, 'right_id' => 19, 'forum_parents' => 'a:0:{}'), array('forum_id' => 6, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => ''), )), array('Move nested children down', 5, 7, true, array( - array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => ''), - array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => ''), - array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => ''), + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 8, 'forum_parents' => ''), + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 8, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 9, 'right_id' => 22, 'forum_parents' => ''), - array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 10, 'right_id' => 11, 'forum_parents' => ''), - array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 12, 'right_id' => 15, 'forum_parents' => ''), - array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 13, 'right_id' => 14, 'forum_parents' => ''), - array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 17, 'forum_parents' => ''), + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 9, 'right_id' => 22, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 10, 'right_id' => 11, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 12, 'right_id' => 15, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 13, 'right_id' => 14, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 17, 'forum_parents' => 'a:0:{}'), array('forum_id' => 5, 'parent_id' => 7, 'left_id' => 18, 'right_id' => 21, 'forum_parents' => ''), array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 19, 'right_id' => 20, 'forum_parents' => ''), )), array('Move single child to parent 0', 6, 0, true, array( - array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => ''), - array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => ''), - array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => ''), + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 10, 'forum_parents' => ''), - array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 8, 'right_id' => 9, 'forum_parents' => ''), + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 10, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 8, 'right_id' => 9, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 11, 'right_id' => 20, 'forum_parents' => ''), - array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 12, 'right_id' => 13, 'forum_parents' => ''), - array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 17, 'forum_parents' => ''), - array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 15, 'right_id' => 16, 'forum_parents' => ''), - array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 18, 'right_id' => 19, 'forum_parents' => ''), + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 11, 'right_id' => 20, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 12, 'right_id' => 13, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 17, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 15, 'right_id' => 16, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 18, 'right_id' => 19, 'forum_parents' => 'a:0:{}'), array('forum_id' => 6, 'parent_id' => 0, 'left_id' => 21, 'right_id' => 22, 'forum_parents' => ''), )), array('Move nested children to parent 0', 5, 0, true, array( - array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => ''), - array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => ''), - array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => ''), + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 8, 'forum_parents' => ''), + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 8, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 9, 'right_id' => 18, 'forum_parents' => ''), - array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 10, 'right_id' => 11, 'forum_parents' => ''), - array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 12, 'right_id' => 15, 'forum_parents' => ''), - array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 13, 'right_id' => 14, 'forum_parents' => ''), - array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 17, 'forum_parents' => ''), + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 9, 'right_id' => 18, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 10, 'right_id' => 11, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 12, 'right_id' => 15, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 13, 'right_id' => 14, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 17, 'forum_parents' => 'a:0:{}'), array('forum_id' => 5, 'parent_id' => 0, 'left_id' => 19, 'right_id' => 22, 'forum_parents' => ''), array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => ''), diff --git a/tests/tree/nestedset_forum_test.php b/tests/tree/nestedset_forum_test.php index 4e335f9d35..631ec2c4bc 100644 --- a/tests/tree/nestedset_forum_test.php +++ b/tests/tree/nestedset_forum_test.php @@ -15,19 +15,19 @@ class pphpbb_tests_tree_nestedset_forum_test extends phpbb_tests_tree_nestedset_ { return array( array(array( - array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => ''), - array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => ''), - array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => ''), + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12, 'forum_parents' => ''), - array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 8, 'right_id' => 11, 'forum_parents' => ''), - array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 9, 'right_id' => 10, 'forum_parents' => ''), + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 8, 'right_id' => 11, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 9, 'right_id' => 10, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => ''), - array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => ''), - array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => ''), - array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => ''), - array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => ''), + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => 'a:0:{}'), )), ); } @@ -51,56 +51,56 @@ class pphpbb_tests_tree_nestedset_forum_test extends phpbb_tests_tree_nestedset_ %s ORDER BY left_id, forum_id ASC', 'WHERE', '', array( - array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => ''), - array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => ''), - array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => ''), + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12, 'forum_parents' => ''), - array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 8, 'right_id' => 11, 'forum_parents' => ''), - array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 9, 'right_id' => 10, 'forum_parents' => ''), + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 8, 'right_id' => 11, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 9, 'right_id' => 10, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => ''), - array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => ''), - array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => ''), - array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => ''), - array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => ''), + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => 'a:0:{}'), )), array('SELECT f.forum_id, f.parent_id, f.left_id, f.right_id, f.forum_parents FROM phpbb_forums f %s ORDER BY f.left_id, f.forum_id ASC', 'WHERE', 'f.', array( - array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => ''), - array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => ''), - array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => ''), + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12, 'forum_parents' => ''), - array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 8, 'right_id' => 11, 'forum_parents' => ''), - array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 9, 'right_id' => 10, 'forum_parents' => ''), + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 8, 'right_id' => 11, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 9, 'right_id' => 10, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => ''), - array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => ''), - array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => ''), - array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => ''), - array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => ''), + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => 'a:0:{}'), )), array('SELECT forum_id, parent_id, left_id, right_id, forum_parents FROM phpbb_forums WHERE forum_id < 4 %s ORDER BY left_id, forum_id ASC', 'AND', '', array( - array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => ''), - array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => ''), - array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => ''), + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => 'a:0:{}'), )), array('SELECT f.forum_id, f.parent_id, f.left_id, f.right_id, f.forum_parents FROM phpbb_forums f WHERE f.forum_id < 4 %s ORDER BY f.left_id, f.forum_id ASC', 'AND', 'f.', array( - array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => ''), - array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => ''), - array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => ''), + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => 'a:0:{}'), )), ); } From 5c4d69581afb9fd9b00d6b7b13cec257a97e875c Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 30 Apr 2013 18:06:29 +0200 Subject: [PATCH 236/281] [ticket/11495] Do not reset item_parent if not required PHPBB3-11495 --- phpBB/includes/tree/nestedset.php | 32 ++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/phpBB/includes/tree/nestedset.php b/phpBB/includes/tree/nestedset.php index 5a12afdfe9..1f414164df 100644 --- a/phpBB/includes/tree/nestedset.php +++ b/phpBB/includes/tree/nestedset.php @@ -310,8 +310,7 @@ abstract class phpbb_tree_nestedset implements phpbb_tree_interface " . $this->column_right_id . ' = ' . $this->column_right_id . ' + CASE WHEN ' . $this->column_right_id . " BETWEEN {$move_up_left} AND {$move_up_right} THEN -{$diff_up} ELSE {$diff_down} - END, - " . $this->column_item_parents . " = '' + END WHERE " . $this->column_left_id . " BETWEEN {$left_id} AND {$right_id} AND " . $this->column_right_id . " BETWEEN {$left_id} AND {$right_id} @@ -692,11 +691,10 @@ abstract class phpbb_tree_nestedset implements phpbb_tree_interface } $sql = 'UPDATE ' . $this->table_name . ' - SET ' . $this->column_left_id . ' = ' . $set_left_id . ', - ' . $this->column_right_id . ' = ' . $set_right_id . ', - ' . (($set_subset_zero) ? $this->column_parent_id . ' = ' . $this->db->sql_case($sql_subset_items, 0, $this->column_parent_id) . ',' : '') . ' - ' . $this->column_item_parents . " = '' - " . ((!$set_subset_zero) ? ' WHERE ' . $sql_not_subset_items . ' ' . $this->get_sql_where('AND') : $this->get_sql_where('WHERE')); + SET ' . (($set_subset_zero) ? $this->column_parent_id . ' = ' . $this->db->sql_case($sql_subset_items, 0, $this->column_parent_id) . ',' : '') . ' + ' . $this->column_left_id . ' = ' . $set_left_id . ', + ' . $this->column_right_id . ' = ' . $set_right_id . ' + ' . ((!$set_subset_zero) ? ' WHERE ' . $sql_not_subset_items . ' ' . $this->get_sql_where('AND') : $this->get_sql_where('WHERE')); $this->db->sql_query($sql); if ($acquired_new_lock) @@ -706,7 +704,7 @@ abstract class phpbb_tree_nestedset implements phpbb_tree_interface } /** - * Add a subset to the nested set + * Prepare adding a subset to the nested set * * @param array $subset_items Subset of items to add * @param array $new_parent Item containing the right bound of the new parent @@ -722,9 +720,8 @@ abstract class phpbb_tree_nestedset implements phpbb_tree_interface $sql = 'UPDATE ' . $this->table_name . ' SET ' . $this->column_left_id . ' = ' . $set_left_id . ', - ' . $this->column_right_id . ' = ' . $set_right_id . ', - ' . $this->column_item_parents . " = '' - WHERE " . $sql_not_subset_items . ' + ' . $this->column_right_id . ' = ' . $set_right_id . ' + WHERE ' . $sql_not_subset_items . ' ' . $this->get_sql_where('AND'); $this->db->sql_query($sql); @@ -776,6 +773,14 @@ abstract class phpbb_tree_nestedset implements phpbb_tree_interface if ($acquired_new_lock = $this->acquire_lock()) { $this->db->sql_transaction('begin'); + + if (!$reset_ids) + { + $sql = 'UPDATE ' . $this->table_name . ' + SET ' . $this->column_item_parents . " = '' + " . $this->get_sql_where('WHERE'); + $this->db->sql_query($sql); + } } if ($reset_ids) @@ -802,10 +807,7 @@ abstract class phpbb_tree_nestedset implements phpbb_tree_interface if ($row[$this->column_left_id] != $new_id) { $sql = 'UPDATE ' . $this->table_name . ' - SET ' . $this->db->sql_build_array('UPDATE', array( - $this->column_left_id => $new_id, - $this->column_item_parents => '', - )) . ' + SET ' . $this->db->sql_build_array('UPDATE', array($this->column_left_id => $new_id)) . ' WHERE ' . $this->column_item_id . ' = ' . (int) $row[$this->column_item_id]; $this->db->sql_query($sql); } From fe02218a2d2f5634e22e494f7b85f9701fa57623 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 30 Apr 2013 18:11:24 +0200 Subject: [PATCH 237/281] [ticket/11495] Remove forum_parents from tests where it is not required PHPBB3-11495 --- .../nestedset_forum_insert_delete_test.php | 64 ++--- tests/tree/nestedset_forum_move_test.php | 248 +++++++++--------- tests/tree/nestedset_forum_test.php | 88 +++---- 3 files changed, 200 insertions(+), 200 deletions(-) diff --git a/tests/tree/nestedset_forum_insert_delete_test.php b/tests/tree/nestedset_forum_insert_delete_test.php index 34aac19270..1f901c7422 100644 --- a/tests/tree/nestedset_forum_insert_delete_test.php +++ b/tests/tree/nestedset_forum_insert_delete_test.php @@ -15,26 +15,26 @@ class phpbb_tests_tree_nestedset_forum_add_remove_test extends phpbb_tests_tree_ { return array( array(1, array(1, 2, 3), array( - array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 2, 'right_id' => 5, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 3, 'right_id' => 4, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 16, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 8, 'right_id' => 9, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 10, 'right_id' => 13, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 11, 'right_id' => 12, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 2, 'right_id' => 5), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 3, 'right_id' => 4), + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 16), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 8, 'right_id' => 9), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 10, 'right_id' => 13), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 11, 'right_id' => 12), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15), )), array(2, array(2), array( - array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 4, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 5, 'right_id' => 10, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 6, 'right_id' => 9, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 7, 'right_id' => 8, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 11, 'right_id' => 20, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 12, 'right_id' => 13, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 17, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 15, 'right_id' => 16, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 18, 'right_id' => 19, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 4), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3), + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 5, 'right_id' => 10), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 6, 'right_id' => 9), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 7, 'right_id' => 8), + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 11, 'right_id' => 20), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 12, 'right_id' => 13), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 17), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 15, 'right_id' => 16), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 18, 'right_id' => 19), )), ); } @@ -46,7 +46,7 @@ class phpbb_tests_tree_nestedset_forum_add_remove_test extends phpbb_tests_tree_ { $this->assertEquals($expected_deleted, $this->set->delete($forum_id)); - $result = $this->db->sql_query("SELECT forum_id, parent_id, left_id, right_id, forum_parents + $result = $this->db->sql_query("SELECT forum_id, parent_id, left_id, right_id FROM phpbb_forums ORDER BY left_id, forum_id ASC"); $this->assertEquals($expected, $this->db->sql_fetchrowset($result)); @@ -64,21 +64,21 @@ class phpbb_tests_tree_nestedset_forum_add_remove_test extends phpbb_tests_tree_ 'right_id' => 24, 'forum_parents' => '', ), array( - array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5), - array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 8, 'right_id' => 11, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 9, 'right_id' => 10, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 8, 'right_id' => 11), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 9, 'right_id' => 10), - array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21), - array('forum_id' => 12, 'parent_id' => 0, 'left_id' => 23, 'right_id' => 24, 'forum_parents' => ''), + array('forum_id' => 12, 'parent_id' => 0, 'left_id' => 23, 'right_id' => 24), )), ); } @@ -93,7 +93,7 @@ class phpbb_tests_tree_nestedset_forum_add_remove_test extends phpbb_tests_tree_ 'forum_rules' => '', ))); - $result = $this->db->sql_query('SELECT forum_id, parent_id, left_id, right_id, forum_parents + $result = $this->db->sql_query('SELECT forum_id, parent_id, left_id, right_id FROM phpbb_forums ORDER BY left_id, forum_id ASC'); $this->assertEquals($expected, $this->db->sql_fetchrowset($result)); diff --git a/tests/tree/nestedset_forum_move_test.php b/tests/tree/nestedset_forum_move_test.php index 0901082926..fe506c8278 100644 --- a/tests/tree/nestedset_forum_move_test.php +++ b/tests/tree/nestedset_forum_move_test.php @@ -16,101 +16,101 @@ class phpbb_tests_tree_nestedset_forum_move_test extends phpbb_tests_tree_nested return array( array('Move first item up', 1, 1, false, array( - array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 8, 'right_id' => 11, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 9, 'right_id' => 10, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5), + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 8, 'right_id' => 11), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 9, 'right_id' => 10), + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21), )), array('Move last item down', 7, -1, false, array( - array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 8, 'right_id' => 11, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 9, 'right_id' => 10, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5), + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 8, 'right_id' => 11), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 9, 'right_id' => 10), + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21), )), array('Move first item down', 1, -1, true, array( - array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 2, 'right_id' => 5, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 3, 'right_id' => 4, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 8, 'right_id' => 9, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 10, 'right_id' => 11, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 2, 'right_id' => 5), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 3, 'right_id' => 4), + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 8, 'right_id' => 9), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 10, 'right_id' => 11), + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21), )), array('Move second item up', 4, 1, true, array( - array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 2, 'right_id' => 5, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 3, 'right_id' => 4, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 8, 'right_id' => 9, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 10, 'right_id' => 11, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 2, 'right_id' => 5), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 3, 'right_id' => 4), + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 8, 'right_id' => 9), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 10, 'right_id' => 11), + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21), )), array('Move last item up', 7, 1, true, array( - array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 16, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 8, 'right_id' => 9, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 10, 'right_id' => 13, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 11, 'right_id' => 12, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 17, 'right_id' => 22, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 18, 'right_id' => 21, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 19, 'right_id' => 20, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5), + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 16), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 8, 'right_id' => 9), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 10, 'right_id' => 13), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 11, 'right_id' => 12), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15), + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 17, 'right_id' => 22), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 18, 'right_id' => 21), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 19, 'right_id' => 20), )), array('Move last item up by 2', 7, 2, true, array( - array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 10, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 4, 'right_id' => 7, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 5, 'right_id' => 6, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 8, 'right_id' => 9, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 11, 'right_id' => 16, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 12, 'right_id' => 13, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 17, 'right_id' => 22, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 18, 'right_id' => 21, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 19, 'right_id' => 20, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 10), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 2, 'right_id' => 3), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 4, 'right_id' => 7), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 5, 'right_id' => 6), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 8, 'right_id' => 9), + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 11, 'right_id' => 16), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 12, 'right_id' => 13), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 14, 'right_id' => 15), + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 17, 'right_id' => 22), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 18, 'right_id' => 21), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 19, 'right_id' => 20), )), array('Move last item up by 100', 7, 100, true, array( - array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 10, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 4, 'right_id' => 7, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 5, 'right_id' => 6, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 8, 'right_id' => 9, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 11, 'right_id' => 16, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 12, 'right_id' => 13, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 17, 'right_id' => 22, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 18, 'right_id' => 21, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 19, 'right_id' => 20, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 10), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 2, 'right_id' => 3), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 4, 'right_id' => 7), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 5, 'right_id' => 6), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 8, 'right_id' => 9), + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 11, 'right_id' => 16), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 12, 'right_id' => 13), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 14, 'right_id' => 15), + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 17, 'right_id' => 22), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 18, 'right_id' => 21), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 19, 'right_id' => 20), )), ); } @@ -122,7 +122,7 @@ class phpbb_tests_tree_nestedset_forum_move_test extends phpbb_tests_tree_nested { $this->assertEquals($expected_moved, $this->set->move($forum_id, $delta)); - $result = $this->db->sql_query("SELECT forum_id, parent_id, left_id, right_id, forum_parents + $result = $this->db->sql_query("SELECT forum_id, parent_id, left_id, right_id FROM phpbb_forums ORDER BY left_id, forum_id ASC"); $this->assertEquals($expected, $this->db->sql_fetchrowset($result)); @@ -133,31 +133,31 @@ class phpbb_tests_tree_nestedset_forum_move_test extends phpbb_tests_tree_nested return array( array('Move last item down', 7, false, array( - array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 8, 'right_id' => 11, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 9, 'right_id' => 10, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5), + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 8, 'right_id' => 11), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 9, 'right_id' => 10), + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21), )), array('Move first item down', 1, true, array( - array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 2, 'right_id' => 5, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 3, 'right_id' => 4, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 8, 'right_id' => 9, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 10, 'right_id' => 11, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 2, 'right_id' => 5), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 3, 'right_id' => 4), + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 8, 'right_id' => 9), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 10, 'right_id' => 11), + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21), )), ); } @@ -169,7 +169,7 @@ class phpbb_tests_tree_nestedset_forum_move_test extends phpbb_tests_tree_nested { $this->assertEquals($expected_moved, $this->set->move_down($forum_id)); - $result = $this->db->sql_query("SELECT forum_id, parent_id, left_id, right_id, forum_parents + $result = $this->db->sql_query("SELECT forum_id, parent_id, left_id, right_id FROM phpbb_forums ORDER BY left_id, forum_id ASC"); $this->assertEquals($expected, $this->db->sql_fetchrowset($result)); @@ -180,31 +180,31 @@ class phpbb_tests_tree_nestedset_forum_move_test extends phpbb_tests_tree_nested return array( array('Move first item up', 1, false, array( - array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 8, 'right_id' => 11, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 9, 'right_id' => 10, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5), + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 8, 'right_id' => 11), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 9, 'right_id' => 10), + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21), )), array('Move second item up', 4, true, array( - array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 2, 'right_id' => 5, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 3, 'right_id' => 4, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 8, 'right_id' => 9, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 10, 'right_id' => 11, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 2, 'right_id' => 5), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 3, 'right_id' => 4), + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 8, 'right_id' => 9), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 10, 'right_id' => 11), + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21), )), ); } @@ -216,7 +216,7 @@ class phpbb_tests_tree_nestedset_forum_move_test extends phpbb_tests_tree_nested { $this->assertEquals($expected_moved, $this->set->move_up($forum_id)); - $result = $this->db->sql_query("SELECT forum_id, parent_id, left_id, right_id, forum_parents + $result = $this->db->sql_query("SELECT forum_id, parent_id, left_id, right_id FROM phpbb_forums ORDER BY left_id, forum_id ASC"); $this->assertEquals($expected, $this->db->sql_fetchrowset($result)); diff --git a/tests/tree/nestedset_forum_test.php b/tests/tree/nestedset_forum_test.php index 631ec2c4bc..28c6b048b0 100644 --- a/tests/tree/nestedset_forum_test.php +++ b/tests/tree/nestedset_forum_test.php @@ -15,19 +15,19 @@ class pphpbb_tests_tree_nestedset_forum_test extends phpbb_tests_tree_nestedset_ { return array( array(array( - array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5), - array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 8, 'right_id' => 11, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 9, 'right_id' => 10, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 8, 'right_id' => 11), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 9, 'right_id' => 10), - array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21), )), ); } @@ -37,7 +37,7 @@ class pphpbb_tests_tree_nestedset_forum_test extends phpbb_tests_tree_nestedset_ */ public function test_forum_constructor($expected) { - $result = $this->db->sql_query('SELECT forum_id, parent_id, left_id, right_id, forum_parents + $result = $this->db->sql_query('SELECT forum_id, parent_id, left_id, right_id FROM phpbb_forums ORDER BY left_id, forum_id ASC'); $this->assertEquals($expected, $this->db->sql_fetchrowset($result)); @@ -46,61 +46,61 @@ class pphpbb_tests_tree_nestedset_forum_test extends phpbb_tests_tree_nestedset_ public function get_sql_where_data() { return array( - array('SELECT forum_id, parent_id, left_id, right_id, forum_parents + array('SELECT forum_id, parent_id, left_id, right_id FROM phpbb_forums %s ORDER BY left_id, forum_id ASC', 'WHERE', '', array( - array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5), - array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 8, 'right_id' => 11, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 9, 'right_id' => 10, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 8, 'right_id' => 11), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 9, 'right_id' => 10), - array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21), )), - array('SELECT f.forum_id, f.parent_id, f.left_id, f.right_id, f.forum_parents + array('SELECT f.forum_id, f.parent_id, f.left_id, f.right_id FROM phpbb_forums f %s ORDER BY f.left_id, f.forum_id ASC', 'WHERE', 'f.', array( - array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5), - array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 8, 'right_id' => 11, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 9, 'right_id' => 10, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12), + array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 8, 'right_id' => 11), + array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 9, 'right_id' => 10), - array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22), + array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15), + array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19), + array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18), + array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21), )), - array('SELECT forum_id, parent_id, left_id, right_id, forum_parents + array('SELECT forum_id, parent_id, left_id, right_id FROM phpbb_forums WHERE forum_id < 4 %s ORDER BY left_id, forum_id ASC', 'AND', '', array( - array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5), )), - array('SELECT f.forum_id, f.parent_id, f.left_id, f.right_id, f.forum_parents + array('SELECT f.forum_id, f.parent_id, f.left_id, f.right_id FROM phpbb_forums f WHERE f.forum_id < 4 %s ORDER BY f.left_id, f.forum_id ASC', 'AND', 'f.', array( - array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3, 'forum_parents' => 'a:0:{}'), - array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5, 'forum_parents' => 'a:0:{}'), + array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6), + array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3), + array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5), )), ); } From 98e6207c35910bf9761433e62ca5fe5af3459873 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 30 Apr 2013 18:13:32 +0200 Subject: [PATCH 238/281] [ticket/11495] Fix "as well" typo and remove brackets PHPBB3-11495 --- phpBB/includes/tree/interface.php | 6 +++--- phpBB/includes/tree/nestedset.php | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/phpBB/includes/tree/interface.php b/phpBB/includes/tree/interface.php index 9bd633a5eb..546e00ed06 100644 --- a/phpBB/includes/tree/interface.php +++ b/phpBB/includes/tree/interface.php @@ -92,7 +92,7 @@ interface phpbb_tree_interface * * @param int $item_id The item to get the ancestors/descendants from * @param bool $order_asc Order the items ascending (most outer ancestor first) - * @param bool $include_item Should the item (matching the given item id) be included in the list aswell + * @param bool $include_item Should the item matching the given item id be included in the list as well * @return array Array of items (containing all columns from the item table) * ID => Item data */ @@ -103,7 +103,7 @@ interface phpbb_tree_interface * * @param int $item_id The item id to get the ancestors from * @param bool $order_asc Order the items ascending (most outer ancestor first) - * @param bool $include_item Should the item (matching the given item id) be included in the list aswell + * @param bool $include_item Should the item matching the given item id be included in the list as well * @return array Array of items (containing all columns from the item table) * ID => Item data */ @@ -114,7 +114,7 @@ interface phpbb_tree_interface * * @param int $item_id The item id to get the descendants from * @param bool $order_asc Order the items ascending - * @param bool $include_item Should the item (matching the given item id) be included in the list aswell + * @param bool $include_item Should the item matching the given item id be included in the list as well * @return array Array of items (containing all columns from the item table) * ID => Item data */ diff --git a/phpBB/includes/tree/nestedset.php b/phpBB/includes/tree/nestedset.php index 1f414164df..2a639d8907 100644 --- a/phpBB/includes/tree/nestedset.php +++ b/phpBB/includes/tree/nestedset.php @@ -580,7 +580,7 @@ abstract class phpbb_tree_nestedset implements phpbb_tree_interface * @param int $item_id The item id to get the node set from * @param string $condition Query string restricting the item list * @param bool $order_asc Order the items ascending by their left_id - * @param bool $include_item Should the item (matching the given item id) be included in the list aswell + * @param bool $include_item Should the item matching the given item id be included in the list as well * @return array Array of items (containing all columns from the item table) * ID => Item data */ From 2f54a63b0fb998c84730e21a3af4150281c22cab Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 30 Apr 2013 18:24:54 +0200 Subject: [PATCH 239/281] [ticket/11495] Fix more grammar issues in doc blocks PHPBB3-11495 --- phpBB/includes/tree/interface.php | 16 ++++++++-------- tests/tree/nestedset_forum_base.php | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/phpBB/includes/tree/interface.php b/phpBB/includes/tree/interface.php index 546e00ed06..2eb40b066c 100644 --- a/phpBB/includes/tree/interface.php +++ b/phpBB/includes/tree/interface.php @@ -90,8 +90,8 @@ interface phpbb_tree_interface /** * Get all items that are either ancestors or descendants of the item * - * @param int $item_id The item to get the ancestors/descendants from - * @param bool $order_asc Order the items ascending (most outer ancestor first) + * @param int $item_id The item id the ancestors/descendants should be retrieved from + * @param bool $order_asc Order the items ascendingly (most outer ancestor first) * @param bool $include_item Should the item matching the given item id be included in the list as well * @return array Array of items (containing all columns from the item table) * ID => Item data @@ -99,10 +99,10 @@ interface phpbb_tree_interface public function get_path_and_subtree_data($item_id, $order_asc, $include_item); /** - * Get all ancestors of the item + * Get all of the item's ancestors * - * @param int $item_id The item id to get the ancestors from - * @param bool $order_asc Order the items ascending (most outer ancestor first) + * @param int $item_id The item id the ancestors should be retrieved from + * @param bool $order_asc Order the items ascendingly (most outer ancestor first) * @param bool $include_item Should the item matching the given item id be included in the list as well * @return array Array of items (containing all columns from the item table) * ID => Item data @@ -110,10 +110,10 @@ interface phpbb_tree_interface public function get_path_data($item_id, $order_asc, $include_item); /** - * Get all descendants of the item + * Get all of the item's descendants * - * @param int $item_id The item id to get the descendants from - * @param bool $order_asc Order the items ascending + * @param int $item_id The item id the descendants should be retrieved from + * @param bool $order_asc Order the items ascendingly * @param bool $include_item Should the item matching the given item id be included in the list as well * @return array Array of items (containing all columns from the item table) * ID => Item data diff --git a/tests/tree/nestedset_forum_base.php b/tests/tree/nestedset_forum_base.php index b9d42fb51d..776e822280 100644 --- a/tests/tree/nestedset_forum_base.php +++ b/tests/tree/nestedset_forum_base.php @@ -34,7 +34,7 @@ class phpbb_tests_tree_nestedset_forum_base extends phpbb_database_test_case 10 => array('forum_id' => 10, 'parent_id' => 9, 'user_id' => 0, 'left_id' => 17, 'right_id' => 18, 'forum_parents' => 'a:0:{}'), 11 => array('forum_id' => 11, 'parent_id' => 7, 'user_id' => 0, 'left_id' => 20, 'right_id' => 21, 'forum_parents' => 'a:0:{}'), - // Unexisting forums + // Non-existent forums 0 => array('forum_id' => 0, 'parent_id' => 0, 'user_id' => 0, 'left_id' => 0, 'right_id' => 0, 'forum_parents' => 'a:0:{}'), 200 => array('forum_id' => 200, 'parent_id' => 0, 'user_id' => 0, 'left_id' => 0, 'right_id' => 0, 'forum_parents' => 'a:0:{}'), ); From d1d59dc5cc3ca779c5e7a971659c8aca5e28215d Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 30 Apr 2013 18:33:28 +0200 Subject: [PATCH 240/281] [ticket/11495] Remove unneccessary values from tests PHPBB3-11495 --- tests/tree/nestedset_forum_test.php | 72 ++++++++++++++--------------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/tests/tree/nestedset_forum_test.php b/tests/tree/nestedset_forum_test.php index 28c6b048b0..516c794ffc 100644 --- a/tests/tree/nestedset_forum_test.php +++ b/tests/tree/nestedset_forum_test.php @@ -46,61 +46,61 @@ class pphpbb_tests_tree_nestedset_forum_test extends phpbb_tests_tree_nestedset_ public function get_sql_where_data() { return array( - array('SELECT forum_id, parent_id, left_id, right_id + array('SELECT forum_id FROM phpbb_forums %s - ORDER BY left_id, forum_id ASC', + ORDER BY forum_id ASC', 'WHERE', '', array( - array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6), - array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3), - array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5), + array('forum_id' => 1), + array('forum_id' => 2), + array('forum_id' => 3), - array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12), - array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 8, 'right_id' => 11), - array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 9, 'right_id' => 10), + array('forum_id' => 4), + array('forum_id' => 5), + array('forum_id' => 6), - array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22), - array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15), - array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19), - array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18), - array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21), + array('forum_id' => 7), + array('forum_id' => 8), + array('forum_id' => 9), + array('forum_id' => 10), + array('forum_id' => 11), )), - array('SELECT f.forum_id, f.parent_id, f.left_id, f.right_id + array('SELECT f.forum_id FROM phpbb_forums f %s - ORDER BY f.left_id, f.forum_id ASC', + ORDER BY f.forum_id ASC', 'WHERE', 'f.', array( - array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6), - array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3), - array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5), + array('forum_id' => 1), + array('forum_id' => 2), + array('forum_id' => 3), - array('forum_id' => 4, 'parent_id' => 0, 'left_id' => 7, 'right_id' => 12), - array('forum_id' => 5, 'parent_id' => 4, 'left_id' => 8, 'right_id' => 11), - array('forum_id' => 6, 'parent_id' => 5, 'left_id' => 9, 'right_id' => 10), + array('forum_id' => 4), + array('forum_id' => 5), + array('forum_id' => 6), - array('forum_id' => 7, 'parent_id' => 0, 'left_id' => 13, 'right_id' => 22), - array('forum_id' => 8, 'parent_id' => 7, 'left_id' => 14, 'right_id' => 15), - array('forum_id' => 9, 'parent_id' => 7, 'left_id' => 16, 'right_id' => 19), - array('forum_id' => 10, 'parent_id' => 9, 'left_id' => 17, 'right_id' => 18), - array('forum_id' => 11, 'parent_id' => 7, 'left_id' => 20, 'right_id' => 21), + array('forum_id' => 7), + array('forum_id' => 8), + array('forum_id' => 9), + array('forum_id' => 10), + array('forum_id' => 11), )), - array('SELECT forum_id, parent_id, left_id, right_id + array('SELECT forum_id FROM phpbb_forums WHERE forum_id < 4 %s - ORDER BY left_id, forum_id ASC', + ORDER BY forum_id ASC', 'AND', '', array( - array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6), - array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3), - array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5), + array('forum_id' => 1), + array('forum_id' => 2), + array('forum_id' => 3), )), - array('SELECT f.forum_id, f.parent_id, f.left_id, f.right_id + array('SELECT f.forum_id FROM phpbb_forums f WHERE f.forum_id < 4 %s - ORDER BY f.left_id, f.forum_id ASC', + ORDER BY f.forum_id ASC', 'AND', 'f.', array( - array('forum_id' => 1, 'parent_id' => 0, 'left_id' => 1, 'right_id' => 6), - array('forum_id' => 2, 'parent_id' => 1, 'left_id' => 2, 'right_id' => 3), - array('forum_id' => 3, 'parent_id' => 1, 'left_id' => 4, 'right_id' => 5), + array('forum_id' => 1), + array('forum_id' => 2), + array('forum_id' => 3), )), ); } From 6a7378ecbdeea1ad356cbde8a085aa7510c61788 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 30 Apr 2013 18:39:22 +0200 Subject: [PATCH 241/281] [ticket/11495] Some more doc changes PHPBB3-11495 --- phpBB/includes/tree/interface.php | 6 +++--- phpBB/includes/tree/nestedset.php | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/phpBB/includes/tree/interface.php b/phpBB/includes/tree/interface.php index 2eb40b066c..cc8aab2115 100644 --- a/phpBB/includes/tree/interface.php +++ b/phpBB/includes/tree/interface.php @@ -90,7 +90,7 @@ interface phpbb_tree_interface /** * Get all items that are either ancestors or descendants of the item * - * @param int $item_id The item id the ancestors/descendants should be retrieved from + * @param int $item_id Id of the item to retrieve the ancestors/descendants from * @param bool $order_asc Order the items ascendingly (most outer ancestor first) * @param bool $include_item Should the item matching the given item id be included in the list as well * @return array Array of items (containing all columns from the item table) @@ -101,7 +101,7 @@ interface phpbb_tree_interface /** * Get all of the item's ancestors * - * @param int $item_id The item id the ancestors should be retrieved from + * @param int $item_id Id of the item to retrieve the ancestors from * @param bool $order_asc Order the items ascendingly (most outer ancestor first) * @param bool $include_item Should the item matching the given item id be included in the list as well * @return array Array of items (containing all columns from the item table) @@ -112,7 +112,7 @@ interface phpbb_tree_interface /** * Get all of the item's descendants * - * @param int $item_id The item id the descendants should be retrieved from + * @param int $item_id Id of the item to retrieve the descendants from * @param bool $order_asc Order the items ascendingly * @param bool $include_item Should the item matching the given item id be included in the list as well * @return array Array of items (containing all columns from the item table) diff --git a/phpBB/includes/tree/nestedset.php b/phpBB/includes/tree/nestedset.php index 2a639d8907..2f17ebab02 100644 --- a/phpBB/includes/tree/nestedset.php +++ b/phpBB/includes/tree/nestedset.php @@ -577,7 +577,7 @@ abstract class phpbb_tree_nestedset implements phpbb_tree_interface /** * Get items that are related to the given item by the condition * - * @param int $item_id The item id to get the node set from + * @param int $item_id Id of the item to retrieve the node set from * @param string $condition Query string restricting the item list * @param bool $order_asc Order the items ascending by their left_id * @param bool $include_item Should the item matching the given item id be included in the list as well From a5b5e4b31da6f91e73b09b3c2a50d1a79e8c108d Mon Sep 17 00:00:00 2001 From: Dhruv Date: Tue, 30 Apr 2013 22:29:20 +0530 Subject: [PATCH 242/281] [ticket/10325] add assert_response_success in test PHPBB3-10325 --- tests/functional/forgot_password_test.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/functional/forgot_password_test.php b/tests/functional/forgot_password_test.php index 3ae74ed1e9..14dfae3d7c 100644 --- a/tests/functional/forgot_password_test.php +++ b/tests/functional/forgot_password_test.php @@ -17,6 +17,7 @@ class phpbb_functional_forgot_password_test extends phpbb_functional_test_case global $config; $this->add_lang('ucp'); $crawler = $this->request('GET', 'ucp.php?mode=sendpassword'); + $this->assert_response_success(); $this->assertEquals($this->lang('SEND_PASSWORD'), $crawler->filter('h2')->text()); } @@ -26,6 +27,7 @@ class phpbb_functional_forgot_password_test extends phpbb_functional_test_case $this->admin_login(); $this->add_lang('ucp'); $crawler = $this->request('GET', 'adm/index.php?sid=' . $this->sid . '&i=acp_board&mode=security'); + //$this->assert_response_success(); $form = $crawler->selectButton('Submit')->form(); $values = $form->getValues(); @@ -37,7 +39,7 @@ class phpbb_functional_forgot_password_test extends phpbb_functional_test_case $this->logout(); $crawler = $this->request('GET', 'ucp.php?mode=sendpassword'); - + $this->assert_response_success(); $this->assertContains($this->lang('UCP_PASSWORD_RESET_DISABLED', '', ''), $crawler->text()); } From a90a0b087ca3b1e29561a08019ca8ba2fa21c19d Mon Sep 17 00:00:00 2001 From: Dhruv Date: Tue, 30 Apr 2013 22:59:32 +0530 Subject: [PATCH 243/281] [ticket/10325] fix language in acp and ucp PHPBB3-10325 --- phpBB/language/en/acp/board.php | 2 +- phpBB/language/en/ucp.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/phpBB/language/en/acp/board.php b/phpBB/language/en/acp/board.php index 39ad5b78bb..1bc8d1cf46 100644 --- a/phpBB/language/en/acp/board.php +++ b/phpBB/language/en/acp/board.php @@ -454,7 +454,7 @@ $lang = array_merge($lang, array( 'ALL' => 'All', 'ALLOW_AUTOLOGIN' => 'Allow "Remember Me" logins', 'ALLOW_AUTOLOGIN_EXPLAIN' => 'Determines whether users are given "Remember Me" option when they visit the board.', - 'ALLOW_PASSWORD_RESET' => 'Allow "forgot password"', + 'ALLOW_PASSWORD_RESET' => 'Allow "Forgot Password"', 'ALLOW_PASSWORD_RESET_EXPLAIN' => 'Determines whether or not users are able to use the "I forgot my password" link on the login page to recover their account. If you use an external authentication mechanism you may wish to disable this feature.', 'AUTOLOGIN_LENGTH' => '"Remember Me" login key expiration length (in days)', 'AUTOLOGIN_LENGTH_EXPLAIN' => 'Number of days after which "Remember Me" login keys are removed or zero to disable.', diff --git a/phpBB/language/en/ucp.php b/phpBB/language/en/ucp.php index 372e44a94d..a91b6b84d5 100644 --- a/phpBB/language/en/ucp.php +++ b/phpBB/language/en/ucp.php @@ -521,7 +521,7 @@ $lang = array_merge($lang, array( 'UCP_USERGROUPS_MEMBER' => 'Edit memberships', 'UCP_USERGROUPS_MANAGE' => 'Manage groups', - 'UCP_PASSWORD_RESET_DISABLED' => 'The administrator has disabled the password reset functionality. If you need help accessing your account, please contact the %sBoard Administrator%s', + 'UCP_PASSWORD_RESET_DISABLED' => 'The password reset functionality has been disabled. If you need help accessing your account, please contact the %sBoard Administrator%s', 'UCP_REGISTER_DISABLE' => 'Creating a new account is currently not possible.', 'UCP_REMIND' => 'Send password', 'UCP_RESEND' => 'Send activation email', From 1d0c8a1fe86b65174ae27c2353d52b69fda2a16d Mon Sep 17 00:00:00 2001 From: Dhruv Date: Tue, 30 Apr 2013 23:09:28 +0530 Subject: [PATCH 244/281] [ticket/10325] use assert_response_success parts PHPBB3-10325 --- tests/functional/forgot_password_test.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/functional/forgot_password_test.php b/tests/functional/forgot_password_test.php index 14dfae3d7c..bfb4616d64 100644 --- a/tests/functional/forgot_password_test.php +++ b/tests/functional/forgot_password_test.php @@ -27,7 +27,11 @@ class phpbb_functional_forgot_password_test extends phpbb_functional_test_case $this->admin_login(); $this->add_lang('ucp'); $crawler = $this->request('GET', 'adm/index.php?sid=' . $this->sid . '&i=acp_board&mode=security'); - //$this->assert_response_success(); + $this->assertEquals(200, $this->client->getResponse()->getStatus()); + $content = $this->client->getResponse()->getContent(); + $this->assertNotContains('Fatal error:', $content); + $this->assertNotContains('Notice:', $content); + $this->assertNotContains('[phpBB Debug]', $content); $form = $crawler->selectButton('Submit')->form(); $values = $form->getValues(); From d7787682df0474b7bb78434339f8edde3727c580 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 30 Apr 2013 22:19:35 +0200 Subject: [PATCH 245/281] [ticket/11495] Throw exception when item that should be deleted does not exist PHPBB3-11495 --- phpBB/includes/tree/nestedset.php | 11 +++++++++++ .../nestedset_forum_insert_delete_test.php | 19 +++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/phpBB/includes/tree/nestedset.php b/phpBB/includes/tree/nestedset.php index 2f17ebab02..4d851a87a8 100644 --- a/phpBB/includes/tree/nestedset.php +++ b/phpBB/includes/tree/nestedset.php @@ -181,9 +181,20 @@ abstract class phpbb_tree_nestedset implements phpbb_tree_interface */ protected function remove_item_from_nestedset($item_id) { + $item_id = (int) $item_id; + if (!$item_id) + { + throw new OutOfBoundsException($this->message_prefix . 'INVALID_ITEM'); + } + $items = $this->get_subtree_data($item_id); $item_ids = array_keys($items); + if (empty($items) || !isset($items[$item_id])) + { + throw new OutOfBoundsException($this->message_prefix . 'INVALID_ITEM'); + } + $this->remove_subset($item_ids, $items[$item_id]); return $item_ids; diff --git a/tests/tree/nestedset_forum_insert_delete_test.php b/tests/tree/nestedset_forum_insert_delete_test.php index 1f901c7422..d0e9e02c2e 100644 --- a/tests/tree/nestedset_forum_insert_delete_test.php +++ b/tests/tree/nestedset_forum_insert_delete_test.php @@ -52,6 +52,25 @@ class phpbb_tests_tree_nestedset_forum_add_remove_test extends phpbb_tests_tree_ $this->assertEquals($expected, $this->db->sql_fetchrowset($result)); } + public function delete_throws_data() + { + return array( + array('Not an item', 0), + array('Item does not exist', 200), + ); + } + + /** + * @dataProvider delete_throws_data + * + * @expectedException OutOfBoundsException + * @expectedExceptionMessage FORUM_NESTEDSET_INVALID_ITEM + */ + public function test_delete_throws($explain, $forum_id) + { + $this->set->delete($forum_id); + } + public function insert_data() { return array( From 356bc00a293300a777304a3c2d442868d4491344 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Tue, 30 Apr 2013 23:21:50 -0500 Subject: [PATCH 246/281] [ticket/11435] Mark extension spacing test as incomplete This test fails until 11435 is fixed Add newlines at EOF PHPBB3-11435 --- .../ext/trivial/styles/all/template/variable_spacing.html | 2 +- .../ext_trivial/styles/silver/template/variable_spacing.html | 2 +- tests/template/template_spacing_test.php | 4 ++++ tests/template/templates/variable_spacing.html | 2 +- 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/tests/template/datasets/ext_trivial/ext/trivial/styles/all/template/variable_spacing.html b/tests/template/datasets/ext_trivial/ext/trivial/styles/all/template/variable_spacing.html index 2909e1c136..028f8aa0d1 100644 --- a/tests/template/datasets/ext_trivial/ext/trivial/styles/all/template/variable_spacing.html +++ b/tests/template/datasets/ext_trivial/ext/trivial/styles/all/template/variable_spacing.html @@ -3,4 +3,4 @@ |{VARIABLE} -
      test
      \ No newline at end of file +
      test
      diff --git a/tests/template/datasets/ext_trivial/styles/silver/template/variable_spacing.html b/tests/template/datasets/ext_trivial/styles/silver/template/variable_spacing.html index c11ae9cb40..ad05e6f661 100644 --- a/tests/template/datasets/ext_trivial/styles/silver/template/variable_spacing.html +++ b/tests/template/datasets/ext_trivial/styles/silver/template/variable_spacing.html @@ -1 +1 @@ - \ No newline at end of file + diff --git a/tests/template/template_spacing_test.php b/tests/template/template_spacing_test.php index 83f8711b38..fb4161066a 100644 --- a/tests/template/template_spacing_test.php +++ b/tests/template/template_spacing_test.php @@ -59,6 +59,10 @@ class phpbb_template_template_spacing_test extends phpbb_template_template_test_ */ public function test_event($desc, $dataset, $style_names, $file, array $vars, array $block_vars, array $destroy, $expected) { + $this->markTestIncomplete( + 'This test will fail until PHPBB3-11435 is fixed' + ); + // Reset the engine state $this->setup_engine_for_events($dataset, $style_names); diff --git a/tests/template/templates/variable_spacing.html b/tests/template/templates/variable_spacing.html index 2909e1c136..028f8aa0d1 100644 --- a/tests/template/templates/variable_spacing.html +++ b/tests/template/templates/variable_spacing.html @@ -3,4 +3,4 @@ |{VARIABLE} -
      test
      \ No newline at end of file +
      test
      From 32f247ed603a2b57ba0b30f4ce0d2429df33ab7e Mon Sep 17 00:00:00 2001 From: Oleg Pudeyev Date: Wed, 1 May 2013 17:14:36 -0400 Subject: [PATCH 247/281] [ticket/11435] Fit comment into 80 columns and link to php manual. PHPBB3-11435 --- phpBB/includes/template/filter.php | 38 +++++++++++++++++------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/phpBB/includes/template/filter.php b/phpBB/includes/template/filter.php index 9e8ad2fef0..c2c100e93e 100644 --- a/phpBB/includes/template/filter.php +++ b/phpBB/includes/template/filter.php @@ -224,28 +224,34 @@ class phpbb_template_filter extends php_user_filter } /* - Preserve whitespace. - PHP removes a newline after the closing tag (if it's there). This is by design. + + Preserve whitespace. + PHP removes a newline after the closing tag (if it's there). + This is by design: + + http://www.php.net/manual/en/language.basic-syntax.phpmode.php + http://www.php.net/manual/en/language.basic-syntax.instruction-separation.php - Consider the following template: + Consider the following template: - - some content - + + some content + - If we were to simply preserve all whitespace, we could simply replace all "?>" tags - with "?>\n". - Doing that, would add additional newlines to the compiled tempalte in place of the - IF and ENDIF statements. These newlines are unwanted (and one is conditional). - The IF and ENDIF are usually on their own line for ease of reading. + If we were to simply preserve all whitespace, we could simply + replace all "?>" tags with "?>\n". + Doing that, would add additional newlines to the compiled + template in place of the IF and ENDIF statements. These + newlines are unwanted (and one is conditional). The IF and + ENDIF are usually on their own line for ease of reading. - This replacement preserves newlines only for statements that aren't the only statement on a line. - It will NOT preserve newlines at the end of statements in the above examle. - It will preserve newlines in situations like: - - inline content + This replacement preserves newlines only for statements that + are not the only statement on a line. It will NOT preserve + newlines at the end of statements in the above example. + It will preserve newlines in situations like: + inline content */ From 6d4a75b3cb9a403d37fe3ac7b3eda5e9c65ad9e0 Mon Sep 17 00:00:00 2001 From: hjpotter92 Date: Thu, 2 May 2013 06:29:32 +0530 Subject: [PATCH 248/281] [ticket/11517] Fix list numbering PHPBB3-11517 --- phpBB/docs/coding-guidelines.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/docs/coding-guidelines.html b/phpBB/docs/coding-guidelines.html index cd113a7226..54b8526cdf 100644 --- a/phpBB/docs/coding-guidelines.html +++ b/phpBB/docs/coding-guidelines.html @@ -2314,7 +2314,7 @@ if (utf8_case_fold_nfc($string1) == utf8_case_fold_nfc($string2))
      -

      8. Copyright and disclaimer

      +

      7. Copyright and disclaimer

      From 00d5cde04eb56b53179385c3ada075b1c207c3a3 Mon Sep 17 00:00:00 2001 From: Dhruv Date: Sat, 4 May 2013 14:44:33 +0530 Subject: [PATCH 249/281] [ticket/10325] fix acp language PHPBB3-10325 --- phpBB/language/en/acp/board.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/language/en/acp/board.php b/phpBB/language/en/acp/board.php index 1bc8d1cf46..ce15dfefb4 100644 --- a/phpBB/language/en/acp/board.php +++ b/phpBB/language/en/acp/board.php @@ -454,7 +454,7 @@ $lang = array_merge($lang, array( 'ALL' => 'All', 'ALLOW_AUTOLOGIN' => 'Allow "Remember Me" logins', 'ALLOW_AUTOLOGIN_EXPLAIN' => 'Determines whether users are given "Remember Me" option when they visit the board.', - 'ALLOW_PASSWORD_RESET' => 'Allow "Forgot Password"', + 'ALLOW_PASSWORD_RESET' => 'Allow password reset ("Forgot Password")', 'ALLOW_PASSWORD_RESET_EXPLAIN' => 'Determines whether or not users are able to use the "I forgot my password" link on the login page to recover their account. If you use an external authentication mechanism you may wish to disable this feature.', 'AUTOLOGIN_LENGTH' => '"Remember Me" login key expiration length (in days)', 'AUTOLOGIN_LENGTH_EXPLAIN' => 'Number of days after which "Remember Me" login keys are removed or zero to disable.', From 3a30bd2753ab56dd5035ebba8cf42850e41c3728 Mon Sep 17 00:00:00 2001 From: Dhruv Date: Sat, 4 May 2013 18:25:43 +0530 Subject: [PATCH 250/281] [ticket/11288] add search tests cases PHPBB3-11288 --- tests/search/common_test_case.php | 98 +++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) diff --git a/tests/search/common_test_case.php b/tests/search/common_test_case.php index dd04f7048c..029637b00b 100644 --- a/tests/search/common_test_case.php +++ b/tests/search/common_test_case.php @@ -86,6 +86,104 @@ abstract class phpbb_search_common_test_case extends phpbb_search_test_case array('-fooo', '-baar'), array(), ), + array( + 'fooo -fooo', + 'all', + true, + array('fooo', '-fooo'), + array(), + ), + array( + 'fooo fooo-', + 'all', + true, + array('fooo', 'fooo'), + array(), + ), + array( + '-fooo fooo', + 'all', + true, + array('-fooo', 'fooo'), + array(), + ), + array( + 'fooo- fooo', + 'all', + true, + array('fooo', 'fooo'), + array(), + ), + array( + 'fooo-baar fooo', + 'all', + true, + array('fooo', 'baar', 'fooo'), + array(), + ), + array( + 'fooo-baar -fooo', + 'all', + true, + array('fooo', 'baar', '-fooo'), + array(), + ), + array( + 'fooo-baar fooo-', + 'all', + true, + array('fooo', 'baar', 'fooo'), + array(), + ), + array( + 'fooo-baar baar', + 'all', + true, + array('fooo', 'baar', 'baar'), + array(), + ), + array( + 'fooo-baar -baar', + 'all', + true, + array('fooo', 'baar', '-baar'), + array(), + ), + array( + 'fooo-baar baar-', + 'all', + true, + array('fooo', 'baar', 'baar'), + array(), + ), + array( + 'fooo-baar fooo-baar', + 'all', + true, + array('fooo', 'baar', 'fooo', 'baar'), + array(), + ), + array( + 'fooo-baar -fooo-baar', + 'all', + true, + array('fooo', 'baar', '-fooo', 'baar'), + array(), + ), + array( + 'fooo-baar fooo-baar-', + 'all', + true, + array('fooo', 'baar', 'fooo', 'baar'), + array(), + ), + array( + 'fooo-baar-baaz', + 'all', + true, + array('fooo', 'baar', 'baaz'), + array(), + ), ); } From bfdc6e19300da8fa62d8661fcbd92548a2d2cf97 Mon Sep 17 00:00:00 2001 From: Dhruv Date: Sat, 4 May 2013 18:56:52 +0530 Subject: [PATCH 251/281] [ticket/11288] fix regex in postgres Postgres search backend now uses updated regex being used by mysql search backend. PHPBB3-11288 --- phpBB/includes/search/fulltext_postgres.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/includes/search/fulltext_postgres.php b/phpBB/includes/search/fulltext_postgres.php index eeb628b18f..5080587681 100644 --- a/phpBB/includes/search/fulltext_postgres.php +++ b/phpBB/includes/search/fulltext_postgres.php @@ -214,7 +214,7 @@ class phpbb_search_fulltext_postgres extends phpbb_search_base { if ($terms == 'all') { - $match = array('#\sand\s#iu', '#\sor\s#iu', '#\snot\s#iu', '#\+#', '#-#', '#\|#'); + $match = array('#\sand\s#iu', '#\sor\s#iu', '#\snot\s#iu', '#(^|\s)\+#', '#(^|\s)-#', '#(^|\s)\|#'); $replace = array(' +', ' |', ' -', ' +', ' -', ' |'); $keywords = preg_replace($match, $replace, $keywords); From 9608d9bf1e4ed23c36496612a6ffb63072c32371 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Sat, 4 May 2013 11:45:49 -0500 Subject: [PATCH 252/281] [ticket/11519] Rename test event template file As requested by Oleg https://github.com/phpbb/phpbb3/pull/1340#issuecomment-17306967 PHPBB3-11519 --- .../{variable_spacing.html => event_variable_spacing.html} | 0 .../ext_trivial/styles/silver/template/variable_spacing.html | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename tests/template/datasets/ext_trivial/ext/trivial/styles/all/template/{variable_spacing.html => event_variable_spacing.html} (100%) diff --git a/tests/template/datasets/ext_trivial/ext/trivial/styles/all/template/variable_spacing.html b/tests/template/datasets/ext_trivial/ext/trivial/styles/all/template/event_variable_spacing.html similarity index 100% rename from tests/template/datasets/ext_trivial/ext/trivial/styles/all/template/variable_spacing.html rename to tests/template/datasets/ext_trivial/ext/trivial/styles/all/template/event_variable_spacing.html diff --git a/tests/template/datasets/ext_trivial/styles/silver/template/variable_spacing.html b/tests/template/datasets/ext_trivial/styles/silver/template/variable_spacing.html index ad05e6f661..49d8a6b873 100644 --- a/tests/template/datasets/ext_trivial/styles/silver/template/variable_spacing.html +++ b/tests/template/datasets/ext_trivial/styles/silver/template/variable_spacing.html @@ -1 +1 @@ - + From 153be855ca8fdee9549be9f51f940a385a0b4e03 Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Mon, 6 May 2013 09:49:37 -0700 Subject: [PATCH 253/281] [ticket/10155] Update copyright in new migration file to 2013 PHPBB3-10155 --- phpBB/includes/db/migration/data/310/jquery_update.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/includes/db/migration/data/310/jquery_update.php b/phpBB/includes/db/migration/data/310/jquery_update.php index bb0c48550a..dc49f74fcb 100644 --- a/phpBB/includes/db/migration/data/310/jquery_update.php +++ b/phpBB/includes/db/migration/data/310/jquery_update.php @@ -2,7 +2,7 @@ /** * * @package migration -* @copyright (c) 2012 phpBB Group +* @copyright (c) 2013 phpBB Group * @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 * */ From 828d3b6b68acad606fe150cff7993c216ebc4474 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Muller?= Date: Sun, 21 Apr 2013 14:22:45 +0200 Subject: [PATCH 254/281] [ticket/11144] Add missing {FORUM_NAME} variable The template variable {FORUM_NAME} was missing from the login page of a password protected forum PHPBB3-11144 --- phpBB/docs/coding-guidelines.html | 2 + phpBB/download/file.php | 2 +- phpBB/includes/functions.php | 1 + phpBB/includes/ucp/ucp_pm_compose.php | 11 ++--- phpBB/posting.php | 1 + .../prosilver/template/login_forum.html | 43 +++++++++++-------- .../subsilver2/template/login_forum.html | 8 ++++ 7 files changed, 41 insertions(+), 27 deletions(-) diff --git a/phpBB/docs/coding-guidelines.html b/phpBB/docs/coding-guidelines.html index cd113a7226..38f11534d2 100644 --- a/phpBB/docs/coding-guidelines.html +++ b/phpBB/docs/coding-guidelines.html @@ -956,6 +956,8 @@ $action_ary = request_var('action', array('' => 0));

      Login checks/redirection:

      To show a forum login box use login_forum_box($forum_data), else use the login_box() function.

      +

      $forum_data should contain at least the forum_id and forum_password fields. If the field forum_name is available, then it is displayed on the forum login page.

      +

      The login_box() function can have a redirect as the first parameter. As a thumb of rule, specify an empty string if you want to redirect to the users current location, else do not add the $SID to the redirect string (for example within the ucp/login we redirect to the board index because else the user would be redirected to the login screen).

      Sensitive Operations:

      diff --git a/phpBB/download/file.php b/phpBB/download/file.php index bf277c69fa..3ceb1ee0cc 100644 --- a/phpBB/download/file.php +++ b/phpBB/download/file.php @@ -170,7 +170,7 @@ else if (!$attachment['in_message']) { // - $sql = 'SELECT p.forum_id, f.forum_password, f.parent_id + $sql = 'SELECT p.forum_id, f.forum_name, f.forum_password, f.parent_id FROM ' . POSTS_TABLE . ' p, ' . FORUMS_TABLE . ' f WHERE p.post_id = ' . $attachment['post_msg_id'] . ' AND p.forum_id = f.forum_id'; diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index ccd2d3147c..98a1dab722 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -3272,6 +3272,7 @@ function login_forum_box($forum_data) page_header($user->lang['LOGIN'], false); $template->assign_vars(array( + 'FORUM_NAME' => isset($forum_data['forum_name']) ? $forum_data['forum_name'] : '', 'S_LOGIN_ACTION' => build_url(array('f')), 'S_HIDDEN_FIELDS' => build_hidden_fields(array('f' => $forum_data['forum_id']))) ); diff --git a/phpBB/includes/ucp/ucp_pm_compose.php b/phpBB/includes/ucp/ucp_pm_compose.php index 8e82188aff..d7509a1072 100644 --- a/phpBB/includes/ucp/ucp_pm_compose.php +++ b/phpBB/includes/ucp/ucp_pm_compose.php @@ -271,19 +271,16 @@ function compose_pm($id, $mode, $action, $user_folders = array()) // Passworded forum? if ($post['forum_id']) { - $sql = 'SELECT forum_password + $sql = 'SELECT forum_id, forum_name, forum_password FROM ' . FORUMS_TABLE . ' WHERE forum_id = ' . (int) $post['forum_id']; $result = $db->sql_query($sql); - $forum_password = (string) $db->sql_fetchfield('forum_password'); + $forum_data = $db->sql_fetchrow($result); $db->sql_freeresult($result); - if ($forum_password) + if (!empty($forum_data['forum_password'])) { - login_forum_box(array( - 'forum_id' => $post['forum_id'], - 'forum_password' => $forum_password, - )); + login_forum_box($forum_data); } } } diff --git a/phpBB/posting.php b/phpBB/posting.php index e57f5420f5..b351f67218 100644 --- a/phpBB/posting.php +++ b/phpBB/posting.php @@ -196,6 +196,7 @@ if ($post_data['forum_password']) { login_forum_box(array( 'forum_id' => $forum_id, + 'forum_name' => $post_data['forum_name'], 'forum_password' => $post_data['forum_password']) ); } diff --git a/phpBB/styles/prosilver/template/login_forum.html b/phpBB/styles/prosilver/template/login_forum.html index a342a9aa24..81a83b6340 100644 --- a/phpBB/styles/prosilver/template/login_forum.html +++ b/phpBB/styles/prosilver/template/login_forum.html @@ -1,31 +1,36 @@ -

      {L_LOGIN} {FORUM_NAME}

      +

      {FORUM_NAME}

      {S_FORM_TOKEN}
      -

      {L_LOGIN_FORUM}

      +
      +

      {L_LOGIN}

      -
      - -
      -
       
      -
      {LOGIN_ERROR}
      -
      - -
      -
      -
      -
      -
      -
       
      -
      {S_HIDDEN_FIELDS}
      -
      - {S_LOGIN_REDIRECT} -
      +

      {L_LOGIN_FORUM}

      + +
      + +
      +
       
      +
      {LOGIN_ERROR}
      +
      + + +
      +
      +
      +
      + {S_LOGIN_REDIRECT} +
      +
       
      +
      {S_HIDDEN_FIELDS}
      +
      +
      +
      diff --git a/phpBB/styles/subsilver2/template/login_forum.html b/phpBB/styles/subsilver2/template/login_forum.html index 96b025a2f9..e91a406611 100644 --- a/phpBB/styles/subsilver2/template/login_forum.html +++ b/phpBB/styles/subsilver2/template/login_forum.html @@ -1,5 +1,13 @@ + + + +

      + +
      From eefcdfa54a80e4f62c88b6758b2e1d22740d1ddd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Muller?= Date: Mon, 6 May 2013 21:50:45 +0200 Subject: [PATCH 255/281] [ticket/11144] Add missing {FORUM_NAME} variable Replace spaces with tabs PHPBB3-11144 --- phpBB/posting.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/posting.php b/phpBB/posting.php index b351f67218..42c4f7bc55 100644 --- a/phpBB/posting.php +++ b/phpBB/posting.php @@ -196,7 +196,7 @@ if ($post_data['forum_password']) { login_forum_box(array( 'forum_id' => $forum_id, - 'forum_name' => $post_data['forum_name'], + 'forum_name' => $post_data['forum_name'], 'forum_password' => $post_data['forum_password']) ); } From 665352d0d191cdf31a07ad50d00ffaf47da77a97 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 7 May 2013 23:49:24 +0200 Subject: [PATCH 256/281] [ticket/11442] Do not suggest an option on ajax confirm box Reverting commit cb13add269b78e1a9ac84a80c78557bb7695df09 Also fixing in prosilver and subsilver2 PHPBB3-11442 --- phpBB/adm/style/confirm_body.html | 2 +- phpBB/styles/prosilver/template/confirm_body.html | 2 +- phpBB/styles/subsilver2/template/confirm_body.html | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/phpBB/adm/style/confirm_body.html b/phpBB/adm/style/confirm_body.html index fa3f1e6c64..d0360d1b3a 100644 --- a/phpBB/adm/style/confirm_body.html +++ b/phpBB/adm/style/confirm_body.html @@ -4,7 +4,7 @@

      {MESSAGE_TEXT}

      -   +  
      diff --git a/phpBB/styles/prosilver/template/confirm_body.html b/phpBB/styles/prosilver/template/confirm_body.html index eb0cad2597..bf575c20fa 100644 --- a/phpBB/styles/prosilver/template/confirm_body.html +++ b/phpBB/styles/prosilver/template/confirm_body.html @@ -4,7 +4,7 @@

      {MESSAGE_TEXT}

      -   +  
      diff --git a/phpBB/styles/subsilver2/template/confirm_body.html b/phpBB/styles/subsilver2/template/confirm_body.html index 7516196b3c..1712017c38 100644 --- a/phpBB/styles/subsilver2/template/confirm_body.html +++ b/phpBB/styles/subsilver2/template/confirm_body.html @@ -9,7 +9,7 @@ {MESSAGE_TITLE} -

      {MESSAGE_TEXT}


      {S_HIDDEN_FIELDS}   +

      {MESSAGE_TEXT}


      {S_HIDDEN_FIELDS}   From 1834ceb614a1bf82aa0369a2b731475a82abfade Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Wed, 8 May 2013 00:08:35 +0200 Subject: [PATCH 257/281] [ticket/11442] Use button name as indicator instead of css classes This leaves it up to the style authors how to style any buttons, without messing up any functionality. PHPBB3-11442 --- phpBB/assets/javascript/core.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/phpBB/assets/javascript/core.js b/phpBB/assets/javascript/core.js index 8bbea8b8c9..642d513cb6 100644 --- a/phpBB/assets/javascript/core.js +++ b/phpBB/assets/javascript/core.js @@ -136,7 +136,7 @@ phpbb.confirm = function(msg, callback, fadedark) { }); var clickHandler = function(e) { - var res = this.className === 'button1'; + var res = this.name === 'confirm'; var fade = (typeof fadedark !== 'undefined' && !fadedark && res) ? div : dark; fade.fadeOut(phpbb.alertTime, function() { div.hide(); @@ -164,11 +164,11 @@ phpbb.confirm = function(msg, callback, fadedark) { $(document).bind('keydown', function(e) { if (e.keyCode === keymap.ENTER) { - $('input[type="button"].button1').trigger('click'); + $('input[name="confirm"]').trigger('click'); e.preventDefault(); e.stopPropagation(); } else if (e.keyCode === keymap.ESC) { - $('input[type="button"].button2').trigger('click'); + $('input[name="cancel"]').trigger('click'); e.preventDefault(); e.stopPropagation(); } From b63a148e088572fd2b410705442aa575b8fe538f Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Mon, 18 Mar 2013 17:09:12 +0100 Subject: [PATCH 258/281] [ticket/11450] Remove unused $db and $phpEx from metadata_manager construct() PHPBB3-11450 --- phpBB/includes/extension/metadata_manager.php | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/phpBB/includes/extension/metadata_manager.php b/phpBB/includes/extension/metadata_manager.php index 1637abd340..5f16a5bcd5 100644 --- a/phpBB/includes/extension/metadata_manager.php +++ b/phpBB/includes/extension/metadata_manager.php @@ -22,9 +22,7 @@ if (!defined('IN_PHPBB')) */ class phpbb_extension_metadata_manager { - protected $phpEx; protected $extension_manager; - protected $db; protected $phpbb_root_path; protected $template; protected $ext_name; @@ -34,17 +32,13 @@ class phpbb_extension_metadata_manager /** * Creates the metadata manager * - * @param phpbb_db_driver $db A database connection * @param string $extension_manager An instance of the phpbb extension manager * @param string $phpbb_root_path Path to the phpbb includes directory. - * @param string $phpEx php file extension */ - public function __construct($ext_name, phpbb_db_driver $db, phpbb_extension_manager $extension_manager, $phpbb_root_path, $phpEx = 'php', phpbb_template $template, phpbb_config $config) + public function __construct($ext_name, phpbb_extension_manager $extension_manager, $phpbb_root_path, phpbb_template $template, phpbb_config $config) { $this->phpbb_root_path = $phpbb_root_path; - $this->db = $db; $this->config = $config; - $this->phpEx = $phpEx; $this->template = $template; $this->extension_manager = $extension_manager; $this->ext_name = $ext_name; From 5794b3d621b9d48b9bf7dcdcc7cc15585bddd021 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Mon, 18 Mar 2013 23:02:24 +0100 Subject: [PATCH 259/281] [ticket/11450] Sort parameters alphabetically PHPBB3-11450 --- phpBB/includes/extension/metadata_manager.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/phpBB/includes/extension/metadata_manager.php b/phpBB/includes/extension/metadata_manager.php index 5f16a5bcd5..030e1bdb9d 100644 --- a/phpBB/includes/extension/metadata_manager.php +++ b/phpBB/includes/extension/metadata_manager.php @@ -35,12 +35,13 @@ class phpbb_extension_metadata_manager * @param string $extension_manager An instance of the phpbb extension manager * @param string $phpbb_root_path Path to the phpbb includes directory. */ - public function __construct($ext_name, phpbb_extension_manager $extension_manager, $phpbb_root_path, phpbb_template $template, phpbb_config $config) + public function __construct($ext_name, phpbb_config $config, phpbb_extension_manager $extension_manager, phpbb_template $template, $phpbb_root_path) { - $this->phpbb_root_path = $phpbb_root_path; $this->config = $config; - $this->template = $template; $this->extension_manager = $extension_manager; + $this->template = $template; + $this->phpbb_root_path = $phpbb_root_path; + $this->ext_name = $ext_name; $this->metadata = array(); $this->metadata_file = ''; From 001e3ebe9e9534ba0f05dd3a391a2a163a77347a Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Mon, 18 Mar 2013 23:09:37 +0100 Subject: [PATCH 260/281] [ticket/11450] Fix doc blocks and add missing class var $config PHPBB3-11450 --- phpBB/includes/extension/metadata_manager.php | 44 +++++++++++++++++-- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/phpBB/includes/extension/metadata_manager.php b/phpBB/includes/extension/metadata_manager.php index 030e1bdb9d..14b77c085b 100644 --- a/phpBB/includes/extension/metadata_manager.php +++ b/phpBB/includes/extension/metadata_manager.php @@ -22,18 +22,56 @@ if (!defined('IN_PHPBB')) */ class phpbb_extension_metadata_manager { + /** + * phpBB Config instance + * @var phpbb_config + */ + protected $config; + + /** + * phpBB Extension Manager + * @var phpbb_extension_manager + */ protected $extension_manager; - protected $phpbb_root_path; + + /** + * phpBB Template instance + * @var phpbb_template + */ protected $template; + + /** + * phpBB root path + * @var string + */ + protected $phpbb_root_path; + + /** + * Name (including vendor) of the extension + * @var string + */ protected $ext_name; + + /** + * Metadata from the composer.json file + * @var array + */ protected $metadata; + + /** + * Link (including root path) to the metadata file + * @var string + */ protected $metadata_file; /** * Creates the metadata manager * - * @param string $extension_manager An instance of the phpbb extension manager - * @param string $phpbb_root_path Path to the phpbb includes directory. + * @param string $ext_name Name (including vendor) of the extension + * @param phpbb_config $config phpBB Config instance + * @param phpbb_extension_manager $extension_manager An instance of the phpBBb extension manager + * @param phpbb_template $template phpBB Template instance + * @param string $phpbb_root_path Path to the phpbb includes directory. */ public function __construct($ext_name, phpbb_config $config, phpbb_extension_manager $extension_manager, phpbb_template $template, $phpbb_root_path) { From 62f35121d948bd177004628a4be2b4e8810a50bd Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Mon, 18 Mar 2013 23:15:27 +0100 Subject: [PATCH 261/281] [ticket/11450] Fix all instances of phpbb_extension_metadata_manager PHPBB3-11450 --- phpBB/includes/acp/acp_extensions.php | 2 +- phpBB/includes/extension/manager.php | 2 +- tests/extension/metadata_manager_test.php | 6 ++---- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/phpBB/includes/acp/acp_extensions.php b/phpBB/includes/acp/acp_extensions.php index e4defa0400..c52e4e0473 100644 --- a/phpBB/includes/acp/acp_extensions.php +++ b/phpBB/includes/acp/acp_extensions.php @@ -54,7 +54,7 @@ class acp_extensions // If they've specified an extension, let's load the metadata manager and validate it. if ($ext_name) { - $md_manager = new phpbb_extension_metadata_manager($ext_name, $db, $phpbb_extension_manager, $phpbb_root_path, $phpEx, $template, $config); + $md_manager = new phpbb_extension_metadata_manager($ext_name, $config, $phpbb_extension_manager, $template, $phpbb_root_path); try { diff --git a/phpBB/includes/extension/manager.php b/phpBB/includes/extension/manager.php index a1022762b8..653117adfa 100644 --- a/phpBB/includes/extension/manager.php +++ b/phpBB/includes/extension/manager.php @@ -155,7 +155,7 @@ class phpbb_extension_manager */ public function create_extension_metadata_manager($name, phpbb_template $template) { - return new phpbb_extension_metadata_manager($name, $this->db, $this, $this->phpbb_root_path, $this->php_ext, $template, $this->config); + return new phpbb_extension_metadata_manager($name, $this->config, $this, $template, $this->phpbb_root_path); } /** diff --git a/tests/extension/metadata_manager_test.php b/tests/extension/metadata_manager_test.php index 05d1cbccc3..8873d25c9c 100644 --- a/tests/extension/metadata_manager_test.php +++ b/tests/extension/metadata_manager_test.php @@ -422,12 +422,10 @@ class metadata_manager_test extends phpbb_database_test_case { return new phpbb_extension_metadata_manager_test( $ext_name, - $this->db, + $this->config, $this->extension_manager, - $this->phpbb_root_path, - $this->phpEx, $this->template, - $this->config + $this->phpbb_root_path ); } } From 269c2ce98de5b55a713e998aacdaa5500d32b617 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 21 Mar 2013 15:19:26 +0100 Subject: [PATCH 262/281] [ticket/11450] Test the extensions details page in ACP Customise Tab PHPBB3-11450 --- .../fixtures/ext/foo/bar/composer.json | 23 ++++ tests/functional/metadata_manager_test.php | 104 ++++++++++++++++++ 2 files changed, 127 insertions(+) create mode 100644 tests/functional/fixtures/ext/foo/bar/composer.json create mode 100644 tests/functional/metadata_manager_test.php diff --git a/tests/functional/fixtures/ext/foo/bar/composer.json b/tests/functional/fixtures/ext/foo/bar/composer.json new file mode 100644 index 0000000000..50a8a7358a --- /dev/null +++ b/tests/functional/fixtures/ext/foo/bar/composer.json @@ -0,0 +1,23 @@ +{ + "name": "foo/bar", + "type": "phpbb3-extension", + "description": "Testing extensions", + "homepage": "", + "version": "1.0.0", + "time": "2013-03-21 01:01:01", + "licence": "GPL-2.0", + "authors": [{ + "name": "Joas Schilling", + "username": "nickvergessen", + "email": "nickvergessen@phpbb.com", + "homepage": "http://www.phpbb.com", + "role": "Developer" + }], + "require": { + "php": ">=5.3", + "phpbb": ">=3.1.0-dev" + }, + "extra": { + "display-name": "phpBB 3.1 Extension Testing" + } +} \ No newline at end of file diff --git a/tests/functional/metadata_manager_test.php b/tests/functional/metadata_manager_test.php new file mode 100644 index 0000000000..0f5b49f01e --- /dev/null +++ b/tests/functional/metadata_manager_test.php @@ -0,0 +1,104 @@ +phpbb_extension_manager = $this->get_extension_manager(); + + $this->purge_cache(); + $this->phpbb_extension_manager->enable('foo/bar'); + + $this->login(); + $this->admin_login(); + $this->add_lang('acp/extensions'); + } + + public function test_extensions_list() + { + $crawler = $this->request('GET', 'adm/index.php?i=acp_extensions&mode=main&sid=' . $this->sid); + $this->assert_response_success(); + + $this->assertContains($this->lang('EXTENSIONS_EXPLAIN'), $this->client->getResponse()->getContent()); + $this->assertContains('phpBB 3.1 Extension Testing', $this->client->getResponse()->getContent()); + $this->assertContains('Details', $this->client->getResponse()->getContent()); + } + + public function test_permissions_tab() + { + $crawler = $this->request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=details&ext_name=foo%2Fbar&sid=' . $this->sid); + $this->assert_response_success(); + + // Test whether the details are displayed + $this->assertContains($this->lang('CLEAN_NAME'), $this->client->getResponse()->getContent()); + $this->assertContains('foo/bar', $this->client->getResponse()->getContent()); + + // Details should be html escaped + $this->assertContains($this->lang('PHP_VERSION'), $this->client->getResponse()->getContent()); + $this->assertContains('>=5.3', $this->client->getResponse()->getContent()); + } +} From 0de153d9034720745eb3589b95953de9a185360d Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 21 Mar 2013 15:27:15 +0100 Subject: [PATCH 263/281] [ticket/11450] Add test for unexisting composer.json PHPBB3-11450 --- tests/functional/metadata_manager_test.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/tests/functional/metadata_manager_test.php b/tests/functional/metadata_manager_test.php index 0f5b49f01e..deb8af7707 100644 --- a/tests/functional/metadata_manager_test.php +++ b/tests/functional/metadata_manager_test.php @@ -88,7 +88,7 @@ class phpbb_functional_metadata_manager_test extends phpbb_functional_test_case $this->assertContains('Details', $this->client->getResponse()->getContent()); } - public function test_permissions_tab() + public function test_extensions_details() { $crawler = $this->request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=details&ext_name=foo%2Fbar&sid=' . $this->sid); $this->assert_response_success(); @@ -101,4 +101,13 @@ class phpbb_functional_metadata_manager_test extends phpbb_functional_test_case $this->assertContains($this->lang('PHP_VERSION'), $this->client->getResponse()->getContent()); $this->assertContains('>=5.3', $this->client->getResponse()->getContent()); } + + public function test_extensions_details_notexists() + { + $crawler = $this->request('GET', 'adm/index.php?i=acp_extensions&mode=main&action=details&ext_name=not%2Fexists&sid=' . $this->sid); + $this->assert_response_success(); + + // Error message because the files do not exist + $this->assertContains('The required file does not exist:', $this->client->getResponse()->getContent()); + } } From a44a35926f9535c8d0d6afaeef6eeaf64a7f470e Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Mon, 1 Apr 2013 11:17:05 +0200 Subject: [PATCH 264/281] [ticket/11450] Require db_tools file to be included PHPBB3-11450 --- tests/extension/metadata_manager_test.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/extension/metadata_manager_test.php b/tests/extension/metadata_manager_test.php index 8873d25c9c..24b2861079 100644 --- a/tests/extension/metadata_manager_test.php +++ b/tests/extension/metadata_manager_test.php @@ -7,6 +7,8 @@ * */ +require_once dirname(__FILE__) . '/../../phpBB/includes/db/db_tools.php'; + class metadata_manager_test extends phpbb_database_test_case { protected $class_loader; From 74f3161b4b555f5ef5482c95a919aae468312142 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Mon, 1 Apr 2013 11:18:46 +0200 Subject: [PATCH 265/281] [ticket/11450] Fix tests class name PHPBB3-11450 --- tests/extension/metadata_manager_test.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/extension/metadata_manager_test.php b/tests/extension/metadata_manager_test.php index 24b2861079..7b51f2d50f 100644 --- a/tests/extension/metadata_manager_test.php +++ b/tests/extension/metadata_manager_test.php @@ -9,7 +9,7 @@ require_once dirname(__FILE__) . '/../../phpBB/includes/db/db_tools.php'; -class metadata_manager_test extends phpbb_database_test_case +class phpbb_extension_metadata_manager_test extends phpbb_database_test_case { protected $class_loader; protected $extension_manager; From d75af4109ff4a2323e1561f3376b4ef0515977cc Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Mon, 1 Apr 2013 11:20:34 +0200 Subject: [PATCH 266/281] [ticket/11450] Add new line at end of file PHPBB3-11450 --- tests/functional/fixtures/ext/foo/bar/composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/functional/fixtures/ext/foo/bar/composer.json b/tests/functional/fixtures/ext/foo/bar/composer.json index 50a8a7358a..067a9d38eb 100644 --- a/tests/functional/fixtures/ext/foo/bar/composer.json +++ b/tests/functional/fixtures/ext/foo/bar/composer.json @@ -20,4 +20,4 @@ "extra": { "display-name": "phpBB 3.1 Extension Testing" } -} \ No newline at end of file +} From 65c407044e77568ddcd80648830b8caf8fb3dd4a Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 4 Apr 2013 21:36:32 +0200 Subject: [PATCH 267/281] [ticket/11450] Move mocked class into mock/metadata_manager.php PHPBB3-11450 --- tests/extension/metadata_manager_test.php | 17 ++--------------- tests/mock/metadata_manager.php | 21 +++++++++++++++++++++ 2 files changed, 23 insertions(+), 15 deletions(-) create mode 100644 tests/mock/metadata_manager.php diff --git a/tests/extension/metadata_manager_test.php b/tests/extension/metadata_manager_test.php index 7b51f2d50f..2f38a26217 100644 --- a/tests/extension/metadata_manager_test.php +++ b/tests/extension/metadata_manager_test.php @@ -418,11 +418,11 @@ class phpbb_extension_metadata_manager_test extends phpbb_database_test_case * Get an instance of the metadata manager * * @param string $ext_name - * @return phpbb_extension_metadata_manager_test + * @return phpbb_mock_metadata_manager */ private function get_metadata_manager($ext_name) { - return new phpbb_extension_metadata_manager_test( + return new phpbb_mock_metadata_manager( $ext_name, $this->config, $this->extension_manager, @@ -431,16 +431,3 @@ class phpbb_extension_metadata_manager_test extends phpbb_database_test_case ); } } - -class phpbb_extension_metadata_manager_test extends phpbb_extension_metadata_manager -{ - public function set_metadata($metadata) - { - $this->metadata = $metadata; - } - - public function merge_metadata($metadata) - { - $this->metadata = array_merge($this->metadata, $metadata); - } -} \ No newline at end of file diff --git a/tests/mock/metadata_manager.php b/tests/mock/metadata_manager.php new file mode 100644 index 0000000000..a7fbf0681c --- /dev/null +++ b/tests/mock/metadata_manager.php @@ -0,0 +1,21 @@ +metadata = $metadata; + } + + public function merge_metadata($metadata) + { + $this->metadata = array_merge($this->metadata, $metadata); + } +} From 4c9c1d8c02142315d88bb7aaee2f64015c5033b7 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 12 Apr 2013 16:29:59 +0200 Subject: [PATCH 268/281] [ticket/11450] Use helpers to copy/remove files PHPBB3-11450 --- tests/functional/metadata_manager_test.php | 44 +++++++++++----------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/tests/functional/metadata_manager_test.php b/tests/functional/metadata_manager_test.php index deb8af7707..c639cad809 100644 --- a/tests/functional/metadata_manager_test.php +++ b/tests/functional/metadata_manager_test.php @@ -7,6 +7,8 @@ * */ +require_once dirname(__FILE__) . '/../../phpBB/includes/db/db_tools.php'; + /** * @group functional */ @@ -14,8 +16,10 @@ class phpbb_functional_metadata_manager_test extends phpbb_functional_test_case { protected $phpbb_extension_manager; + static private $helpers; + static protected $fixtures = array( - 'foo/bar/composer.json', + 'foo/bar/', ); /** @@ -27,23 +31,16 @@ class phpbb_functional_metadata_manager_test extends phpbb_functional_test_case global $phpbb_root_path; parent::setUpBeforeClass(); - $directories = array( - $phpbb_root_path . 'ext/foo/bar/', - ); + self::$helpers = new phpbb_test_case_helpers(self); - foreach ($directories as $dir) + if (!file_exists($phpbb_root_path . 'ext/foo/bar/')) { - if (!is_dir($dir)) - { - mkdir($dir, 0777, true); - } + self::$helpers->makedirs($phpbb_root_path . 'ext/foo/bar/'); } foreach (self::$fixtures as $fixture) { - copy( - "tests/functional/fixtures/ext/$fixture", - "{$phpbb_root_path}ext/$fixture"); + self::$helpers->copy_dir(dirname(__FILE__) . '/fixtures/ext/' . $fixture, $phpbb_root_path . 'ext/' . $fixture); } } @@ -57,11 +54,9 @@ class phpbb_functional_metadata_manager_test extends phpbb_functional_test_case foreach (self::$fixtures as $fixture) { - unlink("{$phpbb_root_path}ext/$fixture"); + self::$helpers->empty_dir($phpbb_root_path . 'ext/' . $fixture); } - - rmdir("{$phpbb_root_path}ext/foo/bar"); - rmdir("{$phpbb_root_path}ext/foo"); + self::$helpers->empty_dir($phpbb_root_path . 'ext/foo/'); } public function setUp() @@ -83,9 +78,9 @@ class phpbb_functional_metadata_manager_test extends phpbb_functional_test_case $crawler = $this->request('GET', 'adm/index.php?i=acp_extensions&mode=main&sid=' . $this->sid); $this->assert_response_success(); - $this->assertContains($this->lang('EXTENSIONS_EXPLAIN'), $this->client->getResponse()->getContent()); - $this->assertContains('phpBB 3.1 Extension Testing', $this->client->getResponse()->getContent()); - $this->assertContains('Details', $this->client->getResponse()->getContent()); + $this->assertContains($this->lang('EXTENSIONS_EXPLAIN'), $crawler->filter('#page-body')->text()); + $this->assertContains('phpBB 3.1 Extension Testing', $crawler->filter('#page-body')->text()); + $this->assertContains('Details', $crawler->filter('#page-body')->text()); } public function test_extensions_details() @@ -94,11 +89,14 @@ class phpbb_functional_metadata_manager_test extends phpbb_functional_test_case $this->assert_response_success(); // Test whether the details are displayed - $this->assertContains($this->lang('CLEAN_NAME'), $this->client->getResponse()->getContent()); - $this->assertContains('foo/bar', $this->client->getResponse()->getContent()); + $this->assertContains($this->lang('CLEAN_NAME'), $crawler->filter('#page-body')->text()); + $this->assertContains('foo/bar', $crawler->filter('#page-body')->text()); // Details should be html escaped - $this->assertContains($this->lang('PHP_VERSION'), $this->client->getResponse()->getContent()); + $this->assertContains($this->lang('PHP_VERSION'), $crawler->filter('#page-body')->text()); + // The Crawler parses the text, so we can not see whether it was escaped anymore + // To test this, we grab the content of the response directly + // $this->assertContains('>=5.3', $$crawler->filter('#page-body')->text()); $this->assertContains('>=5.3', $this->client->getResponse()->getContent()); } @@ -108,6 +106,6 @@ class phpbb_functional_metadata_manager_test extends phpbb_functional_test_case $this->assert_response_success(); // Error message because the files do not exist - $this->assertContains('The required file does not exist:', $this->client->getResponse()->getContent()); + $this->assertContains('The required file does not exist:', $crawler->filter('#page-body')->text()); } } From 54680b9709ab2288408cbb0ddc7737e93d41de18 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 3 May 2013 15:52:16 +0200 Subject: [PATCH 269/281] [ticket/11450] Limit scopes of filters and add better docs PHPBB3-11450 --- tests/functional/metadata_manager_test.php | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/tests/functional/metadata_manager_test.php b/tests/functional/metadata_manager_test.php index c639cad809..0125886e04 100644 --- a/tests/functional/metadata_manager_test.php +++ b/tests/functional/metadata_manager_test.php @@ -78,9 +78,9 @@ class phpbb_functional_metadata_manager_test extends phpbb_functional_test_case $crawler = $this->request('GET', 'adm/index.php?i=acp_extensions&mode=main&sid=' . $this->sid); $this->assert_response_success(); - $this->assertContains($this->lang('EXTENSIONS_EXPLAIN'), $crawler->filter('#page-body')->text()); - $this->assertContains('phpBB 3.1 Extension Testing', $crawler->filter('#page-body')->text()); - $this->assertContains('Details', $crawler->filter('#page-body')->text()); + $this->assertContains($this->lang('EXTENSIONS_EXPLAIN'), $crawler->filter('#main')->text()); + $this->assertContains('phpBB 3.1 Extension Testing', $crawler->filter('#main')->text()); + $this->assertContains('Details', $crawler->filter('#main')->text()); } public function test_extensions_details() @@ -89,15 +89,15 @@ class phpbb_functional_metadata_manager_test extends phpbb_functional_test_case $this->assert_response_success(); // Test whether the details are displayed - $this->assertContains($this->lang('CLEAN_NAME'), $crawler->filter('#page-body')->text()); - $this->assertContains('foo/bar', $crawler->filter('#page-body')->text()); + $this->assertContains($this->lang('CLEAN_NAME'), $crawler->filter('#main')->text()); + $this->assertContains('foo/bar', $crawler->filter('#meta_name')->text()); + $this->assertContains($this->lang('PHP_VERSION'), $crawler->filter('#main')->text()); + $this->assertContains('>=5.3', $crawler->filter('#require_php')->text()); // Details should be html escaped - $this->assertContains($this->lang('PHP_VERSION'), $crawler->filter('#page-body')->text()); - // The Crawler parses the text, so we can not see whether it was escaped anymore - // To test this, we grab the content of the response directly - // $this->assertContains('>=5.3', $$crawler->filter('#page-body')->text()); - $this->assertContains('>=5.3', $this->client->getResponse()->getContent()); + // However, text() only returns the displayed text, so HTML Special Chars are decoded. + // So we test this directly on the content of the response. + $this->assertContains('

      >=5.3

      ', $this->client->getResponse()->getContent()); } public function test_extensions_details_notexists() @@ -106,6 +106,6 @@ class phpbb_functional_metadata_manager_test extends phpbb_functional_test_case $this->assert_response_success(); // Error message because the files do not exist - $this->assertContains('The required file does not exist:', $crawler->filter('#page-body')->text()); + $this->assertContains('The required file does not exist:', $crawler->filter('#main')->text()); } } From 284011ebf256bffb9544493c7b82f90eeff4ae39 Mon Sep 17 00:00:00 2001 From: Dhruv Date: Wed, 8 May 2013 17:04:03 +0530 Subject: [PATCH 270/281] [ticket/10325] move migration into a new file PHPBB3-10325 --- phpBB/includes/db/migration/data/310/dev.php | 2 -- .../db/migration/data/310/forgot_password.php | 28 +++++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 phpBB/includes/db/migration/data/310/forgot_password.php diff --git a/phpBB/includes/db/migration/data/310/dev.php b/phpBB/includes/db/migration/data/310/dev.php index 0794567f1b..13b36bbf30 100644 --- a/phpBB/includes/db/migration/data/310/dev.php +++ b/phpBB/includes/db/migration/data/310/dev.php @@ -84,8 +84,6 @@ class phpbb_db_migration_data_310_dev extends phpbb_db_migration return array( array('config.update', array('search_type', 'phpbb_search_' . $this->config['search_type'])), - array('config.add', array('allow_password_reset', 1)), - array('config.add', array('fulltext_postgres_ts_name', 'simple')), array('config.add', array('fulltext_postgres_min_word_len', 4)), array('config.add', array('fulltext_postgres_max_word_len', 254)), diff --git a/phpBB/includes/db/migration/data/310/forgot_password.php b/phpBB/includes/db/migration/data/310/forgot_password.php new file mode 100644 index 0000000000..a553e51f35 --- /dev/null +++ b/phpBB/includes/db/migration/data/310/forgot_password.php @@ -0,0 +1,28 @@ +config['allow_password_reset']); + } + + static public function depends_on() + { + return array('phpbb_db_migration_data_30x_3_0_11'); + } + + public function update_data() + { + return array( + array('config.add', array('allow_password_reset', 1)), + ); + } +} From 051c2ec25138da5e1c3369b961bc8d2652d115b4 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Thu, 9 May 2013 02:38:27 +0200 Subject: [PATCH 271/281] [ticket/11527] Upgrade composer.phar to 1.0.0-alpha7. PHPBB3-11527 --- composer.phar | Bin 634856 -> 799883 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/composer.phar b/composer.phar index af7b8c1a67f6aebf54ce26b4a973a5ccb150cd8a..a035fdc91138d039ed9e006066c774bb270080e3 100755 GIT binary patch delta 150230 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ð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

      o*fz_S&_>DL@gw7v`0qzWV{GKI9w9< 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 KyVWb#t^B{j6SF%2 delta 40156 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�r^VbyEV zu%p8IVl4C5;E(pDDa_~!e0fXTcqkJj{VcSt+I{cyFcZx?!C}A?P1XMJ-v6Hye6;q> z3BKB_t^A0evM{j?G6NPpbc(0b$$enzww&TgUFWB%8^XBSs};d>F`R*E0*@Fg(sgQj zZ*TF!Nqax$;i`zK?0&UndRV+{lY(8-6B`fb=^B~>ne`j$Uw35JQR z;HCBWA5Q6zB9vQSXwZl}`!i_0SFBQF$?qz#^12(mjB>AXL~{59$~WY7QYr2xs9T3X z@3;Ek(yhD6z5PV)6y)l2+CgZ|Y?`L+xXIz`CUqgHE>(FoS2daGk+C57I$PmRI@hc^ z=_3~ihbQ`}A=;bM)EE=O)ipy$-#k<8LmAW6B&+=0N^_>G^>n|N>PKIG0eRjTi+VJ$ zL`VT7VogYWpu*)!N=?u{n6Bno=<)jyg8G9hD~QAx)j{ibc_~`SLn`806}^ZkoF6u; z@$}+SH6*j4zHx;3AQmDGTMcCF{#jU(FHL9lASr?@MNX$`Wb7mVe03yk%vWQmGamuI z@iahU`%U?9_Pl{2_b+Fdfe>Nl>hU2-lAyAK))lDUR91it*x9qyXbV26O`olvgWn%U zsnxZrpZid03nC)NE>%0NRN0K`Kit9mw9i+l;bur=Oo8F91)0fj-u(ZU+& zucUT!?=rQwmb(h0@+v@nCM|1?ir~x(`$M_uA#8~KE~#fQGIz@Xo*B3PO7qp@v#h8G7+xt-AveOYdKnIQ=SMhV^n%);O?Xkw^rM>}sEF#pBj+N-8Z6vz$3FqU>6W}*hz%VJ7B_bI2BHDjU zb!ZFUSC3ohy^n!I3pS_`8b%)sU2L??k4jIfh4jQpb-1aLQqJ;_kjjQTa>7=^F-_e6 z*G{PeOaTV0#Uiy83J=3Xs`*$=?C&112v3Fi8MWG*aT{R#t=ANJT^$f&iubkR`2lL) z>m5!D&!~lqC5t1&PsPg2?M4rkvK;fkozq2h^X3U+P>AGE(W4YAFe53cyFl{hch{1I z*a~-J0bOwpprHBzj$B_=p)EV){_@!NDk=cTc}|CZ#8M z1?RNOwLzZ}XLwe}N{ShFuaVx#Aood=vy^@G72BY%h|%8I7acFUg(>2ltPkIVzkaM% z()iPAGF`6XK>=>&Pi$7QJtZTJjzJY>YNySo)q-p+g1ds}_+$wEj5J7c-N>sE>#cKP z#y9Cw6(nm(XVii8o(ti1PA*az9XX@+!wE8qR#rY>JPFURl?YN^eKlM&PZjw`~Ca zE+(GAWeM0q#dx^knrMU7f`e`R%?sH zJfyK&-1{)E_;p{KSLAJDHQAHCKjKlGY+9c-w2G(?mU8SlERw+ZFHLZB=bnP$V}}17xe_ip From b3d16f21a80df845890de5fe658648ea545dbfbc Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Thu, 9 May 2013 02:29:03 +0200 Subject: [PATCH 272/281] [ticket/11526] Increase composer minimum stability in olympus to stable. PHPBB3-11526 --- phpBB/composer.json | 1 - 1 file changed, 1 deletion(-) diff --git a/phpBB/composer.json b/phpBB/composer.json index 8d5dd1d52e..9befaf0ee3 100644 --- a/phpBB/composer.json +++ b/phpBB/composer.json @@ -1,5 +1,4 @@ { - "minimum-stability": "beta", "require-dev": { "fabpot/goutte": "v0.1.0" } From 5ea75ddf099c036be04fc0b83d5a10de4efaa0b8 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Thu, 9 May 2013 02:45:26 +0200 Subject: [PATCH 273/281] [ticket/11526] Update all dependencies / regenerate composer.lock. PHPBB3-11526 --- phpBB/composer.lock | 283 +++++++++++++++++++++----------------------- 1 file changed, 137 insertions(+), 146 deletions(-) diff --git a/phpBB/composer.lock b/phpBB/composer.lock index a78fff9a14..102a857a74 100644 --- a/phpBB/composer.lock +++ b/phpBB/composer.lock @@ -1,60 +1,11 @@ { - "hash": "23352b29002e6d22658e314a8e737f71", + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file" + ], + "hash": "17107567f5bb83aa0904e14273f46f25", "packages": [ - { - "name": "symfony/event-dispatcher", - "version": "v2.1.4", - "target-dir": "Symfony/Component/EventDispatcher", - "source": { - "type": "git", - "url": "https://github.com/symfony/EventDispatcher", - "reference": "v2.1.4" - }, - "dist": { - "type": "zip", - "url": "https://github.com/symfony/EventDispatcher/archive/v2.1.4.zip", - "reference": "v2.1.4", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "symfony/dependency-injection": "2.1.*" - }, - "suggest": { - "symfony/dependency-injection": "2.1.*", - "symfony/http-kernel": "2.1.*" - }, - "time": "2012-11-08 09:51:48", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.1-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-0": { - "Symfony\\Component\\EventDispatcher": "" - } - }, - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - } - ], - "description": "Symfony EventDispatcher Component", - "homepage": "http://symfony.com" - } + ], "packages-dev": [ { @@ -72,28 +23,27 @@ "shasum": "" }, "require": { - "php": ">=5.3.0", "ext-curl": "*", + "guzzle/guzzle": "3.0.*", + "php": ">=5.3.0", "symfony/browser-kit": "2.1.*", "symfony/css-selector": "2.1.*", "symfony/dom-crawler": "2.1.*", "symfony/finder": "2.1.*", - "symfony/process": "2.1.*", - "guzzle/guzzle": "3.0.*" + "symfony/process": "2.1.*" }, - "time": "2012-12-02 13:44:35", "type": "application", "extra": { "branch-alias": { "dev-master": "1.0-dev" } }, - "installation-source": "source", "autoload": { "psr-0": { "Goutte": "." } }, + "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], @@ -107,26 +57,27 @@ "homepage": "https://github.com/fabpot/Goutte", "keywords": [ "scraper" - ] + ], + "time": "2012-12-02 13:44:35" }, { "name": "guzzle/guzzle", - "version": "v3.0.5", + "version": "v3.0.7", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle", - "reference": "v3.0.5" + "reference": "v3.0.7" }, "dist": { "type": "zip", - "url": "https://github.com/guzzle/guzzle/archive/v3.0.5.zip", - "reference": "v3.0.5", + "url": "https://github.com/guzzle/guzzle/archive/v3.0.7.zip", + "reference": "v3.0.7", "shasum": "" }, "require": { - "php": ">=5.3.2", "ext-curl": "*", - "symfony/event-dispatcher": "2.1.*" + "php": ">=5.3.2", + "symfony/event-dispatcher": ">=2.1" }, "replace": { "guzzle/batch": "self.version", @@ -153,23 +104,27 @@ }, "require-dev": { "doctrine/common": "*", - "symfony/class-loader": "*", "monolog/monolog": "1.*", - "zendframework/zend-cache": "2.0.*", - "zendframework/zend-log": "2.0.*", - "zend/zend-log1": "1.12", + "phpunit/phpunit": "3.7.*", + "symfony/class-loader": "*", "zend/zend-cache1": "1.12", - "phpunit/phpunit": "3.7.*" + "zend/zend-log1": "1.12", + "zendframework/zend-cache": "2.0.*", + "zendframework/zend-log": "2.0.*" }, - "time": "2012-11-19 00:15:33", "type": "library", - "installation-source": "dist", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, "autoload": { "psr-0": { "Guzzle\\Tests": "tests/", "Guzzle": "src/" } }, + "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], @@ -187,28 +142,29 @@ "description": "Guzzle is a PHP HTTP client library and framework for building RESTful web service clients", "homepage": "http://guzzlephp.org/", "keywords": [ - "framework", - "curl", - "http", - "rest", - "http client", "client", + "curl", + "framework", + "http", + "http client", + "rest", "web service" - ] + ], + "time": "2012-12-19 23:06:35" }, { "name": "symfony/browser-kit", - "version": "v2.1.4", + "version": "v2.1.10", "target-dir": "Symfony/Component/BrowserKit", "source": { "type": "git", - "url": "https://github.com/symfony/BrowserKit", - "reference": "v2.1.4" + "url": "https://github.com/symfony/BrowserKit.git", + "reference": "v2.1.10" }, "dist": { "type": "zip", - "url": "https://github.com/symfony/BrowserKit/archive/v2.1.4.zip", - "reference": "v2.1.4", + "url": "https://api.github.com/repos/symfony/BrowserKit/zipball/v2.1.10", + "reference": "v2.1.10", "shasum": "" }, "require": { @@ -216,25 +172,19 @@ "symfony/dom-crawler": "2.1.*" }, "require-dev": { - "symfony/process": "2.1.*", - "symfony/css-selector": "2.1.*" + "symfony/css-selector": "2.1.*", + "symfony/process": "2.1.*" }, "suggest": { "symfony/process": "2.1.*" }, - "time": "2012-11-08 09:51:48", "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.1-dev" - } - }, - "installation-source": "dist", "autoload": { "psr-0": { "Symfony\\Component\\BrowserKit": "" } }, + "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], @@ -249,39 +199,34 @@ } ], "description": "Symfony BrowserKit Component", - "homepage": "http://symfony.com" + "homepage": "http://symfony.com", + "time": "2013-04-29 20:22:06" }, { "name": "symfony/css-selector", - "version": "v2.1.4", + "version": "v2.1.10", "target-dir": "Symfony/Component/CssSelector", "source": { "type": "git", - "url": "https://github.com/symfony/CssSelector", - "reference": "v2.1.4" + "url": "https://github.com/symfony/CssSelector.git", + "reference": "v2.1.10" }, "dist": { "type": "zip", - "url": "https://github.com/symfony/CssSelector/archive/v2.1.4.zip", - "reference": "v2.1.4", + "url": "https://api.github.com/repos/symfony/CssSelector/zipball/v2.1.10", + "reference": "v2.1.10", "shasum": "" }, "require": { "php": ">=5.3.3" }, - "time": "2012-11-08 09:51:48", "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.1-dev" - } - }, - "installation-source": "dist", "autoload": { "psr-0": { "Symfony\\Component\\CssSelector": "" } }, + "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], @@ -296,21 +241,22 @@ } ], "description": "Symfony CssSelector Component", - "homepage": "http://symfony.com" + "homepage": "http://symfony.com", + "time": "2013-01-09 08:51:07" }, { "name": "symfony/dom-crawler", - "version": "v2.1.4", + "version": "v2.1.10", "target-dir": "Symfony/Component/DomCrawler", "source": { "type": "git", - "url": "https://github.com/symfony/DomCrawler", - "reference": "v2.1.4" + "url": "https://github.com/symfony/DomCrawler.git", + "reference": "v2.1.10" }, "dist": { "type": "zip", - "url": "https://github.com/symfony/DomCrawler/archive/v2.1.4.zip", - "reference": "v2.1.4", + "url": "https://api.github.com/repos/symfony/DomCrawler/zipball/v2.1.10", + "reference": "v2.1.10", "shasum": "" }, "require": { @@ -322,19 +268,13 @@ "suggest": { "symfony/css-selector": "2.1.*" }, - "time": "2012-11-29 10:32:18", "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.1-dev" - } - }, - "installation-source": "dist", "autoload": { "psr-0": { "Symfony\\Component\\DomCrawler": "" } }, + "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], @@ -349,39 +289,88 @@ } ], "description": "Symfony DomCrawler Component", - "homepage": "http://symfony.com" + "homepage": "http://symfony.com", + "time": "2013-03-27 17:13:16" }, { - "name": "symfony/finder", - "version": "v2.1.4", - "target-dir": "Symfony/Component/Finder", + "name": "symfony/event-dispatcher", + "version": "v2.2.1", + "target-dir": "Symfony/Component/EventDispatcher", "source": { "type": "git", - "url": "https://github.com/symfony/Finder", - "reference": "v2.1.4" + "url": "https://github.com/symfony/EventDispatcher.git", + "reference": "v2.2.1" }, "dist": { "type": "zip", - "url": "https://github.com/symfony/Finder/archive/v2.1.4.zip", - "reference": "v2.1.4", + "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/v2.2.1", + "reference": "v2.2.1", "shasum": "" }, "require": { "php": ">=5.3.3" }, - "time": "2012-11-08 09:51:48", + "require-dev": { + "symfony/dependency-injection": ">=2.0,<3.0" + }, + "suggest": { + "symfony/dependency-injection": "2.2.*", + "symfony/http-kernel": "2.2.*" + }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.1-dev" + "dev-master": "2.2-dev" } }, - "installation-source": "dist", + "autoload": { + "psr-0": { + "Symfony\\Component\\EventDispatcher\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + } + ], + "description": "Symfony EventDispatcher Component", + "homepage": "http://symfony.com", + "time": "2013-02-11 11:26:43" + }, + { + "name": "symfony/finder", + "version": "v2.1.10", + "target-dir": "Symfony/Component/Finder", + "source": { + "type": "git", + "url": "https://github.com/symfony/Finder.git", + "reference": "v2.1.10" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/Finder/zipball/v2.1.10", + "reference": "v2.1.10", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", "autoload": { "psr-0": { "Symfony\\Component\\Finder": "" } }, + "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], @@ -396,39 +385,34 @@ } ], "description": "Symfony Finder Component", - "homepage": "http://symfony.com" + "homepage": "http://symfony.com", + "time": "2013-03-06 19:26:55" }, { "name": "symfony/process", - "version": "v2.1.4", + "version": "v2.1.9", "target-dir": "Symfony/Component/Process", "source": { "type": "git", - "url": "https://github.com/symfony/Process", - "reference": "v2.1.4" + "url": "https://github.com/symfony/Process.git", + "reference": "v2.1.9" }, "dist": { "type": "zip", - "url": "https://github.com/symfony/Process/archive/v2.1.4.zip", - "reference": "v2.1.4", + "url": "https://api.github.com/repos/symfony/Process/zipball/v2.1.9", + "reference": "v2.1.9", "shasum": "" }, "require": { "php": ">=5.3.3" }, - "time": "2012-11-19 20:53:52", "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.1-dev" - } - }, - "installation-source": "dist", "autoload": { "psr-0": { "Symfony\\Component\\Process": "" } }, + "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], @@ -443,14 +427,21 @@ } ], "description": "Symfony Process Component", - "homepage": "http://symfony.com" + "homepage": "http://symfony.com", + "time": "2013-03-23 07:44:01" } ], "aliases": [ ], - "minimum-stability": "beta", + "minimum-stability": "stable", "stability-flags": [ + ], + "platform": [ + + ], + "platform-dev": [ + ] } From 585f0bc827673cc633b6c43081568d3551e97ae8 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Fri, 3 May 2013 22:16:31 +0200 Subject: [PATCH 274/281] [ticket/11513] Add PHPUnit 3.7 and DbUnit 1.2 as a composer dev dependency. PHPBB3-11513 --- phpBB/composer.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/phpBB/composer.json b/phpBB/composer.json index 9befaf0ee3..14190f5e82 100644 --- a/phpBB/composer.json +++ b/phpBB/composer.json @@ -1,5 +1,7 @@ { "require-dev": { - "fabpot/goutte": "v0.1.0" + "fabpot/goutte": "v0.1.0", + "phpunit/dbunit": "1.2.*", + "phpunit/phpunit": "3.7.*" } } From a42514105d710bf16f30fed467418128501ca88e Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Fri, 3 May 2013 22:41:24 +0200 Subject: [PATCH 275/281] [ticket/11513] Update (all) composer dependencies. PHPBB3-11513 --- phpBB/composer.lock | 461 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 460 insertions(+), 1 deletion(-) diff --git a/phpBB/composer.lock b/phpBB/composer.lock index 102a857a74..70b352a320 100644 --- a/phpBB/composer.lock +++ b/phpBB/composer.lock @@ -3,7 +3,7 @@ "This file locks the dependencies of your project to a known state", "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file" ], - "hash": "17107567f5bb83aa0904e14273f46f25", + "hash": "656de56578d4eb3e4779bc0ab95524f5", "packages": [ ], @@ -152,6 +152,418 @@ ], "time": "2012-12-19 23:06:35" }, + { + "name": "phpunit/dbunit", + "version": "1.2.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/dbunit.git", + "reference": "1.2.3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/dbunit/zipball/1.2.3", + "reference": "1.2.3", + "shasum": "" + }, + "require": { + "ext-pdo": "*", + "ext-simplexml": "*", + "php": ">=5.3.3", + "phpunit/phpunit": ">=3.7.0@stable" + }, + "bin": [ + "dbunit.php" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "autoload": { + "classmap": [ + "PHPUnit/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "", + "../../symfony/yaml/" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "DbUnit port for PHP/PHPUnit to support database interaction testing.", + "homepage": "https://github.com/sebastianbergmann/dbunit/", + "keywords": [ + "database", + "testing", + "xunit" + ], + "time": "2013-03-01 11:50:46" + }, + { + "name": "phpunit/php-code-coverage", + "version": "1.2.9", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "1.2.9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/1.2.9", + "reference": "1.2.9", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "phpunit/php-file-iterator": ">=1.3.0@stable", + "phpunit/php-text-template": ">=1.1.1@stable", + "phpunit/php-token-stream": ">=1.1.3@stable" + }, + "suggest": { + "ext-dom": "*", + "ext-xdebug": ">=2.0.5" + }, + "type": "library", + "autoload": { + "classmap": [ + "PHP/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "time": "2013-02-26 18:55:56" + }, + { + "name": "phpunit/php-file-iterator", + "version": "1.3.3", + "source": { + "type": "git", + "url": "git://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "1.3.3" + }, + "dist": { + "type": "zip", + "url": "https://github.com/sebastianbergmann/php-file-iterator/zipball/1.3.3", + "reference": "1.3.3", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "File/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "http://www.phpunit.de/", + "keywords": [ + "filesystem", + "iterator" + ], + "time": "2012-10-11 04:44:38" + }, + { + "name": "phpunit/php-text-template", + "version": "1.1.4", + "source": { + "type": "git", + "url": "git://github.com/sebastianbergmann/php-text-template.git", + "reference": "1.1.4" + }, + "dist": { + "type": "zip", + "url": "https://github.com/sebastianbergmann/php-text-template/zipball/1.1.4", + "reference": "1.1.4", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "Text/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "time": "2012-10-31 11:15:28" + }, + { + "name": "phpunit/php-timer", + "version": "1.0.4", + "source": { + "type": "git", + "url": "git://github.com/sebastianbergmann/php-timer.git", + "reference": "1.0.4" + }, + "dist": { + "type": "zip", + "url": "https://github.com/sebastianbergmann/php-timer/zipball/1.0.4", + "reference": "1.0.4", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "PHP/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "http://www.phpunit.de/", + "keywords": [ + "timer" + ], + "time": "2012-10-11 04:45:58" + }, + { + "name": "phpunit/php-token-stream", + "version": "1.1.5", + "source": { + "type": "git", + "url": "git://github.com/sebastianbergmann/php-token-stream.git", + "reference": "1.1.5" + }, + "dist": { + "type": "zip", + "url": "https://github.com/sebastianbergmann/php-token-stream/zipball/1.1.5", + "reference": "1.1.5", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "PHP/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Wrapper around PHP's tokenizer extension.", + "homepage": "http://www.phpunit.de/", + "keywords": [ + "tokenizer" + ], + "time": "2012-10-11 04:47:14" + }, + { + "name": "phpunit/phpunit", + "version": "3.7.19", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "3.7.19" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/3.7.19", + "reference": "3.7.19", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-pcre": "*", + "ext-reflection": "*", + "ext-spl": "*", + "php": ">=5.3.3", + "phpunit/php-code-coverage": ">=1.2.1,<1.3.0", + "phpunit/php-file-iterator": ">=1.3.1", + "phpunit/php-text-template": ">=1.1.1", + "phpunit/php-timer": ">=1.0.2,<1.1.0", + "phpunit/phpunit-mock-objects": ">=1.2.0,<1.3.0", + "symfony/yaml": ">=2.0.0,<2.3.0" + }, + "require-dev": { + "pear-pear/pear": "1.9.4" + }, + "suggest": { + "ext-json": "*", + "ext-simplexml": "*", + "ext-tokenizer": "*", + "phpunit/php-invoker": ">=1.1.0,<1.2.0" + }, + "bin": [ + "composer/bin/phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.7.x-dev" + } + }, + "autoload": { + "classmap": [ + "PHPUnit/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "", + "../../symfony/yaml/" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "http://www.phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "time": "2013-03-25 11:45:06" + }, + { + "name": "phpunit/phpunit-mock-objects", + "version": "1.2.3", + "source": { + "type": "git", + "url": "git://github.com/sebastianbergmann/phpunit-mock-objects.git", + "reference": "1.2.3" + }, + "dist": { + "type": "zip", + "url": "https://github.com/sebastianbergmann/phpunit-mock-objects/archive/1.2.3.zip", + "reference": "1.2.3", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "phpunit/php-text-template": ">=1.1.1@stable" + }, + "suggest": { + "ext-soap": "*" + }, + "type": "library", + "autoload": { + "classmap": [ + "PHPUnit/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Mock Object library for PHPUnit", + "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", + "keywords": [ + "mock", + "xunit" + ], + "time": "2013-01-13 10:24:48" + }, { "name": "symfony/browser-kit", "version": "v2.1.10", @@ -429,6 +841,53 @@ "description": "Symfony Process Component", "homepage": "http://symfony.com", "time": "2013-03-23 07:44:01" + }, + { + "name": "symfony/yaml", + "version": "v2.2.1", + "target-dir": "Symfony/Component/Yaml", + "source": { + "type": "git", + "url": "https://github.com/symfony/Yaml.git", + "reference": "v2.2.1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/Yaml/zipball/v2.2.1", + "reference": "v2.2.1", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.2-dev" + } + }, + "autoload": { + "psr-0": { + "Symfony\\Component\\Yaml\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + } + ], + "description": "Symfony Yaml Component", + "homepage": "http://symfony.com", + "time": "2013-03-23 07:49:54" } ], "aliases": [ From b5b1e88915ae8ae220c62b0d27f514069c3c0249 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Fri, 3 May 2013 23:16:43 +0200 Subject: [PATCH 276/281] [ticket/11513] Use PHPUnit from composer in .travis.yml. PHPBB3-11513 --- .travis.yml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0bb6920412..093719528d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,17 +18,15 @@ before_script: - sh -c "if [ '$DB' = 'postgres' ]; then psql -c 'DROP DATABASE IF EXISTS phpbb_tests;' -U postgres; fi" - sh -c "if [ '$DB' = 'postgres' ]; then psql -c 'create database phpbb_tests;' -U postgres; fi" - sh -c "if [ '$DB' = 'mysql' ]; then mysql -e 'create database IF NOT EXISTS phpbb_tests;'; fi" - - sh -c "if [ '$TRAVIS_PHP_VERSION' != '5.2' ]; then pyrus set auto_discover 1; fi" - - sh -c "if [ '$TRAVIS_PHP_VERSION' = '5.2' ]; then pear install --force phpunit/DbUnit; else pyrus install --force phpunit/DbUnit; fi" - - phpenv rehash + - sh -c "if [ '$TRAVIS_PHP_VERSION' = '5.2' ]; then pear install --force phpunit/DbUnit; phpenv rehash; fi" - cd phpBB - sh -c "if [ '$TRAVIS_PHP_VERSION' != '5.2' ]; then php ../composer.phar install --dev; fi" - cd .. - sh -c "if [ `php -r "echo (int) version_compare(PHP_VERSION, '5.3.19', '>=');"` = "1" ]; then travis/setup-webserver.sh; fi" script: - - phpunit --configuration travis/phpunit-$DB-travis.xml - + - sh -c "if [ '$TRAVIS_PHP_VERSION' = '5.2' ]; then phpunit --configuration travis/phpunit-$DB-travis.xml; else phpBB/vendor/bin/phpunit --configuration travis/phpunit-$DB-travis.xml; fi" + notifications: email: recipients: From f2f97dd5e06be645f830e0467737d9f23544d631 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Thu, 9 May 2013 18:58:31 +0200 Subject: [PATCH 277/281] [ticket/11513] Update all CLI calls to phpunit to use vendor/bin. PHPBB3-11513 --- build/build.xml | 6 ++++-- git-tools/merge.php | 6 +++--- tests/RUNNING_TESTS.txt | 4 ++-- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/build/build.xml b/build/build.xml index f9574a3d4d..75affb0f2d 100644 --- a/build/build.xml +++ b/build/build.xml @@ -56,7 +56,8 @@ @@ -64,7 +65,8 @@ Date: Thu, 9 May 2013 19:14:31 +0200 Subject: [PATCH 278/281] [ticket/11513] Update RUNNING_TESTS.txt to no longer refer to PEAR. PHPBB3-11513 --- tests/RUNNING_TESTS.txt | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/tests/RUNNING_TESTS.txt b/tests/RUNNING_TESTS.txt index f33fa59dc2..0fa45e7bc4 100644 --- a/tests/RUNNING_TESTS.txt +++ b/tests/RUNNING_TESTS.txt @@ -7,9 +7,14 @@ Prerequisites PHPUnit ------- -phpBB unit tests use PHPUnit framework. Version 3.5 or better is required -to run the tests. PHPUnit prefers to be installed via PEAR; refer to -http://www.phpunit.de/ for more information. +phpBB unit tests use the PHPUnit framework (see http://www.phpunit.de for more +information). Version 3.5 or higher is required to run the tests. PHPUnit can +be installed via Composer together with other development dependencies as +follows. + + $ cd phpBB + $ php ../composer.phar install --dev + $ cd .. PHP extensions -------------- From 1c9d36615a60dfbe96da5e9866480313415f262d Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Thu, 9 May 2013 19:59:34 +0200 Subject: [PATCH 279/281] [ticket/11529] Rename RUNNING_TESTS.txt to RUNNING_TESTS.md PHPBB3-11529 --- tests/{RUNNING_TESTS.txt => RUNNING_TESTS.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename tests/{RUNNING_TESTS.txt => RUNNING_TESTS.md} (100%) diff --git a/tests/RUNNING_TESTS.txt b/tests/RUNNING_TESTS.md similarity index 100% rename from tests/RUNNING_TESTS.txt rename to tests/RUNNING_TESTS.md From ab3b0df2449ec8b4b215dcde3c7d0b8cd35147ce Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Thu, 9 May 2013 20:06:12 +0200 Subject: [PATCH 280/281] [ticket/11529] Format markdown code correctly PHPBB3-11529 --- tests/RUNNING_TESTS.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/RUNNING_TESTS.md b/tests/RUNNING_TESTS.md index 0fa45e7bc4..26a93f0430 100644 --- a/tests/RUNNING_TESTS.md +++ b/tests/RUNNING_TESTS.md @@ -79,14 +79,16 @@ In order to run tests on some of the databases that we support, it will be necessary to provide a custom DSN string in test_config.php. This is only needed for MSSQL 2000+ (PHP module), MSSQL via ODBC, and Firebird when PDO_Firebird does not work on your system -(https://bugs.php.net/bug.php?id=61183). The variable must be named $custom_dsn. +(https://bugs.php.net/bug.php?id=61183). The variable must be named `$custom_dsn`. Examples: Firebird using http://www.firebirdsql.org/en/odbc-driver/ -$custom_dsn = "Driver={Firebird/InterBase(r) driver};dbname=$dbhost:$dbname"; + + $custom_dsn = "Driver={Firebird/InterBase(r) driver};dbname=$dbhost:$dbname"; MSSQL -$custom_dsn = "Driver={SQL Server Native Client 10.0};Server=$dbhost;Database=$dbname"; + + $custom_dsn = "Driver={SQL Server Native Client 10.0};Server=$dbhost;Database=$dbname"; The other fields in test_config.php should be filled out as you would normally to connect to that database in phpBB. From d1415676c54138fecfe133a92bbf7aca52d3c2b7 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Thu, 9 May 2013 20:02:55 +0200 Subject: [PATCH 281/281] [ticket/11324] PHP 5.5 is in RC stage. No longer allow failure on travis. PHPBB3-11324 --- .travis.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 093719528d..b08d677bc8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,10 +10,6 @@ env: - DB=mysql - DB=postgres -matrix: - allow_failures: - - php: 5.5 - before_script: - sh -c "if [ '$DB' = 'postgres' ]; then psql -c 'DROP DATABASE IF EXISTS phpbb_tests;' -U postgres; fi" - sh -c "if [ '$DB' = 'postgres' ]; then psql -c 'create database phpbb_tests;' -U postgres; fi"