(.*?)<\\/a>', 'g'), '$1');
+ h = h.replace(/]*)>\s*<\/p>/g, '
' + nb + '
');
+
+ // Clean body
+ if (/^\s*( | <\/p>|
<\/p>|
<\/p>)\s*$/.test(h))
+ h = '';
+
+ // If preformatted
+ if (s.preformatted) {
+ h = h.replace(/^
/, '');
+ h = h.replace(/<\/pre>$/, '');
+ h = '' + h + ' ';
+ }
+
+ // Gecko specific processing
+ if (tinyMCE.isGecko) {
+ // Makes no sence but FF generates it!!
+ h = h.replace(/ \s*<\/li>/g, '');
+ h = h.replace(/ \s*<\/(dd|dt)>/g, '$1>');
+ h = h.replace(/ /g, '');
+ h = h.replace(/]*)>\s* \s*<\/td>/g, ' ' + nb + ' ');
+ }
- // If encoding (not recommended option)
- if (on_submit && (s.encoding == "xml" || s.encoding == "html"))
- h = c.xmlEncode(h);
+ if (s.force_br_newlines)
+ h = h.replace(/( | )<\/p>/g, ' ');
- if (d)
- t5 = new Date().getTime();
+ // Call custom cleanup code
+ h = tinyMCE._customCleanup(inst, on_save ? "get_from_editor" : "insert_to_editor", h);
- if (c.settings.debug)
- tinyMCE.debug("Cleanup in ms: Pre=" + (t2-t1) + ", Serialize: " + (t3-t2) + ", Post: " + (t4-t3) + ", Format: " + (t5-t4) + ", Sum: " + (t5-t1) + ".");
+ // Remove internal classes
+ if (on_save) {
+ h = h.replace(new RegExp(' ?(mceItem[a-zA-Z0-9]*|' + s.visual_table_class + ')', 'g'), '');
+ h = h.replace(new RegExp(' ?class=""', 'g'), '');
+ }
- return h;
-};
+ if (s.remove_linebreaks && !c.settings.indent)
+ h = h.replace(/\n|\r/g, ' ');
+
+ if (d)
+ t4 = new Date().getTime();
+
+ if (on_save && c.settings.indent)
+ h = c.formatHTML(h);
+
+ // If encoding (not recommended option)
+ if (on_submit && (s.encoding == "xml" || s.encoding == "html"))
+ h = c.xmlEncode(h);
+
+ if (d)
+ t5 = new Date().getTime();
+
+ if (c.settings.debug)
+ tinyMCE.debug("Cleanup in ms: Pre=" + (t2-t1) + ", Serialize: " + (t3-t2) + ", Post: " + (t4-t3) + ", Format: " + (t5-t4) + ", Sum: " + (t5-t1) + ".");
+
+ return h;
+ }
+});
function TinyMCE_Cleanup() {
this.isIE = (navigator.appName == "Microsoft Internet Explorer");
- this.rules = tinyMCE.clearArray(new Array());
+ this.rules = tinyMCE.clearArray([]);
// Default config
this.settings = {
@@ -4418,7 +4490,7 @@ function TinyMCE_Cleanup() {
verify_html : false
};
- this.vElements = tinyMCE.clearArray(new Array());
+ this.vElements = tinyMCE.clearArray([]);
this.vElementsRe = '';
this.closeElementsRe = /^(IMG|BR|HR|LINK|META|BASE|INPUT|AREA)$/;
this.codeElementsRe = /^(SCRIPT|STYLE)$/;
@@ -4448,7 +4520,7 @@ TinyMCE_Cleanup.prototype = {
this.nlBeforeAfterRe = this._arrayToRe(s.newline_before_after_elements.split(','), 'gi', '<(\\/?)(', ')([^>]*)>');
this.serializedNodes = [];
- if (s.invalid_elements != '')
+ if (s.invalid_elements !== '')
this.iveRe = this._arrayToRe(s.invalid_elements.toUpperCase().split(','), 'g', '^(', ')$');
else
this.iveRe = null;
@@ -4469,19 +4541,17 @@ TinyMCE_Cleanup.prototype = {
this.fillStr = s.entity_encoding == "named" ? " " : " ";
this.idCount = 0;
this.xmlEncodeRe = new RegExp('[\u007F-\uFFFF<>&"]', 'g');
- this.xmlEncodeAposRe = new RegExp('[\u007F-\uFFFF<>&"\']', 'g');
},
addRuleStr : function(s) {
- var r = this.parseRuleStr(s);
- var n;
+ var r = this.parseRuleStr(s), n;
for (n in r) {
if (r[n])
this.rules[n] = r[n];
}
- this.vElements = tinyMCE.clearArray(new Array());
+ this.vElements = tinyMCE.clearArray([]);
for (n in this.rules) {
if (this.rules[n])
@@ -4492,7 +4562,8 @@ TinyMCE_Cleanup.prototype = {
},
isValid : function(n) {
- this._setupRules(); // Will initialize cleanup rules
+ if (!this.rulesDone)
+ this._setupRules(); // Will initialize cleanup rules
// Empty is true since it removes formatting
if (!n)
@@ -4548,9 +4619,9 @@ TinyMCE_Cleanup.prototype = {
}
r += ')$';
-//tinyMCE.debug(t + "=" + r);
+
if (this.childRules == null)
- this.childRules = tinyMCE.clearArray(new Array());
+ this.childRules = tinyMCE.clearArray([]);
this.childRules[tn[y]] = new RegExp(r);
@@ -4561,7 +4632,7 @@ TinyMCE_Cleanup.prototype = {
},
parseRuleStr : function(s) {
- var ta, p, r, a, i, x, px, t, tn, y, av, or = tinyMCE.clearArray(new Array()), dv;
+ var ta, p, r, a, i, x, px, t, tn, y, av, or = tinyMCE.clearArray([]), dv;
if (s == null || s.length == 0)
return or;
@@ -4621,19 +4692,19 @@ TinyMCE_Cleanup.prototype = {
if (av && av.length > 0) {
if (av[0].charAt(0) == ':') {
if (!r.forceAttribs)
- r.forceAttribs = tinyMCE.clearArray(new Array());
+ r.forceAttribs = tinyMCE.clearArray([]);
r.forceAttribs[t.toLowerCase()] = av[0].substring(1);
} else if (av[0].charAt(0) == '=') {
if (!r.defaultAttribs)
- r.defaultAttribs = tinyMCE.clearArray(new Array());
+ r.defaultAttribs = tinyMCE.clearArray([]);
dv = av[0].substring(1);
- r.defaultAttribs[t.toLowerCase()] = dv == "" ? "mce_empty" : dv;
+ r.defaultAttribs[t.toLowerCase()] = dv == '' ? "mce_empty" : dv;
} else if (av[0].charAt(0) == '<') {
if (!r.validAttribValues)
- r.validAttribValues = tinyMCE.clearArray(new Array());
+ r.validAttribValues = tinyMCE.clearArray([]);
r.validAttribValues[t.toLowerCase()] = this._arrayToRe(this.split('?', av[0].substring(1)), 'i');
}
@@ -4656,7 +4727,7 @@ TinyMCE_Cleanup.prototype = {
//tinyMCE.debug(r.tag, r.oTagName, r.vAttribsRe, r.vAttribsReWC);
} else {
r.vAttribsRe = '';
- r.vAttribs = tinyMCE.clearArray(new Array());
+ r.vAttribs = tinyMCE.clearArray([]);
r.vAttribsReIsWild = false;
}
@@ -4745,7 +4816,8 @@ TinyMCE_Cleanup.prototype = {
serializeNodeAsHTML : function(n, inn) {
var en, no, h = '', i, l, t, st, r, cn, va = false, f = false, at, hc, cr, nn;
- this._setupRules(); // Will initialize cleanup rules
+ if (!this.rulesDone)
+ this._setupRules(); // Will initialize cleanup rules
if (tinyMCE.isRealIE && this._isDuplicate(n))
return '';
@@ -4767,12 +4839,19 @@ TinyMCE_Cleanup.prototype = {
if (st)
break;
- // MSIE sometimes produces /tag>
- if ((tinyMCE.isRealIE) && n.nodeName.indexOf('/') != -1)
- break;
-
nn = n.nodeName;
+ if (tinyMCE.isRealIE) {
+ // MSIE sometimes produces /tag>
+ if (n.nodeName.indexOf('/') != -1)
+ break;
+
+ // MSIE has it's NS in a separate attrib
+ if (n.scopeName && n.scopeName != 'HTML')
+ nn = n.scopeName.toUpperCase() + ':' + nn.toUpperCase();
+ } else if (tinyMCE.isOpera && nn.indexOf(':') > 0)
+ nn = nn.toUpperCase();
+
// Convert fonts to spans
if (this.settings.convert_fonts_to_spans) {
// On get content FONT -> SPAN
@@ -4959,25 +5038,26 @@ TinyMCE_Cleanup.prototype = {
return o;
},
- xmlEncode : function(s, skip_apos) {
- var cl = this, re = !skip_apos ? this.xmlEncodeAposRe : this.xmlEncodeRe;
+ xmlEncode : function(s) {
+ var cl = this, re = this.xmlEncodeRe;
- this._setupEntities(); // Will intialize lookup table
+ if (!this.entitiesDone)
+ this._setupEntities(); // Will intialize lookup table
switch (this.settings.entity_encoding) {
case "raw":
- return tinyMCE.xmlEncode(s, skip_apos);
+ return tinyMCE.xmlEncode(s);
case "named":
- return s.replace(re, function (c, b) {
- b = cl.entities[c.charCodeAt(0)];
+ return s.replace(re, function (c) {
+ var b = cl.entities[c.charCodeAt(0)];
return b ? '&' + b + ';' : c;
});
case "numeric":
- return s.replace(re, function (c, b) {
- return b ? '' + c.charCodeAt(0) + ';' : c;
+ return s.replace(re, function (c) {
+ return '' + c.charCodeAt(0) + ';';
});
}
@@ -4985,11 +5065,10 @@ TinyMCE_Cleanup.prototype = {
},
split : function(re, s) {
- var c = s.split(re);
- var i, l, o = new Array();
+ var i, l, o = [], c = s.split(re);
for (i=0, l=c.length; i ' : '>' + h + '' + tn + '>';
+ o += !h ? ' />' : '>' + h + '' + tn + '>';
- return o;
-};
+ return o;
+ },
-TinyMCE_Engine.prototype.createTag = function(d, tn, a, h) {
- var o = d.createElement(tn);
+ createTag : function(d, tn, a, h) {
+ var o = d.createElement(tn), n;
- if (a) {
- for (n in a) {
- if (typeof(a[n]) != 'function' && a[n] != null)
- tinyMCE.setAttrib(o, n, a[n]);
+ if (a) {
+ for (n in a) {
+ if (typeof(a[n]) != 'function' && a[n] != null)
+ tinyMCE.setAttrib(o, n, a[n]);
+ }
}
- }
-
- if (h)
- o.innerHTML = h;
- return o;
-};
+ if (h)
+ o.innerHTML = h;
-TinyMCE_Engine.prototype.getElementByAttributeValue = function(n, e, a, v) {
- return (n = this.getElementsByAttributeValue(n, e, a, v)).length == 0 ? null : n[0];
-};
+ return o;
+ },
-TinyMCE_Engine.prototype.getElementsByAttributeValue = function(n, e, a, v) {
- var i, nl = n.getElementsByTagName(e), o = new Array();
+ getElementByAttributeValue : function(n, e, a, v) {
+ return (n = this.getElementsByAttributeValue(n, e, a, v)).length == 0 ? null : n[0];
+ },
- for (i=0; i]*)>/gi, '');
- h = h.replace(/]*)>/gi, '');
- h = h.replace(/]*)>/gi, '');
- h = h.replace(/]*)>/gi, '');
- h = h.replace(/<\/strong>/gi, ' ');
- h = h.replace(/<\/em>/gi, ' ');
- }
+ insertAfter : function(n, r){
+ if (r.nextSibling)
+ r.parentNode.insertBefore(n, r.nextSibling);
+ else
+ r.parentNode.appendChild(n);
+ },
- if (tinyMCE.isRealIE) {
- // Since MSIE handles invalid HTML better that valid XHTML we
- // need to make some things invalid. gets converted to .
- h = h.replace(/\s\/>/g, '>');
+ setInnerHTML : function(e, h) {
+ var i, nl, n;
- // Since MSIE auto generated emtpy P tags some times we must tell it to keep the real ones
- h = h.replace(/]*)>\u00A0?<\/p>/gi, '
'); // Keep empty paragraphs
- h = h.replace(/]*)>\s* \s*<\/p>/gi, '
'); // Keep empty paragraphs
- h = h.replace(/]*)>\s+<\/p>/gi, '
'); // Keep empty paragraphs
+ // Convert all strong/em to b/i in Gecko
+ if (tinyMCE.isGecko) {
+ h = h.replace(/]*)>/gi, '');
+ h = h.replace(/]*)>/gi, '');
+ h = h.replace(/]*)>/gi, '');
+ h = h.replace(/]*)>/gi, '');
+ h = h.replace(/<\/strong>/gi, ' ');
+ h = h.replace(/<\/em>/gi, ' ');
+ }
- // Remove first comment
- e.innerHTML = tinyMCE.uniqueTag + h;
- e.firstChild.removeNode(true);
+ if (tinyMCE.isRealIE) {
+ // Since MSIE handles invalid HTML better that valid XHTML we
+ // need to make some things invalid. gets converted to .
+ h = h.replace(/\s\/>/g, '>');
+
+ // Since MSIE auto generated emtpy P tags some times we must tell it to keep the real ones
+ h = h.replace(/]*)>\u00A0?<\/p>/gi, '
'); // Keep empty paragraphs
+ h = h.replace(/]*)>\s* \s*<\/p>/gi, '
'); // Keep empty paragraphs
+ h = h.replace(/]*)>\s+<\/p>/gi, '
'); // Keep empty paragraphs
+
+ // Remove first comment
+ e.innerHTML = tinyMCE.uniqueTag + h;
+ e.firstChild.removeNode(true);
+
+ // Remove weird auto generated empty paragraphs unless it's supposed to be there
+ nl = e.getElementsByTagName("p");
+ for (i=nl.length-1; i>=0; i--) {
+ n = nl[i];
+
+ if (n.nodeName == 'P' && !n.hasChildNodes() && !n.mce_keep)
+ n.parentNode.removeChild(n);
+ }
+ } else {
+ h = this.fixGeckoBaseHREFBug(1, e, h);
+ e.innerHTML = h;
+ this.fixGeckoBaseHREFBug(2, e, h);
+ }
+ },
- // Remove weird auto generated empty paragraphs unless it's supposed to be there
- nl = e.getElementsByTagName("p");
- for (i=nl.length-1; i>=0; i--) {
- n = nl[i];
+ getOuterHTML : function(e) {
+ var d;
- if (n.nodeName == 'P' && !n.hasChildNodes() && !n.mce_keep)
- n.parentNode.removeChild(n);
- }
- } else {
- h = this.fixGeckoBaseHREFBug(1, e, h);
- e.innerHTML = h;
- this.fixGeckoBaseHREFBug(2, e, h);
- }
-};
+ if (tinyMCE.isIE)
+ return e.outerHTML;
-TinyMCE_Engine.prototype.getOuterHTML = function(e) {
- if (tinyMCE.isIE)
- return e.outerHTML;
+ d = e.ownerDocument.createElement("body");
+ d.appendChild(e.cloneNode(true));
- var d = e.ownerDocument.createElement("body");
- d.appendChild(e.cloneNode(true));
- return d.innerHTML;
-};
+ return d.innerHTML;
+ },
-TinyMCE_Engine.prototype.setOuterHTML = function(e, h, d) {
- var d = typeof(d) == "undefined" ? e.ownerDocument : d, i, nl, t;
+ setOuterHTML : function(e, h, d) {
+ var d = typeof(d) == "undefined" ? e.ownerDocument : d, i, nl, t;
- if (tinyMCE.isIE && e.nodeType == 1)
- e.outerHTML = h;
- else {
- t = d.createElement("body");
- t.innerHTML = h;
+ if (tinyMCE.isIE && e.nodeType == 1)
+ e.outerHTML = h;
+ else {
+ t = d.createElement("body");
+ t.innerHTML = h;
- for (i=0, nl=t.childNodes; i-1; i--) {
- if (ar[i].specified && ar[i].nodeValue)
- ne.setAttribute(ar[i].nodeName.toLowerCase(), ar[i].nodeValue);
- }
+ ar = e.attributes;
+ for (i=ar.length-1; i>-1; i--) {
+ if (ar[i].specified && ar[i].nodeValue)
+ ne.setAttribute(ar[i].nodeName.toLowerCase(), ar[i].nodeValue);
+ }
- ar = e.childNodes;
- for (i=0; i= strTok2.length) {
- for (var i=0; i= strTok2.length || strTok1[i] != strTok2[i]) {
- breakPoint = i + 1;
- break;
+ if (targetURL.path == '')
+ targetURL.path = "/";
+ else
+ forceSlash = true;
+
+ // Crop away last path part
+ base_url = baseURL.path.substring(0, baseURL.path.lastIndexOf('/'));
+ strTok1 = base_url.split('/');
+ strTok2 = targetURL.path.split('/');
+
+ if (strTok1.length >= strTok2.length) {
+ for (i=0; i= strTok2.length || strTok1[i] != strTok2[i]) {
+ breakPoint = i + 1;
+ break;
+ }
}
}
- }
- if (strTok1.length < strTok2.length) {
- for (var i=0; i= strTok1.length || strTok1[i] != strTok2[i]) {
- breakPoint = i + 1;
- break;
+ if (strTok1.length < strTok2.length) {
+ for (i=0; i= strTok1.length || strTok1[i] != strTok2[i]) {
+ breakPoint = i + 1;
+ break;
+ }
}
}
- }
- if (breakPoint == 1)
- return targetURL.path;
+ if (breakPoint == 1)
+ return targetURL.path;
- for (var i=0; i<(strTok1.length-(breakPoint-1)); i++)
- outPath += "../";
+ for (i=0; i<(strTok1.length-(breakPoint-1)); i++)
+ outPath += "../";
- for (var i=breakPoint-1; i=0; i--) {
- if (baseURLParts[i].length == 0)
- continue;
+ // Remove empty chunks
+ newBaseURLParts = [];
+ for (i=baseURLParts.length-1; i>=0; i--) {
+ if (baseURLParts[i].length == 0)
+ continue;
- newBaseURLParts[newBaseURLParts.length] = baseURLParts[i];
- }
- baseURLParts = newBaseURLParts.reverse();
+ newBaseURLParts[newBaseURLParts.length] = baseURLParts[i];
+ }
+ baseURLParts = newBaseURLParts.reverse();
- // Merge relURLParts chunks
- var newRelURLParts = new Array();
- var numBack = 0;
- for (var i=relURLParts.length-1; i>=0; i--) {
- if (relURLParts[i].length == 0 || relURLParts[i] == ".")
- continue;
+ // Merge relURLParts chunks
+ newRelURLParts = [];
+ numBack = 0;
+ for (i=relURLParts.length-1; i>=0; i--) {
+ if (relURLParts[i].length == 0 || relURLParts[i] == ".")
+ continue;
- if (relURLParts[i] == '..') {
- numBack++;
- continue;
- }
+ if (relURLParts[i] == '..') {
+ numBack++;
+ continue;
+ }
- if (numBack > 0) {
- numBack--;
- continue;
- }
+ if (numBack > 0) {
+ numBack--;
+ continue;
+ }
- newRelURLParts[newRelURLParts.length] = relURLParts[i];
- }
+ newRelURLParts[newRelURLParts.length] = relURLParts[i];
+ }
- relURLParts = newRelURLParts.reverse();
+ relURLParts = newRelURLParts.reverse();
- // Remove end from absolute path
- var len = baseURLParts.length-numBack;
- var absPath = (len <= 0 ? "" : "/") + baseURLParts.slice(0, len).join('/') + "/" + relURLParts.join('/');
- var start = "", end = "";
+ // Remove end from absolute path
+ len = baseURLParts.length-numBack;
+ absPath = (len <= 0 ? "" : "/") + baseURLParts.slice(0, len).join('/') + "/" + relURLParts.join('/');
+ start = "";
+ end = "";
- // Build output URL
- relURL.protocol = baseURL.protocol;
- relURL.host = baseURL.host;
- relURL.port = baseURL.port;
+ // Build output URL
+ relURL.protocol = baseURL.protocol;
+ relURL.host = baseURL.host;
+ relURL.port = baseURL.port;
- // Re-add trailing slash if it's removed
- if (relURL.path.charAt(relURL.path.length-1) == "/")
- absPath += "/";
+ // Re-add trailing slash if it's removed
+ if (relURL.path.charAt(relURL.path.length-1) == "/")
+ absPath += "/";
- relURL.path = absPath;
+ relURL.path = absPath;
- return this.serializeURL(relURL);
-};
+ return this.serializeURL(relURL);
+ },
-TinyMCE_Engine.prototype.convertURL = function(url, node, on_save) {
- var prot = document.location.protocol;
- var host = document.location.hostname;
- var port = document.location.port;
+ convertURL : function(url, node, on_save) {
+ var dl = document.location, start, portPart, urlParts, baseUrlParts, tmpUrlParts, curl;
+ var prot = dl.protocol, host = dl.hostname, port = dl.port;
- // Pass through file protocol
- if (prot == "file:")
- return url;
+ // Pass through file protocol
+ if (prot == "file:")
+ return url;
- // Something is wrong, remove weirdness
- url = tinyMCE.regexpReplace(url, '(http|https):///', '/');
+ // Something is wrong, remove weirdness
+ url = tinyMCE.regexpReplace(url, '(http|https):///', '/');
- // Mailto link or anchor (Pass through)
- if (url.indexOf('mailto:') != -1 || url.indexOf('javascript:') != -1 || tinyMCE.regexpReplace(url,'[ \t\r\n\+]|%20','').charAt(0) == "#")
- return url;
+ // Mailto link or anchor (Pass through)
+ if (url.indexOf('mailto:') != -1 || url.indexOf('javascript:') != -1 || /^[ \t\r\n\+]*[#\?]/.test(url))
+ return url;
- // Fix relative/Mozilla
- if (!tinyMCE.isIE && !on_save && url.indexOf("://") == -1 && url.charAt(0) != '/')
- return tinyMCE.settings['base_href'] + url;
+ // Fix relative/Mozilla
+ if (!tinyMCE.isIE && !on_save && url.indexOf("://") == -1 && url.charAt(0) != '/')
+ return tinyMCE.settings.base_href + url;
- // Handle relative URLs
- if (on_save && tinyMCE.getParam('relative_urls')) {
- var curl = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings['base_href'], url);
- if (curl.charAt(0) == '/')
- curl = tinyMCE.settings['document_base_prefix'] + curl;
+ // Handle relative URLs
+ if (on_save && tinyMCE.getParam('relative_urls')) {
+ curl = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings.base_href, url);
+ if (curl.charAt(0) == '/')
+ curl = tinyMCE.settings.document_base_prefix + curl;
- var urlParts = tinyMCE.parseURL(curl);
- var tmpUrlParts = tinyMCE.parseURL(tinyMCE.settings['document_base_url']);
+ urlParts = tinyMCE.parseURL(curl);
+ tmpUrlParts = tinyMCE.parseURL(tinyMCE.settings.document_base_url);
- // Force relative
- if (urlParts['host'] == tmpUrlParts['host'] && (urlParts['port'] == tmpUrlParts['port']))
- return tinyMCE.convertAbsoluteURLToRelativeURL(tinyMCE.settings['document_base_url'], curl);
- }
+ // Force relative
+ if (urlParts.host == tmpUrlParts.host && (urlParts.port == tmpUrlParts.port))
+ return tinyMCE.convertAbsoluteURLToRelativeURL(tinyMCE.settings.document_base_url, curl);
+ }
- // Handle absolute URLs
- if (!tinyMCE.getParam('relative_urls')) {
- var urlParts = tinyMCE.parseURL(url);
- var baseUrlParts = tinyMCE.parseURL(tinyMCE.settings['base_href']);
+ // Handle absolute URLs
+ if (!tinyMCE.getParam('relative_urls')) {
+ urlParts = tinyMCE.parseURL(url);
+ baseUrlParts = tinyMCE.parseURL(tinyMCE.settings.base_href);
- // Force absolute URLs from relative URLs
- url = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings['base_href'], url);
+ // Force absolute URLs from relative URLs
+ url = tinyMCE.convertRelativeToAbsoluteURL(tinyMCE.settings.base_href, url);
- // If anchor and path is the same page
- if (urlParts['anchor'] && urlParts['path'] == baseUrlParts['path'])
- return "#" + urlParts['anchor'];
- }
+ // If anchor and path is the same page
+ if (urlParts.anchor && urlParts.path == baseUrlParts.path)
+ return "#" + urlParts.anchor;
+ }
- // Remove current domain
- if (tinyMCE.getParam('remove_script_host')) {
- var start = "", portPart = "";
+ // Remove current domain
+ if (tinyMCE.getParam('remove_script_host')) {
+ start = "";
+ portPart = "";
- if (port != "")
- portPart = ":" + port;
+ if (port !== '')
+ portPart = ":" + port;
- start = prot + "//" + host + portPart + "/";
+ start = prot + "//" + host + portPart + "/";
- if (url.indexOf(start) == 0)
- url = url.substring(start.length-1);
- }
+ if (url.indexOf(start) == 0)
+ url = url.substring(start.length-1);
+ }
- return url;
-};
+ return url;
+ },
-TinyMCE_Engine.prototype.convertAllRelativeURLs = function(body) {
- var i, elms, src, href, mhref, msrc;
+ convertAllRelativeURLs : function(body) {
+ var i, elms, src, href, mhref, msrc;
- // Convert all image URL:s to absolute URL
- elms = body.getElementsByTagName("img");
- for (i=0; i 0)
rng.selectNodeContents(nodes[0]);
else
@@ -6706,7 +6799,7 @@ TinyMCE_Selection.prototype = {
function TinyMCE_UndoRedo(inst) {
this.instance = inst;
- this.undoLevels = new Array();
+ this.undoLevels = [];
this.undoIndex = 0;
this.typingUndoIndex = -1;
this.undoRedo = true;
@@ -6732,10 +6825,13 @@ TinyMCE_UndoRedo.prototype = {
if (this.undoLevels[this.undoIndex] && newHTML != this.undoLevels[this.undoIndex].content) {
//tinyMCE.debug(newHTML, this.undoLevels[this.undoIndex].content);
+ // Is dirty again
+ inst.isNotDirty = false;
+
tinyMCE.dispatchCallback(inst, 'onchange_callback', 'onChange', inst);
// Time to compress
- customUndoLevels = tinyMCE.settings['custom_undo_redo_levels'];
+ customUndoLevels = tinyMCE.settings.custom_undo_redo_levels;
if (customUndoLevels != -1 && this.undoLevels.length > customUndoLevels) {
for (i=0; i 1 ? ',' : '') + 'a[' + i + ']';
-
- o = s._fu;
- s._fu = this;
- r = eval('s._fu(' + as + ')');
- s._fu = o;
-
- return r;
- };
-};
-
/* file:jscripts/tiny_mce/classes/TinyMCE_Debug.class.js */
-TinyMCE_Engine.prototype.debug = function() {
- var m = "", a, i, l = tinyMCE.log.length;
+tinyMCE.add(TinyMCE_Engine, {
+ debug : function() {
+ var m = "", a, i, l = tinyMCE.log.length;
+
+ for (i=0, a = this.debug.arguments; i
diff --git a/wp-includes/js/tinymce/tiny_mce_popup.js b/wp-includes/js/tinymce/tiny_mce_popup.js
index e6c91c3..acfca0a 100644
--- a/wp-includes/js/tinymce/tiny_mce_popup.js
+++ b/wp-includes/js/tinymce/tiny_mce_popup.js
@@ -31,7 +31,7 @@ TinyMCE_Popup.prototype = {
init : function() {
var win = window.opener ? window.opener : window.dialogArguments, c;
- var inst;
+ var inst, re, title, divElm;
if (!win)
win = this.findWin(window);
@@ -61,18 +61,18 @@ TinyMCE_Popup.prototype = {
inst.selectionBookmark = inst.selection.getBookmark(true);
// Setup dir
- if (tinyMCELang['lang_dir'])
- document.dir = tinyMCELang['lang_dir'];
+ if (tinyMCELang.lang_dir)
+ document.dir = tinyMCELang.lang_dir;
// Setup title
- var re = new RegExp('{|\\\$|}', 'g');
- var title = document.title.replace(re, "");
- if (typeof tinyMCELang[title] != "undefined") {
- var divElm = document.createElement("div");
+ re = new RegExp('{|\\\$|}', 'g');
+ title = document.title.replace(re, "");
+ if (typeof(tinyMCELang[title]) != "undefined") {
+ divElm = document.createElement("div");
divElm.innerHTML = tinyMCELang[title];
document.title = divElm.innerHTML;
- if (tinyMCE.setWindowTitle != null)
+ if (typeof(tinyMCE.setWindowTitle) != 'undefined')
tinyMCE.setWindowTitle(window, divElm.innerHTML);
}
@@ -98,7 +98,7 @@ TinyMCE_Popup.prototype = {
if (tinyMCE.getWindowArg('mce_replacevariables', true))
body.innerHTML = tinyMCE.applyTemplate(body.innerHTML, tinyMCE.windowArgs);
- dir = tinyMCE.selectedInstance.settings['directionality'];
+ dir = tinyMCE.selectedInstance.settings.directionality;
if (dir == "rtl" && document.forms && document.forms.length > 0) {
elms = document.forms[0].elements;
for (i=0; i=0; i--) {
+ for (i=nodes.length-1; i>=0; i--) {
if (wrapper.hasChildNodes())
wrapper.insertBefore(nodes[i].cloneNode(true), wrapper.firstChild);
else
@@ -164,7 +165,7 @@ TinyMCE_Popup.prototype = {
// Create iframe
iframe = document.createElement("iframe");
iframe.id = "mcWinIframe";
- iframe.src = document.location.href.toLowerCase().indexOf('https') == -1 ? "about:blank" : tinyMCE.settings['default_document'];
+ iframe.src = document.location.href.toLowerCase().indexOf('https') == -1 ? "about:blank" : tinyMCE.settings.default_document;
iframe.width = "100%";
iframe.height = "100%";
iframe.style.margin = '0';
@@ -191,6 +192,7 @@ TinyMCE_Popup.prototype = {
resizeToContent : function() {
var isMSIE = (navigator.appName == "Microsoft Internet Explorer");
var isOpera = (navigator.userAgent.indexOf("Opera") != -1);
+ var elm, width, height, x, y, dx, dy;
if (isOpera)
return;
@@ -198,11 +200,11 @@ TinyMCE_Popup.prototype = {
if (isMSIE) {
try { window.resizeTo(10, 10); } catch (e) {}
- var elm = document.body;
- var width = elm.offsetWidth;
- var height = elm.offsetHeight;
- var dx = (elm.scrollWidth - width) + 4;
- var dy = elm.scrollHeight - height;
+ elm = document.body;
+ width = elm.offsetWidth;
+ height = elm.offsetHeight;
+ dx = (elm.scrollWidth - width) + 4;
+ dy = elm.scrollHeight - height;
try { window.resizeBy(dx, dy); } catch (e) {}
} else {
@@ -211,8 +213,8 @@ TinyMCE_Popup.prototype = {
window.resizeBy(window.innerWidth * 2, window.innerHeight * 2);
window.sizeToContent();
window.scrollTo(0, 0);
- var x = parseInt(screen.width / 2.0) - (window.outerWidth / 2.0);
- var y = parseInt(screen.height / 2.0) - (window.outerHeight / 2.0);
+ x = parseInt(screen.width / 2.0) - (window.outerWidth / 2.0);
+ y = parseInt(screen.height / 2.0) - (window.outerHeight / 2.0);
window.moveTo(x, y);
}
}
@@ -223,8 +225,10 @@ TinyMCE_Popup.prototype = {
},
restoreSelection : function() {
+ var inst;
+
if (this.storeSelection) {
- var inst = tinyMCE.selectedInstance;
+ inst = tinyMCE.selectedInstance;
inst.getWin().focus();
@@ -272,9 +276,11 @@ TinyMCE_Popup.prototype = {
},
importClass : function(c) {
+ var n;
+
window[c] = function() {};
- for (var n in window.opener[c].prototype)
+ for (n in window.opener[c].prototype)
window[c].prototype[n] = window.opener[c].prototype[n];
window[c].constructor = window.opener[c].constructor;
diff --git a/wp-includes/js/tinymce/wp-mce-help.php b/wp-includes/js/tinymce/wp-mce-help.php
index 6d5f1e4..9bcdc5c 100644
--- a/wp-includes/js/tinymce/wp-mce-help.php
+++ b/wp-includes/js/tinymce/wp-mce-help.php
@@ -6,10 +6,7 @@ header('Content-Type: text/html; charset=' . get_bloginfo('charset'));
-
-text_direction) ) : ?>
-
-
+
-
+
\n";
@@ -175,6 +184,9 @@ class WP_Scripts {
$this->printed[] = $handle;
}
}
+
+ $this->to_print = array();
+ return $this->printed;
}
function print_scripts_l10n( $handle ) {
@@ -199,33 +211,43 @@ class WP_Scripts {
/**
* Determines dependencies of scripts
*
- * Recursively builds hierarchical array of script dependencies. Does NOT catch infinite loops.
+ * Recursively builds array of scripts to print taking dependencies into account. Does NOT catch infinite loops.
*
* @param mixed handles Accepts (string) script name or (array of strings) script names
* @param bool recursion Used internally when function calls itself
- * @return array Hierarchical array of dependencies
*/
function all_deps( $handles, $recursion = false ) {
- if ( ! $handles = (array) $handles )
- return array();
- $return = array();
+ if ( !$handles = (array) $handles )
+ return false;
+
foreach ( $handles as $handle ) {
$handle = explode('?', $handle);
if ( isset($handle[1]) )
$this->args[$handle[0]] = $handle[1];
$handle = $handle[0];
- if ( is_null($return[$handle]) ) // Prime the return array with $handles
- $return[$handle] = true;
- if ( $this->scripts[$handle]->deps ) {
- if ( false !== $return[$handle] && array_diff($this->scripts[$handle]->deps, array_keys($this->scripts)) )
- $return[$handle] = false; // Script required deps which don't exist
+
+ if ( isset($this->to_print[$handle]) ) // Already grobbed it and its deps
+ continue;
+
+ $keep_going = true;
+ if ( !isset($this->scripts[$handle]) )
+ $keep_going = false; // Script doesn't exist
+ elseif ( $this->scripts[$handle]->deps && array_diff($this->scripts[$handle]->deps, array_keys($this->scripts)) )
+ $keep_going = false; // Script requires deps which don't exist (not a necessary check. efficiency?)
+ elseif ( $this->scripts[$handle]->deps && !$this->all_deps( $this->scripts[$handle]->deps, true ) )
+ $keep_going = false; // Script requires deps which don't exist
+
+ if ( !$keep_going ) { // Either script or its deps don't exist.
+ if ( $recursion )
+ return false; // Abort this branch.
else
- $return[$handle] = $this->all_deps( $this->scripts[$handle]->deps, true ); // Build the hierarchy
- }
- if ( $recursion && false === $return[$handle] )
- return false; // Cut the branch
+ continue; // We're at the top level. Move on to the next one.
+ }
+
+ $this->to_print[$handle] = true;
}
- return $return;
+
+ return true;
}
/**
diff --git a/wp-includes/taxonomy.php b/wp-includes/taxonomy.php
new file mode 100644
index 0000000..ea2f432
--- /dev/null
+++ b/wp-includes/taxonomy.php
@@ -0,0 +1,1410 @@
+ 'category', 'object_type' => 'post', 'hierarchical' => true, 'update_count_callback' => '_update_post_term_count');
+$wp_taxonomies['post_tag'] = (object) array('name' => 'post_tag', 'object_type' => 'post', 'hierarchical' => false, 'update_count_callback' => '_update_post_term_count');
+$wp_taxonomies['link_category'] = (object) array('name' => 'link_category', 'object_type' => 'link', 'hierarchical' => false);
+
+/**
+ * get_object_taxonomies() - Return all of the taxonomy names that are of $object_type
+ *
+ * It appears that this function can be used to find all of the names inside of
+ * $wp_taxonomies global variable.
+ *
+ * @example
+ *
+ * Should result in Array(
+ * 'category',
+ * 'post_tag'
+ * )
+ *
+ * @package Taxonomy
+ * @global array $wp_taxonomies
+ * @param string $object_type Name of the type of taxonomy object
+ * @return array The names of all within the object_type.
+ *
+ * @internal
+ * This is all conjecture and might be partially or completely inaccurate.
+ */
+function get_object_taxonomies($object_type) {
+ global $wp_taxonomies;
+
+ $taxonomies = array();
+ foreach ( $wp_taxonomies as $taxonomy ) {
+ if ( $object_type == $taxonomy->object_type )
+ $taxonomies[] = $taxonomy->name;
+ }
+
+ return $taxonomies;
+}
+
+/**
+ * get_taxonomy() - Returns the "taxonomy" object of $taxonomy.
+ *
+ * The get_taxonomy function will first check that the parameter string given
+ * is a taxonomy object and if it is, it will return it.
+ *
+ * @package Taxonomy
+ * @global array $wp_taxonomies
+ * @param string $taxonomy Name of taxonomy object to return
+ * @return object|bool The Taxonomy Object or false if taxonomy doesn't exist
+ *
+ * @internal
+ * This is all conjecture and might be partially or completely inaccurate.
+ */
+function get_taxonomy( $taxonomy ) {
+ global $wp_taxonomies;
+
+ if ( ! is_taxonomy($taxonomy) )
+ return false;
+
+ return $wp_taxonomies[$taxonomy];
+}
+
+/**
+ * is_taxonomy() - Checks that the taxonomy name exists
+ *
+ * @package Taxonomy
+ * @global array $wp_taxonomies
+ * @param string $taxonomy Name of taxonomy object
+ * @return bool Whether the taxonomy exists or not.
+ *
+ * @internal
+ * This is all conjecture and might be partially or completely inaccurate.
+ */
+function is_taxonomy( $taxonomy ) {
+ global $wp_taxonomies;
+
+ return isset($wp_taxonomies[$taxonomy]);
+}
+
+/**
+ * is_taxonomy_hierarchical() - Whether the taxonomy object is hierarchical
+ *
+ * Checks to make sure that the taxonomy is an object first. Then Gets the object, and finally
+ * returns the hierarchical value in the object.
+ *
+ * A false return value, might also mean that the taxonomy does not exist.
+ *
+ * @package Taxonomy
+ * @global array $wp_taxonomies
+ * @param string $taxonomy Name of taxonomy object
+ * @return bool Whether the taxonomy is hierarchical
+ *
+ * @internal
+ * This is all conjecture and might be partially or completely inaccurate.
+ */
+function is_taxonomy_hierarchical($taxonomy) {
+ if ( ! is_taxonomy($taxonomy) )
+ return false;
+
+ $taxonomy = get_taxonomy($taxonomy);
+ return $taxonomy->hierarchical;
+}
+
+/**
+ * register_taxonomy() - Create or modify a taxonomy object.
+ *
+ * A simple function for creating or modifying a taxonomy object based on the parameters given.
+ * The function will accept an array (third optional parameter), along with strings for the
+ * taxonomy name and another string for the object type.
+ *
+ * The function keeps a default set, allowing for the $args to be optional but allow the other
+ * functions to still work. It is possible to overwrite the default set, which contains two
+ * keys: hierarchical and update_count_callback.
+ *
+ * hierarachical has some defined purpose at other parts of the API and is a boolean value.
+ *
+ * update_count_callback works much like a hook, in that it will be called (or something from
+ * somewhere).
+ *
+ * @package Taxonomy
+ * @global array $wp_taxonomies
+ * @param string $taxonomy Name of taxonomy object
+ * @param string $object_type Name of the object type for the taxonomy object.
+ * @param array|string $args See above description for the two keys values.
+ * @return null Nothing is returned, so expect error maybe or use is_taxonomy() to check.
+ *
+ * @internal
+ * This is all conjecture and might be partially or completely inaccurate.
+ */
+function register_taxonomy( $taxonomy, $object_type, $args = array() ) {
+ global $wp_taxonomies;
+
+ $defaults = array('hierarchical' => false, 'update_count_callback' => '');
+ $args = wp_parse_args($args, $defaults);
+
+ $args['name'] = $taxonomy;
+ $args['object_type'] = $object_type;
+ $wp_taxonomies[$taxonomy] = (object) $args;
+}
+
+//
+// Term API
+//
+
+/**
+ * get_objects_in_term() - Return object_ids of valid taxonomy and term
+ *
+ * The strings of $taxonomies must exist before this function will continue. On failure of finding
+ * a valid taxonomy, it will return an WP_Error class, kind of like Exceptions in PHP 5, except you
+ * can't catch them. Even so, you can still test for the WP_Error class and get the error message.
+ *
+ * The $terms aren't checked the same as $taxonomies, but still need to exist for $object_ids to
+ * be returned.
+ *
+ * It is possible to change the order that object_ids is returned by either using PHP sort family
+ * functions or using the database by using $args with either ASC or DESC array. The value should
+ * be in the key named 'order'.
+ *
+ * @package Taxonomy
+ * @subpackage Term
+ * @global object $wpdb Database Query
+ * @param string|array $terms String of term or array of string values of terms that will be used
+ * @param string|array $taxonomies String of taxonomy name or Array of string values of taxonomy names
+ * @param array|string $args Change the order of the object_ids, either ASC or DESC
+ * @return object WP_Error - A PHP 4 compatible Exception class prototype
+ * @return array Empty array if there are no $object_ids
+ * @return array Array of $object_ids
+ *
+ * @internal
+ * This is all conjecture and might be partially or completely inaccurate.
+ */
+function get_objects_in_term( $terms, $taxonomies, $args = array() ) {
+ global $wpdb;
+
+ if ( !is_array( $terms) )
+ $terms = array($terms);
+
+ if ( !is_array($taxonomies) )
+ $taxonomies = array($taxonomies);
+
+ foreach ( $taxonomies as $taxonomy ) {
+ if ( ! is_taxonomy($taxonomy) )
+ return new WP_Error('invalid_taxonomy', __('Invalid Taxonomy'));
+ }
+
+ $defaults = array('order' => 'ASC');
+ $args = wp_parse_args( $args, $defaults );
+ extract($args, EXTR_SKIP);
+
+ $terms = array_map('intval', $terms);
+
+ $taxonomies = "'" . implode("', '", $taxonomies) . "'";
+ $terms = "'" . implode("', '", $terms) . "'";
+
+ $object_ids = $wpdb->get_col("SELECT tr.object_id FROM $wpdb->term_relationships AS tr INNER JOIN $wpdb->term_taxonomy AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tt.taxonomy IN ($taxonomies) AND tt.term_id IN ($terms) ORDER BY tr.object_id $order");
+
+ if ( ! $object_ids )
+ return array();
+
+ return $object_ids;
+}
+
+/**
+ * get_term() -
+ *
+ *
+ *
+ * @package Taxonomy
+ * @subpackage Term
+ * @global object $wpdb Database Query
+ * @param int|object $term
+ * @param string $taxonomy
+ * @param string $output Either OBJECT, ARRAY_A, or ARRAY_N
+ * @return mixed Term Row from database
+ *
+ * @internal
+ * This won't appear but just a note to say that this is all conjecture and parts or whole
+ * might be inaccurate or wrong.
+ */
+function &get_term($term, $taxonomy, $output = OBJECT, $filter = 'raw') {
+ global $wpdb;
+
+ if ( empty($term) )
+ return null;
+
+ if ( ! is_taxonomy($taxonomy) )
+ return new WP_Error('invalid_taxonomy', __('Invalid Taxonomy'));
+
+ if ( is_object($term) ) {
+ wp_cache_add($term->term_id, $term, $taxonomy);
+ $_term = $term;
+ } else {
+ $term = (int) $term;
+ if ( ! $_term = wp_cache_get($term, $taxonomy) ) {
+ $_term = $wpdb->get_row("SELECT t.*, tt.* FROM $wpdb->terms AS t INNER JOIN $wpdb->term_taxonomy AS tt ON t.term_id = tt.term_id WHERE tt.taxonomy = '$taxonomy' AND t.term_id = '$term' LIMIT 1");
+ wp_cache_add($term, $_term, $taxonomy);
+ }
+ }
+
+ /**
+ * @internal
+ * Filter tag is basically: filter 'type' 'hook_name' 'description'
+ *
+ * Takes two parameters the term Object and the taxonomy name. Must return term object.
+ * @filter object get_term Used in @see get_term() as a catch-all filter for every $term
+ */
+ $_term = apply_filters('get_term', $_term, $taxonomy);
+ /**
+ * @internal
+ * Filter tag is basically: filter 'type' 'hook_name' 'description'
+ *
+ * Takes two parameters the term Object and the taxonomy name. Must return term object.
+ * $taxonomy will be the taxonomy name, so for example, if 'category', it would be 'get_category'
+ * as the filter name.
+ * Useful for custom taxonomies or plugging into default taxonomies.
+ * @filter object get_$taxonomy Used in @see get_term() as specific filter for each $taxonomy.
+ */
+ $_term = apply_filters("get_$taxonomy", $_term, $taxonomy);
+ $_term = sanitize_term($_term, $taxonomy, $filter);
+
+ if ( $output == OBJECT ) {
+ return $_term;
+ } elseif ( $output == ARRAY_A ) {
+ return get_object_vars($_term);
+ } elseif ( $output == ARRAY_N ) {
+ return array_values(get_object_vars($_term));
+ } else {
+ return $_term;
+ }
+}
+
+/**
+ * get_term_by() -
+ *
+ *
+ *
+ * @package Taxonomy
+ * @subpackage Term
+ * @global object $wpdb Database Query
+ * @param string $field
+ * @param string $value
+ * @param string $taxonomy
+ * @param string $output Either OBJECT, ARRAY_A, or ARRAY_N
+ * @return mixed Term Row from database
+ *
+ * @internal
+ * This won't appear but just a note to say that this is all conjecture and parts or whole
+ * might be inaccurate or wrong.
+ */
+function get_term_by($field, $value, $taxonomy, $output = OBJECT, $filter = 'raw') {
+ global $wpdb;
+
+ if ( ! is_taxonomy($taxonomy) )
+ return false;
+
+ if ( 'slug' == $field ) {
+ $field = 't.slug';
+ $value = sanitize_title($value);
+ if ( empty($value) )
+ return false;
+ } else if ( 'name' == $field ) {
+ // Assume already escaped
+ $field = 't.name';
+ } else {
+ $field = 't.term_id';
+ $value = (int) $value;
+ }
+
+ $term = $wpdb->get_row("SELECT t.*, tt.* FROM $wpdb->terms AS t INNER JOIN $wpdb->term_taxonomy AS tt ON t.term_id = tt.term_id WHERE tt.taxonomy = '$taxonomy' AND $field = '$value' LIMIT 1");
+ if ( !$term )
+ return false;
+
+ wp_cache_add($term->term_id, $term, $taxonomy);
+
+ $term = sanitize_term($term, $taxonomy, $filter);
+
+ if ( $output == OBJECT ) {
+ return $term;
+ } elseif ( $output == ARRAY_A ) {
+ return get_object_vars($term);
+ } elseif ( $output == ARRAY_N ) {
+ return array_values(get_object_vars($term));
+ } else {
+ return $term;
+ }
+}
+
+/**
+ * get_term_children() - Merge all term children into a single array.
+ *
+ * This recursive function will merge all of the children of $term into
+ * the same array.
+ *
+ * Only useful for taxonomies which are hierarchical.
+ *
+ * @package Taxonomy
+ * @subpackage Term
+ * @global object $wpdb Database Query
+ * @param string $term Name of Term to get children
+ * @param string $taxonomy Taxonomy Name
+ * @return array List of Term Objects
+ *
+ * @internal
+ * This is all conjecture and might be partially or completely inaccurate.
+ */
+function get_term_children( $term, $taxonomy ) {
+ if ( ! is_taxonomy($taxonomy) )
+ return new WP_Error('invalid_taxonomy', __('Invalid Taxonomy'));
+
+ $terms = _get_term_hierarchy($taxonomy);
+
+ if ( ! isset($terms[$term]) )
+ return array();
+
+ $children = $terms[$term];
+
+ foreach ( $terms[$term] as $child ) {
+ if ( isset($terms[$child]) )
+ $children = array_merge($children, get_term_children($child, $taxonomy));
+ }
+
+ return $children;
+}
+
+/**
+ * get_term_field() - Get sanitized Term field
+ *
+ * Does checks for $term, based on the $taxonomy. The function is for
+ * contextual reasons and for simplicity of usage. @see sanitize_term_field() for
+ * more information.
+ *
+ * @package Taxonomy
+ * @subpackage Term
+ * @param string $field Term field to fetch
+ * @param int $term Term ID
+ * @param string $taxonomy Taxonomy Name
+ * @param string $context ??
+ * @return mixed @see sanitize_term_field()
+ *
+ * @internal
+ * This is all conjecture and might be partially or completely inaccurate.
+ */
+function get_term_field( $field, $term, $taxonomy, $context = 'display' ) {
+ $term = (int) $term;
+ $term = get_term( $term, $taxonomy );
+ if ( is_wp_error($term) )
+ return $term;
+
+ if ( !is_object($term) )
+ return '';
+
+ if ( !isset($term->$field) )
+ return '';
+
+ return sanitize_term_field($field, $term->$field, $term->term_id, $taxonomy, $context);
+}
+
+/**
+ * get_term_to_edit() - Sanitizes Term for editing
+ *
+ * Return value is @see sanitize_term() and usage is for sanitizing the term
+ * for editing. Function is for contextual and simplicity.
+ *
+ * @package Taxonomy
+ * @subpackage Term
+ * @param int|object $id Term ID or Object
+ * @param string $taxonomy Taxonomy Name
+ * @return mixed @see sanitize_term()
+ *
+ * @internal
+ * This is all conjecture and might be partially or completely inaccurate.
+ */
+function get_term_to_edit( $id, $taxonomy ) {
+ $term = get_term( $id, $taxonomy );
+
+ if ( is_wp_error($term) )
+ return $term;
+
+ if ( !is_object($term) )
+ return '';
+
+ return sanitize_term($term, $taxonomy, 'edit');
+}
+
+/**
+ * get_terms() -
+ *
+ *
+ *
+ * @package Taxonomy
+ * @subpackage Term
+ * @param string|array Taxonomy name or list of Taxonomy names
+ * @param string|array $args ??
+ * @return array List of Term Objects and their children.
+ *
+ * @internal
+ * This is all conjecture and might be partially or completely inaccurate.
+ */
+function &get_terms($taxonomies, $args = '') {
+ global $wpdb;
+
+ $single_taxonomy = false;
+ if ( !is_array($taxonomies) ) {
+ $single_taxonomy = true;
+ $taxonomies = array($taxonomies);
+ }
+
+ foreach ( $taxonomies as $taxonomy ) {
+ if ( ! is_taxonomy($taxonomy) )
+ return new WP_Error('invalid_taxonomy', __('Invalid Taxonomy'));
+ }
+
+ $in_taxonomies = "'" . implode("', '", $taxonomies) . "'";
+
+ $defaults = array('orderby' => 'name', 'order' => 'ASC',
+ 'hide_empty' => true, 'exclude' => '', 'include' => '',
+ 'number' => '', 'fields' => 'all', 'slug' => '', 'parent' => '',
+ 'hierarchical' => true, 'child_of' => 0, 'get' => '', 'name__like' => '',
+ 'pad_counts' => false);
+ $args = wp_parse_args( $args, $defaults );
+ $args['number'] = (int) $args['number'];
+ if ( !$single_taxonomy || !is_taxonomy_hierarchical($taxonomies[0]) ||
+ '' != $args['parent'] ) {
+ $args['child_of'] = 0;
+ $args['hierarchical'] = false;
+ $args['pad_counts'] = false;
+ }
+
+ if ( 'all' == $args['get'] ) {
+ $args['child_of'] = 0;
+ $args['hide_empty'] = 0;
+ $args['hierarchical'] = false;
+ $args['pad_counts'] = false;
+ }
+ extract($args, EXTR_SKIP);
+
+ if ( $child_of ) {
+ $hierarchy = _get_term_hierarchy($taxonomies[0]);
+ if ( !isset($hierarchy[$child_of]) )
+ return array();
+ }
+
+ if ( $parent ) {
+ $hierarchy = _get_term_hierarchy($taxonomies[0]);
+ if ( !isset($hierarchy[$parent]) )
+ return array();
+ }
+
+ $key = md5( serialize( $args ) . serialize( $taxonomies ) );
+ if ( $cache = wp_cache_get( 'get_terms', 'terms' ) ) {
+ if ( isset( $cache[ $key ] ) )
+ return apply_filters('get_terms', $cache[$key], $taxonomies, $args);
+ }
+
+ if ( 'count' == $orderby )
+ $orderby = 'tt.count';
+ else if ( 'name' == $orderby )
+ $orderby = 't.name';
+ else
+ $orderby = 't.term_id';
+
+ $where = '';
+ $inclusions = '';
+ if ( !empty($include) ) {
+ $exclude = '';
+ $interms = preg_split('/[\s,]+/',$include);
+ if ( count($interms) ) {
+ foreach ( $interms as $interm ) {
+ if (empty($inclusions))
+ $inclusions = ' AND ( t.term_id = ' . intval($interm) . ' ';
+ else
+ $inclusions .= ' OR t.term_id = ' . intval($interm) . ' ';
+ }
+ }
+ }
+
+ if ( !empty($inclusions) )
+ $inclusions .= ')';
+ $where .= $inclusions;
+
+ $exclusions = '';
+ if ( !empty($exclude) ) {
+ $exterms = preg_split('/[\s,]+/',$exclude);
+ if ( count($exterms) ) {
+ foreach ( $exterms as $exterm ) {
+ if (empty($exclusions))
+ $exclusions = ' AND ( t.term_id <> ' . intval($exterm) . ' ';
+ else
+ $exclusions .= ' AND t.term_id <> ' . intval($exterm) . ' ';
+ }
+ }
+ }
+
+ if ( !empty($exclusions) )
+ $exclusions .= ')';
+ $exclusions = apply_filters('list_terms_exclusions', $exclusions, $args );
+ $where .= $exclusions;
+
+ if ( !empty($slug) ) {
+ $slug = sanitize_title($slug);
+ $where .= " AND t.slug = '$slug'";
+ }
+
+ if ( !empty($name__like) )
+ $where .= " AND t.name LIKE '{$name__like}%'";
+
+ if ( '' != $parent ) {
+ $parent = (int) $parent;
+ $where .= " AND tt.parent = '$parent'";
+ }
+
+ if ( $hide_empty && !$hierarchical )
+ $where .= ' AND tt.count > 0';
+
+ if ( !empty($number) )
+ $number = 'LIMIT ' . $number;
+ else
+ $number = '';
+
+ if ( 'all' == $fields )
+ $select_this = 't.*, tt.*';
+ else if ( 'ids' == $fields )
+ $select_this = 't.term_id';
+ else if ( 'names' == $fields )
+ $select_this == 't.name';
+
+ $query = "SELECT $select_this FROM $wpdb->terms AS t INNER JOIN $wpdb->term_taxonomy AS tt ON t.term_id = tt.term_id WHERE tt.taxonomy IN ($in_taxonomies) $where ORDER BY $orderby $order $number";
+
+ if ( 'all' == $fields ) {
+ $terms = $wpdb->get_results($query);
+ update_term_cache($terms);
+ } else if ( 'ids' == $fields ) {
+ $terms = $wpdb->get_col($query);
+ }
+
+ if ( empty($terms) )
+ return array();
+
+ if ( $child_of || $hierarchical ) {
+ $children = _get_term_hierarchy($taxonomies[0]);
+ if ( ! empty($children) )
+ $terms = & _get_term_children($child_of, $terms, $taxonomies[0]);
+ }
+
+ // Update term counts to include children.
+ if ( $pad_counts )
+ _pad_term_counts($terms, $taxonomies[0]);
+
+ // Make sure we show empty categories that have children.
+ if ( $hierarchical && $hide_empty ) {
+ foreach ( $terms as $k => $term ) {
+ if ( ! $term->count ) {
+ $children = _get_term_children($term->term_id, $terms, $taxonomies[0]);
+ foreach ( $children as $child )
+ if ( $child->count )
+ continue 2;
+
+ // It really is empty
+ unset($terms[$k]);
+ }
+ }
+ }
+ reset ( $terms );
+
+ $cache[ $key ] = $terms;
+ wp_cache_set( 'get_terms', $cache, 'terms' );
+
+ $terms = apply_filters('get_terms', $terms, $taxonomies, $args);
+ return $terms;
+}
+
+/**
+ * is_term() - Check if Term exists
+ *
+ * Returns the index of a defined term, or 0 (false) if the term doesn't exist.
+ *
+ * @global $wpdb Database Object
+ * @param int|string $term The term to check
+ * @param string $taxonomy The taxonomy name to use
+ * @return mixed Get the term id or Term Object, if exists.
+ */
+function is_term($term, $taxonomy = '') {
+ global $wpdb;
+
+ if ( is_int($term) ) {
+ if ( 0 == $term )
+ return 0;
+ $where = "t.term_id = '$term'";
+ } else {
+ if ( ! $term = sanitize_title($term) )
+ return 0;
+ $where = "t.slug = '$term'";
+ }
+
+ $term_id = $wpdb->get_var("SELECT term_id FROM $wpdb->terms as t WHERE $where");
+
+ if ( empty($taxonomy) || empty($term_id) )
+ return $term_id;
+
+ return $wpdb->get_row("SELECT tt.term_id, tt.term_taxonomy_id FROM $wpdb->terms AS t INNER JOIN $wpdb->term_taxonomy as tt ON tt.term_id = t.term_id WHERE $where AND tt.taxonomy = '$taxonomy'", ARRAY_A);
+}
+
+/**
+ * sanitize_term() - Sanitize Term all fields
+ *
+ * Relys on @see sanitize_term_field() to sanitize the term. The difference
+ * is that this function will sanitize all fields. The context
+ * is based on @see sanitize_term_field().
+ *
+ * The $term is expected to be either an array or an object.
+ *
+ * @param array|object $term The term to check
+ * @param string $taxonomy The taxonomy name to use
+ * @param string $context Default is display
+ * @return array|object Term with all fields sanitized
+ */
+function sanitize_term($term, $taxonomy, $context = 'display') {
+ $fields = array('term_id', 'name', 'description', 'slug', 'count', 'parent', 'term_group');
+
+ $do_object = false;
+ if ( is_object($term) )
+ $do_object = true;
+
+ foreach ( $fields as $field ) {
+ if ( $do_object )
+ $term->$field = sanitize_term_field($field, $term->$field, $term->term_id, $taxonomy, $context);
+ else
+ $term[$field] = sanitize_term_field($field, $term[$field], $term['term_id'], $taxonomy, $context);
+ }
+
+ return $term;
+}
+
+/**
+ * sanitize_term_field() -
+ *
+ *
+ *
+ * @global object $wpdb Database Object
+ * @param string $field Term field to sanitize
+ * @param string $value Search for this term value
+ * @param int $term_id Term ID
+ * @param string $taxonomy Taxonomy Name
+ * @param string $context Either edit, db, display, attribute, or js.
+ * @return mixed sanitized field
+ */
+function sanitize_term_field($field, $value, $term_id, $taxonomy, $context) {
+ if ( 'parent' == $field || 'term_id' == $field || 'count' == $field
+ || 'term_group' == $field )
+ $value = (int) $value;
+
+ if ( 'edit' == $context ) {
+ $value = apply_filters("edit_term_$field", $value, $term_id, $taxonomy);
+ $value = apply_filters("edit_${taxonomy}_$field", $value, $term_id);
+ if ( 'description' == $field )
+ $value = format_to_edit($value);
+ else
+ $value = attribute_escape($value);
+ } else if ( 'db' == $context ) {
+ $value = apply_filters("pre_term_$field", $value, $taxonomy);
+ $value = apply_filters("pre_${taxonomy}_$field", $value);
+ // Back compat filters
+ if ( 'slug' == $field )
+ $value = apply_filters('pre_category_nicename', $value);
+
+ } else if ( 'rss' == $context ) {
+ $value = apply_filters("term_${field}_rss", $value, $taxonomy);
+ $value = apply_filters("${taxonomy}_$field_rss", $value);
+ } else {
+ // Use display filters by default.
+ $value = apply_filters("term_$field", $value, $term_id, $taxonomy, $context);
+ $value = apply_filters("${taxonomy}_$field", $value, $term_id, $context);
+ }
+
+ if ( 'attribute' == $context )
+ $value = attribute_escape($value);
+ else if ( 'js' == $context )
+ $value = js_escape($value);
+
+ return $value;
+}
+
+/**
+ * wp_count_terms() - Count how many terms are in Taxonomy
+ *
+ * Default $args is 'ignore_empty' which can be @example 'ignore_empty=true' or
+ * @example array('ignore_empty' => true); See @see wp_parse_args() for more
+ * information on parsing $args.
+ *
+ * @global object $wpdb Database Object
+ * @param string $taxonomy Taxonomy name
+ * @param array|string $args Overwrite defaults
+ * @return int How many terms are in $taxonomy
+ */
+function wp_count_terms( $taxonomy, $args = array() ) {
+ global $wpdb;
+
+ $defaults = array('ignore_empty' => false);
+ $args = wp_parse_args($args, $defaults);
+ extract($args, EXTR_SKIP);
+
+ $where = '';
+ if ( $ignore_empty )
+ $where = 'AND count > 0';
+
+ return $wpdb->get_var("SELECT COUNT(*) FROM $wpdb->term_taxonomy WHERE taxonomy = '$taxonomy' $where");
+}
+
+/**
+ * wp_delete_object_term_relationships() -
+ *
+ *
+ *
+ * @global object $wpdb Database Object
+ * @param int $object_id ??
+ * @param string|array $taxonomy List of Taxonomy Names or single Taxonomy name.
+ */
+function wp_delete_object_term_relationships( $object_id, $taxonomies ) {
+ global $wpdb;
+
+ $object_id = (int) $object_id;
+
+ if ( !is_array($taxonomies) )
+ $taxonomies = array($taxonomies);
+
+ foreach ( $taxonomies as $taxonomy ) {
+ $terms = wp_get_object_terms($object_id, $taxonomy, 'fields=tt_ids');
+ $in_terms = "'" . implode("', '", $terms) . "'";
+ $wpdb->query("DELETE FROM $wpdb->term_relationships WHERE object_id = '$object_id' AND term_taxonomy_id IN ($in_terms)");
+ wp_update_term_count($terms, $taxonomy);
+ }
+}
+
+/**
+ * Removes a term from the database.
+ */
+function wp_delete_term( $term, $taxonomy, $args = array() ) {
+ global $wpdb;
+
+ $term = (int) $term;
+
+ if ( ! $ids = is_term($term, $taxonomy) )
+ return false;
+ $tt_id = $ids['term_taxonomy_id'];
+
+ $defaults = array();
+ $args = wp_parse_args($args, $defaults);
+ extract($args, EXTR_SKIP);
+
+ if ( isset($default) ) {
+ $default = (int) $default;
+ if ( ! is_term($default, $taxonomy) )
+ unset($default);
+ }
+
+ // Update children to point to new parent
+ if ( is_taxonomy_hierarchical($taxonomy) ) {
+ $term_obj = get_term($term, $taxonomy);
+ if ( is_wp_error( $term_obj ) )
+ return $term_obj;
+ $parent = $term_obj->parent;
+
+ $wpdb->query("UPDATE $wpdb->term_taxonomy SET parent = '$parent' WHERE parent = '$term_obj->term_id' AND taxonomy = '$taxonomy'");
+ }
+
+ $objects = $wpdb->get_col("SELECT object_id FROM $wpdb->term_relationships WHERE term_taxonomy_id = '$tt_id'");
+
+ foreach ( (array) $objects as $object ) {
+ $terms = wp_get_object_terms($object, $taxonomy, 'fields=ids');
+ if ( 1 == count($terms) && isset($default) )
+ $terms = array($default);
+ else
+ $terms = array_diff($terms, array($term));
+ $terms = array_map('intval', $terms);
+ wp_set_object_terms($object, $terms, $taxonomy);
+ }
+
+ $wpdb->query("DELETE FROM $wpdb->term_taxonomy WHERE term_taxonomy_id = '$tt_id'");
+
+ // Delete the term if no taxonomies use it.
+ if ( !$wpdb->get_var("SELECT COUNT(*) FROM $wpdb->term_taxonomy WHERE term_id = '$term'") )
+ $wpdb->query("DELETE FROM $wpdb->terms WHERE term_id = '$term'");
+
+ clean_term_cache($term, $taxonomy);
+
+ do_action('delete_term', $term, $tt_id, $taxonomy);
+ do_action("delete_$taxonomy", $term, $tt_id);
+
+ return true;
+}
+
+/**
+ * Returns the terms associated with the given object(s), in the supplied taxonomies.
+ * @param int|array $object_id The id of the object(s)) to retrieve for.
+ * @param string|array $taxonomies The taxonomies to retrieve terms from.
+ * @return array The requested term data.
+ */
+function wp_get_object_terms($object_ids, $taxonomies, $args = array()) {
+ global $wpdb;
+
+ if ( !is_array($taxonomies) )
+ $taxonomies = array($taxonomies);
+
+ foreach ( $taxonomies as $taxonomy ) {
+ if ( ! is_taxonomy($taxonomy) )
+ return new WP_Error('invalid_taxonomy', __('Invalid Taxonomy'));
+ }
+
+ if ( !is_array($object_ids) )
+ $object_ids = array($object_ids);
+ $object_ids = array_map('intval', $object_ids);
+
+ $defaults = array('orderby' => 'name', 'order' => 'ASC', 'fields' => 'all');
+ $args = wp_parse_args( $args, $defaults );
+ extract($args, EXTR_SKIP);
+
+ if ( 'count' == $orderby )
+ $orderby = 'tt.count';
+ else if ( 'name' == $orderby )
+ $orderby = 't.name';
+
+ $taxonomies = "'" . implode("', '", $taxonomies) . "'";
+ $object_ids = implode(', ', $object_ids);
+
+ if ( 'all' == $fields )
+ $select_this = 't.*, tt.*';
+ else if ( 'ids' == $fields )
+ $select_this = 't.term_id';
+ else if ( 'names' == $fields )
+ $select_this = 't.name';
+ else if ( 'all_with_object_id' == $fields )
+ $select_this = 't.*, tt.*, tr.object_id';
+
+ $query = "SELECT $select_this FROM $wpdb->terms AS t INNER JOIN $wpdb->term_taxonomy AS tt ON tt.term_id = t.term_id INNER JOIN $wpdb->term_relationships AS tr ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tt.taxonomy IN ($taxonomies) AND tr.object_id IN ($object_ids) ORDER BY $orderby $order";
+
+ if ( 'all' == $fields || 'all_with_object_id' == $fields ) {
+ $terms = $wpdb->get_results($query);
+ update_term_cache($terms);
+ } else if ( 'ids' == $fields || 'names' == $fields ) {
+ $terms = $wpdb->get_col($query);
+ } else if ( 'tt_ids' == $fields ) {
+ $terms = $wpdb->get_col("SELECT tr.term_taxonomy_id FROM $wpdb->term_relationships AS tr INNER JOIN $wpdb->term_taxonomy AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tr.object_id IN ($object_ids) AND tt.taxonomy IN ($taxonomies) ORDER BY tr.term_taxonomy_id $order");
+ }
+
+ if ( ! $terms )
+ return array();
+
+ return $terms;
+}
+
+/**
+ * wp_insert_term() - Adds a new term to the database. Optionally marks it as an alias of an existing term.
+ *
+ *
+ *
+ * @global $wpdb Database Object
+ * @param int|string $term The term to add or update.
+ * @param string $taxonomy The taxonomy to which to add the term
+ * @param array|string $args Change the values of the inserted term
+ * @return array The Term ID and Term Taxonomy ID
+ */
+function wp_insert_term( $term, $taxonomy, $args = array() ) {
+ global $wpdb;
+
+ if ( ! is_taxonomy($taxonomy) )
+ return new WP_Error('invalid_taxonomy', __('Invalid taxonomy'));
+
+ if ( is_int($term) && 0 == $term )
+ return new WP_Error('invalid_term_id', __('Invalid term ID'));
+
+ $defaults = array( 'alias_of' => '', 'description' => '', 'parent' => 0, 'slug' => '');
+ $args = wp_parse_args($args, $defaults);
+ $args['name'] = $term;
+ $args['taxonomy'] = $taxonomy;
+ $args = sanitize_term($args, $taxonomy, 'db');
+ extract($args, EXTR_SKIP);
+
+ if ( empty($slug) )
+ $slug = sanitize_title($name);
+
+ $term_group = 0;
+ if ( $alias_of ) {
+ $alias = $wpdb->fetch_row("SELECT term_id, term_group FROM $wpdb->terms WHERE slug = '$alias_of'");
+ if ( $alias->term_group ) {
+ // The alias we want is already in a group, so let's use that one.
+ $term_group = $alias->term_group;
+ } else {
+ // The alias isn't in a group, so let's create a new one and firstly add the alias term to it.
+ $term_group = $wpdb->get_var("SELECT MAX(term_group) FROM $wpdb->terms GROUP BY term_group") + 1;
+ $wpdb->query("UPDATE $wpdb->terms SET term_group = $term_group WHERE term_id = $alias->term_id");
+ }
+ }
+
+ if ( ! $term_id = is_term($slug) ) {
+ $maxterm = $wpdb->get_var( "SELECT max(term_id) FROM {$wpdb->terms}" );
+ $term_id = mt_rand( $maxterm+100, $maxterm+4000 );
+ $wpdb->query("INSERT INTO $wpdb->terms (term_id, name, slug, term_group) VALUES ('$term_id', '$name', '$slug', '$term_group')");
+ } else if ( is_taxonomy_hierarchical($taxonomy) && !empty($parent) ) {
+ // If the taxonomy supports hierarchy and the term has a parent, make the slug unique
+ // by incorporating parent slugs.
+ $slug = wp_unique_term_slug($slug, (object) $args);
+ $maxterm = $wpdb->get_var( "SELECT max(term_id) FROM {$wpdb->terms}" );
+ $term_id = mt_rand( $maxterm+100, $maxterm+4000 );
+ $wpdb->query("INSERT INTO $wpdb->terms (term_id, name, slug, term_group) VALUES ('$term_id', '$name', '$slug', '$term_group')");
+ }
+
+ if ( empty($slug) ) {
+ $slug = sanitize_title($slug, $term_id);
+ $wpdb->query("UPDATE $wpdb->terms SET slug = '$slug' WHERE term_id = '$term_id'");
+ }
+
+ $tt_id = $wpdb->get_var("SELECT tt.term_taxonomy_id FROM $wpdb->term_taxonomy AS tt INNER JOIN $wpdb->terms AS t ON tt.term_id = t.term_id WHERE tt.taxonomy = '$taxonomy' AND t.term_id = $term_id");
+
+ if ( !empty($tt_id) ) {
+ $term_id = apply_filters('term_id_filter', $term_id, $tt_id);
+ return array('term_id' => $term_id, 'term_taxonomy_id' => $tt_id);
+ }
+
+ $wpdb->query("INSERT INTO $wpdb->term_taxonomy (term_id, taxonomy, description, parent, count) VALUES ('$term_id', '$taxonomy', '$description', '$parent', '0')");
+ $tt_id = (int) $wpdb->insert_id;
+
+ do_action("create_term", $term_id, $tt_id);
+ do_action("create_$taxonomy", $term_id, $tt_id);
+
+ clean_term_cache($term_id, $taxonomy);
+
+ $term_id = apply_filters('term_id_filter', $term_id, $tt_id);
+
+ clean_term_cache($term_id, $taxonomy); // Clean again if ID changed
+
+ do_action("created_term", $term_id, $tt_id);
+ do_action("created_$taxonomy", $term_id, $tt_id);
+
+ return array('term_id' => $term_id, 'term_taxonomy_id' => $tt_id);
+}
+
+/**
+ * wp_set_object_terms() -
+ *
+ * Relates an object (post, link etc) to a term and taxonomy type. Creates the term and taxonomy
+ * relationship if it doesn't already exist. Creates a term if it doesn't exist (using the slug).
+ *
+ * @global $wpdb Database Object
+ * @param int $object_id The object to relate to.
+ * @param array|int|string $term The slug or id of the term.
+ * @param array|string $taxonomy The context in which to relate the term to the object.
+ * @param bool $append If false will delete difference of terms.
+ */
+function wp_set_object_terms($object_id, $terms, $taxonomy, $append = false) {
+ global $wpdb;
+
+ $object_id = (int) $object_id;
+
+ if ( ! is_taxonomy($taxonomy) )
+ return new WP_Error('invalid_taxonomy', __('Invalid Taxonomy'));
+
+ if ( !is_array($terms) )
+ $terms = array($terms);
+
+ if ( ! $append )
+ $old_terms = wp_get_object_terms($object_id, $taxonomy, 'fields=tt_ids');
+
+ $tt_ids = array();
+ $term_ids = array();
+
+ foreach ($terms as $term) {
+ if ( !$id = is_term($term, $taxonomy) )
+ $id = wp_insert_term($term, $taxonomy);
+ $term_ids[] = $id['term_id'];
+ $id = $id['term_taxonomy_id'];
+ $tt_ids[] = $id;
+
+ if ( $wpdb->get_var("SELECT term_taxonomy_id FROM $wpdb->term_relationships WHERE object_id = '$object_id' AND term_taxonomy_id = '$id'") )
+ continue;
+ $wpdb->query("INSERT INTO $wpdb->term_relationships (object_id, term_taxonomy_id) VALUES ('$object_id', '$id')");
+ }
+
+ wp_update_term_count($tt_ids, $taxonomy);
+
+ if ( ! $append ) {
+ $delete_terms = array_diff($old_terms, $tt_ids);
+ if ( $delete_terms ) {
+ $in_delete_terms = "'" . implode("', '", $delete_terms) . "'";
+ $wpdb->query("DELETE FROM $wpdb->term_relationships WHERE object_id = '$object_id' AND term_taxonomy_id IN ($in_delete_terms)");
+ wp_update_term_count($delete_terms, $taxonomy);
+ }
+ }
+
+ return $tt_ids;
+}
+
+function wp_unique_term_slug($slug, $term) {
+ global $wpdb;
+
+ // If the taxonomy supports hierarchy and the term has a parent, make the slug unique
+ // by incorporating parent slugs.
+ if ( is_taxonomy_hierarchical($term->taxonomy) && !empty($term->parent) ) {
+ $the_parent = $term->parent;
+ while ( ! empty($the_parent) ) {
+ $parent_term = get_term($the_parent, $term->taxonomy);
+ if ( is_wp_error($parent_term) || empty($parent_term) )
+ break;
+ $slug .= '-' . $parent_term->slug;
+ if ( empty($parent_term->parent) )
+ break;
+ $the_parent = $parent_term->parent;
+ }
+ }
+
+ // If we didn't get a unique slug, try appending a number to make it unique.
+ if ( $wpdb->get_var("SELECT slug FROM $wpdb->terms WHERE slug = '$slug'") ) {
+ $num = 2;
+ do {
+ $alt_slug = $slug . "-$num";
+ $num++;
+ $slug_check = $wpdb->get_var("SELECT slug FROM $wpdb->terms WHERE slug = '$alt_slug'");
+ } while ( $slug_check );
+ $slug = $alt_slug;
+ }
+
+ return $slug;
+}
+
+function wp_update_term( $term, $taxonomy, $args = array() ) {
+ global $wpdb;
+
+ if ( ! is_taxonomy($taxonomy) )
+ return new WP_Error('invalid_taxonomy', __('Invalid taxonomy'));
+
+ $term_id = (int) $term;
+
+ // First, get all of the original args
+ $term = get_term ($term_id, $taxonomy, ARRAY_A);
+
+ // Escape data pulled from DB.
+ $term = add_magic_quotes($term);
+
+ // Merge old and new args with new args overwriting old ones.
+ $args = array_merge($term, $args);
+
+ $defaults = array( 'alias_of' => '', 'description' => '', 'parent' => 0, 'slug' => '');
+ $args = wp_parse_args($args, $defaults);
+ $args = sanitize_term($args, $taxonomy, 'db');
+ extract($args, EXTR_SKIP);
+
+ $empty_slug = false;
+ if ( empty($slug) ) {
+ $empty_slug = true;
+ $slug = sanitize_title($name);
+ }
+
+ if ( $alias_of ) {
+ $alias = $wpdb->fetch_row("SELECT term_id, term_group FROM $wpdb->terms WHERE slug = '$alias_of'");
+ if ( $alias->term_group ) {
+ // The alias we want is already in a group, so let's use that one.
+ $term_group = $alias->term_group;
+ } else {
+ // The alias isn't in a group, so let's create a new one and firstly add the alias term to it.
+ $term_group = $wpdb->get_var("SELECT MAX(term_group) FROM $wpdb->terms GROUP BY term_group") + 1;
+ $wpdb->query("UPDATE $wpdb->terms SET term_group = $term_group WHERE term_id = $alias->term_id");
+ }
+ }
+
+ // Check for duplicate slug
+ $id = $wpdb->get_var("SELECT term_id FROM $wpdb->terms WHERE slug = '$slug'");
+ if ( $id && ($id != $term_id) ) {
+ // If an empty slug was passed, reset the slug to something unique.
+ // Otherwise, bail.
+ if ( $empty_slug )
+ $slug = wp_unique_term_slug($slug, (object) $args);
+ else
+ return new WP_Error('duplicate_term_slug', sprintf(__('The slug "%s" is already in use by another term'), $slug));
+ }
+
+ $wpdb->query("UPDATE $wpdb->terms SET name = '$name', slug = '$slug', term_group = '$term_group' WHERE term_id = '$term_id'");
+
+ if ( empty($slug) ) {
+ $slug = sanitize_title($name, $term_id);
+ $wpdb->query("UPDATE $wpdb->terms SET slug = '$slug' WHERE term_id = '$term_id'");
+ }
+
+ $tt_id = $wpdb->get_var("SELECT tt.term_taxonomy_id FROM $wpdb->term_taxonomy AS tt INNER JOIN $wpdb->terms AS t ON tt.term_id = t.term_id WHERE tt.taxonomy = '$taxonomy' AND t.term_id = $term_id");
+
+ $wpdb->query("UPDATE $wpdb->term_taxonomy SET term_id = '$term_id', taxonomy = '$taxonomy', description = '$description', parent = '$parent' WHERE term_taxonomy_id = '$tt_id'");
+
+ do_action("edit_term", $term_id, $tt_id);
+ do_action("edit_$taxonomy", $term_id, $tt_id);
+
+ clean_term_cache($term_id, $taxonomy);
+
+ $term_id = apply_filters('term_id_filter', $term_id, $tt_id);
+
+ clean_term_cache($term_id, $taxonomy);
+
+ do_action("edited_term", $term_id, $tt_id);
+ do_action("edited_$taxonomy", $term_id, $tt_id);
+
+ return array('term_id' => $term_id, 'term_taxonomy_id' => $tt_id);
+}
+
+function wp_update_term_count( $terms, $taxonomy ) {
+ global $wpdb;
+
+ if ( empty($terms) )
+ return false;
+
+ if ( !is_array($terms) )
+ $terms = array($terms);
+
+ $terms = array_map('intval', $terms);
+
+ $taxonomy = get_taxonomy($taxonomy);
+ if ( !empty($taxonomy->update_count_callback) ) {
+ call_user_func($taxonomy->update_count_callback, $terms);
+ } else {
+ // Default count updater
+ foreach ($terms as $term) {
+ $count = $wpdb->get_var("SELECT COUNT(*) FROM $wpdb->term_relationships WHERE term_taxonomy_id = '$term'");
+ $wpdb->query("UPDATE $wpdb->term_taxonomy SET count = '$count' WHERE term_taxonomy_id = '$term'");
+ }
+
+ }
+
+ clean_term_cache($terms);
+
+ return true;
+}
+
+//
+// Cache
+//
+
+function clean_object_term_cache($object_ids, $object_type) {
+ global $object_term_cache, $blog_id;
+
+ if ( !is_array($object_ids) )
+ $object_ids = array($object_ids);
+
+ $taxonomies = get_object_taxonomies($object_type);
+
+ foreach ( $object_ids as $id ) {
+ foreach ( $taxonomies as $taxonomy ) {
+ if ( isset($object_term_cache[$blog_id][$id][$taxonomy]) )
+ unset($object_term_cache[$blog_id][$id][$taxonomy]);
+ }
+ }
+
+ do_action('clean_object_term_cache', $object_ids, $object_type);
+}
+
+function clean_term_cache($ids, $taxonomy = '') {
+ global $wpdb;
+
+ if ( !is_array($ids) )
+ $ids = array($ids);
+
+ $taxonomies = array();
+ // If no taxonomy, assume tt_ids.
+ if ( empty($taxonomy) ) {
+ $tt_ids = implode(', ', $ids);
+ $terms = $wpdb->get_results("SELECT term_id, taxonomy FROM $wpdb->term_taxonomy WHERE term_taxonomy_id IN ($tt_ids)");
+ foreach ( (array) $terms as $term ) {
+ $taxonomies[] = $term->taxonomy;
+ wp_cache_delete($term->term_id, $term->taxonomy);
+ }
+ $taxonomies = array_unique($taxonomies);
+ } else {
+ foreach ( $ids as $id ) {
+ wp_cache_delete($id, $taxonomy);
+ }
+ $taxonomies = array($taxonomy);
+ }
+
+ foreach ( $taxonomies as $taxonomy ) {
+ wp_cache_delete('all_ids', $taxonomy);
+ wp_cache_delete("all_{$taxonomy}_ids", $taxonomy);
+ wp_cache_delete('get', $taxonomy);
+ delete_option("{$taxonomy}_children");
+ }
+
+ wp_cache_delete('get_terms', 'terms');
+
+ do_action('clean_term_cache', $ids, $taxonomy);
+}
+
+function &get_object_term_cache($id, $taxonomy) {
+ global $object_term_cache, $blog_id;
+
+ if ( isset($object_term_cache[$blog_id][$id][$taxonomy]) )
+ return $object_term_cache[$blog_id][$id][$taxonomy];
+
+ if ( isset($object_term_cache[$blog_id][$id]) )
+ return array();
+
+ return false;
+}
+
+function update_object_term_cache($object_ids, $object_type) {
+ global $wpdb, $object_term_cache, $blog_id;
+
+ if ( empty($object_ids) )
+ return;
+
+ if ( !is_array($object_ids) )
+ $object_ids = explode(',', $object_ids);
+
+ $count = count( $object_ids);
+ for ( $i = 0; $i < $count; $i++ ) {
+ $object_id = (int) $object_ids[ $i ];
+ if ( isset( $object_term_cache[$blog_id][$object_id] ) ) {
+ unset( $object_ids[ $i ] );
+ continue;
+ }
+ }
+
+ if ( count( $object_ids ) == 0 )
+ return;
+
+ $terms = wp_get_object_terms($object_ids, get_object_taxonomies($object_type), 'fields=all_with_object_id');
+
+ if ( empty($terms) )
+ return;
+
+ foreach ( $terms as $term )
+ $object_term_cache[$blog_id][$term->object_id][$term->taxonomy][$term->term_id] = $term;
+
+ foreach ( $object_ids as $id ) {
+ if ( ! isset($object_term_cache[$blog_id][$id]) )
+ $object_term_cache[$blog_id][$id] = array();
+ }
+}
+
+function update_term_cache($terms, $taxonomy = '') {
+ foreach ( $terms as $term ) {
+ $term_taxonomy = $taxonomy;
+ if ( empty($term_taxonomy) )
+ $term_taxonomy = $term->taxonomy;
+
+ wp_cache_add($term->term_id, $term, $term_taxonomy);
+ }
+}
+
+//
+// Private
+//
+
+function _get_term_hierarchy($taxonomy) {
+ if ( !is_taxonomy_hierarchical($taxonomy) )
+ return array();
+ $children = get_option("{$taxonomy}_children");
+ if ( is_array($children) )
+ return $children;
+
+ $children = array();
+ $terms = get_terms($taxonomy, 'get=all');
+ foreach ( $terms as $term ) {
+ if ( $term->parent > 0 )
+ $children[$term->parent][] = $term->term_id;
+ }
+ update_option("{$taxonomy}_children", $children);
+
+ return $children;
+}
+
+function &_get_term_children($term_id, $terms, $taxonomy) {
+ if ( empty($terms) )
+ return array();
+
+ $term_list = array();
+ $has_children = _get_term_hierarchy($taxonomy);
+
+ if ( ( 0 != $term_id ) && ! isset($has_children[$term_id]) )
+ return array();
+
+ foreach ( $terms as $term ) {
+ $use_id = false;
+ if ( !is_object($term) ) {
+ $term = get_term($term, $taxonomy);
+ if ( is_wp_error( $term ) )
+ return $term;
+ $use_id = true;
+ }
+
+ if ( $term->term_id == $term_id )
+ continue;
+
+ if ( $term->parent == $term_id ) {
+ if ( $use_id )
+ $term_list[] = $term->term_id;
+ else
+ $term_list[] = $term;
+
+ if ( !isset($has_children[$term->term_id]) )
+ continue;
+
+ if ( $children = _get_term_children($term->term_id, $terms, $taxonomy) )
+ $term_list = array_merge($term_list, $children);
+ }
+ }
+
+ return $term_list;
+}
+
+// Recalculates term counts by including items from child terms
+// Assumes all relevant children are already in the $terms argument
+function _pad_term_counts(&$terms, $taxonomy) {
+ global $wpdb;
+
+ // This function only works for post categories.
+ if ( 'category' != $taxonomy )
+ return;
+
+ $term_hier = _get_term_hierarchy($taxonomy);
+
+ if ( empty($term_hier) )
+ return;
+
+ $term_items = array();
+
+ foreach ( $terms as $key => $term ) {
+ $terms_by_id[$term->term_id] = & $terms[$key];
+ $term_ids[$term->term_taxonomy_id] = $term->term_id;
+ }
+
+ // Get the object and term ids and stick them in a lookup table
+ $results = $wpdb->get_results("SELECT object_id, term_taxonomy_id FROM $wpdb->term_relationships INNER JOIN $wpdb->posts ON object_id = ID WHERE term_taxonomy_id IN (".join(',', array_keys($term_ids)).") AND post_type = 'post' AND post_status = 'publish'");
+ foreach ( $results as $row ) {
+ $id = $term_ids[$row->term_taxonomy_id];
+ ++$term_items[$id][$row->object_id];
+ }
+
+ // Touch every ancestor's lookup row for each post in each term
+ foreach ( $term_ids as $term_id ) {
+ $child = $term_id;
+ while ( $parent = $terms_by_id[$child]->parent ) {
+ if ( !empty($term_items[$term_id]) )
+ foreach ( $term_items[$term_id] as $item_id => $touches )
+ ++$term_items[$parent][$item_id];
+ $child = $parent;
+ }
+ }
+
+ // Transfer the touched cells
+ foreach ( (array) $term_items as $id => $items )
+ if ( isset($terms_by_id[$id]) )
+ $terms_by_id[$id]->count = count($items);
+}
+
+//
+// Default callbacks
+//
+
+function _update_post_term_count( $terms ) {
+ global $wpdb;
+
+ foreach ( $terms as $term ) {
+ $count = $wpdb->get_var("SELECT COUNT(*) FROM $wpdb->term_relationships, $wpdb->posts WHERE $wpdb->posts.ID = $wpdb->term_relationships.object_id AND post_status = 'publish' AND post_type = 'post' AND term_taxonomy_id = '$term'");
+ $wpdb->query("UPDATE $wpdb->term_taxonomy SET count = '$count' WHERE term_taxonomy_id = '$term'");
+ }
+}
+
+?>
diff --git a/wp-includes/template-loader.php b/wp-includes/template-loader.php
index 7b654b8..cc218e7 100644
--- a/wp-includes/template-loader.php
+++ b/wp-includes/template-loader.php
@@ -8,7 +8,7 @@ if ( defined('WP_USE_THEMES') && constant('WP_USE_THEMES') ) {
do_feed();
return;
} else if ( is_trackback() ) {
- include(ABSPATH . '/wp-trackback.php');
+ include(ABSPATH . 'wp-trackback.php');
return;
} else if ( is_404() && $template = get_404_template() ) {
include($template);
@@ -35,6 +35,9 @@ if ( defined('WP_USE_THEMES') && constant('WP_USE_THEMES') ) {
} else if ( is_category() && $template = get_category_template()) {
include($template);
return;
+ } else if ( is_tag() && $template = get_tag_template()) {
+ include($template);
+ return;
} else if ( is_author() && $template = get_author_template() ) {
include($template);
return;
@@ -65,7 +68,7 @@ if ( defined('WP_USE_THEMES') && constant('WP_USE_THEMES') ) {
do_feed();
return;
} else if ( is_trackback() ) {
- include(ABSPATH . '/wp-trackback.php');
+ include(ABSPATH . 'wp-trackback.php');
return;
}
}
diff --git a/wp-includes/theme.php b/wp-includes/theme.php
index f20ae68..3362c1d 100644
--- a/wp-includes/theme.php
+++ b/wp-includes/theme.php
@@ -56,35 +56,51 @@ function get_template_directory_uri() {
}
function get_theme_data( $theme_file ) {
+ $themes_allowed_tags = array(
+ 'a' => array(
+ 'href' => array(),'title' => array()
+ ),
+ 'abbr' => array(
+ 'title' => array()
+ ),
+ 'acronym' => array(
+ 'title' => array()
+ ),
+ 'code' => array(),
+ 'em' => array(),
+ 'strong' => array()
+ );
+
$theme_data = implode( '', file( $theme_file ) );
- $theme_data = str_replace ( '\r', '\n', $theme_data );
- preg_match( '|Theme Name:(.*)|i', $theme_data, $theme_name );
- preg_match( '|Theme URI:(.*)|i', $theme_data, $theme_uri );
- preg_match( '|Description:(.*)|i', $theme_data, $description );
- preg_match( '|Author:(.*)|i', $theme_data, $author_name );
- preg_match( '|Author URI:(.*)|i', $theme_data, $author_uri );
- preg_match( '|Template:(.*)|i', $theme_data, $template );
+ $theme_data = str_replace ( '\r', '\n', $theme_data );
+ preg_match( '|Theme Name:(.*)$|mi', $theme_data, $theme_name );
+ preg_match( '|Theme URI:(.*)$|mi', $theme_data, $theme_uri );
+ preg_match( '|Description:(.*)$|mi', $theme_data, $description );
+ preg_match( '|Author:(.*)$|mi', $theme_data, $author_name );
+ preg_match( '|Author URI:(.*)$|mi', $theme_data, $author_uri );
+ preg_match( '|Template:(.*)$|mi', $theme_data, $template );
+
if ( preg_match( '|Version:(.*)|i', $theme_data, $version ) )
- $version = trim( $version[1] );
+ $version = wp_kses( trim( $version[1] ), $themes_allowed_tags );
else
- $version ='';
+ $version = '';
+
if ( preg_match('|Status:(.*)|i', $theme_data, $status) )
- $status = trim($status[1]);
+ $status = wp_kses( trim( $status[1] ), $themes_allowed_tags );
else
$status = 'publish';
- $description = wptexturize( trim( $description[1] ) );
+ $name = $theme = wp_kses( trim( $theme_name[1] ), $themes_allowed_tags );
+ $theme_uri = clean_url( trim( $theme_uri[1] ) );
+ $description = wptexturize( wp_kses( trim( $description[1] ), $themes_allowed_tags ) );
+ $template = wp_kses( trim( $template[1] ), $themes_allowed_tags );
- $name = $theme_name[1];
- $name = trim( $name );
- $theme = $name;
- $theme_uri = trim( $theme_uri[1] );
- $template = trim( $template[1] );
+ $author_uri = clean_url( trim( $author_uri[1] ) );
- if ( '' == $author_uri[1] ) {
- $author = trim( $author_name[1] );
+ if ( empty( $author_uri[1] ) ) {
+ $author = wp_kses( trim( $author_name[1] ), $themes_allowed_tags );
} else {
- $author = '' . trim( $author_name[1] ) . ' ';
+ $author = sprintf( '%3$s ', $author_uri, __( 'Visit author homepage' ), wp_kses( trim( $author_name[1] ), $themes_allowed_tags ) );
}
return array( 'Name' => $name, 'Title' => $theme, 'URI' => $theme_uri, 'Description' => $description, 'Author' => $author, 'Version' => $version, 'Template' => $template, 'Status' => $status );
@@ -98,50 +114,55 @@ function get_themes() {
$themes = array();
$wp_broken_themes = array();
- $theme_root = get_theme_root();
- $theme_loc = str_replace(ABSPATH, '', $theme_root);
+ $theme_loc = $theme_root = get_theme_root();
+ if ( '/' != ABSPATH ) // don't want to replace all forward slashes, see Trac #4541
+ $theme_loc = str_replace(ABSPATH, '', $theme_root);
// Files in wp-content/themes directory and one subdir down
- $themes_dir = @ dir($theme_root);
+ $themes_dir = @ opendir($theme_root);
if ( !$themes_dir )
return false;
- while ( ($theme_dir = $themes_dir->read()) !== false ) {
+ while ( ($theme_dir = readdir($themes_dir)) !== false ) {
if ( is_dir($theme_root . '/' . $theme_dir) && is_readable($theme_root . '/' . $theme_dir) ) {
if ( $theme_dir{0} == '.' || $theme_dir == '..' || $theme_dir == 'CVS' )
continue;
- $stylish_dir = @ dir($theme_root . '/' . $theme_dir);
+ $stylish_dir = @ opendir($theme_root . '/' . $theme_dir);
$found_stylesheet = false;
- while ( ($theme_file = $stylish_dir->read()) !== false ) {
+ while ( ($theme_file = readdir($stylish_dir)) !== false ) {
if ( $theme_file == 'style.css' ) {
$theme_files[] = $theme_dir . '/' . $theme_file;
$found_stylesheet = true;
break;
}
}
+ @closedir($stylish_dir);
if ( !$found_stylesheet ) { // look for themes in that dir
$subdir = "$theme_root/$theme_dir";
$subdir_name = $theme_dir;
- $theme_subdir = @dir( $subdir );
- while ( ($theme_dir = $theme_subdir->read()) !== false ) {
+ $theme_subdir = @ opendir( $subdir );
+ while ( ($theme_dir = readdir($theme_subdir)) !== false ) {
if ( is_dir( $subdir . '/' . $theme_dir) && is_readable($subdir . '/' . $theme_dir) ) {
if ( $theme_dir{0} == '.' || $theme_dir == '..' || $theme_dir == 'CVS' )
continue;
- $stylish_dir = @ dir($subdir . '/' . $theme_dir);
+ $stylish_dir = @ opendir($subdir . '/' . $theme_dir);
$found_stylesheet = false;
- while ( ($theme_file = $stylish_dir->read()) !== false ) {
+ while ( ($theme_file = readdir($stylish_dir)) !== false ) {
if ( $theme_file == 'style.css' ) {
$theme_files[] = $subdir_name . '/' . $theme_dir . '/' . $theme_file;
$found_stylesheet = true;
break;
}
}
+ @closedir($stylish_dir);
}
}
+ @closedir($theme_subdir);
$wp_broken_themes[$theme_dir] = array('Name' => $theme_dir, 'Title' => $theme_dir, 'Description' => __('Stylesheet is missing.'));
}
}
}
+ @closedir($theme_dir);
if ( !$themes_dir || !$theme_files )
return $themes;
@@ -189,7 +210,7 @@ function get_themes() {
if ( !file_exists("$theme_root/$template/index.php") ) {
$parent_dir = dirname(dirname($theme_file));
if ( file_exists("$theme_root/$parent_dir/$template/index.php") ) {
- $template = "$parent_dir/$template";
+ $template = "$parent_dir/$template";
} else {
$wp_broken_themes[$name] = array('Name' => $name, 'Title' => $title, 'Description' => __('Template is missing.'));
continue;
@@ -330,6 +351,17 @@ function get_category_template() {
return apply_filters('category_template', $template);
}
+function get_tag_template() {
+ $template = '';
+ if ( file_exists(TEMPLATEPATH . "/tag-" . get_query_var('tag') . '.php') )
+ $template = TEMPLATEPATH . "/tag-" . get_query_var('tag') . '.php';
+ elseif ( file_exists(TEMPLATEPATH . "/tag.php") )
+ $template = TEMPLATEPATH . "/tag.php";
+
+ return apply_filters('tag_template', $template);
+}
+
+
function get_date_template() {
return get_query_template('date');
}
@@ -400,7 +432,7 @@ function get_comments_popup_template() {
function load_template($_template_file) {
global $posts, $post, $wp_did_header, $wp_did_template_redirect, $wp_query,
- $wp_rewrite, $wpdb, $wp_version, $wp, $id, $comment;
+ $wp_rewrite, $wpdb, $wp_version, $wp, $id, $comment, $user_ID;
if ( is_array($wp_query->query_vars) )
extract($wp_query->query_vars, EXTR_SKIP);
diff --git a/wp-includes/update.php b/wp-includes/update.php
new file mode 100644
index 0000000..657c667
--- /dev/null
+++ b/wp-includes/update.php
@@ -0,0 +1,54 @@
+last_checked ) &&
+ 43200 > ( time() - $current->last_checked ) &&
+ $current->version_checked == $wp_version
+ )
+ return false;
+
+ $new_option = '';
+ $new_option->last_checked = time(); // this gets set whether we get a response or not, so if something is down or misconfigured it won't delay the page load for more than 3 seconds, twice a day
+ $new_option->version_checked = $wp_version;
+
+ $http_request = "GET /core/version-check/1.0/?version=$wp_version&php=$php_version&locale=$locale HTTP/1.0\r\n";
+ $http_request .= "Host: api.wordpress.org\r\n";
+ $http_request .= 'Content-Type: application/x-www-form-urlencoded; charset=' . get_option('blog_charset') . "\r\n";
+ $http_request .= 'User-Agent: WordPress/' . $wp_version . '; ' . get_bloginfo('url') . "\r\n";
+ $http_request .= "\r\n";
+
+ $response = '';
+ if ( false !== ( $fs = @fsockopen( 'api.wordpress.org', 80, $errno, $errstr, 3 ) ) && is_resource($fs) ) {
+ fwrite( $fs, $http_request );
+ while ( !feof( $fs ) )
+ $response .= fgets( $fs, 1160 ); // One TCP-IP packet
+ fclose( $fs );
+
+ $response = explode("\r\n\r\n", $response, 2);
+ $body = trim( $response[1] );
+ $body = str_replace(array("\r\n", "\r"), "\n", $body);
+
+ $returns = explode("\n", $body);
+
+ $new_option->response = $returns[0];
+ if ( isset( $returns[1] ) )
+ $new_option->url = $returns[1];
+ }
+ update_option( 'update_core', $new_option );
+}
+
+add_action( 'init', 'wp_version_check' );
+*/
+?>
diff --git a/wp-includes/user.php b/wp-includes/user.php
index f243fcc..1990a39 100644
--- a/wp-includes/user.php
+++ b/wp-includes/user.php
@@ -91,6 +91,9 @@ function get_usermeta( $user_id, $meta_key = '') {
global $wpdb;
$user_id = (int) $user_id;
+ if ( !$user_id )
+ return false;
+
if ( !empty($meta_key) ) {
$meta_key = preg_replace('|[^a-z0-9_]|i', '', $meta_key);
$metas = $wpdb->get_results("SELECT meta_key, meta_value FROM $wpdb->usermeta WHERE user_id = '$user_id' AND meta_key = '$meta_key'");
@@ -105,13 +108,8 @@ function get_usermeta( $user_id, $meta_key = '') {
return '';
}
- foreach ($metas as $index => $meta) {
- @ $value = unserialize($meta->meta_value);
- if ( $value === FALSE )
- $value = $meta->meta_value;
-
- $values[] = $value;
- }
+ foreach ($metas as $meta)
+ $values[] = maybe_unserialize($meta->meta_value);
if ( count($values) == 1 )
return $values[0];
@@ -179,4 +177,69 @@ function setup_userdata($user_id = '') {
$user_identity = $user->display_name;
}
+function wp_dropdown_users( $args = '' ) {
+ global $wpdb;
+ $defaults = array(
+ 'show_option_all' => '', 'show_option_none' => '',
+ 'orderby' => 'display_name', 'order' => 'ASC',
+ 'include' => '', 'exclude' => '',
+ 'show' => 'display_name', 'echo' => 1,
+ 'selected' => 0, 'name' => 'user', 'class' => ''
+ );
+
+ $defaults['selected'] = is_author() ? get_query_var( 'author' ) : 0;
+
+ $r = wp_parse_args( $args, $defaults );
+ extract( $r, EXTR_SKIP );
+
+ $query = "SELECT * FROM $wpdb->users";
+
+ $query_where = array();
+
+ if ( is_array($include) )
+ $include = join(',', $include);
+ $include = preg_replace('/[^0-9,]/', '', $include); // (int)
+ if ( $include )
+ $query_where[] = "ID IN ($include)";
+
+ if ( is_array($exclude) )
+ $exclude = join(',', $exclude);
+ $exclude = preg_replace('/[^0-9,]/', '', $exclude); // (int)
+ if ( $exclude )
+ $query_where[] = "ID NOT IN ($exclude)";
+
+ if ( $query_where )
+ $query .= " WHERE " . join(' AND', $query_where);
+
+ $query .= " ORDER BY $orderby $order";
+
+ $users = $wpdb->get_results( $query );
+
+ $output = '';
+ if ( !empty($users) ) {
+ $output = "\n";
+
+ if ( $show_option_all )
+ $output .= "\t$show_option_all \n";
+
+ if ( $show_option_none )
+ $output .= "\t$show_option_none \n";
+
+ foreach ( $users as $user ) {
+ $user->ID = (int) $user->ID;
+ $_selected = $user->ID == $selected ? " selected='selected'" : '';
+ $output .= "\t" . wp_specialchars($user->$show) . " \n";
+ }
+
+ $output .= " ";
+ }
+
+ $output = apply_filters('wp_dropdown_users', $output);
+
+ if ( $echo )
+ echo $output;
+
+ return $output;
+}
+
?>
diff --git a/wp-includes/version.php b/wp-includes/version.php
index 13c05a4..1a3d531 100644
--- a/wp-includes/version.php
+++ b/wp-includes/version.php
@@ -2,8 +2,8 @@
// This holds the version number in a separate file so we can bump it without cluttering the SVN
-$wp_version = 'wordpress-mu-1.2.5';
-$wporg_version = 'wordpress-2.2.3';
-$wp_db_version = 5200;
+$wp_version = 'wordpress-mu-1.3rc1';
+$wporg_version = 'wordpress-2.3';
+$wp_db_version = 6124;
?>
diff --git a/wp-includes/widgets.php b/wp-includes/widgets.php
index b2ec69e..7bd6fbd 100644
--- a/wp-includes/widgets.php
+++ b/wp-includes/widgets.php
@@ -59,7 +59,7 @@ function register_sidebar($args = array()) {
function unregister_sidebar( $name ) {
global $wp_registered_sidebars;
-
+
if ( isset( $wp_registered_sidebars[$name] ) )
unset( $wp_registered_sidebars[$name] );
}
@@ -210,7 +210,15 @@ function dynamic_sidebar($index = 1) {
$params = array_merge(array($sidebar), (array) $wp_registered_widgets[$id]['params']);
// Substitute HTML id and class attributes into before_widget
- $params[0]['before_widget'] = sprintf($params[0]['before_widget'], $id, $wp_registered_widgets[$id]['classname']);
+ $classname_ = '';
+ foreach ( (array) $wp_registered_widgets[$id]['classname'] as $cn ) {
+ if ( is_string($cn) )
+ $classname_ .= '_' . $cn;
+ elseif ( is_object($cn) )
+ $classname_ .= '_' . get_class($cn);
+ }
+ $classname_ = ltrim($classname_, '_');
+ $params[0]['before_widget'] = sprintf($params[0]['before_widget'], $id, $classname_);
if ( is_callable($callback) ) {
call_user_func_array($callback, $params);
@@ -329,17 +337,17 @@ function wp_get_widget_defaults() {
function wp_widget_pages( $args ) {
extract( $args );
$options = get_option( 'widget_pages' );
-
+
$title = empty( $options['title'] ) ? __( 'Pages' ) : $options['title'];
$sortby = empty( $options['sortby'] ) ? 'menu_order' : $options['sortby'];
$exclude = empty( $options['exclude'] ) ? '' : $options['exclude'];
-
+
if ( $sortby == 'menu_order' ) {
$sortby = 'menu_order, post_title';
}
-
+
$out = wp_list_pages( array('title_li' => '', 'echo' => 0, 'sort_column' => $sortby, 'exclude' => $exclude) );
-
+
if ( !empty( $out ) ) {
?>
@@ -356,15 +364,15 @@ function wp_widget_pages_control() {
$options = $newoptions = get_option('widget_pages');
if ( $_POST['pages-submit'] ) {
$newoptions['title'] = strip_tags(stripslashes($_POST['pages-title']));
-
+
$sortby = stripslashes( $_POST['pages-sortby'] );
-
+
if ( in_array( $sortby, array( 'post_title', 'menu_order', 'ID' ) ) ) {
$newoptions['sortby'] = $sortby;
} else {
$newoptions['sortby'] = 'menu_order';
}
-
+
$newoptions['exclude'] = strip_tags( stripslashes( $_POST['pages-exclude'] ) );
}
if ( $options != $newoptions ) {
@@ -375,7 +383,7 @@ function wp_widget_pages_control() {
$exclude = attribute_escape( $options['exclude'] );
?>
-
+
>
>
@@ -388,18 +396,12 @@ function wp_widget_pages_control() {
}
function wp_widget_links($args) {
- global $wp_db_version;
extract($args, EXTR_SKIP);
- if ( $wp_db_version < 3582 ) {
- // This ONLY works with li/h2 sidebars.
- get_links_list();
- } else {
- wp_list_bookmarks(array(
- 'title_before' => $before_title, 'title_after' => $after_title,
- 'category_before' => $before_widget, 'category_after' => $after_widget,
- 'show_images' => true, 'class' => 'linkcat widget'
- ));
- }
+ wp_list_bookmarks(array(
+ 'title_before' => $before_title, 'title_after' => $after_title,
+ 'category_before' => $before_widget, 'category_after' => $after_widget,
+ 'show_images' => true, 'class' => 'linkcat widget'
+ ));
}
function wp_widget_search($args) {
@@ -423,14 +425,14 @@ function wp_widget_archives($args) {
$d = $options['dropdown'] ? '1' : '0';
$title = empty($options['title']) ? __('Archives') : $options['title'];
- echo $before_widget;
+ echo $before_widget;
echo $before_title . $title . $after_title;
- if($d) {
+ if($d) {
?>
-
-
+
@@ -438,7 +440,7 @@ function wp_widget_archives($args) {
@@ -648,31 +652,157 @@ function wp_widget_categories($args) {
echo $after_widget;
}
-function wp_widget_categories_control() {
+function wp_widget_categories_control( $number ) {
$options = $newoptions = get_option('widget_categories');
- if ( $_POST['categories-submit'] ) {
- $newoptions['count'] = isset($_POST['categories-count']);
- $newoptions['hierarchical'] = isset($_POST['categories-hierarchical']);
- $newoptions['dropdown'] = isset($_POST['categories-dropdown']);
- $newoptions['title'] = strip_tags(stripslashes($_POST['categories-title']));
+
+ if ( !is_array( $options ) ) {
+ $options = $newoptions = get_option( 'widget_categories' );
+ }
+
+ if ( $_POST['categories-submit-' . $number] ) {
+ $newoptions[$number]['count'] = isset($_POST['categories-count-' . $number]);
+ $newoptions[$number]['hierarchical'] = isset($_POST['categories-hierarchical-' . $number]);
+ $newoptions[$number]['dropdown'] = isset($_POST['categories-dropdown-' . $number]);
+ $newoptions[$number]['title'] = strip_tags(stripslashes($_POST['categories-title-' . $number]));
}
+
if ( $options != $newoptions ) {
$options = $newoptions;
update_option('widget_categories', $options);
}
- $count = $options['count'] ? 'checked="checked"' : '';
- $hierarchical = $options['hierarchical'] ? 'checked="checked"' : '';
- $dropdown = $options['dropdown'] ? 'checked="checked"' : '';
- $title = attribute_escape($options['title']);
+
+ $title = attribute_escape( $options[$number]['title'] );
+?>
+
+
+
+
+
+ />
+
+
+
+ />
+
+
+
+ />
+
+
+
+ 9 ) {
+ $number = 9;
+ } elseif ( $number < 1 ) {
+ $number = 1;
+ }
+
+ $newoptions['number'] = $number;
+ }
+
+ if ( $newoptions != $options ) {
+ $options = $newoptions;
+ update_option( 'widget_categories', $options );
+ wp_widget_categories_register( $options['number'] );
+ }
+}
+
+function wp_widget_categories_page() {
+ $options = get_option( 'widget_categories' );
?>
-
- id="categories-count" name="categories-count" />
- id="categories-hierarchical" name="categories-hierarchical" />
- id="categories-dropdown" name="categories-dropdown" />
-
+
1, 1 => $options );
+
+ update_option( 'widget_categories', $newoptions );
+
+ $sidebars_widgets = get_option( 'sidebars_widgets' );
+ if ( is_array( $sidebars_widgets ) ) {
+ foreach ( $sidebars_widgets as $sidebar => $widgets ) {
+ if ( is_array( $widgets ) ) {
+ foreach ( $widgets as $widget )
+ $new_widgets[$sidebar][] = ( $widget == 'categories' ) ? 'categories-1' : $widget;
+ } else {
+ $new_widgets[$sidebar] = $widgets;
+ }
+ }
+ if ( $new_widgets != $sidebars_widgets )
+ update_option( 'sidebars_widgets', $new_widgets );
+ }
+
+ if ( isset( $_POST['categories-submit'] ) ) {
+ $_POST['categories-submit-1'] = $_POST['categories-submit'];
+ $_POST['categories-count-1'] = $_POST['categories-count'];
+ $_POST['categories-hierarchical-1'] = $_POST['categories-hierarchical'];
+ $_POST['categories-dropdown-1'] = $_POST['categories-dropdown'];
+ $_POST['categories-title-1'] = $_POST['categories-title'];
+ foreach ( $_POST as $k => $v )
+ if ( substr($k, -5) == 'order' )
+ $_POST[$k] = str_replace('categories', 'categories-1', $v);
+ }
+
+ return $newoptions;
+}
+
+function wp_widget_categories_register() {
+ $options = get_option( 'widget_categories' );
+ if ( !isset($options['number']) )
+ $options = wp_widget_categories_upgrade();
+ $number = (int) $options['number'];
+
+ if ( $number > 9 ) {
+ $number = 9;
+ } elseif ( $number < 1 ) {
+ $number = 1;
+ }
+
+ $dims = array( 'width' => 350, 'height' => 170 );
+ $class = array( 'classname' => 'widget_catgories' );
+
+ for ( $i = 1; $i <= 9; $i++ ) {
+ $name = sprintf( __( 'Categories %d' ), $i );
+ $id = 'categories-' . $i;
+
+ $widget_callback = ( $i <= $number ) ? 'wp_widget_categories' : '';
+ $control_callback = ( $i <= $number ) ? 'wp_widget_categories_control' : '';
+
+ wp_register_sidebar_widget( $id, $name, $widget_callback, $class, $i );
+ wp_register_widget_control( $id, $name, $control_callback, $dims, $i );
+ }
+
+ add_action( 'sidebar_admin_setup', 'wp_widget_categories_setup' );
+ add_action( 'sidebar_admin_page', 'wp_widget_categories_page' );
+}
+
function wp_widget_recent_entries($args) {
if ( $output = wp_cache_get('widget_recent_entries') )
return print($output);
@@ -688,7 +818,7 @@ function wp_widget_recent_entries($args) {
else if ( $number > 15 )
$number = 15;
- $r = new WP_Query("showposts=$number&what_to_show=posts&nopaging=0");
+ $r = new WP_Query("showposts=$number&what_to_show=posts&nopaging=0&post_status=publish");
if ($r->have_posts()) :
?>
@@ -709,7 +839,7 @@ function wp_flush_widget_recent_entries() {
}
add_action('save_post', 'wp_flush_widget_recent_entries');
-add_action('post_deleted', 'wp_flush_widget_recent_entries');
+add_action('deleted_post', 'wp_flush_widget_recent_entries');
function wp_widget_recent_entries_control() {
$options = $newoptions = get_option('widget_recent_entries');
@@ -798,14 +928,14 @@ function wp_widget_recent_comments_register() {
$class = array('classname' => 'widget_recent_comments');
wp_register_sidebar_widget('recent-comments', __('Recent Comments'), 'wp_widget_recent_comments', $class);
wp_register_widget_control('recent-comments', __('Recent Comments'), 'wp_widget_recent_comments_control', $dims);
-
+
if ( is_active_widget('wp_widget_recent_comments') )
add_action('wp_head', 'wp_widget_recent_comments_style');
}
function wp_widget_rss($args, $number = 1) {
require_once(ABSPATH . WPINC . '/rss.php');
- extract($args, EXTR_SKIP);
+ extract($args);
$options = get_option('widget_rss');
if ( isset($options['error']) && $options['error'] )
return;
@@ -838,10 +968,10 @@ function wp_widget_rss($args, $number = 1) {
?>
-
items ) ) {
+ if ( is_array( $rss->items ) && !empty( $rss->items ) ) {
$rss->items = array_slice($rss->items, 0, $num_items);
+ echo '';
foreach ($rss->items as $item ) {
while ( strstr($item['link'], 'http') != $item['link'] )
$item['link'] = substr($item['link'], 1);
@@ -859,13 +989,12 @@ function wp_widget_rss($args, $number = 1) {
}
echo "$summary ";
}
+ echo ' ';
} else {
- echo '' . __( 'An error has occurred; the feed is probably down. Try again later.' ) . ' ';
+ echo '' . __( 'An error has occurred; the feed is probably down. Try again later.' ) . ' ';
}
-?>
-
-
-
+
+
+
+
+ 90, 'width' => 300 );
+ $dims100 = array( 'height' => 100, 'width' => 300 );
+ $dims150 = array( 'height' => 150, 'width' => 300 );
- $wp_register_widget_defaults = true;
- $dims90 = array('height' => 90, 'width' => 300);
- $dims100 = array('height' => 100, 'width' => 300);
- $dims150 = array('height' => 150, 'width' => 300);
$class = array('classname' => 'widget_pages');
wp_register_sidebar_widget('pages', __('Pages'), 'wp_widget_pages', $class);
wp_register_widget_control('pages', __('Pages'), 'wp_widget_pages_control', $dims150);
+
$class['classname'] = 'widget_calendar';
wp_register_sidebar_widget('calendar', __('Calendar'), 'wp_widget_calendar', $class);
wp_register_widget_control('calendar', __('Calendar'), 'wp_widget_calendar_control', $dims90);
+
$class['classname'] = 'widget_archives';
wp_register_sidebar_widget('archives', __('Archives'), 'wp_widget_archives', $class);
wp_register_widget_control('archives', __('Archives'), 'wp_widget_archives_control', $dims100);
+
$class['classname'] = 'widget_links';
wp_register_sidebar_widget('links', __('Links'), 'wp_widget_links', $class);
+
$class['classname'] = 'widget_meta';
wp_register_sidebar_widget('meta', __('Meta'), 'wp_widget_meta', $class);
wp_register_widget_control('meta', __('Meta'), 'wp_widget_meta_control', $dims90);
+
$class['classname'] = 'widget_search';
wp_register_sidebar_widget('search', __('Search'), 'wp_widget_search', $class);
- $class['classname'] = 'widget_categories';
- wp_register_sidebar_widget('categories', __('Categories'), 'wp_widget_categories', $class);
- wp_register_widget_control('categories', __('Categories'), 'wp_widget_categories_control', $dims150);
+
$class['classname'] = 'widget_recent_entries';
wp_register_sidebar_widget('recent-posts', __('Recent Posts'), 'wp_widget_recent_entries', $class);
wp_register_widget_control('recent-posts', __('Recent Posts'), 'wp_widget_recent_entries_control', $dims90);
+
+ $class['classname'] = 'widget_tag_cloud';
+ wp_register_sidebar_widget('tag_cloud', __('Tag Cloud'), 'wp_widget_tag_cloud', $class);
+ wp_register_widget_control('tag_cloud', __('Tag Cloud'), 'wp_widget_tag_cloud_control', 'width=300&height=160');
+
+ wp_widget_categories_register();
wp_widget_text_register();
wp_widget_rss_register();
wp_widget_recent_comments_register();
- $wp_register_widget_defaults = false;
+ $GLOBALS['wp_register_widget_defaults'] = false;
do_action('widgets_init');
}
diff --git a/wp-includes/wp-db.php b/wp-includes/wp-db.php
index d829cd5..a3fa04e 100644
--- a/wp-includes/wp-db.php
+++ b/wp-includes/wp-db.php
@@ -34,6 +34,10 @@ class wpdb {
var $optiongroups;
var $optiongroup_options;
var $postmeta;
+ var $usermeta;
+ var $terms;
+ var $term_taxonomy;
+ var $term_relationships;
var $charset;
var $collate;
@@ -81,7 +85,7 @@ class wpdb {
}
function __destruct() {
- return true;
+ return true;
}
/**
@@ -115,6 +119,29 @@ class wpdb {
return mysql_real_escape_string( $string, $this->dbh );
}
+ /**
+ * Escapes content by reference for insertion into the database, for security
+ * @param string $s
+ */
+ function escape_by_ref(&$s) {
+ $s = $this->escape($s);
+ }
+
+ /**
+ * Prepares a SQL query for safe use, using sprintf() syntax
+ */
+ function prepare($args=NULL) {
+ if ( NULL === $args )
+ return;
+ $args = func_get_args();
+ $query = array_shift($args);
+ $query = str_replace("'%s'", '%s', $query); // in case someone mistakenly already singlequoted it
+ $query = str_replace('"%s"', '%s', $query); // doublequote unquoting
+ $query = str_replace('%s', "'%s'", $query); // quote the strings
+ array_walk($args, array(&$this, 'escape_by_ref'));
+ return @vsprintf($query, $args);
+ }
+
// ==================================================================
// Print SQL/DB error.
@@ -323,7 +350,9 @@ class wpdb {
$this->func_call = "\$db->get_row(\"$query\",$output,$y)";
if ( $query )
$this->query($query);
-
+ else
+ return null;
+
if ( !isset($this->last_result[$y]) )
return null;
@@ -348,6 +377,7 @@ class wpdb {
if ( $query )
$this->query($query);
+ $new_array = array();
// Extract the column values
for ( $i=0; $i < count($this->last_result); $i++ ) {
$new_array[$i] = $this->get_var(null, $x, $i);
@@ -366,6 +396,8 @@ class wpdb {
if ( $query )
$this->query($query);
+ else
+ return null;
// Send back array of objects. Each row is an object
if ( $output == OBJECT ) {
diff --git a/wp-includes/wpmu-functions.php b/wp-includes/wpmu-functions.php
index c382ce5..a5126d6 100644
--- a/wp-includes/wpmu-functions.php
+++ b/wp-includes/wpmu-functions.php
@@ -176,18 +176,23 @@ function get_blog_details( $id, $all = true ) {
return false;
}
- if( $all == true ) {
- $wpdb->hide_errors();
- $details->blogname = get_blog_option($id, 'blogname');
- $details->siteurl = get_blog_option($id, 'siteurl');
- $details->post_count = get_blog_option($id, 'post_count');
- $wpdb->show_errors();
+ if ( !$all ) {
+ wp_cache_add( $id, $details, 'blog-details' );
+ return $details;
+ }
- wp_cache_add( $id, serialize( $details ), 'blog-details' );
+ $wpdb->hide_errors();
+ $details->blogname = get_blog_option($id, 'blogname');
+ $details->siteurl = get_blog_option($id, 'siteurl');
+ $details->post_count = get_blog_option($id, 'post_count');
+ $wpdb->show_errors();
- $key = md5( $details->domain . $details->path );
- wp_cache_add( $key, serialize( $details ), 'blog-lookup' );
- }
+ $details = apply_filters('blog_details', $details);
+
+ wp_cache_set( $id, $details, 'blog-details' );
+
+ $key = md5( $details->domain . $details->path );
+ wp_cache_set( $key, $details, 'blog-lookup' );
return $details;
}
@@ -195,7 +200,7 @@ function get_blog_details( $id, $all = true ) {
function refresh_blog_details( $id ) {
global $wpdb, $wpmuBaseTablePrefix;
- $details = get_blog_details( $id );
+ $details = get_blog_details( $id, false );
wp_cache_delete( $id , 'blog-details' );
$key = md5( $details->domain . $details->path );
@@ -267,7 +272,6 @@ function add_site_option( $key, $value ) {
$safe_key = $wpdb->escape( $key );
$exists = $wpdb->get_row("SELECT meta_value FROM $wpdb->sitemeta WHERE meta_key = '$safe_key' AND site_id = '{$wpdb->siteid}'");
-
if ( is_object( $exists ) ) {// If we already have it
update_site_option( $key, $value );
return false;
@@ -296,6 +300,7 @@ function update_site_option( $key, $value ) {
if ( is_array($value) || is_object($value) )
$value = serialize($value);
+ $value = $wpdb->escape( $value );
$wpdb->query( "UPDATE $wpdb->sitemeta SET meta_value = '" . $wpdb->escape( $value ) . "' WHERE site_id='{$wpdb->siteid}' AND meta_key = '$safe_key'" );
wp_cache_delete( $wpdb->siteid . $key, 'site-options' );
@@ -390,11 +395,14 @@ function switch_to_blog( $new_blog ) {
$tmpoldblogdetails[ 'links' ] = $wpdb->links;
$tmpoldblogdetails[ 'link2cat' ] = $wpdb->link2cat;
$tmpoldblogdetails[ 'linkcategories' ] = $wpdb->linkcategories;
- $tmpoldblogdetails[ 'options' ] = $wpdb->options;
+ $tmpoldblogdetails[ 'options' ] = $wpdb->options;
$tmpoldblogdetails[ 'postmeta' ] = $wpdb->postmeta;
+ $tmpoldblogdetails[ 'terms' ] = $wpdb->terms;
+ $tmpoldblogdetails[ 'term_taxonomy' ] = $wpdb->term_taxonomy;
+ $tmpoldblogdetails[ 'term_relationships' ] = $wpdb->term_relationships;
$tmpoldblogdetails[ 'prefix' ] = $wpdb->prefix;
- $tmpoldblogdetails[ 'table_prefix' ] = $table_prefix;
- $tmpoldblogdetails[ 'blog_id' ] = $blog_id;
+ $tmpoldblogdetails[ 'table_prefix' ] = $table_prefix;
+ $tmpoldblogdetails[ 'blog_id' ] = $blog_id;
// fix the new prefix.
$table_prefix = $wpmuBaseTablePrefix . $new_blog . "_";
@@ -409,6 +417,9 @@ function switch_to_blog( $new_blog ) {
$wpdb->linkcategories = $table_prefix . 'linkcategories';
$wpdb->options = $table_prefix . 'options';
$wpdb->postmeta = $table_prefix . 'postmeta';
+ $wpdb->terms = $table_prefix . 'terms';
+ $wpdb->term_taxonomy = $table_prefix . 'term_taxonomy';
+ $wpdb->term_relationships = $table_prefix . 'term_relationships';
$blog_id = $new_blog;
if( is_object( $wp_roles ) ) {
@@ -447,6 +458,9 @@ function restore_current_blog() {
$wpdb->linkcategories = $tmpoldblogdetails[ 'linkcategories' ];
$wpdb->options = $tmpoldblogdetails[ 'options' ];
$wpdb->postmeta = $tmpoldblogdetails[ 'postmeta' ];
+ $wpdb->terms = $tmpoldblogdetails[ 'terms' ];
+ $wpdb->term_taxonomy = $tmpoldblogdetails[ 'term_taxonomy' ];
+ $wpdb->term_relationships = $tmpoldblogdetails[ 'term_relationships' ];
$wpdb->prefix = $tmpoldblogdetails[ 'prefix' ];
$table_prefix = $tmpoldblogdetails[ 'table_prefix' ];
$prev_blog_id = $blog_id;
@@ -787,8 +801,6 @@ function create_empty_blog( $domain, $path, $weblog_title, $site_id = 1 ) {
}
function get_blog_permalink( $blog_id, $post_id ) {
- global $wpdb, $cache_settings;
-
$key = "{$blog_id}-{$post_id}-blog_permalink";
$link = wp_cache_get( $key, 'site-options' );
if( $link == false ) {
@@ -1014,7 +1026,7 @@ function wpmu_validate_blog_signup($blog_id, $blog_title, $user = '') {
if( in_array( $blog_id, $illegal_names ) == true ) {
$errors->add('blog_id', __("That name is not allowed"));
}
- if( strlen( $blog_id ) < 4 ) {
+ if( strlen( $blog_id ) < 4 && !is_site_admin() ) {
$errors->add('blog_id', __("Blog name must be at least 4 characters"));
}
@@ -1264,6 +1276,33 @@ function wpmu_create_blog($domain, $path, $title, $user_id, $meta = '', $site_id
return $blog_id;
}
+function newblog_notify_siteadmin( $blog_id, $user_id ) {
+ global $current_site;
+ if( get_site_option( 'registrationnotification' ) != 'yes' )
+ return;
+ $email = get_site_option( 'admin_email' );
+ if( is_email( $email ) == false )
+ return false;
+ $msg = "New Blog: " . get_blog_option( $blog_id, "blogname" ) . "\nURL: " . get_blog_option( $blog_id, "siteurl" ) . "\nRemote IP: {$_SERVER[ 'REMOTE_ADDR' ]}\n\nDisable these notifications: http://{$current_site->domain}{$current_site->path}wp-admin/wpmu-options.php";
+ $msg = apply_filters( 'newblog_notify_siteadmin', $msg );
+ wp_mail( $email, "New Blog Registration: " . get_blog_option( $blog_id, "siteurl" ), $msg );
+}
+add_action( "wpmu_new_blog", "newblog_notify_siteadmin", 10, 2 );
+
+function newuser_notify_siteadmin( $user_id ) {
+ global $current_site;
+ if( get_site_option( 'registrationnotification' ) != 'yes' )
+ return;
+ $email = get_site_option( 'admin_email' );
+ if( is_email( $email ) == false )
+ return false;
+ $user = new WP_User($user_id);
+ $msg = "New User: " . $user->user_login . "\nRemote IP: {$_SERVER[ 'REMOTE_ADDR' ]}\n\nDisable these notifications: http://{$current_site->domain}{$current_site->path}wp-admin/wpmu-options.php";
+ $msg = apply_filters( 'newuser_notify_siteadmin', $msg );
+ wp_mail( $email, "New User Registration: " . $user->user_login, $msg );
+}
+add_action( "wpmu_new_user", "newuser_notify_siteadmin" );
+
function domain_exists($domain, $path, $site_id = 1) {
global $wpdb;
return $wpdb->get_var("SELECT blog_id FROM $wpdb->blogs WHERE domain = '$domain' AND path = '$path' AND site_id = '$site_id'" );
@@ -1287,7 +1326,7 @@ function install_blog($blog_id, $blog_title = '') {
global $wpdb, $table_prefix, $wp_roles;
$wpdb->hide_errors();
- require_once( ABSPATH . 'wp-admin/upgrade-functions.php');
+ require_once( ABSPATH . 'wp-admin/includes/upgrade.php');
$installed = $wpdb->get_results("SELECT * FROM $wpdb->posts");
if ($installed) die(__('Already Installed You appear to have already installed WordPress. To reinstall please clear your old database tables first.
') . '');
@@ -1311,15 +1350,24 @@ function install_blog($blog_id, $blog_title = '') {
$wpdb->query("UPDATE $wpdb->options SET option_value = '' WHERE option_name = 'admin_email'");
// Default category
- $wpdb->query("INSERT INTO $wpdb->categories (cat_ID, cat_name, category_nicename, category_count, category_description) VALUES ('0', '".addslashes(__('Uncategorized'))."', '".sanitize_title(__('Uncategorized'))."', 1, '')");
- $blogroll_id = $wpdb->get_var( "SELECT cat_ID FROM {$wpdb->sitecategories} WHERE category_nicename = 'blogroll'" );
+ $cat_name = $wpdb->escape(__('Uncategorized'));
+ $cat_slug = sanitize_title(__('Uncategorized'));
+ $wpdb->query("INSERT INTO $wpdb->terms (term_id, name, slug, term_group) VALUES ('1', '$cat_name', '$cat_slug', '0')");
+
+ $wpdb->query("INSERT INTO $wpdb->term_taxonomy (term_id, taxonomy, description, parent, count) VALUES ('1', 'category', '', '0', '1')");
+
+ // Default link category
+ $cat_name = $wpdb->escape(__('Blogroll'));
+ $cat_slug = sanitize_title(__('Blogroll'));
+ $blogroll_id = $wpdb->get_var( "SELECT cat_ID FROM {$wpdb->sitecategories} WHERE category_nicename = '$cat_slug'" );
if( $blogroll_id == null ) {
- $wpdb->query( "INSERT INTO " . $wpdb->sitecategories . " (cat_ID, cat_name, category_nicename, last_updated) VALUES (0, 'Blogroll', 'blogroll', NOW())" );
+ $wpdb->query( "INSERT INTO " . $wpdb->sitecategories . " (cat_ID, cat_name, category_nicename, last_updated) VALUES (0, '$cat_name', '$cat_slug', NOW())" );
$blogroll_id = $wpdb->insert_id;
}
- $wpdb->query("INSERT INTO $wpdb->categories (cat_ID, cat_name, category_nicename, link_count, category_description) VALUES ('{$blogroll_id}', '".addslashes(__('Blogroll'))."', '".sanitize_title(__('Blogroll'))."', 2, '')");
- $wpdb->query("INSERT INTO $wpdb->link2cat (link_id, category_id) VALUES (1, $blogroll_id)");
- $wpdb->query("INSERT INTO $wpdb->link2cat (link_id, category_id) VALUES (2, $blogroll_id)");
+ $wpdb->query("INSERT INTO $wpdb->terms (term_id, name, slug, term_group) VALUES ('$blogroll_id', '$cat_name', '$cat_slug', '0')");
+ $wpdb->query("INSERT INTO $wpdb->term_taxonomy (term_id, taxonomy, description, parent, count) VALUES ('$blogroll_id', 'link_category', '', '0', '2')");
+
+ update_option('default_link_category', $blogroll_id);
// remove all perms
$wpdb->query( "DELETE FROM ".$wpdb->usermeta." WHERE meta_key = '".$table_prefix."user_level'" );
@@ -1334,8 +1382,10 @@ function install_blog_defaults($blog_id, $user_id) {
$wpdb->hide_errors();
// Default links
- $wpdb->query("INSERT INTO $wpdb->links (link_url, link_name, link_image, link_target, link_category, link_description, link_visible, link_owner, link_rating, link_updated, link_rel, link_notes, link_rss) VALUES ('http://wordpress.com/', 'WordPress.com', '', '', 1, '', 'Y', '$user_id', 0, 0, '', '', 'http://wordpress.com/feed/')");
- $wpdb->query("INSERT INTO $wpdb->links (link_url, link_name, link_image, link_target, link_category, link_description, link_visible, link_owner, link_rating, link_updated, link_rel, link_notes, link_rss) VALUES ('http://wordpress.org/', 'WordPress.org', '', '', 1, '', 'Y', '$user_id', 0, 0, '', '', 'http://wordpress.org/development/feed/')");
+ $wpdb->query("INSERT INTO $wpdb->links (link_url, link_name, link_category, link_owner, link_rss) VALUES ('http://wordpress.com/', 'WordPress.com', 1356, '$user_id', 'http://wordpress.com/feed/');");
+ $wpdb->query("INSERT INTO $wpdb->links (link_url, link_name, link_category, link_owner, link_rss) VALUES ('http://wordpress.org/', 'WordPress.org', 1356, '$user_id', 'http://wordpress.org/development/feed/');");
+ $wpdb->query( "INSERT INTO $wpdb->term_relationships (`object_id`, `term_taxonomy_id`) VALUES (1, 2)" );
+ $wpdb->query( "INSERT INTO $wpdb->term_relationships (`object_id`, `term_taxonomy_id`) VALUES (2, 2)" );
// First post
$now = date('Y-m-d H:i:s');
@@ -1348,13 +1398,12 @@ function install_blog_defaults($blog_id, $user_id) {
$first_post = str_replace( "SITE_NAME", $current_site->site_name, $first_post );
$first_post = stripslashes( $first_post );
- $wpdb->query("INSERT INTO $wpdb->posts (post_author, post_date, post_date_gmt, post_content, post_title, post_category, post_excerpt, post_status, comment_status, ping_status, post_password, post_name, to_ping, pinged, post_modified, post_modified_gmt, post_content_filtered, post_parent, guid, menu_order, post_type, post_mime_type, comment_count) VALUES ('".$user_id."', '$now', '$now_gmt', '".addslashes($first_post)."', '".addslashes(__('Hello world!'))."', '0', '', 'publish', 'open', 'open', '', '".addslashes(__('hello-world'))."', to_ping, pinged, '$now', '$now_gmt', '', 0, '', 0, 'post', '', 1)");
- $wpdb->query( "INSERT INTO $wpdb->post2cat (`rel_id`, `post_id`, `category_id`) VALUES (1, 1, 1)" );
+ $wpdb->query("INSERT INTO $wpdb->posts (post_author, post_date, post_date_gmt, post_content, post_title, post_category, post_name, post_modified, post_modified_gmt, comment_count) VALUES ('".$user_id."', '$now', '$now_gmt', '".addslashes($first_post)."', '".addslashes(__('Hello world!'))."', '0', '".addslashes(__('hello-world'))."', '$now', '$now_gmt', '1')");
+ $wpdb->query( "INSERT INTO $wpdb->term_relationships (`object_id`, `term_taxonomy_id`) VALUES (1, 1)" );
update_option( "post_count", 1 );
// First page
$wpdb->query("INSERT INTO $wpdb->posts (post_author, post_date, post_date_gmt, post_content, post_excerpt, post_title, post_category, post_name, post_modified, post_modified_gmt, post_status, post_type, to_ping, pinged, post_content_filtered) VALUES ('$user_id', '$now', '$now_gmt', '".$wpdb->escape(__('This is an example of a WordPress page, you could edit this to put information about yourself or your site so readers know where you are coming from. You can create as many pages like this one or sub-pages as you like and manage all of your content inside of WordPress.'))."', '', '".$wpdb->escape(__('About'))."', '0', '".$wpdb->escape(__('about'))."', '$now', '$now_gmt', 'publish', 'page', '', '', '')");
- $wpdb->query( "INSERT INTO $wpdb->post2cat (`rel_id`, `post_id`, `category_id`) VALUES (2, 2, 1)" );
// Flush rules to pick up the new page.
$wp_rewrite->init();
$wp_rewrite->flush_rules();
@@ -1819,192 +1868,38 @@ add_action( 'admin_footer', 'add_switcher' );
/* Global Categories */
-function global_categories( $cat_ID ) {
+function global_terms( $term_id, $tt_id ) {
global $wpdb;
- $cat_ID = intval( $cat_ID );
- $c = $wpdb->get_row( "SELECT * FROM $wpdb->categories WHERE cat_ID = '$cat_ID'" );
+ $term_id = intval( $term_id );
+ $c = $wpdb->get_row( "SELECT * FROM $wpdb->terms WHERE term_id = '$term_id'" );
- $global_category = $wpdb->get_row( "SELECT * FROM $wpdb->sitecategories WHERE category_nicename = '" . $wpdb->escape( $c->category_nicename ) . "'" );
+ $global_id = $wpdb->get_var( "SELECT cat_ID FROM $wpdb->sitecategories WHERE category_nicename = '" . $wpdb->escape( $c->slug ) . "'" );
- if ( $global_category ) {
- $global_id = $global_category->cat_ID;
- } else {
- $wpdb->query( "INSERT INTO $wpdb->sitecategories ( cat_name, category_nicename ) VALUES ( '" . $wpdb->escape( $c->cat_name ) . "', '" . $wpdb->escape( $c->category_nicename ) . "' )" );
+ if ( $global_id == null ) {
+ $wpdb->query( "INSERT INTO $wpdb->sitecategories ( cat_name, category_nicename ) VALUES ( '" . $wpdb->escape( $c->name ) . "', '" . $wpdb->escape( $c->slug ) . "' )" );
$global_id = $wpdb->insert_id;
}
- $wpdb->query( "UPDATE $wpdb->categories SET cat_ID = '$global_id' WHERE cat_id = '$cat_ID'" );
- $wpdb->query( "UPDATE $wpdb->categories SET category_parent = '$global_id' WHERE category_parent = '$cat_ID'" );
- $wpdb->query( "UPDATE $wpdb->post2cat SET category_id = '$global_id' WHERE category_id = '$cat_ID'" );
- $wpdb->query( "UPDATE $wpdb->link2cat SET category_id = '$global_id' WHERE category_id = '$cat_ID'" );
- wp_cache_delete($cat_ID, 'category');
- wp_cache_delete($global_id, 'category');
- wp_cache_delete('all_category_ids', 'category');
-
- do_action('update_cat_id', $global_id, $cat_ID);
-
- return $global_id;
-}
-
-add_filter( 'cat_id_filter', 'global_categories' );
-
-/* WordPress MU Default Filters */
-add_filter('the_title', 'wp_filter_kses');
-
-/* Pluggable */
-
-function wp_login($username, $password, $already_md5 = false) {
- global $wpdb, $error, $current_user;
-
- $username = sanitize_user($username);
-
- if ( '' == $username )
- return false;
-
- if ( '' == $password ) {
- $error = __('ERROR : The password field is empty.');
- return false;
- }
-
- if ($current_user->data->user_login == $username)
- return true;
-
- $login = get_userdatabylogin($username);
-
- if (!$login) {
- if( is_site_admin( $username ) ) {
- unset( $login );
- $userdetails = get_userdatabylogin( $username );
- $login->user_login = $username;
- $login->user_pass = $userdetails->user_pass;
- } else {
- $admins = get_admin_users_for_domain();
- reset( $admins );
- while( list( $key, $val ) = each( $admins ) )
- {
- if( $val[ 'user_login' ] == $username ) {
- unset( $login );
- $login->user_login = $username;
- $login->user_pass = $val[ 'user_pass' ];
- }
- }
- }
- }
- if (!$login) {
- $error = __('Error : Wrong username.');
- return false;
- } else {
- if( is_site_admin( $username ) == false && ( $primary_blog = get_usermeta( $login->ID, "primary_blog" ) ) ) {
- $details = get_blog_details( $primary_blog );
- if( is_object( $details ) && $details->archived == 1 || $details->spam == 1 || $details->deleted == 1 ) {
- $error = __('Error : Blog suspended.');
- return false;
- }
- }
- // If the password is already_md5, it has been double hashed.
- // Otherwise, it is plain text.
- if ( ($already_md5 && $login->user_login == $username && md5($login->user_pass) == $password) || ($login->user_login == $username && $login->user_pass == md5($password)) ) {
- return true;
- } else {
- $error = __('Error : Incorrect password.');
- $pwd = '';
- return false;
- }
- }
-}
-
-function get_userdata( $user_id ) {
- global $wpdb, $cache_userdata, $wpmuBaseTablePrefix;
- $user_id = (int) $user_id;
- if ( $user_id == 0 )
- return false;
-
- $user = wp_cache_get($user_id, 'users');
- $user_level = $wpmuBaseTablePrefix . $wpdb->blogid . '_user_level';
- if ( $user && is_site_admin( $user->user_login ) ) {
- $user->$user_level = 10;
- $user->user_level = 10;
- $cap_key = $wpdb->prefix . 'capabilities';
- $user->{$cap_key} = array( 'administrator' => '1' );
- return $user;
- } elseif ( $user ) {
- return $user;
- }
-
- if ( !$user = $wpdb->get_row("SELECT * FROM $wpdb->users WHERE ID = '$user_id'") )
- return false;
-
- $metavalues = $wpdb->get_results("SELECT meta_key, meta_value FROM $wpdb->usermeta WHERE user_id = '$user_id' /* pluggable get_userdata */");
-
- if ($metavalues) {
- foreach ( $metavalues as $meta ) {
- @ $value = unserialize($meta->meta_value);
- if ($value === FALSE)
- $value = $meta->meta_value;
- $user->{$meta->meta_key} = $value;
-
- // We need to set user_level from meta, not row
- if ( $wpdb->prefix . 'user_level' == $meta->meta_key )
- $user->user_level = $meta->meta_value;
- } // end foreach
- } //end if
-
- if( is_site_admin( $user->user_login ) == true ) {
- $user->user_level = 10;
- $cap_key = $wpdb->prefix . 'capabilities';
- $user->{$cap_key} = array( 'administrator' => '1' );
- }
-
- wp_cache_add($user_id, $user, 'users');
- wp_cache_add($user->user_login, $user, 'userlogins');
-
- return $user;
-}
-function get_userdatabylogin($user_login) {
- global $wpdb;
- $user_login = sanitize_user( $user_login );
+ if ( $global_id == $term_id )
+ return $global_id;
- if ( empty( $user_login ) )
- return false;
-
- $userdata = wp_cache_get($user_login, 'userlogins');
- if( $userdata && is_site_admin( $user_login ) == true ) {
- $userdata->user_level = 10;
- $cap_key = $wpdb->prefix . 'capabilities';
- $userdata->{$cap_key} = array( 'administrator' => '1' );
- return $userdata;
- } elseif( $userdata )
- return $userdata;
-
- if ( !$user = $wpdb->get_row("SELECT * FROM $wpdb->users WHERE user_login = '$user_login'") )
- return false;
+ $wpdb->query( "UPDATE $wpdb->terms SET term_id = '$global_id' WHERE term_id = '$term_id'" );
+ $wpdb->query( "UPDATE $wpdb->term_taxonomy SET term_id = '$global_id' WHERE term_id = '$term_id'" );
+ $wpdb->query( "UPDATE $wpdb->term_taxonomy SET parent = '$global_id' WHERE parent = '$term_id'" );
- $metavalues = $wpdb->get_results("SELECT meta_key, meta_value FROM $wpdb->usermeta WHERE user_id = '$user->ID'");
+ $wpdb->query( "UPDATE $wpdb->categories SET cat_ID = '$global_id' WHERE cat_ID = '$term_id'" );
+ $wpdb->query( "UPDATE $wpdb->categories SET category_parent = '$global_id' WHERE category_parent = '$term_id'" );
- if ($metavalues) {
- foreach ( $metavalues as $meta ) {
- @ $value = unserialize($meta->meta_value);
- if ($value === FALSE)
- $value = $meta->meta_value;
- $user->{$meta->meta_key} = $value;
+ clean_term_cache($global_id, 'category');
+ clean_term_cache($global_id, 'post_tag');
- // We need to set user_level from meta, not row
- if ( $wpdb->prefix . 'user_level' == $meta->meta_key )
- $user->user_level = $meta->meta_value;
- }
- }
- if( is_site_admin( $user_login ) == true ) {
- $user->user_level = 10;
- $cap_key = $wpdb->prefix . 'capabilities';
- $user->{$cap_key} = array( 'administrator' => '1' );
- }
+ return $global_id;
+}
+add_filter( 'term_id_filter', 'global_terms', 10, 2 ); // taxonomy specific filter
- wp_cache_add($user->ID, $user, 'users');
- wp_cache_add($user->user_login, $user, 'userlogins');
-
- return $user;
-}
+/* WordPress MU Default Filters */
+add_filter('the_title', 'wp_filter_kses');
function choose_primary_blog() {
global $current_user;
@@ -2022,5 +1917,4 @@ function choose_primary_blog() {
}
}
add_action( 'profile_personal_options', 'choose_primary_blog' );
-
?>
--
cgit