From 49de9e3d444ab71a2ad1e5ac1db6d92e3cb80466 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Sat, 2 Mar 2013 15:03:13 -0600 Subject: [ticket/11387] Log module added only after it has been added PHPBB3-11387 --- phpBB/includes/db/migration/tool/module.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'phpBB') diff --git a/phpBB/includes/db/migration/tool/module.php b/phpBB/includes/db/migration/tool/module.php index 6ffb073543..3ba82d8a0f 100644 --- a/phpBB/includes/db/migration/tool/module.php +++ b/phpBB/includes/db/migration/tool/module.php @@ -209,9 +209,6 @@ class phpbb_db_migration_tool_module implements phpbb_db_migration_tool_interfac } // The "manual" way - $module_log_name = ((isset($this->user->lang[$data['module_langname']])) ? $this->user->lang[$data['module_langname']] : $data['module_langname']); - add_log('admin', 'LOG_MODULE_ADD', $module_log_name); - if (!is_numeric($parent)) { $sql = 'SELECT module_id @@ -267,6 +264,8 @@ class phpbb_db_migration_tool_module implements phpbb_db_migration_tool_interfac else { // Success + $module_log_name = ((isset($this->user->lang[$data['module_langname']])) ? $this->user->lang[$data['module_langname']] : $data['module_langname']); + add_log('admin', 'LOG_MODULE_ADD', $module_log_name); // Move the module if requested above/below an existing one if (isset($data['before']) && $data['before']) -- cgit v1.2.1 From a38a92424ddf00383c17a6dffffe522065e25c9f Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Thu, 14 Mar 2013 10:45:17 -0700 Subject: [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(-) (limited to 'phpBB') 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'); -- cgit v1.2.1 From 56914e72b7ec2e4063e0d510f2d61a56c37f80d0 Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Fri, 15 Mar 2013 09:51:34 -0700 Subject: [ticket/10155] Use new migration file for jQuery config update --- phpBB/includes/db/migration/data/310/dev.php | 2 +- phpBB/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 (limited to 'phpBB') 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')), + ); + } + +} -- cgit v1.2.1 From 58d7acbf5a4483f7e2ebac6d9ed38189c48facfb Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Sun, 17 Mar 2013 19:54:32 +0100 Subject: [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(-) (limited to 'phpBB') 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']; } /** -- cgit v1.2.1 From ac26be98c69094173c90acc49d208f751b93b7df Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Sun, 17 Mar 2013 17:01:38 -0700 Subject: [ticket/10155] Use more descriptive title for migration file PHPBB3-10155 --- phpBB/includes/db/migration/data/310/dev_p2.php | 31 ---------------------- .../db/migration/data/310/jquery_update.php | 31 ++++++++++++++++++++++ 2 files changed, 31 insertions(+), 31 deletions(-) delete mode 100644 phpBB/includes/db/migration/data/310/dev_p2.php create mode 100644 phpBB/includes/db/migration/data/310/jquery_update.php (limited to 'phpBB') diff --git a/phpBB/includes/db/migration/data/310/dev_p2.php b/phpBB/includes/db/migration/data/310/dev_p2.php deleted file mode 100644 index f5ec6eeb01..0000000000 --- a/phpBB/includes/db/migration/data/310/dev_p2.php +++ /dev/null @@ -1,31 +0,0 @@ -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')), - ); - } - -} diff --git a/phpBB/includes/db/migration/data/310/jquery_update.php b/phpBB/includes/db/migration/data/310/jquery_update.php new file mode 100644 index 0000000000..ac6cf2666a --- /dev/null +++ b/phpBB/includes/db/migration/data/310/jquery_update.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')), + ); + } + +} -- cgit v1.2.1 From aefca4b40f67bc4d0cc52c8f89705148237a5f05 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Thu, 21 Mar 2013 14:59:53 +0100 Subject: [ticket/11465] Use extension finder when adding extensions' acp modules The method acp_modules::get_module_infos() needs to use the extension finder whenever it is looking for a module's info file. While transitioning to the new extension system, only the initial search for all module info files was changed to the new system. Due to this it is not possible to add an extension's acp/mcp/ucp module manually in the ACP. This patch will always use the extension finder for the acp module's info files and therefore properly find the needed file. Additionally, the code has been cleaned up a little bit. PHPBB3-11465 --- phpBB/includes/acp/acp_modules.php | 72 +++++++++++++------------------------- 1 file changed, 25 insertions(+), 47 deletions(-) (limited to 'phpBB') diff --git a/phpBB/includes/acp/acp_modules.php b/phpBB/includes/acp/acp_modules.php index 7c2ea86122..9cf6bf0214 100644 --- a/phpBB/includes/acp/acp_modules.php +++ b/phpBB/includes/acp/acp_modules.php @@ -544,81 +544,59 @@ class acp_modules */ function get_module_infos($module = '', $module_class = false, $use_all_available = false) { - global $phpbb_root_path, $phpEx; + global $phpbb_extension_manager, $phpbb_root_path, $phpEx; $module_class = ($module_class === false) ? $this->module_class : $module_class; $directory = $phpbb_root_path . 'includes/' . $module_class . '/info/'; $fileinfo = array(); - if (!$module) - { - global $phpbb_extension_manager; - - $finder = $phpbb_extension_manager->get_finder(); + $finder = $phpbb_extension_manager->get_finder(); - $modules = $finder - ->extension_suffix('_module') - ->extension_directory("/$module_class") - ->core_path("includes/$module_class/info/") - ->core_prefix($module_class . '_') - ->get_classes(true, $use_all_available); + $modules = $finder + ->extension_suffix('_module') + ->extension_directory("/$module_class") + ->core_path("includes/$module_class/info/") + ->core_prefix($module_class . '_') + ->get_classes(true, $use_all_available); - foreach ($modules as $module) + foreach ($modules as $cur_module) + { + // Skip entries we do not need if we know the module we are + // looking for + if ($module && strpos($cur_module, $module) === false) { - $info_class = preg_replace('/_module$/', '_info', $module); - - // If the class does not exist it might be following the old - // format. phpbb_acp_info_acp_foo needs to be turned into - // acp_foo_info and the respective file has to be included - // manually because it does not support auto loading - if (!class_exists($info_class)) - { - $info_class = str_replace("phpbb_{$module_class}_info_", '', $module) . '_info'; - if (file_exists($directory . $info_class . '.' . $phpEx)) - { - include($directory . $info_class . '.' . $phpEx); - } - } - - if (class_exists($info_class)) - { - $info = new $info_class(); - $module_info = $info->module(); - - $main_class = (isset($module_info['filename'])) ? $module_info['filename'] : $module; - - $fileinfo[$main_class] = $module_info; - } + continue; } - ksort($fileinfo); - } - else - { - $info_class = preg_replace('/_module$/', '_info', $module); + $info_class = preg_replace('/_module$/', '_info', $cur_module); + // If the class does not exist it might be following the old + // format. phpbb_acp_info_acp_foo needs to be turned into + // acp_foo_info and the respective file has to be included + // manually because it does not support auto loading if (!class_exists($info_class)) { - $info_class = $module . '_info'; - if (!class_exists($info_class) && file_exists($directory . $module . '.' . $phpEx)) + $info_class = str_replace("phpbb_{$module_class}_info_", '', $cur_module) . '_info'; + if (file_exists($directory . $info_class . '.' . $phpEx)) { - include($directory . $module . '.' . $phpEx); + include($directory . $info_class . '.' . $phpEx); } } - // Get module title tag if (class_exists($info_class)) { $info = new $info_class(); $module_info = $info->module(); - $main_class = (isset($module_info['filename'])) ? $module_info['filename'] : $module; + $main_class = (isset($module_info['filename'])) ? $module_info['filename'] : $cur_module; $fileinfo[$main_class] = $module_info; } } + ksort($fileinfo); + return $fileinfo; } -- cgit v1.2.1 From 73d6855edf2f7a72a2f4836e7cce8f94e34f5502 Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Fri, 22 Mar 2013 11:22:25 -0700 Subject: [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(-) (limited to 'phpBB') 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() -- cgit v1.2.1 From 323a494cd16bd202d89260f756519c2d76f2f9fe Mon Sep 17 00:00:00 2001 From: OpenShift guest Date: Mon, 25 Mar 2013 18:21:48 -0400 Subject: [ticket/11458] Search for permission language files in extensions Extensions that add new permission masks only need to add a permission file in the language folder of the extension. The file must start with 'permissions_' eg 'permissions_blog.php'. The permission language file will be automatically included when viewing/setting permissions. PHPBB3-11458 --- phpBB/includes/functions_admin.php | 35 +++++++++++------------------------ 1 file changed, 11 insertions(+), 24 deletions(-) (limited to 'phpBB') diff --git a/phpBB/includes/functions_admin.php b/phpBB/includes/functions_admin.php index d273b9fb3a..5d71f55d1a 100644 --- a/phpBB/includes/functions_admin.php +++ b/phpBB/includes/functions_admin.php @@ -3040,38 +3040,25 @@ function tidy_database() */ function add_permission_language() { - global $user, $phpEx; + global $user, $phpEx, $phpbb_extension_manager; // First of all, our own file. We need to include it as the first file because it presets all relevant variables. $user->add_lang('acp/permissions_phpbb'); - $files_to_add = array(); + // add permission language files from extensions + $finder = $phpbb_extension_manager->get_finder(); - // Now search in acp and mods folder for permissions_ files. - foreach (array('acp/', 'mods/') as $path) - { - $dh = @opendir($user->lang_path . $user->lang_name . '/' . $path); - - if ($dh) - { - while (($file = readdir($dh)) !== false) - { - if ($file !== 'permissions_phpbb.' . $phpEx && strpos($file, 'permissions_') === 0 && substr($file, -(strlen($phpEx) + 1)) === '.' . $phpEx) - { - $files_to_add[] = $path . substr($file, 0, -(strlen($phpEx) + 1)); - } - } - closedir($dh); - } - } + $lang_files = $finder + ->prefix('permissions_') + ->suffix(".$phpEx") + ->extension_directory('/language/' . $user->lang_name) + ->core_path('language/' . $user->lang_name . '/mods') + ->find(); - if (!sizeof($files_to_add)) + foreach ($lang_files as $lang_file => $ext_name) { - return false; + $user->add_lang_ext($ext_name, $lang_file); } - - $user->add_lang($files_to_add); - return true; } /** -- cgit v1.2.1 From 29a5db25ec21a8b349195d01bdd0cfea09814653 Mon Sep 17 00:00:00 2001 From: Vjacheslav Trushkin Date: Sun, 7 Apr 2013 19:12:04 +0300 Subject: [ticket/11482] Implementation of advanced DEFINE tag Implementation of advanced DEFINE tag and ENDDEFINE PHPBB3-11482 --- phpBB/includes/template/filter.php | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'phpBB') diff --git a/phpBB/includes/template/filter.php b/phpBB/includes/template/filter.php index 9e8ad2fef0..a3894905e5 100644 --- a/phpBB/includes/template/filter.php +++ b/phpBB/includes/template/filter.php @@ -329,6 +329,10 @@ class phpbb_template_filter extends php_user_filter return 'compile_tag_define($matches[2], false) . ' ?>'; break; + case 'ENDDEFINE': + return 'compile_tag_enddefine() . ' ?>'; + break; + case 'INCLUDE': return 'compile_tag_include($matches[2]) . ' ?>'; break; @@ -833,6 +837,16 @@ class phpbb_template_filter extends php_user_filter $match = array(); preg_match('#^((?:' . self::REGEX_NS . '\.)+)?\$(?=[A-Z])([A-Z0-9_\-]*)(?: = (.*?))?$#', $tag_args, $match); + if (!empty($match[2]) && !isset($match[3]) && $op) + { + // DEFINE tag with ENDDEFINE + $array = '$_tpldata[\'DEFINE\'][\'.vars\']'; + $code = 'ob_start(); '; + $code .= 'if (!isset(' . $array . ')) { ' . $array . ' = array(); } '; + $code .= $array . '[] = \'' . $match[2] . '\''; + return $code; + } + if (empty($match[2]) || (!isset($match[3]) && $op)) { return ''; @@ -859,6 +873,20 @@ class phpbb_template_filter extends php_user_filter return (($match[1]) ? $this->generate_block_data_ref(substr($match[1], 0, -1), true, true) . '[\'' . $match[2] . '\']' : '$_tpldata[\'DEFINE\'][\'.\'][\'' . $match[2] . '\']') . ' = ' . $parsed_statement . ';'; } + /** + * Compile ENDDEFINE tag + * + * @return string compiled template code + */ + private function compile_tag_enddefine() + { + $array = '$_tpldata[\'DEFINE\'][\'.vars\']'; + $code = 'if (!isset(' . $array . ') || !sizeof(' . $array . ')) { trigger_error(\'ENDDEFINE tag without DEFINE in \' . basename(__FILE__), E_USER_ERROR); }'; + $code .= '$define_var = array_pop(' . $array . '); '; + $code .= '$_tpldata[\'DEFINE\'][\'.\'][$define_var] = ob_get_clean();'; + return $code; + } + /** * Compile INCLUDE tag * -- cgit v1.2.1 From 78bcc31a5d0cb01a4748f184fddd00a9b50f09f1 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Wed, 10 Apr 2013 13:08:31 +0200 Subject: [ticket/11465] The info file does not have _info suffix PHPBB3-11465 --- phpBB/includes/acp/acp_modules.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'phpBB') diff --git a/phpBB/includes/acp/acp_modules.php b/phpBB/includes/acp/acp_modules.php index 9cf6bf0214..62af12ad32 100644 --- a/phpBB/includes/acp/acp_modules.php +++ b/phpBB/includes/acp/acp_modules.php @@ -577,10 +577,11 @@ class acp_modules // manually because it does not support auto loading if (!class_exists($info_class)) { - $info_class = str_replace("phpbb_{$module_class}_info_", '', $cur_module) . '_info'; - if (file_exists($directory . $info_class . '.' . $phpEx)) + $info_class_file = str_replace("phpbb_{$module_class}_info_", '', $cur_module); + $info_class = $info_class_file . '_info'; + if (file_exists($directory . $info_class_file . '.' . $phpEx)) { - include($directory . $info_class . '.' . $phpEx); + include($directory . $info_class_file . '.' . $phpEx); } } -- cgit v1.2.1 From 8567aaed324eb87856ee6274f8330c52beecd0a3 Mon Sep 17 00:00:00 2001 From: Vjacheslav Trushkin Date: Wed, 10 Apr 2013 20:12:03 +0300 Subject: [ticket/11482] Use double quotes for code Use double quotes for code to avoid excessive escaping PHPBB3-11482 --- phpBB/includes/template/filter.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'phpBB') diff --git a/phpBB/includes/template/filter.php b/phpBB/includes/template/filter.php index a3894905e5..5b0957280d 100644 --- a/phpBB/includes/template/filter.php +++ b/phpBB/includes/template/filter.php @@ -840,10 +840,10 @@ class phpbb_template_filter extends php_user_filter if (!empty($match[2]) && !isset($match[3]) && $op) { // DEFINE tag with ENDDEFINE - $array = '$_tpldata[\'DEFINE\'][\'.vars\']'; + $array = "\$_tpldata['DEFINE']['.vars']"; $code = 'ob_start(); '; - $code .= 'if (!isset(' . $array . ')) { ' . $array . ' = array(); } '; - $code .= $array . '[] = \'' . $match[2] . '\''; + $code .= "if (!isset($array)) { $array = array(); } "; + $code .= "{$array}[] = '{$match[2]}'"; return $code; } @@ -880,10 +880,10 @@ class phpbb_template_filter extends php_user_filter */ private function compile_tag_enddefine() { - $array = '$_tpldata[\'DEFINE\'][\'.vars\']'; - $code = 'if (!isset(' . $array . ') || !sizeof(' . $array . ')) { trigger_error(\'ENDDEFINE tag without DEFINE in \' . basename(__FILE__), E_USER_ERROR); }'; - $code .= '$define_var = array_pop(' . $array . '); '; - $code .= '$_tpldata[\'DEFINE\'][\'.\'][$define_var] = ob_get_clean();'; + $array = "\$_tpldata['DEFINE']['.vars']"; + $code = "if (!isset($array) || !sizeof($array)) { trigger_error('ENDDEFINE tag without DEFINE in ' . basename(__FILE__), E_USER_ERROR); }"; + $code .= "\$define_var = array_pop($array); "; + $code .= "\$_tpldata['DEFINE']['.'][\$define_var] = ob_get_clean();"; return $code; } -- cgit v1.2.1 From 88072fd6c2c3ec6cc6d2a880bd76a9c601fd0767 Mon Sep 17 00:00:00 2001 From: Vjacheslav Trushkin Date: Tue, 9 Apr 2013 18:38:59 +0300 Subject: [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(+) (limited to 'phpBB') 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 -- cgit v1.2.1 From 316efcbbbb72058bb9986be08af3d11173817386 Mon Sep 17 00:00:00 2001 From: Vjacheslav Trushkin Date: Tue, 9 Apr 2013 18:39:47 +0300 Subject: [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(+) (limited to 'phpBB') 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 -- cgit v1.2.1 From 67f0e19128415210f0ece4a8cd3df12e4b35eaf6 Mon Sep 17 00:00:00 2001 From: Vjacheslav Trushkin Date: Tue, 9 Apr 2013 18:47:08 +0300 Subject: [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(-) (limited to 'phpBB') 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')); }); -- cgit v1.2.1 From cbb9f084fce0fd42ed1481233f417c79e8a0abfa Mon Sep 17 00:00:00 2001 From: Vjacheslav Trushkin Date: Wed, 10 Apr 2013 09:08:25 +0300 Subject: [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(-) (limited to 'phpBB') 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() { -- cgit v1.2.1 From 474b4a60a527a4c0cd853872ce80ae50fdd2f374 Mon Sep 17 00:00:00 2001 From: OpenShift guest Date: Sat, 13 Apr 2013 10:49:59 -0400 Subject: [ticket/11458] We still auto add language files from the mods and acp folders in the language directory, so we revert some changes here PHPBB3-11458 --- phpBB/includes/functions_admin.php | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) (limited to 'phpBB') diff --git a/phpBB/includes/functions_admin.php b/phpBB/includes/functions_admin.php index 5d71f55d1a..b5efa49159 100644 --- a/phpBB/includes/functions_admin.php +++ b/phpBB/includes/functions_admin.php @@ -3045,20 +3045,47 @@ function add_permission_language() // First of all, our own file. We need to include it as the first file because it presets all relevant variables. $user->add_lang('acp/permissions_phpbb'); - // add permission language files from extensions + $files_to_add = array(); + + // Now search in acp and mods folder for permissions_ files. + foreach (array('acp/', 'mods/') as $path) + { + $dh = @opendir($user->lang_path . $user->lang_name . '/' . $path); + + if ($dh) + { + while (($file = readdir($dh)) !== false) + { + if ($file !== 'permissions_phpbb.' . $phpEx && strpos($file, 'permissions_') === 0 && substr($file, -(strlen($phpEx) + 1)) === '.' . $phpEx) + { + $files_to_add[] = $path . substr($file, 0, -(strlen($phpEx) + 1)); + } + } + closedir($dh); + } + } + + // find permission language files from extensions $finder = $phpbb_extension_manager->get_finder(); - $lang_files = $finder + $ext_lang_files = $finder ->prefix('permissions_') ->suffix(".$phpEx") ->extension_directory('/language/' . $user->lang_name) - ->core_path('language/' . $user->lang_name . '/mods') ->find(); - foreach ($lang_files as $lang_file => $ext_name) + foreach ($ext_lang_files as $lang_file => $ext_name) { $user->add_lang_ext($ext_name, $lang_file); } + + if (!sizeof($files_to_add)) + { + return false; + } + + $user->add_lang($files_to_add); + return true; } /** -- cgit v1.2.1 From 7240759e34d4e67fbce632c03ae6818aad36a07c Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Sun, 14 Apr 2013 17:25:45 +0200 Subject: [ticket/11465] Check if class exists before including info file PHPBB3-11465 --- phpBB/includes/acp/acp_modules.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB') diff --git a/phpBB/includes/acp/acp_modules.php b/phpBB/includes/acp/acp_modules.php index 62af12ad32..ab416fb406 100644 --- a/phpBB/includes/acp/acp_modules.php +++ b/phpBB/includes/acp/acp_modules.php @@ -579,7 +579,7 @@ class acp_modules { $info_class_file = str_replace("phpbb_{$module_class}_info_", '', $cur_module); $info_class = $info_class_file . '_info'; - if (file_exists($directory . $info_class_file . '.' . $phpEx)) + if (!class_exists($info_class) && file_exists($directory . $info_class_file . '.' . $phpEx)) { include($directory . $info_class_file . '.' . $phpEx); } -- cgit v1.2.1 From a1183a58894967bfec7da01c5004138e4daeb583 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 16 Apr 2013 23:07:48 +0200 Subject: [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 (limited to 'phpBB') 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: [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 (limited to 'phpBB') 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; + } +} -- cgit v1.2.1 From 57a05e7cf509f56309591aaf9344226a8f1a9a8e Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 16 Apr 2013 23:09:21 +0200 Subject: [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 (limited to 'phpBB') 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']; + } +} -- cgit v1.2.1 From f831e3c66efe79841a0bcc01cf0b2d37e6d4e65c Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Wed, 17 Apr 2013 22:52:17 +0200 Subject: [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(-) (limited to 'phpBB') 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 -- cgit v1.2.1 From 5c379db085bab4ff0f807a9e7dfe6edb52ef25ab Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Wed, 17 Apr 2013 22:56:12 +0200 Subject: [ticket/11495] Fix description of get_sql_where PHPBB3-11495 --- phpBB/includes/nestedset/base.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'phpBB') 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. -- cgit v1.2.1 From 8c3443ba996c57a0420e4559022c97c2547404c0 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 18 Apr 2013 00:13:19 +0200 Subject: [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(-) (limited to 'phpBB') 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 -- cgit v1.2.1 From 86937e03ec4af92b6467427d9ee69467139f8119 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 18 Apr 2013 00:15:02 +0200 Subject: [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 (limited to 'phpBB') 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:34:09 +0200 Subject: [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(-) (limited to 'phpBB') 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 -- cgit v1.2.1 From 514bcb2fac1a11a53e20c789ea95be6207c38e80 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 18 Apr 2013 00:50:30 +0200 Subject: [ticket/11495] Move nestedset default values to new method PHPBB3-11495 --- phpBB/includes/nestedset/base.php | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) (limited to 'phpBB') 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 */ -- cgit v1.2.1 From a183fc1118b5ec3b1654ab4fda9c56fa1144e4ce Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 18 Apr 2013 00:54:26 +0200 Subject: [ticket/11495] Manually specify the table columns PHPBB3-11495 --- phpBB/includes/nestedset/base.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'phpBB') 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 '; -- cgit v1.2.1 From 153b29c6c9dad621e03bf2296a93306c30ea23f0 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 18 Apr 2013 19:31:08 +0200 Subject: [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(-) (limited to 'phpBB') 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 -- cgit v1.2.1 From b28180be1d911364e5c00e3e97e8dac9be6f3d6f Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 18 Apr 2013 22:16:14 +0200 Subject: [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(-) (limited to 'phpBB') 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; } } -- cgit v1.2.1 From 5cb7342dd3b7abd2366abbdb7c0ba11d3d27f922 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 18 Apr 2013 22:17:05 +0200 Subject: [ticket/11495] Remove acquire locks from forum implementation PHPBB3-11495 --- phpBB/includes/nestedset/forum.php | 65 ++------------------------------------ 1 file changed, 2 insertions(+), 63 deletions(-) (limited to 'phpBB') 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; - } } -- cgit v1.2.1 From f3ff8b36be01bf6414268d9dca0500b6c7d4f47f Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 19 Apr 2013 01:14:38 +0200 Subject: [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(-) (limited to 'phpBB') 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_'; -- cgit v1.2.1 From d24ff2329fe145864712cb37ec19183bd4e21a42 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 19 Apr 2013 16:18:03 +0200 Subject: [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 +++--- 2 files changed, 9 insertions(+), 16 deletions(-) (limited to 'phpBB') 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 */ -- cgit v1.2.1 From 3d54a81ed9394f13aff4c40d524ed7cff0546604 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 19 Apr 2013 16:19:01 +0200 Subject: [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 ++++++------ 2 files changed, 13 insertions(+), 12 deletions(-) (limited to 'phpBB') 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 -- cgit v1.2.1 From f66b5323a75db084686d9a16c7090b15c5c13e54 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 19 Apr 2013 19:09:22 +0200 Subject: [ticket/11495] Cast some values to int PHPBB3-11495 --- phpBB/includes/nestedset/base.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'phpBB') 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 -- cgit v1.2.1 From 87dc3b1e55bcfcade98eedfaa07e77c454dd7d4f Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 19 Apr 2013 21:07:42 +0200 Subject: [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 +++++----- 2 files changed, 90 insertions(+), 31 deletions(-) (limited to 'phpBB') 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'); + } + + $current_parent = $item_data[$current_parent_id]; + unset($item_data[$current_parent_id]); + $move_items = array_keys($item_data); - if (in_array($new_parent[$this->column_item_id], $move_items)) + 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'); + } + + $item = $item_data[$item_id]; + $move_items = array_keys($item_data); - if (in_array($new_parent[$this->column_item_id], $move_items)) + 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 -- cgit v1.2.1 From e8b192fa32a4e7bba6d772075eb430424d0c4750 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 25 Apr 2013 12:57:21 +0200 Subject: [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(-) (limited to 'phpBB') 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 -- cgit v1.2.1 From 61e72d3a1000c48146466305c6693595324f5282 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 25 Apr 2013 13:09:00 +0200 Subject: [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(+) (limited to 'phpBB') 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 -- cgit v1.2.1 From 4bff28a0eeaf44eae9e99725ead6ff2cf770b857 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 25 Apr 2013 13:40:25 +0200 Subject: [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 ++++++++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) (limited to 'phpBB') 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); } -- cgit v1.2.1 From 3efae6d8af6dfe22c0790d3004fdbf20eb16a292 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 25 Apr 2013 13:44:52 +0200 Subject: [ticket/11495] Explain whether move_children prepends/appends/overwrittes PHPBB3-11495 --- phpBB/includes/nestedset/interface.php | 3 +++ 1 file changed, 3 insertions(+) (limited to 'phpBB') 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 -- cgit v1.2.1 From ab7054445fbf397ae5bf4c13eb44a2019d71cc2d Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 25 Apr 2013 13:48:19 +0200 Subject: [ticket/11495] Rename set_parent to change_parent() PHPBB3-11495 --- phpBB/includes/nestedset/base.php | 2 +- phpBB/includes/nestedset/interface.php | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'phpBB') 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 -- cgit v1.2.1 From fe97915fc91e4fbfb211e3eb6038dd1b482553dd Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 25 Apr 2013 14:05:41 +0200 Subject: [ticket/11495] Split get_branch_data into multiple methods PHPBB3-11495 --- phpBB/includes/nestedset/base.php | 56 +++++++++++++++++++++++----------- phpBB/includes/nestedset/interface.php | 27 +++++++++++++--- 2 files changed, 62 insertions(+), 21 deletions(-) (limited to 'phpBB') 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/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_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 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($item_id, $type, $order_desc, $include_item); + 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 -- cgit v1.2.1 From 9d7d962c0db3425e9448eb07649c6709664a56bd Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 25 Apr 2013 14:08:06 +0200 Subject: [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(-) (limited to 'phpBB') 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 */ -- cgit v1.2.1 From 804f139be0534691fc1c8f6ddaf7ebc68a7d0a1c Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 25 Apr 2013 16:17:58 +0200 Subject: [ticket/11495] Use default exceptions PHPBB3-11495 --- phpBB/includes/nestedset/base.php | 28 ++++++++++++++-------------- phpBB/includes/nestedset/exception.php | 20 -------------------- 2 files changed, 14 insertions(+), 34 deletions(-) delete mode 100644 phpBB/includes/nestedset/exception.php (limited to 'phpBB') 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: [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(-) (limited to 'phpBB') 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 */ -- cgit v1.2.1 From b334a2ce0fe3ae196da9686028667c430eb411d1 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 25 Apr 2013 17:04:37 +0200 Subject: [ticket/11495] Move classes to tree/ as they all implement a tree PHPBB3-11495 --- phpBB/includes/nestedset/base.php | 766 -------------------------------- phpBB/includes/nestedset/forum.php | 52 --- phpBB/includes/nestedset/interface.php | 171 ------- phpBB/includes/tree/interface.php | 171 +++++++ phpBB/includes/tree/nestedset.php | 766 ++++++++++++++++++++++++++++++++ phpBB/includes/tree/nestedset_forum.php | 52 +++ 6 files changed, 989 insertions(+), 989 deletions(-) delete mode 100644 phpBB/includes/nestedset/base.php delete mode 100644 phpBB/includes/nestedset/forum.php delete mode 100644 phpBB/includes/nestedset/interface.php create mode 100644 phpBB/includes/tree/interface.php create mode 100644 phpBB/includes/tree/nestedset.php create mode 100644 phpBB/includes/tree/nestedset_forum.php (limited to 'phpBB') diff --git a/phpBB/includes/nestedset/base.php b/phpBB/includes/nestedset/base.php deleted file mode 100644 index cb06a0dabe..0000000000 --- a/phpBB/includes/nestedset/base.php +++ /dev/null @@ -1,766 +0,0 @@ -sql_where) ? '' : $operator . ' ' . sprintf($this->sql_where, $column_prefix); - } - - /** - * @inheritdoc - */ - public function insert(array $additional_data) - { - $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); - - $item_data[$this->column_item_id] = (int) $this->db->sql_nextid(); - - return array_merge($item_data, $this->add($item_data)); - } - - /** - * @inheritdoc - */ - public function add(array $item) - { - $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->column_right_id); - $this->db->sql_freeresult($result); - - $update_item_data = array( - $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->column_item_id . ' = ' . (int) $item[$this->column_item_id]; - $this->db->sql_query($sql); - - return $update_item_data; - } - - /** - * @inheritdoc - */ - public function remove($item_id) - { - $items = $this->get_children_branch_data($item_id); - $item_ids = array_keys($items); - - $this->remove_subset($item_ids, $items[$item_id]); - - return $item_ids; - } - - /** - * @inheritdoc - */ - public function delete($item_id) - { - $removed_items = $this->remove($item_id); - - $sql = 'DELETE FROM ' . $this->table_name . ' - WHERE ' . $this->db->sql_in_set($this->column_item_id, $removed_items) . ' - ' . $this->get_sql_where('AND'); - $this->db->sql_query($sql); - - return $removed_items; - } - - /** - * @inheritdoc - */ - public function move($item_id, $delta) - { - if ($delta == 0) - { - return false; - } - - if (!$this->lock->acquire()) - { - throw new RuntimeException($this->message_prefix . 'LOCK_FAILED_ACQUIRE'); - } - - $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 OutOfBoundsException($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 - * siblings between the current spot and the target then the - * item will move as far as possible - */ - $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 '; - - if ($action == 'move_up') - { - $sql .= $this->column_right_id . ' < ' . (int) $item[$this->column_right_id] . ' ORDER BY ' . $this->column_right_id . ' DESC'; - } - else - { - $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); - - $target = false; - while ($row = $this->db->sql_fetchrow($result)) - { - $target = $row; - } - $this->db->sql_freeresult($result); - - if (!$target) - { - $this->lock->release(); - // 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 = (int) $target[$this->column_left_id]; - $right_id = (int) $item[$this->column_right_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]; - $move_up_right = (int) $item[$this->column_right_id]; - } - else - { - $left_id = (int) $item[$this->column_left_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 = (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 = (int) $target[$this->column_right_id]; - } - - // Now do the dirty job - $sql = 'UPDATE ' . $this->table_name . ' - 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->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 . " = '' - WHERE - " . $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); - - $this->lock->release(); - - return true; - } - - /** - * @inheritdoc - */ - public function move_down($item_id) - { - return $this->move($item_id, -1); - } - - /** - * @inheritdoc - */ - public function move_up($item_id) - { - return $this->move($item_id, 1); - } - - /** - * @inheritdoc - */ - public function move_children($current_parent_id, $new_parent_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 OutOfBoundsException($this->message_prefix . 'INVALID_ITEM'); - } - - if (!$this->lock->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 OutOfBoundsException($this->message_prefix . 'INVALID_ITEM'); - } - - $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 OutOfBoundsException($this->message_prefix . 'INVALID_PARENT'); - } - - $diff = sizeof($move_items) * 2; - $sql_exclude_moved_items = $this->db->sql_in_set($this->column_item_id, $move_items, true); - - $this->db->sql_transaction('begin'); - - $this->remove_subset($move_items, $current_parent, false, true); - - if ($new_parent_id) - { - // Retrieve new-parent again, it may have been changed... - $sql = 'SELECT * - FROM ' . $this->table_name . ' - 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); - - if (!$new_parent) - { - $this->db->sql_transaction('rollback'); - $this->lock->release(); - throw new OutOfBoundsException($this->message_prefix . 'INVALID_PARENT'); - } - - $new_right_id = $this->prepare_adding_subset($move_items, $new_parent, true); - - if ($new_right_id > $current_parent[$this->column_right_id]) - { - $diff = ' + ' . ($new_right_id - $current_parent[$this->column_right_id]); - } - else - { - $diff = ' - ' . abs($new_right_id - $current_parent[$this->column_right_id]); - } - } - else - { - $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'); - $result = $this->db->sql_query($sql); - $row = $this->db->sql_fetchrow($result); - $this->db->sql_freeresult($result); - - $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_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'); - $this->db->sql_query($sql); - - $this->db->sql_transaction('commit'); - $this->lock->release(); - - return true; - } - - /** - * @inheritdoc - */ - public function change_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 OutOfBoundsException($this->message_prefix . 'INVALID_ITEM'); - } - - if (!$this->lock->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 OutOfBoundsException($this->message_prefix . 'INVALID_ITEM'); - } - - $item = $item_data[$item_id]; - $move_items = array_keys($item_data); - - if (in_array($new_parent_id, $move_items)) - { - $this->lock->release(); - throw new OutOfBoundsException($this->message_prefix . 'INVALID_PARENT'); - } - - $diff = sizeof($move_items) * 2; - $sql_exclude_moved_items = $this->db->sql_in_set($this->column_item_id, $move_items, true); - - $this->db->sql_transaction('begin'); - - $this->remove_subset($move_items, $item, false, true); - - if ($new_parent_id) - { - // Retrieve new-parent again, it may have been changed... - $sql = 'SELECT * - FROM ' . $this->table_name . ' - 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); - - if (!$new_parent) - { - $this->db->sql_transaction('rollback'); - $this->lock->release(); - throw new OutOfBoundsException($this->message_prefix . 'INVALID_PARENT'); - } - - $new_right_id = $this->prepare_adding_subset($move_items, $new_parent, true); - - if ($new_right_id > (int) $item[$this->column_right_id]) - { - $diff = ' + ' . ($new_right_id - (int) $item[$this->column_right_id] - 1); - } - else - { - $diff = ' - ' . abs($new_right_id - (int) $item[$this->column_right_id] - 1); - } - } - else - { - $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'); - $result = $this->db->sql_query($sql); - $row = $this->db->sql_fetchrow($result); - $this->db->sql_freeresult($result); - - $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_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'); - $this->db->sql_query($sql); - - $this->db->sql_transaction('commit'); - $this->lock->release(); - - return true; - } - - /** - * @inheritdoc - */ - public function get_full_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 . ' - 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); - } - - /** - * @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 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) - { - $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->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_id == $row[$this->column_item_id]) - { - continue; - } - - $rows[(int) $row[$this->column_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(array $item) - { - $parents = array(); - if ((int) $item[$this->column_parent_id]) - { - if (!$item[$this->column_item_parents]) - { - $sql = 'SELECT ' . implode(', ', $this->item_basic_data) . ' - FROM ' . $this->table_name . ' - 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); - - while ($row = $this->db->sql_fetchrow($result)) - { - $parents[$row[$this->column_item_id]] = $row; - } - $this->db->sql_freeresult($result); - - $item_parents = serialize($parents); - - $sql = 'UPDATE ' . $this->table_name . ' - SET ' . $this->column_item_parents . " = '" . $this->db->sql_escape($item_parents) . "' - WHERE " . $this->column_parent_id . ' = ' . (int) $item[$this->column_parent_id]; - $this->db->sql_query($sql); - } - else - { - $parents = unserialize($item[$this->column_item_parents]); - } - } - - return $parents; - } - - /** - * 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 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) - { - if (!$table_already_locked && !$this->lock->acquire()) - { - throw new RuntimeException($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); - - $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 . ' > ' . (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); - - 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->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); - - if (!$table_already_locked) - { - $this->lock->release(); - } - } - - /** - * Add 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 - * @return int New right id of the parent item - */ - 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 . ' > ' . (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 . ', - ' . $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); - - 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 - */ - public function regenerate_left_right_ids($new_id, $parent_id = 0, $reset_ids = false) - { - 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, - $this->column_right_id => 0, - $this->column_item_parents => '', - )) . ' - ' . $this->get_sql_where('WHERE'); - $this->db->sql_query($sql); - } - - $sql = 'SELECT * - FROM ' . $this->table_name . ' - WHERE ' . $this->column_parent_id . ' = ' . (int) $parent_id . ' - ' . $this->get_sql_where('AND') . ' - 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->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 => '', - )) . ' - WHERE ' . $this->column_item_id . ' = ' . (int) $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->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) - { - $sql = 'UPDATE ' . $this->table_name . ' - SET ' . $this->db->sql_build_array('UPDATE', array($this->column_right_id => $new_id)) . ' - WHERE ' . $this->column_item_id . ' = ' . (int) $row[$this->column_item_id]; - $this->db->sql_query($sql); - } - $new_id++; - } - $this->db->sql_freeresult($result); - - - if ($reset_ids) - { - $this->db->sql_transaction('commit'); - $this->lock->release(); - } - - return $new_id; - } -} diff --git a/phpBB/includes/nestedset/forum.php b/phpBB/includes/nestedset/forum.php deleted file mode 100644 index dbf0e70202..0000000000 --- a/phpBB/includes/nestedset/forum.php +++ /dev/null @@ -1,52 +0,0 @@ -db = $db; - $this->lock = $lock; - $this->table_name = $table_name; - } -} diff --git a/phpBB/includes/nestedset/interface.php b/phpBB/includes/nestedset/interface.php deleted file mode 100644 index eadc9083b1..0000000000 --- a/phpBB/includes/nestedset/interface.php +++ /dev/null @@ -1,171 +0,0 @@ - down, > 0 => up - * @return bool True if the item was moved - */ - public function move($item_id, $delta); - - /** - * Move an item down by 1 - * - * @param int $item_id The item to be moved - * @return bool True if the item was moved - */ - public function move_down($item_id); - - /** - * Move an item up by 1 - * - * @param int $item_id The item to be moved - * @return bool True if the item was moved - */ - public function move_up($item_id); - - /** - * 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 - */ - public function move_children($current_parent_id, $new_parent_id); - - /** - * 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 change_parent($item, $new_parent_id); - - /** - * Get children and parent branch 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 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_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 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_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 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_children_branch_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); - - /** - * 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/interface.php b/phpBB/includes/tree/interface.php new file mode 100644 index 0000000000..fd10bd357f --- /dev/null +++ b/phpBB/includes/tree/interface.php @@ -0,0 +1,171 @@ + down, > 0 => up + * @return bool True if the item was moved + */ + public function move($item_id, $delta); + + /** + * Move an item down by 1 + * + * @param int $item_id The item to be moved + * @return bool True if the item was moved + */ + public function move_down($item_id); + + /** + * Move an item up by 1 + * + * @param int $item_id The item to be moved + * @return bool True if the item was moved + */ + public function move_up($item_id); + + /** + * 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 + */ + public function move_children($current_parent_id, $new_parent_id); + + /** + * 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 change_parent($item, $new_parent_id); + + /** + * Get children and parent branch 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 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_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 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_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 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_children_branch_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); + + /** + * 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 new file mode 100644 index 0000000000..2110e1a6d2 --- /dev/null +++ b/phpBB/includes/tree/nestedset.php @@ -0,0 +1,766 @@ +sql_where) ? '' : $operator . ' ' . sprintf($this->sql_where, $column_prefix); + } + + /** + * @inheritdoc + */ + public function insert(array $additional_data) + { + $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); + + $item_data[$this->column_item_id] = (int) $this->db->sql_nextid(); + + return array_merge($item_data, $this->add($item_data)); + } + + /** + * @inheritdoc + */ + public function add(array $item) + { + $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->column_right_id); + $this->db->sql_freeresult($result); + + $update_item_data = array( + $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->column_item_id . ' = ' . (int) $item[$this->column_item_id]; + $this->db->sql_query($sql); + + return $update_item_data; + } + + /** + * @inheritdoc + */ + public function remove($item_id) + { + $items = $this->get_children_branch_data($item_id); + $item_ids = array_keys($items); + + $this->remove_subset($item_ids, $items[$item_id]); + + return $item_ids; + } + + /** + * @inheritdoc + */ + public function delete($item_id) + { + $removed_items = $this->remove($item_id); + + $sql = 'DELETE FROM ' . $this->table_name . ' + WHERE ' . $this->db->sql_in_set($this->column_item_id, $removed_items) . ' + ' . $this->get_sql_where('AND'); + $this->db->sql_query($sql); + + return $removed_items; + } + + /** + * @inheritdoc + */ + public function move($item_id, $delta) + { + if ($delta == 0) + { + return false; + } + + if (!$this->lock->acquire()) + { + throw new RuntimeException($this->message_prefix . 'LOCK_FAILED_ACQUIRE'); + } + + $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 OutOfBoundsException($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 + * siblings between the current spot and the target then the + * item will move as far as possible + */ + $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 '; + + if ($action == 'move_up') + { + $sql .= $this->column_right_id . ' < ' . (int) $item[$this->column_right_id] . ' ORDER BY ' . $this->column_right_id . ' DESC'; + } + else + { + $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); + + $target = false; + while ($row = $this->db->sql_fetchrow($result)) + { + $target = $row; + } + $this->db->sql_freeresult($result); + + if (!$target) + { + $this->lock->release(); + // 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 = (int) $target[$this->column_left_id]; + $right_id = (int) $item[$this->column_right_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]; + $move_up_right = (int) $item[$this->column_right_id]; + } + else + { + $left_id = (int) $item[$this->column_left_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 = (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 = (int) $target[$this->column_right_id]; + } + + // Now do the dirty job + $sql = 'UPDATE ' . $this->table_name . ' + 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->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 . " = '' + WHERE + " . $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); + + $this->lock->release(); + + return true; + } + + /** + * @inheritdoc + */ + public function move_down($item_id) + { + return $this->move($item_id, -1); + } + + /** + * @inheritdoc + */ + public function move_up($item_id) + { + return $this->move($item_id, 1); + } + + /** + * @inheritdoc + */ + public function move_children($current_parent_id, $new_parent_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 OutOfBoundsException($this->message_prefix . 'INVALID_ITEM'); + } + + if (!$this->lock->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 OutOfBoundsException($this->message_prefix . 'INVALID_ITEM'); + } + + $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 OutOfBoundsException($this->message_prefix . 'INVALID_PARENT'); + } + + $diff = sizeof($move_items) * 2; + $sql_exclude_moved_items = $this->db->sql_in_set($this->column_item_id, $move_items, true); + + $this->db->sql_transaction('begin'); + + $this->remove_subset($move_items, $current_parent, false, true); + + if ($new_parent_id) + { + // Retrieve new-parent again, it may have been changed... + $sql = 'SELECT * + FROM ' . $this->table_name . ' + 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); + + if (!$new_parent) + { + $this->db->sql_transaction('rollback'); + $this->lock->release(); + throw new OutOfBoundsException($this->message_prefix . 'INVALID_PARENT'); + } + + $new_right_id = $this->prepare_adding_subset($move_items, $new_parent, true); + + if ($new_right_id > $current_parent[$this->column_right_id]) + { + $diff = ' + ' . ($new_right_id - $current_parent[$this->column_right_id]); + } + else + { + $diff = ' - ' . abs($new_right_id - $current_parent[$this->column_right_id]); + } + } + else + { + $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'); + $result = $this->db->sql_query($sql); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + $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_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'); + $this->db->sql_query($sql); + + $this->db->sql_transaction('commit'); + $this->lock->release(); + + return true; + } + + /** + * @inheritdoc + */ + public function change_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 OutOfBoundsException($this->message_prefix . 'INVALID_ITEM'); + } + + if (!$this->lock->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 OutOfBoundsException($this->message_prefix . 'INVALID_ITEM'); + } + + $item = $item_data[$item_id]; + $move_items = array_keys($item_data); + + if (in_array($new_parent_id, $move_items)) + { + $this->lock->release(); + throw new OutOfBoundsException($this->message_prefix . 'INVALID_PARENT'); + } + + $diff = sizeof($move_items) * 2; + $sql_exclude_moved_items = $this->db->sql_in_set($this->column_item_id, $move_items, true); + + $this->db->sql_transaction('begin'); + + $this->remove_subset($move_items, $item, false, true); + + if ($new_parent_id) + { + // Retrieve new-parent again, it may have been changed... + $sql = 'SELECT * + FROM ' . $this->table_name . ' + 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); + + if (!$new_parent) + { + $this->db->sql_transaction('rollback'); + $this->lock->release(); + throw new OutOfBoundsException($this->message_prefix . 'INVALID_PARENT'); + } + + $new_right_id = $this->prepare_adding_subset($move_items, $new_parent, true); + + if ($new_right_id > (int) $item[$this->column_right_id]) + { + $diff = ' + ' . ($new_right_id - (int) $item[$this->column_right_id] - 1); + } + else + { + $diff = ' - ' . abs($new_right_id - (int) $item[$this->column_right_id] - 1); + } + } + else + { + $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'); + $result = $this->db->sql_query($sql); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + $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_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'); + $this->db->sql_query($sql); + + $this->db->sql_transaction('commit'); + $this->lock->release(); + + return true; + } + + /** + * @inheritdoc + */ + public function get_full_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 . ' + 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); + } + + /** + * @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 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) + { + $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->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_id == $row[$this->column_item_id]) + { + continue; + } + + $rows[(int) $row[$this->column_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(array $item) + { + $parents = array(); + if ((int) $item[$this->column_parent_id]) + { + if (!$item[$this->column_item_parents]) + { + $sql = 'SELECT ' . implode(', ', $this->item_basic_data) . ' + FROM ' . $this->table_name . ' + 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); + + while ($row = $this->db->sql_fetchrow($result)) + { + $parents[$row[$this->column_item_id]] = $row; + } + $this->db->sql_freeresult($result); + + $item_parents = serialize($parents); + + $sql = 'UPDATE ' . $this->table_name . ' + SET ' . $this->column_item_parents . " = '" . $this->db->sql_escape($item_parents) . "' + WHERE " . $this->column_parent_id . ' = ' . (int) $item[$this->column_parent_id]; + $this->db->sql_query($sql); + } + else + { + $parents = unserialize($item[$this->column_item_parents]); + } + } + + return $parents; + } + + /** + * 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 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) + { + if (!$table_already_locked && !$this->lock->acquire()) + { + throw new RuntimeException($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); + + $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 . ' > ' . (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); + + 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->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); + + if (!$table_already_locked) + { + $this->lock->release(); + } + } + + /** + * Add 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 + * @return int New right id of the parent item + */ + 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 . ' > ' . (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 . ', + ' . $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); + + 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 + */ + public function regenerate_left_right_ids($new_id, $parent_id = 0, $reset_ids = false) + { + 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, + $this->column_right_id => 0, + $this->column_item_parents => '', + )) . ' + ' . $this->get_sql_where('WHERE'); + $this->db->sql_query($sql); + } + + $sql = 'SELECT * + FROM ' . $this->table_name . ' + WHERE ' . $this->column_parent_id . ' = ' . (int) $parent_id . ' + ' . $this->get_sql_where('AND') . ' + 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->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 => '', + )) . ' + WHERE ' . $this->column_item_id . ' = ' . (int) $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->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) + { + $sql = 'UPDATE ' . $this->table_name . ' + SET ' . $this->db->sql_build_array('UPDATE', array($this->column_right_id => $new_id)) . ' + WHERE ' . $this->column_item_id . ' = ' . (int) $row[$this->column_item_id]; + $this->db->sql_query($sql); + } + $new_id++; + } + $this->db->sql_freeresult($result); + + + if ($reset_ids) + { + $this->db->sql_transaction('commit'); + $this->lock->release(); + } + + return $new_id; + } +} diff --git a/phpBB/includes/tree/nestedset_forum.php b/phpBB/includes/tree/nestedset_forum.php new file mode 100644 index 0000000000..0a66e68915 --- /dev/null +++ b/phpBB/includes/tree/nestedset_forum.php @@ -0,0 +1,52 @@ +db = $db; + $this->lock = $lock; + $this->table_name = $table_name; + } +} -- cgit v1.2.1 From 5de14b940e71941853d3bb279779631ae75b9b6f Mon Sep 17 00:00:00 2001 From: Dhruv Date: Sat, 26 Jan 2013 00:22:56 +0530 Subject: [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(+) (limited to 'phpBB') 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', -- cgit v1.2.1 From c6e9bd13a75441e9b35a1bfa5d2a08cc38ff1fa5 Mon Sep 17 00:00:00 2001 From: Dhruv Date: Sat, 26 Jan 2013 01:01:57 +0530 Subject: [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(+) (limited to 'phpBB') 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', -- cgit v1.2.1 From 73d873548400f18b02167ef49195a50a11970c24 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 25 Apr 2013 17:19:52 +0200 Subject: [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(-) (limited to 'phpBB') 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) { -- cgit v1.2.1 From abfb7bc51fa254edd6274e39625eb8a4edec32be Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 25 Apr 2013 17:24:18 +0200 Subject: [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(-) (limited to 'phpBB') 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); -- cgit v1.2.1 From 2dbe3b3c975d61b84310f7da27b8d525a22d1723 Mon Sep 17 00:00:00 2001 From: Dhruv Date: Sat, 26 Jan 2013 01:09:30 +0530 Subject: [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(+) (limited to 'phpBB') 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'); -- cgit v1.2.1 From f8012cc239d8b442e78bbbb8a5cc5856d2a714a0 Mon Sep 17 00:00:00 2001 From: Dhruv Date: Sat, 26 Jan 2013 11:10:17 +0530 Subject: [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(-) (limited to 'phpBB') 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', -- cgit v1.2.1 From 1a51abcca293b0e2bd836af0dcb9d77054c1d401 Mon Sep 17 00:00:00 2001 From: Dhruv Date: Sun, 27 Jan 2013 03:07:52 +0530 Subject: [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(-) (limited to 'phpBB') 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', -- cgit v1.2.1 From f1e615c4297a509325b764e1966118fe171ebbb5 Mon Sep 17 00:00:00 2001 From: Dhruv Date: Sun, 27 Jan 2013 03:09:52 +0530 Subject: [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(-) (limited to 'phpBB') 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', -- cgit v1.2.1 From c048067bbd45b51595cc243cc4edde1d84eda405 Mon Sep 17 00:00:00 2001 From: Dhruv Date: Sun, 27 Jan 2013 11:27:28 +0530 Subject: [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(-) (limited to 'phpBB') 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', -- cgit v1.2.1 From 419aaa402f025d16e8b823586e32917d1d036599 Mon Sep 17 00:00:00 2001 From: Dhruv Date: Mon, 28 Jan 2013 01:05:04 +0530 Subject: [ticket/10325] improve acp option language PHPBB3-10325 --- phpBB/language/en/acp/board.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB') 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', -- cgit v1.2.1 From d242b7a1a5c9b6ecc8bc21027a33bc344501a0ce Mon Sep 17 00:00:00 2001 From: Dhruv Date: Thu, 25 Apr 2013 21:05:02 +0530 Subject: [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(-) (limited to 'phpBB') 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', -- cgit v1.2.1 From 0def8b7d9cb06cd2abf462f18f1404fc119861bd Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 25 Apr 2013 18:09:21 +0200 Subject: [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(-) (limited to 'phpBB') 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', + ) + ); } } -- cgit v1.2.1 From baff4287e5a7142b7af41e56c29b064bb56fd7fb Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 25 Apr 2013 22:39:24 +0200 Subject: [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 +- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'phpBB') 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: [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(-) (limited to 'phpBB') 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) . ' -- cgit v1.2.1 From 2afa6730232cc2e92ae6543852d031a29c8a361f Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 26 Apr 2013 08:42:44 +0200 Subject: [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(-) (limited to 'phpBB') 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 -- cgit v1.2.1 From cb13add269b78e1a9ac84a80c78557bb7695df09 Mon Sep 17 00:00:00 2001 From: marc1706 Date: Sun, 28 Apr 2013 22:54:48 +0200 Subject: [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(-) (limited to 'phpBB') 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}

-   +  
-- cgit v1.2.1 From 198b992dcef0a0a7099eb3db6185d567b58b6e5a Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Sun, 28 Apr 2013 22:53:05 -0500 Subject: [ticket/11413] Schema changes and migration file Notifications tables are dropped because phpBB currently does not have any way to make the necessary changes to the DB schema (and no release has yet been made with these changes). This will fix the following bugs: PHPBB3-11411 PHPBB3-11413 PHPBB3-11414 PHPBB3-11416 PHPBB3-11420 PHPBB3-11413 --- phpBB/develop/create_schema_files.php | 26 +-- .../db/migration/data/310/notifications.php | 64 ------- .../db/migration/data/310/notifications2.php | 206 +++++++++++++++++++++ phpBB/install/schemas/firebird_schema.sql | 23 ++- phpBB/install/schemas/mssql_schema.sql | 15 +- phpBB/install/schemas/mysql_40_schema.sql | 14 +- phpBB/install/schemas/mysql_41_schema.sql | 14 +- phpBB/install/schemas/oracle_schema.sql | 30 ++- phpBB/install/schemas/postgres_schema.sql | 14 +- phpBB/install/schemas/sqlite_schema.sql | 13 +- 10 files changed, 304 insertions(+), 115 deletions(-) create mode 100644 phpBB/includes/db/migration/data/310/notifications2.php (limited to 'phpBB') diff --git a/phpBB/develop/create_schema_files.php b/phpBB/develop/create_schema_files.php index b454fb2c16..3121db391d 100644 --- a/phpBB/develop/create_schema_files.php +++ b/phpBB/develop/create_schema_files.php @@ -1317,16 +1317,20 @@ function get_schema_struct() $schema_data['phpbb_notification_types'] = array( 'COLUMNS' => array( - 'notification_type' => array('VCHAR:255', ''), + 'notification_type_id' => array('USINT', NULL, 'auto_increment'), + 'notification_type_name' => array('VCHAR:255', ''), 'notification_type_enabled' => array('BOOL', 1), ), - 'PRIMARY_KEY' => array('notification_type', 'notification_type_enabled'), + 'PRIMARY_KEY' => array('notification_type_id'), + 'KEYS' => array( + 'type' => array('UNIQUE', array('notification_type_name')), + ), ); $schema_data['phpbb_notifications'] = array( 'COLUMNS' => array( - 'notification_id' => array('UINT', NULL, 'auto_increment'), - 'item_type' => array('VCHAR:255', ''), + 'notification_id' => array('UINT:10', NULL, 'auto_increment'), + 'notification_type_id' => array('USINT', 0), 'item_id' => array('UINT', 0), 'item_parent_id' => array('UINT', 0), 'user_id' => array('UINT', 0), @@ -1336,7 +1340,7 @@ function get_schema_struct() ), 'PRIMARY_KEY' => 'notification_id', 'KEYS' => array( - 'item_ident' => array('INDEX', array('item_type', 'item_id')), + 'item_ident' => array('INDEX', array('notification_type_id', 'item_id')), 'user' => array('INDEX', array('user_id', 'notification_read')), ), ); @@ -1814,12 +1818,12 @@ function get_schema_struct() ); $schema_data['phpbb_user_notifications'] = array( - 'COLUMNS' => array( - 'item_type' => array('VCHAR:255', ''), - 'item_id' => array('UINT', 0), - 'user_id' => array('UINT', 0), - 'method' => array('VCHAR:255', ''), - 'notify' => array('BOOL', 1), + 'COLUMNS' => array( + 'notification_type_id' => array('USINT', 0), + 'item_id' => array('UINT', 0), + 'user_id' => array('UINT', 0), + 'method' => array('VCHAR:255', ''), + 'notify' => array('BOOL', 1), ), ); diff --git a/phpBB/includes/db/migration/data/310/notifications.php b/phpBB/includes/db/migration/data/310/notifications.php index 82bfd4cb2d..17c939d95a 100644 --- a/phpBB/includes/db/migration/data/310/notifications.php +++ b/phpBB/includes/db/migration/data/310/notifications.php @@ -91,70 +91,6 @@ class phpbb_db_migration_data_310_notifications extends phpbb_db_migration ), )), array('config.add', array('load_notifications', 1)), - array('custom', array(array($this, 'convert_notifications'))), ); } - - public function convert_notifications() - { - $convert_notifications = array( - array( - 'check' => ($this->config['allow_topic_notify']), - 'item_type' => 'post', - ), - array( - 'check' => ($this->config['allow_forum_notify']), - 'item_type' => 'topic', - ), - array( - 'check' => ($this->config['allow_bookmarks']), - 'item_type' => 'bookmark', - ), - array( - 'check' => ($this->config['allow_privmsg']), - 'item_type' => 'pm', - ), - ); - - foreach ($convert_notifications as $convert_data) - { - if ($convert_data['check']) - { - $sql = 'SELECT user_id, user_notify_type - FROM ' . USERS_TABLE . ' - WHERE user_notify = 1'; - $result = $this->db->sql_query($sql); - while ($row = $this->db->sql_fetchrow($result)) - { - $this->sql_query('INSERT INTO ' . $this->table_prefix . 'user_notifications ' . $this->db->sql_build_array('INSERT', array( - 'item_type' => $convert_data['item_type'], - 'item_id' => 0, - 'user_id' => $row['user_id'], - 'method' => '', - ))); - - if ($row['user_notify_type'] == NOTIFY_EMAIL || $row['user_notify_type'] == NOTIFY_BOTH) - { - $this->sql_query('INSERT INTO ' . $this->table_prefix . 'user_notifications ' . $this->db->sql_build_array('INSERT', array( - 'item_type' => $convert_data['item_type'], - 'item_id' => 0, - 'user_id' => $row['user_id'], - 'method' => 'email', - ))); - } - - if ($row['user_notify_type'] == NOTIFY_IM || $row['user_notify_type'] == NOTIFY_BOTH) - { - $this->sql_query('INSERT INTO ' . $this->table_prefix . 'user_notifications ' . $this->db->sql_build_array('INSERT', array( - 'item_type' => $convert_data['item_type'], - 'item_id' => 0, - 'user_id' => $row['user_id'], - 'method' => 'jabber', - ))); - } - } - $this->db->sql_freeresult($result); - } - } - } } diff --git a/phpBB/includes/db/migration/data/310/notifications2.php b/phpBB/includes/db/migration/data/310/notifications2.php new file mode 100644 index 0000000000..a3f29b073a --- /dev/null +++ b/phpBB/includes/db/migration/data/310/notifications2.php @@ -0,0 +1,206 @@ + array( + $this->table_prefix . 'notification_types', + $this->table_prefix . 'notifications', + $this->table_prefix . 'user_notifications', + ), + 'add_tables' => array( + $this->table_prefix . 'notification_types' => array( + 'COLUMNS' => array( + 'notification_type_id' => array('USINT', NULL, 'auto_increment'), + 'notification_type_name' => array('VCHAR:255', ''), + 'notification_type_enabled' => array('BOOL', 1), + ), + 'PRIMARY_KEY' => array('notification_type_id'), + 'KEYS' => array( + 'type' => array('UNIQUE', array('notification_type_name')), + ), + ), + $this->table_prefix . 'notifications' => array( + 'COLUMNS' => array( + 'notification_id' => array('UINT:10', NULL, 'auto_increment'), + 'notification_type_id' => array('USINT', 0), + 'item_id' => array('UINT', 0), + 'item_parent_id' => array('UINT', 0), + 'user_id' => array('UINT', 0), + 'notification_read' => array('BOOL', 0), + 'notification_time' => array('TIMESTAMP', 1), + 'notification_data' => array('TEXT_UNI', ''), + ), + 'PRIMARY_KEY' => 'notification_id', + 'KEYS' => array( + 'item_ident' => array('INDEX', array('notification_type_id', 'item_id')), + 'user' => array('INDEX', array('user_id', 'notification_read')), + ), + ), + $this->table_prefix . 'user_notifications' => array( + 'COLUMNS' => array( + 'notification_type_id' => array('USINT', 0), + 'item_id' => array('UINT', 0), + 'user_id' => array('UINT', 0), + 'method' => array('VCHAR:255', ''), + 'notify' => array('BOOL', 1), + ), + 'PRIMARY_KEY' => array( + 'notification_type_id', + 'item_id', + 'user_id', + ), + ), + ), + ); + } + + public function revert_schema() + { + return array( + 'drop_tables' => array( + $this->table_prefix . 'notification_types', + $this->table_prefix . 'notifications', + $this->table_prefix . 'user_notifications', + ), + 'add_tables' => array( + $this->table_prefix . 'notification_types' => array( + 'COLUMNS' => array( + 'notification_type' => array('VCHAR:255', ''), + 'notification_type_enabled' => array('BOOL', 1), + ), + 'PRIMARY_KEY' => array('notification_type', 'notification_type_enabled'), + ), + $this->table_prefix . 'notifications' => array( + 'COLUMNS' => array( + 'notification_id' => array('UINT', NULL, 'auto_increment'), + 'item_type' => array('VCHAR:255', ''), + 'item_id' => array('UINT', 0), + 'item_parent_id' => array('UINT', 0), + 'user_id' => array('UINT', 0), + 'notification_read' => array('BOOL', 0), + 'notification_time' => array('TIMESTAMP', 1), + 'notification_data' => array('TEXT_UNI', ''), + ), + 'PRIMARY_KEY' => 'notification_id', + 'KEYS' => array( + 'item_ident' => array('INDEX', array('item_type', 'item_id')), + 'user' => array('INDEX', array('user_id', 'notification_read')), + ), + ), + $this->table_prefix . 'user_notifications' => array( + 'COLUMNS' => array( + 'item_type' => array('VCHAR:255', ''), + 'item_id' => array('UINT', 0), + 'user_id' => array('UINT', 0), + 'method' => array('VCHAR:255', ''), + 'notify' => array('BOOL', 1), + ), + ), + ), + ); + } + + public function update_data() + { + return array( + array('custom', array(array($this, 'convert_notifications'))), + ); + } + + public function convert_notifications() + { + $insert_table = $this->table_prefix . 'user_notifications'; + + $sql = 'SELECT user_id, user_notify_type, user_notify_pm + FROM ' . USERS_TABLE; + $result = $this->db->sql_query($sql); + + $sql_insert_data = array(); + while ($row = $this->db->sql_fetchrow($result)) + { + $notification_methods = array(); + + // In-board notification + $notification_methods[] = ''; + + if ($row['user_notify_type'] == NOTIFY_EMAIL || $row['user_notify_type'] == NOTIFY_BOTH) + { + $notification_methods[] = 'email'; + } + + if ($row['user_notify_type'] == NOTIFY_IM || $row['user_notify_type'] == NOTIFY_BOTH) + { + $notification_methods[] = 'jabber'; + } + + // Notifications for posts + foreach (array('post', 'topic') as $item_type) + { + $sql_insert_data = $this->add_method_rows( + $sql_insert_data, + $item_type, + 0, + $row['user_id'], + $notification_methods + ); + } + + if ($row['user_notify_pm']) + { + // Notifications for private messages + // User either gets all methods or no method + $sql_insert_data = $this->add_method_rows( + $sql_insert_data, + 'pm', + 0, + $row['user_id'], + $notification_methods + ); + } + + if (sizeof($sql_insert_data) > 500) + { + $this->db->sql_multi_insert($insert_table, $sql_insert_data); + $sql_insert_data = array(); + } + } + $this->db->sql_freeresult($result); + + if (!empty($sql_insert_data)) + { + $this->db->sql_multi_insert($insert_table, $sql_insert_data); + } + } + + protected function add_method_rows(array $sql_insert_data, $item_type, $item_id, $user_id, array $methods) + { + $row_base = array( + 'item_type' => $item_type, + 'item_id' => (int) $item_id, + 'user_id' => (int) $user_id, + ); + + foreach ($methods as $method) + { + $row_base['method'] = $method; + $sql_insert_data[] = $row_base; + } + + return $sql_insert_data; + } +} diff --git a/phpBB/install/schemas/firebird_schema.sql b/phpBB/install/schemas/firebird_schema.sql index 18ca184c65..92227eb38c 100644 --- a/phpBB/install/schemas/firebird_schema.sql +++ b/phpBB/install/schemas/firebird_schema.sql @@ -642,17 +642,30 @@ END;; # Table: 'phpbb_notification_types' CREATE TABLE phpbb_notification_types ( - notification_type VARCHAR(255) CHARACTER SET NONE DEFAULT '' NOT NULL, + notification_type_id INTEGER NOT NULL, + notification_type_name VARCHAR(255) CHARACTER SET NONE DEFAULT '' NOT NULL, notification_type_enabled INTEGER DEFAULT 1 NOT NULL );; -ALTER TABLE phpbb_notification_types ADD PRIMARY KEY (notification_type, notification_type_enabled);; +ALTER TABLE phpbb_notification_types ADD PRIMARY KEY (notification_type_id);; + +CREATE UNIQUE INDEX phpbb_notification_types_type ON phpbb_notification_types(notification_type_name);; + +CREATE GENERATOR phpbb_notification_types_gen;; +SET GENERATOR phpbb_notification_types_gen TO 0;; + +CREATE TRIGGER t_phpbb_notification_types FOR phpbb_notification_types +BEFORE INSERT +AS +BEGIN + NEW.notification_type_id = GEN_ID(phpbb_notification_types_gen, 1); +END;; # Table: 'phpbb_notifications' CREATE TABLE phpbb_notifications ( notification_id INTEGER NOT NULL, - item_type VARCHAR(255) CHARACTER SET NONE DEFAULT '' NOT NULL, + notification_type_id INTEGER DEFAULT 0 NOT NULL, item_id INTEGER DEFAULT 0 NOT NULL, item_parent_id INTEGER DEFAULT 0 NOT NULL, user_id INTEGER DEFAULT 0 NOT NULL, @@ -663,7 +676,7 @@ CREATE TABLE phpbb_notifications ( ALTER TABLE phpbb_notifications ADD PRIMARY KEY (notification_id);; -CREATE INDEX phpbb_notifications_item_ident ON phpbb_notifications(item_type, item_id);; +CREATE INDEX phpbb_notifications_item_ident ON phpbb_notifications(notification_type_id, item_id);; CREATE INDEX phpbb_notifications_user ON phpbb_notifications(user_id, notification_read);; CREATE GENERATOR phpbb_notifications_gen;; @@ -1290,7 +1303,7 @@ CREATE INDEX phpbb_topics_watch_notify_stat ON phpbb_topics_watch(notify_status) # Table: 'phpbb_user_notifications' CREATE TABLE phpbb_user_notifications ( - item_type VARCHAR(255) CHARACTER SET NONE DEFAULT '' NOT NULL, + notification_type_id INTEGER DEFAULT 0 NOT NULL, item_id INTEGER DEFAULT 0 NOT NULL, user_id INTEGER DEFAULT 0 NOT NULL, method VARCHAR(255) CHARACTER SET NONE DEFAULT '' NOT NULL, diff --git a/phpBB/install/schemas/mssql_schema.sql b/phpBB/install/schemas/mssql_schema.sql index 3530f9cd25..e869cbd1b5 100644 --- a/phpBB/install/schemas/mssql_schema.sql +++ b/phpBB/install/schemas/mssql_schema.sql @@ -793,7 +793,8 @@ GO Table: 'phpbb_notification_types' */ CREATE TABLE [phpbb_notification_types] ( - [notification_type] [varchar] (255) DEFAULT ('') NOT NULL , + [notification_type_id] [int] IDENTITY (1, 1) NOT NULL , + [notification_type_name] [varchar] (255) DEFAULT ('') NOT NULL , [notification_type_enabled] [int] DEFAULT (1) NOT NULL ) ON [PRIMARY] GO @@ -801,18 +802,20 @@ GO ALTER TABLE [phpbb_notification_types] WITH NOCHECK ADD CONSTRAINT [PK_phpbb_notification_types] PRIMARY KEY CLUSTERED ( - [notification_type], - [notification_type_enabled] + [notification_type_id] ) ON [PRIMARY] GO +CREATE UNIQUE INDEX [type] ON [phpbb_notification_types]([notification_type_name]) ON [PRIMARY] +GO + /* Table: 'phpbb_notifications' */ CREATE TABLE [phpbb_notifications] ( [notification_id] [int] IDENTITY (1, 1) NOT NULL , - [item_type] [varchar] (255) DEFAULT ('') NOT NULL , + [notification_type_id] [int] DEFAULT (0) NOT NULL , [item_id] [int] DEFAULT (0) NOT NULL , [item_parent_id] [int] DEFAULT (0) NOT NULL , [user_id] [int] DEFAULT (0) NOT NULL , @@ -829,7 +832,7 @@ ALTER TABLE [phpbb_notifications] WITH NOCHECK ADD ) ON [PRIMARY] GO -CREATE INDEX [item_ident] ON [phpbb_notifications]([item_type], [item_id]) ON [PRIMARY] +CREATE INDEX [item_ident] ON [phpbb_notifications]([notification_type_id], [item_id]) ON [PRIMARY] GO CREATE INDEX [user] ON [phpbb_notifications]([user_id], [notification_read]) ON [PRIMARY] @@ -1588,7 +1591,7 @@ GO Table: 'phpbb_user_notifications' */ CREATE TABLE [phpbb_user_notifications] ( - [item_type] [varchar] (255) DEFAULT ('') NOT NULL , + [notification_type_id] [int] DEFAULT (0) NOT NULL , [item_id] [int] DEFAULT (0) NOT NULL , [user_id] [int] DEFAULT (0) NOT NULL , [method] [varchar] (255) DEFAULT ('') NOT NULL , diff --git a/phpBB/install/schemas/mysql_40_schema.sql b/phpBB/install/schemas/mysql_40_schema.sql index 8c405677a8..70048ea6bd 100644 --- a/phpBB/install/schemas/mysql_40_schema.sql +++ b/phpBB/install/schemas/mysql_40_schema.sql @@ -452,16 +452,18 @@ CREATE TABLE phpbb_modules ( # Table: 'phpbb_notification_types' CREATE TABLE phpbb_notification_types ( - notification_type varbinary(255) DEFAULT '' NOT NULL, + notification_type_id smallint(4) UNSIGNED NOT NULL auto_increment, + notification_type_name varbinary(255) DEFAULT '' NOT NULL, notification_type_enabled tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - PRIMARY KEY (notification_type, notification_type_enabled) + PRIMARY KEY (notification_type_id), + UNIQUE type (notification_type_name) ); # Table: 'phpbb_notifications' CREATE TABLE phpbb_notifications ( - notification_id mediumint(8) UNSIGNED NOT NULL auto_increment, - item_type varbinary(255) DEFAULT '' NOT NULL, + notification_id int(10) UNSIGNED NOT NULL auto_increment, + notification_type_id smallint(4) UNSIGNED DEFAULT '0' NOT NULL, item_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, item_parent_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, @@ -469,7 +471,7 @@ CREATE TABLE phpbb_notifications ( notification_time int(11) UNSIGNED DEFAULT '1' NOT NULL, notification_data blob NOT NULL, PRIMARY KEY (notification_id), - KEY item_ident (item_type, item_id), + KEY item_ident (notification_type_id, item_id), KEY user (user_id, notification_read) ); @@ -911,7 +913,7 @@ CREATE TABLE phpbb_topics_watch ( # Table: 'phpbb_user_notifications' CREATE TABLE phpbb_user_notifications ( - item_type varbinary(255) DEFAULT '' NOT NULL, + notification_type_id smallint(4) UNSIGNED DEFAULT '0' NOT NULL, item_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, method varbinary(255) DEFAULT '' NOT NULL, diff --git a/phpBB/install/schemas/mysql_41_schema.sql b/phpBB/install/schemas/mysql_41_schema.sql index cb259aa57d..e5ab9ceafa 100644 --- a/phpBB/install/schemas/mysql_41_schema.sql +++ b/phpBB/install/schemas/mysql_41_schema.sql @@ -452,16 +452,18 @@ CREATE TABLE phpbb_modules ( # Table: 'phpbb_notification_types' CREATE TABLE phpbb_notification_types ( - notification_type varchar(255) DEFAULT '' NOT NULL, + notification_type_id smallint(4) UNSIGNED NOT NULL auto_increment, + notification_type_name varchar(255) DEFAULT '' NOT NULL, notification_type_enabled tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - PRIMARY KEY (notification_type, notification_type_enabled) + PRIMARY KEY (notification_type_id), + UNIQUE type (notification_type_name) ) CHARACTER SET `utf8` COLLATE `utf8_bin`; # Table: 'phpbb_notifications' CREATE TABLE phpbb_notifications ( - notification_id mediumint(8) UNSIGNED NOT NULL auto_increment, - item_type varchar(255) DEFAULT '' NOT NULL, + notification_id int(10) UNSIGNED NOT NULL auto_increment, + notification_type_id smallint(4) UNSIGNED DEFAULT '0' NOT NULL, item_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, item_parent_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, @@ -469,7 +471,7 @@ CREATE TABLE phpbb_notifications ( notification_time int(11) UNSIGNED DEFAULT '1' NOT NULL, notification_data text NOT NULL, PRIMARY KEY (notification_id), - KEY item_ident (item_type, item_id), + KEY item_ident (notification_type_id, item_id), KEY user (user_id, notification_read) ) CHARACTER SET `utf8` COLLATE `utf8_bin`; @@ -911,7 +913,7 @@ CREATE TABLE phpbb_topics_watch ( # Table: 'phpbb_user_notifications' CREATE TABLE phpbb_user_notifications ( - item_type varchar(255) DEFAULT '' NOT NULL, + notification_type_id smallint(4) UNSIGNED DEFAULT '0' NOT NULL, item_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, method varchar(255) DEFAULT '' NOT NULL, diff --git a/phpBB/install/schemas/oracle_schema.sql b/phpBB/install/schemas/oracle_schema.sql index 35f05e34cd..b2e7409c7a 100644 --- a/phpBB/install/schemas/oracle_schema.sql +++ b/phpBB/install/schemas/oracle_schema.sql @@ -870,19 +870,37 @@ END; Table: 'phpbb_notification_types' */ CREATE TABLE phpbb_notification_types ( - notification_type varchar2(255) DEFAULT '' , + notification_type_id number(4) NOT NULL, + notification_type_name varchar2(255) DEFAULT '' , notification_type_enabled number(1) DEFAULT '1' NOT NULL, - CONSTRAINT pk_phpbb_notification_types PRIMARY KEY (notification_type, notification_type_enabled) + CONSTRAINT pk_phpbb_notification_types PRIMARY KEY (notification_type_id), + CONSTRAINT u_phpbb_type UNIQUE (notification_type_name) ) / +CREATE SEQUENCE phpbb_notification_types_seq +/ + +CREATE OR REPLACE TRIGGER t_phpbb_notification_types +BEFORE INSERT ON phpbb_notification_types +FOR EACH ROW WHEN ( + new.notification_type_id IS NULL OR new.notification_type_id = 0 +) +BEGIN + SELECT phpbb_notification_types_seq.nextval + INTO :new.notification_type_id + FROM dual; +END; +/ + + /* Table: 'phpbb_notifications' */ CREATE TABLE phpbb_notifications ( - notification_id number(8) NOT NULL, - item_type varchar2(255) DEFAULT '' , + notification_id number(10) NOT NULL, + notification_type_id number(4) DEFAULT '0' NOT NULL, item_id number(8) DEFAULT '0' NOT NULL, item_parent_id number(8) DEFAULT '0' NOT NULL, user_id number(8) DEFAULT '0' NOT NULL, @@ -893,7 +911,7 @@ CREATE TABLE phpbb_notifications ( ) / -CREATE INDEX phpbb_notifications_item_ident ON phpbb_notifications (item_type, item_id) +CREATE INDEX phpbb_notifications_item_ident ON phpbb_notifications (notification_type_id, item_id) / CREATE INDEX phpbb_notifications_user ON phpbb_notifications (user_id, notification_read) / @@ -1702,7 +1720,7 @@ CREATE INDEX phpbb_topics_watch_notify_stat ON phpbb_topics_watch (notify_status Table: 'phpbb_user_notifications' */ CREATE TABLE phpbb_user_notifications ( - item_type varchar2(255) DEFAULT '' , + notification_type_id number(4) DEFAULT '0' NOT NULL, item_id number(8) DEFAULT '0' NOT NULL, user_id number(8) DEFAULT '0' NOT NULL, method varchar2(255) DEFAULT '' , diff --git a/phpBB/install/schemas/postgres_schema.sql b/phpBB/install/schemas/postgres_schema.sql index 6dc507b46d..cd6de434b5 100644 --- a/phpBB/install/schemas/postgres_schema.sql +++ b/phpBB/install/schemas/postgres_schema.sql @@ -623,12 +623,16 @@ CREATE INDEX phpbb_modules_class_left_id ON phpbb_modules (module_class, left_id /* Table: 'phpbb_notification_types' */ +CREATE SEQUENCE phpbb_notification_types_seq; + CREATE TABLE phpbb_notification_types ( - notification_type varchar(255) DEFAULT '' NOT NULL, + notification_type_id INT2 DEFAULT nextval('phpbb_notification_types_seq'), + notification_type_name varchar(255) DEFAULT '' NOT NULL, notification_type_enabled INT2 DEFAULT '1' NOT NULL CHECK (notification_type_enabled >= 0), - PRIMARY KEY (notification_type, notification_type_enabled) + PRIMARY KEY (notification_type_id) ); +CREATE UNIQUE INDEX phpbb_notification_types_type ON phpbb_notification_types (notification_type_name); /* Table: 'phpbb_notifications' @@ -637,7 +641,7 @@ CREATE SEQUENCE phpbb_notifications_seq; CREATE TABLE phpbb_notifications ( notification_id INT4 DEFAULT nextval('phpbb_notifications_seq'), - item_type varchar(255) DEFAULT '' NOT NULL, + notification_type_id INT2 DEFAULT '0' NOT NULL CHECK (notification_type_id >= 0), item_id INT4 DEFAULT '0' NOT NULL CHECK (item_id >= 0), item_parent_id INT4 DEFAULT '0' NOT NULL CHECK (item_parent_id >= 0), user_id INT4 DEFAULT '0' NOT NULL CHECK (user_id >= 0), @@ -647,7 +651,7 @@ CREATE TABLE phpbb_notifications ( PRIMARY KEY (notification_id) ); -CREATE INDEX phpbb_notifications_item_ident ON phpbb_notifications (item_type, item_id); +CREATE INDEX phpbb_notifications_item_ident ON phpbb_notifications (notification_type_id, item_id); CREATE INDEX phpbb_notifications_user ON phpbb_notifications (user_id, notification_read); /* @@ -1171,7 +1175,7 @@ CREATE INDEX phpbb_topics_watch_notify_stat ON phpbb_topics_watch (notify_status Table: 'phpbb_user_notifications' */ CREATE TABLE phpbb_user_notifications ( - item_type varchar(255) DEFAULT '' NOT NULL, + notification_type_id INT2 DEFAULT '0' NOT NULL CHECK (notification_type_id >= 0), item_id INT4 DEFAULT '0' NOT NULL CHECK (item_id >= 0), user_id INT4 DEFAULT '0' NOT NULL CHECK (user_id >= 0), method varchar(255) DEFAULT '' NOT NULL, diff --git a/phpBB/install/schemas/sqlite_schema.sql b/phpBB/install/schemas/sqlite_schema.sql index ccb67ad46f..e12bb624b6 100644 --- a/phpBB/install/schemas/sqlite_schema.sql +++ b/phpBB/install/schemas/sqlite_schema.sql @@ -439,16 +439,17 @@ CREATE INDEX phpbb_modules_class_left_id ON phpbb_modules (module_class, left_id # Table: 'phpbb_notification_types' CREATE TABLE phpbb_notification_types ( - notification_type varchar(255) NOT NULL DEFAULT '', - notification_type_enabled INTEGER UNSIGNED NOT NULL DEFAULT '1', - PRIMARY KEY (notification_type, notification_type_enabled) + notification_type_id INTEGER PRIMARY KEY NOT NULL , + notification_type_name varchar(255) NOT NULL DEFAULT '', + notification_type_enabled INTEGER UNSIGNED NOT NULL DEFAULT '1' ); +CREATE UNIQUE INDEX phpbb_notification_types_type ON phpbb_notification_types (notification_type_name); # Table: 'phpbb_notifications' CREATE TABLE phpbb_notifications ( notification_id INTEGER PRIMARY KEY NOT NULL , - item_type varchar(255) NOT NULL DEFAULT '', + notification_type_id INTEGER UNSIGNED NOT NULL DEFAULT '0', item_id INTEGER UNSIGNED NOT NULL DEFAULT '0', item_parent_id INTEGER UNSIGNED NOT NULL DEFAULT '0', user_id INTEGER UNSIGNED NOT NULL DEFAULT '0', @@ -457,7 +458,7 @@ CREATE TABLE phpbb_notifications ( notification_data text(65535) NOT NULL DEFAULT '' ); -CREATE INDEX phpbb_notifications_item_ident ON phpbb_notifications (item_type, item_id); +CREATE INDEX phpbb_notifications_item_ident ON phpbb_notifications (notification_type_id, item_id); CREATE INDEX phpbb_notifications_user ON phpbb_notifications (user_id, notification_read); # Table: 'phpbb_poll_options' @@ -883,7 +884,7 @@ CREATE INDEX phpbb_topics_watch_notify_stat ON phpbb_topics_watch (notify_status # Table: 'phpbb_user_notifications' CREATE TABLE phpbb_user_notifications ( - item_type varchar(255) NOT NULL DEFAULT '', + notification_type_id INTEGER UNSIGNED NOT NULL DEFAULT '0', item_id INTEGER UNSIGNED NOT NULL DEFAULT '0', user_id INTEGER UNSIGNED NOT NULL DEFAULT '0', method varchar(255) NOT NULL DEFAULT '', -- cgit v1.2.1 From 4c5e51e379f770d9bd3610e7235dafcb985494e1 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Sun, 28 Apr 2013 23:40:48 -0500 Subject: [ticket/11413] Rename columns in notification/manager.php PHPBB3-11413 --- phpBB/config/services.yml | 1 + phpBB/includes/notification/manager.php | 276 +++++++++++++++++++------------- 2 files changed, 166 insertions(+), 111 deletions(-) (limited to 'phpBB') diff --git a/phpBB/config/services.yml b/phpBB/config/services.yml index 7923c94a3f..3142b8faab 100644 --- a/phpBB/config/services.yml +++ b/phpBB/config/services.yml @@ -218,6 +218,7 @@ services: - @service_container - @user_loader - @dbal.conn + - @cache - @user - %core.root_path% - %core.php_ext% diff --git a/phpBB/includes/notification/manager.php b/phpBB/includes/notification/manager.php index 9eceeb753a..8ea4cdc121 100644 --- a/phpBB/includes/notification/manager.php +++ b/phpBB/includes/notification/manager.php @@ -36,6 +36,9 @@ class phpbb_notification_manager /** @var phpbb_db_driver */ protected $db; + /** @var phpbb_cache_service */ + protected $cache; + /** @var phpbb_user */ protected $user; @@ -70,7 +73,7 @@ class phpbb_notification_manager * @param string $user_notifications_table * @return phpbb_notification_manager */ - public function __construct($notification_types, $notification_methods, $phpbb_container, phpbb_user_loader $user_loader, phpbb_db_driver $db, $user, $phpbb_root_path, $php_ext, $notification_types_table, $notifications_table, $user_notifications_table) + public function __construct($notification_types, $notification_methods, $phpbb_container, phpbb_user_loader $user_loader, phpbb_db_driver $db, phpbb_cache_service $cache, $user, $phpbb_root_path, $php_ext, $notification_types_table, $notifications_table, $user_notifications_table) { $this->notification_types = $notification_types; $this->notification_methods = $notification_methods; @@ -78,6 +81,7 @@ class phpbb_notification_manager $this->user_loader = $user_loader; $this->db = $db; + $this->cache = $cache; $this->user = $user; $this->phpbb_root_path = $phpbb_root_path; @@ -145,7 +149,7 @@ class phpbb_notification_manager FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt WHERE n.user_id = ' . (int) $options['user_id'] . ' AND n.notification_read = 0 - AND nt.notification_type = n.item_type + AND nt.notification_type_id = n.notification_type_id AND nt.notification_type_enabled = 1'; $result = $this->db->sql_query($sql); $unread_count = (int) $this->db->sql_fetchfield('unread_count', $result); @@ -158,7 +162,7 @@ class phpbb_notification_manager $sql = 'SELECT COUNT(n.notification_id) AS total_count FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt WHERE n.user_id = ' . (int) $options['user_id'] . ' - AND nt.notification_type = n.item_type + AND nt.notification_type_id = n.notification_type_id AND nt.notification_type_enabled = 1'; $result = $this->db->sql_query($sql); $total_count = (int) $this->db->sql_fetchfield('total_count', $result); @@ -170,11 +174,11 @@ class phpbb_notification_manager $rowset = array(); // Get the main notifications - $sql = 'SELECT n.* + $sql = 'SELECT n.*, nt.notification_type_name FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt WHERE n.user_id = ' . (int) $options['user_id'] . (($options['notification_id']) ? ((is_array($options['notification_id'])) ? ' AND ' . $this->db->sql_in_set('n.notification_id', $options['notification_id']) : ' AND n.notification_id = ' . (int) $options['notification_id']) : '') . ' - AND nt.notification_type = n.item_type + AND nt.notification_type_id = n.notification_type_id AND nt.notification_type_enabled = 1 ORDER BY n.' . $this->db->sql_escape($options['order_by']) . ' ' . $this->db->sql_escape($options['order_dir']); $result = $this->db->sql_query_limit($sql, $options['limit'], $options['start']); @@ -188,12 +192,12 @@ class phpbb_notification_manager // Get all unread notifications if ($unread_count && $options['all_unread'] && !empty($rowset)) { - $sql = 'SELECT n.* + $sql = 'SELECT n.*, nt.notification_type_name FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt WHERE n.user_id = ' . (int) $options['user_id'] . ' AND n.notification_read = 0 AND ' . $this->db->sql_in_set('n.notification_id', array_keys($rowset), true) . ' - AND nt.notification_type = n.item_type + AND nt.notification_type_id = n.notification_type_id AND nt.notification_type_enabled = 1 ORDER BY n.' . $this->db->sql_escape($options['order_by']) . ' ' . $this->db->sql_escape($options['order_dir']); $result = $this->db->sql_query_limit($sql, $options['limit'], $options['start']); @@ -207,17 +211,17 @@ class phpbb_notification_manager foreach ($rowset as $row) { - $notification = $this->get_item_type_class($row['item_type'], $row); + $notification = $this->get_item_type_class($row['notification_type_name'], $row); // Array of user_ids to query all at once $user_ids = array_merge($user_ids, $notification->users_to_query()); // Some notification types also require querying additional tables themselves - if (!isset($load_special[$row['item_type']])) + if (!isset($load_special[$row['notification_type_name']])) { - $load_special[$row['item_type']] = array(); + $load_special[$row['notification_type_name']] = array(); } - $load_special[$row['item_type']] = array_merge($load_special[$row['item_type']], $notification->get_load_special()); + $load_special[$row['notification_type_name']] = array_merge($load_special[$row['notification_type_name']], $notification->get_load_special()); $notifications[$row['notification_id']] = $notification; } @@ -243,19 +247,21 @@ class phpbb_notification_manager /** * Mark notifications read * - * @param bool|string|array $item_type Type identifier or array of item types (only acceptable if the $data is identical for the specified types). False to mark read for all item types + * @param bool|string|array $notification_type_name Type identifier or array of item types (only acceptable if the $data is identical for the specified types). False to mark read for all item types * @param bool|int|array $item_id Item id or array of item ids. False to mark read for all item ids * @param bool|int|array $user_id User id or array of user ids. False to mark read for all user ids * @param bool|int $time Time at which to mark all notifications prior to as read. False to mark all as read. (Default: False) */ - public function mark_notifications_read($item_type, $item_id, $user_id, $time = false) + public function mark_notifications_read($notification_type_name, $item_id, $user_id, $time = false) { $time = ($time !== false) ? $time : time(); $sql = 'UPDATE ' . $this->notifications_table . " 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) . "'") : '') . + (($notification_type_name !== false) ? ' AND ' . + (is_array($notification_type_name) ? $this->db->sql_in_set('notification_type_id', $this->get_notification_type_ids($notification_type_name)) : 'notification_type_id = ' . $this->get_notification_type_id($notification_type_name)) + : '') . (($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); @@ -264,29 +270,21 @@ class phpbb_notification_manager /** * Mark notifications read from a parent identifier * - * @param string|array $item_type Type identifier or array of item types (only acceptable if the $data is identical for the specified types) + * @param string|array $notification_type_name Type identifier or array of item types (only acceptable if the $data is identical for the specified types) * @param bool|int|array $item_parent_id Item parent id or array of item parent ids. False to mark read for all item parent ids * @param bool|int|array $user_id User id or array of user ids. False to mark read for all user ids * @param bool|int $time Time at which to mark all notifications prior to as read. False to mark all as read. (Default: False) */ - public function mark_notifications_read_by_parent($item_type, $item_parent_id, $user_id, $time = false) + public function mark_notifications_read_by_parent($notification_type_name, $item_parent_id, $user_id, $time = false) { - if (is_array($item_type)) - { - foreach ($item_type as $type) - { - $this->mark_notifications_read_by_parent($type, $item_parent_id, $user_id, $time); - } - - return; - } - $time = ($time !== false) ? $time : time(); $sql = 'UPDATE ' . $this->notifications_table . " SET notification_read = 1 - WHERE item_type = '" . $this->db->sql_escape($item_type) . "' - AND notification_time <= " . (int) $time . + WHERE notification_time <= " . (int) $time . + (($notification_type_name !== false) ? ' AND ' . + (is_array($notification_type_name) ? $this->db->sql_in_set('notification_type_id', $this->get_notification_type_ids($notification_type_name)) : 'notification_type_id = ' . $this->get_notification_type_id($notification_type_name)) + : '') . (($item_parent_id !== false) ? ' AND ' . (is_array($item_parent_id) ? $this->db->sql_in_set('item_parent_id', $item_parent_id) : 'item_parent_id = ' . (int) $item_parent_id) : '') . (($user_id !== false) ? ' AND ' . (is_array($user_id) ? $this->db->sql_in_set('user_id', $user_id) : 'user_id = ' . (int) $user_id) : ''); $this->db->sql_query($sql); @@ -312,7 +310,7 @@ class phpbb_notification_manager /** * Add a notification * - * @param string|array $item_type Type identifier or array of item types (only acceptable if the $data is identical for the specified types) + * @param string|array $notification_type_name Type identifier or array of item types (only acceptable if the $data is identical for the specified types) * Note: If you send an array of types, any user who could receive multiple notifications from this single item will only receive * a single notification. If they MUST receive multiple notifications, call this function multiple times instead of sending an array * @param array $data Data specific for this type that will be inserted @@ -320,18 +318,18 @@ class phpbb_notification_manager * ignore_users array of data to specify which users should not receive certain types of notifications * @return array Information about what users were notified and how they were notified */ - public function add_notifications($item_type, $data, array $options = array()) + public function add_notifications($notification_type_name, $data, array $options = array()) { $options = array_merge(array( 'ignore_users' => array(), ), $options); - if (is_array($item_type)) + if (is_array($notification_type_name)) { $notified_users = array(); $temp_options = $options; - foreach ($item_type as $type) + foreach ($notification_type_name as $type) { $temp_options['ignore_users'] = $options['ignore_users'] + $notified_users; $notified_users += $this->add_notifications($type, $data, $temp_options); @@ -340,12 +338,12 @@ class phpbb_notification_manager return $notified_users; } - $item_id = $this->get_item_type_class($item_type)->get_item_id($data); + $item_id = $this->get_item_type_class($notification_type_name)->get_item_id($data); // find out which users want to receive this type of notification - $notify_users = $this->get_item_type_class($item_type)->find_users_for_notification($data, $options); + $notify_users = $this->get_item_type_class($notification_type_name)->find_users_for_notification($data, $options); - $this->add_notifications_for_users($item_type, $data, $notify_users); + $this->add_notifications_for_users($notification_type_name, $data, $notify_users); return $notify_users; } @@ -353,15 +351,15 @@ class phpbb_notification_manager /** * Add a notification for specific users * - * @param string|array $item_type Type identifier or array of item types (only acceptable if the $data is identical for the specified types) + * @param string|array $notification_type_name Type identifier or array of item types (only acceptable if the $data is identical for the specified types) * @param array $data Data specific for this type that will be inserted * @param array $notify_users User list to notify */ - public function add_notifications_for_users($item_type, $data, $notify_users) + public function add_notifications_for_users($notification_type_name, $data, $notify_users) { - if (is_array($item_type)) + if (is_array($notification_type_name)) { - foreach ($item_type as $type) + foreach ($notification_type_name as $type) { $this->add_notifications_for_users($type, $data, $notify_users); } @@ -369,24 +367,9 @@ class phpbb_notification_manager return; } - $sql = 'SELECT notification_type - FROM ' . $this->notification_types_table . " - WHERE notification_type = '" . $this->db->sql_escape($item_type) . "'"; - $result = $this->db->sql_query($sql); + $notification_type_id = $this->get_notification_type_id($notification_type_name); - if ($this->db->sql_fetchrow($result) === false) - { - // Does not exist in the database, must add the item type - $sql = 'INSERT INTO ' . $this->notification_types_table . ' ' . $this->db->sql_build_array('INSERT', array( - 'notification_type' => $item_type, - 'notification_type_enabled' => 1, - )); - $this->db->sql_query($sql); - } - - $this->db->sql_freeresult($result); - - $item_id = $this->get_item_type_class($item_type)->get_item_id($data); + $item_id = $this->get_item_type_class($notification_type_name)->get_item_id($data); $user_ids = array(); $notification_objects = $notification_methods = array(); @@ -397,10 +380,10 @@ class phpbb_notification_manager // Make sure not to send new notifications to users who've already been notified about this item // This may happen when an item was added, but now new users are able to see the item $sql = 'SELECT n.user_id - FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . " nt - WHERE n.item_type = '" . $this->db->sql_escape($item_type) . "' - AND n.item_id = " . (int) $item_id . ' - AND nt.notification_type = n.item_type + FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt + WHERE n.notification_type_id = ' . (int) $notification_type_id . ' + AND n.item_id = ' . (int) $item_id . ' + AND nt.notification_type_id = n.notification_type_id AND nt.notification_type_enabled = 1'; $result = $this->db->sql_query($sql); while ($row = $this->db->sql_fetchrow($result)) @@ -415,7 +398,7 @@ class phpbb_notification_manager } // Allow notifications to perform actions before creating the insert array (such as run a query to cache some data needed for all notifications) - $notification = $this->get_item_type_class($item_type); + $notification = $this->get_item_type_class($notification_type_name); $pre_create_data = $notification->pre_create_insert_array($data, $notify_users); unset($notification); @@ -424,7 +407,7 @@ class phpbb_notification_manager // 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) { - $notification = $this->get_item_type_class($item_type); + $notification = $this->get_item_type_class($notification_type_name); $notification->user_id = (int) $user; @@ -464,14 +447,14 @@ class phpbb_notification_manager /** * Update a notification * - * @param string|array $item_type Type identifier or array of item types (only acceptable if the $data is identical for the specified types) + * @param string|array $notification_type_name Type identifier or array of item types (only acceptable if the $data is identical for the specified types) * @param array $data Data specific for this type that will be updated */ - public function update_notifications($item_type, $data) + public function update_notifications($notification_type_name, $data) { - if (is_array($item_type)) + if (is_array($notification_type_name)) { - foreach ($item_type as $type) + foreach ($notification_type_name as $type) { $this->update_notifications($type, $data); } @@ -479,7 +462,7 @@ class phpbb_notification_manager return; } - $notification = $this->get_item_type_class($item_type); + $notification = $this->get_item_type_class($notification_type_name); // Allow the notifications class to over-ride the update_notifications functionality if (method_exists($notification, 'update_notifications')) @@ -491,28 +474,29 @@ class phpbb_notification_manager } } + $notification_type_id = $this->get_notification_type_id($notification_type_name); $item_id = $notification->get_item_id($data); $update_array = $notification->create_update_array($data); $sql = 'UPDATE ' . $this->notifications_table . ' - SET ' . $this->db->sql_build_array('UPDATE', $update_array) . " - WHERE item_type = '" . $this->db->sql_escape($item_type) . "' - AND item_id = " . (int) $item_id; + SET ' . $this->db->sql_build_array('UPDATE', $update_array) . ' + WHERE notification_type_id = ' . (int) $notification_type_id . ' + AND item_id = ' . (int) $item_id; $this->db->sql_query($sql); } /** * Delete a notification * - * @param string|array $item_type Type identifier or array of item types (only acceptable if the $item_id is identical for the specified types) + * @param string|array $notification_type_name Type identifier or array of item types (only acceptable if the $item_id is identical for the specified types) * @param int|array $item_id Identifier within the type (or array of ids) * @param array $data Data specific for this type that will be updated */ - public function delete_notifications($item_type, $item_id) + public function delete_notifications($notification_type_name, $item_id) { - if (is_array($item_type)) + if (is_array($notification_type_name)) { - foreach ($item_type as $type) + foreach ($notification_type_name as $type) { $this->delete_notifications($type, $item_id); } @@ -520,9 +504,11 @@ class phpbb_notification_manager return; } - $sql = 'DELETE FROM ' . $this->notifications_table . " - WHERE item_type = '" . $this->db->sql_escape($item_type) . "' - AND " . (is_array($item_id) ? $this->db->sql_in_set('item_id', $item_id) : 'item_id = ' . (int) $item_id); + $notification_type_id = $this->get_notification_type_id($notification_type_name); + + $sql = 'DELETE FROM ' . $this->notifications_table . ' + WHERE notification_type_id = ' . (int) $notification_type_id . ' + AND ' . (is_array($item_id) ? $this->db->sql_in_set('item_id', $item_id) : 'item_id = ' . (int) $item_id); $this->db->sql_query($sql); } @@ -646,24 +632,25 @@ class phpbb_notification_manager /** * Add a subscription * - * @param string $item_type Type identifier of the subscription + * @param string $notification_type_name Type identifier of the subscription * @param int $item_id The id of the item * @param string $method The method of the notification e.g. '', 'email', or 'jabber' * @param bool|int $user_id The user_id to add the subscription for (bool false for current user) */ - public function add_subscription($item_type, $item_id = 0, $method = '', $user_id = false) + public function add_subscription($notification_type_name, $item_id = 0, $method = '', $user_id = false) { if ($method !== '') { - $this->add_subscription($item_type, $item_type, '', $user_id); + $this->add_subscription($notification_type_name, $item_id, '', $user_id); } + $notification_type_id = $this->get_notification_type_id($notification_type_name); $user_id = ($user_id === false) ? $this->user->data['user_id'] : $user_id; $sql = 'SELECT notify - FROM ' . $this->user_notifications_table . " - WHERE item_type = '" . $this->db->sql_escape($item_type) . "' - AND item_id = " . (int) $item_id . ' + FROM ' . $this->user_notifications_table . ' + WHERE notification_type_id = ' . (int) $notification_type_name . ' + AND item_id = ' . (int) $item_id . ' AND user_id = ' .(int) $user_id . " AND method = '" . $this->db->sql_escape($method) . "'"; $this->db->sql_query($sql); @@ -674,7 +661,7 @@ class phpbb_notification_manager { $sql = 'INSERT INTO ' . $this->user_notifications_table . ' ' . $this->db->sql_build_array('INSERT', array( - 'item_type' => $item_type, + 'notification_type_id' => $notification_type_id, 'item_id' => (int) $item_id, 'user_id' => (int) $user_id, 'method' => $method, @@ -684,10 +671,10 @@ class phpbb_notification_manager } else if (!$current) { - $sql = 'UPDATE ' . $this->user_notifications_table . " + $sql = 'UPDATE ' . $this->user_notifications_table . ' SET notify = 1 - WHERE item_type = '" . $this->db->sql_escape($item_type) . "' - AND item_id = " . (int) $item_id . ' + WHERE notification_type_id = ' . (int) $notification_type_id . ' + AND item_id = ' . (int) $item_id . ' AND user_id = ' .(int) $user_id . " AND method = '" . $this->db->sql_escape($method) . "'"; $this->db->sql_query($sql); @@ -697,22 +684,23 @@ class phpbb_notification_manager /** * Delete a subscription * - * @param string $item_type Type identifier of the subscription + * @param string $notification_type_name Type identifier of the subscription * @param int $item_id The id of the item * @param string $method The method of the notification e.g. '', 'email', or 'jabber' * @param bool|int $user_id The user_id to add the subscription for (bool false for current user) */ - public function delete_subscription($item_type, $item_id = 0, $method = '', $user_id = false) + public function delete_subscription($notification_type_name, $item_id = 0, $method = '', $user_id = false) { + $notification_type_id = $this->get_notification_type_id($notification_type_name); $user_id = ($user_id === false) ? $this->user->data['user_id'] : $user_id; // If no method, make sure that no other notification methods for this item are selected before deleting if ($method === '') { $sql = 'SELECT COUNT(*) as num_notifications - FROM ' . $this->user_notifications_table . " - WHERE item_type = '" . $this->db->sql_escape($item_type) . "' - AND item_id = " . (int) $item_id . ' + FROM ' . $this->user_notifications_table . ' + WHERE notification_type_id = ' . (int) $notification_type_id . ' + AND item_id = ' . (int) $item_id . ' AND user_id = ' .(int) $user_id . " AND method <> '' AND notify = 1"; @@ -726,10 +714,10 @@ class phpbb_notification_manager } } - $sql = 'UPDATE ' . $this->user_notifications_table . " + $sql = 'UPDATE ' . $this->user_notifications_table . ' SET notify = 0 - WHERE item_type = '" . $this->db->sql_escape($item_type) . "' - AND item_id = " . (int) $item_id . ' + WHERE notification_type_id = ' . (int) $notification_type_id . ' + AND item_id = '. (int) $item_id . ' AND user_id = ' .(int) $user_id . " AND method = '" . $this->db->sql_escape($method) . "'"; $this->db->sql_query($sql); @@ -738,7 +726,7 @@ class phpbb_notification_manager { $sql = 'INSERT INTO ' . $this->user_notifications_table . ' ' . $this->db->sql_build_array('INSERT', array( - 'item_type' => $item_type, + 'notification_type_id' => (int) $notification_type_id, 'item_id' => (int) $item_id, 'user_id' => (int) $user_id, 'method' => $method, @@ -755,13 +743,13 @@ class phpbb_notification_manager * is disabled so that all those notifications are hidden and do not * cause errors * - * @param string $item_type Type identifier of the subscription + * @param string $notification_type_name Type identifier of the subscription */ - public function disable_notifications($item_type) + public function disable_notifications($notification_type_name) { $sql = 'UPDATE ' . $this->notification_types_table . " SET notification_type_enabled = 0 - WHERE notification_type = '" . $this->db->sql_escape($item_type) . "'"; + WHERE notification_type_name = '" . $this->db->sql_escape($notification_type_name) . "'"; $this->db->sql_query($sql); } @@ -771,17 +759,21 @@ class phpbb_notification_manager * This should be called when an extension which has notification types * is purged so that all those notifications are removed * - * @param string $item_type Type identifier of the subscription + * @param string $notification_type_name Type identifier of the subscription */ - public function purge_notifications($item_type) + public function purge_notifications($notification_type_name) { - $sql = 'DELETE FROM ' . $this->notifications_table . " - WHERE item_type = '" . $this->db->sql_escape($item_type) . "'"; + $notification_type_id = $this->get_notification_type_id($notification_type_name); + + $sql = 'DELETE FROM ' . $this->notifications_table . ' + WHERE notification_type_id = ' . (int) $notification_type_id; $this->db->sql_query($sql); - $sql = 'DELETE FROM ' . $this->notification_types_table . " - WHERE notification_type = '" . $this->db->sql_escape($item_type) . "'"; + $sql = 'DELETE FROM ' . $this->notification_types_table . ' + WHERE notification_type_id = ' . (int) $notification_type_id; $this->db->sql_query($sql); + + $this->cache->destroy('notification_type_ids'); } /** @@ -791,13 +783,13 @@ class phpbb_notification_manager * that was disabled is re-enabled so that all those notifications that * were hidden are shown again * - * @param string $item_type Type identifier of the subscription + * @param string $notification_type_name Type identifier of the subscription */ - public function enable_notifications($item_type) + public function enable_notifications($notification_type_name) { $sql = 'UPDATE ' . $this->notification_types_table . " SET notification_type_enabled = 1 - WHERE notification_type = '" . $this->db->sql_escape($item_type) . "'"; + WHERE notification_type_name = '" . $this->db->sql_escape($notification_type_name) . "'"; $this->db->sql_query($sql); } @@ -816,11 +808,11 @@ class phpbb_notification_manager /** * Helper to get the notifications item type class and set it up */ - public function get_item_type_class($item_type, $data = array()) + public function get_item_type_class($notification_type_name, $data = array()) { - $item_type = (strpos($item_type, 'notification.type.') === 0) ? $item_type : 'notification.type.' . $item_type; + $notification_type_name = (strpos($notification_type_name, 'notification.type.') === 0) ? $notification_type_name : 'notification.type.' . $notification_type_name; - $item = $this->load_object($item_type); + $item = $this->load_object($notification_type_name); $item->set_initial_data($data); @@ -851,4 +843,66 @@ class phpbb_notification_manager return $object; } + + /** + * Get the notification type id from the name + * + * @param string $notification_type_name The name + * @return int the notification_type_id + */ + public function get_notification_type_id($notification_type_name) + { + $notification_type_ids = $this->cache->get('notification_type_ids'); + + if ($notification_type_ids === false) + { + $notification_type_ids = array(); + + $sql = 'SELECT notification_type_id, notification_type_name + FROM ' . $this->notification_types_table; + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + $notification_type_ids[$row['notification_type_name']] = (int) $row['notification_type_id']; + } + $this->db->sql_freeresult($result); + + $this->cache->put('notification_type_ids', $notification_type_ids); + } + + if (!isset($notification_type_ids[$notification_type_name])) + { + $notification_type = $this->get_item_type_class($notification_type_name); + + $sql = 'INSERT INTO ' . $this->notification_types_table . ' ' . $this->db->sql_build_array('INSERT', array( + 'notification_type_name' => $notification_type_name, + 'notification_type_enabled' => 1, + )); + $this->db->sql_query($sql); + + $notification_type_ids[$notification_type_name] = (int) $this->db->sql_nextid(); + + $this->cache->put('notification_type_ids', $notification_type_ids); + } + + return $notification_type_ids[$notification_type_name]; + } + + /** + * Get notification type ids (as an array) + * + * @param array $notification_type_names Array of strings + * @return array Array of integers + */ + public function get_notification_type_ids(array $notification_type_names) + { + $notification_type_ids = array(); + + foreach ($notification_type_names as $name) + { + $notification_type_ids[$name] = $this->get_notification_type_id($name); + } + + return $notification_type_ids; + } } -- cgit v1.2.1 From 33287a73609a99f33f3d0718fceaf72e39d5283e Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Mon, 29 Apr 2013 21:22:07 -0500 Subject: [ticket/11413] Undo editing the user_notifications table item_type is not equivalent to notification_type_name, it can be a generic string (typically used to be able to subscribe to multiple notification types while only subscribing to one item PHPBB3-11413 --- phpBB/develop/create_schema_files.php | 10 +++--- .../db/migration/data/310/notifications2.php | 28 ++------------- phpBB/includes/notification/manager.php | 41 +++++++++++----------- phpBB/includes/notification/type/base.php | 20 ++++++++--- phpBB/includes/notification/type/bookmark.php | 8 ++--- phpBB/includes/notification/type/post.php | 8 ++--- phpBB/includes/notification/type/quote.php | 22 ++++++------ phpBB/install/schemas/firebird_schema.sql | 2 +- phpBB/install/schemas/mssql_schema.sql | 2 +- phpBB/install/schemas/mysql_40_schema.sql | 2 +- phpBB/install/schemas/mysql_41_schema.sql | 2 +- phpBB/install/schemas/oracle_schema.sql | 2 +- phpBB/install/schemas/postgres_schema.sql | 2 +- phpBB/install/schemas/sqlite_schema.sql | 2 +- 14 files changed, 69 insertions(+), 82 deletions(-) (limited to 'phpBB') diff --git a/phpBB/develop/create_schema_files.php b/phpBB/develop/create_schema_files.php index 3121db391d..0fd1a722ca 100644 --- a/phpBB/develop/create_schema_files.php +++ b/phpBB/develop/create_schema_files.php @@ -1819,11 +1819,11 @@ function get_schema_struct() $schema_data['phpbb_user_notifications'] = array( 'COLUMNS' => array( - 'notification_type_id' => array('USINT', 0), - 'item_id' => array('UINT', 0), - 'user_id' => array('UINT', 0), - 'method' => array('VCHAR:255', ''), - 'notify' => array('BOOL', 1), + 'item_type' => array('VCHAR:255', ''), + 'item_id' => array('UINT', 0), + 'user_id' => array('UINT', 0), + 'method' => array('VCHAR:255', ''), + 'notify' => array('BOOL', 1), ), ); diff --git a/phpBB/includes/db/migration/data/310/notifications2.php b/phpBB/includes/db/migration/data/310/notifications2.php index a3f29b073a..cd078f8f60 100644 --- a/phpBB/includes/db/migration/data/310/notifications2.php +++ b/phpBB/includes/db/migration/data/310/notifications2.php @@ -20,7 +20,6 @@ class phpbb_db_migration_data_310_notifications2 extends phpbb_db_migration 'drop_tables' => array( $this->table_prefix . 'notification_types', $this->table_prefix . 'notifications', - $this->table_prefix . 'user_notifications', ), 'add_tables' => array( $this->table_prefix . 'notification_types' => array( @@ -51,20 +50,6 @@ class phpbb_db_migration_data_310_notifications2 extends phpbb_db_migration 'user' => array('INDEX', array('user_id', 'notification_read')), ), ), - $this->table_prefix . 'user_notifications' => array( - 'COLUMNS' => array( - 'notification_type_id' => array('USINT', 0), - 'item_id' => array('UINT', 0), - 'user_id' => array('UINT', 0), - 'method' => array('VCHAR:255', ''), - 'notify' => array('BOOL', 1), - ), - 'PRIMARY_KEY' => array( - 'notification_type_id', - 'item_id', - 'user_id', - ), - ), ), ); } @@ -75,7 +60,6 @@ class phpbb_db_migration_data_310_notifications2 extends phpbb_db_migration 'drop_tables' => array( $this->table_prefix . 'notification_types', $this->table_prefix . 'notifications', - $this->table_prefix . 'user_notifications', ), 'add_tables' => array( $this->table_prefix . 'notification_types' => array( @@ -102,15 +86,6 @@ class phpbb_db_migration_data_310_notifications2 extends phpbb_db_migration 'user' => array('INDEX', array('user_id', 'notification_read')), ), ), - $this->table_prefix . 'user_notifications' => array( - 'COLUMNS' => array( - 'item_type' => array('VCHAR:255', ''), - 'item_id' => array('UINT', 0), - 'user_id' => array('UINT', 0), - 'method' => array('VCHAR:255', ''), - 'notify' => array('BOOL', 1), - ), - ), ), ); } @@ -126,6 +101,9 @@ class phpbb_db_migration_data_310_notifications2 extends phpbb_db_migration { $insert_table = $this->table_prefix . 'user_notifications'; + $sql = 'DELETE FROM ' . $insert_table; + $this->db->sql_query($sql); + $sql = 'SELECT user_id, user_notify_type, user_notify_pm FROM ' . USERS_TABLE; $result = $this->db->sql_query($sql); diff --git a/phpBB/includes/notification/manager.php b/phpBB/includes/notification/manager.php index 8ea4cdc121..e7d6af71b8 100644 --- a/phpBB/includes/notification/manager.php +++ b/phpBB/includes/notification/manager.php @@ -632,25 +632,25 @@ class phpbb_notification_manager /** * Add a subscription * - * @param string $notification_type_name Type identifier of the subscription + * @param string $item_type Type identifier of the subscription * @param int $item_id The id of the item * @param string $method The method of the notification e.g. '', 'email', or 'jabber' * @param bool|int $user_id The user_id to add the subscription for (bool false for current user) */ - public function add_subscription($notification_type_name, $item_id = 0, $method = '', $user_id = false) + public function add_subscription($item_type, $item_id = 0, $method = '', $user_id = false) { if ($method !== '') { - $this->add_subscription($notification_type_name, $item_id, '', $user_id); + // Make sure to subscribe them to the base subscription + $this->add_subscription($item_type, $item_id, '', $user_id); } - $notification_type_id = $this->get_notification_type_id($notification_type_name); $user_id = ($user_id === false) ? $this->user->data['user_id'] : $user_id; $sql = 'SELECT notify - FROM ' . $this->user_notifications_table . ' - WHERE notification_type_id = ' . (int) $notification_type_name . ' - AND item_id = ' . (int) $item_id . ' + FROM ' . $this->user_notifications_table . " + WHERE item_type = '" . $this->db->sql_escape($item_type) . "' + AND item_id = " . (int) $item_id . ' AND user_id = ' .(int) $user_id . " AND method = '" . $this->db->sql_escape($method) . "'"; $this->db->sql_query($sql); @@ -661,7 +661,7 @@ class phpbb_notification_manager { $sql = 'INSERT INTO ' . $this->user_notifications_table . ' ' . $this->db->sql_build_array('INSERT', array( - 'notification_type_id' => $notification_type_id, + 'item_type' => $item_type, 'item_id' => (int) $item_id, 'user_id' => (int) $user_id, 'method' => $method, @@ -671,10 +671,10 @@ class phpbb_notification_manager } else if (!$current) { - $sql = 'UPDATE ' . $this->user_notifications_table . ' + $sql = 'UPDATE ' . $this->user_notifications_table . " SET notify = 1 - WHERE notification_type_id = ' . (int) $notification_type_id . ' - AND item_id = ' . (int) $item_id . ' + WHERE item_type = '" . $this->db->sql_escape($item_type) . "' + AND item_id = " . (int) $item_id . ' AND user_id = ' .(int) $user_id . " AND method = '" . $this->db->sql_escape($method) . "'"; $this->db->sql_query($sql); @@ -684,23 +684,22 @@ class phpbb_notification_manager /** * Delete a subscription * - * @param string $notification_type_name Type identifier of the subscription + * @param string $item_type Type identifier of the subscription * @param int $item_id The id of the item * @param string $method The method of the notification e.g. '', 'email', or 'jabber' * @param bool|int $user_id The user_id to add the subscription for (bool false for current user) */ - public function delete_subscription($notification_type_name, $item_id = 0, $method = '', $user_id = false) + public function delete_subscription($item_type, $item_id = 0, $method = '', $user_id = false) { - $notification_type_id = $this->get_notification_type_id($notification_type_name); $user_id = ($user_id === false) ? $this->user->data['user_id'] : $user_id; // If no method, make sure that no other notification methods for this item are selected before deleting if ($method === '') { $sql = 'SELECT COUNT(*) as num_notifications - FROM ' . $this->user_notifications_table . ' - WHERE notification_type_id = ' . (int) $notification_type_id . ' - AND item_id = ' . (int) $item_id . ' + FROM ' . $this->user_notifications_table . " + WHERE item_type = '" . $this->db->sql_escape($item_type) . "' + AND item_id = " . (int) $item_id . ' AND user_id = ' .(int) $user_id . " AND method <> '' AND notify = 1"; @@ -714,10 +713,10 @@ class phpbb_notification_manager } } - $sql = 'UPDATE ' . $this->user_notifications_table . ' + $sql = 'UPDATE ' . $this->user_notifications_table . " SET notify = 0 - WHERE notification_type_id = ' . (int) $notification_type_id . ' - AND item_id = '. (int) $item_id . ' + WHERE item_type = '" . $this->db->sql_escape($item_type) . "' + AND item_id = " . (int) $item_id . ' AND user_id = ' .(int) $user_id . " AND method = '" . $this->db->sql_escape($method) . "'"; $this->db->sql_query($sql); @@ -726,7 +725,7 @@ class phpbb_notification_manager { $sql = 'INSERT INTO ' . $this->user_notifications_table . ' ' . $this->db->sql_build_array('INSERT', array( - 'notification_type_id' => (int) $notification_type_id, + 'item_type' => $item_type, 'item_id' => (int) $item_id, 'user_id' => (int) $user_id, 'method' => $method, diff --git a/phpBB/includes/notification/type/base.php b/phpBB/includes/notification/type/base.php index 600ef7c965..f56956d16a 100644 --- a/phpBB/includes/notification/type/base.php +++ b/phpBB/includes/notification/type/base.php @@ -68,11 +68,19 @@ abstract class phpbb_notification_type_base implements phpbb_notification_type_i */ public static $notification_option = false; + /** + * The notification_type_id, set upon creation of the class + * This is the notification_type_id from the notification_types table + * + * @var int + */ + protected $notification_type_id; + /** * Indentification data - * item_type - Type of the item (translates to the notification type) - * item_id - ID of the item (e.g. post_id, msg_id) - * item_parent_id - Parent item id (ex: for topic => forum_id, for post => topic_id, etc) + * notification_type_id - ID of the item type (auto generated, from notification types table) + * item_id - ID of the item (e.g. post_id, msg_id) + * item_parent_id - Parent item id (ex: for topic => forum_id, for post => topic_id, etc) * user_id * notification_read * notification_time @@ -124,6 +132,8 @@ abstract class phpbb_notification_type_base implements phpbb_notification_type_i public function set_notification_manager(phpbb_notification_manager $notification_manager) { $this->notification_manager = $notification_manager; + + $this->notification_type_id = $this->notification_manager->get_notification_type_id($this->get_type()); } /** @@ -211,7 +221,7 @@ abstract class phpbb_notification_type_base implements phpbb_notification_type_i // Defaults $this->data = array_merge(array( 'item_id' => static::get_item_id($type_data), - 'item_type' => $this->get_type(), + 'notification_type_id' => $this->notification_type_id, 'item_parent_id' => static::get_item_parent_id($type_data), 'notification_time' => time(), @@ -460,7 +470,7 @@ abstract class phpbb_notification_type_base implements phpbb_notification_type_i $this->notification_read = (bool) !$unread; $where = array( - "item_type = '" . $this->db->sql_escape($this->item_type) . "'", + 'notification_type_id = ' . (int) $this->notification_type_id, 'item_id = ' . (int) $this->item_id, 'user_id = ' . (int) $this->user_id, ); diff --git a/phpBB/includes/notification/type/bookmark.php b/phpBB/includes/notification/type/bookmark.php index 946cb9b4ed..ae2e75d3eb 100644 --- a/phpBB/includes/notification/type/bookmark.php +++ b/phpBB/includes/notification/type/bookmark.php @@ -103,11 +103,11 @@ class phpbb_notification_type_bookmark extends phpbb_notification_type_post // Try to find the users who already have been notified about replies and have not read the topic since and just update their notifications $update_notifications = array(); $sql = 'SELECT n.* - FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . " nt - WHERE n.item_type = '" . $this->get_type() . "' - AND n.item_parent_id = " . (int) self::get_item_parent_id($post) . ' + FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt + WHERE n.notification_type_id = ' . (int) $this->notification_type_id . ' + AND n.item_parent_id = ' . (int) self::get_item_parent_id($post) . ' AND n.notification_read = 0 - AND nt.notification_type = n.item_type + AND nt.notification_type_id = n.notification_type_id AND nt.notification_type_enabled = 1'; $result = $this->db->sql_query($sql); while ($row = $this->db->sql_fetchrow($result)) diff --git a/phpBB/includes/notification/type/post.php b/phpBB/includes/notification/type/post.php index 626c13b7fd..9207fd866e 100644 --- a/phpBB/includes/notification/type/post.php +++ b/phpBB/includes/notification/type/post.php @@ -138,11 +138,11 @@ class phpbb_notification_type_post extends phpbb_notification_type_base // Try to find the users who already have been notified about replies and have not read the topic since and just update their notifications $update_notifications = array(); $sql = 'SELECT n.* - FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . " nt - WHERE n.item_type = '" . $this->get_type() . "' - AND n.item_parent_id = " . (int) self::get_item_parent_id($post) . ' + FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt + WHERE n.notification_type_id = ' . (int) $this->notification_type_id . ' + AND n.item_parent_id = ' . (int) self::get_item_parent_id($post) . ' AND n.notification_read = 0 - AND nt.notification_type = n.item_type + AND nt.notification_type_id = n.notification_type_id AND nt.notification_type_enabled = 1'; $result = $this->db->sql_query($sql); while ($row = $this->db->sql_fetchrow($result)) diff --git a/phpBB/includes/notification/type/quote.php b/phpBB/includes/notification/type/quote.php index e9eb7bea21..0ed13f36fb 100644 --- a/phpBB/includes/notification/type/quote.php +++ b/phpBB/includes/notification/type/quote.php @@ -122,11 +122,11 @@ class phpbb_notification_type_quote extends phpbb_notification_type_post // Try to find the users who already have been notified about replies and have not read the topic since and just update their notifications $update_notifications = array(); $sql = 'SELECT n.* - FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . " nt - WHERE n.item_type = '" . $this->get_type() . "' - AND n.item_parent_id = " . (int) self::get_item_parent_id($post) . ' + FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt + WHERE n.notification_type_id = ' . (int) $this->notification_type_id . ' + AND n.item_parent_id = ' . (int) self::get_item_parent_id($post) . ' AND n.notification_read = 0 - AND nt.notification_type = n.item_type + AND nt.notification_type_id = n.notification_type_id AND nt.notification_type_enabled = 1'; $result = $this->db->sql_query($sql); while ($row = $this->db->sql_fetchrow($result)) @@ -154,10 +154,10 @@ class phpbb_notification_type_quote extends phpbb_notification_type_post { $old_notifications = array(); $sql = 'SELECT n.user_id - FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . " nt - WHERE n.item_type = '" . $this->get_type() . "' - AND n.item_id = " . self::get_item_id($post) . ' - AND nt.notification_type = n.item_type + FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt + WHERE n.notification_type_id = ' . (int) $this->notification_type_id . ' + AND n.item_id = ' . self::get_item_id($post) . ' + AND nt.notification_type_id = n.notification_type_id AND nt.notification_type_enabled = 1'; $result = $this->db->sql_query($sql); while ($row = $this->db->sql_fetchrow($result)) @@ -185,9 +185,9 @@ class phpbb_notification_type_quote extends phpbb_notification_type_post // Remove the necessary notifications if (!empty($remove_notifications)) { - $sql = 'DELETE FROM ' . $this->notifications_table . " - WHERE item_type = '" . $this->get_type() . "' - AND item_id = " . self::get_item_id($post) . ' + $sql = 'DELETE FROM ' . $this->notifications_table . ' + WHERE notification_type_id = ' . (int) $this->notification_type_id . ' + AND item_id = ' . self::get_item_id($post) . ' AND ' . $this->db->sql_in_set('user_id', $remove_notifications); $this->db->sql_query($sql); } diff --git a/phpBB/install/schemas/firebird_schema.sql b/phpBB/install/schemas/firebird_schema.sql index 92227eb38c..a64b8eeffc 100644 --- a/phpBB/install/schemas/firebird_schema.sql +++ b/phpBB/install/schemas/firebird_schema.sql @@ -1303,7 +1303,7 @@ CREATE INDEX phpbb_topics_watch_notify_stat ON phpbb_topics_watch(notify_status) # Table: 'phpbb_user_notifications' CREATE TABLE phpbb_user_notifications ( - notification_type_id INTEGER DEFAULT 0 NOT NULL, + item_type VARCHAR(255) CHARACTER SET NONE DEFAULT '' NOT NULL, item_id INTEGER DEFAULT 0 NOT NULL, user_id INTEGER DEFAULT 0 NOT NULL, method VARCHAR(255) CHARACTER SET NONE DEFAULT '' NOT NULL, diff --git a/phpBB/install/schemas/mssql_schema.sql b/phpBB/install/schemas/mssql_schema.sql index e869cbd1b5..8465dc4d72 100644 --- a/phpBB/install/schemas/mssql_schema.sql +++ b/phpBB/install/schemas/mssql_schema.sql @@ -1591,7 +1591,7 @@ GO Table: 'phpbb_user_notifications' */ CREATE TABLE [phpbb_user_notifications] ( - [notification_type_id] [int] DEFAULT (0) NOT NULL , + [item_type] [varchar] (255) DEFAULT ('') NOT NULL , [item_id] [int] DEFAULT (0) NOT NULL , [user_id] [int] DEFAULT (0) NOT NULL , [method] [varchar] (255) DEFAULT ('') NOT NULL , diff --git a/phpBB/install/schemas/mysql_40_schema.sql b/phpBB/install/schemas/mysql_40_schema.sql index 70048ea6bd..37e4e66ad7 100644 --- a/phpBB/install/schemas/mysql_40_schema.sql +++ b/phpBB/install/schemas/mysql_40_schema.sql @@ -913,7 +913,7 @@ CREATE TABLE phpbb_topics_watch ( # Table: 'phpbb_user_notifications' CREATE TABLE phpbb_user_notifications ( - notification_type_id smallint(4) UNSIGNED DEFAULT '0' NOT NULL, + item_type varbinary(255) DEFAULT '' NOT NULL, item_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, method varbinary(255) DEFAULT '' NOT NULL, diff --git a/phpBB/install/schemas/mysql_41_schema.sql b/phpBB/install/schemas/mysql_41_schema.sql index e5ab9ceafa..ff0f315f93 100644 --- a/phpBB/install/schemas/mysql_41_schema.sql +++ b/phpBB/install/schemas/mysql_41_schema.sql @@ -913,7 +913,7 @@ CREATE TABLE phpbb_topics_watch ( # Table: 'phpbb_user_notifications' CREATE TABLE phpbb_user_notifications ( - notification_type_id smallint(4) UNSIGNED DEFAULT '0' NOT NULL, + item_type varchar(255) DEFAULT '' NOT NULL, item_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, method varchar(255) DEFAULT '' NOT NULL, diff --git a/phpBB/install/schemas/oracle_schema.sql b/phpBB/install/schemas/oracle_schema.sql index b2e7409c7a..11f245869d 100644 --- a/phpBB/install/schemas/oracle_schema.sql +++ b/phpBB/install/schemas/oracle_schema.sql @@ -1720,7 +1720,7 @@ CREATE INDEX phpbb_topics_watch_notify_stat ON phpbb_topics_watch (notify_status Table: 'phpbb_user_notifications' */ CREATE TABLE phpbb_user_notifications ( - notification_type_id number(4) DEFAULT '0' NOT NULL, + item_type varchar2(255) DEFAULT '' , item_id number(8) DEFAULT '0' NOT NULL, user_id number(8) DEFAULT '0' NOT NULL, method varchar2(255) DEFAULT '' , diff --git a/phpBB/install/schemas/postgres_schema.sql b/phpBB/install/schemas/postgres_schema.sql index cd6de434b5..fea5700167 100644 --- a/phpBB/install/schemas/postgres_schema.sql +++ b/phpBB/install/schemas/postgres_schema.sql @@ -1175,7 +1175,7 @@ CREATE INDEX phpbb_topics_watch_notify_stat ON phpbb_topics_watch (notify_status Table: 'phpbb_user_notifications' */ CREATE TABLE phpbb_user_notifications ( - notification_type_id INT2 DEFAULT '0' NOT NULL CHECK (notification_type_id >= 0), + item_type varchar(255) DEFAULT '' NOT NULL, item_id INT4 DEFAULT '0' NOT NULL CHECK (item_id >= 0), user_id INT4 DEFAULT '0' NOT NULL CHECK (user_id >= 0), method varchar(255) DEFAULT '' NOT NULL, diff --git a/phpBB/install/schemas/sqlite_schema.sql b/phpBB/install/schemas/sqlite_schema.sql index e12bb624b6..02ffb9a857 100644 --- a/phpBB/install/schemas/sqlite_schema.sql +++ b/phpBB/install/schemas/sqlite_schema.sql @@ -884,7 +884,7 @@ CREATE INDEX phpbb_topics_watch_notify_stat ON phpbb_topics_watch (notify_status # Table: 'phpbb_user_notifications' CREATE TABLE phpbb_user_notifications ( - notification_type_id INTEGER UNSIGNED NOT NULL DEFAULT '0', + item_type varchar(255) NOT NULL DEFAULT '', item_id INTEGER UNSIGNED NOT NULL DEFAULT '0', user_id INTEGER UNSIGNED NOT NULL DEFAULT '0', method varchar(255) NOT NULL DEFAULT '', -- cgit v1.2.1 From 7bda5a016a726711855fb7a749f9f3638e63d1e3 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Mon, 29 Apr 2013 21:42:14 -0500 Subject: [ticket/11413] Prevent recursive function calls PHPBB3-11413 --- phpBB/includes/notification/manager.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'phpBB') diff --git a/phpBB/includes/notification/manager.php b/phpBB/includes/notification/manager.php index e7d6af71b8..a9eb503fb8 100644 --- a/phpBB/includes/notification/manager.php +++ b/phpBB/includes/notification/manager.php @@ -871,7 +871,10 @@ class phpbb_notification_manager if (!isset($notification_type_ids[$notification_type_name])) { - $notification_type = $this->get_item_type_class($notification_type_name); + if (!isset($this->notification_types[$notification_type_name]) && !isset($this->notification_types['notification.type.' . $notification_type_name])) + { + throw new phpbb_notification_exception('Notification type ' . $notification_type_name . ' does not exist'); + } $sql = 'INSERT INTO ' . $this->notification_types_table . ' ' . $this->db->sql_build_array('INSERT', array( 'notification_type_name' => $notification_type_name, -- cgit v1.2.1 From 4cd0914f8976913de0ec46cc78c8ac5731415838 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Mon, 29 Apr 2013 22:16:46 -0500 Subject: [ticket/11413] Fix notification tests Send types/methods the cache service, not the driver (not sure why the driver was sent before) PHPBB3-11413 --- phpBB/config/notifications.yml | 34 ++++++++++++++--------------- phpBB/includes/notification/exception.php | 29 ++++++++++++++++++++++++ phpBB/includes/notification/method/base.php | 4 ++-- phpBB/includes/notification/type/base.php | 4 ++-- 4 files changed, 50 insertions(+), 21 deletions(-) create mode 100644 phpBB/includes/notification/exception.php (limited to 'phpBB') diff --git a/phpBB/config/notifications.yml b/phpBB/config/notifications.yml index 60aa63a854..c66527941e 100644 --- a/phpBB/config/notifications.yml +++ b/phpBB/config/notifications.yml @@ -19,7 +19,7 @@ services: arguments: - @user_loader - @dbal.conn - - @cache.driver + - @cache - @user - @auth - @config @@ -37,7 +37,7 @@ services: arguments: - @user_loader - @dbal.conn - - @cache.driver + - @cache - @user - @auth - @config @@ -55,7 +55,7 @@ services: arguments: - @user_loader - @dbal.conn - - @cache.driver + - @cache - @user - @auth - @config @@ -73,7 +73,7 @@ services: arguments: - @user_loader - @dbal.conn - - @cache.driver + - @cache - @user - @auth - @config @@ -91,7 +91,7 @@ services: arguments: - @user_loader - @dbal.conn - - @cache.driver + - @cache - @user - @auth - @config @@ -109,7 +109,7 @@ services: arguments: - @user_loader - @dbal.conn - - @cache.driver + - @cache - @user - @auth - @config @@ -127,7 +127,7 @@ services: arguments: - @user_loader - @dbal.conn - - @cache.driver + - @cache - @user - @auth - @config @@ -145,7 +145,7 @@ services: arguments: - @user_loader - @dbal.conn - - @cache.driver + - @cache - @user - @auth - @config @@ -163,7 +163,7 @@ services: arguments: - @user_loader - @dbal.conn - - @cache.driver + - @cache - @user - @auth - @config @@ -181,7 +181,7 @@ services: arguments: - @user_loader - @dbal.conn - - @cache.driver + - @cache - @user - @auth - @config @@ -199,7 +199,7 @@ services: arguments: - @user_loader - @dbal.conn - - @cache.driver + - @cache - @user - @auth - @config @@ -217,7 +217,7 @@ services: arguments: - @user_loader - @dbal.conn - - @cache.driver + - @cache - @user - @auth - @config @@ -235,7 +235,7 @@ services: arguments: - @user_loader - @dbal.conn - - @cache.driver + - @cache - @user - @auth - @config @@ -253,7 +253,7 @@ services: arguments: - @user_loader - @dbal.conn - - @cache.driver + - @cache - @user - @auth - @config @@ -271,7 +271,7 @@ services: arguments: - @user_loader - @dbal.conn - - @cache.driver + - @cache - @user - @auth - @config @@ -289,7 +289,7 @@ services: arguments: - @user_loader - @dbal.conn - - @cache.driver + - @cache - @user - @auth - @config @@ -304,7 +304,7 @@ services: arguments: - @user_loader - @dbal.conn - - @cache.driver + - @cache - @user - @auth - @config diff --git a/phpBB/includes/notification/exception.php b/phpBB/includes/notification/exception.php new file mode 100644 index 0000000000..a52d6fdc57 --- /dev/null +++ b/phpBB/includes/notification/exception.php @@ -0,0 +1,29 @@ +getMessage(); + } +} diff --git a/phpBB/includes/notification/method/base.php b/phpBB/includes/notification/method/base.php index 22418c9be8..bae85310b2 100644 --- a/phpBB/includes/notification/method/base.php +++ b/phpBB/includes/notification/method/base.php @@ -66,7 +66,7 @@ abstract class phpbb_notification_method_base implements phpbb_notification_meth * * @param phpbb_user_loader $user_loader * @param phpbb_db_driver $db - * @param phpbb_cache_driver_interface $cache + * @param phpbb_cache_service $cache * @param phpbb_user $user * @param phpbb_auth $auth * @param phpbb_config $config @@ -74,7 +74,7 @@ abstract class phpbb_notification_method_base implements phpbb_notification_meth * @param string $php_ext * @return phpbb_notification_method_base */ - public function __construct(phpbb_user_loader $user_loader, phpbb_db_driver $db, phpbb_cache_driver_interface $cache, $user, phpbb_auth $auth, phpbb_config $config, $phpbb_root_path, $php_ext) + public function __construct(phpbb_user_loader $user_loader, phpbb_db_driver $db, phpbb_cache_service $cache, $user, phpbb_auth $auth, phpbb_config $config, $phpbb_root_path, $php_ext) { $this->user_loader = $user_loader; $this->db = $db; diff --git a/phpBB/includes/notification/type/base.php b/phpBB/includes/notification/type/base.php index f56956d16a..983383ce2a 100644 --- a/phpBB/includes/notification/type/base.php +++ b/phpBB/includes/notification/type/base.php @@ -96,7 +96,7 @@ abstract class phpbb_notification_type_base implements phpbb_notification_type_i * * @param phpbb_user_loader $user_loader * @param phpbb_db_driver $db - * @param phpbb_cache_driver_interface $cache + * @param phpbb_cache_service $cache * @param phpbb_user $user * @param phpbb_auth $auth * @param phpbb_config $config @@ -107,7 +107,7 @@ abstract class phpbb_notification_type_base implements phpbb_notification_type_i * @param string $user_notifications_table * @return phpbb_notification_type_base */ - public function __construct(phpbb_user_loader $user_loader, phpbb_db_driver $db, phpbb_cache_driver_interface $cache, $user, phpbb_auth $auth, phpbb_config $config, $phpbb_root_path, $php_ext, $notification_types_table, $notifications_table, $user_notifications_table) + public function __construct(phpbb_user_loader $user_loader, phpbb_db_driver $db, phpbb_cache_service $cache, $user, phpbb_auth $auth, phpbb_config $config, $phpbb_root_path, $php_ext, $notification_types_table, $notifications_table, $user_notifications_table) { $this->user_loader = $user_loader; $this->db = $db; -- cgit v1.2.1 From 947550df8f5e2ba624adc26ddd22c7fe74e4f602 Mon Sep 17 00:00:00 2001 From: Vjacheslav Trushkin Date: Tue, 30 Apr 2013 11:27:43 +0300 Subject: [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(-) (limited to 'phpBB') 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() { -- cgit v1.2.1 From 8a4260703fa76bb92f144b527b3d55289568db74 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 30 Apr 2013 10:32:01 +0200 Subject: [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 ++++++++++++------------ 2 files changed, 22 insertions(+), 22 deletions(-) (limited to 'phpBB') 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(); -- cgit v1.2.1 From 4810c61fd7b912ea2914b99f7db502b6f503068f Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 30 Apr 2013 10:37:59 +0200 Subject: [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 ++++++--- 2 files changed, 6 insertions(+), 12 deletions(-) (limited to 'phpBB') 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]) -- cgit v1.2.1 From 67f2edae170576104e619ffb38672cabf44e20fa Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 30 Apr 2013 13:54:50 +0200 Subject: [ticket/11495] Use descendants and ancestors instead of parents/children PHPBB3-11495 --- phpBB/includes/tree/interface.php | 28 ++++++++++++++-------------- phpBB/includes/tree/nestedset.php | 18 +++++++++--------- 2 files changed, 23 insertions(+), 23 deletions(-) (limited to 'phpBB') 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)) -- cgit v1.2.1 From 87e8e60d3c09c96a4495dda748673fb8b9078a3e Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 30 Apr 2013 14:12:45 +0200 Subject: [ticket/11495] Correctly distinguish between children and descendants PHPBB3-11495 --- phpBB/includes/tree/interface.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'phpBB') 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) -- cgit v1.2.1 From 863d0c7687cc926dfda0ddd20b34e7942748fb2e Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 30 Apr 2013 14:36:26 +0200 Subject: [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 +- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'phpBB') 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: [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(-) (limited to 'phpBB') 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(); } /** -- cgit v1.2.1 From 529e4c00fbb78ba513afbbacfb3d5465efbd82ef Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 30 Apr 2013 15:07:56 +0200 Subject: [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 | 111 ++++++++++++++++++++++++-------------- 1 file changed, 71 insertions(+), 40 deletions(-) (limited to 'phpBB') 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 ($reset_ids) + if ($acquired_new_lock = $this->acquire_lock()) { - if (!$this->lock->acquire()) - { - throw new RuntimeException($this->message_prefix . 'LOCK_FAILED_ACQUIRE'); - } $this->db->sql_transaction('begin'); + } + if ($reset_ids) + { $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; -- cgit v1.2.1 From 055ee41065fb0b7c08c66daff196eb2d3460b0cc Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 30 Apr 2013 15:16:41 +0200 Subject: [ticket/11495] Remove useless cast PHPBB3-11495 --- phpBB/includes/tree/nestedset.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB') 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]) { -- cgit v1.2.1 From 714092ab4e52dc039536a05846b50f4d4d488799 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 30 Apr 2013 15:48:29 +0200 Subject: [ticket/11495] Add owns_lock() method to lock classes PHPBB3-11495 --- phpBB/includes/lock/db.php | 11 +++++++++++ phpBB/includes/lock/flock.php | 11 +++++++++++ 2 files changed, 22 insertions(+) (limited to 'phpBB') 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. * -- cgit v1.2.1 From 78b0d3e723ab57c2e32b95a66159861fe461d77f Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 30 Apr 2013 15:50:14 +0200 Subject: [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(-) (limited to 'phpBB') 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; } /** -- cgit v1.2.1 From 6055a3cc7ed76cfe458ea524bfad66f475f35ce8 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 30 Apr 2013 16:19:25 +0200 Subject: [ticket/11495] Remove useless release_lock() method PHPBB3-11495 --- phpBB/includes/tree/nestedset.php | 38 ++++++++++++++------------------------ 1 file changed, 14 insertions(+), 24 deletions(-) (limited to 'phpBB') 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; -- cgit v1.2.1 From f3f7be4cd1a0495cf44787c713480d5aceb1bae1 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 30 Apr 2013 17:11:55 +0200 Subject: [ticket/11495] Fix @return doc of get_sql_where() PHPBB3-11495 --- phpBB/includes/tree/nestedset.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'phpBB') 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 = '') { -- cgit v1.2.1 From 5c4d69581afb9fd9b00d6b7b13cec257a97e875c Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 30 Apr 2013 18:06:29 +0200 Subject: [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(-) (limited to 'phpBB') 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); } -- cgit v1.2.1 From 98e6207c35910bf9761433e62ca5fe5af3459873 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 30 Apr 2013 18:13:32 +0200 Subject: [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(-) (limited to 'phpBB') 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 */ -- cgit v1.2.1 From 2f54a63b0fb998c84730e21a3af4150281c22cab Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 30 Apr 2013 18:24:54 +0200 Subject: [ticket/11495] Fix more grammar issues in doc blocks PHPBB3-11495 --- phpBB/includes/tree/interface.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'phpBB') 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 -- cgit v1.2.1 From 6a7378ecbdeea1ad356cbde8a085aa7510c61788 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 30 Apr 2013 18:39:22 +0200 Subject: [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(-) (limited to 'phpBB') 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 -- cgit v1.2.1 From a90a0b087ca3b1e29561a08019ca8ba2fa21c19d Mon Sep 17 00:00:00 2001 From: Dhruv Date: Tue, 30 Apr 2013 22:59:32 +0530 Subject: [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(-) (limited to 'phpBB') 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', -- cgit v1.2.1 From d7787682df0474b7bb78434339f8edde3727c580 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 30 Apr 2013 22:19:35 +0200 Subject: [ticket/11495] Throw exception when item that should be deleted does not exist PHPBB3-11495 --- phpBB/includes/tree/nestedset.php | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'phpBB') 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; -- cgit v1.2.1 From 81b2ad158c272cd306ea35a9b44875a5c11e7135 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Tue, 30 Apr 2013 21:01:46 -0500 Subject: [ticket/11413] Use sql_insert_buffer PHPBB3-11413 --- .../db/migration/data/310/notifications2.php | 27 +++++++--------------- 1 file changed, 8 insertions(+), 19 deletions(-) (limited to 'phpBB') diff --git a/phpBB/includes/db/migration/data/310/notifications2.php b/phpBB/includes/db/migration/data/310/notifications2.php index cd078f8f60..44b3f8fd49 100644 --- a/phpBB/includes/db/migration/data/310/notifications2.php +++ b/phpBB/includes/db/migration/data/310/notifications2.php @@ -108,7 +108,7 @@ class phpbb_db_migration_data_310_notifications2 extends phpbb_db_migration FROM ' . USERS_TABLE; $result = $this->db->sql_query($sql); - $sql_insert_data = array(); + $insert_buffer = new phpbb_db_sql_insert_buffer($this->db, $insert_table); while ($row = $this->db->sql_fetchrow($result)) { $notification_methods = array(); @@ -129,8 +129,8 @@ class phpbb_db_migration_data_310_notifications2 extends phpbb_db_migration // Notifications for posts foreach (array('post', 'topic') as $item_type) { - $sql_insert_data = $this->add_method_rows( - $sql_insert_data, + $this->add_method_rows( + $insert_buffer, $item_type, 0, $row['user_id'], @@ -142,30 +142,21 @@ class phpbb_db_migration_data_310_notifications2 extends phpbb_db_migration { // Notifications for private messages // User either gets all methods or no method - $sql_insert_data = $this->add_method_rows( - $sql_insert_data, + $this->add_method_rows( + $insert_buffer, 'pm', 0, $row['user_id'], $notification_methods ); } - - if (sizeof($sql_insert_data) > 500) - { - $this->db->sql_multi_insert($insert_table, $sql_insert_data); - $sql_insert_data = array(); - } } $this->db->sql_freeresult($result); - if (!empty($sql_insert_data)) - { - $this->db->sql_multi_insert($insert_table, $sql_insert_data); - } + $insert_buffer->flush(); } - protected function add_method_rows(array $sql_insert_data, $item_type, $item_id, $user_id, array $methods) + protected function add_method_rows(phpbb_db_sql_insert_buffer $insert_buffer, $item_type, $item_id, $user_id, array $methods) { $row_base = array( 'item_type' => $item_type, @@ -176,9 +167,7 @@ class phpbb_db_migration_data_310_notifications2 extends phpbb_db_migration foreach ($methods as $method) { $row_base['method'] = $method; - $sql_insert_data[] = $row_base; + $insert_buffer->insert($row_base); } - - return $sql_insert_data; } } -- cgit v1.2.1 From 2f2feaa4e8ad9a18fd9ddcb7d65ae958c544dbcb Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Tue, 30 Apr 2013 21:38:40 -0500 Subject: [ticket/11413] Don't use the database for the convert test Different databases seem to work slightly differently here and are causing errors PHPBB3-11413 --- phpBB/includes/db/migration/data/310/notifications2.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'phpBB') diff --git a/phpBB/includes/db/migration/data/310/notifications2.php b/phpBB/includes/db/migration/data/310/notifications2.php index 44b3f8fd49..c90944dcc9 100644 --- a/phpBB/includes/db/migration/data/310/notifications2.php +++ b/phpBB/includes/db/migration/data/310/notifications2.php @@ -100,7 +100,16 @@ class phpbb_db_migration_data_310_notifications2 extends phpbb_db_migration public function convert_notifications() { $insert_table = $this->table_prefix . 'user_notifications'; + $insert_buffer = new phpbb_db_sql_insert_buffer($this->db, $insert_table); + + $this->perform_conversion($insert_buffer, $insert_table); + } + /** + * Perform the conversion (separate for testability) + */ + public function perform_conversion($insert_buffer, $insert_table) + { $sql = 'DELETE FROM ' . $insert_table; $this->db->sql_query($sql); @@ -108,7 +117,6 @@ class phpbb_db_migration_data_310_notifications2 extends phpbb_db_migration FROM ' . USERS_TABLE; $result = $this->db->sql_query($sql); - $insert_buffer = new phpbb_db_sql_insert_buffer($this->db, $insert_table); while ($row = $this->db->sql_fetchrow($result)) { $notification_methods = array(); @@ -162,6 +170,7 @@ class phpbb_db_migration_data_310_notifications2 extends phpbb_db_migration 'item_type' => $item_type, 'item_id' => (int) $item_id, 'user_id' => (int) $user_id, + 'notify' => 1 ); foreach ($methods as $method) -- cgit v1.2.1 From 9db4e856db426c68d0e3055dbcad9754ce65779d Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Wed, 1 May 2013 13:00:43 -0500 Subject: [ticket/11415] Move while loop from ext manager to acp_extensions.php Now enable_step works as it's supposed to (do one step at a time) and less refreshes are required for the user. PHPBB3-11415 --- phpBB/includes/acp/acp_extensions.php | 34 +++++++++++++++++++++++++--------- phpBB/includes/extension/manager.php | 21 +++------------------ 2 files changed, 28 insertions(+), 27 deletions(-) (limited to 'phpBB') diff --git a/phpBB/includes/acp/acp_extensions.php b/phpBB/includes/acp/acp_extensions.php index e4defa0400..7fdeb1ff8b 100644 --- a/phpBB/includes/acp/acp_extensions.php +++ b/phpBB/includes/acp/acp_extensions.php @@ -44,6 +44,10 @@ class acp_extensions $action = $request->variable('action', 'list'); $ext_name = $request->variable('ext_name', ''); + // What is a safe limit of execution time? Half the max execution time should be safe. + $safe_time_limit = (ini_get('max_execution_time') / 2); + $start_time = time(); + // Cancel action if ($request->is_set_post('cancel')) { @@ -105,11 +109,15 @@ class acp_extensions try { - if ($phpbb_extension_manager->enable_step($ext_name)) + while ($phpbb_extension_manager->enable_step($ext_name)) { - $template->assign_var('S_NEXT_STEP', true); + // Are we approaching the time limit? If so we want to pause the update and continue after refreshing + if ((time() - $start_time) >= $safe_time_limit) + { + $template->assign_var('S_NEXT_STEP', true); - meta_refresh(0, $this->u_action . '&action=enable&ext_name=' . urlencode($ext_name)); + meta_refresh(0, $this->u_action . '&action=enable&ext_name=' . urlencode($ext_name)); + } } } catch (phpbb_db_migration_exception $e) @@ -139,11 +147,15 @@ class acp_extensions break; case 'disable': - if ($phpbb_extension_manager->disable_step($ext_name)) + while ($phpbb_extension_manager->disable_step($ext_name)) { - $template->assign_var('S_NEXT_STEP', true); + // Are we approaching the time limit? If so we want to pause the update and continue after refreshing + if ((time() - $start_time) >= $safe_time_limit) + { + $template->assign_var('S_NEXT_STEP', true); - meta_refresh(0, $this->u_action . '&action=disable&ext_name=' . urlencode($ext_name)); + meta_refresh(0, $this->u_action . '&action=disable&ext_name=' . urlencode($ext_name)); + } } $this->tpl_name = 'acp_ext_disable'; @@ -165,11 +177,15 @@ class acp_extensions case 'purge': try { - if ($phpbb_extension_manager->purge_step($ext_name)) + while ($phpbb_extension_manager->purge_step($ext_name)) { - $template->assign_var('S_NEXT_STEP', true); + // Are we approaching the time limit? If so we want to pause the update and continue after refreshing + if ((time() - $start_time) >= $safe_time_limit) + { + $template->assign_var('S_NEXT_STEP', true); - meta_refresh(0, $this->u_action . '&action=purge&ext_name=' . urlencode($ext_name)); + meta_refresh(0, $this->u_action . '&action=purge&ext_name=' . urlencode($ext_name)); + } } } catch (phpbb_db_migration_exception $e) diff --git a/phpBB/includes/extension/manager.php b/phpBB/includes/extension/manager.php index a1022762b8..d3e9d56501 100644 --- a/phpBB/includes/extension/manager.php +++ b/phpBB/includes/extension/manager.php @@ -546,22 +546,11 @@ class phpbb_extension_manager $migrations = $finder->get_classes_from_files($migrations); $this->migrator->set_migrations($migrations); - // What is a safe limit of execution time? Half the max execution time should be safe. - $safe_time_limit = (ini_get('max_execution_time') / 2); - $start_time = time(); - if ($mode == 'enable') { - while (!$this->migrator->finished()) - { - $this->migrator->update(); + $this->migrator->update(); - // Are we approaching the time limit? If so we want to pause the update and continue after refreshing - if ((time() - $start_time) >= $safe_time_limit) - { - return false; - } - } + return $this->migrator->finished(); } else if ($mode == 'purge') { @@ -571,11 +560,7 @@ class phpbb_extension_manager { $this->migrator->revert($migration); - // Are we approaching the time limit? If so we want to pause the update and continue after refreshing - if ((time() - $start_time) >= $safe_time_limit) - { - return false; - } + return false; } } } -- cgit v1.2.1 From 7ed21cc6f2b7eee305d0c7c00821ef1ce680b77e Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Wed, 1 May 2013 14:02:13 -0500 Subject: [ticket/11415] Move migrator to base extension class from ext.manager PHPBB3-11415 --- phpBB/includes/extension/base.php | 75 +++++++++++++++++++++++++++++-- phpBB/includes/extension/manager.php | 86 +++++++----------------------------- 2 files changed, 86 insertions(+), 75 deletions(-) (limited to 'phpBB') diff --git a/phpBB/includes/extension/base.php b/phpBB/includes/extension/base.php index d51589d719..dc6d771672 100644 --- a/phpBB/includes/extension/base.php +++ b/phpBB/includes/extension/base.php @@ -27,25 +27,42 @@ class phpbb_extension_base implements phpbb_extension_interface /** @var ContainerInterface */ protected $container; + /** @var string */ + protected $extension_name; + + /** @var string */ + protected $extension_path; + /** * Constructor * * @param ContainerInterface $container Container object + * @param string $extension_name Name of this extension (from ext.manager) + * @param string $extension_path Relative path to this extension */ - public function __construct(ContainerInterface $container) + public function __construct(ContainerInterface $container, $extension_name, $extension_path) { $this->container = $container; + + $this->extension_name = $extension_name; + $this->extension_path = $extension_path; } /** - * Single enable step that does nothing + * Single enable step that installs any included migrations * * @param mixed $old_state State returned by previous call of this method * @return false Indicates no further steps are required */ public function enable_step($old_state) { - return false; + $migrations = $this->get_migration_file_list(); + $migrator = $this->container->get('migrator'); + $migrator->set_migrations($migrations); + + $migrator->update(); + + return !$migrator->finished(); } /** @@ -60,13 +77,63 @@ class phpbb_extension_base implements phpbb_extension_interface } /** - * Single purge step that does nothing + * Single purge step that reverts any included and installed migrations * * @param mixed $old_state State returned by previous call of this method * @return false Indicates no further steps are required */ public function purge_step($old_state) { + $migrations = $this->get_migration_file_list(); + $migrator = $this->container->get('migrator'); + $migrator->set_migrations($migrations); + + foreach ($migrations as $migration) + { + while ($migrator->migration_state($migration) !== false) + { + $migrator->revert($migration); + + return true; + } + } + return false; } + + /** + * Get the list of migration files from this extension + * + * @return array + */ + protected function get_migration_file_list() + { + static $migrations = false; + + if ($migrations !== false) + { + return $migrations; + } + + // Only have the finder search in this extension path directory + $extensions = array( + $this->extension_name => $this->extension_path, + ); + + $extension_manager = $this->container->get('ext.manager'); + $finder = $extension_manager->get_finder(); + $migrations = array(); + $file_list = $finder + ->extension_directory('/migrations') + ->find_from_paths($extensions); + + foreach ($file_list as $file) + { + $migrations[$file['named_path']] = $file['ext_name']; + } + + $migrations = $finder->get_classes_from_files($migrations); + + return $migrations; + } } diff --git a/phpBB/includes/extension/manager.php b/phpBB/includes/extension/manager.php index d3e9d56501..8b8a69f14c 100644 --- a/phpBB/includes/extension/manager.php +++ b/phpBB/includes/extension/manager.php @@ -138,11 +138,11 @@ class phpbb_extension_manager if (class_exists($extension_class_name)) { - return new $extension_class_name($this->container); + return new $extension_class_name($this->container, $name, $this->get_extension_path($name, true)); } else { - return new phpbb_extension_base($this->container); + return new phpbb_extension_base($this->container, $name, $this->get_extension_path($name, true)); } } @@ -178,12 +178,6 @@ class phpbb_extension_manager $old_state = (isset($this->extensions[$name]['ext_state'])) ? unserialize($this->extensions[$name]['ext_state']) : false; - // Returns false if not completed - if (!$this->handle_migrations($name, 'enable')) - { - return true; - } - $extension = $this->get_extension($name); $state = $extension->enable_step($old_state); @@ -199,12 +193,21 @@ class phpbb_extension_manager $this->extensions[$name]['ext_path'] = $this->get_extension_path($extension_data['ext_name']); ksort($this->extensions); - $sql = 'UPDATE ' . $this->extension_table . ' - SET ' . $this->db->sql_build_array('UPDATE', $extension_data) . " + $sql = 'SELECT COUNT(ext_name) as row_count + FROM ' . $this->extension_table . " WHERE ext_name = '" . $this->db->sql_escape($name) . "'"; - $this->db->sql_query($sql); + $result = $this->db->sql_query($sql); + $count = $this->db->sql_fetchfield('row_count'); + $this->db->sql_freeresult($result); - if (!$this->db->sql_affectedrows()) + if ($count) + { + $sql = 'UPDATE ' . $this->extension_table . ' + SET ' . $this->db->sql_build_array('UPDATE', $extension_data) . " + WHERE ext_name = '" . $this->db->sql_escape($name) . "'"; + $this->db->sql_query($sql); + } + else { $sql = 'INSERT INTO ' . $this->extension_table . ' ' . $this->db->sql_build_array('INSERT', $extension_data); @@ -335,12 +338,6 @@ class phpbb_extension_manager $old_state = unserialize($this->extensions[$name]['ext_state']); - // Returns false if not completed - if (!$this->handle_migrations($name, 'purge')) - { - return true; - } - $extension = $this->get_extension($name); $state = $extension->purge_step($old_state); @@ -514,57 +511,4 @@ class phpbb_extension_manager { return new phpbb_extension_finder($this, $this->filesystem, $this->phpbb_root_path, $this->cache, $this->php_ext, $this->cache_name . '_finder'); } - - /** - * Handle installing/reverting migrations - * - * @param string $extension_name Name of the extension - * @param string $mode enable or purge - * @return bool True if completed, False if not completed - */ - protected function handle_migrations($extension_name, $mode) - { - $extensions = array( - $extension_name => $this->phpbb_root_path . $this->get_extension_path($extension_name), - ); - - $finder = $this->get_finder(); - $migrations = array(); - $file_list = $finder - ->extension_directory('/migrations') - ->find_from_paths($extensions); - - if (empty($file_list)) - { - return true; - } - - foreach ($file_list as $file) - { - $migrations[$file['named_path']] = $file['ext_name']; - } - $migrations = $finder->get_classes_from_files($migrations); - $this->migrator->set_migrations($migrations); - - if ($mode == 'enable') - { - $this->migrator->update(); - - return $this->migrator->finished(); - } - else if ($mode == 'purge') - { - foreach ($migrations as $migration) - { - while ($this->migrator->migration_state($migration) !== false) - { - $this->migrator->revert($migration); - - return false; - } - } - } - - return true; - } } -- cgit v1.2.1 From 60e32728393d4258f92f7893f8275889278a995f Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Wed, 1 May 2013 14:09:08 -0500 Subject: [ticket/11415] Remove migrator dependency from extension manager PHPBB3-11415 --- phpBB/config/services.yml | 1 - phpBB/includes/extension/manager.php | 5 +---- 2 files changed, 1 insertion(+), 5 deletions(-) (limited to 'phpBB') diff --git a/phpBB/config/services.yml b/phpBB/config/services.yml index 7923c94a3f..306dc2dc77 100644 --- a/phpBB/config/services.yml +++ b/phpBB/config/services.yml @@ -130,7 +130,6 @@ services: - @service_container - @dbal.conn - @config - - @migrator - @filesystem - %tables.ext% - %core.root_path% diff --git a/phpBB/includes/extension/manager.php b/phpBB/includes/extension/manager.php index 8b8a69f14c..b42043748f 100644 --- a/phpBB/includes/extension/manager.php +++ b/phpBB/includes/extension/manager.php @@ -29,7 +29,6 @@ class phpbb_extension_manager protected $db; protected $config; - protected $migrator; protected $cache; protected $php_ext; protected $extensions; @@ -43,7 +42,6 @@ class phpbb_extension_manager * @param ContainerInterface $container A container * @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. @@ -51,13 +49,12 @@ 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_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; $this->db = $db; $this->config = $config; - $this->migrator = $migrator; $this->cache = $cache; $this->filesystem = $filesystem; $this->php_ext = $php_ext; -- cgit v1.2.1 From 87b01fc854b22e3839776505486d5a564e671f5f Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Wed, 1 May 2013 15:18:53 -0500 Subject: [ticket/11415] Make migrator/ext.manager dependencies of the base ext class PHPBB3-11415 --- phpBB/includes/extension/base.php | 30 +++++++++++++++++++----------- phpBB/includes/extension/manager.php | 6 ++++-- 2 files changed, 23 insertions(+), 13 deletions(-) (limited to 'phpBB') diff --git a/phpBB/includes/extension/base.php b/phpBB/includes/extension/base.php index dc6d771672..2d22658ff1 100644 --- a/phpBB/includes/extension/base.php +++ b/phpBB/includes/extension/base.php @@ -27,6 +27,12 @@ class phpbb_extension_base implements phpbb_extension_interface /** @var ContainerInterface */ protected $container; + /** @var phpbb_extension_manager */ + protected $extension_manager; + + /** @var phpbb_db_migrator */ + protected $migrator; + /** @var string */ protected $extension_name; @@ -37,12 +43,15 @@ class phpbb_extension_base implements phpbb_extension_interface * Constructor * * @param ContainerInterface $container Container object + * @param phpbb_extension_manager $extension_manager * @param string $extension_name Name of this extension (from ext.manager) * @param string $extension_path Relative path to this extension */ - public function __construct(ContainerInterface $container, $extension_name, $extension_path) + public function __construct(ContainerInterface $container, phpbb_extension_manager $extension_manager, phpbb_db_migrator $migrator, $extension_name, $extension_path) { $this->container = $container; + $this->extension_manager = $extension_manager; + $this->migrator = $migrator; $this->extension_name = $extension_name; $this->extension_path = $extension_path; @@ -57,12 +66,12 @@ class phpbb_extension_base implements phpbb_extension_interface public function enable_step($old_state) { $migrations = $this->get_migration_file_list(); - $migrator = $this->container->get('migrator'); - $migrator->set_migrations($migrations); - $migrator->update(); + $this->migrator->set_migrations($migrations); - return !$migrator->finished(); + $this->migrator->update(); + + return !$this->migrator->finished(); } /** @@ -85,14 +94,14 @@ class phpbb_extension_base implements phpbb_extension_interface public function purge_step($old_state) { $migrations = $this->get_migration_file_list(); - $migrator = $this->container->get('migrator'); - $migrator->set_migrations($migrations); + + $this->migrator->set_migrations($migrations); foreach ($migrations as $migration) { - while ($migrator->migration_state($migration) !== false) + while ($this->migrator->migration_state($migration) !== false) { - $migrator->revert($migration); + $this->migrator->revert($migration); return true; } @@ -120,8 +129,7 @@ class phpbb_extension_base implements phpbb_extension_interface $this->extension_name => $this->extension_path, ); - $extension_manager = $this->container->get('ext.manager'); - $finder = $extension_manager->get_finder(); + $finder = $this->extension_manager->get_finder(); $migrations = array(); $file_list = $finder ->extension_directory('/migrations') diff --git a/phpBB/includes/extension/manager.php b/phpBB/includes/extension/manager.php index b42043748f..799c8b2418 100644 --- a/phpBB/includes/extension/manager.php +++ b/phpBB/includes/extension/manager.php @@ -133,13 +133,15 @@ class phpbb_extension_manager { $extension_class_name = 'phpbb_ext_' . str_replace('/', '_', $name) . '_ext'; + $migrator = $this->container->get('migrator'); + if (class_exists($extension_class_name)) { - return new $extension_class_name($this->container, $name, $this->get_extension_path($name, true)); + return new $extension_class_name($this->container, $this, $migrator, $name, $this->get_extension_path($name, true)); } else { - return new phpbb_extension_base($this->container, $name, $this->get_extension_path($name, true)); + return new phpbb_extension_base($this->container, $this, $migrator, $name, $this->get_extension_path($name, true)); } } -- cgit v1.2.1 From 32f247ed603a2b57ba0b30f4ce0d2429df33ab7e Mon Sep 17 00:00:00 2001 From: Oleg Pudeyev Date: Wed, 1 May 2013 17:14:36 -0400 Subject: [ticket/11435] Fit comment into 80 columns and link to php manual. PHPBB3-11435 --- phpBB/includes/template/filter.php | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) (limited to 'phpBB') 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: - Consider the following template: + http://www.php.net/manual/en/language.basic-syntax.phpmode.php + http://www.php.net/manual/en/language.basic-syntax.instruction-separation.php - - 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. + Consider the following template: - 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: + + some content + - inline 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 + 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 + 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 */ -- cgit v1.2.1 From 6d4a75b3cb9a403d37fe3ac7b3eda5e9c65ad9e0 Mon Sep 17 00:00:00 2001 From: hjpotter92 Date: Thu, 2 May 2013 06:29:32 +0530 Subject: [ticket/11517] Fix list numbering PHPBB3-11517 --- phpBB/docs/coding-guidelines.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB') 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

-- cgit v1.2.1 From 07c972f5d71f7aa56d6623774e977ea7958a906e Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Thu, 2 May 2013 15:39:26 -0500 Subject: [ticket/11413] Remove changes for ticket 11420 from this branch PHPBB3-11413 --- .../db/migration/data/310/notifications.php | 64 ++++++++++++++++++++++ 1 file changed, 64 insertions(+) (limited to 'phpBB') diff --git a/phpBB/includes/db/migration/data/310/notifications.php b/phpBB/includes/db/migration/data/310/notifications.php index 17c939d95a..82bfd4cb2d 100644 --- a/phpBB/includes/db/migration/data/310/notifications.php +++ b/phpBB/includes/db/migration/data/310/notifications.php @@ -91,6 +91,70 @@ class phpbb_db_migration_data_310_notifications extends phpbb_db_migration ), )), array('config.add', array('load_notifications', 1)), + array('custom', array(array($this, 'convert_notifications'))), ); } + + public function convert_notifications() + { + $convert_notifications = array( + array( + 'check' => ($this->config['allow_topic_notify']), + 'item_type' => 'post', + ), + array( + 'check' => ($this->config['allow_forum_notify']), + 'item_type' => 'topic', + ), + array( + 'check' => ($this->config['allow_bookmarks']), + 'item_type' => 'bookmark', + ), + array( + 'check' => ($this->config['allow_privmsg']), + 'item_type' => 'pm', + ), + ); + + foreach ($convert_notifications as $convert_data) + { + if ($convert_data['check']) + { + $sql = 'SELECT user_id, user_notify_type + FROM ' . USERS_TABLE . ' + WHERE user_notify = 1'; + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + $this->sql_query('INSERT INTO ' . $this->table_prefix . 'user_notifications ' . $this->db->sql_build_array('INSERT', array( + 'item_type' => $convert_data['item_type'], + 'item_id' => 0, + 'user_id' => $row['user_id'], + 'method' => '', + ))); + + if ($row['user_notify_type'] == NOTIFY_EMAIL || $row['user_notify_type'] == NOTIFY_BOTH) + { + $this->sql_query('INSERT INTO ' . $this->table_prefix . 'user_notifications ' . $this->db->sql_build_array('INSERT', array( + 'item_type' => $convert_data['item_type'], + 'item_id' => 0, + 'user_id' => $row['user_id'], + 'method' => 'email', + ))); + } + + if ($row['user_notify_type'] == NOTIFY_IM || $row['user_notify_type'] == NOTIFY_BOTH) + { + $this->sql_query('INSERT INTO ' . $this->table_prefix . 'user_notifications ' . $this->db->sql_build_array('INSERT', array( + 'item_type' => $convert_data['item_type'], + 'item_id' => 0, + 'user_id' => $row['user_id'], + 'method' => 'jabber', + ))); + } + } + $this->db->sql_freeresult($result); + } + } + } } -- cgit v1.2.1 From bc9b6c3b6c4081b1671224d69f973c923e105675 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Thu, 2 May 2013 15:49:17 -0500 Subject: [ticket/11413] Correct copyright year PHPBB3-11413 --- phpBB/includes/db/migration/data/310/notifications2.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB') diff --git a/phpBB/includes/db/migration/data/310/notifications2.php b/phpBB/includes/db/migration/data/310/notifications2.php index c90944dcc9..f655c6734b 100644 --- a/phpBB/includes/db/migration/data/310/notifications2.php +++ b/phpBB/includes/db/migration/data/310/notifications2.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 * */ -- cgit v1.2.1 From 5edae8af1f7d8d94141596b6391c8f967d9694db Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Thu, 2 May 2013 15:52:20 -0500 Subject: [ticket/11413] Remove conversion of user_notifications PHPBB3-11413 --- .../db/migration/data/310/notifications2.php | 90 ---------------------- 1 file changed, 90 deletions(-) (limited to 'phpBB') diff --git a/phpBB/includes/db/migration/data/310/notifications2.php b/phpBB/includes/db/migration/data/310/notifications2.php index f655c6734b..ce8343089f 100644 --- a/phpBB/includes/db/migration/data/310/notifications2.php +++ b/phpBB/includes/db/migration/data/310/notifications2.php @@ -89,94 +89,4 @@ class phpbb_db_migration_data_310_notifications2 extends phpbb_db_migration ), ); } - - public function update_data() - { - return array( - array('custom', array(array($this, 'convert_notifications'))), - ); - } - - public function convert_notifications() - { - $insert_table = $this->table_prefix . 'user_notifications'; - $insert_buffer = new phpbb_db_sql_insert_buffer($this->db, $insert_table); - - $this->perform_conversion($insert_buffer, $insert_table); - } - - /** - * Perform the conversion (separate for testability) - */ - public function perform_conversion($insert_buffer, $insert_table) - { - $sql = 'DELETE FROM ' . $insert_table; - $this->db->sql_query($sql); - - $sql = 'SELECT user_id, user_notify_type, user_notify_pm - FROM ' . USERS_TABLE; - $result = $this->db->sql_query($sql); - - while ($row = $this->db->sql_fetchrow($result)) - { - $notification_methods = array(); - - // In-board notification - $notification_methods[] = ''; - - if ($row['user_notify_type'] == NOTIFY_EMAIL || $row['user_notify_type'] == NOTIFY_BOTH) - { - $notification_methods[] = 'email'; - } - - if ($row['user_notify_type'] == NOTIFY_IM || $row['user_notify_type'] == NOTIFY_BOTH) - { - $notification_methods[] = 'jabber'; - } - - // Notifications for posts - foreach (array('post', 'topic') as $item_type) - { - $this->add_method_rows( - $insert_buffer, - $item_type, - 0, - $row['user_id'], - $notification_methods - ); - } - - if ($row['user_notify_pm']) - { - // Notifications for private messages - // User either gets all methods or no method - $this->add_method_rows( - $insert_buffer, - 'pm', - 0, - $row['user_id'], - $notification_methods - ); - } - } - $this->db->sql_freeresult($result); - - $insert_buffer->flush(); - } - - protected function add_method_rows(phpbb_db_sql_insert_buffer $insert_buffer, $item_type, $item_id, $user_id, array $methods) - { - $row_base = array( - 'item_type' => $item_type, - 'item_id' => (int) $item_id, - 'user_id' => (int) $user_id, - 'notify' => 1 - ); - - foreach ($methods as $method) - { - $row_base['method'] = $method; - $insert_buffer->insert($row_base); - } - } } -- cgit v1.2.1 From 3c76cdeb6701a4aded7a7c39b8c9b44c00b5848a Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Fri, 3 May 2013 08:50:27 -0500 Subject: [ticket/11413] Remove remaining irrelevant code to this PR PHPBB3-11413 --- phpBB/config/notifications.yml | 34 +++++++++++++++---------------- phpBB/includes/notification/type/base.php | 6 +++--- 2 files changed, 20 insertions(+), 20 deletions(-) (limited to 'phpBB') diff --git a/phpBB/config/notifications.yml b/phpBB/config/notifications.yml index c66527941e..60aa63a854 100644 --- a/phpBB/config/notifications.yml +++ b/phpBB/config/notifications.yml @@ -19,7 +19,7 @@ services: arguments: - @user_loader - @dbal.conn - - @cache + - @cache.driver - @user - @auth - @config @@ -37,7 +37,7 @@ services: arguments: - @user_loader - @dbal.conn - - @cache + - @cache.driver - @user - @auth - @config @@ -55,7 +55,7 @@ services: arguments: - @user_loader - @dbal.conn - - @cache + - @cache.driver - @user - @auth - @config @@ -73,7 +73,7 @@ services: arguments: - @user_loader - @dbal.conn - - @cache + - @cache.driver - @user - @auth - @config @@ -91,7 +91,7 @@ services: arguments: - @user_loader - @dbal.conn - - @cache + - @cache.driver - @user - @auth - @config @@ -109,7 +109,7 @@ services: arguments: - @user_loader - @dbal.conn - - @cache + - @cache.driver - @user - @auth - @config @@ -127,7 +127,7 @@ services: arguments: - @user_loader - @dbal.conn - - @cache + - @cache.driver - @user - @auth - @config @@ -145,7 +145,7 @@ services: arguments: - @user_loader - @dbal.conn - - @cache + - @cache.driver - @user - @auth - @config @@ -163,7 +163,7 @@ services: arguments: - @user_loader - @dbal.conn - - @cache + - @cache.driver - @user - @auth - @config @@ -181,7 +181,7 @@ services: arguments: - @user_loader - @dbal.conn - - @cache + - @cache.driver - @user - @auth - @config @@ -199,7 +199,7 @@ services: arguments: - @user_loader - @dbal.conn - - @cache + - @cache.driver - @user - @auth - @config @@ -217,7 +217,7 @@ services: arguments: - @user_loader - @dbal.conn - - @cache + - @cache.driver - @user - @auth - @config @@ -235,7 +235,7 @@ services: arguments: - @user_loader - @dbal.conn - - @cache + - @cache.driver - @user - @auth - @config @@ -253,7 +253,7 @@ services: arguments: - @user_loader - @dbal.conn - - @cache + - @cache.driver - @user - @auth - @config @@ -271,7 +271,7 @@ services: arguments: - @user_loader - @dbal.conn - - @cache + - @cache.driver - @user - @auth - @config @@ -289,7 +289,7 @@ services: arguments: - @user_loader - @dbal.conn - - @cache + - @cache.driver - @user - @auth - @config @@ -304,7 +304,7 @@ services: arguments: - @user_loader - @dbal.conn - - @cache + - @cache.driver - @user - @auth - @config diff --git a/phpBB/includes/notification/type/base.php b/phpBB/includes/notification/type/base.php index 983383ce2a..46517f1c9b 100644 --- a/phpBB/includes/notification/type/base.php +++ b/phpBB/includes/notification/type/base.php @@ -30,7 +30,7 @@ abstract class phpbb_notification_type_base implements phpbb_notification_type_i /** @var phpbb_db_driver */ protected $db; - /** @var phpbb_cache_service */ + /** @var phpbb_cache_driver_interface */ protected $cache; /** @var phpbb_template */ @@ -96,7 +96,7 @@ abstract class phpbb_notification_type_base implements phpbb_notification_type_i * * @param phpbb_user_loader $user_loader * @param phpbb_db_driver $db - * @param phpbb_cache_service $cache + * @param phpbb_cache_driver_interface $cache * @param phpbb_user $user * @param phpbb_auth $auth * @param phpbb_config $config @@ -107,7 +107,7 @@ abstract class phpbb_notification_type_base implements phpbb_notification_type_i * @param string $user_notifications_table * @return phpbb_notification_type_base */ - public function __construct(phpbb_user_loader $user_loader, phpbb_db_driver $db, phpbb_cache_service $cache, $user, phpbb_auth $auth, phpbb_config $config, $phpbb_root_path, $php_ext, $notification_types_table, $notifications_table, $user_notifications_table) + public function __construct(phpbb_user_loader $user_loader, phpbb_db_driver $db, phpbb_cache_driver_interface $cache, $user, phpbb_auth $auth, phpbb_config $config, $phpbb_root_path, $php_ext, $notification_types_table, $notifications_table, $user_notifications_table) { $this->user_loader = $user_loader; $this->db = $db; -- cgit v1.2.1 From 00d5cde04eb56b53179385c3ada075b1c207c3a3 Mon Sep 17 00:00:00 2001 From: Dhruv Date: Sat, 4 May 2013 14:44:33 +0530 Subject: [ticket/10325] fix acp language PHPBB3-10325 --- phpBB/language/en/acp/board.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB') 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.', -- cgit v1.2.1 From bfdc6e19300da8fa62d8661fcbd92548a2d2cf97 Mon Sep 17 00:00:00 2001 From: Dhruv Date: Sat, 4 May 2013 18:56:52 +0530 Subject: [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(-) (limited to 'phpBB') 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); -- cgit v1.2.1 From 153be855ca8fdee9549be9f51f940a385a0b4e03 Mon Sep 17 00:00:00 2001 From: Matt Friedman Date: Mon, 6 May 2013 09:49:37 -0700 Subject: [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(-) (limited to 'phpBB') 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 * */ -- cgit v1.2.1 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: [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 + phpBB/styles/prosilver/template/login_forum.html | 45 +++++++++++++---------- phpBB/styles/subsilver2/template/login_forum.html | 8 ++++ 7 files changed, 42 insertions(+), 28 deletions(-) (limited to 'phpBB') 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}

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

{L_LOGIN}

+ +

{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 @@ + + + +

+ +
-- cgit v1.2.1 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: [ticket/11144] Add missing {FORUM_NAME} variable Replace spaces with tabs PHPBB3-11144 --- phpBB/posting.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB') 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']) ); } -- cgit v1.2.1 From 665352d0d191cdf31a07ad50d00ffaf47da77a97 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Tue, 7 May 2013 23:49:24 +0200 Subject: [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(-) (limited to 'phpBB') 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}  
-- cgit v1.2.1 From 1834ceb614a1bf82aa0369a2b731475a82abfade Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Wed, 8 May 2013 00:08:35 +0200 Subject: [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(-) (limited to 'phpBB') 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(); } -- cgit v1.2.1 From b63a148e088572fd2b410705442aa575b8fe538f Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Mon, 18 Mar 2013 17:09:12 +0100 Subject: [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(-) (limited to 'phpBB') 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; -- cgit v1.2.1 From 5794b3d621b9d48b9bf7dcdcc7cc15585bddd021 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Mon, 18 Mar 2013 23:02:24 +0100 Subject: [ticket/11450] Sort parameters alphabetically PHPBB3-11450 --- phpBB/includes/extension/metadata_manager.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'phpBB') 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 = ''; -- cgit v1.2.1 From 001e3ebe9e9534ba0f05dd3a391a2a163a77347a Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Mon, 18 Mar 2013 23:09:37 +0100 Subject: [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(-) (limited to 'phpBB') 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) { -- cgit v1.2.1 From 62f35121d948bd177004628a4be2b4e8810a50bd Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Mon, 18 Mar 2013 23:15:27 +0100 Subject: [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 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'phpBB') 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); } /** -- cgit v1.2.1 From 284011ebf256bffb9544493c7b82f90eeff4ae39 Mon Sep 17 00:00:00 2001 From: Dhruv Date: Wed, 8 May 2013 17:04:03 +0530 Subject: [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 (limited to 'phpBB') 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)), + ); + } +} -- cgit v1.2.1 From b3d16f21a80df845890de5fe658648ea545dbfbc Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Thu, 9 May 2013 02:29:03 +0200 Subject: [ticket/11526] Increase composer minimum stability in olympus to stable. PHPBB3-11526 --- phpBB/composer.json | 1 - 1 file changed, 1 deletion(-) (limited to 'phpBB') 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" } -- cgit v1.2.1 From 5ea75ddf099c036be04fc0b83d5a10de4efaa0b8 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Thu, 9 May 2013 02:45:26 +0200 Subject: [ticket/11526] Update all dependencies / regenerate composer.lock. PHPBB3-11526 --- phpBB/composer.lock | 279 +++++++++++++++++++++++++--------------------------- 1 file changed, 135 insertions(+), 144 deletions(-) (limited to 'phpBB') 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", + "client", "curl", + "framework", "http", - "rest", "http client", - "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": [ + ] } -- cgit v1.2.1 From 585f0bc827673cc633b6c43081568d3551e97ae8 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Fri, 3 May 2013 22:16:31 +0200 Subject: [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(-) (limited to 'phpBB') 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.*" } } -- cgit v1.2.1 From a42514105d710bf16f30fed467418128501ca88e Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Fri, 3 May 2013 22:41:24 +0200 Subject: [ticket/11513] Update (all) composer dependencies. PHPBB3-11513 --- phpBB/composer.lock | 461 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 460 insertions(+), 1 deletion(-) (limited to 'phpBB') 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": [ -- cgit v1.2.1 From a50d23078e8964396bda1e2c9cfc6e503f4f6fb9 Mon Sep 17 00:00:00 2001 From: OpenShift guest Date: Fri, 10 May 2013 10:15:25 -0400 Subject: [ticket/11458] Use finder to get all permission language files PHPBB3-11458 --- phpBB/includes/functions_admin.php | 47 ++++++++++---------------------------- 1 file changed, 12 insertions(+), 35 deletions(-) (limited to 'phpBB') diff --git a/phpBB/includes/functions_admin.php b/phpBB/includes/functions_admin.php index b5efa49159..d9e445cff9 100644 --- a/phpBB/includes/functions_admin.php +++ b/phpBB/includes/functions_admin.php @@ -3042,50 +3042,27 @@ function add_permission_language() { global $user, $phpEx, $phpbb_extension_manager; - // First of all, our own file. We need to include it as the first file because it presets all relevant variables. - $user->add_lang('acp/permissions_phpbb'); - - $files_to_add = array(); - - // Now search in acp and mods folder for permissions_ files. - foreach (array('acp/', 'mods/') as $path) - { - $dh = @opendir($user->lang_path . $user->lang_name . '/' . $path); - - if ($dh) - { - while (($file = readdir($dh)) !== false) - { - if ($file !== 'permissions_phpbb.' . $phpEx && strpos($file, 'permissions_') === 0 && substr($file, -(strlen($phpEx) + 1)) === '.' . $phpEx) - { - $files_to_add[] = $path . substr($file, 0, -(strlen($phpEx) + 1)); - } - } - closedir($dh); - } - } - - // find permission language files from extensions + // add permission language files from extensions $finder = $phpbb_extension_manager->get_finder(); - $ext_lang_files = $finder + $lang_files = $finder ->prefix('permissions_') ->suffix(".$phpEx") + ->core_path('language/' . $user->lang_name . '/') ->extension_directory('/language/' . $user->lang_name) ->find(); - foreach ($ext_lang_files as $lang_file => $ext_name) + foreach ($lang_files as $lang_file => $ext_name) { - $user->add_lang_ext($ext_name, $lang_file); - } - - if (!sizeof($files_to_add)) - { - return false; + if ($ext_name === '/') + { + $user->add_lang($lang_file); + } + else + { + $user->add_lang_ext($ext_name, $lang_file); + } } - - $user->add_lang($files_to_add); - return true; } /** -- cgit v1.2.1 From c9ff3151323fd764354dad5538740baa7c9d8104 Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Fri, 10 May 2013 13:40:49 -0500 Subject: [ticket/11413] Rename file to something more helpful PHPBB3-11413 --- .../db/migration/data/310/notifications2.php | 92 ---------------------- .../data/310/notifications_schema_fix.php | 92 ++++++++++++++++++++++ 2 files changed, 92 insertions(+), 92 deletions(-) delete mode 100644 phpBB/includes/db/migration/data/310/notifications2.php create mode 100644 phpBB/includes/db/migration/data/310/notifications_schema_fix.php (limited to 'phpBB') diff --git a/phpBB/includes/db/migration/data/310/notifications2.php b/phpBB/includes/db/migration/data/310/notifications2.php deleted file mode 100644 index ce8343089f..0000000000 --- a/phpBB/includes/db/migration/data/310/notifications2.php +++ /dev/null @@ -1,92 +0,0 @@ - array( - $this->table_prefix . 'notification_types', - $this->table_prefix . 'notifications', - ), - 'add_tables' => array( - $this->table_prefix . 'notification_types' => array( - 'COLUMNS' => array( - 'notification_type_id' => array('USINT', NULL, 'auto_increment'), - 'notification_type_name' => array('VCHAR:255', ''), - 'notification_type_enabled' => array('BOOL', 1), - ), - 'PRIMARY_KEY' => array('notification_type_id'), - 'KEYS' => array( - 'type' => array('UNIQUE', array('notification_type_name')), - ), - ), - $this->table_prefix . 'notifications' => array( - 'COLUMNS' => array( - 'notification_id' => array('UINT:10', NULL, 'auto_increment'), - 'notification_type_id' => array('USINT', 0), - 'item_id' => array('UINT', 0), - 'item_parent_id' => array('UINT', 0), - 'user_id' => array('UINT', 0), - 'notification_read' => array('BOOL', 0), - 'notification_time' => array('TIMESTAMP', 1), - 'notification_data' => array('TEXT_UNI', ''), - ), - 'PRIMARY_KEY' => 'notification_id', - 'KEYS' => array( - 'item_ident' => array('INDEX', array('notification_type_id', 'item_id')), - 'user' => array('INDEX', array('user_id', 'notification_read')), - ), - ), - ), - ); - } - - public function revert_schema() - { - return array( - 'drop_tables' => array( - $this->table_prefix . 'notification_types', - $this->table_prefix . 'notifications', - ), - 'add_tables' => array( - $this->table_prefix . 'notification_types' => array( - 'COLUMNS' => array( - 'notification_type' => array('VCHAR:255', ''), - 'notification_type_enabled' => array('BOOL', 1), - ), - 'PRIMARY_KEY' => array('notification_type', 'notification_type_enabled'), - ), - $this->table_prefix . 'notifications' => array( - 'COLUMNS' => array( - 'notification_id' => array('UINT', NULL, 'auto_increment'), - 'item_type' => array('VCHAR:255', ''), - 'item_id' => array('UINT', 0), - 'item_parent_id' => array('UINT', 0), - 'user_id' => array('UINT', 0), - 'notification_read' => array('BOOL', 0), - 'notification_time' => array('TIMESTAMP', 1), - 'notification_data' => array('TEXT_UNI', ''), - ), - 'PRIMARY_KEY' => 'notification_id', - 'KEYS' => array( - 'item_ident' => array('INDEX', array('item_type', 'item_id')), - 'user' => array('INDEX', array('user_id', 'notification_read')), - ), - ), - ), - ); - } -} diff --git a/phpBB/includes/db/migration/data/310/notifications_schema_fix.php b/phpBB/includes/db/migration/data/310/notifications_schema_fix.php new file mode 100644 index 0000000000..27e63e10d0 --- /dev/null +++ b/phpBB/includes/db/migration/data/310/notifications_schema_fix.php @@ -0,0 +1,92 @@ + array( + $this->table_prefix . 'notification_types', + $this->table_prefix . 'notifications', + ), + 'add_tables' => array( + $this->table_prefix . 'notification_types' => array( + 'COLUMNS' => array( + 'notification_type_id' => array('USINT', NULL, 'auto_increment'), + 'notification_type_name' => array('VCHAR:255', ''), + 'notification_type_enabled' => array('BOOL', 1), + ), + 'PRIMARY_KEY' => array('notification_type_id'), + 'KEYS' => array( + 'type' => array('UNIQUE', array('notification_type_name')), + ), + ), + $this->table_prefix . 'notifications' => array( + 'COLUMNS' => array( + 'notification_id' => array('UINT:10', NULL, 'auto_increment'), + 'notification_type_id' => array('USINT', 0), + 'item_id' => array('UINT', 0), + 'item_parent_id' => array('UINT', 0), + 'user_id' => array('UINT', 0), + 'notification_read' => array('BOOL', 0), + 'notification_time' => array('TIMESTAMP', 1), + 'notification_data' => array('TEXT_UNI', ''), + ), + 'PRIMARY_KEY' => 'notification_id', + 'KEYS' => array( + 'item_ident' => array('INDEX', array('notification_type_id', 'item_id')), + 'user' => array('INDEX', array('user_id', 'notification_read')), + ), + ), + ), + ); + } + + public function revert_schema() + { + return array( + 'drop_tables' => array( + $this->table_prefix . 'notification_types', + $this->table_prefix . 'notifications', + ), + 'add_tables' => array( + $this->table_prefix . 'notification_types' => array( + 'COLUMNS' => array( + 'notification_type' => array('VCHAR:255', ''), + 'notification_type_enabled' => array('BOOL', 1), + ), + 'PRIMARY_KEY' => array('notification_type', 'notification_type_enabled'), + ), + $this->table_prefix . 'notifications' => array( + 'COLUMNS' => array( + 'notification_id' => array('UINT', NULL, 'auto_increment'), + 'item_type' => array('VCHAR:255', ''), + 'item_id' => array('UINT', 0), + 'item_parent_id' => array('UINT', 0), + 'user_id' => array('UINT', 0), + 'notification_read' => array('BOOL', 0), + 'notification_time' => array('TIMESTAMP', 1), + 'notification_data' => array('TEXT_UNI', ''), + ), + 'PRIMARY_KEY' => 'notification_id', + 'KEYS' => array( + 'item_ident' => array('INDEX', array('item_type', 'item_id')), + 'user' => array('INDEX', array('user_id', 'notification_read')), + ), + ), + ), + ); + } +} -- cgit v1.2.1 From 7d66a9ad525049b8df453ba0325e3dd38fb1157a Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Fri, 10 May 2013 13:42:54 -0500 Subject: [ticket/11413] Translate the error PHPBB3-11413 --- phpBB/includes/notification/manager.php | 2 +- phpBB/language/en/common.php | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'phpBB') diff --git a/phpBB/includes/notification/manager.php b/phpBB/includes/notification/manager.php index a9eb503fb8..bf437e95f0 100644 --- a/phpBB/includes/notification/manager.php +++ b/phpBB/includes/notification/manager.php @@ -873,7 +873,7 @@ class phpbb_notification_manager { if (!isset($this->notification_types[$notification_type_name]) && !isset($this->notification_types['notification.type.' . $notification_type_name])) { - throw new phpbb_notification_exception('Notification type ' . $notification_type_name . ' does not exist'); + throw new phpbb_notification_exception($user->lang('NOTIFICATION_TYPE_NOT_EXIST', $notification_type_name)); } $sql = 'INSERT INTO ' . $this->notification_types_table . ' ' . $this->db->sql_build_array('INSERT', array( diff --git a/phpBB/language/en/common.php b/phpBB/language/en/common.php index c1d6ef4af3..47a77d1dee 100644 --- a/phpBB/language/en/common.php +++ b/phpBB/language/en/common.php @@ -424,6 +424,7 @@ $lang = array_merge($lang, array( 'NOTIFICATION_TOPIC_APPROVED' => 'Your topic "%2$s" in the forum "%3$s" was approved.', 'NOTIFICATION_TOPIC_DISAPPROVED' => 'Your topic "%1$s" was disapproved for reason: "%2$s".', 'NOTIFICATION_TOPIC_IN_QUEUE' => 'A new topic titled "%2$s" was posted by %1$s and needs approval.', + 'NOTIFICATION_TYPE_NOT_EXIST' => 'The notification type "%s" is missing from the file system.', 'NOTIFY_ADMIN' => 'Please notify the board administrator or webmaster.', 'NOTIFY_ADMIN_EMAIL' => 'Please notify the board administrator or webmaster: %1$s', 'NO_ACCESS_ATTACHMENT' => 'You are not allowed to access this file.', -- cgit v1.2.1 From 27b2bbb8ff9efc6e06cfc5077dc939b1f1f7d0e5 Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Fri, 10 May 2013 13:58:55 -0500 Subject: [ticket/11415] Create function in finder find_from_extension PHPBB3-11415 --- phpBB/includes/extension/base.php | 15 ++------------- phpBB/includes/extension/finder.php | 28 ++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 13 deletions(-) (limited to 'phpBB') diff --git a/phpBB/includes/extension/base.php b/phpBB/includes/extension/base.php index 2d22658ff1..a6c9bbb5bc 100644 --- a/phpBB/includes/extension/base.php +++ b/phpBB/includes/extension/base.php @@ -125,21 +125,10 @@ class phpbb_extension_base implements phpbb_extension_interface } // Only have the finder search in this extension path directory - $extensions = array( - $this->extension_name => $this->extension_path, - ); - $finder = $this->extension_manager->get_finder(); - $migrations = array(); - $file_list = $finder + $migrations = $finder ->extension_directory('/migrations') - ->find_from_paths($extensions); - - foreach ($file_list as $file) - { - $migrations[$file['named_path']] = $file['ext_name']; - } - + ->find_from_extension($this->extension_name, $this->extension_path); $migrations = $finder->get_classes_from_files($migrations); return $migrations; diff --git a/phpBB/includes/extension/finder.php b/phpBB/includes/extension/finder.php index 766b9e9b63..49bb2a514f 100644 --- a/phpBB/includes/extension/finder.php +++ b/phpBB/includes/extension/finder.php @@ -377,6 +377,34 @@ class phpbb_extension_finder return $files; } + + /** + * Finds all file system entries matching the configured options for one + * specific extension + * + * @param string $extension_name Name of the extension + * @param string $extension_path Relative path to the extension root directory + * @param bool $cache Whether the result should be cached + * @param bool $is_dir Directories will be returned when true, only files + * otherwise + * @return array An array of paths to found items + */ + public function find_from_extension($extension_name, $extension_path, $cache = true, $is_dir = false) + { + $extensions = array( + $extension_name => $extension_path, + ); + + $files = array(); + $file_list = $this->find_from_paths($extensions, $cache, $is_dir); + + foreach ($file_list as $file) + { + $files[$file['named_path']] = $file['ext_name']; + } + + return $files; + } /** * Finds all file system entries matching the configured options from -- cgit v1.2.1 From f91f8666fd423c3e9f74d05355c8fa3e8ece2de9 Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Fri, 10 May 2013 14:01:31 -0500 Subject: [ticket/11415] Send the extension base the finder rather than the manager PHPBB3-11415 --- phpBB/includes/extension/base.php | 15 +++++++-------- phpBB/includes/extension/manager.php | 4 ++-- 2 files changed, 9 insertions(+), 10 deletions(-) (limited to 'phpBB') diff --git a/phpBB/includes/extension/base.php b/phpBB/includes/extension/base.php index a6c9bbb5bc..c4462b64d8 100644 --- a/phpBB/includes/extension/base.php +++ b/phpBB/includes/extension/base.php @@ -27,8 +27,8 @@ class phpbb_extension_base implements phpbb_extension_interface /** @var ContainerInterface */ protected $container; - /** @var phpbb_extension_manager */ - protected $extension_manager; + /** @var phpbb_extension_finder */ + protected $finder; /** @var phpbb_db_migrator */ protected $migrator; @@ -43,14 +43,14 @@ class phpbb_extension_base implements phpbb_extension_interface * Constructor * * @param ContainerInterface $container Container object - * @param phpbb_extension_manager $extension_manager + * @param phpbb_extension_finder $extension_finder * @param string $extension_name Name of this extension (from ext.manager) * @param string $extension_path Relative path to this extension */ - public function __construct(ContainerInterface $container, phpbb_extension_manager $extension_manager, phpbb_db_migrator $migrator, $extension_name, $extension_path) + public function __construct(ContainerInterface $container, phpbb_extension_finder $extension_finder, phpbb_db_migrator $migrator, $extension_name, $extension_path) { $this->container = $container; - $this->extension_manager = $extension_manager; + $this->extension_finder = $extension_finder; $this->migrator = $migrator; $this->extension_name = $extension_name; @@ -125,11 +125,10 @@ class phpbb_extension_base implements phpbb_extension_interface } // Only have the finder search in this extension path directory - $finder = $this->extension_manager->get_finder(); - $migrations = $finder + $migrations = $this->extension_finder ->extension_directory('/migrations') ->find_from_extension($this->extension_name, $this->extension_path); - $migrations = $finder->get_classes_from_files($migrations); + $migrations = $this->extension_finder->get_classes_from_files($migrations); return $migrations; } diff --git a/phpBB/includes/extension/manager.php b/phpBB/includes/extension/manager.php index 799c8b2418..48b72bcdd0 100644 --- a/phpBB/includes/extension/manager.php +++ b/phpBB/includes/extension/manager.php @@ -137,11 +137,11 @@ class phpbb_extension_manager if (class_exists($extension_class_name)) { - return new $extension_class_name($this->container, $this, $migrator, $name, $this->get_extension_path($name, true)); + return new $extension_class_name($this->container, $this->get_finder(), $migrator, $name, $this->get_extension_path($name, true)); } else { - return new phpbb_extension_base($this->container, $this, $migrator, $name, $this->get_extension_path($name, true)); + return new phpbb_extension_base($this->container, $this->get_finder(), $migrator, $name, $this->get_extension_path($name, true)); } } -- cgit v1.2.1 From b40c6fe46ae6e9ebdbbafd22b75d2d0ac0804e97 Mon Sep 17 00:00:00 2001 From: Vjacheslav Trushkin Date: Sat, 11 May 2013 23:30:44 +0300 Subject: [ticket/11533] Columns counter for notification settings Add columns counter template variable. It counts number of notification types + column for name + column for checkbox PHPBB3-11533 --- phpBB/includes/ucp/ucp_notifications.php | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'phpBB') diff --git a/phpBB/includes/ucp/ucp_notifications.php b/phpBB/includes/ucp/ucp_notifications.php index 338c921e94..72c41776b3 100644 --- a/phpBB/includes/ucp/ucp_notifications.php +++ b/phpBB/includes/ucp/ucp_notifications.php @@ -200,6 +200,10 @@ class ucp_notifications } } } + + $template->assign_vars(array( + strtoupper($block) . '_COLS' => sizeof($notification_methods) + 2, + )); } /** -- cgit v1.2.1 From f129fdb5597413f15a61b9a1c98b7aa07feec3c8 Mon Sep 17 00:00:00 2001 From: Vjacheslav Trushkin Date: Sat, 11 May 2013 23:32:23 +0300 Subject: [ticket/11533] Change list to table for notification settings PHPBB3-11533 --- .../prosilver/template/ucp_notifications.html | 59 +++++++++------------- 1 file changed, 25 insertions(+), 34 deletions(-) (limited to 'phpBB') diff --git a/phpBB/styles/prosilver/template/ucp_notifications.html b/phpBB/styles/prosilver/template/ucp_notifications.html index df59c55e40..723609e460 100644 --- a/phpBB/styles/prosilver/template/ucp_notifications.html +++ b/phpBB/styles/prosilver/template/ucp_notifications.html @@ -9,44 +9,35 @@

{TITLE_EXPLAIN}

-
    -
  • -
    -
    {L_NOTIFICATION_TYPE}
    - -
    {notification_methods.NAME}
    - -
    {L_NOTIFICATIONS}
    -
    -
  • -
-
    - - - -
  • -
    -
    - {notification_types.GROUP_NAME} -
    -
    -
  • - -
  • -
    -
    + + + + + + + + + + + + + + + + + -
    checked="checked" /> {notification_methods.NAME}
    + -
    checked="checked" /> {L_NOTIFICATIONS}
    - - - - - + + + + + +
    {L_NOTIFICATION_TYPE}{notification_methods.NAME}{L_NOTIFICATIONS}
    {notification_types.GROUP_NAME}
    {notification_types.NAME}
       {notification_types.EXPLAIN} - +
    checked="checked" /> checked="checked" />
    -- cgit v1.2.1 From 858f644c38b15f8205ac862422370d8d46ceede2 Mon Sep 17 00:00:00 2001 From: Vjacheslav Trushkin Date: Sat, 11 May 2013 23:32:55 +0300 Subject: [ticket/11533] Fix colspan and unnecessary tables Fix colspan and remove unnecessary tables in notification settings page in subsilver2. PHPBB3-11533 --- .../subsilver2/template/ucp_notifications.html | 238 ++++++++++----------- 1 file changed, 115 insertions(+), 123 deletions(-) (limited to 'phpBB') diff --git a/phpBB/styles/subsilver2/template/ucp_notifications.html b/phpBB/styles/subsilver2/template/ucp_notifications.html index 1a1fda4c17..d85584d20e 100644 --- a/phpBB/styles/subsilver2/template/ucp_notifications.html +++ b/phpBB/styles/subsilver2/template/ucp_notifications.html @@ -2,145 +2,137 @@ - + +
    - + - + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + +
    {TITLE}{TITLE}
    {TITLE_EXPLAIN}{TITLE_EXPLAIN}
    {L_NOTIFICATION_TYPE}{L_NOTIFICATIONS}{notification_methods.NAME}
    {L_NOTIFICATION_TYPE}{L_NOTIFICATIONS}{notification_methods.NAME}
    {notification_types.GROUP_NAME}
    - {notification_types.NAME} -
       {notification_types.EXPLAIN} -
    checked="checked" /> checked="checked" />
    - - {S_HIDDEN_FIELDS} -    - - {S_FORM_TOKEN} -
    {notification_types.GROUP_NAME}
    + {notification_types.NAME} +
       {notification_types.EXPLAIN} +
    checked="checked" /> checked="checked" />
    + + {S_HIDDEN_FIELDS} +    + + {S_FORM_TOKEN} +
    + + -
    - + + +
    + - +
    - - - - - -
    - - - - - - -
     [ {TOTAL_COUNT}
    - -
    +
    + + + + + + +
     [ {TOTAL_COUNT}
    +
    +
    -
    - -
    - - - - - - - - - - - - - - - - - - +
    +
    - - - - -
    -
    {L_NOTIFICATIONS}{L_MARK_READ}
    - {notification_list.AVATAR} - - - - - - - {notification_list.FORMATTED_TITLE} -
    - » {notification_list.TIME} -
    -
    - -
    - - {S_HIDDEN_FIELDS} - - {S_FORM_TOKEN} -
    + + + + + + + + + + + + + + + + + + +
    + + +
    - - -
    +
    {L_NOTIFICATIONS}{L_MARK_READ}
    + {notification_list.AVATAR} + + + + + + + {notification_list.FORMATTED_TITLE} +
    + » {notification_list.TIME} +
    +
    + +
    + + {S_HIDDEN_FIELDS} + + {S_FORM_TOKEN} +
    +
    - - - - - + +
    - - - - -
    - -
    -
    + + - + + +
    + + + +
    + +
    - -
    -
    + -- cgit v1.2.1 From d680aac7c5662223f1f491b244456220450cac23 Mon Sep 17 00:00:00 2001 From: gamerchan Date: Fri, 3 May 2013 11:10:53 +0530 Subject: [ticket/11105] Added spaces between ; and "url=" to adhere to w3c conventions. There was no space between ; and the string "url=". But according to w3c, we should have atleast one space between them. So, added space characters accordingly. PHPBB3-11105 --- phpBB/includes/functions.php | 2 +- phpBB/install/install_convert.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'phpBB') diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index 98a1dab722..cf676a3351 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -2740,7 +2740,7 @@ function meta_refresh($time, $url, $disable_cd_check = false) // For XHTML compatibility we change back & to & $template->assign_vars(array( - 'META' => '') + 'META' => '') ); return $url; diff --git a/phpBB/install/install_convert.php b/phpBB/install/install_convert.php index 62efc3e46b..fb97255981 100644 --- a/phpBB/install/install_convert.php +++ b/phpBB/install/install_convert.php @@ -2087,7 +2087,7 @@ class install_convert extends module // Because we should not rely on correct settings, we simply use the relative path here directly. $template->assign_vars(array( 'S_REFRESH' => true, - 'META' => '') + 'META' => '') ); } } -- cgit v1.2.1 From ad430ae406fc2bfc21f35ee068b1eb809f39f963 Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Mon, 13 May 2013 00:41:57 -0500 Subject: [ticket/11413] $user should have been $this->user PHPBB3-11413 --- phpBB/includes/notification/manager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'phpBB') diff --git a/phpBB/includes/notification/manager.php b/phpBB/includes/notification/manager.php index bf437e95f0..97833710c0 100644 --- a/phpBB/includes/notification/manager.php +++ b/phpBB/includes/notification/manager.php @@ -873,7 +873,7 @@ class phpbb_notification_manager { if (!isset($this->notification_types[$notification_type_name]) && !isset($this->notification_types['notification.type.' . $notification_type_name])) { - throw new phpbb_notification_exception($user->lang('NOTIFICATION_TYPE_NOT_EXIST', $notification_type_name)); + throw new phpbb_notification_exception($this->user->lang('NOTIFICATION_TYPE_NOT_EXIST', $notification_type_name)); } $sql = 'INSERT INTO ' . $this->notification_types_table . ' ' . $this->db->sql_build_array('INSERT', array( -- cgit v1.2.1 From 05cd045923068b08962856ec5e0c36f72f8f831c Mon Sep 17 00:00:00 2001 From: Nathaniel Guse Date: Mon, 13 May 2013 00:56:08 -0500 Subject: [ticket/11413] Revert some cache service related changes from earlier PHPBB3-11413 --- phpBB/includes/notification/method/base.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'phpBB') diff --git a/phpBB/includes/notification/method/base.php b/phpBB/includes/notification/method/base.php index bae85310b2..b633956d01 100644 --- a/phpBB/includes/notification/method/base.php +++ b/phpBB/includes/notification/method/base.php @@ -30,7 +30,7 @@ abstract class phpbb_notification_method_base implements phpbb_notification_meth /** @var phpbb_db_driver */ protected $db; - /** @var phpbb_cache_service */ + /** @var phpbb_cache_driver_interface */ protected $cache; /** @var phpbb_template */ @@ -66,7 +66,7 @@ abstract class phpbb_notification_method_base implements phpbb_notification_meth * * @param phpbb_user_loader $user_loader * @param phpbb_db_driver $db - * @param phpbb_cache_service $cache + * @param phpbb_cache_driver_interface $cache * @param phpbb_user $user * @param phpbb_auth $auth * @param phpbb_config $config @@ -74,7 +74,7 @@ abstract class phpbb_notification_method_base implements phpbb_notification_meth * @param string $php_ext * @return phpbb_notification_method_base */ - public function __construct(phpbb_user_loader $user_loader, phpbb_db_driver $db, phpbb_cache_service $cache, $user, phpbb_auth $auth, phpbb_config $config, $phpbb_root_path, $php_ext) + public function __construct(phpbb_user_loader $user_loader, phpbb_db_driver $db, phpbb_cache_driver_interface $cache, $user, phpbb_auth $auth, phpbb_config $config, $phpbb_root_path, $php_ext) { $this->user_loader = $user_loader; $this->db = $db; -- cgit v1.2.1 From 6890bf9f8d97473d55f2d6819c8ec155f9d52658 Mon Sep 17 00:00:00 2001 From: Marc Alexander Date: Mon, 13 May 2013 12:17:31 +0200 Subject: [ticket/11535] Correctly merge avatar_errors array into primary error array The $avatar_errors array needs to be merged into the primary $error array before the group settings get applied. This is currently not the case. Functional tests for this will be provided by PR #1401. PHPBB3-11535 --- phpBB/includes/acp/acp_groups.php | 10 ++++++++-- phpBB/includes/ucp/ucp_groups.php | 10 ++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) (limited to 'phpBB') diff --git a/phpBB/includes/acp/acp_groups.php b/phpBB/includes/acp/acp_groups.php index 865810687b..37c49d7d72 100644 --- a/phpBB/includes/acp/acp_groups.php +++ b/phpBB/includes/acp/acp_groups.php @@ -381,6 +381,9 @@ class acp_groups $submit_ary['avatar_width'] = 0; $submit_ary['avatar_height'] = 0; } + + // Merge any avatar errors into the primary error array + $error = array_merge($error, $phpbb_avatar_manager->localize_errors($user, $avatar_error)); } // Validate the length of "Maximum number of allowed recipients per private message" setting. @@ -570,8 +573,11 @@ class acp_groups $avatar = phpbb_get_group_avatar($group_row, 'GROUP_AVATAR', true); - // Merge any avatar errors into the primary error array - $error = array_merge($error, $phpbb_avatar_manager->localize_errors($user, $avatar_error)); + if (!$update) + { + // Merge any avatar errors into the primary error array + $error = array_merge($error, $phpbb_avatar_manager->localize_errors($user, $avatar_error)); + } $back_link = request_var('back_link', ''); diff --git a/phpBB/includes/ucp/ucp_groups.php b/phpBB/includes/ucp/ucp_groups.php index 50d13e00b1..a633ce448c 100644 --- a/phpBB/includes/ucp/ucp_groups.php +++ b/phpBB/includes/ucp/ucp_groups.php @@ -547,6 +547,9 @@ class ucp_groups $submit_ary['avatar_width'] = 0; $submit_ary['avatar_height'] = 0; } + + // Merge any avatars errors into the primary error array + $error = array_merge($error, $phpbb_avatar_manager->localize_errors($user, $avatar_error)); } if (!check_form_key('ucp_groups')) @@ -672,8 +675,11 @@ class ucp_groups } } - // Merge any avatars errors into the primary error array - $error = array_merge($error, $phpbb_avatar_manager->localize_errors($user, $avatar_error)); + if (!$update) + { + // Merge any avatars errors into the primary error array + $error = array_merge($error, $phpbb_avatar_manager->localize_errors($user, $avatar_error)); + } $template->assign_vars(array( 'S_EDIT' => true, -- cgit v1.2.1 From 33521310c74d934a64d453e3adfac53bd6c505be Mon Sep 17 00:00:00 2001 From: Vjacheslav Trushkin Date: Tue, 14 May 2013 09:16:39 +0300 Subject: [ticket/11489] CSS changes for topiclist lists PHPBB3-11489 --- phpBB/styles/prosilver/theme/bidi.css | 58 ++++++++++---- phpBB/styles/prosilver/theme/colours.css | 5 -- phpBB/styles/prosilver/theme/content.css | 126 +++++++++++++++++-------------- 3 files changed, 114 insertions(+), 75 deletions(-) (limited to 'phpBB') diff --git a/phpBB/styles/prosilver/theme/bidi.css b/phpBB/styles/prosilver/theme/bidi.css index 5cff0a811b..f617428565 100644 --- a/phpBB/styles/prosilver/theme/bidi.css +++ b/phpBB/styles/prosilver/theme/bidi.css @@ -268,8 +268,45 @@ left: 0; } -.rtl ul.topiclist dt { +.rtl ul.topiclist dt, .rtl li.header dt { float: right; + margin-right: 0; + margin-left: -410px; +} + +.rtl ul.topiclist.missing-column dt { + margin-right: 0; + margin-left: -330px; +} + +.rtl ul.topiclist.two-long-columns dt { + margin-right: 0; + margin-left: -250px; +} + +.rtl ul.topiclist.two-columns dt { + margin-right: 0; + margin-left: -80px; +} + +.rtl ul.topiclist dt .list-inner { + margin-right: 0; + margin-left: 410px; +} + +.rtl ul.topiclist.missing-column dt .list-inner { + margin-right: 0; + margin-left: 330px; +} + +.rtl ul.topiclist.two-long-columns dt .list-inner { + margin-right: 0; + margin-left: 250px; +} + +.rtl ul.topiclist.two-columns dt .list-inner { + margin-right: 0; + margin-left: 80px; } .rtl ul.topiclist dl { @@ -308,31 +345,24 @@ background-position: 99.5% 50%; } -.rtl li.header dl.icon dt { +.rtl li.header dl.icon dt .list-inner { /* Tweak for headers alignment when folder icon used */ padding-right: 0; padding-left: 50px; } .rtl dl.icon dt { - padding-left: 0; - padding-right: 45px; /* Space for folder icon */ background-position: 99.5% 95%; /* Position of topic icon */ } -.rtl dd.lastpost span, .rtl ul.topiclist dd.searchby span, .rtl ul.topiclist dd.info span, .rtl ul.topiclist dd.time span, .rtl dd.redirect span, .rtl dd.moderation span { +.rtl dl.icon dt .list-inner { padding-left: 0; - padding-right: 5px; -} - -.rtl dd.mark { - float: left !important; + padding-right: 45px; /* Space for folder icon */ } -.rtl ul.topiclist dd.searchextra { - margin-left: 0; - margin-right: 5px; - border-right: none; +.rtl dd.lastpost span, .rtl ul.topiclist dd.info span, .rtl ul.topiclist dd.time span, .rtl dd.redirect span, .rtl dd.moderation span { + padding-left: 0; + padding-right: 5px; } /* Post body styles diff --git a/phpBB/styles/prosilver/theme/colours.css b/phpBB/styles/prosilver/theme/colours.css index baff88d6b7..a2fe112b45 100644 --- a/phpBB/styles/prosilver/theme/colours.css +++ b/phpBB/styles/prosilver/theme/colours.css @@ -406,11 +406,6 @@ li.header dt, li.header dd { color: #FFFFFF; } -/* Forum list column styles */ -ul.topiclist dd.searchextra { - color: #333333; -} - /* Post body styles ----------------------------------------*/ .postbody { diff --git a/phpBB/styles/prosilver/theme/content.css b/phpBB/styles/prosilver/theme/content.css index bf9e587ce1..6eea435017 100644 --- a/phpBB/styles/prosilver/theme/content.css +++ b/phpBB/styles/prosilver/theme/content.css @@ -25,20 +25,53 @@ ul.topiclist li.row dl { padding: 2px 0; } -ul.topiclist dt { +ul.topiclist dt, ul.topiclist dd { display: block; float: left; - width: 50%; +} + +ul.topiclist dt { + width: 100%; + margin-right: -410px; font-size: 1.1em; +} + +ul.topiclist.missing-column dt { + margin-right: -330px; +} + +ul.topiclist.two-long-columns dt { + margin-right: -250px; +} + +ul.topiclist.two-columns dt { + margin-right: -80px; +} + +ul.topiclist dt .list-inner { + margin-right: 410px; padding-left: 5px; padding-right: 5px; } +ul.topiclist.missing-column dt .list-inner { + margin-right: 330px; +} + +ul.topiclist.two-long-columns dt .list-inner { + margin-right: 250px; +} + +ul.topiclist.two-columns dt .list-inner { + margin-right: 80px; +} + ul.topiclist dd { - display: block; - float: left; border-left: 1px solid transparent; padding: 4px 0; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; } ul.topiclist dfn { @@ -85,17 +118,26 @@ li.header dt, li.header dd { li.header dt { font-weight: bold; + width: 100%; + margin-right: -410px; +} + +li.header dt .list-inner { + margin-right: 410px; } li.header dd { - margin-left: 1px; + padding-left: 1px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; } -li.header dl.icon { +li.header dl.icon dt, li.header dl.icon dd { min-height: 0; } -li.header dl.icon dt { +li.header dl.icon dt .list-inner { /* Tweak for headers alignment when folder icon used */ padding-left: 0; padding-right: 50px; @@ -103,19 +145,27 @@ li.header dl.icon dt { /* Forum list column styles */ dl.icon { - min-height: 35px; background-position: 10px 50%; /* Position of folder icon */ background-repeat: no-repeat; } dl.icon dt { - padding-left: 45px; /* Space for folder icon */ background-repeat: no-repeat; background-position: 5px 95%; /* Position of topic icon */ } -dd.posts, dd.topics, dd.views { - width: 8%; +dl.icon dt .list-inner { + padding-left: 45px; /* Space for folder icon */ +} + +dl.icon dt, dl.icon dd { + min-height: 40px; + *min-height: 32px; +} + +dd.posts, dd.topics, dd.views, dd.extra, dd.mark { + width: 80px; + *width: 79px; text-align: center; line-height: 2.2em; font-size: 1.2em; @@ -133,73 +183,37 @@ dl.icon dt li { list-style-type: inherit; } -dd.lastpost { - width: 25%; +dd.lastpost, dd.redirect, dd.moderation, dd.time, dd.info { + width: 250px; + *width: 249px; font-size: 1.1em; } dd.redirect { - font-size: 1.1em; line-height: 2.5em; } -dd.moderation { - font-size: 1.1em; -} - -dd.lastpost span, ul.topiclist dd.searchby span, ul.topiclist dd.info span, ul.topiclist dd.time span, dd.redirect span, dd.moderation span { - display: block; - padding-left: 5px; -} - dd.time { - width: auto; line-height: 200%; - font-size: 1.1em; } -dd.extra { - width: 12%; - line-height: 200%; - text-align: center; - font-size: 1.1em; +dd.lastpost span, ul.topiclist dd.info span, ul.topiclist dd.time span, dd.redirect span, dd.moderation span { + display: block; + padding-left: 5px; } -dd.mark { - float: right !important; - width: 9%; - text-align: center; +dd.extra, dd.mark { line-height: 200%; - font-size: 1.2em; -} - -dd.info { - width: 30%; } dd.option { - width: 15%; + width: 125px; + *width: 124px; line-height: 200%; text-align: center; font-size: 1.1em; } -dd.searchby { - width: 47%; - font-size: 1.1em; - line-height: 1em; -} - -ul.topiclist dd.searchextra { - margin-left: 5px; - padding: 0.2em 0; - font-size: 1.1em; - border-left: none; - clear: both; - width: 98%; - overflow: hidden; -} - /* Container for post/reply buttons and pagination */ .topic-actions { margin-bottom: 3px; -- cgit v1.2.1 From 0d8ba50b644015604b9047e439f385ecdaab87c0 Mon Sep 17 00:00:00 2001 From: Vjacheslav Trushkin Date: Tue, 14 May 2013 09:17:11 +0300 Subject: [ticket/11489] Template changes for new topiclist layout PHPBB3-11489 --- .../styles/prosilver/template/forumlist_body.html | 30 ++++++----- phpBB/styles/prosilver/template/mcp_forum.html | 13 +++-- phpBB/styles/prosilver/template/mcp_front.html | 38 +++++++------ phpBB/styles/prosilver/template/mcp_queue.html | 12 +++-- phpBB/styles/prosilver/template/mcp_reports.html | 20 ++++--- .../styles/prosilver/template/search_results.html | 42 ++++++++------- .../styles/prosilver/template/ucp_attachments.html | 10 ++-- .../prosilver/template/ucp_groups_manage.html | 14 +++-- .../prosilver/template/ucp_groups_membership.html | 62 +++++++++++++--------- .../prosilver/template/ucp_main_bookmarks.html | 49 +++++++++-------- .../styles/prosilver/template/ucp_main_drafts.html | 18 ++++--- .../styles/prosilver/template/ucp_main_front.html | 34 ++++++------ .../prosilver/template/ucp_main_subscribed.html | 54 ++++++++++--------- .../prosilver/template/ucp_notifications.html | 28 +++++----- .../prosilver/template/ucp_pm_viewfolder.html | 9 ++-- .../styles/prosilver/template/viewforum_body.html | 41 +++++++------- 16 files changed, 267 insertions(+), 207 deletions(-) (limited to 'phpBB') diff --git a/phpBB/styles/prosilver/template/forumlist_body.html b/phpBB/styles/prosilver/template/forumlist_body.html index 539ed047c9..0c67de76ec 100644 --- a/phpBB/styles/prosilver/template/forumlist_body.html +++ b/phpBB/styles/prosilver/template/forumlist_body.html @@ -13,7 +13,7 @@
    • -
      {forumrow.FORUM_NAME}{L_FORUM}
      +
      {L_TOPICS}
      {L_POSTS}
      {L_LAST_POST}
      @@ -27,20 +27,22 @@
    • - +
      + - {forumrow.FORUM_IMAGE} - {forumrow.FORUM_NAME}
      - {forumrow.FORUM_DESC} - -
      {forumrow.L_MODERATOR_STR}{L_COLON} {forumrow.MODERATORS} - - -
      {forumrow.L_SUBFORUM_STR} - - {forumrow.subforum.SUBFORUM_NAME}, - - + {forumrow.FORUM_IMAGE} + {forumrow.FORUM_NAME}
      + {forumrow.FORUM_DESC} + +
      {forumrow.L_MODERATOR_STR}{L_COLON} {forumrow.MODERATORS} + + +
      {forumrow.L_SUBFORUM_STR} + + {forumrow.subforum.SUBFORUM_NAME}, + + +
      {L_REDIRECTS}{L_COLON} {forumrow.CLICKS}
      diff --git a/phpBB/styles/prosilver/template/mcp_forum.html b/phpBB/styles/prosilver/template/mcp_forum.html index e559f178f2..ac686932b7 100644 --- a/phpBB/styles/prosilver/template/mcp_forum.html +++ b/phpBB/styles/prosilver/template/mcp_forum.html @@ -24,22 +24,24 @@ -
        +
        • -
          {L_TOPICS}
          +
          {L_TOPICS}
          {L_REPLIES}
          {L_LAST_POST}
          {L_MARK}
        -
    + {topicrow.ATTACH_ICON_IMG} {L_POST_BY_AUTHOR} {topicrow.TOPIC_AUTHOR_FULL} » {topicrow.FIRST_POST_TIME} + + +
    {topicrow.REPLIES} {L_REPLIES}
    {L_LAST_POST} {L_POST_BY_AUTHOR} {topicrow.LAST_POST_AUTHOR_FULL}
    {topicrow.LAST_POST_TIME}
    diff --git a/phpBB/styles/prosilver/template/mcp_front.html b/phpBB/styles/prosilver/template/mcp_front.html index 886a4b784b..e88b7c62df 100644 --- a/phpBB/styles/prosilver/template/mcp_front.html +++ b/phpBB/styles/prosilver/template/mcp_front.html @@ -13,22 +13,24 @@

    {L_UNAPPROVED_TOTAL}

    -
      +
      • -
        {L_VIEW_DETAILS}
        +
        {L_VIEW_DETAILS}
        {L_TOPIC} & {L_FORUM}
      -
        +
        • - {unapproved.SUBJECT} {unapproved.ATTACH_ICON_IMG}
          - {L_POSTED} {L_POST_BY_AUTHOR} {unapproved.AUTHOR_FULL} » {unapproved.POST_TIME} +
          + {unapproved.SUBJECT} {unapproved.ATTACH_ICON_IMG}
          + {L_POSTED} {L_POST_BY_AUTHOR} {unapproved.AUTHOR_FULL} » {unapproved.POST_TIME} +
          {L_TOPIC}{L_COLON} {unapproved.TOPIC_TITLE} [{L_MODERATE}]
          @@ -65,22 +67,24 @@

          {L_REPORTS_TOTAL}

          -
            +
            • -
              {L_VIEW_DETAILS}
              +
              {L_VIEW_DETAILS}
              {L_REPORTER} & {L_FORUM}
            -
              +
              • - {report.SUBJECT} {report.ATTACH_ICON_IMG}
                - {L_POSTED} {L_POST_BY_AUTHOR} {report.AUTHOR_FULL} » {report.POST_TIME} +
                + {report.SUBJECT} {report.ATTACH_ICON_IMG}
                + {L_POSTED} {L_POST_BY_AUTHOR} {report.AUTHOR_FULL} » {report.POST_TIME} +
                {L_REPORTED} {L_POST_BY_AUTHOR} {report.REPORTER_FULL} {L_REPORTED_ON_DATE} {report.REPORT_TIME}
                @@ -104,23 +108,25 @@

                {L_PM_REPORTS_TOTAL}

                -
                  +
                  • -
                    {L_VIEW_DETAILS}
                    +
                    {L_VIEW_DETAILS}
                    {L_REPORTER}
                  -
                    +
                    • - {pm_report.PM_SUBJECT} {pm_report.ATTACH_ICON_IMG}
                      - {L_MESSAGE_BY_AUTHOR} {pm_report.PM_AUTHOR_FULL} » {pm_report.PM_TIME}
                      - {L_MESSAGE_TO} {pm_report.RECIPIENTS} +
                      + {pm_report.PM_SUBJECT} {pm_report.ATTACH_ICON_IMG}
                      + {L_MESSAGE_BY_AUTHOR} {pm_report.PM_AUTHOR_FULL} » {pm_report.PM_TIME}
                      + {L_MESSAGE_TO} {pm_report.RECIPIENTS} +
                      {L_REPORTED} {L_POST_BY_AUTHOR} {pm_report.REPORTER_FULL} {L_REPORTED_ON_DATE} {pm_report.REPORT_TIME} diff --git a/phpBB/styles/prosilver/template/mcp_queue.html b/phpBB/styles/prosilver/template/mcp_queue.html index 847151a01e..4d20804e66 100644 --- a/phpBB/styles/prosilver/template/mcp_queue.html +++ b/phpBB/styles/prosilver/template/mcp_queue.html @@ -26,16 +26,16 @@
                    -
                      +
                      • -
                        {L_TOPIC}{L_POST}
                        +
                        {L_TOPIC}{L_POST}
                        {L_TOPIC} & {L_FORUM}
                        {L_MARK}
                      -
                        +
                          @@ -46,8 +46,10 @@
                        • - {postrow.POST_SUBJECT} {postrow.ATTACH_ICON_IMG}
                          - {L_POSTED} {L_POST_BY_AUTHOR} {postrow.POST_AUTHOR_FULL} » {postrow.POST_TIME} +
                          + {postrow.POST_SUBJECT} {postrow.ATTACH_ICON_IMG}
                          + {L_POSTED} {L_POST_BY_AUTHOR} {postrow.POST_AUTHOR_FULL} » {postrow.POST_TIME} +
                          diff --git a/phpBB/styles/prosilver/template/mcp_reports.html b/phpBB/styles/prosilver/template/mcp_reports.html index ea9a4edd6f..9a70b4a62a 100644 --- a/phpBB/styles/prosilver/template/mcp_reports.html +++ b/phpBB/styles/prosilver/template/mcp_reports.html @@ -28,33 +28,37 @@
                        -
                          +
                          • -
                            {L_VIEW_DETAILS}
                            +
                            {L_VIEW_DETAILS}
                            {L_REPORTER} & {L_FORUM}
                            {L_MARK}
                          -
                            +
                            • - {postrow.PM_SUBJECT} {postrow.ATTACH_ICON_IMG}
                              - {L_MESSAGE_BY_AUTHOR} {postrow.PM_AUTHOR_FULL} » {postrow.PM_TIME}
                              - {L_MESSAGE_TO} {postrow.RECIPIENTS} +
                              + {postrow.PM_SUBJECT} {postrow.ATTACH_ICON_IMG}
                              + {L_MESSAGE_BY_AUTHOR} {postrow.PM_AUTHOR_FULL} » {postrow.PM_TIME}
                              + {L_MESSAGE_TO} {postrow.RECIPIENTS} +
                              {postrow.REPORTER_FULL} « {postrow.REPORT_TIME}
                              - {postrow.POST_SUBJECT} {postrow.ATTACH_ICON_IMG}
                              - {L_POSTED} {L_POST_BY_AUTHOR} {postrow.POST_AUTHOR_FULL} » {postrow.POST_TIME} +
                              + {postrow.POST_SUBJECT} {postrow.ATTACH_ICON_IMG}
                              + {L_POSTED} {L_POST_BY_AUTHOR} {postrow.POST_AUTHOR_FULL} » {postrow.POST_TIME} +
                              {postrow.REPORTER_FULL} « {postrow.REPORT_TIME}
                              diff --git a/phpBB/styles/prosilver/template/search_results.html b/phpBB/styles/prosilver/template/search_results.html index 6e63a65993..34fbb4cb12 100644 --- a/phpBB/styles/prosilver/template/search_results.html +++ b/phpBB/styles/prosilver/template/search_results.html @@ -48,7 +48,7 @@
                              • -
                                {L_TOPICS}
                                +
                                {L_TOPICS}
                                {L_REPLIES}
                                {L_VIEWS}
                                {L_LAST_POST}
                                @@ -61,25 +61,29 @@
                              • 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} - {REPORTED_IMG}
                                - -
                                {searchresults.TOPIC_REPLIES}
                                {searchresults.TOPIC_VIEWS}
                                diff --git a/phpBB/styles/prosilver/template/ucp_attachments.html b/phpBB/styles/prosilver/template/ucp_attachments.html index 478b14ab86..6e1bdfdd57 100644 --- a/phpBB/styles/prosilver/template/ucp_attachments.html +++ b/phpBB/styles/prosilver/template/ucp_attachments.html @@ -24,7 +24,7 @@
                                • -
                                  {L_FILENAME}
                                  +
                                  {L_DOWNLOADS}
                                  {L_POST_TIME}
                                  {L_MARK}
                                  @@ -36,8 +36,12 @@
                                • -
                                  {attachrow.FILENAME} ({attachrow.SIZE})
                                  - {L_PM}{L_COLON} {L_TOPIC}{L_COLON} {attachrow.TOPIC_TITLE}
                                  +
                                  +
                                  + {attachrow.FILENAME} ({attachrow.SIZE})
                                  + {L_PM}{L_COLON} {L_TOPIC}{L_COLON} {attachrow.TOPIC_TITLE} +
                                  +
                                  {attachrow.DOWNLOAD_COUNT}
                                  {attachrow.POST_TIME}
                                  diff --git a/phpBB/styles/prosilver/template/ucp_groups_manage.html b/phpBB/styles/prosilver/template/ucp_groups_manage.html index f6fcfa043d..0ef6faf25d 100644 --- a/phpBB/styles/prosilver/template/ucp_groups_manage.html +++ b/phpBB/styles/prosilver/template/ucp_groups_manage.html @@ -207,21 +207,25 @@ -
                                    +
                                    • -
                                      {L_GROUP_LEADER}
                                      +
                                      {L_GROUP_LEADER}
                                      {L_OPTIONS}
                                    -
                                      +
                                      • -
                                        style="color: #{leader.GROUP_COLOUR};">{leader.GROUP_NAME} -
                                        {leader.GROUP_DESC}
                                        +
                                        + +
                                        {L_EDIT}
                                        {L_GROUP_LIST}
                                        diff --git a/phpBB/styles/prosilver/template/ucp_groups_membership.html b/phpBB/styles/prosilver/template/ucp_groups_membership.html index bf266208f2..d7df3b02c2 100644 --- a/phpBB/styles/prosilver/template/ucp_groups_membership.html +++ b/phpBB/styles/prosilver/template/ucp_groups_membership.html @@ -10,15 +10,15 @@

                                        {L_GROUPS_EXPLAIN}

                                        -
                                          +
                                          • -
                                            {L_GROUP_LEADER}
                                            +
                                            {L_GROUP_LEADER}
                                            {L_SELECT}
                                          -
                                            +
                                              @@ -26,10 +26,13 @@
                                            • -
                                              checked="checked" value="{leader.GROUP_ID}" /> - style="color:#{leader.GROUP_COLOUR}">{leader.GROUP_NAME} -
                                              {leader.GROUP_DESC} -
                                              {leader.GROUP_STATUS} +
                                              +
                                              + checked="checked" value="{leader.GROUP_ID}" /> + style="color:#{leader.GROUP_COLOUR}">{leader.GROUP_NAME} +
                                              {leader.GROUP_DESC} +
                                              {leader.GROUP_STATUS} +
                                              disabled="disabled" />
                                              @@ -39,15 +42,15 @@ -
                                                +
                                                • -
                                                  {L_GROUP_MEMBER}
                                                  +
                                                  {L_GROUP_MEMBER}
                                                  {L_SELECT}
                                                -
                                                  +
                                                    @@ -55,10 +58,13 @@
                                                  • -
                                                    checked="checked" value="{member.GROUP_ID}" /> - style="color:#{member.GROUP_COLOUR}">{member.GROUP_NAME} -
                                                    {member.GROUP_DESC} -
                                                    {member.GROUP_STATUS} +
                                                    +
                                                    + checked="checked" value="{member.GROUP_ID}" /> + style="color:#{member.GROUP_COLOUR}">{member.GROUP_NAME} +
                                                    {member.GROUP_DESC} +
                                                    {member.GROUP_STATUS} +
                                                    disabled="disabled" />
                                                    @@ -72,15 +78,15 @@
                                                    -
                                                      +
                                                      • -
                                                        {L_GROUP_PENDING}
                                                        +
                                                        {L_GROUP_PENDING}
                                                        {L_SELECT}
                                                      -
                                                        +
                                                          @@ -89,9 +95,11 @@
                                                        • - style="color:#{pending.GROUP_COLOUR}">{pending.GROUP_NAME} -
                                                          {pending.GROUP_DESC} -
                                                          {pending.GROUP_STATUS} +
                                                          + style="color:#{pending.GROUP_COLOUR}">{pending.GROUP_NAME} +
                                                          {pending.GROUP_DESC} +
                                                          {pending.GROUP_STATUS} +
                                                          disabled="disabled" />
                                                          @@ -104,15 +112,15 @@
                                                          -
                                                            +
                                                            • -
                                                              {L_GROUP_NONMEMBER}
                                                              +
                                                              {L_GROUP_NONMEMBER}
                                                              {L_SELECT}
                                                            -
                                                              +
                                                                @@ -121,9 +129,11 @@
                                                              • - style="color:#{nonmember.GROUP_COLOUR}">{nonmember.GROUP_NAME} -
                                                                {nonmember.GROUP_DESC} -
                                                                {nonmember.GROUP_STATUS} +
                                                                + style="color:#{nonmember.GROUP_COLOUR}">{nonmember.GROUP_NAME} +
                                                                {nonmember.GROUP_DESC} +
                                                                {nonmember.GROUP_STATUS} +
                                                                disabled="disabled" />
                                                                diff --git a/phpBB/styles/prosilver/template/ucp_main_bookmarks.html b/phpBB/styles/prosilver/template/ucp_main_bookmarks.html index 8707a749c1..017fadad77 100644 --- a/phpBB/styles/prosilver/template/ucp_main_bookmarks.html +++ b/phpBB/styles/prosilver/template/ucp_main_bookmarks.html @@ -14,43 +14,48 @@ -
                                                                  +
                                                                  • -
                                                                    {L_BOOKMARKS}
                                                                    +
                                                                    {L_BOOKMARKS}
                                                                    {L_LAST_POST}
                                                                    +
                                                                    {L_MARK}
                                                                  -
                                                                    +
                                                                    • -
                                                                      {L_DELETED_TOPIC}
                                                                      -
                                                                      +
                                                                      +
                                                                      {L_DELETED_TOPIC}
                                                                      +
                                                                       
                                                                      +
                                                                      style="background-image: url({T_ICONS_PATH}{topicrow.TOPIC_ICON_IMG}); background-repeat: no-repeat;" title="{topicrow.TOPIC_FOLDER_IMG_ALT}"> - {NEWEST_POST_IMG} {topicrow.TOPIC_TITLE} - {topicrow.UNAPPROVED_IMG} - {REPORTED_IMG}
                                                                      - -