studio2011 initial commit
No files matched your search
@@ -0,0 +1,450 @@
|
||||
<?php
|
||||
/**
|
||||
* General API for generating and formatting diffs - the differences between
|
||||
* two sequences of strings.
|
||||
*
|
||||
* The original PHP version of this code was written by Geoffrey T. Dairiki
|
||||
* <dairiki@dairiki.org>, and is used/adapted with his permission.
|
||||
*
|
||||
* Copyright 2004 Geoffrey T. Dairiki <dairiki@dairiki.org>
|
||||
* Copyright 2004-2010 The Horde Project (http://www.horde.org/)
|
||||
*
|
||||
* See the enclosed file COPYING for license information (LGPL). If you did
|
||||
* not receive this file, see http://opensource.org/licenses/lgpl-license.php.
|
||||
*
|
||||
* @package Text_Diff
|
||||
* @author Geoffrey T. Dairiki <dairiki@dairiki.org>
|
||||
*/
|
||||
class Text_Diff {
|
||||
|
||||
/**
|
||||
* Array of changes.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
var $_edits;
|
||||
|
||||
/**
|
||||
* Computes diffs between sequences of strings.
|
||||
*
|
||||
* @param string $engine Name of the diffing engine to use. 'auto'
|
||||
* will automatically select the best.
|
||||
* @param array $params Parameters to pass to the diffing engine.
|
||||
* Normally an array of two arrays, each
|
||||
* containing the lines from a file.
|
||||
*/
|
||||
function Text_Diff($engine, $params)
|
||||
{
|
||||
// Backward compatibility workaround.
|
||||
if (!is_string($engine)) {
|
||||
$params = array($engine, $params);
|
||||
$engine = 'auto';
|
||||
}
|
||||
|
||||
if ($engine == 'auto') {
|
||||
$engine = extension_loaded('xdiff') ? 'xdiff' : 'native';
|
||||
} else {
|
||||
$engine = basename($engine);
|
||||
}
|
||||
|
||||
// WP #7391
|
||||
require_once dirname(__FILE__).'/Diff/Engine/' . $engine . '.php';
|
||||
$class = 'Text_Diff_Engine_' . $engine;
|
||||
$diff_engine = new $class();
|
||||
|
||||
$this->_edits = call_user_func_array(array($diff_engine, 'diff'), $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the array of differences.
|
||||
*/
|
||||
function getDiff()
|
||||
{
|
||||
return $this->_edits;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the number of new (added) lines in a given diff.
|
||||
*
|
||||
* @since Text_Diff 1.1.0
|
||||
*
|
||||
* @return integer The number of new lines
|
||||
*/
|
||||
function countAddedLines()
|
||||
{
|
||||
$count = 0;
|
||||
foreach ($this->_edits as $edit) {
|
||||
if (is_a($edit, 'Text_Diff_Op_add') ||
|
||||
is_a($edit, 'Text_Diff_Op_change')) {
|
||||
$count += $edit->nfinal();
|
||||
}
|
||||
}
|
||||
return $count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of deleted (removed) lines in a given diff.
|
||||
*
|
||||
* @since Text_Diff 1.1.0
|
||||
*
|
||||
* @return integer The number of deleted lines
|
||||
*/
|
||||
function countDeletedLines()
|
||||
{
|
||||
$count = 0;
|
||||
foreach ($this->_edits as $edit) {
|
||||
if (is_a($edit, 'Text_Diff_Op_delete') ||
|
||||
is_a($edit, 'Text_Diff_Op_change')) {
|
||||
$count += $edit->norig();
|
||||
}
|
||||
}
|
||||
return $count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes a reversed diff.
|
||||
*
|
||||
* Example:
|
||||
* <code>
|
||||
* $diff = new Text_Diff($lines1, $lines2);
|
||||
* $rev = $diff->reverse();
|
||||
* </code>
|
||||
*
|
||||
* @return Text_Diff A Diff object representing the inverse of the
|
||||
* original diff. Note that we purposely don't return a
|
||||
* reference here, since this essentially is a clone()
|
||||
* method.
|
||||
*/
|
||||
function reverse()
|
||||
{
|
||||
if (version_compare(zend_version(), '2', '>')) {
|
||||
$rev = clone($this);
|
||||
} else {
|
||||
$rev = $this;
|
||||
}
|
||||
$rev->_edits = array();
|
||||
foreach ($this->_edits as $edit) {
|
||||
$rev->_edits[] = $edit->reverse();
|
||||
}
|
||||
return $rev;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks for an empty diff.
|
||||
*
|
||||
* @return boolean True if two sequences were identical.
|
||||
*/
|
||||
function isEmpty()
|
||||
{
|
||||
foreach ($this->_edits as $edit) {
|
||||
if (!is_a($edit, 'Text_Diff_Op_copy')) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the length of the Longest Common Subsequence (LCS).
|
||||
*
|
||||
* This is mostly for diagnostic purposes.
|
||||
*
|
||||
* @return integer The length of the LCS.
|
||||
*/
|
||||
function lcs()
|
||||
{
|
||||
$lcs = 0;
|
||||
foreach ($this->_edits as $edit) {
|
||||
if (is_a($edit, 'Text_Diff_Op_copy')) {
|
||||
$lcs += count($edit->orig);
|
||||
}
|
||||
}
|
||||
return $lcs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the original set of lines.
|
||||
*
|
||||
* This reconstructs the $from_lines parameter passed to the constructor.
|
||||
*
|
||||
* @return array The original sequence of strings.
|
||||
*/
|
||||
function getOriginal()
|
||||
{
|
||||
$lines = array();
|
||||
foreach ($this->_edits as $edit) {
|
||||
if ($edit->orig) {
|
||||
array_splice($lines, count($lines), 0, $edit->orig);
|
||||
}
|
||||
}
|
||||
return $lines;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the final set of lines.
|
||||
*
|
||||
* This reconstructs the $to_lines parameter passed to the constructor.
|
||||
*
|
||||
* @return array The sequence of strings.
|
||||
*/
|
||||
function getFinal()
|
||||
{
|
||||
$lines = array();
|
||||
foreach ($this->_edits as $edit) {
|
||||
if ($edit->final) {
|
||||
array_splice($lines, count($lines), 0, $edit->final);
|
||||
}
|
||||
}
|
||||
return $lines;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes trailing newlines from a line of text. This is meant to be used
|
||||
* with array_walk().
|
||||
*
|
||||
* @param string $line The line to trim.
|
||||
* @param integer $key The index of the line in the array. Not used.
|
||||
*/
|
||||
function trimNewlines(&$line, $key)
|
||||
{
|
||||
$line = str_replace(array("\n", "\r"), '', $line);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the location of the system temporary directory.
|
||||
*
|
||||
* @static
|
||||
*
|
||||
* @access protected
|
||||
*
|
||||
* @return string A directory name which can be used for temp files.
|
||||
* Returns false if one could not be found.
|
||||
*/
|
||||
function _getTempDir()
|
||||
{
|
||||
$tmp_locations = array('/tmp', '/var/tmp', 'c:\WUTemp', 'c:\temp',
|
||||
'c:\windows\temp', 'c:\winnt\temp');
|
||||
|
||||
/* Try PHP's upload_tmp_dir directive. */
|
||||
$tmp = ini_get('upload_tmp_dir');
|
||||
|
||||
/* Otherwise, try to determine the TMPDIR environment variable. */
|
||||
if (!strlen($tmp)) {
|
||||
$tmp = getenv('TMPDIR');
|
||||
}
|
||||
|
||||
/* If we still cannot determine a value, then cycle through a list of
|
||||
* preset possibilities. */
|
||||
while (!strlen($tmp) && count($tmp_locations)) {
|
||||
$tmp_check = array_shift($tmp_locations);
|
||||
if (@is_dir($tmp_check)) {
|
||||
$tmp = $tmp_check;
|
||||
}
|
||||
}
|
||||
|
||||
/* If it is still empty, we have failed, so return false; otherwise
|
||||
* return the directory determined. */
|
||||
return strlen($tmp) ? $tmp : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks a diff for validity.
|
||||
*
|
||||
* This is here only for debugging purposes.
|
||||
*/
|
||||
function _check($from_lines, $to_lines)
|
||||
{
|
||||
if (serialize($from_lines) != serialize($this->getOriginal())) {
|
||||
trigger_error("Reconstructed original doesn't match", E_USER_ERROR);
|
||||
}
|
||||
if (serialize($to_lines) != serialize($this->getFinal())) {
|
||||
trigger_error("Reconstructed final doesn't match", E_USER_ERROR);
|
||||
}
|
||||
|
||||
$rev = $this->reverse();
|
||||
if (serialize($to_lines) != serialize($rev->getOriginal())) {
|
||||
trigger_error("Reversed original doesn't match", E_USER_ERROR);
|
||||
}
|
||||
if (serialize($from_lines) != serialize($rev->getFinal())) {
|
||||
trigger_error("Reversed final doesn't match", E_USER_ERROR);
|
||||
}
|
||||
|
||||
$prevtype = null;
|
||||
foreach ($this->_edits as $edit) {
|
||||
if ($prevtype == get_class($edit)) {
|
||||
trigger_error("Edit sequence is non-optimal", E_USER_ERROR);
|
||||
}
|
||||
$prevtype = get_class($edit);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @package Text_Diff
|
||||
* @author Geoffrey T. Dairiki <dairiki@dairiki.org>
|
||||
*/
|
||||
class Text_MappedDiff extends Text_Diff {
|
||||
|
||||
/**
|
||||
* Computes a diff between sequences of strings.
|
||||
*
|
||||
* This can be used to compute things like case-insensitve diffs, or diffs
|
||||
* which ignore changes in white-space.
|
||||
*
|
||||
* @param array $from_lines An array of strings.
|
||||
* @param array $to_lines An array of strings.
|
||||
* @param array $mapped_from_lines This array should have the same size
|
||||
* number of elements as $from_lines. The
|
||||
* elements in $mapped_from_lines and
|
||||
* $mapped_to_lines are what is actually
|
||||
* compared when computing the diff.
|
||||
* @param array $mapped_to_lines This array should have the same number
|
||||
* of elements as $to_lines.
|
||||
*/
|
||||
function Text_MappedDiff($from_lines, $to_lines,
|
||||
$mapped_from_lines, $mapped_to_lines)
|
||||
{
|
||||
assert(count($from_lines) == count($mapped_from_lines));
|
||||
assert(count($to_lines) == count($mapped_to_lines));
|
||||
|
||||
parent::Text_Diff($mapped_from_lines, $mapped_to_lines);
|
||||
|
||||
$xi = $yi = 0;
|
||||
for ($i = 0; $i < count($this->_edits); $i++) {
|
||||
$orig = &$this->_edits[$i]->orig;
|
||||
if (is_array($orig)) {
|
||||
$orig = array_slice($from_lines, $xi, count($orig));
|
||||
$xi += count($orig);
|
||||
}
|
||||
|
||||
$final = &$this->_edits[$i]->final;
|
||||
if (is_array($final)) {
|
||||
$final = array_slice($to_lines, $yi, count($final));
|
||||
$yi += count($final);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @package Text_Diff
|
||||
* @author Geoffrey T. Dairiki <dairiki@dairiki.org>
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
class Text_Diff_Op {
|
||||
|
||||
var $orig;
|
||||
var $final;
|
||||
|
||||
function &reverse()
|
||||
{
|
||||
trigger_error('Abstract method', E_USER_ERROR);
|
||||
}
|
||||
|
||||
function norig()
|
||||
{
|
||||
return $this->orig ? count($this->orig) : 0;
|
||||
}
|
||||
|
||||
function nfinal()
|
||||
{
|
||||
return $this->final ? count($this->final) : 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @package Text_Diff
|
||||
* @author Geoffrey T. Dairiki <dairiki@dairiki.org>
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
class Text_Diff_Op_copy extends Text_Diff_Op {
|
||||
|
||||
function Text_Diff_Op_copy($orig, $final = false)
|
||||
{
|
||||
if (!is_array($final)) {
|
||||
$final = $orig;
|
||||
}
|
||||
$this->orig = $orig;
|
||||
$this->final = $final;
|
||||
}
|
||||
|
||||
function &reverse()
|
||||
{
|
||||
$reverse = &new Text_Diff_Op_copy($this->final, $this->orig);
|
||||
return $reverse;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @package Text_Diff
|
||||
* @author Geoffrey T. Dairiki <dairiki@dairiki.org>
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
class Text_Diff_Op_delete extends Text_Diff_Op {
|
||||
|
||||
function Text_Diff_Op_delete($lines)
|
||||
{
|
||||
$this->orig = $lines;
|
||||
$this->final = false;
|
||||
}
|
||||
|
||||
function &reverse()
|
||||
{
|
||||
$reverse = &new Text_Diff_Op_add($this->orig);
|
||||
return $reverse;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @package Text_Diff
|
||||
* @author Geoffrey T. Dairiki <dairiki@dairiki.org>
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
class Text_Diff_Op_add extends Text_Diff_Op {
|
||||
|
||||
function Text_Diff_Op_add($lines)
|
||||
{
|
||||
$this->final = $lines;
|
||||
$this->orig = false;
|
||||
}
|
||||
|
||||
function &reverse()
|
||||
{
|
||||
$reverse = &new Text_Diff_Op_delete($this->final);
|
||||
return $reverse;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @package Text_Diff
|
||||
* @author Geoffrey T. Dairiki <dairiki@dairiki.org>
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
class Text_Diff_Op_change extends Text_Diff_Op {
|
||||
|
||||
function Text_Diff_Op_change($orig, $final)
|
||||
{
|
||||
$this->orig = $orig;
|
||||
$this->final = $final;
|
||||
}
|
||||
|
||||
function &reverse()
|
||||
{
|
||||
$reverse = &new Text_Diff_Op_change($this->final, $this->orig);
|
||||
return $reverse;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,436 @@
|
||||
<?php
|
||||
/**
|
||||
* Class used internally by Text_Diff to actually compute the diffs.
|
||||
*
|
||||
* This class is implemented using native PHP code.
|
||||
*
|
||||
* The algorithm used here is mostly lifted from the perl module
|
||||
* Algorithm::Diff (version 1.06) by Ned Konz, which is available at:
|
||||
* http://www.perl.com/CPAN/authors/id/N/NE/NEDKONZ/Algorithm-Diff-1.06.zip
|
||||
*
|
||||
* More ideas are taken from: http://www.ics.uci.edu/~eppstein/161/960229.html
|
||||
*
|
||||
* Some ideas (and a bit of code) are taken from analyze.c, of GNU
|
||||
* diffutils-2.7, which can be found at:
|
||||
* ftp://gnudist.gnu.org/pub/gnu/diffutils/diffutils-2.7.tar.gz
|
||||
*
|
||||
* Some ideas (subdivision by NCHUNKS > 2, and some optimizations) are from
|
||||
* Geoffrey T. Dairiki <dairiki@dairiki.org>. The original PHP version of this
|
||||
* code was written by him, and is used/adapted with his permission.
|
||||
*
|
||||
* Copyright 2004-2010 The Horde Project (http://www.horde.org/)
|
||||
*
|
||||
* See the enclosed file COPYING for license information (LGPL). If you did
|
||||
* not receive this file, see http://opensource.org/licenses/lgpl-license.php.
|
||||
*
|
||||
* @author Geoffrey T. Dairiki <dairiki@dairiki.org>
|
||||
* @package Text_Diff
|
||||
*/
|
||||
class Text_Diff_Engine_native {
|
||||
|
||||
function diff($from_lines, $to_lines)
|
||||
{
|
||||
array_walk($from_lines, array('Text_Diff', 'trimNewlines'));
|
||||
array_walk($to_lines, array('Text_Diff', 'trimNewlines'));
|
||||
|
||||
$n_from = count($from_lines);
|
||||
$n_to = count($to_lines);
|
||||
|
||||
$this->xchanged = $this->ychanged = array();
|
||||
$this->xv = $this->yv = array();
|
||||
$this->xind = $this->yind = array();
|
||||
unset($this->seq);
|
||||
unset($this->in_seq);
|
||||
unset($this->lcs);
|
||||
|
||||
// Skip leading common lines.
|
||||
for ($skip = 0; $skip < $n_from && $skip < $n_to; $skip++) {
|
||||
if ($from_lines[$skip] !== $to_lines[$skip]) {
|
||||
break;
|
||||
}
|
||||
$this->xchanged[$skip] = $this->ychanged[$skip] = false;
|
||||
}
|
||||
|
||||
// Skip trailing common lines.
|
||||
$xi = $n_from; $yi = $n_to;
|
||||
for ($endskip = 0; --$xi > $skip && --$yi > $skip; $endskip++) {
|
||||
if ($from_lines[$xi] !== $to_lines[$yi]) {
|
||||
break;
|
||||
}
|
||||
$this->xchanged[$xi] = $this->ychanged[$yi] = false;
|
||||
}
|
||||
|
||||
// Ignore lines which do not exist in both files.
|
||||
for ($xi = $skip; $xi < $n_from - $endskip; $xi++) {
|
||||
$xhash[$from_lines[$xi]] = 1;
|
||||
}
|
||||
for ($yi = $skip; $yi < $n_to - $endskip; $yi++) {
|
||||
$line = $to_lines[$yi];
|
||||
if (($this->ychanged[$yi] = empty($xhash[$line]))) {
|
||||
continue;
|
||||
}
|
||||
$yhash[$line] = 1;
|
||||
$this->yv[] = $line;
|
||||
$this->yind[] = $yi;
|
||||
}
|
||||
for ($xi = $skip; $xi < $n_from - $endskip; $xi++) {
|
||||
$line = $from_lines[$xi];
|
||||
if (($this->xchanged[$xi] = empty($yhash[$line]))) {
|
||||
continue;
|
||||
}
|
||||
$this->xv[] = $line;
|
||||
$this->xind[] = $xi;
|
||||
}
|
||||
|
||||
// Find the LCS.
|
||||
$this->_compareseq(0, count($this->xv), 0, count($this->yv));
|
||||
|
||||
// Merge edits when possible.
|
||||
$this->_shiftBoundaries($from_lines, $this->xchanged, $this->ychanged);
|
||||
$this->_shiftBoundaries($to_lines, $this->ychanged, $this->xchanged);
|
||||
|
||||
// Compute the edit operations.
|
||||
$edits = array();
|
||||
$xi = $yi = 0;
|
||||
while ($xi < $n_from || $yi < $n_to) {
|
||||
assert($yi < $n_to || $this->xchanged[$xi]);
|
||||
assert($xi < $n_from || $this->ychanged[$yi]);
|
||||
|
||||
// Skip matching "snake".
|
||||
$copy = array();
|
||||
while ($xi < $n_from && $yi < $n_to
|
||||
&& !$this->xchanged[$xi] && !$this->ychanged[$yi]) {
|
||||
$copy[] = $from_lines[$xi++];
|
||||
++$yi;
|
||||
}
|
||||
if ($copy) {
|
||||
$edits[] = &new Text_Diff_Op_copy($copy);
|
||||
}
|
||||
|
||||
// Find deletes & adds.
|
||||
$delete = array();
|
||||
while ($xi < $n_from && $this->xchanged[$xi]) {
|
||||
$delete[] = $from_lines[$xi++];
|
||||
}
|
||||
|
||||
$add = array();
|
||||
while ($yi < $n_to && $this->ychanged[$yi]) {
|
||||
$add[] = $to_lines[$yi++];
|
||||
}
|
||||
|
||||
if ($delete && $add) {
|
||||
$edits[] = &new Text_Diff_Op_change($delete, $add);
|
||||
} elseif ($delete) {
|
||||
$edits[] = &new Text_Diff_Op_delete($delete);
|
||||
} elseif ($add) {
|
||||
$edits[] = &new Text_Diff_Op_add($add);
|
||||
}
|
||||
}
|
||||
|
||||
return $edits;
|
||||
}
|
||||
|
||||
/**
|
||||
* Divides the Largest Common Subsequence (LCS) of the sequences (XOFF,
|
||||
* XLIM) and (YOFF, YLIM) into NCHUNKS approximately equally sized
|
||||
* segments.
|
||||
*
|
||||
* Returns (LCS, PTS). LCS is the length of the LCS. PTS is an array of
|
||||
* NCHUNKS+1 (X, Y) indexes giving the diving points between sub
|
||||
* sequences. The first sub-sequence is contained in (X0, X1), (Y0, Y1),
|
||||
* the second in (X1, X2), (Y1, Y2) and so on. Note that (X0, Y0) ==
|
||||
* (XOFF, YOFF) and (X[NCHUNKS], Y[NCHUNKS]) == (XLIM, YLIM).
|
||||
*
|
||||
* This function assumes that the first lines of the specified portions of
|
||||
* the two files do not match, and likewise that the last lines do not
|
||||
* match. The caller must trim matching lines from the beginning and end
|
||||
* of the portions it is going to specify.
|
||||
*/
|
||||
function _diag ($xoff, $xlim, $yoff, $ylim, $nchunks)
|
||||
{
|
||||
$flip = false;
|
||||
|
||||
if ($xlim - $xoff > $ylim - $yoff) {
|
||||
/* Things seems faster (I'm not sure I understand why) when the
|
||||
* shortest sequence is in X. */
|
||||
$flip = true;
|
||||
list ($xoff, $xlim, $yoff, $ylim)
|
||||
= array($yoff, $ylim, $xoff, $xlim);
|
||||
}
|
||||
|
||||
if ($flip) {
|
||||
for ($i = $ylim - 1; $i >= $yoff; $i--) {
|
||||
$ymatches[$this->xv[$i]][] = $i;
|
||||
}
|
||||
} else {
|
||||
for ($i = $ylim - 1; $i >= $yoff; $i--) {
|
||||
$ymatches[$this->yv[$i]][] = $i;
|
||||
}
|
||||
}
|
||||
|
||||
$this->lcs = 0;
|
||||
$this->seq[0]= $yoff - 1;
|
||||
$this->in_seq = array();
|
||||
$ymids[0] = array();
|
||||
|
||||
$numer = $xlim - $xoff + $nchunks - 1;
|
||||
$x = $xoff;
|
||||
for ($chunk = 0; $chunk < $nchunks; $chunk++) {
|
||||
if ($chunk > 0) {
|
||||
for ($i = 0; $i <= $this->lcs; $i++) {
|
||||
$ymids[$i][$chunk - 1] = $this->seq[$i];
|
||||
}
|
||||
}
|
||||
|
||||
$x1 = $xoff + (int)(($numer + ($xlim - $xoff) * $chunk) / $nchunks);
|
||||
for (; $x < $x1; $x++) {
|
||||
$line = $flip ? $this->yv[$x] : $this->xv[$x];
|
||||
if (empty($ymatches[$line])) {
|
||||
continue;
|
||||
}
|
||||
$matches = $ymatches[$line];
|
||||
reset($matches);
|
||||
while (list(, $y) = each($matches)) {
|
||||
if (empty($this->in_seq[$y])) {
|
||||
$k = $this->_lcsPos($y);
|
||||
assert($k > 0);
|
||||
$ymids[$k] = $ymids[$k - 1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (list(, $y) = each($matches)) {
|
||||
if ($y > $this->seq[$k - 1]) {
|
||||
assert($y <= $this->seq[$k]);
|
||||
/* Optimization: this is a common case: next match is
|
||||
* just replacing previous match. */
|
||||
$this->in_seq[$this->seq[$k]] = false;
|
||||
$this->seq[$k] = $y;
|
||||
$this->in_seq[$y] = 1;
|
||||
} elseif (empty($this->in_seq[$y])) {
|
||||
$k = $this->_lcsPos($y);
|
||||
assert($k > 0);
|
||||
$ymids[$k] = $ymids[$k - 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$seps[] = $flip ? array($yoff, $xoff) : array($xoff, $yoff);
|
||||
$ymid = $ymids[$this->lcs];
|
||||
for ($n = 0; $n < $nchunks - 1; $n++) {
|
||||
$x1 = $xoff + (int)(($numer + ($xlim - $xoff) * $n) / $nchunks);
|
||||
$y1 = $ymid[$n] + 1;
|
||||
$seps[] = $flip ? array($y1, $x1) : array($x1, $y1);
|
||||
}
|
||||
$seps[] = $flip ? array($ylim, $xlim) : array($xlim, $ylim);
|
||||
|
||||
return array($this->lcs, $seps);
|
||||
}
|
||||
|
||||
function _lcsPos($ypos)
|
||||
{
|
||||
$end = $this->lcs;
|
||||
if ($end == 0 || $ypos > $this->seq[$end]) {
|
||||
$this->seq[++$this->lcs] = $ypos;
|
||||
$this->in_seq[$ypos] = 1;
|
||||
return $this->lcs;
|
||||
}
|
||||
|
||||
$beg = 1;
|
||||
while ($beg < $end) {
|
||||
$mid = (int)(($beg + $end) / 2);
|
||||
if ($ypos > $this->seq[$mid]) {
|
||||
$beg = $mid + 1;
|
||||
} else {
|
||||
$end = $mid;
|
||||
}
|
||||
}
|
||||
|
||||
assert($ypos != $this->seq[$end]);
|
||||
|
||||
$this->in_seq[$this->seq[$end]] = false;
|
||||
$this->seq[$end] = $ypos;
|
||||
$this->in_seq[$ypos] = 1;
|
||||
return $end;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds LCS of two sequences.
|
||||
*
|
||||
* The results are recorded in the vectors $this->{x,y}changed[], by
|
||||
* storing a 1 in the element for each line that is an insertion or
|
||||
* deletion (ie. is not in the LCS).
|
||||
*
|
||||
* The subsequence of file 0 is (XOFF, XLIM) and likewise for file 1.
|
||||
*
|
||||
* Note that XLIM, YLIM are exclusive bounds. All line numbers are
|
||||
* origin-0 and discarded lines are not counted.
|
||||
*/
|
||||
function _compareseq ($xoff, $xlim, $yoff, $ylim)
|
||||
{
|
||||
/* Slide down the bottom initial diagonal. */
|
||||
while ($xoff < $xlim && $yoff < $ylim
|
||||
&& $this->xv[$xoff] == $this->yv[$yoff]) {
|
||||
++$xoff;
|
||||
++$yoff;
|
||||
}
|
||||
|
||||
/* Slide up the top initial diagonal. */
|
||||
while ($xlim > $xoff && $ylim > $yoff
|
||||
&& $this->xv[$xlim - 1] == $this->yv[$ylim - 1]) {
|
||||
--$xlim;
|
||||
--$ylim;
|
||||
}
|
||||
|
||||
if ($xoff == $xlim || $yoff == $ylim) {
|
||||
$lcs = 0;
|
||||
} else {
|
||||
/* This is ad hoc but seems to work well. $nchunks =
|
||||
* sqrt(min($xlim - $xoff, $ylim - $yoff) / 2.5); $nchunks =
|
||||
* max(2,min(8,(int)$nchunks)); */
|
||||
$nchunks = min(7, $xlim - $xoff, $ylim - $yoff) + 1;
|
||||
list($lcs, $seps)
|
||||
= $this->_diag($xoff, $xlim, $yoff, $ylim, $nchunks);
|
||||
}
|
||||
|
||||
if ($lcs == 0) {
|
||||
/* X and Y sequences have no common subsequence: mark all
|
||||
* changed. */
|
||||
while ($yoff < $ylim) {
|
||||
$this->ychanged[$this->yind[$yoff++]] = 1;
|
||||
}
|
||||
while ($xoff < $xlim) {
|
||||
$this->xchanged[$this->xind[$xoff++]] = 1;
|
||||
}
|
||||
} else {
|
||||
/* Use the partitions to split this problem into subproblems. */
|
||||
reset($seps);
|
||||
$pt1 = $seps[0];
|
||||
while ($pt2 = next($seps)) {
|
||||
$this->_compareseq ($pt1[0], $pt2[0], $pt1[1], $pt2[1]);
|
||||
$pt1 = $pt2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjusts inserts/deletes of identical lines to join changes as much as
|
||||
* possible.
|
||||
*
|
||||
* We do something when a run of changed lines include a line at one end
|
||||
* and has an excluded, identical line at the other. We are free to
|
||||
* choose which identical line is included. `compareseq' usually chooses
|
||||
* the one at the beginning, but usually it is cleaner to consider the
|
||||
* following identical line to be the "change".
|
||||
*
|
||||
* This is extracted verbatim from analyze.c (GNU diffutils-2.7).
|
||||
*/
|
||||
function _shiftBoundaries($lines, &$changed, $other_changed)
|
||||
{
|
||||
$i = 0;
|
||||
$j = 0;
|
||||
|
||||
assert('count($lines) == count($changed)');
|
||||
$len = count($lines);
|
||||
$other_len = count($other_changed);
|
||||
|
||||
while (1) {
|
||||
/* Scan forward to find the beginning of another run of
|
||||
* changes. Also keep track of the corresponding point in the
|
||||
* other file.
|
||||
*
|
||||
* Throughout this code, $i and $j are adjusted together so that
|
||||
* the first $i elements of $changed and the first $j elements of
|
||||
* $other_changed both contain the same number of zeros (unchanged
|
||||
* lines).
|
||||
*
|
||||
* Furthermore, $j is always kept so that $j == $other_len or
|
||||
* $other_changed[$j] == false. */
|
||||
while ($j < $other_len && $other_changed[$j]) {
|
||||
$j++;
|
||||
}
|
||||
|
||||
while ($i < $len && ! $changed[$i]) {
|
||||
assert('$j < $other_len && ! $other_changed[$j]');
|
||||
$i++; $j++;
|
||||
while ($j < $other_len && $other_changed[$j]) {
|
||||
$j++;
|
||||
}
|
||||
}
|
||||
|
||||
if ($i == $len) {
|
||||
break;
|
||||
}
|
||||
|
||||
$start = $i;
|
||||
|
||||
/* Find the end of this run of changes. */
|
||||
while (++$i < $len && $changed[$i]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
do {
|
||||
/* Record the length of this run of changes, so that we can
|
||||
* later determine whether the run has grown. */
|
||||
$runlength = $i - $start;
|
||||
|
||||
/* Move the changed region back, so long as the previous
|
||||
* unchanged line matches the last changed one. This merges
|
||||
* with previous changed regions. */
|
||||
while ($start > 0 && $lines[$start - 1] == $lines[$i - 1]) {
|
||||
$changed[--$start] = 1;
|
||||
$changed[--$i] = false;
|
||||
while ($start > 0 && $changed[$start - 1]) {
|
||||
$start--;
|
||||
}
|
||||
assert('$j > 0');
|
||||
while ($other_changed[--$j]) {
|
||||
continue;
|
||||
}
|
||||
assert('$j >= 0 && !$other_changed[$j]');
|
||||
}
|
||||
|
||||
/* Set CORRESPONDING to the end of the changed run, at the
|
||||
* last point where it corresponds to a changed run in the
|
||||
* other file. CORRESPONDING == LEN means no such point has
|
||||
* been found. */
|
||||
$corresponding = $j < $other_len ? $i : $len;
|
||||
|
||||
/* Move the changed region forward, so long as the first
|
||||
* changed line matches the following unchanged one. This
|
||||
* merges with following changed regions. Do this second, so
|
||||
* that if there are no merges, the changed region is moved
|
||||
* forward as far as possible. */
|
||||
while ($i < $len && $lines[$start] == $lines[$i]) {
|
||||
$changed[$start++] = false;
|
||||
$changed[$i++] = 1;
|
||||
while ($i < $len && $changed[$i]) {
|
||||
$i++;
|
||||
}
|
||||
|
||||
assert('$j < $other_len && ! $other_changed[$j]');
|
||||
$j++;
|
||||
if ($j < $other_len && $other_changed[$j]) {
|
||||
$corresponding = $i;
|
||||
while ($j < $other_len && $other_changed[$j]) {
|
||||
$j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
} while ($runlength != $i - $start);
|
||||
|
||||
/* If possible, move the fully-merged run of changes back to a
|
||||
* corresponding run in the other file. */
|
||||
while ($corresponding < $i) {
|
||||
$changed[--$start] = 1;
|
||||
$changed[--$i] = 0;
|
||||
assert('$j > 0');
|
||||
while ($other_changed[--$j]) {
|
||||
continue;
|
||||
}
|
||||
assert('$j >= 0 && !$other_changed[$j]');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,162 @@
|
||||
<?php
|
||||
/**
|
||||
* Class used internally by Diff to actually compute the diffs.
|
||||
*
|
||||
* This class uses the Unix `diff` program via shell_exec to compute the
|
||||
* differences between the two input arrays.
|
||||
*
|
||||
* Copyright 2007-2010 The Horde Project (http://www.horde.org/)
|
||||
*
|
||||
* See the enclosed file COPYING for license information (LGPL). If you did
|
||||
* not receive this file, see http://opensource.org/licenses/lgpl-license.php.
|
||||
*
|
||||
* @author Milian Wolff <mail@milianw.de>
|
||||
* @package Text_Diff
|
||||
* @since 0.3.0
|
||||
*/
|
||||
class Text_Diff_Engine_shell {
|
||||
|
||||
/**
|
||||
* Path to the diff executable
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
var $_diffCommand = 'diff';
|
||||
|
||||
/**
|
||||
* Returns the array of differences.
|
||||
*
|
||||
* @param array $from_lines lines of text from old file
|
||||
* @param array $to_lines lines of text from new file
|
||||
*
|
||||
* @return array all changes made (array with Text_Diff_Op_* objects)
|
||||
*/
|
||||
function diff($from_lines, $to_lines)
|
||||
{
|
||||
array_walk($from_lines, array('Text_Diff', 'trimNewlines'));
|
||||
array_walk($to_lines, array('Text_Diff', 'trimNewlines'));
|
||||
|
||||
$temp_dir = Text_Diff::_getTempDir();
|
||||
|
||||
// Execute gnu diff or similar to get a standard diff file.
|
||||
$from_file = tempnam($temp_dir, 'Text_Diff');
|
||||
$to_file = tempnam($temp_dir, 'Text_Diff');
|
||||
$fp = fopen($from_file, 'w');
|
||||
fwrite($fp, implode("\n", $from_lines));
|
||||
fclose($fp);
|
||||
$fp = fopen($to_file, 'w');
|
||||
fwrite($fp, implode("\n", $to_lines));
|
||||
fclose($fp);
|
||||
$diff = shell_exec($this->_diffCommand . ' ' . $from_file . ' ' . $to_file);
|
||||
unlink($from_file);
|
||||
unlink($to_file);
|
||||
|
||||
if (is_null($diff)) {
|
||||
// No changes were made
|
||||
return array(new Text_Diff_Op_copy($from_lines));
|
||||
}
|
||||
|
||||
$from_line_no = 1;
|
||||
$to_line_no = 1;
|
||||
$edits = array();
|
||||
|
||||
// Get changed lines by parsing something like:
|
||||
// 0a1,2
|
||||
// 1,2c4,6
|
||||
// 1,5d6
|
||||
preg_match_all('#^(\d+)(?:,(\d+))?([adc])(\d+)(?:,(\d+))?$#m', $diff,
|
||||
$matches, PREG_SET_ORDER);
|
||||
|
||||
foreach ($matches as $match) {
|
||||
if (!isset($match[5])) {
|
||||
// This paren is not set every time (see regex).
|
||||
$match[5] = false;
|
||||
}
|
||||
|
||||
if ($match[3] == 'a') {
|
||||
$from_line_no--;
|
||||
}
|
||||
|
||||
if ($match[3] == 'd') {
|
||||
$to_line_no--;
|
||||
}
|
||||
|
||||
if ($from_line_no < $match[1] || $to_line_no < $match[4]) {
|
||||
// copied lines
|
||||
assert('$match[1] - $from_line_no == $match[4] - $to_line_no');
|
||||
array_push($edits,
|
||||
new Text_Diff_Op_copy(
|
||||
$this->_getLines($from_lines, $from_line_no, $match[1] - 1),
|
||||
$this->_getLines($to_lines, $to_line_no, $match[4] - 1)));
|
||||
}
|
||||
|
||||
switch ($match[3]) {
|
||||
case 'd':
|
||||
// deleted lines
|
||||
array_push($edits,
|
||||
new Text_Diff_Op_delete(
|
||||
$this->_getLines($from_lines, $from_line_no, $match[2])));
|
||||
$to_line_no++;
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
// changed lines
|
||||
array_push($edits,
|
||||
new Text_Diff_Op_change(
|
||||
$this->_getLines($from_lines, $from_line_no, $match[2]),
|
||||
$this->_getLines($to_lines, $to_line_no, $match[5])));
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
// added lines
|
||||
array_push($edits,
|
||||
new Text_Diff_Op_add(
|
||||
$this->_getLines($to_lines, $to_line_no, $match[5])));
|
||||
$from_line_no++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($from_lines)) {
|
||||
// Some lines might still be pending. Add them as copied
|
||||
array_push($edits,
|
||||
new Text_Diff_Op_copy(
|
||||
$this->_getLines($from_lines, $from_line_no,
|
||||
$from_line_no + count($from_lines) - 1),
|
||||
$this->_getLines($to_lines, $to_line_no,
|
||||
$to_line_no + count($to_lines) - 1)));
|
||||
}
|
||||
|
||||
return $edits;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get lines from either the old or new text
|
||||
*
|
||||
* @access private
|
||||
*
|
||||
* @param array &$text_lines Either $from_lines or $to_lines
|
||||
* @param int &$line_no Current line number
|
||||
* @param int $end Optional end line, when we want to chop more
|
||||
* than one line.
|
||||
*
|
||||
* @return array The chopped lines
|
||||
*/
|
||||
function _getLines(&$text_lines, &$line_no, $end = false)
|
||||
{
|
||||
if (!empty($end)) {
|
||||
$lines = array();
|
||||
// We can shift even more
|
||||
while ($line_no <= $end) {
|
||||
array_push($lines, array_shift($text_lines));
|
||||
$line_no++;
|
||||
}
|
||||
} else {
|
||||
$lines = array(array_shift($text_lines));
|
||||
$line_no++;
|
||||
}
|
||||
|
||||
return $lines;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,248 @@
|
||||
<?php
|
||||
/**
|
||||
* Parses unified or context diffs output from eg. the diff utility.
|
||||
*
|
||||
* Example:
|
||||
* <code>
|
||||
* $patch = file_get_contents('example.patch');
|
||||
* $diff = new Text_Diff('string', array($patch));
|
||||
* $renderer = new Text_Diff_Renderer_inline();
|
||||
* echo $renderer->render($diff);
|
||||
* </code>
|
||||
*
|
||||
* Copyright 2005 Örjan Persson <o@42mm.org>
|
||||
* Copyright 2005-2010 The Horde Project (http://www.horde.org/)
|
||||
*
|
||||
* See the enclosed file COPYING for license information (LGPL). If you did
|
||||
* not receive this file, see http://opensource.org/licenses/lgpl-license.php.
|
||||
*
|
||||
* @author Örjan Persson <o@42mm.org>
|
||||
* @package Text_Diff
|
||||
* @since 0.2.0
|
||||
*/
|
||||
class Text_Diff_Engine_string {
|
||||
|
||||
/**
|
||||
* Parses a unified or context diff.
|
||||
*
|
||||
* First param contains the whole diff and the second can be used to force
|
||||
* a specific diff type. If the second parameter is 'autodetect', the
|
||||
* diff will be examined to find out which type of diff this is.
|
||||
*
|
||||
* @param string $diff The diff content.
|
||||
* @param string $mode The diff mode of the content in $diff. One of
|
||||
* 'context', 'unified', or 'autodetect'.
|
||||
*
|
||||
* @return array List of all diff operations.
|
||||
*/
|
||||
function diff($diff, $mode = 'autodetect')
|
||||
{
|
||||
// Detect line breaks.
|
||||
$lnbr = "\n";
|
||||
if (strpos($diff, "\r\n") !== false) {
|
||||
$lnbr = "\r\n";
|
||||
} elseif (strpos($diff, "\r") !== false) {
|
||||
$lnbr = "\r";
|
||||
}
|
||||
|
||||
// Make sure we have a line break at the EOF.
|
||||
if (substr($diff, -strlen($lnbr)) != $lnbr) {
|
||||
$diff .= $lnbr;
|
||||
}
|
||||
|
||||
if ($mode != 'autodetect' && $mode != 'context' && $mode != 'unified') {
|
||||
return PEAR::raiseError('Type of diff is unsupported');
|
||||
}
|
||||
|
||||
if ($mode == 'autodetect') {
|
||||
$context = strpos($diff, '***');
|
||||
$unified = strpos($diff, '---');
|
||||
if ($context === $unified) {
|
||||
return PEAR::raiseError('Type of diff could not be detected');
|
||||
} elseif ($context === false || $unified === false) {
|
||||
$mode = $context !== false ? 'context' : 'unified';
|
||||
} else {
|
||||
$mode = $context < $unified ? 'context' : 'unified';
|
||||
}
|
||||
}
|
||||
|
||||
// Split by new line and remove the diff header, if there is one.
|
||||
$diff = explode($lnbr, $diff);
|
||||
if (($mode == 'context' && strpos($diff[0], '***') === 0) ||
|
||||
($mode == 'unified' && strpos($diff[0], '---') === 0)) {
|
||||
array_shift($diff);
|
||||
array_shift($diff);
|
||||
}
|
||||
|
||||
if ($mode == 'context') {
|
||||
return $this->parseContextDiff($diff);
|
||||
} else {
|
||||
return $this->parseUnifiedDiff($diff);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses an array containing the unified diff.
|
||||
*
|
||||
* @param array $diff Array of lines.
|
||||
*
|
||||
* @return array List of all diff operations.
|
||||
*/
|
||||
function parseUnifiedDiff($diff)
|
||||
{
|
||||
$edits = array();
|
||||
$end = count($diff) - 1;
|
||||
for ($i = 0; $i < $end;) {
|
||||
$diff1 = array();
|
||||
switch (substr($diff[$i], 0, 1)) {
|
||||
case ' ':
|
||||
do {
|
||||
$diff1[] = substr($diff[$i], 1);
|
||||
} while (++$i < $end && substr($diff[$i], 0, 1) == ' ');
|
||||
$edits[] = &new Text_Diff_Op_copy($diff1);
|
||||
break;
|
||||
|
||||
case '+':
|
||||
// get all new lines
|
||||
do {
|
||||
$diff1[] = substr($diff[$i], 1);
|
||||
} while (++$i < $end && substr($diff[$i], 0, 1) == '+');
|
||||
$edits[] = &new Text_Diff_Op_add($diff1);
|
||||
break;
|
||||
|
||||
case '-':
|
||||
// get changed or removed lines
|
||||
$diff2 = array();
|
||||
do {
|
||||
$diff1[] = substr($diff[$i], 1);
|
||||
} while (++$i < $end && substr($diff[$i], 0, 1) == '-');
|
||||
|
||||
while ($i < $end && substr($diff[$i], 0, 1) == '+') {
|
||||
$diff2[] = substr($diff[$i++], 1);
|
||||
}
|
||||
if (count($diff2) == 0) {
|
||||
$edits[] = &new Text_Diff_Op_delete($diff1);
|
||||
} else {
|
||||
$edits[] = &new Text_Diff_Op_change($diff1, $diff2);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
$i++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $edits;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses an array containing the context diff.
|
||||
*
|
||||
* @param array $diff Array of lines.
|
||||
*
|
||||
* @return array List of all diff operations.
|
||||
*/
|
||||
function parseContextDiff(&$diff)
|
||||
{
|
||||
$edits = array();
|
||||
$i = $max_i = $j = $max_j = 0;
|
||||
$end = count($diff) - 1;
|
||||
while ($i < $end && $j < $end) {
|
||||
while ($i >= $max_i && $j >= $max_j) {
|
||||
// Find the boundaries of the diff output of the two files
|
||||
for ($i = $j;
|
||||
$i < $end && substr($diff[$i], 0, 3) == '***';
|
||||
$i++);
|
||||
for ($max_i = $i;
|
||||
$max_i < $end && substr($diff[$max_i], 0, 3) != '---';
|
||||
$max_i++);
|
||||
for ($j = $max_i;
|
||||
$j < $end && substr($diff[$j], 0, 3) == '---';
|
||||
$j++);
|
||||
for ($max_j = $j;
|
||||
$max_j < $end && substr($diff[$max_j], 0, 3) != '***';
|
||||
$max_j++);
|
||||
}
|
||||
|
||||
// find what hasn't been changed
|
||||
$array = array();
|
||||
while ($i < $max_i &&
|
||||
$j < $max_j &&
|
||||
strcmp($diff[$i], $diff[$j]) == 0) {
|
||||
$array[] = substr($diff[$i], 2);
|
||||
$i++;
|
||||
$j++;
|
||||
}
|
||||
|
||||
while ($i < $max_i && ($max_j-$j) <= 1) {
|
||||
if ($diff[$i] != '' && substr($diff[$i], 0, 1) != ' ') {
|
||||
break;
|
||||
}
|
||||
$array[] = substr($diff[$i++], 2);
|
||||
}
|
||||
|
||||
while ($j < $max_j && ($max_i-$i) <= 1) {
|
||||
if ($diff[$j] != '' && substr($diff[$j], 0, 1) != ' ') {
|
||||
break;
|
||||
}
|
||||
$array[] = substr($diff[$j++], 2);
|
||||
}
|
||||
if (count($array) > 0) {
|
||||
$edits[] = &new Text_Diff_Op_copy($array);
|
||||
}
|
||||
|
||||
if ($i < $max_i) {
|
||||
$diff1 = array();
|
||||
switch (substr($diff[$i], 0, 1)) {
|
||||
case '!':
|
||||
$diff2 = array();
|
||||
do {
|
||||
$diff1[] = substr($diff[$i], 2);
|
||||
if ($j < $max_j && substr($diff[$j], 0, 1) == '!') {
|
||||
$diff2[] = substr($diff[$j++], 2);
|
||||
}
|
||||
} while (++$i < $max_i && substr($diff[$i], 0, 1) == '!');
|
||||
$edits[] = &new Text_Diff_Op_change($diff1, $diff2);
|
||||
break;
|
||||
|
||||
case '+':
|
||||
do {
|
||||
$diff1[] = substr($diff[$i], 2);
|
||||
} while (++$i < $max_i && substr($diff[$i], 0, 1) == '+');
|
||||
$edits[] = &new Text_Diff_Op_add($diff1);
|
||||
break;
|
||||
|
||||
case '-':
|
||||
do {
|
||||
$diff1[] = substr($diff[$i], 2);
|
||||
} while (++$i < $max_i && substr($diff[$i], 0, 1) == '-');
|
||||
$edits[] = &new Text_Diff_Op_delete($diff1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($j < $max_j) {
|
||||
$diff2 = array();
|
||||
switch (substr($diff[$j], 0, 1)) {
|
||||
case '+':
|
||||
do {
|
||||
$diff2[] = substr($diff[$j++], 2);
|
||||
} while ($j < $max_j && substr($diff[$j], 0, 1) == '+');
|
||||
$edits[] = &new Text_Diff_Op_add($diff2);
|
||||
break;
|
||||
|
||||
case '-':
|
||||
do {
|
||||
$diff2[] = substr($diff[$j++], 2);
|
||||
} while ($j < $max_j && substr($diff[$j], 0, 1) == '-');
|
||||
$edits[] = &new Text_Diff_Op_delete($diff2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $edits;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
/**
|
||||
* Class used internally by Diff to actually compute the diffs.
|
||||
*
|
||||
* This class uses the xdiff PECL package (http://pecl.php.net/package/xdiff)
|
||||
* to compute the differences between the two input arrays.
|
||||
*
|
||||
* Copyright 2004-2010 The Horde Project (http://www.horde.org/)
|
||||
*
|
||||
* See the enclosed file COPYING for license information (LGPL). If you did
|
||||
* not receive this file, see http://opensource.org/licenses/lgpl-license.php.
|
||||
*
|
||||
* @author Jon Parise <jon@horde.org>
|
||||
* @package Text_Diff
|
||||
*/
|
||||
class Text_Diff_Engine_xdiff {
|
||||
|
||||
/**
|
||||
*/
|
||||
function diff($from_lines, $to_lines)
|
||||
{
|
||||
array_walk($from_lines, array('Text_Diff', 'trimNewlines'));
|
||||
array_walk($to_lines, array('Text_Diff', 'trimNewlines'));
|
||||
|
||||
/* Convert the two input arrays into strings for xdiff processing. */
|
||||
$from_string = implode("\n", $from_lines);
|
||||
$to_string = implode("\n", $to_lines);
|
||||
|
||||
/* Diff the two strings and convert the result to an array. */
|
||||
$diff = xdiff_string_diff($from_string, $to_string, count($to_lines));
|
||||
$diff = explode("\n", $diff);
|
||||
|
||||
/* Walk through the diff one line at a time. We build the $edits
|
||||
* array of diff operations by reading the first character of the
|
||||
* xdiff output (which is in the "unified diff" format).
|
||||
*
|
||||
* Note that we don't have enough information to detect "changed"
|
||||
* lines using this approach, so we can't add Text_Diff_Op_changed
|
||||
* instances to the $edits array. The result is still perfectly
|
||||
* valid, albeit a little less descriptive and efficient. */
|
||||
$edits = array();
|
||||
foreach ($diff as $line) {
|
||||
if (!strlen($line)) {
|
||||
continue;
|
||||
}
|
||||
switch ($line[0]) {
|
||||
case ' ':
|
||||
$edits[] = &new Text_Diff_Op_copy(array(substr($line, 1)));
|
||||
break;
|
||||
|
||||
case '+':
|
||||
$edits[] = &new Text_Diff_Op_add(array(substr($line, 1)));
|
||||
break;
|
||||
|
||||
case '-':
|
||||
$edits[] = &new Text_Diff_Op_delete(array(substr($line, 1)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $edits;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,235 @@
|
||||
<?php
|
||||
/**
|
||||
* A class to render Diffs in different formats.
|
||||
*
|
||||
* This class renders the diff in classic diff format. It is intended that
|
||||
* this class be customized via inheritance, to obtain fancier outputs.
|
||||
*
|
||||
* Copyright 2004-2010 The Horde Project (http://www.horde.org/)
|
||||
*
|
||||
* See the enclosed file COPYING for license information (LGPL). If you did
|
||||
* not receive this file, see http://opensource.org/licenses/lgpl-license.php.
|
||||
*
|
||||
* @package Text_Diff
|
||||
*/
|
||||
class Text_Diff_Renderer {
|
||||
|
||||
/**
|
||||
* Number of leading context "lines" to preserve.
|
||||
*
|
||||
* This should be left at zero for this class, but subclasses may want to
|
||||
* set this to other values.
|
||||
*/
|
||||
var $_leading_context_lines = 0;
|
||||
|
||||
/**
|
||||
* Number of trailing context "lines" to preserve.
|
||||
*
|
||||
* This should be left at zero for this class, but subclasses may want to
|
||||
* set this to other values.
|
||||
*/
|
||||
var $_trailing_context_lines = 0;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
function Text_Diff_Renderer($params = array())
|
||||
{
|
||||
foreach ($params as $param => $value) {
|
||||
$v = '_' . $param;
|
||||
if (isset($this->$v)) {
|
||||
$this->$v = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get any renderer parameters.
|
||||
*
|
||||
* @return array All parameters of this renderer object.
|
||||
*/
|
||||
function getParams()
|
||||
{
|
||||
$params = array();
|
||||
foreach (get_object_vars($this) as $k => $v) {
|
||||
if ($k[0] == '_') {
|
||||
$params[substr($k, 1)] = $v;
|
||||
}
|
||||
}
|
||||
|
||||
return $params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a diff.
|
||||
*
|
||||
* @param Text_Diff $diff A Text_Diff object.
|
||||
*
|
||||
* @return string The formatted output.
|
||||
*/
|
||||
function render($diff)
|
||||
{
|
||||
$xi = $yi = 1;
|
||||
$block = false;
|
||||
$context = array();
|
||||
|
||||
$nlead = $this->_leading_context_lines;
|
||||
$ntrail = $this->_trailing_context_lines;
|
||||
|
||||
$output = $this->_startDiff();
|
||||
|
||||
$diffs = $diff->getDiff();
|
||||
foreach ($diffs as $i => $edit) {
|
||||
/* If these are unchanged (copied) lines, and we want to keep
|
||||
* leading or trailing context lines, extract them from the copy
|
||||
* block. */
|
||||
if (is_a($edit, 'Text_Diff_Op_copy')) {
|
||||
/* Do we have any diff blocks yet? */
|
||||
if (is_array($block)) {
|
||||
/* How many lines to keep as context from the copy
|
||||
* block. */
|
||||
$keep = $i == count($diffs) - 1 ? $ntrail : $nlead + $ntrail;
|
||||
if (count($edit->orig) <= $keep) {
|
||||
/* We have less lines in the block than we want for
|
||||
* context => keep the whole block. */
|
||||
$block[] = $edit;
|
||||
} else {
|
||||
if ($ntrail) {
|
||||
/* Create a new block with as many lines as we need
|
||||
* for the trailing context. */
|
||||
$context = array_slice($edit->orig, 0, $ntrail);
|
||||
$block[] = &new Text_Diff_Op_copy($context);
|
||||
}
|
||||
/* @todo */
|
||||
$output .= $this->_block($x0, $ntrail + $xi - $x0,
|
||||
$y0, $ntrail + $yi - $y0,
|
||||
$block);
|
||||
$block = false;
|
||||
}
|
||||
}
|
||||
/* Keep the copy block as the context for the next block. */
|
||||
$context = $edit->orig;
|
||||
} else {
|
||||
/* Don't we have any diff blocks yet? */
|
||||
if (!is_array($block)) {
|
||||
/* Extract context lines from the preceding copy block. */
|
||||
$context = array_slice($context, count($context) - $nlead);
|
||||
$x0 = $xi - count($context);
|
||||
$y0 = $yi - count($context);
|
||||
$block = array();
|
||||
if ($context) {
|
||||
$block[] = &new Text_Diff_Op_copy($context);
|
||||
}
|
||||
}
|
||||
$block[] = $edit;
|
||||
}
|
||||
|
||||
if ($edit->orig) {
|
||||
$xi += count($edit->orig);
|
||||
}
|
||||
if ($edit->final) {
|
||||
$yi += count($edit->final);
|
||||
}
|
||||
}
|
||||
|
||||
if (is_array($block)) {
|
||||
$output .= $this->_block($x0, $xi - $x0,
|
||||
$y0, $yi - $y0,
|
||||
$block);
|
||||
}
|
||||
|
||||
return $output . $this->_endDiff();
|
||||
}
|
||||
|
||||
function _block($xbeg, $xlen, $ybeg, $ylen, &$edits)
|
||||
{
|
||||
$output = $this->_startBlock($this->_blockHeader($xbeg, $xlen, $ybeg, $ylen));
|
||||
|
||||
foreach ($edits as $edit) {
|
||||
switch (strtolower(get_class($edit))) {
|
||||
case 'text_diff_op_copy':
|
||||
$output .= $this->_context($edit->orig);
|
||||
break;
|
||||
|
||||
case 'text_diff_op_add':
|
||||
$output .= $this->_added($edit->final);
|
||||
break;
|
||||
|
||||
case 'text_diff_op_delete':
|
||||
$output .= $this->_deleted($edit->orig);
|
||||
break;
|
||||
|
||||
case 'text_diff_op_change':
|
||||
$output .= $this->_changed($edit->orig, $edit->final);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $output . $this->_endBlock();
|
||||
}
|
||||
|
||||
function _startDiff()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
function _endDiff()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
function _blockHeader($xbeg, $xlen, $ybeg, $ylen)
|
||||
{
|
||||
if ($xlen > 1) {
|
||||
$xbeg .= ',' . ($xbeg + $xlen - 1);
|
||||
}
|
||||
if ($ylen > 1) {
|
||||
$ybeg .= ',' . ($ybeg + $ylen - 1);
|
||||
}
|
||||
|
||||
// this matches the GNU Diff behaviour
|
||||
if ($xlen && !$ylen) {
|
||||
$ybeg--;
|
||||
} elseif (!$xlen) {
|
||||
$xbeg--;
|
||||
}
|
||||
|
||||
return $xbeg . ($xlen ? ($ylen ? 'c' : 'd') : 'a') . $ybeg;
|
||||
}
|
||||
|
||||
function _startBlock($header)
|
||||
{
|
||||
return $header . "\n";
|
||||
}
|
||||
|
||||
function _endBlock()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
function _lines($lines, $prefix = ' ')
|
||||
{
|
||||
return $prefix . implode("\n$prefix", $lines) . "\n";
|
||||
}
|
||||
|
||||
function _context($lines)
|
||||
{
|
||||
return $this->_lines($lines, ' ');
|
||||
}
|
||||
|
||||
function _added($lines)
|
||||
{
|
||||
return $this->_lines($lines, '> ');
|
||||
}
|
||||
|
||||
function _deleted($lines)
|
||||
{
|
||||
return $this->_lines($lines, '< ');
|
||||
}
|
||||
|
||||
function _changed($orig, $final)
|
||||
{
|
||||
return $this->_deleted($orig) . "---\n" . $this->_added($final);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,206 @@
|
||||
<?php
|
||||
/**
|
||||
* "Inline" diff renderer.
|
||||
*
|
||||
* Copyright 2004-2010 The Horde Project (http://www.horde.org/)
|
||||
*
|
||||
* See the enclosed file COPYING for license information (LGPL). If you did
|
||||
* not receive this file, see http://opensource.org/licenses/lgpl-license.php.
|
||||
*
|
||||
* @author Ciprian Popovici
|
||||
* @package Text_Diff
|
||||
*/
|
||||
|
||||
/** Text_Diff_Renderer */
|
||||
|
||||
// WP #7391
|
||||
require_once dirname(dirname(__FILE__)) . '/Renderer.php';
|
||||
|
||||
/**
|
||||
* "Inline" diff renderer.
|
||||
*
|
||||
* This class renders diffs in the Wiki-style "inline" format.
|
||||
*
|
||||
* @author Ciprian Popovici
|
||||
* @package Text_Diff
|
||||
*/
|
||||
class Text_Diff_Renderer_inline extends Text_Diff_Renderer {
|
||||
|
||||
/**
|
||||
* Number of leading context "lines" to preserve.
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
var $_leading_context_lines = 10000;
|
||||
|
||||
/**
|
||||
* Number of trailing context "lines" to preserve.
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
var $_trailing_context_lines = 10000;
|
||||
|
||||
/**
|
||||
* Prefix for inserted text.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
var $_ins_prefix = '<ins>';
|
||||
|
||||
/**
|
||||
* Suffix for inserted text.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
var $_ins_suffix = '</ins>';
|
||||
|
||||
/**
|
||||
* Prefix for deleted text.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
var $_del_prefix = '<del>';
|
||||
|
||||
/**
|
||||
* Suffix for deleted text.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
var $_del_suffix = '</del>';
|
||||
|
||||
/**
|
||||
* Header for each change block.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
var $_block_header = '';
|
||||
|
||||
/**
|
||||
* Whether to split down to character-level.
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
var $_split_characters = false;
|
||||
|
||||
/**
|
||||
* What are we currently splitting on? Used to recurse to show word-level
|
||||
* or character-level changes.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
var $_split_level = 'lines';
|
||||
|
||||
function _blockHeader($xbeg, $xlen, $ybeg, $ylen)
|
||||
{
|
||||
return $this->_block_header;
|
||||
}
|
||||
|
||||
function _startBlock($header)
|
||||
{
|
||||
return $header;
|
||||
}
|
||||
|
||||
function _lines($lines, $prefix = ' ', $encode = true)
|
||||
{
|
||||
if ($encode) {
|
||||
array_walk($lines, array(&$this, '_encode'));
|
||||
}
|
||||
|
||||
if ($this->_split_level == 'lines') {
|
||||
return implode("\n", $lines) . "\n";
|
||||
} else {
|
||||
return implode('', $lines);
|
||||
}
|
||||
}
|
||||
|
||||
function _added($lines)
|
||||
{
|
||||
array_walk($lines, array(&$this, '_encode'));
|
||||
$lines[0] = $this->_ins_prefix . $lines[0];
|
||||
$lines[count($lines) - 1] .= $this->_ins_suffix;
|
||||
return $this->_lines($lines, ' ', false);
|
||||
}
|
||||
|
||||
function _deleted($lines, $words = false)
|
||||
{
|
||||
array_walk($lines, array(&$this, '_encode'));
|
||||
$lines[0] = $this->_del_prefix . $lines[0];
|
||||
$lines[count($lines) - 1] .= $this->_del_suffix;
|
||||
return $this->_lines($lines, ' ', false);
|
||||
}
|
||||
|
||||
function _changed($orig, $final)
|
||||
{
|
||||
/* If we've already split on characters, just display. */
|
||||
if ($this->_split_level == 'characters') {
|
||||
return $this->_deleted($orig)
|
||||
. $this->_added($final);
|
||||
}
|
||||
|
||||
/* If we've already split on words, just display. */
|
||||
if ($this->_split_level == 'words') {
|
||||
$prefix = '';
|
||||
while ($orig[0] !== false && $final[0] !== false &&
|
||||
substr($orig[0], 0, 1) == ' ' &&
|
||||
substr($final[0], 0, 1) == ' ') {
|
||||
$prefix .= substr($orig[0], 0, 1);
|
||||
$orig[0] = substr($orig[0], 1);
|
||||
$final[0] = substr($final[0], 1);
|
||||
}
|
||||
return $prefix . $this->_deleted($orig) . $this->_added($final);
|
||||
}
|
||||
|
||||
$text1 = implode("\n", $orig);
|
||||
$text2 = implode("\n", $final);
|
||||
|
||||
/* Non-printing newline marker. */
|
||||
$nl = "\0";
|
||||
|
||||
if ($this->_split_characters) {
|
||||
$diff = new Text_Diff('native',
|
||||
array(preg_split('//', $text1),
|
||||
preg_split('//', $text2)));
|
||||
} else {
|
||||
/* We want to split on word boundaries, but we need to preserve
|
||||
* whitespace as well. Therefore we split on words, but include
|
||||
* all blocks of whitespace in the wordlist. */
|
||||
$diff = new Text_Diff('native',
|
||||
array($this->_splitOnWords($text1, $nl),
|
||||
$this->_splitOnWords($text2, $nl)));
|
||||
}
|
||||
|
||||
/* Get the diff in inline format. */
|
||||
$renderer = new Text_Diff_Renderer_inline
|
||||
(array_merge($this->getParams(),
|
||||
array('split_level' => $this->_split_characters ? 'characters' : 'words')));
|
||||
|
||||
/* Run the diff and get the output. */
|
||||
return str_replace($nl, "\n", $renderer->render($diff)) . "\n";
|
||||
}
|
||||
|
||||
function _splitOnWords($string, $newlineEscape = "\n")
|
||||
{
|
||||
// Ignore \0; otherwise the while loop will never finish.
|
||||
$string = str_replace("\0", '', $string);
|
||||
|
||||
$words = array();
|
||||
$length = strlen($string);
|
||||
$pos = 0;
|
||||
|
||||
while ($pos < $length) {
|
||||
// Eat a word with any preceding whitespace.
|
||||
$spaces = strspn(substr($string, $pos), " \n");
|
||||
$nextpos = strcspn(substr($string, $pos + $spaces), " \n");
|
||||
$words[] = str_replace("\n", $newlineEscape, substr($string, $pos, $spaces + $nextpos));
|
||||
$pos += $spaces + $nextpos;
|
||||
}
|
||||
|
||||
return $words;
|
||||
}
|
||||
|
||||
function _encode(&$string)
|
||||
{
|
||||
$string = htmlspecialchars($string);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,378 @@
|
||||
<?php
|
||||
/**
|
||||
* Admin Bar
|
||||
*
|
||||
* This code handles the building and rendering of the press bar.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Instantiate the admin bar object and set it up as a global for access elsewhere.
|
||||
*
|
||||
* To hide the admin bar, you're looking in the wrong place. Unhooking this function will not
|
||||
* properly remove the admin bar. For that, use show_admin_bar(false) or the show_admin_bar filter.
|
||||
*
|
||||
* @since 3.1.0
|
||||
* @access private
|
||||
* @return bool Whether the admin bar was successfully initialized.
|
||||
*/
|
||||
function _wp_admin_bar_init() {
|
||||
global $wp_admin_bar;
|
||||
|
||||
if ( ! is_admin_bar_showing() )
|
||||
return false;
|
||||
|
||||
/* Load the admin bar class code ready for instantiation */
|
||||
require( ABSPATH . WPINC . '/class-wp-admin-bar.php' );
|
||||
|
||||
/* Instantiate the admin bar */
|
||||
$admin_bar_class = apply_filters( 'wp_admin_bar_class', 'WP_Admin_Bar' );
|
||||
if ( class_exists( $admin_bar_class ) )
|
||||
$wp_admin_bar = new $admin_bar_class;
|
||||
else
|
||||
return false;
|
||||
|
||||
$wp_admin_bar->initialize();
|
||||
$wp_admin_bar->add_menus();
|
||||
|
||||
return true;
|
||||
}
|
||||
add_action( 'init', '_wp_admin_bar_init' ); // Don't remove. Wrong way to disable.
|
||||
|
||||
/**
|
||||
* Render the admin bar to the page based on the $wp_admin_bar->menu member var.
|
||||
* This is called very late on the footer actions so that it will render after anything else being
|
||||
* added to the footer.
|
||||
*
|
||||
* It includes the action "admin_bar_menu" which should be used to hook in and
|
||||
* add new menus to the admin bar. That way you can be sure that you are adding at most optimal point,
|
||||
* right before the admin bar is rendered. This also gives you access to the $post global, among others.
|
||||
*
|
||||
* @since 3.1.0
|
||||
*/
|
||||
function wp_admin_bar_render() {
|
||||
global $wp_admin_bar;
|
||||
|
||||
if ( ! is_admin_bar_showing() || ! is_object( $wp_admin_bar ) )
|
||||
return false;
|
||||
|
||||
$wp_admin_bar->load_user_locale_translations();
|
||||
|
||||
do_action_ref_array( 'admin_bar_menu', array( &$wp_admin_bar ) );
|
||||
|
||||
do_action( 'wp_before_admin_bar_render' );
|
||||
|
||||
$wp_admin_bar->render();
|
||||
|
||||
do_action( 'wp_after_admin_bar_render' );
|
||||
|
||||
$wp_admin_bar->unload_user_locale_translations();
|
||||
}
|
||||
add_action( 'wp_footer', 'wp_admin_bar_render', 1000 );
|
||||
add_action( 'admin_footer', 'wp_admin_bar_render', 1000 );
|
||||
|
||||
/**
|
||||
* Add the "My Account" menu and all submenus.
|
||||
*
|
||||
* @since 3.1.0
|
||||
*/
|
||||
function wp_admin_bar_my_account_menu() {
|
||||
global $wp_admin_bar, $user_identity;
|
||||
|
||||
$user_id = get_current_user_id();
|
||||
|
||||
if ( 0 != $user_id ) {
|
||||
/* Add the 'My Account' menu */
|
||||
$avatar = get_avatar( get_current_user_id(), 16 );
|
||||
$id = ( ! empty( $avatar ) ) ? 'my-account-with-avatar' : 'my-account';
|
||||
|
||||
$wp_admin_bar->add_menu( array( 'id' => $id, 'title' => $avatar . $user_identity, 'href' => get_edit_profile_url( $user_id ) ) );
|
||||
|
||||
/* Add the "My Account" sub menus */
|
||||
$wp_admin_bar->add_menu( array( 'parent' => $id, 'title' => __( 'Edit My Profile' ), 'href' => get_edit_profile_url( $user_id ) ) );
|
||||
if ( is_multisite() )
|
||||
$wp_admin_bar->add_menu( array( 'parent' => $id, 'title' => __( 'Dashboard' ), 'href' => get_dashboard_url( $user_id ) ) );
|
||||
else
|
||||
$wp_admin_bar->add_menu( array( 'parent' => $id, 'title' => __( 'Dashboard' ), 'href' => admin_url() ) );
|
||||
$wp_admin_bar->add_menu( array( 'parent' => $id, 'title' => __( 'Log Out' ), 'href' => wp_logout_url() ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the "My Sites/[Site Name]" menu and all submenus.
|
||||
*
|
||||
* @since 3.1.0
|
||||
*/
|
||||
function wp_admin_bar_my_sites_menu() {
|
||||
global $wpdb, $wp_admin_bar;
|
||||
|
||||
/* Add the 'My Sites' menu if the user has more than one site. */
|
||||
if ( count( $wp_admin_bar->user->blogs ) <= 1 )
|
||||
return;
|
||||
|
||||
$wp_admin_bar->add_menu( array( 'id' => 'my-blogs', 'title' => __( 'My Sites' ), 'href' => admin_url( 'my-sites.php' ) ) );
|
||||
|
||||
$default = includes_url('images/wpmini-blue.png');
|
||||
|
||||
foreach ( (array) $wp_admin_bar->user->blogs as $blog ) {
|
||||
// @todo Replace with some favicon lookup.
|
||||
//$blavatar = '<img src="' . esc_url( blavatar_url( blavatar_domain( $blog->siteurl ), 'img', 16, $default ) ) . '" alt="Blavatar" width="16" height="16" />';
|
||||
$blavatar = '<img src="' . esc_url($default) . '" alt="' . esc_attr__( 'Blavatar' ) . '" width="16" height="16" class="blavatar"/>';
|
||||
|
||||
$blogname = empty( $blog->blogname ) ? $blog->domain : $blog->blogname;
|
||||
|
||||
$wp_admin_bar->add_menu( array( 'parent' => 'my-blogs', 'id' => 'blog-' . $blog->userblog_id, 'title' => $blavatar . $blogname, 'href' => get_admin_url($blog->userblog_id) ) );
|
||||
$wp_admin_bar->add_menu( array( 'parent' => 'blog-' . $blog->userblog_id, 'id' => 'blog-' . $blog->userblog_id . '-d', 'title' => __( 'Dashboard' ), 'href' => get_admin_url($blog->userblog_id) ) );
|
||||
|
||||
if ( current_user_can_for_blog( $blog->userblog_id, 'edit_posts' ) ) {
|
||||
$wp_admin_bar->add_menu( array( 'parent' => 'blog-' . $blog->userblog_id, 'id' => 'blog-' . $blog->userblog_id . '-n', 'title' => __( 'New Post' ), 'href' => get_admin_url($blog->userblog_id, 'post-new.php') ) );
|
||||
$wp_admin_bar->add_menu( array( 'parent' => 'blog-' . $blog->userblog_id, 'id' => 'blog-' . $blog->userblog_id . '-c', 'title' => __( 'Manage Comments' ), 'href' => get_admin_url($blog->userblog_id, 'edit-comments.php') ) );
|
||||
}
|
||||
|
||||
$wp_admin_bar->add_menu( array( 'parent' => 'blog-' . $blog->userblog_id, 'id' => 'blog-' . $blog->userblog_id . '-v', 'title' => __( 'Visit Site' ), 'href' => get_home_url($blog->userblog_id) ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a shortlink.
|
||||
*
|
||||
* @since 3.1.0
|
||||
*/
|
||||
function wp_admin_bar_shortlink_menu() {
|
||||
global $wp_admin_bar;
|
||||
|
||||
$short = wp_get_shortlink( 0, 'query' );
|
||||
$id = 'get-shortlink';
|
||||
|
||||
if ( empty( $short ) )
|
||||
return;
|
||||
|
||||
$html = '<input class="shortlink-input" type="text" readonly="readonly" value="' . esc_attr( $short ) . '" />';
|
||||
|
||||
$wp_admin_bar->add_menu( array(
|
||||
'id' => $id,
|
||||
'title' => __( 'Shortlink' ),
|
||||
'href' => $short,
|
||||
'meta' => array( 'html' => $html ),
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide an edit link for posts and terms.
|
||||
*
|
||||
* @since 3.1.0
|
||||
*/
|
||||
function wp_admin_bar_edit_menu () {
|
||||
global $wp_admin_bar;
|
||||
|
||||
$current_object = get_queried_object();
|
||||
|
||||
if ( empty($current_object) )
|
||||
return;
|
||||
|
||||
if ( ! empty( $current_object->post_type ) && ( $post_type_object = get_post_type_object( $current_object->post_type ) ) && current_user_can( $post_type_object->cap->edit_post, $current_object->ID ) && $post_type_object->show_ui ) {
|
||||
$wp_admin_bar->add_menu( array( 'id' => 'edit', 'title' => $post_type_object->labels->edit_item, 'href' => get_edit_post_link( $current_object->ID ) ) );
|
||||
} elseif ( ! empty( $current_object->taxonomy ) && ( $tax = get_taxonomy( $current_object->taxonomy ) ) && current_user_can( $tax->cap->edit_terms ) && $tax->show_ui ) {
|
||||
$wp_admin_bar->add_menu( array( 'id' => 'edit', 'title' => $tax->labels->edit_item, 'href' => get_edit_term_link( $current_object->term_id, $current_object->taxonomy ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add "Add New" menu.
|
||||
*
|
||||
* @since 3.1.0
|
||||
*/
|
||||
function wp_admin_bar_new_content_menu() {
|
||||
global $wp_admin_bar;
|
||||
|
||||
$actions = array();
|
||||
foreach ( (array) get_post_types( array( 'show_ui' => true ), 'objects' ) as $ptype_obj ) {
|
||||
if ( true !== $ptype_obj->show_in_menu || ! current_user_can( $ptype_obj->cap->edit_posts ) )
|
||||
continue;
|
||||
|
||||
$actions[ 'post-new.php?post_type=' . $ptype_obj->name ] = array( $ptype_obj->labels->singular_name, $ptype_obj->cap->edit_posts, 'new-' . $ptype_obj->name );
|
||||
}
|
||||
|
||||
if ( empty( $actions ) )
|
||||
return;
|
||||
|
||||
$wp_admin_bar->add_menu( array( 'id' => 'new-content', 'title' => _x( 'Add New', 'admin bar menu group label' ), 'href' => admin_url( array_shift( array_keys( $actions ) ) ) ) );
|
||||
|
||||
foreach ( $actions as $link => $action ) {
|
||||
$wp_admin_bar->add_menu( array( 'parent' => 'new-content', 'id' => $action[2], 'title' => $action[0], 'href' => admin_url($link) ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add edit comments link with awaiting moderation count bubble.
|
||||
*
|
||||
* @since 3.1.0
|
||||
*/
|
||||
function wp_admin_bar_comments_menu() {
|
||||
global $wp_admin_bar;
|
||||
|
||||
if ( !current_user_can('edit_posts') )
|
||||
return;
|
||||
|
||||
$awaiting_mod = wp_count_comments();
|
||||
$awaiting_mod = $awaiting_mod->moderated;
|
||||
|
||||
$awaiting_mod = $awaiting_mod ? "<span id='ab-awaiting-mod' class='pending-count'>" . number_format_i18n( $awaiting_mod ) . "</span>" : '';
|
||||
$wp_admin_bar->add_menu( array( 'id' => 'comments', 'title' => sprintf( __('Comments %s'), $awaiting_mod ), 'href' => admin_url('edit-comments.php') ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add "Appearance" menu with widget and nav menu submenu.
|
||||
*
|
||||
* @since 3.1.0
|
||||
*/
|
||||
function wp_admin_bar_appearance_menu() {
|
||||
global $wp_admin_bar;
|
||||
|
||||
if ( !current_user_can('switch_themes') )
|
||||
return;
|
||||
|
||||
$wp_admin_bar->add_menu( array( 'id' => 'appearance', 'title' => __('Appearance'), 'href' => admin_url('themes.php') ) );
|
||||
|
||||
if ( !current_user_can('edit_theme_options') )
|
||||
return;
|
||||
|
||||
if ( current_theme_supports( 'widgets' ) )
|
||||
$wp_admin_bar->add_menu( array( 'parent' => 'appearance', 'id' => 'widgets', 'title' => __('Widgets'), 'href' => admin_url('widgets.php') ) );
|
||||
|
||||
if ( current_theme_supports( 'menus' ) || current_theme_supports( 'widgets' ) )
|
||||
$wp_admin_bar->add_menu( array( 'parent' => 'appearance', 'id' => 'menus', 'title' => __('Menus'), 'href' => admin_url('nav-menus.php') ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide an update link if theme/plugin/core updates are available.
|
||||
*
|
||||
* @since 3.1.0
|
||||
*/
|
||||
function wp_admin_bar_updates_menu() {
|
||||
global $wp_admin_bar;
|
||||
|
||||
if ( !current_user_can('install_plugins') )
|
||||
return;
|
||||
|
||||
$plugin_update_count = $theme_update_count = $wordpress_update_count = 0;
|
||||
$update_plugins = get_site_transient( 'update_plugins' );
|
||||
if ( !empty($update_plugins->response) )
|
||||
$plugin_update_count = count( $update_plugins->response );
|
||||
$update_themes = get_site_transient( 'update_themes' );
|
||||
if ( !empty($update_themes->response) )
|
||||
$theme_update_count = count( $update_themes->response );
|
||||
/* @todo get_core_updates() is only available on admin page loads
|
||||
$update_wordpress = get_core_updates( array('dismissed' => false) );
|
||||
if ( !empty($update_wordpress) && !in_array( $update_wordpress[0]->response, array('development', 'latest') ) )
|
||||
$wordpress_update_count = 1;
|
||||
*/
|
||||
|
||||
$update_count = $plugin_update_count + $theme_update_count + $wordpress_update_count;
|
||||
|
||||
if ( !$update_count )
|
||||
return;
|
||||
|
||||
$update_title = array();
|
||||
if ( $wordpress_update_count )
|
||||
$update_title[] = sprintf(__('%d WordPress Update'), $wordpress_update_count);
|
||||
if ( $plugin_update_count )
|
||||
$update_title[] = sprintf(_n('%d Plugin Update', '%d Plugin Updates', $plugin_update_count), $plugin_update_count);
|
||||
if ( $theme_update_count )
|
||||
$update_title[] = sprintf(_n('%d Theme Update', '%d Themes Updates', $theme_update_count), $theme_update_count);
|
||||
|
||||
$update_title = !empty($update_title) ? esc_attr(implode(', ', $update_title)) : '';
|
||||
|
||||
$update_title = "<span title='$update_title'>";
|
||||
$update_title .= sprintf( __('Updates %s'), "<span id='ab-updates' class='update-count'>" . number_format_i18n($update_count) . '</span>' );
|
||||
$update_title .= '</span>';
|
||||
|
||||
$wp_admin_bar->add_menu( array( 'id' => 'updates', 'title' => $update_title, 'href' => network_admin_url( 'update-core.php' ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Style and scripts for the admin bar.
|
||||
*
|
||||
* @since 3.1.0
|
||||
*
|
||||
*/
|
||||
function wp_admin_bar_header() { ?>
|
||||
<style type="text/css" media="print">#wpadminbar { display:none; }</style>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Default admin bar callback.
|
||||
*
|
||||
* @since 3.1.0
|
||||
*
|
||||
*/
|
||||
function _admin_bar_bump_cb() { ?>
|
||||
<style type="text/css">
|
||||
html { margin-top: 28px !important; }
|
||||
* html body { margin-top: 28px !important; }
|
||||
</style>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the display status of the admin bar
|
||||
*
|
||||
* This can be called immediately upon plugin load. It does not need to be called from a function hooked to the init action.
|
||||
*
|
||||
* @since 3.1.0
|
||||
*
|
||||
* @param bool $show Whether to allow the admin bar to show.
|
||||
* @return void
|
||||
*/
|
||||
function show_admin_bar( $show ) {
|
||||
global $show_admin_bar;
|
||||
$show_admin_bar = (bool) $show;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the admin bar should be showing.
|
||||
*
|
||||
* @since 3.1.0
|
||||
*
|
||||
* @return bool Whether the admin bar should be showing.
|
||||
*/
|
||||
function is_admin_bar_showing() {
|
||||
global $show_admin_bar, $pagenow;
|
||||
|
||||
/* For all these types of request we never want an admin bar period */
|
||||
if ( defined('XMLRPC_REQUEST') || defined('APP_REQUEST') || defined('DOING_AJAX') || defined('IFRAME_REQUEST') )
|
||||
return false;
|
||||
|
||||
if ( ! isset( $show_admin_bar ) ) {
|
||||
if ( ! is_user_logged_in() || 'wp-login.php' == $pagenow ) {
|
||||
$show_admin_bar = false;
|
||||
} else {
|
||||
$context = is_admin() ? 'admin' : 'front';
|
||||
$show_admin_bar = _get_admin_bar_pref( $context );
|
||||
}
|
||||
}
|
||||
|
||||
$show_admin_bar = apply_filters( 'show_admin_bar', $show_admin_bar );
|
||||
|
||||
return $show_admin_bar;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the admin bar display preference of a user based on context.
|
||||
*
|
||||
* @since 3.1.0
|
||||
* @access private
|
||||
*
|
||||
* @param string $context Context of this preference check, either 'admin' or 'front'
|
||||
* @param int $user Optional. ID of the user to check, defaults to 0 for current user
|
||||
* @return bool Whether the admin bar should be showing for this user
|
||||
*/
|
||||
function _get_admin_bar_pref( $context, $user = 0 ) {
|
||||
$pref = get_user_option( "show_admin_bar_{$context}", $user );
|
||||
if ( false === $pref )
|
||||
return 'admin' != $context || is_multisite();
|
||||
|
||||
return 'true' === $pref;
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,354 @@
|
||||
<?php
|
||||
/**
|
||||
* Atom Syndication Format PHP Library
|
||||
*
|
||||
* @package AtomLib
|
||||
* @link http://code.google.com/p/phpatomlib/
|
||||
*
|
||||
* @author Elias Torres <elias@torrez.us>
|
||||
* @version 0.4
|
||||
* @since 2.3
|
||||
*/
|
||||
|
||||
/**
|
||||
* Structure that store common Atom Feed Properties
|
||||
*
|
||||
* @package AtomLib
|
||||
*/
|
||||
class AtomFeed {
|
||||
/**
|
||||
* Stores Links
|
||||
* @var array
|
||||
* @access public
|
||||
*/
|
||||
var $links = array();
|
||||
/**
|
||||
* Stores Categories
|
||||
* @var array
|
||||
* @access public
|
||||
*/
|
||||
var $categories = array();
|
||||
/**
|
||||
* Stores Entries
|
||||
*
|
||||
* @var array
|
||||
* @access public
|
||||
*/
|
||||
var $entries = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Structure that store Atom Entry Properties
|
||||
*
|
||||
* @package AtomLib
|
||||
*/
|
||||
class AtomEntry {
|
||||
/**
|
||||
* Stores Links
|
||||
* @var array
|
||||
* @access public
|
||||
*/
|
||||
var $links = array();
|
||||
/**
|
||||
* Stores Categories
|
||||
* @var array
|
||||
* @access public
|
||||
*/
|
||||
var $categories = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* AtomLib Atom Parser API
|
||||
*
|
||||
* @package AtomLib
|
||||
*/
|
||||
class AtomParser {
|
||||
|
||||
var $NS = 'http://www.w3.org/2005/Atom';
|
||||
var $ATOM_CONTENT_ELEMENTS = array('content','summary','title','subtitle','rights');
|
||||
var $ATOM_SIMPLE_ELEMENTS = array('id','updated','published','draft');
|
||||
|
||||
var $debug = false;
|
||||
|
||||
var $depth = 0;
|
||||
var $indent = 2;
|
||||
var $in_content;
|
||||
var $ns_contexts = array();
|
||||
var $ns_decls = array();
|
||||
var $content_ns_decls = array();
|
||||
var $content_ns_contexts = array();
|
||||
var $is_xhtml = false;
|
||||
var $is_html = false;
|
||||
var $is_text = true;
|
||||
var $skipped_div = false;
|
||||
|
||||
var $FILE = "php://input";
|
||||
|
||||
var $feed;
|
||||
var $current;
|
||||
|
||||
function AtomParser() {
|
||||
|
||||
$this->feed = new AtomFeed();
|
||||
$this->current = null;
|
||||
$this->map_attrs_func = create_function('$k,$v', 'return "$k=\"$v\"";');
|
||||
$this->map_xmlns_func = create_function('$p,$n', '$xd = "xmlns"; if(strlen($n[0])>0) $xd .= ":{$n[0]}"; return "{$xd}=\"{$n[1]}\"";');
|
||||
}
|
||||
|
||||
function _p($msg) {
|
||||
if($this->debug) {
|
||||
print str_repeat(" ", $this->depth * $this->indent) . $msg ."\n";
|
||||
}
|
||||
}
|
||||
|
||||
function error_handler($log_level, $log_text, $error_file, $error_line) {
|
||||
$this->error = $log_text;
|
||||
}
|
||||
|
||||
function parse() {
|
||||
|
||||
set_error_handler(array(&$this, 'error_handler'));
|
||||
|
||||
array_unshift($this->ns_contexts, array());
|
||||
|
||||
$parser = xml_parser_create_ns();
|
||||
xml_set_object($parser, $this);
|
||||
xml_set_element_handler($parser, "start_element", "end_element");
|
||||
xml_parser_set_option($parser,XML_OPTION_CASE_FOLDING,0);
|
||||
xml_parser_set_option($parser,XML_OPTION_SKIP_WHITE,0);
|
||||
xml_set_character_data_handler($parser, "cdata");
|
||||
xml_set_default_handler($parser, "_default");
|
||||
xml_set_start_namespace_decl_handler($parser, "start_ns");
|
||||
xml_set_end_namespace_decl_handler($parser, "end_ns");
|
||||
|
||||
$this->content = '';
|
||||
|
||||
$ret = true;
|
||||
|
||||
$fp = fopen($this->FILE, "r");
|
||||
while ($data = fread($fp, 4096)) {
|
||||
if($this->debug) $this->content .= $data;
|
||||
|
||||
if(!xml_parse($parser, $data, feof($fp))) {
|
||||
trigger_error(sprintf(__('XML error: %s at line %d')."\n",
|
||||
xml_error_string(xml_get_error_code($xml_parser)),
|
||||
xml_get_current_line_number($xml_parser)));
|
||||
$ret = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
fclose($fp);
|
||||
|
||||
xml_parser_free($parser);
|
||||
|
||||
restore_error_handler();
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
function start_element($parser, $name, $attrs) {
|
||||
|
||||
$tag = array_pop(split(":", $name));
|
||||
|
||||
switch($name) {
|
||||
case $this->NS . ':feed':
|
||||
$this->current = $this->feed;
|
||||
break;
|
||||
case $this->NS . ':entry':
|
||||
$this->current = new AtomEntry();
|
||||
break;
|
||||
};
|
||||
|
||||
$this->_p("start_element('$name')");
|
||||
#$this->_p(print_r($this->ns_contexts,true));
|
||||
#$this->_p('current(' . $this->current . ')');
|
||||
|
||||
array_unshift($this->ns_contexts, $this->ns_decls);
|
||||
|
||||
$this->depth++;
|
||||
|
||||
if(!empty($this->in_content)) {
|
||||
|
||||
$this->content_ns_decls = array();
|
||||
|
||||
if($this->is_html || $this->is_text)
|
||||
trigger_error("Invalid content in element found. Content must not be of type text or html if it contains markup.");
|
||||
|
||||
$attrs_prefix = array();
|
||||
|
||||
// resolve prefixes for attributes
|
||||
foreach($attrs as $key => $value) {
|
||||
$with_prefix = $this->ns_to_prefix($key, true);
|
||||
$attrs_prefix[$with_prefix[1]] = $this->xml_escape($value);
|
||||
}
|
||||
|
||||
$attrs_str = join(' ', array_map($this->map_attrs_func, array_keys($attrs_prefix), array_values($attrs_prefix)));
|
||||
if(strlen($attrs_str) > 0) {
|
||||
$attrs_str = " " . $attrs_str;
|
||||
}
|
||||
|
||||
$with_prefix = $this->ns_to_prefix($name);
|
||||
|
||||
if(!$this->is_declared_content_ns($with_prefix[0])) {
|
||||
array_push($this->content_ns_decls, $with_prefix[0]);
|
||||
}
|
||||
|
||||
$xmlns_str = '';
|
||||
if(count($this->content_ns_decls) > 0) {
|
||||
array_unshift($this->content_ns_contexts, $this->content_ns_decls);
|
||||
$xmlns_str .= join(' ', array_map($this->map_xmlns_func, array_keys($this->content_ns_contexts[0]), array_values($this->content_ns_contexts[0])));
|
||||
if(strlen($xmlns_str) > 0) {
|
||||
$xmlns_str = " " . $xmlns_str;
|
||||
}
|
||||
}
|
||||
|
||||
array_push($this->in_content, array($tag, $this->depth, "<". $with_prefix[1] ."{$xmlns_str}{$attrs_str}" . ">"));
|
||||
|
||||
} else if(in_array($tag, $this->ATOM_CONTENT_ELEMENTS) || in_array($tag, $this->ATOM_SIMPLE_ELEMENTS)) {
|
||||
$this->in_content = array();
|
||||
$this->is_xhtml = $attrs['type'] == 'xhtml';
|
||||
$this->is_html = $attrs['type'] == 'html' || $attrs['type'] == 'text/html';
|
||||
$this->is_text = !in_array('type',array_keys($attrs)) || $attrs['type'] == 'text';
|
||||
$type = $this->is_xhtml ? 'XHTML' : ($this->is_html ? 'HTML' : ($this->is_text ? 'TEXT' : $attrs['type']));
|
||||
|
||||
if(in_array('src',array_keys($attrs))) {
|
||||
$this->current->$tag = $attrs;
|
||||
} else {
|
||||
array_push($this->in_content, array($tag,$this->depth, $type));
|
||||
}
|
||||
} else if($tag == 'link') {
|
||||
array_push($this->current->links, $attrs);
|
||||
} else if($tag == 'category') {
|
||||
array_push($this->current->categories, $attrs);
|
||||
}
|
||||
|
||||
$this->ns_decls = array();
|
||||
}
|
||||
|
||||
function end_element($parser, $name) {
|
||||
|
||||
$tag = array_pop(split(":", $name));
|
||||
|
||||
$ccount = count($this->in_content);
|
||||
|
||||
# if we are *in* content, then let's proceed to serialize it
|
||||
if(!empty($this->in_content)) {
|
||||
# if we are ending the original content element
|
||||
# then let's finalize the content
|
||||
if($this->in_content[0][0] == $tag &&
|
||||
$this->in_content[0][1] == $this->depth) {
|
||||
$origtype = $this->in_content[0][2];
|
||||
array_shift($this->in_content);
|
||||
$newcontent = array();
|
||||
foreach($this->in_content as $c) {
|
||||
if(count($c) == 3) {
|
||||
array_push($newcontent, $c[2]);
|
||||
} else {
|
||||
if($this->is_xhtml || $this->is_text) {
|
||||
array_push($newcontent, $this->xml_escape($c));
|
||||
} else {
|
||||
array_push($newcontent, $c);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(in_array($tag, $this->ATOM_CONTENT_ELEMENTS)) {
|
||||
$this->current->$tag = array($origtype, join('',$newcontent));
|
||||
} else {
|
||||
$this->current->$tag = join('',$newcontent);
|
||||
}
|
||||
$this->in_content = array();
|
||||
} else if($this->in_content[$ccount-1][0] == $tag &&
|
||||
$this->in_content[$ccount-1][1] == $this->depth) {
|
||||
$this->in_content[$ccount-1][2] = substr($this->in_content[$ccount-1][2],0,-1) . "/>";
|
||||
} else {
|
||||
# else, just finalize the current element's content
|
||||
$endtag = $this->ns_to_prefix($name);
|
||||
array_push($this->in_content, array($tag, $this->depth, "</$endtag[1]>"));
|
||||
}
|
||||
}
|
||||
|
||||
array_shift($this->ns_contexts);
|
||||
|
||||
$this->depth--;
|
||||
|
||||
if($name == ($this->NS . ':entry')) {
|
||||
array_push($this->feed->entries, $this->current);
|
||||
$this->current = null;
|
||||
}
|
||||
|
||||
$this->_p("end_element('$name')");
|
||||
}
|
||||
|
||||
function start_ns($parser, $prefix, $uri) {
|
||||
$this->_p("starting: " . $prefix . ":" . $uri);
|
||||
array_push($this->ns_decls, array($prefix,$uri));
|
||||
}
|
||||
|
||||
function end_ns($parser, $prefix) {
|
||||
$this->_p("ending: #" . $prefix . "#");
|
||||
}
|
||||
|
||||
function cdata($parser, $data) {
|
||||
$this->_p("data: #" . str_replace(array("\n"), array("\\n"), trim($data)) . "#");
|
||||
if(!empty($this->in_content)) {
|
||||
array_push($this->in_content, $data);
|
||||
}
|
||||
}
|
||||
|
||||
function _default($parser, $data) {
|
||||
# when does this gets called?
|
||||
}
|
||||
|
||||
|
||||
function ns_to_prefix($qname, $attr=false) {
|
||||
# split 'http://www.w3.org/1999/xhtml:div' into ('http','//www.w3.org/1999/xhtml','div')
|
||||
$components = split(":", $qname);
|
||||
|
||||
# grab the last one (e.g 'div')
|
||||
$name = array_pop($components);
|
||||
|
||||
if(!empty($components)) {
|
||||
# re-join back the namespace component
|
||||
$ns = join(":",$components);
|
||||
foreach($this->ns_contexts as $context) {
|
||||
foreach($context as $mapping) {
|
||||
if($mapping[1] == $ns && strlen($mapping[0]) > 0) {
|
||||
return array($mapping, "$mapping[0]:$name");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if($attr) {
|
||||
return array(null, $name);
|
||||
} else {
|
||||
foreach($this->ns_contexts as $context) {
|
||||
foreach($context as $mapping) {
|
||||
if(strlen($mapping[0]) == 0) {
|
||||
return array($mapping, $name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function is_declared_content_ns($new_mapping) {
|
||||
foreach($this->content_ns_contexts as $context) {
|
||||
foreach($context as $mapping) {
|
||||
if($new_mapping == $mapping) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function xml_escape($string)
|
||||
{
|
||||
return str_replace(array('&','"',"'",'<','>'),
|
||||
array('&','"',''','<','>'),
|
||||
$string );
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,369 @@
|
||||
<?php
|
||||
/**
|
||||
* Author Template functions for use in themes.
|
||||
*
|
||||
* These functions must be used within the WordPress Loop.
|
||||
*
|
||||
* @link http://codex.wordpress.org/Author_Templates
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Template
|
||||
*/
|
||||
|
||||
/**
|
||||
* Retrieve the author of the current post.
|
||||
*
|
||||
* @since 1.5
|
||||
* @uses $authordata The current author's DB object.
|
||||
* @uses apply_filters() Calls 'the_author' hook on the author display name.
|
||||
*
|
||||
* @param string $deprecated Deprecated.
|
||||
* @return string The author's display name.
|
||||
*/
|
||||
function get_the_author($deprecated = '') {
|
||||
global $authordata;
|
||||
|
||||
if ( !empty( $deprecated ) )
|
||||
_deprecated_argument( __FUNCTION__, '2.1' );
|
||||
|
||||
return apply_filters('the_author', is_object($authordata) ? $authordata->display_name : null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the name of the author of the current post.
|
||||
*
|
||||
* The behavior of this function is based off of old functionality predating
|
||||
* get_the_author(). This function is not deprecated, but is designed to echo
|
||||
* the value from get_the_author() and as an result of any old theme that might
|
||||
* still use the old behavior will also pass the value from get_the_author().
|
||||
*
|
||||
* The normal, expected behavior of this function is to echo the author and not
|
||||
* return it. However, backwards compatiability has to be maintained.
|
||||
*
|
||||
* @since 0.71
|
||||
* @see get_the_author()
|
||||
* @link http://codex.wordpress.org/Template_Tags/the_author
|
||||
*
|
||||
* @param string $deprecated Deprecated.
|
||||
* @param string $deprecated_echo Deprecated. Use get_the_author(). Echo the string or return it.
|
||||
* @return string The author's display name, from get_the_author().
|
||||
*/
|
||||
function the_author( $deprecated = '', $deprecated_echo = true ) {
|
||||
if ( !empty( $deprecated ) )
|
||||
_deprecated_argument( __FUNCTION__, '2.1' );
|
||||
if ( $deprecated_echo !== true )
|
||||
_deprecated_argument( __FUNCTION__, '1.5', __('Use <code>get_the_author()</code> instead if you do not want the value echoed.') );
|
||||
if ( $deprecated_echo )
|
||||
echo get_the_author();
|
||||
return get_the_author();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the author who last edited the current post.
|
||||
*
|
||||
* @since 2.8
|
||||
* @uses $post The current post's DB object.
|
||||
* @uses get_post_meta() Retrieves the ID of the author who last edited the current post.
|
||||
* @uses get_userdata() Retrieves the author's DB object.
|
||||
* @uses apply_filters() Calls 'the_modified_author' hook on the author display name.
|
||||
* @return string The author's display name.
|
||||
*/
|
||||
function get_the_modified_author() {
|
||||
global $post;
|
||||
if ( $last_id = get_post_meta($post->ID, '_edit_last', true) ) {
|
||||
$last_user = get_userdata($last_id);
|
||||
return apply_filters('the_modified_author', $last_user->display_name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the name of the author who last edited the current post.
|
||||
*
|
||||
* @since 2.8
|
||||
* @see get_the_author()
|
||||
* @return string The author's display name, from get_the_modified_author().
|
||||
*/
|
||||
function the_modified_author() {
|
||||
echo get_the_modified_author();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the requested data of the author of the current post.
|
||||
* @link http://codex.wordpress.org/Template_Tags/the_author_meta
|
||||
* @since 2.8.0
|
||||
* @uses $authordata The current author's DB object (if $user_id not specified).
|
||||
* @param string $field selects the field of the users record.
|
||||
* @param int $user_id Optional. User ID.
|
||||
* @return string The author's field from the current author's DB object.
|
||||
*/
|
||||
function get_the_author_meta($field = '', $user_id = false) {
|
||||
if ( ! $user_id )
|
||||
global $authordata;
|
||||
else
|
||||
$authordata = get_userdata( $user_id );
|
||||
|
||||
// Keys used as object vars cannot have dashes.
|
||||
$field = str_replace('-', '', $field);
|
||||
$field = strtolower($field);
|
||||
$user_field = "user_$field";
|
||||
|
||||
if ( 'id' == $field )
|
||||
$value = isset($authordata->ID) ? (int)$authordata->ID : 0;
|
||||
elseif ( isset($authordata->$user_field) )
|
||||
$value = $authordata->$user_field;
|
||||
else
|
||||
$value = isset($authordata->$field) ? $authordata->$field : '';
|
||||
|
||||
return apply_filters('get_the_author_' . $field, $value, $user_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the requested data of the author of the current post.
|
||||
* @link http://codex.wordpress.org/Template_Tags/the_author_meta
|
||||
* @since 2.8.0
|
||||
* @param string $field selects the field of the users record.
|
||||
* @param int $user_id Optional. User ID.
|
||||
* @echo string The author's field from the current author's DB object.
|
||||
*/
|
||||
function the_author_meta($field = '', $user_id = false) {
|
||||
echo apply_filters('the_author_' . $field, get_the_author_meta($field, $user_id), $user_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve either author's link or author's name.
|
||||
*
|
||||
* If the author has a home page set, return an HTML link, otherwise just return the
|
||||
* author's name.
|
||||
*
|
||||
* @uses get_the_author_meta()
|
||||
* @uses get_the_author()
|
||||
*/
|
||||
function get_the_author_link() {
|
||||
if ( get_the_author_meta('url') ) {
|
||||
return '<a href="' . get_the_author_meta('url') . '" title="' . esc_attr( sprintf(__("Visit %s’s website"), get_the_author()) ) . '" rel="external">' . get_the_author() . '</a>';
|
||||
} else {
|
||||
return get_the_author();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Display either author's link or author's name.
|
||||
*
|
||||
* If the author has a home page set, echo an HTML link, otherwise just echo the
|
||||
* author's name.
|
||||
*
|
||||
* @link http://codex.wordpress.org/Template_Tags/the_author_link
|
||||
* @since 2.1
|
||||
* @uses get_the_author_link()
|
||||
*/
|
||||
function the_author_link() {
|
||||
echo get_the_author_link();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the number of posts by the author of the current post.
|
||||
*
|
||||
* @since 1.5
|
||||
* @uses $post The current post in the Loop's DB object.
|
||||
* @uses count_user_posts()
|
||||
* @return int The number of posts by the author.
|
||||
*/
|
||||
function get_the_author_posts() {
|
||||
global $post;
|
||||
return count_user_posts($post->post_author);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the number of posts by the author of the current post.
|
||||
*
|
||||
* @link http://codex.wordpress.org/Template_Tags/the_author_posts
|
||||
* @since 0.71
|
||||
* @uses get_the_author_posts() Echoes returned value from function.
|
||||
*/
|
||||
function the_author_posts() {
|
||||
echo get_the_author_posts();
|
||||
}
|
||||
|
||||
/**
|
||||
* Display an HTML link to the author page of the author of the current post.
|
||||
*
|
||||
* Does just echo get_author_posts_url() function, like the others do. The
|
||||
* reason for this, is that another function is used to help in printing the
|
||||
* link to the author's posts.
|
||||
*
|
||||
* @link http://codex.wordpress.org/Template_Tags/the_author_posts_link
|
||||
* @since 1.2.0
|
||||
* @uses $authordata The current author's DB object.
|
||||
* @uses get_author_posts_url()
|
||||
* @uses get_the_author()
|
||||
* @param string $deprecated Deprecated.
|
||||
*/
|
||||
function the_author_posts_link($deprecated = '') {
|
||||
if ( !empty( $deprecated ) )
|
||||
_deprecated_argument( __FUNCTION__, '2.1' );
|
||||
|
||||
global $authordata;
|
||||
$link = sprintf(
|
||||
'<a href="%1$s" title="%2$s">%3$s</a>',
|
||||
get_author_posts_url( $authordata->ID, $authordata->user_nicename ),
|
||||
esc_attr( sprintf( __( 'Posts by %s' ), get_the_author() ) ),
|
||||
get_the_author()
|
||||
);
|
||||
echo apply_filters( 'the_author_posts_link', $link );
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the URL to the author page for the user with the ID provided.
|
||||
*
|
||||
* @since 2.1.0
|
||||
* @uses $wp_rewrite WP_Rewrite
|
||||
* @return string The URL to the author's page.
|
||||
*/
|
||||
function get_author_posts_url($author_id, $author_nicename = '') {
|
||||
global $wp_rewrite;
|
||||
$auth_ID = (int) $author_id;
|
||||
$link = $wp_rewrite->get_author_permastruct();
|
||||
|
||||
if ( empty($link) ) {
|
||||
$file = home_url( '/' );
|
||||
$link = $file . '?author=' . $auth_ID;
|
||||
} else {
|
||||
if ( '' == $author_nicename ) {
|
||||
$user = get_userdata($author_id);
|
||||
if ( !empty($user->user_nicename) )
|
||||
$author_nicename = $user->user_nicename;
|
||||
}
|
||||
$link = str_replace('%author%', $author_nicename, $link);
|
||||
$link = home_url( user_trailingslashit( $link ) );
|
||||
}
|
||||
|
||||
$link = apply_filters('author_link', $link, $author_id, $author_nicename);
|
||||
|
||||
return $link;
|
||||
}
|
||||
|
||||
/**
|
||||
* List all the authors of the blog, with several options available.
|
||||
*
|
||||
* <ul>
|
||||
* <li>optioncount (boolean) (false): Show the count in parenthesis next to the
|
||||
* author's name.</li>
|
||||
* <li>exclude_admin (boolean) (true): Exclude the 'admin' user that is
|
||||
* installed bydefault.</li>
|
||||
* <li>show_fullname (boolean) (false): Show their full names.</li>
|
||||
* <li>hide_empty (boolean) (true): Don't show authors without any posts.</li>
|
||||
* <li>feed (string) (''): If isn't empty, show links to author's feeds.</li>
|
||||
* <li>feed_image (string) (''): If isn't empty, use this image to link to
|
||||
* feeds.</li>
|
||||
* <li>echo (boolean) (true): Set to false to return the output, instead of
|
||||
* echoing.</li>
|
||||
* <li>style (string) ('list'): Whether to display list of authors in list form
|
||||
* or as a string.</li>
|
||||
* <li>html (bool) (true): Whether to list the items in html form or plaintext.
|
||||
* </li>
|
||||
* </ul>
|
||||
*
|
||||
* @link http://codex.wordpress.org/Template_Tags/wp_list_authors
|
||||
* @since 1.2.0
|
||||
* @param array $args The argument array.
|
||||
* @return null|string The output, if echo is set to false.
|
||||
*/
|
||||
function wp_list_authors($args = '') {
|
||||
global $wpdb;
|
||||
|
||||
$defaults = array(
|
||||
'orderby' => 'name', 'order' => 'ASC', 'number' => '',
|
||||
'optioncount' => false, 'exclude_admin' => true,
|
||||
'show_fullname' => false, 'hide_empty' => true,
|
||||
'feed' => '', 'feed_image' => '', 'feed_type' => '', 'echo' => true,
|
||||
'style' => 'list', 'html' => true
|
||||
);
|
||||
|
||||
$args = wp_parse_args( $args, $defaults );
|
||||
extract( $args, EXTR_SKIP );
|
||||
|
||||
$return = '';
|
||||
|
||||
$query_args = wp_array_slice_assoc( $args, array( 'orderby', 'order', 'number' ) );
|
||||
$query_args['fields'] = 'ids';
|
||||
$authors = get_users( $query_args );
|
||||
|
||||
$author_count = array();
|
||||
foreach ( (array) $wpdb->get_results("SELECT DISTINCT post_author, COUNT(ID) AS count FROM $wpdb->posts WHERE post_type = 'post' AND " . get_private_posts_cap_sql( 'post' ) . " GROUP BY post_author") as $row )
|
||||
$author_count[$row->post_author] = $row->count;
|
||||
|
||||
foreach ( $authors as $author_id ) {
|
||||
$author = get_userdata( $author_id );
|
||||
|
||||
if ( $exclude_admin && 'admin' == $author->display_name )
|
||||
continue;
|
||||
|
||||
$posts = isset( $author_count[$author->ID] ) ? $author_count[$author->ID] : 0;
|
||||
|
||||
if ( !$posts && $hide_empty )
|
||||
continue;
|
||||
|
||||
$link = '';
|
||||
|
||||
if ( $show_fullname && $author->first_name && $author->last_name )
|
||||
$name = "$author->first_name $author->last_name";
|
||||
else
|
||||
$name = $author->display_name;
|
||||
|
||||
if ( !$html ) {
|
||||
$return .= $name . ', ';
|
||||
|
||||
continue; // No need to go further to process HTML.
|
||||
}
|
||||
|
||||
if ( 'list' == $style ) {
|
||||
$return .= '<li>';
|
||||
}
|
||||
|
||||
$link = '<a href="' . get_author_posts_url( $author->ID, $author->user_nicename ) . '" title="' . esc_attr( sprintf(__("Posts by %s"), $author->display_name) ) . '">' . $name . '</a>';
|
||||
|
||||
if ( !empty( $feed_image ) || !empty( $feed ) ) {
|
||||
$link .= ' ';
|
||||
if ( empty( $feed_image ) ) {
|
||||
$link .= '(';
|
||||
}
|
||||
|
||||
$link .= '<a href="' . get_author_feed_link( $author->ID ) . '"';
|
||||
|
||||
$alt = $title = '';
|
||||
if ( !empty( $feed ) ) {
|
||||
$title = ' title="' . esc_attr( $feed ) . '"';
|
||||
$alt = ' alt="' . esc_attr( $feed ) . '"';
|
||||
$name = $feed;
|
||||
$link .= $title;
|
||||
}
|
||||
|
||||
$link .= '>';
|
||||
|
||||
if ( !empty( $feed_image ) )
|
||||
$link .= '<img src="' . esc_url( $feed_image ) . '" style="border: none;"' . $alt . $title . ' />';
|
||||
else
|
||||
$link .= $name;
|
||||
|
||||
$link .= '</a>';
|
||||
|
||||
if ( empty( $feed_image ) )
|
||||
$link .= ')';
|
||||
}
|
||||
|
||||
if ( $optioncount )
|
||||
$link .= ' ('. $posts . ')';
|
||||
|
||||
$return .= $link;
|
||||
$return .= ( 'list' == $style ) ? '</li>' : ', ';
|
||||
}
|
||||
|
||||
$return = rtrim($return, ', ');
|
||||
|
||||
if ( !$echo )
|
||||
return $return;
|
||||
|
||||
echo $return;
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,256 @@
|
||||
<?php
|
||||
/**
|
||||
* Bookmark Template Functions for usage in Themes
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Template
|
||||
*/
|
||||
|
||||
/**
|
||||
* The formatted output of a list of bookmarks.
|
||||
*
|
||||
* The $bookmarks array must contain bookmark objects and will be iterated over
|
||||
* to retrieve the bookmark to be used in the output.
|
||||
*
|
||||
* The output is formatted as HTML with no way to change that format. However,
|
||||
* what is between, before, and after can be changed. The link itself will be
|
||||
* HTML.
|
||||
*
|
||||
* This function is used internally by wp_list_bookmarks() and should not be
|
||||
* used by themes.
|
||||
*
|
||||
* The defaults for overwriting are:
|
||||
* 'show_updated' - Default is 0 (integer). Will show the time of when the
|
||||
* bookmark was last updated.
|
||||
* 'show_description' - Default is 0 (integer). Whether to show the description
|
||||
* of the bookmark.
|
||||
* 'show_images' - Default is 1 (integer). Whether to show link image if
|
||||
* available.
|
||||
* 'show_name' - Default is 0 (integer). Whether to show link name if
|
||||
* available.
|
||||
* 'before' - Default is '<li>' (string). The html or text to prepend to each
|
||||
* bookmarks.
|
||||
* 'after' - Default is '</li>' (string). The html or text to append to each
|
||||
* bookmarks.
|
||||
* 'link_before' - Default is '' (string). The html or text to prepend to each
|
||||
* bookmarks inside the <a> tag.
|
||||
* 'link_after' - Default is '' (string). The html or text to append to each
|
||||
* bookmarks inside the <a> tag.
|
||||
* 'between' - Default is '\n' (string). The string for use in between the link,
|
||||
* description, and image.
|
||||
* 'show_rating' - Default is 0 (integer). Whether to show the link rating.
|
||||
*
|
||||
* @since 2.1.0
|
||||
* @access private
|
||||
* @usedby wp_list_bookmarks()
|
||||
*
|
||||
* @param array $bookmarks List of bookmarks to traverse
|
||||
* @param string|array $args Optional. Overwrite the defaults.
|
||||
* @return string Formatted output in HTML
|
||||
*/
|
||||
function _walk_bookmarks($bookmarks, $args = '' ) {
|
||||
$defaults = array(
|
||||
'show_updated' => 0, 'show_description' => 0,
|
||||
'show_images' => 1, 'show_name' => 0,
|
||||
'before' => '<li>', 'after' => '</li>', 'between' => "\n",
|
||||
'show_rating' => 0, 'link_before' => '', 'link_after' => ''
|
||||
);
|
||||
|
||||
$r = wp_parse_args( $args, $defaults );
|
||||
extract( $r, EXTR_SKIP );
|
||||
|
||||
$output = ''; // Blank string to start with.
|
||||
|
||||
foreach ( (array) $bookmarks as $bookmark ) {
|
||||
if ( !isset($bookmark->recently_updated) )
|
||||
$bookmark->recently_updated = false;
|
||||
$output .= $before;
|
||||
if ( $show_updated && $bookmark->recently_updated )
|
||||
$output .= get_option('links_recently_updated_prepend');
|
||||
|
||||
$the_link = '#';
|
||||
if ( !empty($bookmark->link_url) )
|
||||
$the_link = esc_url($bookmark->link_url);
|
||||
|
||||
$desc = esc_attr(sanitize_bookmark_field('link_description', $bookmark->link_description, $bookmark->link_id, 'display'));
|
||||
$name = esc_attr(sanitize_bookmark_field('link_name', $bookmark->link_name, $bookmark->link_id, 'display'));
|
||||
$title = $desc;
|
||||
|
||||
if ( $show_updated )
|
||||
if ( '00' != substr($bookmark->link_updated_f, 0, 2) ) {
|
||||
$title .= ' (';
|
||||
$title .= sprintf(__('Last updated: %s'), date(get_option('links_updated_date_format'), $bookmark->link_updated_f + (get_option('gmt_offset') * 3600)));
|
||||
$title .= ')';
|
||||
}
|
||||
|
||||
$alt = ' alt="' . $name . ( $show_description ? ' ' . $title : '' ) . '"';
|
||||
|
||||
if ( '' != $title )
|
||||
$title = ' title="' . $title . '"';
|
||||
|
||||
$rel = $bookmark->link_rel;
|
||||
if ( '' != $rel )
|
||||
$rel = ' rel="' . esc_attr($rel) . '"';
|
||||
|
||||
$target = $bookmark->link_target;
|
||||
if ( '' != $target )
|
||||
$target = ' target="' . $target . '"';
|
||||
|
||||
$output .= '<a href="' . $the_link . '"' . $rel . $title . $target . '>';
|
||||
|
||||
$output .= $link_before;
|
||||
|
||||
if ( $bookmark->link_image != null && $show_images ) {
|
||||
if ( strpos($bookmark->link_image, 'http') === 0 )
|
||||
$output .= "<img src=\"$bookmark->link_image\" $alt $title />";
|
||||
else // If it's a relative path
|
||||
$output .= "<img src=\"" . get_option('siteurl') . "$bookmark->link_image\" $alt $title />";
|
||||
|
||||
if ( $show_name )
|
||||
$output .= " $name";
|
||||
} else {
|
||||
$output .= $name;
|
||||
}
|
||||
|
||||
$output .= $link_after;
|
||||
|
||||
$output .= '</a>';
|
||||
|
||||
if ( $show_updated && $bookmark->recently_updated )
|
||||
$output .= get_option('links_recently_updated_append');
|
||||
|
||||
if ( $show_description && '' != $desc )
|
||||
$output .= $between . $desc;
|
||||
|
||||
if ( $show_rating )
|
||||
$output .= $between . sanitize_bookmark_field('link_rating', $bookmark->link_rating, $bookmark->link_id, 'display');
|
||||
|
||||
$output .= "$after\n";
|
||||
} // end while
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve or echo all of the bookmarks.
|
||||
*
|
||||
* List of default arguments are as follows:
|
||||
* 'orderby' - Default is 'name' (string). How to order the links by. String is
|
||||
* based off of the bookmark scheme.
|
||||
* 'order' - Default is 'ASC' (string). Either 'ASC' or 'DESC'. Orders in either
|
||||
* ascending or descending order.
|
||||
* 'limit' - Default is -1 (integer) or show all. The amount of bookmarks to
|
||||
* display.
|
||||
* 'category' - Default is empty string (string). Include the links in what
|
||||
* category ID(s).
|
||||
* 'category_name' - Default is empty string (string). Get links by category
|
||||
* name.
|
||||
* 'hide_invisible' - Default is 1 (integer). Whether to show (default) or hide
|
||||
* links marked as 'invisible'.
|
||||
* 'show_updated' - Default is 0 (integer). Will show the time of when the
|
||||
* bookmark was last updated.
|
||||
* 'echo' - Default is 1 (integer). Whether to echo (default) or return the
|
||||
* formatted bookmarks.
|
||||
* 'categorize' - Default is 1 (integer). Whether to show links listed by
|
||||
* category (default) or show links in one column.
|
||||
* 'show_description' - Default is 0 (integer). Whether to show the description
|
||||
* of the bookmark.
|
||||
*
|
||||
* These options define how the Category name will appear before the category
|
||||
* links are displayed, if 'categorize' is 1. If 'categorize' is 0, then it will
|
||||
* display for only the 'title_li' string and only if 'title_li' is not empty.
|
||||
* 'title_li' - Default is 'Bookmarks' (translatable string). What to show
|
||||
* before the links appear.
|
||||
* 'title_before' - Default is '<h2>' (string). The HTML or text to show before
|
||||
* the 'title_li' string.
|
||||
* 'title_after' - Default is '</h2>' (string). The HTML or text to show after
|
||||
* the 'title_li' string.
|
||||
* 'class' - Default is 'linkcat' (string). The CSS class to use for the
|
||||
* 'title_li'.
|
||||
*
|
||||
* 'category_before' - Default is '<li id="%id" class="%class">'. String must
|
||||
* contain '%id' and '%class' to get
|
||||
* the id of the category and the 'class' argument. These are used for
|
||||
* formatting in themes.
|
||||
* Argument will be displayed before the 'title_before' argument.
|
||||
* 'category_after' - Default is '</li>' (string). The HTML or text that will
|
||||
* appear after the list of links.
|
||||
*
|
||||
* These are only used if 'categorize' is set to 1 or true.
|
||||
* 'category_orderby' - Default is 'name'. How to order the bookmark category
|
||||
* based on term scheme.
|
||||
* 'category_order' - Default is 'ASC'. Set the order by either ASC (ascending)
|
||||
* or DESC (descending).
|
||||
*
|
||||
* @see _walk_bookmarks() For other arguments that can be set in this function
|
||||
* and passed to _walk_bookmarks().
|
||||
* @see get_bookmarks() For other arguments that can be set in this function and
|
||||
* passed to get_bookmarks().
|
||||
* @link http://codex.wordpress.org/Template_Tags/wp_list_bookmarks
|
||||
*
|
||||
* @since 2.1.0
|
||||
* @uses _list_bookmarks() Used to iterate over all of the bookmarks and return
|
||||
* the html
|
||||
* @uses get_terms() Gets all of the categories that are for links.
|
||||
*
|
||||
* @param string|array $args Optional. Overwrite the defaults of the function
|
||||
* @return string|null Will only return if echo option is set to not echo.
|
||||
* Default is not return anything.
|
||||
*/
|
||||
function wp_list_bookmarks($args = '') {
|
||||
$defaults = array(
|
||||
'orderby' => 'name', 'order' => 'ASC',
|
||||
'limit' => -1, 'category' => '', 'exclude_category' => '',
|
||||
'category_name' => '', 'hide_invisible' => 1,
|
||||
'show_updated' => 0, 'echo' => 1,
|
||||
'categorize' => 1, 'title_li' => __('Bookmarks'),
|
||||
'title_before' => '<h2>', 'title_after' => '</h2>',
|
||||
'category_orderby' => 'name', 'category_order' => 'ASC',
|
||||
'class' => 'linkcat', 'category_before' => '<li id="%id" class="%class">',
|
||||
'category_after' => '</li>'
|
||||
);
|
||||
|
||||
$r = wp_parse_args( $args, $defaults );
|
||||
extract( $r, EXTR_SKIP );
|
||||
|
||||
$output = '';
|
||||
|
||||
if ( $categorize ) {
|
||||
//Split the bookmarks into ul's for each category
|
||||
$cats = get_terms('link_category', array('name__like' => $category_name, 'include' => $category, 'exclude' => $exclude_category, 'orderby' => $category_orderby, 'order' => $category_order, 'hierarchical' => 0));
|
||||
|
||||
foreach ( (array) $cats as $cat ) {
|
||||
$params = array_merge($r, array('category'=>$cat->term_id));
|
||||
$bookmarks = get_bookmarks($params);
|
||||
if ( empty($bookmarks) )
|
||||
continue;
|
||||
$output .= str_replace(array('%id', '%class'), array("linkcat-$cat->term_id", $class), $category_before);
|
||||
$catname = apply_filters( "link_category", $cat->name );
|
||||
$output .= "$title_before$catname$title_after\n\t<ul class='xoxo blogroll'>\n";
|
||||
$output .= _walk_bookmarks($bookmarks, $r);
|
||||
$output .= "\n\t</ul>\n$category_after\n";
|
||||
}
|
||||
} else {
|
||||
//output one single list using title_li for the title
|
||||
$bookmarks = get_bookmarks($r);
|
||||
|
||||
if ( !empty($bookmarks) ) {
|
||||
if ( !empty( $title_li ) ){
|
||||
$output .= str_replace(array('%id', '%class'), array("linkcat-$category", $class), $category_before);
|
||||
$output .= "$title_before$title_li$title_after\n\t<ul class='xoxo blogroll'>\n";
|
||||
$output .= _walk_bookmarks($bookmarks, $r);
|
||||
$output .= "\n\t</ul>\n$category_after\n";
|
||||
} else {
|
||||
$output .= _walk_bookmarks($bookmarks, $r);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$output = apply_filters( 'wp_list_bookmarks', $output );
|
||||
|
||||
if ( !$echo )
|
||||
return $output;
|
||||
echo $output;
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,370 @@
|
||||
<?php
|
||||
/**
|
||||
* Link/Bookmark API
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Bookmark
|
||||
*/
|
||||
|
||||
/**
|
||||
* Retrieve Bookmark data
|
||||
*
|
||||
* @since 2.1.0
|
||||
* @uses $wpdb Database Object
|
||||
*
|
||||
* @param mixed $bookmark
|
||||
* @param string $output Optional. Either OBJECT, ARRAY_N, or ARRAY_A constant
|
||||
* @param string $filter Optional, default is 'raw'.
|
||||
* @return array|object Type returned depends on $output value.
|
||||
*/
|
||||
function get_bookmark($bookmark, $output = OBJECT, $filter = 'raw') {
|
||||
global $wpdb;
|
||||
|
||||
if ( empty($bookmark) ) {
|
||||
if ( isset($GLOBALS['link']) )
|
||||
$_bookmark = & $GLOBALS['link'];
|
||||
else
|
||||
$_bookmark = null;
|
||||
} elseif ( is_object($bookmark) ) {
|
||||
wp_cache_add($bookmark->link_id, $bookmark, 'bookmark');
|
||||
$_bookmark = $bookmark;
|
||||
} else {
|
||||
if ( isset($GLOBALS['link']) && ($GLOBALS['link']->link_id == $bookmark) ) {
|
||||
$_bookmark = & $GLOBALS['link'];
|
||||
} elseif ( ! $_bookmark = wp_cache_get($bookmark, 'bookmark') ) {
|
||||
$_bookmark = $wpdb->get_row($wpdb->prepare("SELECT * FROM $wpdb->links WHERE link_id = %d LIMIT 1", $bookmark));
|
||||
$_bookmark->link_category = array_unique( wp_get_object_terms($_bookmark->link_id, 'link_category', array('fields' => 'ids')) );
|
||||
wp_cache_add($_bookmark->link_id, $_bookmark, 'bookmark');
|
||||
}
|
||||
}
|
||||
|
||||
$_bookmark = sanitize_bookmark($_bookmark, $filter);
|
||||
|
||||
if ( $output == OBJECT ) {
|
||||
return $_bookmark;
|
||||
} elseif ( $output == ARRAY_A ) {
|
||||
return get_object_vars($_bookmark);
|
||||
} elseif ( $output == ARRAY_N ) {
|
||||
return array_values(get_object_vars($_bookmark));
|
||||
} else {
|
||||
return $_bookmark;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve single bookmark data item or field.
|
||||
*
|
||||
* @since 2.3.0
|
||||
* @uses get_bookmark() Gets bookmark object using $bookmark as ID
|
||||
* @uses sanitize_bookmark_field() Sanitizes Bookmark field based on $context.
|
||||
*
|
||||
* @param string $field The name of the data field to return
|
||||
* @param int $bookmark The bookmark ID to get field
|
||||
* @param string $context Optional. The context of how the field will be used.
|
||||
* @return string
|
||||
*/
|
||||
function get_bookmark_field( $field, $bookmark, $context = 'display' ) {
|
||||
$bookmark = (int) $bookmark;
|
||||
$bookmark = get_bookmark( $bookmark );
|
||||
|
||||
if ( is_wp_error($bookmark) )
|
||||
return $bookmark;
|
||||
|
||||
if ( !is_object($bookmark) )
|
||||
return '';
|
||||
|
||||
if ( !isset($bookmark->$field) )
|
||||
return '';
|
||||
|
||||
return sanitize_bookmark_field($field, $bookmark->$field, $bookmark->link_id, $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the list of bookmarks
|
||||
*
|
||||
* Attempts to retrieve from the cache first based on MD5 hash of arguments. If
|
||||
* that fails, then the query will be built from the arguments and executed. The
|
||||
* results will be stored to the cache.
|
||||
*
|
||||
* List of default arguments are as follows:
|
||||
* 'orderby' - Default is 'name' (string). How to order the links by. String is
|
||||
* based off of the bookmark scheme.
|
||||
* 'order' - Default is 'ASC' (string). Either 'ASC' or 'DESC'. Orders in either
|
||||
* ascending or descending order.
|
||||
* 'limit' - Default is -1 (integer) or show all. The amount of bookmarks to
|
||||
* display.
|
||||
* 'category' - Default is empty string (string). Include the links in what
|
||||
* category ID(s).
|
||||
* 'category_name' - Default is empty string (string). Get links by category
|
||||
* name.
|
||||
* 'hide_invisible' - Default is 1 (integer). Whether to show (default) or hide
|
||||
* links marked as 'invisible'.
|
||||
* 'show_updated' - Default is 0 (integer). Will show the time of when the
|
||||
* bookmark was last updated.
|
||||
* 'include' - Default is empty string (string). Include other categories
|
||||
* separated by commas.
|
||||
* 'exclude' - Default is empty string (string). Exclude other categories
|
||||
* separated by commas.
|
||||
*
|
||||
* @since 2.1.0
|
||||
* @uses $wpdb Database Object
|
||||
* @link http://codex.wordpress.org/Template_Tags/get_bookmarks
|
||||
*
|
||||
* @param string|array $args List of arguments to overwrite the defaults
|
||||
* @return array List of bookmark row objects
|
||||
*/
|
||||
function get_bookmarks($args = '') {
|
||||
global $wpdb;
|
||||
|
||||
$defaults = array(
|
||||
'orderby' => 'name', 'order' => 'ASC',
|
||||
'limit' => -1, 'category' => '',
|
||||
'category_name' => '', 'hide_invisible' => 1,
|
||||
'show_updated' => 0, 'include' => '',
|
||||
'exclude' => '', 'search' => ''
|
||||
);
|
||||
|
||||
$r = wp_parse_args( $args, $defaults );
|
||||
extract( $r, EXTR_SKIP );
|
||||
|
||||
$cache = array();
|
||||
$key = md5( serialize( $r ) );
|
||||
if ( $cache = wp_cache_get( 'get_bookmarks', 'bookmark' ) ) {
|
||||
if ( is_array($cache) && isset( $cache[ $key ] ) )
|
||||
return apply_filters('get_bookmarks', $cache[ $key ], $r );
|
||||
}
|
||||
|
||||
if ( !is_array($cache) )
|
||||
$cache = array();
|
||||
|
||||
$inclusions = '';
|
||||
if ( !empty($include) ) {
|
||||
$exclude = ''; //ignore exclude, category, and category_name params if using include
|
||||
$category = '';
|
||||
$category_name = '';
|
||||
$inclinks = preg_split('/[\s,]+/',$include);
|
||||
if ( count($inclinks) ) {
|
||||
foreach ( $inclinks as $inclink ) {
|
||||
if (empty($inclusions))
|
||||
$inclusions = ' AND ( link_id = ' . intval($inclink) . ' ';
|
||||
else
|
||||
$inclusions .= ' OR link_id = ' . intval($inclink) . ' ';
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!empty($inclusions))
|
||||
$inclusions .= ')';
|
||||
|
||||
$exclusions = '';
|
||||
if ( !empty($exclude) ) {
|
||||
$exlinks = preg_split('/[\s,]+/',$exclude);
|
||||
if ( count($exlinks) ) {
|
||||
foreach ( $exlinks as $exlink ) {
|
||||
if (empty($exclusions))
|
||||
$exclusions = ' AND ( link_id <> ' . intval($exlink) . ' ';
|
||||
else
|
||||
$exclusions .= ' AND link_id <> ' . intval($exlink) . ' ';
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!empty($exclusions))
|
||||
$exclusions .= ')';
|
||||
|
||||
if ( !empty($category_name) ) {
|
||||
if ( $category = get_term_by('name', $category_name, 'link_category') ) {
|
||||
$category = $category->term_id;
|
||||
} else {
|
||||
$cache[ $key ] = array();
|
||||
wp_cache_set( 'get_bookmarks', $cache, 'bookmark' );
|
||||
return apply_filters( 'get_bookmarks', array(), $r );
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! empty($search) ) {
|
||||
$search = like_escape($search);
|
||||
$search = " AND ( (link_url LIKE '%$search%') OR (link_name LIKE '%$search%') OR (link_description LIKE '%$search%') ) ";
|
||||
}
|
||||
|
||||
$category_query = '';
|
||||
$join = '';
|
||||
if ( !empty($category) ) {
|
||||
$incategories = preg_split('/[\s,]+/',$category);
|
||||
if ( count($incategories) ) {
|
||||
foreach ( $incategories as $incat ) {
|
||||
if (empty($category_query))
|
||||
$category_query = ' AND ( tt.term_id = ' . intval($incat) . ' ';
|
||||
else
|
||||
$category_query .= ' OR tt.term_id = ' . intval($incat) . ' ';
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!empty($category_query)) {
|
||||
$category_query .= ") AND taxonomy = 'link_category'";
|
||||
$join = " INNER JOIN $wpdb->term_relationships AS tr ON ($wpdb->links.link_id = tr.object_id) INNER JOIN $wpdb->term_taxonomy as tt ON tt.term_taxonomy_id = tr.term_taxonomy_id";
|
||||
}
|
||||
|
||||
if ( $show_updated && get_option('links_recently_updated_time') ) {
|
||||
$recently_updated_test = ", IF (DATE_ADD(link_updated, INTERVAL " . get_option('links_recently_updated_time') . " MINUTE) >= NOW(), 1,0) as recently_updated ";
|
||||
} else {
|
||||
$recently_updated_test = '';
|
||||
}
|
||||
|
||||
$get_updated = ( $show_updated ) ? ', UNIX_TIMESTAMP(link_updated) AS link_updated_f ' : '';
|
||||
|
||||
$orderby = strtolower($orderby);
|
||||
$length = '';
|
||||
switch ($orderby) {
|
||||
case 'length':
|
||||
$length = ", CHAR_LENGTH(link_name) AS length";
|
||||
break;
|
||||
case 'rand':
|
||||
$orderby = 'rand()';
|
||||
break;
|
||||
default:
|
||||
$orderparams = array();
|
||||
foreach ( explode(',', $orderby) as $ordparam )
|
||||
$orderparams[] = 'link_' . trim($ordparam);
|
||||
$orderby = implode(',', $orderparams);
|
||||
}
|
||||
|
||||
if ( 'link_id' == $orderby )
|
||||
$orderby = "$wpdb->links.link_id";
|
||||
|
||||
$visible = '';
|
||||
if ( $hide_invisible )
|
||||
$visible = "AND link_visible = 'Y'";
|
||||
|
||||
$query = "SELECT * $length $recently_updated_test $get_updated FROM $wpdb->links $join WHERE 1=1 $visible $category_query";
|
||||
$query .= " $exclusions $inclusions $search";
|
||||
$query .= " ORDER BY $orderby $order";
|
||||
if ($limit != -1)
|
||||
$query .= " LIMIT $limit";
|
||||
|
||||
$results = $wpdb->get_results($query);
|
||||
|
||||
$cache[ $key ] = $results;
|
||||
wp_cache_set( 'get_bookmarks', $cache, 'bookmark' );
|
||||
|
||||
return apply_filters('get_bookmarks', $results, $r);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitizes all bookmark fields
|
||||
*
|
||||
* @since 2.3.0
|
||||
*
|
||||
* @param object|array $bookmark Bookmark row
|
||||
* @param string $context Optional, default is 'display'. How to filter the
|
||||
* fields
|
||||
* @return object|array Same type as $bookmark but with fields sanitized.
|
||||
*/
|
||||
function sanitize_bookmark($bookmark, $context = 'display') {
|
||||
$fields = array('link_id', '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', );
|
||||
|
||||
if ( is_object($bookmark) ) {
|
||||
$do_object = true;
|
||||
$link_id = $bookmark->link_id;
|
||||
} else {
|
||||
$do_object = false;
|
||||
$link_id = $bookmark['link_id'];
|
||||
}
|
||||
|
||||
foreach ( $fields as $field ) {
|
||||
if ( $do_object ) {
|
||||
if ( isset($bookmark->$field) )
|
||||
$bookmark->$field = sanitize_bookmark_field($field, $bookmark->$field, $link_id, $context);
|
||||
} else {
|
||||
if ( isset($bookmark[$field]) )
|
||||
$bookmark[$field] = sanitize_bookmark_field($field, $bookmark[$field], $link_id, $context);
|
||||
}
|
||||
}
|
||||
|
||||
return $bookmark;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitizes a bookmark field
|
||||
*
|
||||
* Sanitizes the bookmark fields based on what the field name is. If the field
|
||||
* has a strict value set, then it will be tested for that, else a more generic
|
||||
* filtering is applied. After the more strict filter is applied, if the
|
||||
* $context is 'raw' then the value is immediately return.
|
||||
*
|
||||
* Hooks exist for the more generic cases. With the 'edit' context, the
|
||||
* 'edit_$field' filter will be called and passed the $value and $bookmark_id
|
||||
* respectively. With the 'db' context, the 'pre_$field' filter is called and
|
||||
* passed the value. The 'display' context is the final context and has the
|
||||
* $field has the filter name and is passed the $value, $bookmark_id, and
|
||||
* $context respectively.
|
||||
*
|
||||
* @since 2.3.0
|
||||
*
|
||||
* @param string $field The bookmark field
|
||||
* @param mixed $value The bookmark field value
|
||||
* @param int $bookmark_id Bookmark ID
|
||||
* @param string $context How to filter the field value. Either 'raw', 'edit',
|
||||
* 'attribute', 'js', 'db', or 'display'
|
||||
* @return mixed The filtered value
|
||||
*/
|
||||
function sanitize_bookmark_field($field, $value, $bookmark_id, $context) {
|
||||
switch ( $field ) {
|
||||
case 'link_id' : // ints
|
||||
case 'link_rating' :
|
||||
$value = (int) $value;
|
||||
break;
|
||||
case 'link_category' : // array( ints )
|
||||
$value = array_map('absint', (array) $value);
|
||||
// We return here so that the categories aren't filtered.
|
||||
// The 'link_category' filter is for the name of a link category, not an array of a link's link categories
|
||||
return $value;
|
||||
break;
|
||||
case 'link_visible' : // bool stored as Y|N
|
||||
$value = preg_replace('/[^YNyn]/', '', $value);
|
||||
break;
|
||||
case 'link_target' : // "enum"
|
||||
$targets = array('_top', '_blank');
|
||||
if ( ! in_array($value, $targets) )
|
||||
$value = '';
|
||||
break;
|
||||
}
|
||||
|
||||
if ( 'raw' == $context )
|
||||
return $value;
|
||||
|
||||
if ( 'edit' == $context ) {
|
||||
$value = apply_filters("edit_$field", $value, $bookmark_id);
|
||||
|
||||
if ( 'link_notes' == $field ) {
|
||||
$value = esc_html( $value ); // textarea_escaped
|
||||
} else {
|
||||
$value = esc_attr($value);
|
||||
}
|
||||
} else if ( 'db' == $context ) {
|
||||
$value = apply_filters("pre_$field", $value);
|
||||
} else {
|
||||
// Use display filters by default.
|
||||
$value = apply_filters($field, $value, $bookmark_id, $context);
|
||||
|
||||
if ( 'attribute' == $context )
|
||||
$value = esc_attr($value);
|
||||
else if ( 'js' == $context )
|
||||
$value = esc_js($value);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes bookmark cache
|
||||
*
|
||||
* @since 2.7.0
|
||||
* @uses wp_cache_delete() Deletes the contents of 'get_bookmarks'
|
||||
*/
|
||||
function clean_bookmark_cache($bookmark_id) {
|
||||
wp_cache_delete( $bookmark_id, 'bookmark' );
|
||||
wp_cache_delete( 'get_bookmarks', 'bookmark' );
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,497 @@
|
||||
<?php
|
||||
/**
|
||||
* Object Cache API
|
||||
*
|
||||
* @link http://codex.wordpress.org/Function_Reference/WP_Cache
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Cache
|
||||
*/
|
||||
|
||||
/**
|
||||
* Adds data to the cache, if the cache key doesn't aleady exist.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @uses $wp_object_cache Object Cache Class
|
||||
* @see WP_Object_Cache::add()
|
||||
*
|
||||
* @param int|string $key The cache ID to use for retrieval later
|
||||
* @param mixed $data The data to add to the cache store
|
||||
* @param string $flag The group to add the cache to
|
||||
* @param int $expire When the cache data should be expired
|
||||
* @return unknown
|
||||
*/
|
||||
function wp_cache_add($key, $data, $flag = '', $expire = 0) {
|
||||
global $wp_object_cache;
|
||||
|
||||
return $wp_object_cache->add($key, $data, $flag, $expire);
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the cache.
|
||||
*
|
||||
* This function has ceased to do anything since WordPress 2.5. The
|
||||
* functionality was removed along with the rest of the persistant cache. This
|
||||
* does not mean that plugins can't implement this function when they need to
|
||||
* make sure that the cache is cleaned up after WordPress no longer needs it.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @return bool Always returns True
|
||||
*/
|
||||
function wp_cache_close() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the cache contents matching ID and flag.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @uses $wp_object_cache Object Cache Class
|
||||
* @see WP_Object_Cache::delete()
|
||||
*
|
||||
* @param int|string $id What the contents in the cache are called
|
||||
* @param string $flag Where the cache contents are grouped
|
||||
* @return bool True on successful removal, false on failure
|
||||
*/
|
||||
function wp_cache_delete($id, $flag = '') {
|
||||
global $wp_object_cache;
|
||||
|
||||
return $wp_object_cache->delete($id, $flag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all cache items.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @uses $wp_object_cache Object Cache Class
|
||||
* @see WP_Object_Cache::flush()
|
||||
*
|
||||
* @return bool Always returns true
|
||||
*/
|
||||
function wp_cache_flush() {
|
||||
global $wp_object_cache;
|
||||
|
||||
return $wp_object_cache->flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the cache contents from the cache by ID and flag.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @uses $wp_object_cache Object Cache Class
|
||||
* @see WP_Object_Cache::get()
|
||||
*
|
||||
* @param int|string $id What the contents in the cache are called
|
||||
* @param string $flag Where the cache contents are grouped
|
||||
* @return bool|mixed False on failure to retrieve contents or the cache
|
||||
* contents on success
|
||||
*/
|
||||
function wp_cache_get($id, $flag = '') {
|
||||
global $wp_object_cache;
|
||||
|
||||
return $wp_object_cache->get($id, $flag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up Object Cache Global and assigns it.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @global WP_Object_Cache $wp_object_cache WordPress Object Cache
|
||||
*/
|
||||
function wp_cache_init() {
|
||||
$GLOBALS['wp_object_cache'] =& new WP_Object_Cache();
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces the contents of the cache with new data.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @uses $wp_object_cache Object Cache Class
|
||||
* @see WP_Object_Cache::replace()
|
||||
*
|
||||
* @param int|string $key What to call the contents in the cache
|
||||
* @param mixed $data The contents to store in the cache
|
||||
* @param string $flag Where to group the cache contents
|
||||
* @param int $expire When to expire the cache contents
|
||||
* @return bool False if cache ID and group already exists, true on success
|
||||
*/
|
||||
function wp_cache_replace($key, $data, $flag = '', $expire = 0) {
|
||||
global $wp_object_cache;
|
||||
|
||||
return $wp_object_cache->replace($key, $data, $flag, $expire);
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the data to the cache.
|
||||
*
|
||||
* @since 2.0
|
||||
* @uses $wp_object_cache Object Cache Class
|
||||
* @see WP_Object_Cache::set()
|
||||
*
|
||||
* @param int|string $key What to call the contents in the cache
|
||||
* @param mixed $data The contents to store in the cache
|
||||
* @param string $flag Where to group the cache contents
|
||||
* @param int $expire When to expire the cache contents
|
||||
* @return bool False if cache ID and group already exists, true on success
|
||||
*/
|
||||
function wp_cache_set($key, $data, $flag = '', $expire = 0) {
|
||||
global $wp_object_cache;
|
||||
|
||||
return $wp_object_cache->set($key, $data, $flag, $expire);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a group or set of groups to the list of global groups.
|
||||
*
|
||||
* @since 2.6.0
|
||||
*
|
||||
* @param string|array $groups A group or an array of groups to add
|
||||
*/
|
||||
function wp_cache_add_global_groups( $groups ) {
|
||||
global $wp_object_cache;
|
||||
|
||||
return $wp_object_cache->add_global_groups($groups);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a group or set of groups to the list of non-persistent groups.
|
||||
*
|
||||
* @since 2.6.0
|
||||
*
|
||||
* @param string|array $groups A group or an array of groups to add
|
||||
*/
|
||||
function wp_cache_add_non_persistent_groups( $groups ) {
|
||||
// Default cache doesn't persist so nothing to do here.
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset internal cache keys and structures. If the cache backend uses global blog or site IDs as part of its cache keys,
|
||||
* this function instructs the backend to reset those keys and perform any cleanup since blog or site IDs have changed since cache init.
|
||||
*
|
||||
* @since 2.6.0
|
||||
*/
|
||||
function wp_cache_reset() {
|
||||
global $wp_object_cache;
|
||||
|
||||
return $wp_object_cache->reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* WordPress Object Cache
|
||||
*
|
||||
* The WordPress Object Cache is used to save on trips to the database. The
|
||||
* Object Cache stores all of the cache data to memory and makes the cache
|
||||
* contents available by using a key, which is used to name and later retrieve
|
||||
* the cache contents.
|
||||
*
|
||||
* The Object Cache can be replaced by other caching mechanisms by placing files
|
||||
* in the wp-content folder which is looked at in wp-settings. If that file
|
||||
* exists, then this file will not be included.
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Cache
|
||||
* @since 2.0
|
||||
*/
|
||||
class WP_Object_Cache {
|
||||
|
||||
/**
|
||||
* Holds the cached objects
|
||||
*
|
||||
* @var array
|
||||
* @access private
|
||||
* @since 2.0.0
|
||||
*/
|
||||
var $cache = array ();
|
||||
|
||||
/**
|
||||
* Cache objects that do not exist in the cache
|
||||
*
|
||||
* @var array
|
||||
* @access private
|
||||
* @since 2.0.0
|
||||
*/
|
||||
var $non_existent_objects = array ();
|
||||
|
||||
/**
|
||||
* The amount of times the cache data was already stored in the cache.
|
||||
*
|
||||
* @since 2.5.0
|
||||
* @access private
|
||||
* @var int
|
||||
*/
|
||||
var $cache_hits = 0;
|
||||
|
||||
/**
|
||||
* Amount of times the cache did not have the request in cache
|
||||
*
|
||||
* @var int
|
||||
* @access public
|
||||
* @since 2.0.0
|
||||
*/
|
||||
var $cache_misses = 0;
|
||||
|
||||
/**
|
||||
* List of global groups
|
||||
*
|
||||
* @var array
|
||||
* @access protected
|
||||
* @since 3.0.0
|
||||
*/
|
||||
var $global_groups = array();
|
||||
|
||||
/**
|
||||
* Adds data to the cache if it doesn't already exist.
|
||||
*
|
||||
* @uses WP_Object_Cache::get Checks to see if the cache already has data.
|
||||
* @uses WP_Object_Cache::set Sets the data after the checking the cache
|
||||
* contents existance.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param int|string $id What to call the contents in the cache
|
||||
* @param mixed $data The contents to store in the cache
|
||||
* @param string $group Where to group the cache contents
|
||||
* @param int $expire When to expire the cache contents
|
||||
* @return bool False if cache ID and group already exists, true on success
|
||||
*/
|
||||
function add( $id, $data, $group = 'default', $expire = '' ) {
|
||||
if ( empty ($group) )
|
||||
$group = 'default';
|
||||
|
||||
if (false !== $this->get($id, $group))
|
||||
return false;
|
||||
|
||||
return $this->set($id, $data, $group, $expire);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the list of global groups.
|
||||
*
|
||||
* @since 3.0.0
|
||||
*
|
||||
* @param array $groups List of groups that are global.
|
||||
*/
|
||||
function add_global_groups( $groups ) {
|
||||
$groups = (array) $groups;
|
||||
|
||||
$this->global_groups = array_merge($this->global_groups, $groups);
|
||||
$this->global_groups = array_unique($this->global_groups);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the contents of the cache ID in the group
|
||||
*
|
||||
* If the cache ID does not exist in the group and $force parameter is set
|
||||
* to false, then nothing will happen. The $force parameter is set to false
|
||||
* by default.
|
||||
*
|
||||
* On success the group and the id will be added to the
|
||||
* $non_existent_objects property in the class.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param int|string $id What the contents in the cache are called
|
||||
* @param string $group Where the cache contents are grouped
|
||||
* @param bool $force Optional. Whether to force the unsetting of the cache
|
||||
* ID in the group
|
||||
* @return bool False if the contents weren't deleted and true on success
|
||||
*/
|
||||
function delete($id, $group = 'default', $force = false) {
|
||||
if (empty ($group))
|
||||
$group = 'default';
|
||||
|
||||
if (!$force && false === $this->get($id, $group))
|
||||
return false;
|
||||
|
||||
unset ($this->cache[$group][$id]);
|
||||
$this->non_existent_objects[$group][$id] = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the object cache of all data
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @return bool Always returns true
|
||||
*/
|
||||
function flush() {
|
||||
$this->cache = array ();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the cache contents, if it exists
|
||||
*
|
||||
* The contents will be first attempted to be retrieved by searching by the
|
||||
* ID in the cache group. If the cache is hit (success) then the contents
|
||||
* are returned.
|
||||
*
|
||||
* On failure, the $non_existent_objects property is checked and if the
|
||||
* cache group and ID exist in there the cache misses will not be
|
||||
* incremented. If not in the nonexistent objects property, then the cache
|
||||
* misses will be incremented and the cache group and ID will be added to
|
||||
* the nonexistent objects.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param int|string $id What the contents in the cache are called
|
||||
* @param string $group Where the cache contents are grouped
|
||||
* @return bool|mixed False on failure to retrieve contents or the cache
|
||||
* contents on success
|
||||
*/
|
||||
function get($id, $group = 'default') {
|
||||
if ( empty ($group) )
|
||||
$group = 'default';
|
||||
|
||||
if ( isset ($this->cache[$group][$id]) ) {
|
||||
$this->cache_hits += 1;
|
||||
if ( is_object($this->cache[$group][$id]) )
|
||||
return wp_clone($this->cache[$group][$id]);
|
||||
else
|
||||
return $this->cache[$group][$id];
|
||||
}
|
||||
|
||||
if ( isset ($this->non_existent_objects[$group][$id]) )
|
||||
return false;
|
||||
|
||||
$this->non_existent_objects[$group][$id] = true;
|
||||
$this->cache_misses += 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace the contents in the cache, if contents already exist
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @see WP_Object_Cache::set()
|
||||
*
|
||||
* @param int|string $id What to call the contents in the cache
|
||||
* @param mixed $data The contents to store in the cache
|
||||
* @param string $group Where to group the cache contents
|
||||
* @param int $expire When to expire the cache contents
|
||||
* @return bool False if not exists, true if contents were replaced
|
||||
*/
|
||||
function replace($id, $data, $group = 'default', $expire = '') {
|
||||
if (empty ($group))
|
||||
$group = 'default';
|
||||
|
||||
if ( false === $this->get($id, $group) )
|
||||
return false;
|
||||
|
||||
return $this->set($id, $data, $group, $expire);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset keys
|
||||
*
|
||||
* @since 3.0.0
|
||||
*/
|
||||
function reset() {
|
||||
// Clear out non-global caches since the blog ID has changed.
|
||||
foreach ( array_keys($this->cache) as $group ) {
|
||||
if ( !in_array($group, $this->global_groups) )
|
||||
unset($this->cache[$group]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the data contents into the cache
|
||||
*
|
||||
* The cache contents is grouped by the $group parameter followed by the
|
||||
* $id. This allows for duplicate ids in unique groups. Therefore, naming of
|
||||
* the group should be used with care and should follow normal function
|
||||
* naming guidelines outside of core WordPress usage.
|
||||
*
|
||||
* The $expire parameter is not used, because the cache will automatically
|
||||
* expire for each time a page is accessed and PHP finishes. The method is
|
||||
* more for cache plugins which use files.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param int|string $id What to call the contents in the cache
|
||||
* @param mixed $data The contents to store in the cache
|
||||
* @param string $group Where to group the cache contents
|
||||
* @param int $expire Not Used
|
||||
* @return bool Always returns true
|
||||
*/
|
||||
function set($id, $data, $group = 'default', $expire = '') {
|
||||
if ( empty ($group) )
|
||||
$group = 'default';
|
||||
|
||||
if ( NULL === $data )
|
||||
$data = '';
|
||||
|
||||
if ( is_object($data) )
|
||||
$data = wp_clone($data);
|
||||
|
||||
$this->cache[$group][$id] = $data;
|
||||
|
||||
if ( isset($this->non_existent_objects[$group][$id]) )
|
||||
unset ($this->non_existent_objects[$group][$id]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Echoes the stats of the caching.
|
||||
*
|
||||
* Gives the cache hits, and cache misses. Also prints every cached group,
|
||||
* key and the data.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
function stats() {
|
||||
echo "<p>";
|
||||
echo "<strong>Cache Hits:</strong> {$this->cache_hits}<br />";
|
||||
echo "<strong>Cache Misses:</strong> {$this->cache_misses}<br />";
|
||||
echo "</p>";
|
||||
echo '<ul>';
|
||||
foreach ($this->cache as $group => $cache) {
|
||||
echo "<li><strong>Group:</strong> $group - ( " . number_format( strlen( serialize( $cache ) ) / 1024, 2 ) . 'k )</li>';
|
||||
}
|
||||
echo '</ul>';
|
||||
}
|
||||
|
||||
/**
|
||||
* PHP4 constructor; Calls PHP 5 style constructor
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @return WP_Object_Cache
|
||||
*/
|
||||
function WP_Object_Cache() {
|
||||
return $this->__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up object properties; PHP 5 style constructor
|
||||
*
|
||||
* @since 2.0.8
|
||||
* @return null|WP_Object_Cache If cache is disabled, returns null.
|
||||
*/
|
||||
function __construct() {
|
||||
/**
|
||||
* @todo This should be moved to the PHP4 style constructor, PHP5
|
||||
* already calls __destruct()
|
||||
*/
|
||||
register_shutdown_function(array(&$this, "__destruct"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Will save the object cache before object is completely destroyed.
|
||||
*
|
||||
* Called upon object destruction, which should be when PHP ends.
|
||||
*
|
||||
* @since 2.0.8
|
||||
*
|
||||
* @return bool True value. Won't be used by PHP
|
||||
*/
|
||||
function __destruct() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,414 @@
|
||||
<?php
|
||||
/**
|
||||
* Canonical API to handle WordPress Redirecting
|
||||
*
|
||||
* Based on "Permalink Redirect" from Scott Yang and "Enforce www. Preference"
|
||||
* by Mark Jaquith
|
||||
*
|
||||
* @package WordPress
|
||||
* @since 2.3.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Redirects incoming links to the proper URL based on the site url.
|
||||
*
|
||||
* Search engines consider www.somedomain.com and somedomain.com to be two
|
||||
* different URLs when they both go to the same location. This SEO enhancement
|
||||
* prevents penality for duplicate content by redirecting all incoming links to
|
||||
* one or the other.
|
||||
*
|
||||
* Prevents redirection for feeds, trackbacks, searches, comment popup, and
|
||||
* admin URLs. Does not redirect on IIS, page/post previews, and on form data.
|
||||
*
|
||||
* Will also attempt to find the correct link when a user enters a URL that does
|
||||
* not exist based on exact WordPress query. Will instead try to parse the URL
|
||||
* or query in an attempt to figure the correct page to go to.
|
||||
*
|
||||
* @since 2.3.0
|
||||
* @uses $wp_rewrite
|
||||
* @uses $is_IIS
|
||||
*
|
||||
* @param string $requested_url Optional. The URL that was requested, used to
|
||||
* figure if redirect is needed.
|
||||
* @param bool $do_redirect Optional. Redirect to the new URL.
|
||||
* @return null|false|string Null, if redirect not needed. False, if redirect
|
||||
* not needed or the string of the URL
|
||||
*/
|
||||
function redirect_canonical( $requested_url = null, $do_redirect = true ) {
|
||||
global $wp_rewrite, $is_IIS, $wp_query, $wpdb;
|
||||
|
||||
if ( is_trackback() || is_search() || is_comments_popup() || is_admin() || !empty($_POST) || is_preview() || is_robots() || $is_IIS )
|
||||
return;
|
||||
|
||||
if ( !$requested_url ) {
|
||||
// build the URL in the address bar
|
||||
$requested_url = is_ssl() ? 'https://' : 'http://';
|
||||
$requested_url .= $_SERVER['HTTP_HOST'];
|
||||
$requested_url .= $_SERVER['REQUEST_URI'];
|
||||
}
|
||||
|
||||
$original = @parse_url($requested_url);
|
||||
if ( false === $original )
|
||||
return;
|
||||
|
||||
// Some PHP setups turn requests for / into /index.php in REQUEST_URI
|
||||
// See: http://trac.wordpress.org/ticket/5017
|
||||
// See: http://trac.wordpress.org/ticket/7173
|
||||
// Disabled, for now:
|
||||
// $original['path'] = preg_replace('|/index\.php$|', '/', $original['path']);
|
||||
|
||||
$redirect = $original;
|
||||
$redirect_url = false;
|
||||
|
||||
// Notice fixing
|
||||
if ( !isset($redirect['path']) )
|
||||
$redirect['path'] = '';
|
||||
if ( !isset($redirect['query']) )
|
||||
$redirect['query'] = '';
|
||||
|
||||
if ( is_singular() && 1 > $wp_query->post_count && ($id = get_query_var('p')) ) {
|
||||
|
||||
$vars = $wpdb->get_results( $wpdb->prepare("SELECT post_type, post_parent FROM $wpdb->posts WHERE ID = %d", $id) );
|
||||
|
||||
if ( isset($vars[0]) && $vars = $vars[0] ) {
|
||||
if ( 'revision' == $vars->post_type && $vars->post_parent > 0 )
|
||||
$id = $vars->post_parent;
|
||||
|
||||
if ( $redirect_url = get_permalink($id) )
|
||||
$redirect['query'] = remove_query_arg(array('p', 'page_id', 'attachment_id', 'post_type'), $redirect['query']);
|
||||
}
|
||||
}
|
||||
|
||||
// These tests give us a WP-generated permalink
|
||||
if ( is_404() ) {
|
||||
|
||||
// Redirect ?page_id, ?p=, ?attachment_id= to their respective url's
|
||||
$id = max( get_query_var('p'), get_query_var('page_id'), get_query_var('attachment_id') );
|
||||
if ( $id && $redirect_post = get_post($id) ) {
|
||||
$post_type_obj = get_post_type_object($redirect_post->post_type);
|
||||
if ( $post_type_obj->public ) {
|
||||
$redirect_url = get_permalink($redirect_post);
|
||||
$redirect['query'] = remove_query_arg(array('p', 'page_id', 'attachment_id', 'post_type'), $redirect['query']);
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! $redirect_url )
|
||||
$redirect_url = redirect_guess_404_permalink();
|
||||
|
||||
} elseif ( is_object($wp_rewrite) && $wp_rewrite->using_permalinks() ) {
|
||||
// rewriting of old ?p=X, ?m=2004, ?m=200401, ?m=20040101
|
||||
if ( is_attachment() && !empty($_GET['attachment_id']) && ! $redirect_url ) {
|
||||
if ( $redirect_url = get_attachment_link(get_query_var('attachment_id')) )
|
||||
$redirect['query'] = remove_query_arg('attachment_id', $redirect['query']);
|
||||
} elseif ( is_single() && !empty($_GET['p']) && ! $redirect_url ) {
|
||||
if ( $redirect_url = get_permalink(get_query_var('p')) )
|
||||
$redirect['query'] = remove_query_arg(array('p', 'post_type'), $redirect['query']);
|
||||
} elseif ( is_single() && !empty($_GET['name']) && ! $redirect_url ) {
|
||||
if ( $redirect_url = get_permalink( $wp_query->get_queried_object_id() ) )
|
||||
$redirect['query'] = remove_query_arg('name', $redirect['query']);
|
||||
} elseif ( is_page() && !empty($_GET['page_id']) && ! $redirect_url ) {
|
||||
if ( $redirect_url = get_permalink(get_query_var('page_id')) )
|
||||
$redirect['query'] = remove_query_arg('page_id', $redirect['query']);
|
||||
} elseif ( is_page() && !is_feed() && isset($wp_query->queried_object) && 'page' == get_option('show_on_front') && $wp_query->queried_object->ID == get_option('page_on_front') && ! $redirect_url ) {
|
||||
$redirect_url = home_url('/');
|
||||
} elseif ( is_home() && !empty($_GET['page_id']) && 'page' == get_option('show_on_front') && get_query_var('page_id') == get_option('page_for_posts') && ! $redirect_url ) {
|
||||
if ( $redirect_url = get_permalink(get_option('page_for_posts')) )
|
||||
$redirect['query'] = remove_query_arg('page_id', $redirect['query']);
|
||||
} elseif ( !empty($_GET['m']) && ( is_year() || is_month() || is_day() ) ) {
|
||||
$m = get_query_var('m');
|
||||
switch ( strlen($m) ) {
|
||||
case 4: // Yearly
|
||||
$redirect_url = get_year_link($m);
|
||||
break;
|
||||
case 6: // Monthly
|
||||
$redirect_url = get_month_link( substr($m, 0, 4), substr($m, 4, 2) );
|
||||
break;
|
||||
case 8: // Daily
|
||||
$redirect_url = get_day_link(substr($m, 0, 4), substr($m, 4, 2), substr($m, 6, 2));
|
||||
break;
|
||||
}
|
||||
if ( $redirect_url )
|
||||
$redirect['query'] = remove_query_arg('m', $redirect['query']);
|
||||
// now moving on to non ?m=X year/month/day links
|
||||
} elseif ( is_day() && get_query_var('year') && get_query_var('monthnum') && !empty($_GET['day']) ) {
|
||||
if ( $redirect_url = get_day_link(get_query_var('year'), get_query_var('monthnum'), get_query_var('day')) )
|
||||
$redirect['query'] = remove_query_arg(array('year', 'monthnum', 'day'), $redirect['query']);
|
||||
} elseif ( is_month() && get_query_var('year') && !empty($_GET['monthnum']) ) {
|
||||
if ( $redirect_url = get_month_link(get_query_var('year'), get_query_var('monthnum')) )
|
||||
$redirect['query'] = remove_query_arg(array('year', 'monthnum'), $redirect['query']);
|
||||
} elseif ( is_year() && !empty($_GET['year']) ) {
|
||||
if ( $redirect_url = get_year_link(get_query_var('year')) )
|
||||
$redirect['query'] = remove_query_arg('year', $redirect['query']);
|
||||
} elseif ( is_author() && !empty($_GET['author']) && preg_match( '|^[0-9]+$|', $_GET['author'] ) ) {
|
||||
$author = get_userdata(get_query_var('author'));
|
||||
if ( false !== $author && $redirect_url = get_author_posts_url($author->ID, $author->user_nicename) )
|
||||
$redirect['query'] = remove_query_arg('author', $redirect['query']);
|
||||
} elseif ( is_category() || is_tag() || is_tax() ) { // Terms (Tags/categories)
|
||||
|
||||
$term_count = 0;
|
||||
foreach ( $wp_query->tax_query->queries as $tax_query )
|
||||
$term_count += count( $tax_query['terms'] );
|
||||
|
||||
$obj = $wp_query->get_queried_object();
|
||||
if ( $term_count <= 1 && !empty($obj->term_id) && ( $tax_url = get_term_link((int)$obj->term_id, $obj->taxonomy) ) && !is_wp_error($tax_url) && !empty($redirect['query']) ) {
|
||||
if ( !empty($redirect['query']) ) {
|
||||
if ( is_category() ) {
|
||||
$redirect['query'] = remove_query_arg( array( 'category_name', 'category', 'cat'), $redirect['query']);
|
||||
} elseif ( is_tag() ) {
|
||||
$redirect['query'] = remove_query_arg( array( 'tag', 'tag_id'), $redirect['query']);
|
||||
} elseif ( is_tax() ) { // Custom taxonomies will have a custom query var, remove those too:
|
||||
$tax = get_taxonomy( $obj->taxonomy );
|
||||
if ( false !== $tax->query_var)
|
||||
$redirect['query'] = remove_query_arg($tax->query_var, $redirect['query']);
|
||||
else
|
||||
$redirect['query'] = remove_query_arg( array( 'term', 'taxonomy'), $redirect['query']);
|
||||
}
|
||||
}
|
||||
$tax_url = parse_url($tax_url);
|
||||
if ( ! empty($tax_url['query']) ) { // Custom taxonomies may only be accessable via ?taxonomy=..&term=..
|
||||
parse_str($tax_url['query'], $query_vars);
|
||||
$redirect['query'] = add_query_arg($query_vars, $redirect['query']);
|
||||
} else { // Taxonomy is accessable via a "pretty-URL"
|
||||
$redirect['path'] = $tax_url['path'];
|
||||
}
|
||||
}
|
||||
} elseif ( is_single() && strpos($wp_rewrite->permalink_structure, '%category%') !== false ) {
|
||||
$category = get_category_by_path(get_query_var('category_name'));
|
||||
$post_terms = wp_get_object_terms($wp_query->get_queried_object_id(), 'category', array('fields' => 'tt_ids'));
|
||||
if ( (!$category || is_wp_error($category)) || ( !is_wp_error($post_terms) && !empty($post_terms) && !in_array($category->term_taxonomy_id, $post_terms) ) )
|
||||
$redirect_url = get_permalink($wp_query->get_queried_object_id());
|
||||
}
|
||||
|
||||
// Post Paging
|
||||
if ( is_singular() && get_query_var('page') && $redirect_url ) {
|
||||
$redirect_url = trailingslashit( $redirect_url ) . user_trailingslashit( get_query_var( 'page' ), 'single_paged' );
|
||||
$redirect['query'] = remove_query_arg( 'page', $redirect['query'] );
|
||||
}
|
||||
|
||||
// paging and feeds
|
||||
if ( get_query_var('paged') || is_feed() || get_query_var('cpage') ) {
|
||||
while ( preg_match( "#/$wp_rewrite->pagination_base/?[0-9]+?(/+)?$#", $redirect['path'] ) || preg_match( '#/(comments/?)?(feed|rss|rdf|atom|rss2)(/+)?$#', $redirect['path'] ) || preg_match( '#/comment-page-[0-9]+(/+)?$#', $redirect['path'] ) ) {
|
||||
// Strip off paging and feed
|
||||
$redirect['path'] = preg_replace("#/$wp_rewrite->pagination_base/?[0-9]+?(/+)?$#", '/', $redirect['path']); // strip off any existing paging
|
||||
$redirect['path'] = preg_replace('#/(comments/?)?(feed|rss2?|rdf|atom)(/+|$)#', '/', $redirect['path']); // strip off feed endings
|
||||
$redirect['path'] = preg_replace('#/comment-page-[0-9]+?(/+)?$#', '/', $redirect['path']); // strip off any existing comment paging
|
||||
}
|
||||
|
||||
$addl_path = '';
|
||||
if ( is_feed() && in_array( get_query_var('feed'), $wp_rewrite->feeds ) ) {
|
||||
$addl_path = !empty( $addl_path ) ? trailingslashit($addl_path) : '';
|
||||
if ( get_query_var( 'withcomments' ) )
|
||||
$addl_path .= 'comments/';
|
||||
$addl_path .= user_trailingslashit( 'feed/' . ( ( get_default_feed() == get_query_var('feed') || 'feed' == get_query_var('feed') ) ? '' : get_query_var('feed') ), 'feed' );
|
||||
$redirect['query'] = remove_query_arg( 'feed', $redirect['query'] );
|
||||
}
|
||||
|
||||
if ( get_query_var('paged') > 0 ) {
|
||||
$paged = get_query_var('paged');
|
||||
$redirect['query'] = remove_query_arg( 'paged', $redirect['query'] );
|
||||
if ( !is_feed() ) {
|
||||
if ( $paged > 1 && !is_single() ) {
|
||||
$addl_path = ( !empty( $addl_path ) ? trailingslashit($addl_path) : '' ) . user_trailingslashit("$wp_rewrite->pagination_base/$paged", 'paged');
|
||||
} elseif ( !is_single() ) {
|
||||
$addl_path = !empty( $addl_path ) ? trailingslashit($addl_path) : '';
|
||||
}
|
||||
} elseif ( $paged > 1 ) {
|
||||
$redirect['query'] = add_query_arg( 'paged', $paged, $redirect['query'] );
|
||||
}
|
||||
}
|
||||
|
||||
if ( get_option('page_comments') && ( ( 'newest' == get_option('default_comments_page') && get_query_var('cpage') > 0 ) || ( 'newest' != get_option('default_comments_page') && get_query_var('cpage') > 1 ) ) ) {
|
||||
$addl_path = ( !empty( $addl_path ) ? trailingslashit($addl_path) : '' ) . user_trailingslashit( 'comment-page-' . get_query_var('cpage'), 'commentpaged' );
|
||||
$redirect['query'] = remove_query_arg( 'cpage', $redirect['query'] );
|
||||
}
|
||||
|
||||
$redirect['path'] = user_trailingslashit( preg_replace('|/index.php/?$|', '/', $redirect['path']) ); // strip off trailing /index.php/
|
||||
if ( !empty( $addl_path ) && $wp_rewrite->using_index_permalinks() && strpos($redirect['path'], '/index.php/') === false )
|
||||
$redirect['path'] = trailingslashit($redirect['path']) . 'index.php/';
|
||||
if ( !empty( $addl_path ) )
|
||||
$redirect['path'] = trailingslashit($redirect['path']) . $addl_path;
|
||||
$redirect_url = $redirect['scheme'] . '://' . $redirect['host'] . $redirect['path'];
|
||||
}
|
||||
}
|
||||
|
||||
// tack on any additional query vars
|
||||
$redirect['query'] = preg_replace( '#^\??&*?#', '', $redirect['query'] );
|
||||
if ( $redirect_url && !empty($redirect['query']) ) {
|
||||
parse_str( $redirect['query'], $_parsed_query );
|
||||
$redirect = @parse_url($redirect_url);
|
||||
|
||||
if ( ! empty( $_parsed_query['name'] ) && ! empty( $redirect['query'] ) ) {
|
||||
parse_str( $redirect['query'], $_parsed_redirect_query );
|
||||
|
||||
if ( empty( $_parsed_redirect_query['name'] ) )
|
||||
unset( $_parsed_query['name'] );
|
||||
}
|
||||
|
||||
$redirect_url = add_query_arg( $_parsed_query, $redirect_url );
|
||||
}
|
||||
|
||||
if ( $redirect_url )
|
||||
$redirect = @parse_url($redirect_url);
|
||||
|
||||
// www.example.com vs example.com
|
||||
$user_home = @parse_url(home_url());
|
||||
if ( !empty($user_home['host']) )
|
||||
$redirect['host'] = $user_home['host'];
|
||||
if ( empty($user_home['path']) )
|
||||
$user_home['path'] = '/';
|
||||
|
||||
// Handle ports
|
||||
if ( !empty($user_home['port']) )
|
||||
$redirect['port'] = $user_home['port'];
|
||||
else
|
||||
unset($redirect['port']);
|
||||
|
||||
// trailing /index.php
|
||||
$redirect['path'] = preg_replace('|/index.php/*?$|', '/', $redirect['path']);
|
||||
|
||||
// Remove trailing spaces from the path
|
||||
$redirect['path'] = preg_replace( '#(%20| )+$#', '', $redirect['path'] );
|
||||
|
||||
if ( !empty( $redirect['query'] ) ) {
|
||||
// Remove trailing spaces from certain terminating query string args
|
||||
$redirect['query'] = preg_replace( '#((p|page_id|cat|tag)=[^&]*?)(%20| )+$#', '$1', $redirect['query'] );
|
||||
|
||||
// Clean up empty query strings
|
||||
$redirect['query'] = trim(preg_replace( '#(^|&)(p|page_id|cat|tag)=?(&|$)#', '&', $redirect['query']), '&');
|
||||
|
||||
// Remove redundant leading ampersands
|
||||
$redirect['query'] = preg_replace( '#^\??&*?#', '', $redirect['query'] );
|
||||
}
|
||||
|
||||
// strip /index.php/ when we're not using PATHINFO permalinks
|
||||
if ( !$wp_rewrite->using_index_permalinks() )
|
||||
$redirect['path'] = str_replace('/index.php/', '/', $redirect['path']);
|
||||
|
||||
// trailing slashes
|
||||
if ( is_object($wp_rewrite) && $wp_rewrite->using_permalinks() && !is_404() && (!is_front_page() || ( is_front_page() && (get_query_var('paged') > 1) ) ) ) {
|
||||
$user_ts_type = '';
|
||||
if ( get_query_var('paged') > 0 ) {
|
||||
$user_ts_type = 'paged';
|
||||
} else {
|
||||
foreach ( array('single', 'category', 'page', 'day', 'month', 'year', 'home') as $type ) {
|
||||
$func = 'is_' . $type;
|
||||
if ( call_user_func($func) ) {
|
||||
$user_ts_type = $type;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
$redirect['path'] = user_trailingslashit($redirect['path'], $user_ts_type);
|
||||
} elseif ( is_front_page() ) {
|
||||
$redirect['path'] = trailingslashit($redirect['path']);
|
||||
}
|
||||
|
||||
// Strip multiple slashes out of the URL
|
||||
if ( strpos($redirect['path'], '//') > -1 )
|
||||
$redirect['path'] = preg_replace('|/+|', '/', $redirect['path']);
|
||||
|
||||
// Always trailing slash the Front Page URL
|
||||
if ( trailingslashit( $redirect['path'] ) == trailingslashit( $user_home['path'] ) )
|
||||
$redirect['path'] = trailingslashit($redirect['path']);
|
||||
|
||||
// Ignore differences in host capitalization, as this can lead to infinite redirects
|
||||
// Only redirect no-www <=> yes-www
|
||||
if ( strtolower($original['host']) == strtolower($redirect['host']) ||
|
||||
( strtolower($original['host']) != 'www.' . strtolower($redirect['host']) && 'www.' . strtolower($original['host']) != strtolower($redirect['host']) ) )
|
||||
$redirect['host'] = $original['host'];
|
||||
|
||||
$compare_original = array($original['host'], $original['path']);
|
||||
|
||||
if ( !empty( $original['port'] ) )
|
||||
$compare_original[] = $original['port'];
|
||||
|
||||
if ( !empty( $original['query'] ) )
|
||||
$compare_original[] = $original['query'];
|
||||
|
||||
$compare_redirect = array($redirect['host'], $redirect['path']);
|
||||
|
||||
if ( !empty( $redirect['port'] ) )
|
||||
$compare_redirect[] = $redirect['port'];
|
||||
|
||||
if ( !empty( $redirect['query'] ) )
|
||||
$compare_redirect[] = $redirect['query'];
|
||||
|
||||
if ( $compare_original !== $compare_redirect ) {
|
||||
$redirect_url = $redirect['scheme'] . '://' . $redirect['host'];
|
||||
if ( !empty($redirect['port']) )
|
||||
$redirect_url .= ':' . $redirect['port'];
|
||||
$redirect_url .= $redirect['path'];
|
||||
if ( !empty($redirect['query']) )
|
||||
$redirect_url .= '?' . $redirect['query'];
|
||||
}
|
||||
|
||||
if ( !$redirect_url || $redirect_url == $requested_url )
|
||||
return false;
|
||||
|
||||
// Hex encoded octets are case-insensitive.
|
||||
if ( false !== strpos($requested_url, '%') ) {
|
||||
if ( !function_exists('lowercase_octets') ) {
|
||||
function lowercase_octets($matches) {
|
||||
return strtolower( $matches[0] );
|
||||
}
|
||||
}
|
||||
$requested_url = preg_replace_callback('|%[a-fA-F0-9][a-fA-F0-9]|', 'lowercase_octets', $requested_url);
|
||||
}
|
||||
|
||||
// Note that you can use the "redirect_canonical" filter to cancel a canonical redirect for whatever reason by returning FALSE
|
||||
$redirect_url = apply_filters('redirect_canonical', $redirect_url, $requested_url);
|
||||
|
||||
if ( !$redirect_url || $redirect_url == $requested_url ) // yes, again -- in case the filter aborted the request
|
||||
return false;
|
||||
|
||||
if ( $do_redirect ) {
|
||||
// protect against chained redirects
|
||||
if ( !redirect_canonical($redirect_url, false) ) {
|
||||
wp_redirect($redirect_url, 301);
|
||||
exit();
|
||||
} else {
|
||||
// Debug
|
||||
// die("1: $redirect_url<br />2: " . redirect_canonical( $redirect_url, false ) );
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return $redirect_url;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to guess correct post based on query vars.
|
||||
*
|
||||
* @since 2.3.0
|
||||
* @uses $wpdb
|
||||
*
|
||||
* @return bool|string Returns False, if it can't find post, returns correct
|
||||
* location on success.
|
||||
*/
|
||||
function redirect_guess_404_permalink() {
|
||||
global $wpdb;
|
||||
|
||||
if ( !get_query_var('name') )
|
||||
return false;
|
||||
|
||||
$where = $wpdb->prepare("post_name LIKE %s", like_escape( get_query_var('name') ) . '%');
|
||||
|
||||
// if any of post_type, year, monthnum, or day are set, use them to refine the query
|
||||
if ( get_query_var('post_type') )
|
||||
$where .= $wpdb->prepare(" AND post_type = %s", get_query_var('post_type'));
|
||||
if ( get_query_var('year') )
|
||||
$where .= $wpdb->prepare(" AND YEAR(post_date) = %d", get_query_var('year'));
|
||||
if ( get_query_var('monthnum') )
|
||||
$where .= $wpdb->prepare(" AND MONTH(post_date) = %d", get_query_var('monthnum'));
|
||||
if ( get_query_var('day') )
|
||||
$where .= $wpdb->prepare(" AND DAYOFMONTH(post_date) = %d", get_query_var('day'));
|
||||
|
||||
$post_id = $wpdb->get_var("SELECT ID FROM $wpdb->posts WHERE $where AND post_status = 'publish'");
|
||||
if ( !$post_id )
|
||||
return false;
|
||||
return get_permalink($post_id);
|
||||
}
|
||||
|
||||
add_action('template_redirect', 'redirect_canonical');
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,359 @@
|
||||
<?php
|
||||
/**
|
||||
* WordPress Category API
|
||||
*
|
||||
* @package WordPress
|
||||
*/
|
||||
|
||||
/**
|
||||
* Retrieves all category IDs.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @link http://codex.wordpress.org/Function_Reference/get_all_category_ids
|
||||
*
|
||||
* @return object List of all of the category IDs.
|
||||
*/
|
||||
function get_all_category_ids() {
|
||||
if ( ! $cat_ids = wp_cache_get( 'all_category_ids', 'category' ) ) {
|
||||
$cat_ids = get_terms( 'category', array('fields' => 'ids', 'get' => 'all') );
|
||||
wp_cache_add( 'all_category_ids', $cat_ids, 'category' );
|
||||
}
|
||||
|
||||
return $cat_ids;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve list of category objects.
|
||||
*
|
||||
* If you change the type to 'link' in the arguments, then the link categories
|
||||
* will be returned instead. Also all categories will be updated to be backwards
|
||||
* compatible with pre-2.3 plugins and themes.
|
||||
*
|
||||
* @since 2.1.0
|
||||
* @see get_terms() Type of arguments that can be changed.
|
||||
* @link http://codex.wordpress.org/Function_Reference/get_categories
|
||||
*
|
||||
* @param string|array $args Optional. Change the defaults retrieving categories.
|
||||
* @return array List of categories.
|
||||
*/
|
||||
function &get_categories( $args = '' ) {
|
||||
$defaults = array( 'taxonomy' => 'category' );
|
||||
$args = wp_parse_args( $args, $defaults );
|
||||
|
||||
$taxonomy = apply_filters( 'get_categories_taxonomy', $args['taxonomy'], $args );
|
||||
|
||||
// Back compat
|
||||
if ( isset($args['type']) && 'link' == $args['type'] ) {
|
||||
_deprecated_argument( __FUNCTION__, '3.0', '' );
|
||||
$taxonomy = $args['taxonomy'] = 'link_category';
|
||||
}
|
||||
|
||||
$categories = (array) get_terms( $taxonomy, $args );
|
||||
|
||||
foreach ( array_keys( $categories ) as $k )
|
||||
_make_cat_compat( $categories[$k] );
|
||||
|
||||
return $categories;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves category data given a category ID or category object.
|
||||
*
|
||||
* If you pass the $category parameter an object, which is assumed to be the
|
||||
* category row object retrieved the database. It will cache the category data.
|
||||
*
|
||||
* If you pass $category an integer of the category ID, then that category will
|
||||
* be retrieved from the database, if it isn't already cached, and pass it back.
|
||||
*
|
||||
* If you look at get_term(), then both types will be passed through several
|
||||
* filters and finally sanitized based on the $filter parameter value.
|
||||
*
|
||||
* The category will converted to maintain backwards compatibility.
|
||||
*
|
||||
* @since 1.5.1
|
||||
* @uses get_term() Used to get the category data from the taxonomy.
|
||||
*
|
||||
* @param int|object $category Category ID or Category row object
|
||||
* @param string $output Optional. Constant OBJECT, ARRAY_A, or ARRAY_N
|
||||
* @param string $filter Optional. Default is raw or no WordPress defined filter will applied.
|
||||
* @return mixed Category data in type defined by $output parameter.
|
||||
*/
|
||||
function &get_category( $category, $output = OBJECT, $filter = 'raw' ) {
|
||||
$category = get_term( $category, 'category', $output, $filter );
|
||||
if ( is_wp_error( $category ) )
|
||||
return $category;
|
||||
|
||||
_make_cat_compat( $category );
|
||||
|
||||
return $category;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve category based on URL containing the category slug.
|
||||
*
|
||||
* Breaks the $category_path parameter up to get the category slug.
|
||||
*
|
||||
* Tries to find the child path and will return it. If it doesn't find a
|
||||
* match, then it will return the first category matching slug, if $full_match,
|
||||
* is set to false. If it does not, then it will return null.
|
||||
*
|
||||
* It is also possible that it will return a WP_Error object on failure. Check
|
||||
* for it when using this function.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @param string $category_path URL containing category slugs.
|
||||
* @param bool $full_match Optional. Whether full path should be matched.
|
||||
* @param string $output Optional. Constant OBJECT, ARRAY_A, or ARRAY_N
|
||||
* @return null|object|array Null on failure. Type is based on $output value.
|
||||
*/
|
||||
function get_category_by_path( $category_path, $full_match = true, $output = OBJECT ) {
|
||||
$category_path = rawurlencode( urldecode( $category_path ) );
|
||||
$category_path = str_replace( '%2F', '/', $category_path );
|
||||
$category_path = str_replace( '%20', ' ', $category_path );
|
||||
$category_paths = '/' . trim( $category_path, '/' );
|
||||
$leaf_path = sanitize_title( basename( $category_paths ) );
|
||||
$category_paths = explode( '/', $category_paths );
|
||||
$full_path = '';
|
||||
foreach ( (array) $category_paths as $pathdir )
|
||||
$full_path .= ( $pathdir != '' ? '/' : '' ) . sanitize_title( $pathdir );
|
||||
|
||||
$categories = get_terms( 'category', array('get' => 'all', 'slug' => $leaf_path) );
|
||||
|
||||
if ( empty( $categories ) )
|
||||
return null;
|
||||
|
||||
foreach ( $categories as $category ) {
|
||||
$path = '/' . $leaf_path;
|
||||
$curcategory = $category;
|
||||
while ( ( $curcategory->parent != 0 ) && ( $curcategory->parent != $curcategory->term_id ) ) {
|
||||
$curcategory = get_term( $curcategory->parent, 'category' );
|
||||
if ( is_wp_error( $curcategory ) )
|
||||
return $curcategory;
|
||||
$path = '/' . $curcategory->slug . $path;
|
||||
}
|
||||
|
||||
if ( $path == $full_path )
|
||||
return get_category( $category->term_id, $output );
|
||||
}
|
||||
|
||||
// If full matching is not required, return the first cat that matches the leaf.
|
||||
if ( ! $full_match )
|
||||
return get_category( $categories[0]->term_id, $output );
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve category object by category slug.
|
||||
*
|
||||
* @since 2.3.0
|
||||
*
|
||||
* @param string $slug The category slug.
|
||||
* @return object Category data object
|
||||
*/
|
||||
function get_category_by_slug( $slug ) {
|
||||
$category = get_term_by( 'slug', $slug, 'category' );
|
||||
if ( $category )
|
||||
_make_cat_compat( $category );
|
||||
|
||||
return $category;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieve the ID of a category from its name.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param string $cat_name Optional. Default is 'General' and can be any category name.
|
||||
* @return int 0, if failure and ID of category on success.
|
||||
*/
|
||||
function get_cat_ID( $cat_name='General' ) {
|
||||
$cat = get_term_by( 'name', $cat_name, 'category' );
|
||||
if ( $cat )
|
||||
return $cat->term_id;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieve the name of a category from its ID.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param int $cat_id Category ID
|
||||
* @return string Category name, or an empty string if category doesn't exist.
|
||||
*/
|
||||
function get_cat_name( $cat_id ) {
|
||||
$cat_id = (int) $cat_id;
|
||||
$category = &get_category( $cat_id );
|
||||
if ( ! $category || is_wp_error( $category ) )
|
||||
return '';
|
||||
return $category->name;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if a category is an ancestor of another category.
|
||||
*
|
||||
* You can use either an id or the category object for both parameters. If you
|
||||
* use an integer the category will be retrieved.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @param int|object $cat1 ID or object to check if this is the parent category.
|
||||
* @param int|object $cat2 The child category.
|
||||
* @return bool Whether $cat2 is child of $cat1
|
||||
*/
|
||||
function cat_is_ancestor_of( $cat1, $cat2 ) {
|
||||
if ( ! isset($cat1->term_id) )
|
||||
$cat1 = &get_category( $cat1 );
|
||||
if ( ! isset($cat2->parent) )
|
||||
$cat2 = &get_category( $cat2 );
|
||||
|
||||
if ( empty($cat1->term_id) || empty($cat2->parent) )
|
||||
return false;
|
||||
if ( $cat2->parent == $cat1->term_id )
|
||||
return true;
|
||||
|
||||
return cat_is_ancestor_of( $cat1, get_category( $cat2->parent ) );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sanitizes category data based on context.
|
||||
*
|
||||
* @since 2.3.0
|
||||
* @uses sanitize_term() See this function for what context are supported.
|
||||
*
|
||||
* @param object|array $category Category data
|
||||
* @param string $context Optional. Default is 'display'.
|
||||
* @return object|array Same type as $category with sanitized data for safe use.
|
||||
*/
|
||||
function sanitize_category( $category, $context = 'display' ) {
|
||||
return sanitize_term( $category, 'category', $context );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sanitizes data in single category key field.
|
||||
*
|
||||
* @since 2.3.0
|
||||
* @uses sanitize_term_field() See function for more details.
|
||||
*
|
||||
* @param string $field Category key to sanitize
|
||||
* @param mixed $value Category value to sanitize
|
||||
* @param int $cat_id Category ID
|
||||
* @param string $context What filter to use, 'raw', 'display', etc.
|
||||
* @return mixed Same type as $value after $value has been sanitized.
|
||||
*/
|
||||
function sanitize_category_field( $field, $value, $cat_id, $context ) {
|
||||
return sanitize_term_field( $field, $value, $cat_id, 'category', $context );
|
||||
}
|
||||
|
||||
/* Tags */
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves all post tags.
|
||||
*
|
||||
* @since 2.3.0
|
||||
* @see get_terms() For list of arguments to pass.
|
||||
* @uses apply_filters() Calls 'get_tags' hook on array of tags and with $args.
|
||||
*
|
||||
* @param string|array $args Tag arguments to use when retrieving tags.
|
||||
* @return array List of tags.
|
||||
*/
|
||||
function &get_tags( $args = '' ) {
|
||||
$tags = get_terms( 'post_tag', $args );
|
||||
|
||||
if ( empty( $tags ) ) {
|
||||
$return = array();
|
||||
return $return;
|
||||
}
|
||||
|
||||
$tags = apply_filters( 'get_tags', $tags, $args );
|
||||
return $tags;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieve post tag by tag ID or tag object.
|
||||
*
|
||||
* If you pass the $tag parameter an object, which is assumed to be the tag row
|
||||
* object retrieved the database. It will cache the tag data.
|
||||
*
|
||||
* If you pass $tag an integer of the tag ID, then that tag will
|
||||
* be retrieved from the database, if it isn't already cached, and pass it back.
|
||||
*
|
||||
* If you look at get_term(), then both types will be passed through several
|
||||
* filters and finally sanitized based on the $filter parameter value.
|
||||
*
|
||||
* @since 2.3.0
|
||||
*
|
||||
* @param int|object $tag
|
||||
* @param string $output Optional. Constant OBJECT, ARRAY_A, or ARRAY_N
|
||||
* @param string $filter Optional. Default is raw or no WordPress defined filter will applied.
|
||||
* @return object|array Return type based on $output value.
|
||||
*/
|
||||
function &get_tag( $tag, $output = OBJECT, $filter = 'raw' ) {
|
||||
return get_term( $tag, 'post_tag', $output, $filter );
|
||||
}
|
||||
|
||||
|
||||
/* Cache */
|
||||
|
||||
|
||||
/**
|
||||
* Remove the category cache data based on ID.
|
||||
*
|
||||
* @since 2.1.0
|
||||
* @uses clean_term_cache() Clears the cache for the category based on ID
|
||||
*
|
||||
* @param int $id Category ID
|
||||
*/
|
||||
function clean_category_cache( $id ) {
|
||||
clean_term_cache( $id, 'category' );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update category structure to old pre 2.3 from new taxonomy structure.
|
||||
*
|
||||
* This function was added for the taxonomy support to update the new category
|
||||
* structure with the old category one. This will maintain compatibility with
|
||||
* plugins and themes which depend on the old key or property names.
|
||||
*
|
||||
* The parameter should only be passed a variable and not create the array or
|
||||
* object inline to the parameter. The reason for this is that parameter is
|
||||
* passed by reference and PHP will fail unless it has the variable.
|
||||
*
|
||||
* There is no return value, because everything is updated on the variable you
|
||||
* pass to it. This is one of the features with using pass by reference in PHP.
|
||||
*
|
||||
* @since 2.3.0
|
||||
* @access private
|
||||
*
|
||||
* @param array|object $category Category Row object or array
|
||||
*/
|
||||
function _make_cat_compat( &$category ) {
|
||||
if ( is_object( $category ) ) {
|
||||
$category->cat_ID = &$category->term_id;
|
||||
$category->category_count = &$category->count;
|
||||
$category->category_description = &$category->description;
|
||||
$category->cat_name = &$category->name;
|
||||
$category->category_nicename = &$category->slug;
|
||||
$category->category_parent = &$category->parent;
|
||||
} elseif ( is_array( $category ) && isset( $category['term_id'] ) ) {
|
||||
$category['cat_ID'] = &$category['term_id'];
|
||||
$category['category_count'] = &$category['count'];
|
||||
$category['category_description'] = &$category['description'];
|
||||
$category['cat_name'] = &$category['name'];
|
||||
$category['category_nicename'] = &$category['slug'];
|
||||
$category['category_parent'] = &$category['parent'];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
|
||||
if ( !class_exists('SimplePie') )
|
||||
require_once (ABSPATH . WPINC . '/class-simplepie.php');
|
||||
|
||||
class WP_Feed_Cache extends SimplePie_Cache {
|
||||
/**
|
||||
* Don't call the constructor. Please.
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
function WP_Feed_Cache() {
|
||||
trigger_error('Please call SimplePie_Cache::create() instead of the constructor', E_USER_ERROR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new SimplePie_Cache object
|
||||
*
|
||||
* @static
|
||||
* @access public
|
||||
*/
|
||||
function create($location, $filename, $extension) {
|
||||
return new WP_Feed_Cache_Transient($location, $filename, $extension);
|
||||
}
|
||||
}
|
||||
|
||||
class WP_Feed_Cache_Transient {
|
||||
var $name;
|
||||
var $mod_name;
|
||||
var $lifetime = 43200; //Default lifetime in cache of 12 hours
|
||||
|
||||
function WP_Feed_Cache_Transient($location, $filename, $extension) {
|
||||
$this->name = 'feed_' . $filename;
|
||||
$this->mod_name = 'feed_mod_' . $filename;
|
||||
$this->lifetime = apply_filters('wp_feed_cache_transient_lifetime', $this->lifetime, $filename);
|
||||
}
|
||||
|
||||
function save($data) {
|
||||
if ( is_a($data, 'SimplePie') )
|
||||
$data = $data->data;
|
||||
|
||||
set_transient($this->name, $data, $this->lifetime);
|
||||
set_transient($this->mod_name, time(), $this->lifetime);
|
||||
return true;
|
||||
}
|
||||
|
||||
function load() {
|
||||
return get_transient($this->name);
|
||||
}
|
||||
|
||||
function mtime() {
|
||||
return get_transient($this->mod_name);
|
||||
}
|
||||
|
||||
function touch() {
|
||||
return set_transient($this->mod_name, time(), $this->lifetime);
|
||||
}
|
||||
|
||||
function unlink() {
|
||||
delete_transient($this->name);
|
||||
delete_transient($this->mod_name);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class WP_SimplePie_File extends SimplePie_File {
|
||||
|
||||
function WP_SimplePie_File($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false) {
|
||||
$this->url = $url;
|
||||
$this->timeout = $timeout;
|
||||
$this->redirects = $redirects;
|
||||
$this->headers = $headers;
|
||||
$this->useragent = $useragent;
|
||||
|
||||
$this->method = SIMPLEPIE_FILE_SOURCE_REMOTE;
|
||||
|
||||
if ( preg_match('/^http(s)?:\/\//i', $url) ) {
|
||||
$args = array( 'timeout' => $this->timeout, 'redirection' => $this->redirects);
|
||||
|
||||
if ( !empty($this->headers) )
|
||||
$args['headers'] = $this->headers;
|
||||
|
||||
if ( SIMPLEPIE_USERAGENT != $this->useragent ) //Use default WP user agent unless custom has been specified
|
||||
$args['user-agent'] = $this->useragent;
|
||||
|
||||
$res = wp_remote_request($url, $args);
|
||||
|
||||
if ( is_wp_error($res) ) {
|
||||
$this->error = 'WP HTTP Error: ' . $res->get_error_message();
|
||||
$this->success = false;
|
||||
} else {
|
||||
$this->headers = $res['headers'];
|
||||
$this->body = $res['body'];
|
||||
$this->status_code = $res['response']['code'];
|
||||
}
|
||||
} else {
|
||||
if ( ! $this->body = file_get_contents($url) ) {
|
||||
$this->error = 'file_get_contents could not read the file';
|
||||
$this->success = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,863 @@
|
||||
<?php
|
||||
if ( !class_exists( 'Services_JSON' ) ) :
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
/**
|
||||
* Converts to and from JSON format.
|
||||
*
|
||||
* JSON (JavaScript Object Notation) is a lightweight data-interchange
|
||||
* format. It is easy for humans to read and write. It is easy for machines
|
||||
* to parse and generate. It is based on a subset of the JavaScript
|
||||
* Programming Language, Standard ECMA-262 3rd Edition - December 1999.
|
||||
* This feature can also be found in Python. JSON is a text format that is
|
||||
* completely language independent but uses conventions that are familiar
|
||||
* to programmers of the C-family of languages, including C, C++, C#, Java,
|
||||
* JavaScript, Perl, TCL, and many others. These properties make JSON an
|
||||
* ideal data-interchange language.
|
||||
*
|
||||
* This package provides a simple encoder and decoder for JSON notation. It
|
||||
* is intended for use with client-side Javascript applications that make
|
||||
* use of HTTPRequest to perform server communication functions - data can
|
||||
* be encoded into JSON notation for use in a client-side javascript, or
|
||||
* decoded from incoming Javascript requests. JSON format is native to
|
||||
* Javascript, and can be directly eval()'ed with no further parsing
|
||||
* overhead
|
||||
*
|
||||
* All strings should be in ASCII or UTF-8 format!
|
||||
*
|
||||
* LICENSE: Redistribution and use in source and binary forms, with or
|
||||
* without modification, are permitted provided that the following
|
||||
* conditions are met: Redistributions of source code must retain the
|
||||
* above copyright notice, this list of conditions and the following
|
||||
* disclaimer. Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||
* NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
* DAMAGE.
|
||||
*
|
||||
* @category
|
||||
* @package Services_JSON
|
||||
* @author Michal Migurski <mike-json@teczno.com>
|
||||
* @author Matt Knapp <mdknapp[at]gmail[dot]com>
|
||||
* @author Brett Stimmerman <brettstimmerman[at]gmail[dot]com>
|
||||
* @copyright 2005 Michal Migurski
|
||||
* @version CVS: $Id: JSON.php 288200 2009-09-09 15:41:29Z alan_k $
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php
|
||||
* @link http://pear.php.net/pepr/pepr-proposal-show.php?id=198
|
||||
*/
|
||||
|
||||
/**
|
||||
* Marker constant for Services_JSON::decode(), used to flag stack state
|
||||
*/
|
||||
define('SERVICES_JSON_SLICE', 1);
|
||||
|
||||
/**
|
||||
* Marker constant for Services_JSON::decode(), used to flag stack state
|
||||
*/
|
||||
define('SERVICES_JSON_IN_STR', 2);
|
||||
|
||||
/**
|
||||
* Marker constant for Services_JSON::decode(), used to flag stack state
|
||||
*/
|
||||
define('SERVICES_JSON_IN_ARR', 3);
|
||||
|
||||
/**
|
||||
* Marker constant for Services_JSON::decode(), used to flag stack state
|
||||
*/
|
||||
define('SERVICES_JSON_IN_OBJ', 4);
|
||||
|
||||
/**
|
||||
* Marker constant for Services_JSON::decode(), used to flag stack state
|
||||
*/
|
||||
define('SERVICES_JSON_IN_CMT', 5);
|
||||
|
||||
/**
|
||||
* Behavior switch for Services_JSON::decode()
|
||||
*/
|
||||
define('SERVICES_JSON_LOOSE_TYPE', 16);
|
||||
|
||||
/**
|
||||
* Behavior switch for Services_JSON::decode()
|
||||
*/
|
||||
define('SERVICES_JSON_SUPPRESS_ERRORS', 32);
|
||||
|
||||
/**
|
||||
* Converts to and from JSON format.
|
||||
*
|
||||
* Brief example of use:
|
||||
*
|
||||
* <code>
|
||||
* // create a new instance of Services_JSON
|
||||
* $json = new Services_JSON();
|
||||
*
|
||||
* // convert a complexe value to JSON notation, and send it to the browser
|
||||
* $value = array('foo', 'bar', array(1, 2, 'baz'), array(3, array(4)));
|
||||
* $output = $json->encode($value);
|
||||
*
|
||||
* print($output);
|
||||
* // prints: ["foo","bar",[1,2,"baz"],[3,[4]]]
|
||||
*
|
||||
* // accept incoming POST data, assumed to be in JSON notation
|
||||
* $input = file_get_contents('php://input', 1000000);
|
||||
* $value = $json->decode($input);
|
||||
* </code>
|
||||
*/
|
||||
class Services_JSON
|
||||
{
|
||||
/**
|
||||
* constructs a new JSON instance
|
||||
*
|
||||
* @param int $use object behavior flags; combine with boolean-OR
|
||||
*
|
||||
* possible values:
|
||||
* - SERVICES_JSON_LOOSE_TYPE: loose typing.
|
||||
* "{...}" syntax creates associative arrays
|
||||
* instead of objects in decode().
|
||||
* - SERVICES_JSON_SUPPRESS_ERRORS: error suppression.
|
||||
* Values which can't be encoded (e.g. resources)
|
||||
* appear as NULL instead of throwing errors.
|
||||
* By default, a deeply-nested resource will
|
||||
* bubble up with an error, so all return values
|
||||
* from encode() should be checked with isError()
|
||||
*/
|
||||
function Services_JSON($use = 0)
|
||||
{
|
||||
$this->use = $use;
|
||||
}
|
||||
|
||||
/**
|
||||
* convert a string from one UTF-16 char to one UTF-8 char
|
||||
*
|
||||
* Normally should be handled by mb_convert_encoding, but
|
||||
* provides a slower PHP-only method for installations
|
||||
* that lack the multibye string extension.
|
||||
*
|
||||
* @param string $utf16 UTF-16 character
|
||||
* @return string UTF-8 character
|
||||
* @access private
|
||||
*/
|
||||
function utf162utf8($utf16)
|
||||
{
|
||||
// oh please oh please oh please oh please oh please
|
||||
if(function_exists('mb_convert_encoding')) {
|
||||
return mb_convert_encoding($utf16, 'UTF-8', 'UTF-16');
|
||||
}
|
||||
|
||||
$bytes = (ord($utf16[0]) << 8) | ord($utf16[1]);
|
||||
|
||||
switch(true) {
|
||||
case ((0x7F & $bytes) == $bytes):
|
||||
// this case should never be reached, because we are in ASCII range
|
||||
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
return chr(0x7F & $bytes);
|
||||
|
||||
case (0x07FF & $bytes) == $bytes:
|
||||
// return a 2-byte UTF-8 character
|
||||
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
return chr(0xC0 | (($bytes >> 6) & 0x1F))
|
||||
. chr(0x80 | ($bytes & 0x3F));
|
||||
|
||||
case (0xFFFF & $bytes) == $bytes:
|
||||
// return a 3-byte UTF-8 character
|
||||
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
return chr(0xE0 | (($bytes >> 12) & 0x0F))
|
||||
. chr(0x80 | (($bytes >> 6) & 0x3F))
|
||||
. chr(0x80 | ($bytes & 0x3F));
|
||||
}
|
||||
|
||||
// ignoring UTF-32 for now, sorry
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* convert a string from one UTF-8 char to one UTF-16 char
|
||||
*
|
||||
* Normally should be handled by mb_convert_encoding, but
|
||||
* provides a slower PHP-only method for installations
|
||||
* that lack the multibye string extension.
|
||||
*
|
||||
* @param string $utf8 UTF-8 character
|
||||
* @return string UTF-16 character
|
||||
* @access private
|
||||
*/
|
||||
function utf82utf16($utf8)
|
||||
{
|
||||
// oh please oh please oh please oh please oh please
|
||||
if(function_exists('mb_convert_encoding')) {
|
||||
return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8');
|
||||
}
|
||||
|
||||
switch(strlen($utf8)) {
|
||||
case 1:
|
||||
// this case should never be reached, because we are in ASCII range
|
||||
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
return $utf8;
|
||||
|
||||
case 2:
|
||||
// return a UTF-16 character from a 2-byte UTF-8 char
|
||||
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
return chr(0x07 & (ord($utf8[0]) >> 2))
|
||||
. chr((0xC0 & (ord($utf8[0]) << 6))
|
||||
| (0x3F & ord($utf8[1])));
|
||||
|
||||
case 3:
|
||||
// return a UTF-16 character from a 3-byte UTF-8 char
|
||||
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
return chr((0xF0 & (ord($utf8[0]) << 4))
|
||||
| (0x0F & (ord($utf8[1]) >> 2)))
|
||||
. chr((0xC0 & (ord($utf8[1]) << 6))
|
||||
| (0x7F & ord($utf8[2])));
|
||||
}
|
||||
|
||||
// ignoring UTF-32 for now, sorry
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* encodes an arbitrary variable into JSON format (and sends JSON Header)
|
||||
*
|
||||
* @param mixed $var any number, boolean, string, array, or object to be encoded.
|
||||
* see argument 1 to Services_JSON() above for array-parsing behavior.
|
||||
* if var is a strng, note that encode() always expects it
|
||||
* to be in ASCII or UTF-8 format!
|
||||
*
|
||||
* @return mixed JSON string representation of input var or an error if a problem occurs
|
||||
* @access public
|
||||
*/
|
||||
function encode($var)
|
||||
{
|
||||
header('Content-type: application/json');
|
||||
return $this->_encode($var);
|
||||
}
|
||||
/**
|
||||
* encodes an arbitrary variable into JSON format without JSON Header - warning - may allow CSS!!!!)
|
||||
*
|
||||
* @param mixed $var any number, boolean, string, array, or object to be encoded.
|
||||
* see argument 1 to Services_JSON() above for array-parsing behavior.
|
||||
* if var is a strng, note that encode() always expects it
|
||||
* to be in ASCII or UTF-8 format!
|
||||
*
|
||||
* @return mixed JSON string representation of input var or an error if a problem occurs
|
||||
* @access public
|
||||
*/
|
||||
function encodeUnsafe($var)
|
||||
{
|
||||
return $this->_encode($var);
|
||||
}
|
||||
/**
|
||||
* PRIVATE CODE that does the work of encodes an arbitrary variable into JSON format
|
||||
*
|
||||
* @param mixed $var any number, boolean, string, array, or object to be encoded.
|
||||
* see argument 1 to Services_JSON() above for array-parsing behavior.
|
||||
* if var is a strng, note that encode() always expects it
|
||||
* to be in ASCII or UTF-8 format!
|
||||
*
|
||||
* @return mixed JSON string representation of input var or an error if a problem occurs
|
||||
* @access public
|
||||
*/
|
||||
function _encode($var)
|
||||
{
|
||||
|
||||
switch (gettype($var)) {
|
||||
case 'boolean':
|
||||
return $var ? 'true' : 'false';
|
||||
|
||||
case 'NULL':
|
||||
return 'null';
|
||||
|
||||
case 'integer':
|
||||
return (int) $var;
|
||||
|
||||
case 'double':
|
||||
case 'float':
|
||||
return (float) $var;
|
||||
|
||||
case 'string':
|
||||
// STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT
|
||||
$ascii = '';
|
||||
$strlen_var = strlen($var);
|
||||
|
||||
/*
|
||||
* Iterate over every character in the string,
|
||||
* escaping with a slash or encoding to UTF-8 where necessary
|
||||
*/
|
||||
for ($c = 0; $c < $strlen_var; ++$c) {
|
||||
|
||||
$ord_var_c = ord($var[$c]);
|
||||
|
||||
switch (true) {
|
||||
case $ord_var_c == 0x08:
|
||||
$ascii .= '\b';
|
||||
break;
|
||||
case $ord_var_c == 0x09:
|
||||
$ascii .= '\t';
|
||||
break;
|
||||
case $ord_var_c == 0x0A:
|
||||
$ascii .= '\n';
|
||||
break;
|
||||
case $ord_var_c == 0x0C:
|
||||
$ascii .= '\f';
|
||||
break;
|
||||
case $ord_var_c == 0x0D:
|
||||
$ascii .= '\r';
|
||||
break;
|
||||
|
||||
case $ord_var_c == 0x22:
|
||||
case $ord_var_c == 0x2F:
|
||||
case $ord_var_c == 0x5C:
|
||||
// double quote, slash, slosh
|
||||
$ascii .= '\\'.$var[$c];
|
||||
break;
|
||||
|
||||
case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)):
|
||||
// characters U-00000000 - U-0000007F (same as ASCII)
|
||||
$ascii .= $var[$c];
|
||||
break;
|
||||
|
||||
case (($ord_var_c & 0xE0) == 0xC0):
|
||||
// characters U-00000080 - U-000007FF, mask 110XXXXX
|
||||
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
if ($c+1 >= $strlen_var) {
|
||||
$c += 1;
|
||||
$ascii .= '?';
|
||||
break;
|
||||
}
|
||||
|
||||
$char = pack('C*', $ord_var_c, ord($var[$c + 1]));
|
||||
$c += 1;
|
||||
$utf16 = $this->utf82utf16($char);
|
||||
$ascii .= sprintf('\u%04s', bin2hex($utf16));
|
||||
break;
|
||||
|
||||
case (($ord_var_c & 0xF0) == 0xE0):
|
||||
if ($c+2 >= $strlen_var) {
|
||||
$c += 2;
|
||||
$ascii .= '?';
|
||||
break;
|
||||
}
|
||||
// characters U-00000800 - U-0000FFFF, mask 1110XXXX
|
||||
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
$char = pack('C*', $ord_var_c,
|
||||
@ord($var[$c + 1]),
|
||||
@ord($var[$c + 2]));
|
||||
$c += 2;
|
||||
$utf16 = $this->utf82utf16($char);
|
||||
$ascii .= sprintf('\u%04s', bin2hex($utf16));
|
||||
break;
|
||||
|
||||
case (($ord_var_c & 0xF8) == 0xF0):
|
||||
if ($c+3 >= $strlen_var) {
|
||||
$c += 3;
|
||||
$ascii .= '?';
|
||||
break;
|
||||
}
|
||||
// characters U-00010000 - U-001FFFFF, mask 11110XXX
|
||||
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
$char = pack('C*', $ord_var_c,
|
||||
ord($var[$c + 1]),
|
||||
ord($var[$c + 2]),
|
||||
ord($var[$c + 3]));
|
||||
$c += 3;
|
||||
$utf16 = $this->utf82utf16($char);
|
||||
$ascii .= sprintf('\u%04s', bin2hex($utf16));
|
||||
break;
|
||||
|
||||
case (($ord_var_c & 0xFC) == 0xF8):
|
||||
// characters U-00200000 - U-03FFFFFF, mask 111110XX
|
||||
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
if ($c+4 >= $strlen_var) {
|
||||
$c += 4;
|
||||
$ascii .= '?';
|
||||
break;
|
||||
}
|
||||
$char = pack('C*', $ord_var_c,
|
||||
ord($var[$c + 1]),
|
||||
ord($var[$c + 2]),
|
||||
ord($var[$c + 3]),
|
||||
ord($var[$c + 4]));
|
||||
$c += 4;
|
||||
$utf16 = $this->utf82utf16($char);
|
||||
$ascii .= sprintf('\u%04s', bin2hex($utf16));
|
||||
break;
|
||||
|
||||
case (($ord_var_c & 0xFE) == 0xFC):
|
||||
if ($c+5 >= $strlen_var) {
|
||||
$c += 5;
|
||||
$ascii .= '?';
|
||||
break;
|
||||
}
|
||||
// characters U-04000000 - U-7FFFFFFF, mask 1111110X
|
||||
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
$char = pack('C*', $ord_var_c,
|
||||
ord($var[$c + 1]),
|
||||
ord($var[$c + 2]),
|
||||
ord($var[$c + 3]),
|
||||
ord($var[$c + 4]),
|
||||
ord($var[$c + 5]));
|
||||
$c += 5;
|
||||
$utf16 = $this->utf82utf16($char);
|
||||
$ascii .= sprintf('\u%04s', bin2hex($utf16));
|
||||
break;
|
||||
}
|
||||
}
|
||||
return '"'.$ascii.'"';
|
||||
|
||||
case 'array':
|
||||
/*
|
||||
* As per JSON spec if any array key is not an integer
|
||||
* we must treat the the whole array as an object. We
|
||||
* also try to catch a sparsely populated associative
|
||||
* array with numeric keys here because some JS engines
|
||||
* will create an array with empty indexes up to
|
||||
* max_index which can cause memory issues and because
|
||||
* the keys, which may be relevant, will be remapped
|
||||
* otherwise.
|
||||
*
|
||||
* As per the ECMA and JSON specification an object may
|
||||
* have any string as a property. Unfortunately due to
|
||||
* a hole in the ECMA specification if the key is a
|
||||
* ECMA reserved word or starts with a digit the
|
||||
* parameter is only accessible using ECMAScript's
|
||||
* bracket notation.
|
||||
*/
|
||||
|
||||
// treat as a JSON object
|
||||
if (is_array($var) && count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) {
|
||||
$properties = array_map(array($this, 'name_value'),
|
||||
array_keys($var),
|
||||
array_values($var));
|
||||
|
||||
foreach($properties as $property) {
|
||||
if(Services_JSON::isError($property)) {
|
||||
return $property;
|
||||
}
|
||||
}
|
||||
|
||||
return '{' . join(',', $properties) . '}';
|
||||
}
|
||||
|
||||
// treat it like a regular array
|
||||
$elements = array_map(array($this, '_encode'), $var);
|
||||
|
||||
foreach($elements as $element) {
|
||||
if(Services_JSON::isError($element)) {
|
||||
return $element;
|
||||
}
|
||||
}
|
||||
|
||||
return '[' . join(',', $elements) . ']';
|
||||
|
||||
case 'object':
|
||||
$vars = get_object_vars($var);
|
||||
|
||||
$properties = array_map(array($this, 'name_value'),
|
||||
array_keys($vars),
|
||||
array_values($vars));
|
||||
|
||||
foreach($properties as $property) {
|
||||
if(Services_JSON::isError($property)) {
|
||||
return $property;
|
||||
}
|
||||
}
|
||||
|
||||
return '{' . join(',', $properties) . '}';
|
||||
|
||||
default:
|
||||
return ($this->use & SERVICES_JSON_SUPPRESS_ERRORS)
|
||||
? 'null'
|
||||
: new Services_JSON_Error(gettype($var)." can not be encoded as JSON string");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* array-walking function for use in generating JSON-formatted name-value pairs
|
||||
*
|
||||
* @param string $name name of key to use
|
||||
* @param mixed $value reference to an array element to be encoded
|
||||
*
|
||||
* @return string JSON-formatted name-value pair, like '"name":value'
|
||||
* @access private
|
||||
*/
|
||||
function name_value($name, $value)
|
||||
{
|
||||
$encoded_value = $this->_encode($value);
|
||||
|
||||
if(Services_JSON::isError($encoded_value)) {
|
||||
return $encoded_value;
|
||||
}
|
||||
|
||||
return $this->_encode(strval($name)) . ':' . $encoded_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* reduce a string by removing leading and trailing comments and whitespace
|
||||
*
|
||||
* @param $str string string value to strip of comments and whitespace
|
||||
*
|
||||
* @return string string value stripped of comments and whitespace
|
||||
* @access private
|
||||
*/
|
||||
function reduce_string($str)
|
||||
{
|
||||
$str = preg_replace(array(
|
||||
|
||||
// eliminate single line comments in '// ...' form
|
||||
'#^\s*//(.+)$#m',
|
||||
|
||||
// eliminate multi-line comments in '/* ... */' form, at start of string
|
||||
'#^\s*/\*(.+)\*/#Us',
|
||||
|
||||
// eliminate multi-line comments in '/* ... */' form, at end of string
|
||||
'#/\*(.+)\*/\s*$#Us'
|
||||
|
||||
), '', $str);
|
||||
|
||||
// eliminate extraneous space
|
||||
return trim($str);
|
||||
}
|
||||
|
||||
/**
|
||||
* decodes a JSON string into appropriate variable
|
||||
*
|
||||
* @param string $str JSON-formatted string
|
||||
*
|
||||
* @return mixed number, boolean, string, array, or object
|
||||
* corresponding to given JSON input string.
|
||||
* See argument 1 to Services_JSON() above for object-output behavior.
|
||||
* Note that decode() always returns strings
|
||||
* in ASCII or UTF-8 format!
|
||||
* @access public
|
||||
*/
|
||||
function decode($str)
|
||||
{
|
||||
$str = $this->reduce_string($str);
|
||||
|
||||
switch (strtolower($str)) {
|
||||
case 'true':
|
||||
return true;
|
||||
|
||||
case 'false':
|
||||
return false;
|
||||
|
||||
case 'null':
|
||||
return null;
|
||||
|
||||
default:
|
||||
$m = array();
|
||||
|
||||
if (is_numeric($str)) {
|
||||
// Lookie-loo, it's a number
|
||||
|
||||
// This would work on its own, but I'm trying to be
|
||||
// good about returning integers where appropriate:
|
||||
// return (float)$str;
|
||||
|
||||
// Return float or int, as appropriate
|
||||
return ((float)$str == (integer)$str)
|
||||
? (integer)$str
|
||||
: (float)$str;
|
||||
|
||||
} elseif (preg_match('/^("|\').*(\1)$/s', $str, $m) && $m[1] == $m[2]) {
|
||||
// STRINGS RETURNED IN UTF-8 FORMAT
|
||||
$delim = substr($str, 0, 1);
|
||||
$chrs = substr($str, 1, -1);
|
||||
$utf8 = '';
|
||||
$strlen_chrs = strlen($chrs);
|
||||
|
||||
for ($c = 0; $c < $strlen_chrs; ++$c) {
|
||||
|
||||
$substr_chrs_c_2 = substr($chrs, $c, 2);
|
||||
$ord_chrs_c = ord($chrs[$c]);
|
||||
|
||||
switch (true) {
|
||||
case $substr_chrs_c_2 == '\b':
|
||||
$utf8 .= chr(0x08);
|
||||
++$c;
|
||||
break;
|
||||
case $substr_chrs_c_2 == '\t':
|
||||
$utf8 .= chr(0x09);
|
||||
++$c;
|
||||
break;
|
||||
case $substr_chrs_c_2 == '\n':
|
||||
$utf8 .= chr(0x0A);
|
||||
++$c;
|
||||
break;
|
||||
case $substr_chrs_c_2 == '\f':
|
||||
$utf8 .= chr(0x0C);
|
||||
++$c;
|
||||
break;
|
||||
case $substr_chrs_c_2 == '\r':
|
||||
$utf8 .= chr(0x0D);
|
||||
++$c;
|
||||
break;
|
||||
|
||||
case $substr_chrs_c_2 == '\\"':
|
||||
case $substr_chrs_c_2 == '\\\'':
|
||||
case $substr_chrs_c_2 == '\\\\':
|
||||
case $substr_chrs_c_2 == '\\/':
|
||||
if (($delim == '"' && $substr_chrs_c_2 != '\\\'') ||
|
||||
($delim == "'" && $substr_chrs_c_2 != '\\"')) {
|
||||
$utf8 .= $chrs[++$c];
|
||||
}
|
||||
break;
|
||||
|
||||
case preg_match('/\\\u[0-9A-F]{4}/i', substr($chrs, $c, 6)):
|
||||
// single, escaped unicode character
|
||||
$utf16 = chr(hexdec(substr($chrs, ($c + 2), 2)))
|
||||
. chr(hexdec(substr($chrs, ($c + 4), 2)));
|
||||
$utf8 .= $this->utf162utf8($utf16);
|
||||
$c += 5;
|
||||
break;
|
||||
|
||||
case ($ord_chrs_c >= 0x20) && ($ord_chrs_c <= 0x7F):
|
||||
$utf8 .= $chrs[$c];
|
||||
break;
|
||||
|
||||
case ($ord_chrs_c & 0xE0) == 0xC0:
|
||||
// characters U-00000080 - U-000007FF, mask 110XXXXX
|
||||
//see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
$utf8 .= substr($chrs, $c, 2);
|
||||
++$c;
|
||||
break;
|
||||
|
||||
case ($ord_chrs_c & 0xF0) == 0xE0:
|
||||
// characters U-00000800 - U-0000FFFF, mask 1110XXXX
|
||||
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
$utf8 .= substr($chrs, $c, 3);
|
||||
$c += 2;
|
||||
break;
|
||||
|
||||
case ($ord_chrs_c & 0xF8) == 0xF0:
|
||||
// characters U-00010000 - U-001FFFFF, mask 11110XXX
|
||||
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
$utf8 .= substr($chrs, $c, 4);
|
||||
$c += 3;
|
||||
break;
|
||||
|
||||
case ($ord_chrs_c & 0xFC) == 0xF8:
|
||||
// characters U-00200000 - U-03FFFFFF, mask 111110XX
|
||||
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
$utf8 .= substr($chrs, $c, 5);
|
||||
$c += 4;
|
||||
break;
|
||||
|
||||
case ($ord_chrs_c & 0xFE) == 0xFC:
|
||||
// characters U-04000000 - U-7FFFFFFF, mask 1111110X
|
||||
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
$utf8 .= substr($chrs, $c, 6);
|
||||
$c += 5;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $utf8;
|
||||
|
||||
} elseif (preg_match('/^\[.*\]$/s', $str) || preg_match('/^\{.*\}$/s', $str)) {
|
||||
// array, or object notation
|
||||
|
||||
if ($str[0] == '[') {
|
||||
$stk = array(SERVICES_JSON_IN_ARR);
|
||||
$arr = array();
|
||||
} else {
|
||||
if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
|
||||
$stk = array(SERVICES_JSON_IN_OBJ);
|
||||
$obj = array();
|
||||
} else {
|
||||
$stk = array(SERVICES_JSON_IN_OBJ);
|
||||
$obj = new stdClass();
|
||||
}
|
||||
}
|
||||
|
||||
array_push($stk, array('what' => SERVICES_JSON_SLICE,
|
||||
'where' => 0,
|
||||
'delim' => false));
|
||||
|
||||
$chrs = substr($str, 1, -1);
|
||||
$chrs = $this->reduce_string($chrs);
|
||||
|
||||
if ($chrs == '') {
|
||||
if (reset($stk) == SERVICES_JSON_IN_ARR) {
|
||||
return $arr;
|
||||
|
||||
} else {
|
||||
return $obj;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//print("\nparsing {$chrs}\n");
|
||||
|
||||
$strlen_chrs = strlen($chrs);
|
||||
|
||||
for ($c = 0; $c <= $strlen_chrs; ++$c) {
|
||||
|
||||
$top = end($stk);
|
||||
$substr_chrs_c_2 = substr($chrs, $c, 2);
|
||||
|
||||
if (($c == $strlen_chrs) || (($chrs[$c] == ',') && ($top['what'] == SERVICES_JSON_SLICE))) {
|
||||
// found a comma that is not inside a string, array, etc.,
|
||||
// OR we've reached the end of the character list
|
||||
$slice = substr($chrs, $top['where'], ($c - $top['where']));
|
||||
array_push($stk, array('what' => SERVICES_JSON_SLICE, 'where' => ($c + 1), 'delim' => false));
|
||||
//print("Found split at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
|
||||
|
||||
if (reset($stk) == SERVICES_JSON_IN_ARR) {
|
||||
// we are in an array, so just push an element onto the stack
|
||||
array_push($arr, $this->decode($slice));
|
||||
|
||||
} elseif (reset($stk) == SERVICES_JSON_IN_OBJ) {
|
||||
// we are in an object, so figure
|
||||
// out the property name and set an
|
||||
// element in an associative array,
|
||||
// for now
|
||||
$parts = array();
|
||||
|
||||
if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
|
||||
// "name":value pair
|
||||
$key = $this->decode($parts[1]);
|
||||
$val = $this->decode($parts[2]);
|
||||
|
||||
if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
|
||||
$obj[$key] = $val;
|
||||
} else {
|
||||
$obj->$key = $val;
|
||||
}
|
||||
} elseif (preg_match('/^\s*(\w+)\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
|
||||
// name:value pair, where name is unquoted
|
||||
$key = $parts[1];
|
||||
$val = $this->decode($parts[2]);
|
||||
|
||||
if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
|
||||
$obj[$key] = $val;
|
||||
} else {
|
||||
$obj->$key = $val;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} elseif ((($chrs[$c] == '"') || ($chrs[$c] == "'")) && ($top['what'] != SERVICES_JSON_IN_STR)) {
|
||||
// found a quote, and we are not inside a string
|
||||
array_push($stk, array('what' => SERVICES_JSON_IN_STR, 'where' => $c, 'delim' => $chrs[$c]));
|
||||
//print("Found start of string at {$c}\n");
|
||||
|
||||
} elseif (($chrs[$c] == $top['delim']) &&
|
||||
($top['what'] == SERVICES_JSON_IN_STR) &&
|
||||
((strlen(substr($chrs, 0, $c)) - strlen(rtrim(substr($chrs, 0, $c), '\\'))) % 2 != 1)) {
|
||||
// found a quote, we're in a string, and it's not escaped
|
||||
// we know that it's not escaped becase there is _not_ an
|
||||
// odd number of backslashes at the end of the string so far
|
||||
array_pop($stk);
|
||||
//print("Found end of string at {$c}: ".substr($chrs, $top['where'], (1 + 1 + $c - $top['where']))."\n");
|
||||
|
||||
} elseif (($chrs[$c] == '[') &&
|
||||
in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
|
||||
// found a left-bracket, and we are in an array, object, or slice
|
||||
array_push($stk, array('what' => SERVICES_JSON_IN_ARR, 'where' => $c, 'delim' => false));
|
||||
//print("Found start of array at {$c}\n");
|
||||
|
||||
} elseif (($chrs[$c] == ']') && ($top['what'] == SERVICES_JSON_IN_ARR)) {
|
||||
// found a right-bracket, and we're in an array
|
||||
array_pop($stk);
|
||||
//print("Found end of array at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
|
||||
|
||||
} elseif (($chrs[$c] == '{') &&
|
||||
in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
|
||||
// found a left-brace, and we are in an array, object, or slice
|
||||
array_push($stk, array('what' => SERVICES_JSON_IN_OBJ, 'where' => $c, 'delim' => false));
|
||||
//print("Found start of object at {$c}\n");
|
||||
|
||||
} elseif (($chrs[$c] == '}') && ($top['what'] == SERVICES_JSON_IN_OBJ)) {
|
||||
// found a right-brace, and we're in an object
|
||||
array_pop($stk);
|
||||
//print("Found end of object at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
|
||||
|
||||
} elseif (($substr_chrs_c_2 == '/*') &&
|
||||
in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
|
||||
// found a comment start, and we are in an array, object, or slice
|
||||
array_push($stk, array('what' => SERVICES_JSON_IN_CMT, 'where' => $c, 'delim' => false));
|
||||
$c++;
|
||||
//print("Found start of comment at {$c}\n");
|
||||
|
||||
} elseif (($substr_chrs_c_2 == '*/') && ($top['what'] == SERVICES_JSON_IN_CMT)) {
|
||||
// found a comment end, and we're in one now
|
||||
array_pop($stk);
|
||||
$c++;
|
||||
|
||||
for ($i = $top['where']; $i <= $c; ++$i)
|
||||
$chrs = substr_replace($chrs, ' ', $i, 1);
|
||||
|
||||
//print("Found end of comment at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (reset($stk) == SERVICES_JSON_IN_ARR) {
|
||||
return $arr;
|
||||
|
||||
} elseif (reset($stk) == SERVICES_JSON_IN_OBJ) {
|
||||
return $obj;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo Ultimately, this should just call PEAR::isError()
|
||||
*/
|
||||
function isError($data, $code = null)
|
||||
{
|
||||
if (class_exists('pear')) {
|
||||
return PEAR::isError($data, $code);
|
||||
} elseif (is_object($data) && (get_class($data) == 'services_json_error' ||
|
||||
is_subclass_of($data, 'services_json_error'))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (class_exists('PEAR_Error')) {
|
||||
|
||||
class Services_JSON_Error extends PEAR_Error
|
||||
{
|
||||
function Services_JSON_Error($message = 'unknown error', $code = null,
|
||||
$mode = null, $options = null, $userinfo = null)
|
||||
{
|
||||
parent::PEAR_Error($message, $code, $mode, $options, $userinfo);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
/**
|
||||
* @todo Ultimately, this class shall be descended from PEAR_Error
|
||||
*/
|
||||
class Services_JSON_Error
|
||||
{
|
||||
function Services_JSON_Error($message = 'unknown error', $code = null,
|
||||
$mode = null, $options = null, $userinfo = null)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
endif;
|
||||
?>
|
||||
@@ -0,0 +1,302 @@
|
||||
<?php
|
||||
/**
|
||||
* API for fetching the HTML to embed remote content based on a provided URL.
|
||||
* Used internally by the {@link WP_Embed} class, but is designed to be generic.
|
||||
*
|
||||
* @link http://codex.wordpress.org/oEmbed oEmbed Codex Article
|
||||
* @link http://oembed.com/ oEmbed Homepage
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage oEmbed
|
||||
*/
|
||||
|
||||
/**
|
||||
* oEmbed class.
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage oEmbed
|
||||
* @since 2.9.0
|
||||
*/
|
||||
class WP_oEmbed {
|
||||
var $providers = array();
|
||||
|
||||
/**
|
||||
* PHP4 constructor
|
||||
*/
|
||||
function WP_oEmbed() {
|
||||
return $this->__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* PHP5 constructor
|
||||
*
|
||||
* @uses apply_filters() Filters a list of pre-defined oEmbed providers.
|
||||
*/
|
||||
function __construct() {
|
||||
// List out some popular sites that support oEmbed.
|
||||
// The WP_Embed class disables discovery for non-unfiltered_html users, so only providers in this array will be used for them.
|
||||
// Add to this list using the wp_oembed_add_provider() function (see it's PHPDoc for details).
|
||||
$this->providers = apply_filters( 'oembed_providers', array(
|
||||
'#http://(www\.)?youtube.com/watch.*#i' => array( 'http://www.youtube.com/oembed', true ),
|
||||
'http://youtu.be/*' => array( 'http://www.youtube.com/oembed', false ),
|
||||
'http://blip.tv/file/*' => array( 'http://blip.tv/oembed/', false ),
|
||||
'#http://(www\.)?vimeo\.com/.*#i' => array( 'http://www.vimeo.com/api/oembed.{format}', true ),
|
||||
'#http://(www\.)?dailymotion\.com/.*#i' => array( 'http://www.dailymotion.com/api/oembed', true ),
|
||||
'#http://(www\.)?flickr\.com/.*#i' => array( 'http://www.flickr.com/services/oembed/', true ),
|
||||
'#http://(.+)?smugmug\.com/.*#i' => array( 'http://api.smugmug.com/services/oembed/', true ),
|
||||
'#http://(www\.)?hulu\.com/watch/.*#i' => array( 'http://www.hulu.com/api/oembed.{format}', true ),
|
||||
'#http://(www\.)?viddler\.com/.*#i' => array( 'http://lab.viddler.com/services/oembed/', true ),
|
||||
'http://qik.com/*' => array( 'http://qik.com/api/oembed.{format}', false ),
|
||||
'http://revision3.com/*' => array( 'http://revision3.com/api/oembed/', false ),
|
||||
'http://i*.photobucket.com/albums/*' => array( 'http://photobucket.com/oembed', false ),
|
||||
'http://gi*.photobucket.com/groups/*' => array( 'http://photobucket.com/oembed', false ),
|
||||
'#http://(www\.)?scribd\.com/.*#i' => array( 'http://www.scribd.com/services/oembed', true ),
|
||||
'http://wordpress.tv/*' => array( 'http://wordpress.tv/oembed/', false ),
|
||||
'#http://(answers|surveys)\.polldaddy.com/.*#i' => array( 'http://polldaddy.com/oembed/', true ),
|
||||
'#http://(www\.)?funnyordie\.com/videos/.*#i' => array( 'http://www.funnyordie.com/oembed', true ),
|
||||
) );
|
||||
|
||||
// Fix any embeds that contain new lines in the middle of the HTML which breaks wpautop().
|
||||
add_filter( 'oembed_dataparse', array(&$this, '_strip_newlines'), 10, 3 );
|
||||
}
|
||||
|
||||
/**
|
||||
* The do-it-all function that takes a URL and attempts to return the HTML.
|
||||
*
|
||||
* @see WP_oEmbed::discover()
|
||||
* @see WP_oEmbed::fetch()
|
||||
* @see WP_oEmbed::data2html()
|
||||
*
|
||||
* @param string $url The URL to the content that should be attempted to be embedded.
|
||||
* @param array $args Optional arguments. Usually passed from a shortcode.
|
||||
* @return bool|string False on failure, otherwise the UNSANITIZED (and potentially unsafe) HTML that should be used to embed.
|
||||
*/
|
||||
function get_html( $url, $args = '' ) {
|
||||
$provider = false;
|
||||
|
||||
if ( !isset($args['discover']) )
|
||||
$args['discover'] = true;
|
||||
|
||||
foreach ( $this->providers as $matchmask => $data ) {
|
||||
list( $providerurl, $regex ) = $data;
|
||||
|
||||
// Turn the asterisk-type provider URLs into regex
|
||||
if ( !$regex )
|
||||
$matchmask = '#' . str_replace( '___wildcard___', '(.+)', preg_quote( str_replace( '*', '___wildcard___', $matchmask ), '#' ) ) . '#i';
|
||||
|
||||
if ( preg_match( $matchmask, $url ) ) {
|
||||
$provider = str_replace( '{format}', 'json', $providerurl ); // JSON is easier to deal with than XML
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !$provider && $args['discover'] )
|
||||
$provider = $this->discover( $url );
|
||||
|
||||
if ( !$provider || false === $data = $this->fetch( $provider, $url, $args ) )
|
||||
return false;
|
||||
|
||||
return apply_filters( 'oembed_result', $this->data2html( $data, $url ), $url, $args );
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to find oEmbed provider discovery <link> tags at the given URL.
|
||||
*
|
||||
* @param string $url The URL that should be inspected for discovery <link> tags.
|
||||
* @return bool|string False on failure, otherwise the oEmbed provider URL.
|
||||
*/
|
||||
function discover( $url ) {
|
||||
$providers = array();
|
||||
|
||||
// Fetch URL content
|
||||
if ( $html = wp_remote_retrieve_body( wp_remote_get( $url ) ) ) {
|
||||
|
||||
// <link> types that contain oEmbed provider URLs
|
||||
$linktypes = apply_filters( 'oembed_linktypes', array(
|
||||
'application/json+oembed' => 'json',
|
||||
'text/xml+oembed' => 'xml',
|
||||
'application/xml+oembed' => 'xml', // Incorrect, but used by at least Vimeo
|
||||
) );
|
||||
|
||||
// Strip <body>
|
||||
$html = substr( $html, 0, stripos( $html, '</head>' ) );
|
||||
|
||||
// Do a quick check
|
||||
$tagfound = false;
|
||||
foreach ( $linktypes as $linktype => $format ) {
|
||||
if ( stripos($html, $linktype) ) {
|
||||
$tagfound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $tagfound && preg_match_all( '/<link([^<>]+)>/i', $html, $links ) ) {
|
||||
foreach ( $links[1] as $link ) {
|
||||
$atts = shortcode_parse_atts( $link );
|
||||
|
||||
if ( !empty($atts['type']) && !empty($linktypes[$atts['type']]) && !empty($atts['href']) ) {
|
||||
$providers[$linktypes[$atts['type']]] = $atts['href'];
|
||||
|
||||
// Stop here if it's JSON (that's all we need)
|
||||
if ( 'json' == $linktypes[$atts['type']] )
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// JSON is preferred to XML
|
||||
if ( !empty($providers['json']) )
|
||||
return $providers['json'];
|
||||
elseif ( !empty($providers['xml']) )
|
||||
return $providers['xml'];
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Connects to a oEmbed provider and returns the result.
|
||||
*
|
||||
* @param string $provider The URL to the oEmbed provider.
|
||||
* @param string $url The URL to the content that is desired to be embedded.
|
||||
* @param array $args Optional arguments. Usually passed from a shortcode.
|
||||
* @return bool|object False on failure, otherwise the result in the form of an object.
|
||||
*/
|
||||
function fetch( $provider, $url, $args = '' ) {
|
||||
$args = wp_parse_args( $args, wp_embed_defaults() );
|
||||
|
||||
$provider = add_query_arg( 'maxwidth', $args['width'], $provider );
|
||||
$provider = add_query_arg( 'maxheight', $args['height'], $provider );
|
||||
$provider = add_query_arg( 'url', urlencode($url), $provider );
|
||||
|
||||
foreach( array( 'json', 'xml' ) as $format ) {
|
||||
$result = $this->_fetch_with_format( $provider, $format );
|
||||
if ( is_wp_error( $result ) && 'not-implemented' == $result->get_error_code() )
|
||||
continue;
|
||||
return ( $result && ! is_wp_error( $result ) ) ? $result : false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches result from an oEmbed provider for a specific format and complete provider URL
|
||||
*
|
||||
* @since 3.0.0
|
||||
* @access private
|
||||
* @param string $provider_url_with_args URL to the provider with full arguments list (url, maxheight, etc.)
|
||||
* @param string $format Format to use
|
||||
* @return bool|object False on failure, otherwise the result in the form of an object.
|
||||
*/
|
||||
function _fetch_with_format( $provider_url_with_args, $format ) {
|
||||
$provider_url_with_args = add_query_arg( 'format', $format, $provider_url_with_args );
|
||||
$response = wp_remote_get( $provider_url_with_args );
|
||||
if ( 501 == wp_remote_retrieve_response_code( $response ) )
|
||||
return new WP_Error( 'not-implemented' );
|
||||
if ( ! $body = wp_remote_retrieve_body( $response ) )
|
||||
return false;
|
||||
$parse_method = "_parse_$format";
|
||||
return $this->$parse_method( $body );
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a json response body.
|
||||
*
|
||||
* @since 3.0.0
|
||||
* @access private
|
||||
*/
|
||||
function _parse_json( $response_body ) {
|
||||
return ( ( $data = json_decode( trim( $response_body ) ) ) && is_object( $data ) ) ? $data : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses an XML response body.
|
||||
*
|
||||
* @since 3.0.0
|
||||
* @access private
|
||||
*/
|
||||
function _parse_xml( $response_body ) {
|
||||
if ( function_exists('simplexml_load_string') ) {
|
||||
$errors = libxml_use_internal_errors( 'true' );
|
||||
$data = simplexml_load_string( $response_body );
|
||||
libxml_use_internal_errors( $errors );
|
||||
if ( is_object( $data ) )
|
||||
return $data;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a data object from {@link WP_oEmbed::fetch()} and returns the HTML.
|
||||
*
|
||||
* @param object $data A data object result from an oEmbed provider.
|
||||
* @param string $url The URL to the content that is desired to be embedded.
|
||||
* @return bool|string False on error, otherwise the HTML needed to embed.
|
||||
*/
|
||||
function data2html( $data, $url ) {
|
||||
if ( !is_object($data) || empty($data->type) )
|
||||
return false;
|
||||
|
||||
switch ( $data->type ) {
|
||||
case 'photo':
|
||||
if ( empty($data->url) || empty($data->width) || empty($data->height) )
|
||||
return false;
|
||||
|
||||
$title = ( !empty($data->title) ) ? $data->title : '';
|
||||
$return = '<a href="' . esc_url( $url ) . '"><img src="' . esc_url( $data->url ) . '" alt="' . esc_attr($title) . '" width="' . esc_attr($data->width) . '" height="' . esc_attr($data->height) . '" /></a>';
|
||||
break;
|
||||
|
||||
case 'video':
|
||||
case 'rich':
|
||||
$return = ( !empty($data->html) ) ? $data->html : false;
|
||||
break;
|
||||
|
||||
case 'link':
|
||||
$return = ( !empty($data->title) ) ? '<a href="' . esc_url($url) . '">' . esc_html($data->title) . '</a>' : false;
|
||||
break;
|
||||
|
||||
default;
|
||||
$return = false;
|
||||
}
|
||||
|
||||
// You can use this filter to add support for custom data types or to filter the result
|
||||
return apply_filters( 'oembed_dataparse', $return, $data, $url );
|
||||
}
|
||||
|
||||
/**
|
||||
* Strip any new lines from the HTML.
|
||||
*
|
||||
* @access private
|
||||
* @param string $html Existing HTML.
|
||||
* @param object $data Data object from WP_oEmbed::data2html()
|
||||
* @param string $url The original URL passed to oEmbed.
|
||||
* @return string Possibly modified $html
|
||||
*/
|
||||
function _strip_newlines( $html, $data, $url ) {
|
||||
if ( false !== strpos( $html, "\n" ) )
|
||||
$html = str_replace( array( "\r\n", "\n" ), '', $html );
|
||||
|
||||
return $html;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the initialized {@link WP_oEmbed} object
|
||||
*
|
||||
* @since 2.9.0
|
||||
* @access private
|
||||
*
|
||||
* @see WP_oEmbed
|
||||
* @uses WP_oEmbed
|
||||
*
|
||||
* @return WP_oEmbed object.
|
||||
*/
|
||||
function &_wp_oembed_get_object() {
|
||||
static $wp_oembed;
|
||||
|
||||
if ( is_null($wp_oembed) )
|
||||
$wp_oembed = new WP_oEmbed();
|
||||
|
||||
return $wp_oembed;
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,258 @@
|
||||
<?php
|
||||
/**
|
||||
* Portable PHP password hashing framework.
|
||||
* @package phpass
|
||||
* @since 2.5
|
||||
* @version 0.2 / genuine.
|
||||
* @link http://www.openwall.com/phpass/
|
||||
*/
|
||||
|
||||
#
|
||||
# Written by Solar Designer <solar at openwall.com> in 2004-2006 and placed in
|
||||
# the public domain.
|
||||
#
|
||||
# There's absolutely no warranty.
|
||||
#
|
||||
# Please be sure to update the Version line if you edit this file in any way.
|
||||
# It is suggested that you leave the main version number intact, but indicate
|
||||
# your project name (after the slash) and add your own revision information.
|
||||
#
|
||||
# Please do not change the "private" password hashing method implemented in
|
||||
# here, thereby making your hashes incompatible. However, if you must, please
|
||||
# change the hash type identifier (the "$P$") to something different.
|
||||
#
|
||||
# Obviously, since this code is in the public domain, the above are not
|
||||
# requirements (there can be none), but merely suggestions.
|
||||
#
|
||||
|
||||
/**
|
||||
* Portable PHP password hashing framework.
|
||||
*
|
||||
* @package phpass
|
||||
* @version 0.2 / genuine.
|
||||
* @link http://www.openwall.com/phpass/
|
||||
* @since 2.5
|
||||
*/
|
||||
class PasswordHash {
|
||||
var $itoa64;
|
||||
var $iteration_count_log2;
|
||||
var $portable_hashes;
|
||||
var $random_state;
|
||||
|
||||
function PasswordHash($iteration_count_log2, $portable_hashes)
|
||||
{
|
||||
$this->itoa64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
|
||||
|
||||
if ($iteration_count_log2 < 4 || $iteration_count_log2 > 31)
|
||||
$iteration_count_log2 = 8;
|
||||
$this->iteration_count_log2 = $iteration_count_log2;
|
||||
|
||||
$this->portable_hashes = $portable_hashes;
|
||||
|
||||
$this->random_state = microtime() . uniqid(rand(), TRUE); // removed getmypid() for compability reasons
|
||||
}
|
||||
|
||||
function get_random_bytes($count)
|
||||
{
|
||||
$output = '';
|
||||
if ( @is_readable('/dev/urandom') &&
|
||||
($fh = @fopen('/dev/urandom', 'rb'))) {
|
||||
$output = fread($fh, $count);
|
||||
fclose($fh);
|
||||
}
|
||||
|
||||
if (strlen($output) < $count) {
|
||||
$output = '';
|
||||
for ($i = 0; $i < $count; $i += 16) {
|
||||
$this->random_state =
|
||||
md5(microtime() . $this->random_state);
|
||||
$output .=
|
||||
pack('H*', md5($this->random_state));
|
||||
}
|
||||
$output = substr($output, 0, $count);
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
function encode64($input, $count)
|
||||
{
|
||||
$output = '';
|
||||
$i = 0;
|
||||
do {
|
||||
$value = ord($input[$i++]);
|
||||
$output .= $this->itoa64[$value & 0x3f];
|
||||
if ($i < $count)
|
||||
$value |= ord($input[$i]) << 8;
|
||||
$output .= $this->itoa64[($value >> 6) & 0x3f];
|
||||
if ($i++ >= $count)
|
||||
break;
|
||||
if ($i < $count)
|
||||
$value |= ord($input[$i]) << 16;
|
||||
$output .= $this->itoa64[($value >> 12) & 0x3f];
|
||||
if ($i++ >= $count)
|
||||
break;
|
||||
$output .= $this->itoa64[($value >> 18) & 0x3f];
|
||||
} while ($i < $count);
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
function gensalt_private($input)
|
||||
{
|
||||
$output = '$P$';
|
||||
$output .= $this->itoa64[min($this->iteration_count_log2 +
|
||||
((PHP_VERSION >= '5') ? 5 : 3), 30)];
|
||||
$output .= $this->encode64($input, 6);
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
function crypt_private($password, $setting)
|
||||
{
|
||||
$output = '*0';
|
||||
if (substr($setting, 0, 2) == $output)
|
||||
$output = '*1';
|
||||
|
||||
if (substr($setting, 0, 3) != '$P$')
|
||||
return $output;
|
||||
|
||||
$count_log2 = strpos($this->itoa64, $setting[3]);
|
||||
if ($count_log2 < 7 || $count_log2 > 30)
|
||||
return $output;
|
||||
|
||||
$count = 1 << $count_log2;
|
||||
|
||||
$salt = substr($setting, 4, 8);
|
||||
if (strlen($salt) != 8)
|
||||
return $output;
|
||||
|
||||
# We're kind of forced to use MD5 here since it's the only
|
||||
# cryptographic primitive available in all versions of PHP
|
||||
# currently in use. To implement our own low-level crypto
|
||||
# in PHP would result in much worse performance and
|
||||
# consequently in lower iteration counts and hashes that are
|
||||
# quicker to crack (by non-PHP code).
|
||||
if (PHP_VERSION >= '5') {
|
||||
$hash = md5($salt . $password, TRUE);
|
||||
do {
|
||||
$hash = md5($hash . $password, TRUE);
|
||||
} while (--$count);
|
||||
} else {
|
||||
$hash = pack('H*', md5($salt . $password));
|
||||
do {
|
||||
$hash = pack('H*', md5($hash . $password));
|
||||
} while (--$count);
|
||||
}
|
||||
|
||||
$output = substr($setting, 0, 12);
|
||||
$output .= $this->encode64($hash, 16);
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
function gensalt_extended($input)
|
||||
{
|
||||
$count_log2 = min($this->iteration_count_log2 + 8, 24);
|
||||
# This should be odd to not reveal weak DES keys, and the
|
||||
# maximum valid value is (2**24 - 1) which is odd anyway.
|
||||
$count = (1 << $count_log2) - 1;
|
||||
|
||||
$output = '_';
|
||||
$output .= $this->itoa64[$count & 0x3f];
|
||||
$output .= $this->itoa64[($count >> 6) & 0x3f];
|
||||
$output .= $this->itoa64[($count >> 12) & 0x3f];
|
||||
$output .= $this->itoa64[($count >> 18) & 0x3f];
|
||||
|
||||
$output .= $this->encode64($input, 3);
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
function gensalt_blowfish($input)
|
||||
{
|
||||
# This one needs to use a different order of characters and a
|
||||
# different encoding scheme from the one in encode64() above.
|
||||
# We care because the last character in our encoded string will
|
||||
# only represent 2 bits. While two known implementations of
|
||||
# bcrypt will happily accept and correct a salt string which
|
||||
# has the 4 unused bits set to non-zero, we do not want to take
|
||||
# chances and we also do not want to waste an additional byte
|
||||
# of entropy.
|
||||
$itoa64 = './ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||
|
||||
$output = '$2a$';
|
||||
$output .= chr(ord('0') + $this->iteration_count_log2 / 10);
|
||||
$output .= chr(ord('0') + $this->iteration_count_log2 % 10);
|
||||
$output .= '$';
|
||||
|
||||
$i = 0;
|
||||
do {
|
||||
$c1 = ord($input[$i++]);
|
||||
$output .= $itoa64[$c1 >> 2];
|
||||
$c1 = ($c1 & 0x03) << 4;
|
||||
if ($i >= 16) {
|
||||
$output .= $itoa64[$c1];
|
||||
break;
|
||||
}
|
||||
|
||||
$c2 = ord($input[$i++]);
|
||||
$c1 |= $c2 >> 4;
|
||||
$output .= $itoa64[$c1];
|
||||
$c1 = ($c2 & 0x0f) << 2;
|
||||
|
||||
$c2 = ord($input[$i++]);
|
||||
$c1 |= $c2 >> 6;
|
||||
$output .= $itoa64[$c1];
|
||||
$output .= $itoa64[$c2 & 0x3f];
|
||||
} while (1);
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
function HashPassword($password)
|
||||
{
|
||||
$random = '';
|
||||
|
||||
if (CRYPT_BLOWFISH == 1 && !$this->portable_hashes) {
|
||||
$random = $this->get_random_bytes(16);
|
||||
$hash =
|
||||
crypt($password, $this->gensalt_blowfish($random));
|
||||
if (strlen($hash) == 60)
|
||||
return $hash;
|
||||
}
|
||||
|
||||
if (CRYPT_EXT_DES == 1 && !$this->portable_hashes) {
|
||||
if (strlen($random) < 3)
|
||||
$random = $this->get_random_bytes(3);
|
||||
$hash =
|
||||
crypt($password, $this->gensalt_extended($random));
|
||||
if (strlen($hash) == 20)
|
||||
return $hash;
|
||||
}
|
||||
|
||||
if (strlen($random) < 6)
|
||||
$random = $this->get_random_bytes(6);
|
||||
$hash =
|
||||
$this->crypt_private($password,
|
||||
$this->gensalt_private($random));
|
||||
if (strlen($hash) == 34)
|
||||
return $hash;
|
||||
|
||||
# Returning '*' on error is safe here, but would _not_ be safe
|
||||
# in a crypt(3)-like function used _both_ for generating new
|
||||
# hashes and for validating passwords against existing hashes.
|
||||
return '*';
|
||||
}
|
||||
|
||||
function CheckPassword($password, $stored_hash)
|
||||
{
|
||||
$hash = $this->crypt_private($password, $stored_hash);
|
||||
if ($hash[0] == '*')
|
||||
$hash = crypt($password, $stored_hash);
|
||||
|
||||
return $hash == $stored_hash;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,652 @@
|
||||
<?php
|
||||
/**
|
||||
* mail_fetch/setup.php
|
||||
*
|
||||
* @package SquirrelMail
|
||||
*
|
||||
* @copyright (c) 1999-2006 The SquirrelMail Project Team
|
||||
*
|
||||
* @copyright (c) 1999 CDI (cdi@thewebmasters.net) All Rights Reserved
|
||||
* Modified by Philippe Mingo 2001 mingo@rotedic.com
|
||||
* An RFC 1939 compliant wrapper class for the POP3 protocol.
|
||||
*
|
||||
* Licensed under the GNU GPL. For full terms see the file COPYING.
|
||||
* @license http://opensource.org/licenses/gpl-license.php GNU General Public License
|
||||
*
|
||||
* pop3 class
|
||||
*
|
||||
* $Id: class-pop3.php 17436 2011-02-09 17:36:23Z ryan $
|
||||
*/
|
||||
|
||||
class POP3 {
|
||||
var $ERROR = ''; // Error string.
|
||||
|
||||
var $TIMEOUT = 60; // Default timeout before giving up on a
|
||||
// network operation.
|
||||
|
||||
var $COUNT = -1; // Mailbox msg count
|
||||
|
||||
var $BUFFER = 512; // Socket buffer for socket fgets() calls.
|
||||
// Per RFC 1939 the returned line a POP3
|
||||
// server can send is 512 bytes.
|
||||
|
||||
var $FP = ''; // The connection to the server's
|
||||
// file descriptor
|
||||
|
||||
var $MAILSERVER = ''; // Set this to hard code the server name
|
||||
|
||||
var $DEBUG = FALSE; // set to true to echo pop3
|
||||
// commands and responses to error_log
|
||||
// this WILL log passwords!
|
||||
|
||||
var $BANNER = ''; // Holds the banner returned by the
|
||||
// pop server - used for apop()
|
||||
|
||||
var $ALLOWAPOP = FALSE; // Allow or disallow apop()
|
||||
// This must be set to true
|
||||
// manually
|
||||
|
||||
function POP3 ( $server = '', $timeout = '' ) {
|
||||
settype($this->BUFFER,"integer");
|
||||
if( !empty($server) ) {
|
||||
// Do not allow programs to alter MAILSERVER
|
||||
// if it is already specified. They can get around
|
||||
// this if they -really- want to, so don't count on it.
|
||||
if(empty($this->MAILSERVER))
|
||||
$this->MAILSERVER = $server;
|
||||
}
|
||||
if(!empty($timeout)) {
|
||||
settype($timeout,"integer");
|
||||
$this->TIMEOUT = $timeout;
|
||||
if (!ini_get('safe_mode'))
|
||||
set_time_limit($timeout);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function update_timer () {
|
||||
if (!ini_get('safe_mode'))
|
||||
set_time_limit($this->TIMEOUT);
|
||||
return true;
|
||||
}
|
||||
|
||||
function connect ($server, $port = 110) {
|
||||
// Opens a socket to the specified server. Unless overridden,
|
||||
// port defaults to 110. Returns true on success, false on fail
|
||||
|
||||
// If MAILSERVER is set, override $server with it's value
|
||||
|
||||
if (!isset($port) || !$port) {$port = 110;}
|
||||
if(!empty($this->MAILSERVER))
|
||||
$server = $this->MAILSERVER;
|
||||
|
||||
if(empty($server)){
|
||||
$this->ERROR = "POP3 connect: " . _("No server specified");
|
||||
unset($this->FP);
|
||||
return false;
|
||||
}
|
||||
|
||||
$fp = @fsockopen("$server", $port, $errno, $errstr);
|
||||
|
||||
if(!$fp) {
|
||||
$this->ERROR = "POP3 connect: " . _("Error ") . "[$errno] [$errstr]";
|
||||
unset($this->FP);
|
||||
return false;
|
||||
}
|
||||
|
||||
socket_set_blocking($fp,-1);
|
||||
$this->update_timer();
|
||||
$reply = fgets($fp,$this->BUFFER);
|
||||
$reply = $this->strip_clf($reply);
|
||||
if($this->DEBUG)
|
||||
error_log("POP3 SEND [connect: $server] GOT [$reply]",0);
|
||||
if(!$this->is_ok($reply)) {
|
||||
$this->ERROR = "POP3 connect: " . _("Error ") . "[$reply]";
|
||||
unset($this->FP);
|
||||
return false;
|
||||
}
|
||||
$this->FP = $fp;
|
||||
$this->BANNER = $this->parse_banner($reply);
|
||||
return true;
|
||||
}
|
||||
|
||||
function user ($user = "") {
|
||||
// Sends the USER command, returns true or false
|
||||
|
||||
if( empty($user) ) {
|
||||
$this->ERROR = "POP3 user: " . _("no login ID submitted");
|
||||
return false;
|
||||
} elseif(!isset($this->FP)) {
|
||||
$this->ERROR = "POP3 user: " . _("connection not established");
|
||||
return false;
|
||||
} else {
|
||||
$reply = $this->send_cmd("USER $user");
|
||||
if(!$this->is_ok($reply)) {
|
||||
$this->ERROR = "POP3 user: " . _("Error ") . "[$reply]";
|
||||
return false;
|
||||
} else
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
function pass ($pass = "") {
|
||||
// Sends the PASS command, returns # of msgs in mailbox,
|
||||
// returns false (undef) on Auth failure
|
||||
|
||||
if(empty($pass)) {
|
||||
$this->ERROR = "POP3 pass: " . _("No password submitted");
|
||||
return false;
|
||||
} elseif(!isset($this->FP)) {
|
||||
$this->ERROR = "POP3 pass: " . _("connection not established");
|
||||
return false;
|
||||
} else {
|
||||
$reply = $this->send_cmd("PASS $pass");
|
||||
if(!$this->is_ok($reply)) {
|
||||
$this->ERROR = "POP3 pass: " . _("Authentication failed") . " [$reply]";
|
||||
$this->quit();
|
||||
return false;
|
||||
} else {
|
||||
// Auth successful.
|
||||
$count = $this->last("count");
|
||||
$this->COUNT = $count;
|
||||
return $count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function apop ($login,$pass) {
|
||||
// Attempts an APOP login. If this fails, it'll
|
||||
// try a standard login. YOUR SERVER MUST SUPPORT
|
||||
// THE USE OF THE APOP COMMAND!
|
||||
// (apop is optional per rfc1939)
|
||||
|
||||
if(!isset($this->FP)) {
|
||||
$this->ERROR = "POP3 apop: " . _("No connection to server");
|
||||
return false;
|
||||
} elseif(!$this->ALLOWAPOP) {
|
||||
$retVal = $this->login($login,$pass);
|
||||
return $retVal;
|
||||
} elseif(empty($login)) {
|
||||
$this->ERROR = "POP3 apop: " . _("No login ID submitted");
|
||||
return false;
|
||||
} elseif(empty($pass)) {
|
||||
$this->ERROR = "POP3 apop: " . _("No password submitted");
|
||||
return false;
|
||||
} else {
|
||||
$banner = $this->BANNER;
|
||||
if( (!$banner) or (empty($banner)) ) {
|
||||
$this->ERROR = "POP3 apop: " . _("No server banner") . ' - ' . _("abort");
|
||||
$retVal = $this->login($login,$pass);
|
||||
return $retVal;
|
||||
} else {
|
||||
$AuthString = $banner;
|
||||
$AuthString .= $pass;
|
||||
$APOPString = md5($AuthString);
|
||||
$cmd = "APOP $login $APOPString";
|
||||
$reply = $this->send_cmd($cmd);
|
||||
if(!$this->is_ok($reply)) {
|
||||
$this->ERROR = "POP3 apop: " . _("apop authentication failed") . ' - ' . _("abort");
|
||||
$retVal = $this->login($login,$pass);
|
||||
return $retVal;
|
||||
} else {
|
||||
// Auth successful.
|
||||
$count = $this->last("count");
|
||||
$this->COUNT = $count;
|
||||
return $count;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function login ($login = "", $pass = "") {
|
||||
// Sends both user and pass. Returns # of msgs in mailbox or
|
||||
// false on failure (or -1, if the error occurs while getting
|
||||
// the number of messages.)
|
||||
|
||||
if( !isset($this->FP) ) {
|
||||
$this->ERROR = "POP3 login: " . _("No connection to server");
|
||||
return false;
|
||||
} else {
|
||||
$fp = $this->FP;
|
||||
if( !$this->user( $login ) ) {
|
||||
// Preserve the error generated by user()
|
||||
return false;
|
||||
} else {
|
||||
$count = $this->pass($pass);
|
||||
if( (!$count) || ($count == -1) ) {
|
||||
// Preserve the error generated by last() and pass()
|
||||
return false;
|
||||
} else
|
||||
return $count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function top ($msgNum, $numLines = "0") {
|
||||
// Gets the header and first $numLines of the msg body
|
||||
// returns data in an array with each returned line being
|
||||
// an array element. If $numLines is empty, returns
|
||||
// only the header information, and none of the body.
|
||||
|
||||
if(!isset($this->FP)) {
|
||||
$this->ERROR = "POP3 top: " . _("No connection to server");
|
||||
return false;
|
||||
}
|
||||
$this->update_timer();
|
||||
|
||||
$fp = $this->FP;
|
||||
$buffer = $this->BUFFER;
|
||||
$cmd = "TOP $msgNum $numLines";
|
||||
fwrite($fp, "TOP $msgNum $numLines\r\n");
|
||||
$reply = fgets($fp, $buffer);
|
||||
$reply = $this->strip_clf($reply);
|
||||
if($this->DEBUG) {
|
||||
@error_log("POP3 SEND [$cmd] GOT [$reply]",0);
|
||||
}
|
||||
if(!$this->is_ok($reply))
|
||||
{
|
||||
$this->ERROR = "POP3 top: " . _("Error ") . "[$reply]";
|
||||
return false;
|
||||
}
|
||||
|
||||
$count = 0;
|
||||
$MsgArray = array();
|
||||
|
||||
$line = fgets($fp,$buffer);
|
||||
while ( !ereg("^\.\r\n",$line))
|
||||
{
|
||||
$MsgArray[$count] = $line;
|
||||
$count++;
|
||||
$line = fgets($fp,$buffer);
|
||||
if(empty($line)) { break; }
|
||||
}
|
||||
|
||||
return $MsgArray;
|
||||
}
|
||||
|
||||
function pop_list ($msgNum = "") {
|
||||
// If called with an argument, returns that msgs' size in octets
|
||||
// No argument returns an associative array of undeleted
|
||||
// msg numbers and their sizes in octets
|
||||
|
||||
if(!isset($this->FP))
|
||||
{
|
||||
$this->ERROR = "POP3 pop_list: " . _("No connection to server");
|
||||
return false;
|
||||
}
|
||||
$fp = $this->FP;
|
||||
$Total = $this->COUNT;
|
||||
if( (!$Total) or ($Total == -1) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if($Total == 0)
|
||||
{
|
||||
return array("0","0");
|
||||
// return -1; // mailbox empty
|
||||
}
|
||||
|
||||
$this->update_timer();
|
||||
|
||||
if(!empty($msgNum))
|
||||
{
|
||||
$cmd = "LIST $msgNum";
|
||||
fwrite($fp,"$cmd\r\n");
|
||||
$reply = fgets($fp,$this->BUFFER);
|
||||
$reply = $this->strip_clf($reply);
|
||||
if($this->DEBUG) {
|
||||
@error_log("POP3 SEND [$cmd] GOT [$reply]",0);
|
||||
}
|
||||
if(!$this->is_ok($reply))
|
||||
{
|
||||
$this->ERROR = "POP3 pop_list: " . _("Error ") . "[$reply]";
|
||||
return false;
|
||||
}
|
||||
list($junk,$num,$size) = preg_split('/\s+/',$reply);
|
||||
return $size;
|
||||
}
|
||||
$cmd = "LIST";
|
||||
$reply = $this->send_cmd($cmd);
|
||||
if(!$this->is_ok($reply))
|
||||
{
|
||||
$reply = $this->strip_clf($reply);
|
||||
$this->ERROR = "POP3 pop_list: " . _("Error ") . "[$reply]";
|
||||
return false;
|
||||
}
|
||||
$MsgArray = array();
|
||||
$MsgArray[0] = $Total;
|
||||
for($msgC=1;$msgC <= $Total; $msgC++)
|
||||
{
|
||||
if($msgC > $Total) { break; }
|
||||
$line = fgets($fp,$this->BUFFER);
|
||||
$line = $this->strip_clf($line);
|
||||
if(ereg("^\.",$line))
|
||||
{
|
||||
$this->ERROR = "POP3 pop_list: " . _("Premature end of list");
|
||||
return false;
|
||||
}
|
||||
list($thisMsg,$msgSize) = preg_split('/\s+/',$line);
|
||||
settype($thisMsg,"integer");
|
||||
if($thisMsg != $msgC)
|
||||
{
|
||||
$MsgArray[$msgC] = "deleted";
|
||||
}
|
||||
else
|
||||
{
|
||||
$MsgArray[$msgC] = $msgSize;
|
||||
}
|
||||
}
|
||||
return $MsgArray;
|
||||
}
|
||||
|
||||
function get ($msgNum) {
|
||||
// Retrieve the specified msg number. Returns an array
|
||||
// where each line of the msg is an array element.
|
||||
|
||||
if(!isset($this->FP))
|
||||
{
|
||||
$this->ERROR = "POP3 get: " . _("No connection to server");
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->update_timer();
|
||||
|
||||
$fp = $this->FP;
|
||||
$buffer = $this->BUFFER;
|
||||
$cmd = "RETR $msgNum";
|
||||
$reply = $this->send_cmd($cmd);
|
||||
|
||||
if(!$this->is_ok($reply))
|
||||
{
|
||||
$this->ERROR = "POP3 get: " . _("Error ") . "[$reply]";
|
||||
return false;
|
||||
}
|
||||
|
||||
$count = 0;
|
||||
$MsgArray = array();
|
||||
|
||||
$line = fgets($fp,$buffer);
|
||||
while ( !ereg("^\.\r\n",$line))
|
||||
{
|
||||
if ( $line[0] == '.' ) { $line = substr($line,1); }
|
||||
$MsgArray[$count] = $line;
|
||||
$count++;
|
||||
$line = fgets($fp,$buffer);
|
||||
if(empty($line)) { break; }
|
||||
}
|
||||
return $MsgArray;
|
||||
}
|
||||
|
||||
function last ( $type = "count" ) {
|
||||
// Returns the highest msg number in the mailbox.
|
||||
// returns -1 on error, 0+ on success, if type != count
|
||||
// results in a popstat() call (2 element array returned)
|
||||
|
||||
$last = -1;
|
||||
if(!isset($this->FP))
|
||||
{
|
||||
$this->ERROR = "POP3 last: " . _("No connection to server");
|
||||
return $last;
|
||||
}
|
||||
|
||||
$reply = $this->send_cmd("STAT");
|
||||
if(!$this->is_ok($reply))
|
||||
{
|
||||
$this->ERROR = "POP3 last: " . _("Error ") . "[$reply]";
|
||||
return $last;
|
||||
}
|
||||
|
||||
$Vars = preg_split('/\s+/',$reply);
|
||||
$count = $Vars[1];
|
||||
$size = $Vars[2];
|
||||
settype($count,"integer");
|
||||
settype($size,"integer");
|
||||
if($type != "count")
|
||||
{
|
||||
return array($count,$size);
|
||||
}
|
||||
return $count;
|
||||
}
|
||||
|
||||
function reset () {
|
||||
// Resets the status of the remote server. This includes
|
||||
// resetting the status of ALL msgs to not be deleted.
|
||||
// This method automatically closes the connection to the server.
|
||||
|
||||
if(!isset($this->FP))
|
||||
{
|
||||
$this->ERROR = "POP3 reset: " . _("No connection to server");
|
||||
return false;
|
||||
}
|
||||
$reply = $this->send_cmd("RSET");
|
||||
if(!$this->is_ok($reply))
|
||||
{
|
||||
// The POP3 RSET command -never- gives a -ERR
|
||||
// response - if it ever does, something truely
|
||||
// wild is going on.
|
||||
|
||||
$this->ERROR = "POP3 reset: " . _("Error ") . "[$reply]";
|
||||
@error_log("POP3 reset: ERROR [$reply]",0);
|
||||
}
|
||||
$this->quit();
|
||||
return true;
|
||||
}
|
||||
|
||||
function send_cmd ( $cmd = "" )
|
||||
{
|
||||
// Sends a user defined command string to the
|
||||
// POP server and returns the results. Useful for
|
||||
// non-compliant or custom POP servers.
|
||||
// Do NOT includ the \r\n as part of your command
|
||||
// string - it will be appended automatically.
|
||||
|
||||
// The return value is a standard fgets() call, which
|
||||
// will read up to $this->BUFFER bytes of data, until it
|
||||
// encounters a new line, or EOF, whichever happens first.
|
||||
|
||||
// This method works best if $cmd responds with only
|
||||
// one line of data.
|
||||
|
||||
if(!isset($this->FP))
|
||||
{
|
||||
$this->ERROR = "POP3 send_cmd: " . _("No connection to server");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(empty($cmd))
|
||||
{
|
||||
$this->ERROR = "POP3 send_cmd: " . _("Empty command string");
|
||||
return "";
|
||||
}
|
||||
|
||||
$fp = $this->FP;
|
||||
$buffer = $this->BUFFER;
|
||||
$this->update_timer();
|
||||
fwrite($fp,"$cmd\r\n");
|
||||
$reply = fgets($fp,$buffer);
|
||||
$reply = $this->strip_clf($reply);
|
||||
if($this->DEBUG) { @error_log("POP3 SEND [$cmd] GOT [$reply]",0); }
|
||||
return $reply;
|
||||
}
|
||||
|
||||
function quit() {
|
||||
// Closes the connection to the POP3 server, deleting
|
||||
// any msgs marked as deleted.
|
||||
|
||||
if(!isset($this->FP))
|
||||
{
|
||||
$this->ERROR = "POP3 quit: " . _("connection does not exist");
|
||||
return false;
|
||||
}
|
||||
$fp = $this->FP;
|
||||
$cmd = "QUIT";
|
||||
fwrite($fp,"$cmd\r\n");
|
||||
$reply = fgets($fp,$this->BUFFER);
|
||||
$reply = $this->strip_clf($reply);
|
||||
if($this->DEBUG) { @error_log("POP3 SEND [$cmd] GOT [$reply]",0); }
|
||||
fclose($fp);
|
||||
unset($this->FP);
|
||||
return true;
|
||||
}
|
||||
|
||||
function popstat () {
|
||||
// Returns an array of 2 elements. The number of undeleted
|
||||
// msgs in the mailbox, and the size of the mbox in octets.
|
||||
|
||||
$PopArray = $this->last("array");
|
||||
|
||||
if($PopArray == -1) { return false; }
|
||||
|
||||
if( (!$PopArray) or (empty($PopArray)) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return $PopArray;
|
||||
}
|
||||
|
||||
function uidl ($msgNum = "")
|
||||
{
|
||||
// Returns the UIDL of the msg specified. If called with
|
||||
// no arguments, returns an associative array where each
|
||||
// undeleted msg num is a key, and the msg's uidl is the element
|
||||
// Array element 0 will contain the total number of msgs
|
||||
|
||||
if(!isset($this->FP)) {
|
||||
$this->ERROR = "POP3 uidl: " . _("No connection to server");
|
||||
return false;
|
||||
}
|
||||
|
||||
$fp = $this->FP;
|
||||
$buffer = $this->BUFFER;
|
||||
|
||||
if(!empty($msgNum)) {
|
||||
$cmd = "UIDL $msgNum";
|
||||
$reply = $this->send_cmd($cmd);
|
||||
if(!$this->is_ok($reply))
|
||||
{
|
||||
$this->ERROR = "POP3 uidl: " . _("Error ") . "[$reply]";
|
||||
return false;
|
||||
}
|
||||
list ($ok,$num,$myUidl) = preg_split('/\s+/',$reply);
|
||||
return $myUidl;
|
||||
} else {
|
||||
$this->update_timer();
|
||||
|
||||
$UIDLArray = array();
|
||||
$Total = $this->COUNT;
|
||||
$UIDLArray[0] = $Total;
|
||||
|
||||
if ($Total < 1)
|
||||
{
|
||||
return $UIDLArray;
|
||||
}
|
||||
$cmd = "UIDL";
|
||||
fwrite($fp, "UIDL\r\n");
|
||||
$reply = fgets($fp, $buffer);
|
||||
$reply = $this->strip_clf($reply);
|
||||
if($this->DEBUG) { @error_log("POP3 SEND [$cmd] GOT [$reply]",0); }
|
||||
if(!$this->is_ok($reply))
|
||||
{
|
||||
$this->ERROR = "POP3 uidl: " . _("Error ") . "[$reply]";
|
||||
return false;
|
||||
}
|
||||
|
||||
$line = "";
|
||||
$count = 1;
|
||||
$line = fgets($fp,$buffer);
|
||||
while ( !ereg("^\.\r\n",$line)) {
|
||||
if(ereg("^\.\r\n",$line)) {
|
||||
break;
|
||||
}
|
||||
list ($msg,$msgUidl) = preg_split('/\s+/',$line);
|
||||
$msgUidl = $this->strip_clf($msgUidl);
|
||||
if($count == $msg) {
|
||||
$UIDLArray[$msg] = $msgUidl;
|
||||
}
|
||||
else
|
||||
{
|
||||
$UIDLArray[$count] = 'deleted';
|
||||
}
|
||||
$count++;
|
||||
$line = fgets($fp,$buffer);
|
||||
}
|
||||
}
|
||||
return $UIDLArray;
|
||||
}
|
||||
|
||||
function delete ($msgNum = "") {
|
||||
// Flags a specified msg as deleted. The msg will not
|
||||
// be deleted until a quit() method is called.
|
||||
|
||||
if(!isset($this->FP))
|
||||
{
|
||||
$this->ERROR = "POP3 delete: " . _("No connection to server");
|
||||
return false;
|
||||
}
|
||||
if(empty($msgNum))
|
||||
{
|
||||
$this->ERROR = "POP3 delete: " . _("No msg number submitted");
|
||||
return false;
|
||||
}
|
||||
$reply = $this->send_cmd("DELE $msgNum");
|
||||
if(!$this->is_ok($reply))
|
||||
{
|
||||
$this->ERROR = "POP3 delete: " . _("Command failed ") . "[$reply]";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// *********************************************************
|
||||
|
||||
// The following methods are internal to the class.
|
||||
|
||||
function is_ok ($cmd = "") {
|
||||
// Return true or false on +OK or -ERR
|
||||
|
||||
if( empty($cmd) )
|
||||
return false;
|
||||
else
|
||||
return( ereg ("^\+OK", $cmd ) );
|
||||
}
|
||||
|
||||
function strip_clf ($text = "") {
|
||||
// Strips \r\n from server responses
|
||||
|
||||
if(empty($text))
|
||||
return $text;
|
||||
else {
|
||||
$stripped = str_replace("\r",'',$text);
|
||||
$stripped = str_replace("\n",'',$stripped);
|
||||
return $stripped;
|
||||
}
|
||||
}
|
||||
|
||||
function parse_banner ( $server_text ) {
|
||||
$outside = true;
|
||||
$banner = "";
|
||||
$length = strlen($server_text);
|
||||
for($count =0; $count < $length; $count++)
|
||||
{
|
||||
$digit = substr($server_text,$count,1);
|
||||
if(!empty($digit)) {
|
||||
if( (!$outside) && ($digit != '<') && ($digit != '>') )
|
||||
{
|
||||
$banner .= $digit;
|
||||
}
|
||||
if ($digit == '<')
|
||||
{
|
||||
$outside = false;
|
||||
}
|
||||
if($digit == '>')
|
||||
{
|
||||
$outside = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
$banner = $this->strip_clf($banner); // Just in case
|
||||
return "<$banner>";
|
||||
}
|
||||
|
||||
} // End class
|
||||
?>
|
||||
@@ -0,0 +1,236 @@
|
||||
<?php
|
||||
class WP_Admin_Bar {
|
||||
var $changed_locale = false;
|
||||
var $menu;
|
||||
var $need_to_change_locale = false;
|
||||
var $proto = 'http://';
|
||||
var $user;
|
||||
|
||||
function initialize() {
|
||||
/* Set the protocol used throughout this code */
|
||||
if ( is_ssl() )
|
||||
$this->proto = 'https://';
|
||||
|
||||
$this->user = new stdClass;
|
||||
$this->menu = new stdClass;
|
||||
|
||||
/* Populate settings we need for the menu based on the current user. */
|
||||
$this->user->blogs = get_blogs_of_user( get_current_user_id() );
|
||||
if ( is_multisite() ) {
|
||||
$this->user->active_blog = get_active_blog_for_user( get_current_user_id() );
|
||||
$this->user->domain = empty( $this->user->active_blog ) ? user_admin_url() : trailingslashit( get_home_url( $this->user->active_blog->blog_id ) );
|
||||
$this->user->account_domain = $this->user->domain;
|
||||
} else {
|
||||
$this->user->active_blog = $this->user->blogs[get_current_blog_id()];
|
||||
$this->user->domain = trailingslashit( home_url() );
|
||||
$this->user->account_domain = $this->user->domain;
|
||||
}
|
||||
$this->user->locale = get_locale();
|
||||
|
||||
add_action( 'wp_head', 'wp_admin_bar_header' );
|
||||
|
||||
add_action( 'admin_head', 'wp_admin_bar_header' );
|
||||
|
||||
if ( current_theme_supports( 'admin-bar' ) ) {
|
||||
$admin_bar_args = get_theme_support( 'admin-bar' ); // add_theme_support( 'admin-bar', array( 'callback' => '__return_false') );
|
||||
$header_callback = $admin_bar_args[0]['callback'];
|
||||
}
|
||||
|
||||
if ( empty($header_callback) )
|
||||
$header_callback = '_admin_bar_bump_cb';
|
||||
|
||||
add_action('wp_head', $header_callback);
|
||||
|
||||
wp_enqueue_script( 'admin-bar' );
|
||||
wp_enqueue_style( 'admin-bar' );
|
||||
|
||||
do_action( 'admin_bar_init' );
|
||||
}
|
||||
|
||||
function add_menu( $args = array() ) {
|
||||
$defaults = array(
|
||||
'title' => false,
|
||||
'href' => false,
|
||||
'parent' => false, // false for a root menu, pass the ID value for a submenu of that menu.
|
||||
'id' => false, // defaults to a sanitized title value.
|
||||
'meta' => false // array of any of the following options: array( 'html' => '', 'class' => '', 'onclick' => '', target => '', title => '' );
|
||||
);
|
||||
|
||||
$r = wp_parse_args( $args, $defaults );
|
||||
extract( $r, EXTR_SKIP );
|
||||
|
||||
if ( empty( $title ) )
|
||||
return false;
|
||||
|
||||
/* Make sure we have a valid ID */
|
||||
if ( empty( $id ) )
|
||||
$id = esc_attr( sanitize_title( trim( $title ) ) );
|
||||
|
||||
if ( ! empty( $parent ) ) {
|
||||
/* Add the menu to the parent item */
|
||||
$child = array( 'id' => $id, 'title' => $title, 'href' => $href );
|
||||
|
||||
if ( ! empty( $meta ) )
|
||||
$child['meta'] = $meta;
|
||||
|
||||
$this->add_node( $parent, $this->menu, $child );
|
||||
} else {
|
||||
/* Add the menu item */
|
||||
$this->menu->{$id} = array( 'title' => $title, 'href' => $href );
|
||||
|
||||
if ( ! empty( $meta ) )
|
||||
$this->menu->{$id}['meta'] = $meta;
|
||||
}
|
||||
}
|
||||
|
||||
function remove_menu( $id ) {
|
||||
return $this->remove_node( $id, $this->menu );
|
||||
}
|
||||
|
||||
function render() {
|
||||
?>
|
||||
<div id="wpadminbar">
|
||||
<div class="quicklinks">
|
||||
<ul>
|
||||
<?php foreach ( (array) $this->menu as $id => $menu_item ) : ?>
|
||||
<?php $this->recursive_render( $id, $menu_item ) ?>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div id="adminbarsearch-wrap">
|
||||
<form action="<?php echo home_url(); ?>" method="get" id="adminbarsearch">
|
||||
<input class="adminbar-input" name="s" id="adminbar-search" type="text" value="" maxlength="150" />
|
||||
<input type="submit" class="adminbar-button" value="<?php _e('Search'); ?>"/>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
/* Wipe the menu, might reduce memory usage, but probably not. */
|
||||
$this->menu = null;
|
||||
}
|
||||
|
||||
/* Helpers */
|
||||
function recursive_render( $id, &$menu_item ) { ?>
|
||||
<?php
|
||||
$is_parent = ! empty( $menu_item['children'] );
|
||||
|
||||
$menuclass = $is_parent ? 'menupop' : '';
|
||||
if ( ! empty( $menu_item['meta']['class'] ) )
|
||||
$menuclass .= ' ' . $menu_item['meta']['class'];
|
||||
?>
|
||||
|
||||
<li id="<?php echo esc_attr( "wp-admin-bar-$id" ); ?>" class="<?php echo esc_attr( $menuclass ); ?>">
|
||||
<a href="<?php echo esc_url( $menu_item['href'] ) ?>"<?php
|
||||
if ( ! empty( $menu_item['meta']['onclick'] ) ) :
|
||||
?> onclick="<?php echo esc_js( $menu_item['meta']['onclick'] ); ?>"<?php
|
||||
endif;
|
||||
if ( ! empty( $menu_item['meta']['target'] ) ) :
|
||||
?> target="<?php echo esc_attr( $menu_item['meta']['target'] ); ?>"<?php
|
||||
endif;
|
||||
if ( ! empty( $menu_item['meta']['title'] ) ) :
|
||||
?> title="<?php echo esc_attr( $menu_item['meta']['title'] ); ?>"<?php
|
||||
endif;
|
||||
|
||||
?>><?php
|
||||
|
||||
if ( $is_parent ) :
|
||||
?><span><?php
|
||||
endif;
|
||||
|
||||
echo $menu_item['title'];
|
||||
|
||||
if ( $is_parent ) :
|
||||
?></span><?php
|
||||
endif;
|
||||
|
||||
?></a>
|
||||
|
||||
<?php if ( $is_parent ) : ?>
|
||||
<ul>
|
||||
<?php foreach ( $menu_item['children'] as $child_id => $child_menu_item ) : ?>
|
||||
<?php $this->recursive_render( $child_id, $child_menu_item ); ?>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ( ! empty( $menu_item['meta']['html'] ) ) : ?>
|
||||
<?php echo $menu_item['meta']['html']; ?>
|
||||
<?php endif; ?>
|
||||
</li><?php
|
||||
}
|
||||
|
||||
function add_node( $parent_id, &$menu, $child ) {
|
||||
foreach( $menu as $id => $menu_item ) {
|
||||
if ( $parent_id == $id ) {
|
||||
$menu->{$parent_id}['children']->{$child['id']} = $child;
|
||||
$child = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( ! empty( $menu->{$id}['children'] ) )
|
||||
$this->add_node( $parent_id, $menu->{$id}['children'], $child );
|
||||
}
|
||||
|
||||
$child = null;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function add_menus() {
|
||||
add_action( 'admin_bar_menu', 'wp_admin_bar_my_account_menu', 10 );
|
||||
add_action( 'admin_bar_menu', 'wp_admin_bar_my_sites_menu', 20 );
|
||||
add_action( 'admin_bar_menu', 'wp_admin_bar_edit_menu', 30 );
|
||||
add_action( 'admin_bar_menu', 'wp_admin_bar_shortlink_menu', 80 );
|
||||
add_action( 'admin_bar_menu', 'wp_admin_bar_updates_menu', 70 );
|
||||
|
||||
if ( !is_network_admin() && !is_user_admin() ) {
|
||||
add_action( 'admin_bar_menu', 'wp_admin_bar_new_content_menu', 40 );
|
||||
add_action( 'admin_bar_menu', 'wp_admin_bar_comments_menu', 50 );
|
||||
add_action( 'admin_bar_menu', 'wp_admin_bar_appearance_menu', 60 );
|
||||
}
|
||||
|
||||
do_action( 'add_admin_bar_menus' );
|
||||
}
|
||||
|
||||
function remove_node( $id, &$menu ) {
|
||||
if ( isset( $menu->$id ) ) {
|
||||
unset( $menu->$id );
|
||||
return true;
|
||||
}
|
||||
|
||||
foreach( $menu as $menu_item_id => $menu_item ) {
|
||||
if ( ! empty( $menu->{$menu_item_id}['children'] ) )
|
||||
$this->remove_node( $id, $menu->{$menu_item_id}['children'] );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: Convert to a core feature for multisite or remove
|
||||
function load_user_locale_translations() {
|
||||
$this->need_to_change_locale = ( get_locale() != $this->user->locale );
|
||||
if ( ! $this->need_to_change_locale )
|
||||
return;
|
||||
/*
|
||||
$this->previous_translations = get_translations_for_domain( 'default' );
|
||||
$this->adminbar_locale_filter = lambda( '$_', '$GLOBALS["wp_admin_bar"]->user->locale;' );
|
||||
unload_textdomain( 'default' );
|
||||
add_filter( 'locale', $this->adminbar_locale_filter );
|
||||
load_default_textdomain();
|
||||
$this->changed_locale = true;
|
||||
*/
|
||||
}
|
||||
|
||||
function unload_user_locale_translations() {
|
||||
global $l10n;
|
||||
if ( ! $this->changed_locale )
|
||||
return;
|
||||
/*
|
||||
remove_filter( 'locale', $this->adminbar_locale_filter );
|
||||
$l10n['default'] = &$this->previous_translations;
|
||||
*/
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,138 @@
|
||||
<?php
|
||||
/**
|
||||
* Send XML response back to AJAX request.
|
||||
*
|
||||
* @package WordPress
|
||||
* @since 2.1.0
|
||||
*/
|
||||
class WP_Ajax_Response {
|
||||
/**
|
||||
* Store XML responses to send.
|
||||
*
|
||||
* @since 2.1.0
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $responses = array();
|
||||
|
||||
/**
|
||||
* PHP4 Constructor - Passes args to {@link WP_Ajax_Response::add()}.
|
||||
*
|
||||
* @since 2.1.0
|
||||
* @see WP_Ajax_Response::add()
|
||||
*
|
||||
* @param string|array $args Optional. Will be passed to add() method.
|
||||
* @return WP_Ajax_Response
|
||||
*/
|
||||
function WP_Ajax_Response( $args = '' ) {
|
||||
if ( !empty($args) )
|
||||
$this->add($args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Append to XML response based on given arguments.
|
||||
*
|
||||
* The arguments that can be passed in the $args parameter are below. It is
|
||||
* also possible to pass a WP_Error object in either the 'id' or 'data'
|
||||
* argument. The parameter isn't actually optional, content should be given
|
||||
* in order to send the correct response.
|
||||
*
|
||||
* 'what' argument is a string that is the XMLRPC response type.
|
||||
* 'action' argument is a boolean or string that acts like a nonce.
|
||||
* 'id' argument can be WP_Error or an integer.
|
||||
* 'old_id' argument is false by default or an integer of the previous ID.
|
||||
* 'position' argument is an integer or a string with -1 = top, 1 = bottom,
|
||||
* html ID = after, -html ID = before.
|
||||
* 'data' argument is a string with the content or message.
|
||||
* 'supplemental' argument is an array of strings that will be children of
|
||||
* the supplemental element.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @param string|array $args Override defaults.
|
||||
* @return string XML response.
|
||||
*/
|
||||
function add( $args = '' ) {
|
||||
$defaults = array(
|
||||
'what' => 'object', 'action' => false,
|
||||
'id' => '0', 'old_id' => false,
|
||||
'position' => 1,
|
||||
'data' => '', 'supplemental' => array()
|
||||
);
|
||||
|
||||
$r = wp_parse_args( $args, $defaults );
|
||||
extract( $r, EXTR_SKIP );
|
||||
$position = preg_replace( '/[^a-z0-9:_-]/i', '', $position );
|
||||
|
||||
if ( is_wp_error($id) ) {
|
||||
$data = $id;
|
||||
$id = 0;
|
||||
}
|
||||
|
||||
$response = '';
|
||||
if ( is_wp_error($data) ) {
|
||||
foreach ( (array) $data->get_error_codes() as $code ) {
|
||||
$response .= "<wp_error code='$code'><![CDATA[" . $data->get_error_message($code) . "]]></wp_error>";
|
||||
if ( !$error_data = $data->get_error_data($code) )
|
||||
continue;
|
||||
$class = '';
|
||||
if ( is_object($error_data) ) {
|
||||
$class = ' class="' . get_class($error_data) . '"';
|
||||
$error_data = get_object_vars($error_data);
|
||||
}
|
||||
|
||||
$response .= "<wp_error_data code='$code'$class>";
|
||||
|
||||
if ( is_scalar($error_data) ) {
|
||||
$response .= "<![CDATA[$error_data]]>";
|
||||
} elseif ( is_array($error_data) ) {
|
||||
foreach ( $error_data as $k => $v )
|
||||
$response .= "<$k><![CDATA[$v]]></$k>";
|
||||
}
|
||||
|
||||
$response .= "</wp_error_data>";
|
||||
}
|
||||
} else {
|
||||
$response = "<response_data><![CDATA[$data]]></response_data>";
|
||||
}
|
||||
|
||||
$s = '';
|
||||
if ( is_array($supplemental) ) {
|
||||
foreach ( $supplemental as $k => $v )
|
||||
$s .= "<$k><![CDATA[$v]]></$k>";
|
||||
$s = "<supplemental>$s</supplemental>";
|
||||
}
|
||||
|
||||
if ( false === $action )
|
||||
$action = $_POST['action'];
|
||||
|
||||
$x = '';
|
||||
$x .= "<response action='{$action}_$id'>"; // The action attribute in the xml output is formatted like a nonce action
|
||||
$x .= "<$what id='$id' " . ( false === $old_id ? '' : "old_id='$old_id' " ) . "position='$position'>";
|
||||
$x .= $response;
|
||||
$x .= $s;
|
||||
$x .= "</$what>";
|
||||
$x .= "</response>";
|
||||
|
||||
$this->responses[] = $x;
|
||||
return $x;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display XML formatted responses.
|
||||
*
|
||||
* Sets the content type header to text/xml.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*/
|
||||
function send() {
|
||||
header('Content-Type: text/xml');
|
||||
echo "<?xml version='1.0' standalone='yes'?><wp_ajax>";
|
||||
foreach ( (array) $this->responses as $response )
|
||||
echo $response;
|
||||
echo '</wp_ajax>';
|
||||
die();
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,212 @@
|
||||
<?php
|
||||
/**
|
||||
* WordPress Error API.
|
||||
*
|
||||
* Contains the WP_Error class and the is_wp_error() function.
|
||||
*
|
||||
* @package WordPress
|
||||
*/
|
||||
|
||||
/**
|
||||
* WordPress Error class.
|
||||
*
|
||||
* Container for checking for WordPress errors and error messages. Return
|
||||
* WP_Error and use {@link is_wp_error()} to check if this class is returned.
|
||||
* Many core WordPress functions pass this class in the event of an error and
|
||||
* if not handled properly will result in code errors.
|
||||
*
|
||||
* @package WordPress
|
||||
* @since 2.1.0
|
||||
*/
|
||||
class WP_Error {
|
||||
/**
|
||||
* Stores the list of errors.
|
||||
*
|
||||
* @since 2.1.0
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $errors = array();
|
||||
|
||||
/**
|
||||
* Stores the list of data for error codes.
|
||||
*
|
||||
* @since 2.1.0
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $error_data = array();
|
||||
|
||||
/**
|
||||
* PHP4 Constructor - Sets up error message.
|
||||
*
|
||||
* If code parameter is empty then nothing will be done. It is possible to
|
||||
* add multiple messages to the same code, but with other methods in the
|
||||
* class.
|
||||
*
|
||||
* All parameters are optional, but if the code parameter is set, then the
|
||||
* data parameter is optional.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @param string|int $code Error code
|
||||
* @param string $message Error message
|
||||
* @param mixed $data Optional. Error data.
|
||||
* @return WP_Error
|
||||
*/
|
||||
function WP_Error($code = '', $message = '', $data = '') {
|
||||
if ( empty($code) )
|
||||
return;
|
||||
|
||||
$this->errors[$code][] = $message;
|
||||
|
||||
if ( ! empty($data) )
|
||||
$this->error_data[$code] = $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve all error codes.
|
||||
*
|
||||
* @since 2.1.0
|
||||
* @access public
|
||||
*
|
||||
* @return array List of error codes, if avaiable.
|
||||
*/
|
||||
function get_error_codes() {
|
||||
if ( empty($this->errors) )
|
||||
return array();
|
||||
|
||||
return array_keys($this->errors);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve first error code available.
|
||||
*
|
||||
* @since 2.1.0
|
||||
* @access public
|
||||
*
|
||||
* @return string|int Empty string, if no error codes.
|
||||
*/
|
||||
function get_error_code() {
|
||||
$codes = $this->get_error_codes();
|
||||
|
||||
if ( empty($codes) )
|
||||
return '';
|
||||
|
||||
return $codes[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve all error messages or error messages matching code.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @param string|int $code Optional. Retrieve messages matching code, if exists.
|
||||
* @return array Error strings on success, or empty array on failure (if using codee parameter).
|
||||
*/
|
||||
function get_error_messages($code = '') {
|
||||
// Return all messages if no code specified.
|
||||
if ( empty($code) ) {
|
||||
$all_messages = array();
|
||||
foreach ( (array) $this->errors as $code => $messages )
|
||||
$all_messages = array_merge($all_messages, $messages);
|
||||
|
||||
return $all_messages;
|
||||
}
|
||||
|
||||
if ( isset($this->errors[$code]) )
|
||||
return $this->errors[$code];
|
||||
else
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get single error message.
|
||||
*
|
||||
* This will get the first message available for the code. If no code is
|
||||
* given then the first code available will be used.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @param string|int $code Optional. Error code to retrieve message.
|
||||
* @return string
|
||||
*/
|
||||
function get_error_message($code = '') {
|
||||
if ( empty($code) )
|
||||
$code = $this->get_error_code();
|
||||
$messages = $this->get_error_messages($code);
|
||||
if ( empty($messages) )
|
||||
return '';
|
||||
return $messages[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve error data for error code.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @param string|int $code Optional. Error code.
|
||||
* @return mixed Null, if no errors.
|
||||
*/
|
||||
function get_error_data($code = '') {
|
||||
if ( empty($code) )
|
||||
$code = $this->get_error_code();
|
||||
|
||||
if ( isset($this->error_data[$code]) )
|
||||
return $this->error_data[$code];
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Append more error messages to list of error messages.
|
||||
*
|
||||
* @since 2.1.0
|
||||
* @access public
|
||||
*
|
||||
* @param string|int $code Error code.
|
||||
* @param string $message Error message.
|
||||
* @param mixed $data Optional. Error data.
|
||||
*/
|
||||
function add($code, $message, $data = '') {
|
||||
$this->errors[$code][] = $message;
|
||||
if ( ! empty($data) )
|
||||
$this->error_data[$code] = $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add data for error code.
|
||||
*
|
||||
* The error code can only contain one error data.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @param mixed $data Error data.
|
||||
* @param string|int $code Error code.
|
||||
*/
|
||||
function add_data($data, $code = '') {
|
||||
if ( empty($code) )
|
||||
$code = $this->get_error_code();
|
||||
|
||||
$this->error_data[$code] = $data;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether variable is a WordPress Error.
|
||||
*
|
||||
* Looks at the object and if a WP_Error class. Does not check to see if the
|
||||
* parent is also WP_Error, so can't inherit WP_Error and still use this
|
||||
* function.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @param mixed $thing Check if unknown variable is WordPress Error object.
|
||||
* @return bool True, if WP_Error. False, if not WP_Error.
|
||||
*/
|
||||
function is_wp_error($thing) {
|
||||
if ( is_object($thing) && is_a($thing, 'WP_Error') )
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
/**
|
||||
* WP_HTTP_IXR_Client
|
||||
*
|
||||
* @package WordPress
|
||||
* @since 3.1.0
|
||||
*
|
||||
*/
|
||||
class WP_HTTP_IXR_Client extends IXR_Client {
|
||||
function WP_HTTP_IXR_Client($server, $path = false, $port = 80, $timeout = 15) {
|
||||
if ( ! $path ) {
|
||||
// Assume we have been given a URL instead
|
||||
$bits = parse_url($server);
|
||||
$this->scheme = $bits['scheme'];
|
||||
$this->server = $bits['host'];
|
||||
$this->port = isset($bits['port']) ? $bits['port'] : 80;
|
||||
$this->path = !empty($bits['path']) ? $bits['path'] : '/';
|
||||
|
||||
// Make absolutely sure we have a path
|
||||
if ( ! $this->path )
|
||||
$this->path = '/';
|
||||
} else {
|
||||
$this->scheme = 'http';
|
||||
$this->server = $server;
|
||||
$this->path = $path;
|
||||
$this->port = $port;
|
||||
}
|
||||
$this->useragent = 'The Incutio XML-RPC PHP Library';
|
||||
$this->timeout = $timeout;
|
||||
}
|
||||
|
||||
function query() {
|
||||
$args = func_get_args();
|
||||
$method = array_shift($args);
|
||||
$request = new IXR_Request($method, $args);
|
||||
$xml = $request->getXml();
|
||||
|
||||
$url = $this->scheme . '://' . $this->server . ':' . $this->port . $this->path;
|
||||
$args = array(
|
||||
'headers' => array('Content-Type' => 'text/xml'),
|
||||
'user-agent' => $this->useragent,
|
||||
'body' => $xml,
|
||||
);
|
||||
|
||||
// Merge Custom headers ala #8145
|
||||
foreach ( $this->headers as $header => $value )
|
||||
$args['headers'][$header] = $value;
|
||||
|
||||
if ( $this->timeout !== false )
|
||||
$args['timeout'] = $this->timeout;
|
||||
|
||||
// Now send the request
|
||||
if ( $this->debug )
|
||||
echo '<pre class="ixr_request">' . htmlspecialchars($xml) . "\n</pre>\n\n";
|
||||
|
||||
$response = wp_remote_post($url, $args);
|
||||
|
||||
if ( is_wp_error($response) ) {
|
||||
$errno = $response->get_error_code();
|
||||
$errorstr = $response->get_error_message();
|
||||
$this->error = new IXR_Error(-32300, "transport error: $errno $errorstr");
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( $response['response']['code'] != 200 ) {
|
||||
$this->error = new IXR_Error(-32301, "transport error - HTTP status code was not 200 ({$response['response']['code']})");
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( $this->debug )
|
||||
echo '<pre class="ixr_response">' . htmlspecialchars($response['body']) . "\n</pre>\n\n";
|
||||
|
||||
// Now parse what we've got back
|
||||
$this->message = new IXR_Message( $response['body'] );
|
||||
if ( ! $this->message->parse() ) {
|
||||
// XML error
|
||||
$this->error = new IXR_Error(-32700, 'parse error. not well formed');
|
||||
return false;
|
||||
}
|
||||
|
||||
// Is the message a fault?
|
||||
if ( $this->message->messageType == 'fault' ) {
|
||||
$this->error = new IXR_Error($this->message->faultCode, $this->message->faultString);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Message must be OK
|
||||
return true;
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,399 @@
|
||||
<?php
|
||||
/**
|
||||
* A class for displaying various tree-like structures.
|
||||
*
|
||||
* Extend the Walker class to use it, see examples at the below. Child classes
|
||||
* do not need to implement all of the abstract methods in the class. The child
|
||||
* only needs to implement the methods that are needed. Also, the methods are
|
||||
* not strictly abstract in that the parameter definition needs to be followed.
|
||||
* The child classes can have additional parameters.
|
||||
*
|
||||
* @package WordPress
|
||||
* @since 2.1.0
|
||||
* @abstract
|
||||
*/
|
||||
class Walker {
|
||||
/**
|
||||
* What the class handles.
|
||||
*
|
||||
* @since 2.1.0
|
||||
* @var string
|
||||
* @access public
|
||||
*/
|
||||
var $tree_type;
|
||||
|
||||
/**
|
||||
* DB fields to use.
|
||||
*
|
||||
* @since 2.1.0
|
||||
* @var array
|
||||
* @access protected
|
||||
*/
|
||||
var $db_fields;
|
||||
|
||||
/**
|
||||
* Max number of pages walked by the paged walker
|
||||
*
|
||||
* @since 2.7.0
|
||||
* @var int
|
||||
* @access protected
|
||||
*/
|
||||
var $max_pages = 1;
|
||||
|
||||
/**
|
||||
* Starts the list before the elements are added.
|
||||
*
|
||||
* Additional parameters are used in child classes. The args parameter holds
|
||||
* additional values that may be used with the child class methods. This
|
||||
* method is called at the start of the output list.
|
||||
*
|
||||
* @since 2.1.0
|
||||
* @abstract
|
||||
*
|
||||
* @param string $output Passed by reference. Used to append additional content.
|
||||
*/
|
||||
function start_lvl(&$output) {}
|
||||
|
||||
/**
|
||||
* Ends the list of after the elements are added.
|
||||
*
|
||||
* Additional parameters are used in child classes. The args parameter holds
|
||||
* additional values that may be used with the child class methods. This
|
||||
* method finishes the list at the end of output of the elements.
|
||||
*
|
||||
* @since 2.1.0
|
||||
* @abstract
|
||||
*
|
||||
* @param string $output Passed by reference. Used to append additional content.
|
||||
*/
|
||||
function end_lvl(&$output) {}
|
||||
|
||||
/**
|
||||
* Start the element output.
|
||||
*
|
||||
* Additional parameters are used in child classes. The args parameter holds
|
||||
* additional values that may be used with the child class methods. Includes
|
||||
* the element output also.
|
||||
*
|
||||
* @since 2.1.0
|
||||
* @abstract
|
||||
*
|
||||
* @param string $output Passed by reference. Used to append additional content.
|
||||
*/
|
||||
function start_el(&$output) {}
|
||||
|
||||
/**
|
||||
* Ends the element output, if needed.
|
||||
*
|
||||
* Additional parameters are used in child classes. The args parameter holds
|
||||
* additional values that may be used with the child class methods.
|
||||
*
|
||||
* @since 2.1.0
|
||||
* @abstract
|
||||
*
|
||||
* @param string $output Passed by reference. Used to append additional content.
|
||||
*/
|
||||
function end_el(&$output) {}
|
||||
|
||||
/**
|
||||
* Traverse elements to create list from elements.
|
||||
*
|
||||
* Display one element if the element doesn't have any children otherwise,
|
||||
* display the element and its children. Will only traverse up to the max
|
||||
* depth and no ignore elements under that depth. It is possible to set the
|
||||
* max depth to include all depths, see walk() method.
|
||||
*
|
||||
* This method shouldn't be called directly, use the walk() method instead.
|
||||
*
|
||||
* @since 2.5.0
|
||||
*
|
||||
* @param object $element Data object
|
||||
* @param array $children_elements List of elements to continue traversing.
|
||||
* @param int $max_depth Max depth to traverse.
|
||||
* @param int $depth Depth of current element.
|
||||
* @param array $args
|
||||
* @param string $output Passed by reference. Used to append additional content.
|
||||
* @return null Null on failure with no changes to parameters.
|
||||
*/
|
||||
function display_element( $element, &$children_elements, $max_depth, $depth=0, $args, &$output ) {
|
||||
|
||||
if ( !$element )
|
||||
return;
|
||||
|
||||
$id_field = $this->db_fields['id'];
|
||||
|
||||
//display this element
|
||||
if ( is_array( $args[0] ) )
|
||||
$args[0]['has_children'] = ! empty( $children_elements[$element->$id_field] );
|
||||
$cb_args = array_merge( array(&$output, $element, $depth), $args);
|
||||
call_user_func_array(array(&$this, 'start_el'), $cb_args);
|
||||
|
||||
$id = $element->$id_field;
|
||||
|
||||
// descend only when the depth is right and there are childrens for this element
|
||||
if ( ($max_depth == 0 || $max_depth > $depth+1 ) && isset( $children_elements[$id]) ) {
|
||||
|
||||
foreach( $children_elements[ $id ] as $child ){
|
||||
|
||||
if ( !isset($newlevel) ) {
|
||||
$newlevel = true;
|
||||
//start the child delimiter
|
||||
$cb_args = array_merge( array(&$output, $depth), $args);
|
||||
call_user_func_array(array(&$this, 'start_lvl'), $cb_args);
|
||||
}
|
||||
$this->display_element( $child, $children_elements, $max_depth, $depth + 1, $args, $output );
|
||||
}
|
||||
unset( $children_elements[ $id ] );
|
||||
}
|
||||
|
||||
if ( isset($newlevel) && $newlevel ){
|
||||
//end the child delimiter
|
||||
$cb_args = array_merge( array(&$output, $depth), $args);
|
||||
call_user_func_array(array(&$this, 'end_lvl'), $cb_args);
|
||||
}
|
||||
|
||||
//end this element
|
||||
$cb_args = array_merge( array(&$output, $element, $depth), $args);
|
||||
call_user_func_array(array(&$this, 'end_el'), $cb_args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display array of elements hierarchically.
|
||||
*
|
||||
* It is a generic function which does not assume any existing order of
|
||||
* elements. max_depth = -1 means flatly display every element. max_depth =
|
||||
* 0 means display all levels. max_depth > 0 specifies the number of
|
||||
* display levels.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @param array $elements
|
||||
* @param int $max_depth
|
||||
* @return string
|
||||
*/
|
||||
function walk( $elements, $max_depth) {
|
||||
|
||||
$args = array_slice(func_get_args(), 2);
|
||||
$output = '';
|
||||
|
||||
if ($max_depth < -1) //invalid parameter
|
||||
return $output;
|
||||
|
||||
if (empty($elements)) //nothing to walk
|
||||
return $output;
|
||||
|
||||
$id_field = $this->db_fields['id'];
|
||||
$parent_field = $this->db_fields['parent'];
|
||||
|
||||
// flat display
|
||||
if ( -1 == $max_depth ) {
|
||||
$empty_array = array();
|
||||
foreach ( $elements as $e )
|
||||
$this->display_element( $e, $empty_array, 1, 0, $args, $output );
|
||||
return $output;
|
||||
}
|
||||
|
||||
/*
|
||||
* need to display in hierarchical order
|
||||
* separate elements into two buckets: top level and children elements
|
||||
* children_elements is two dimensional array, eg.
|
||||
* children_elements[10][] contains all sub-elements whose parent is 10.
|
||||
*/
|
||||
$top_level_elements = array();
|
||||
$children_elements = array();
|
||||
foreach ( $elements as $e) {
|
||||
if ( 0 == $e->$parent_field )
|
||||
$top_level_elements[] = $e;
|
||||
else
|
||||
$children_elements[ $e->$parent_field ][] = $e;
|
||||
}
|
||||
|
||||
/*
|
||||
* when none of the elements is top level
|
||||
* assume the first one must be root of the sub elements
|
||||
*/
|
||||
if ( empty($top_level_elements) ) {
|
||||
|
||||
$first = array_slice( $elements, 0, 1 );
|
||||
$root = $first[0];
|
||||
|
||||
$top_level_elements = array();
|
||||
$children_elements = array();
|
||||
foreach ( $elements as $e) {
|
||||
if ( $root->$parent_field == $e->$parent_field )
|
||||
$top_level_elements[] = $e;
|
||||
else
|
||||
$children_elements[ $e->$parent_field ][] = $e;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ( $top_level_elements as $e )
|
||||
$this->display_element( $e, $children_elements, $max_depth, 0, $args, $output );
|
||||
|
||||
/*
|
||||
* if we are displaying all levels, and remaining children_elements is not empty,
|
||||
* then we got orphans, which should be displayed regardless
|
||||
*/
|
||||
if ( ( $max_depth == 0 ) && count( $children_elements ) > 0 ) {
|
||||
$empty_array = array();
|
||||
foreach ( $children_elements as $orphans )
|
||||
foreach( $orphans as $op )
|
||||
$this->display_element( $op, $empty_array, 1, 0, $args, $output );
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* paged_walk() - produce a page of nested elements
|
||||
*
|
||||
* Given an array of hierarchical elements, the maximum depth, a specific page number,
|
||||
* and number of elements per page, this function first determines all top level root elements
|
||||
* belonging to that page, then lists them and all of their children in hierarchical order.
|
||||
*
|
||||
* @package WordPress
|
||||
* @since 2.7
|
||||
* @param int $max_depth = 0 means display all levels; $max_depth > 0 specifies the number of display levels.
|
||||
* @param int $page_num the specific page number, beginning with 1.
|
||||
* @return XHTML of the specified page of elements
|
||||
*/
|
||||
function paged_walk( $elements, $max_depth, $page_num, $per_page ) {
|
||||
|
||||
/* sanity check */
|
||||
if ( empty($elements) || $max_depth < -1 )
|
||||
return '';
|
||||
|
||||
$args = array_slice( func_get_args(), 4 );
|
||||
$output = '';
|
||||
|
||||
$id_field = $this->db_fields['id'];
|
||||
$parent_field = $this->db_fields['parent'];
|
||||
|
||||
$count = -1;
|
||||
if ( -1 == $max_depth )
|
||||
$total_top = count( $elements );
|
||||
if ( $page_num < 1 || $per_page < 0 ) {
|
||||
// No paging
|
||||
$paging = false;
|
||||
$start = 0;
|
||||
if ( -1 == $max_depth )
|
||||
$end = $total_top;
|
||||
$this->max_pages = 1;
|
||||
} else {
|
||||
$paging = true;
|
||||
$start = ( (int)$page_num - 1 ) * (int)$per_page;
|
||||
$end = $start + $per_page;
|
||||
if ( -1 == $max_depth )
|
||||
$this->max_pages = ceil($total_top / $per_page);
|
||||
}
|
||||
|
||||
// flat display
|
||||
if ( -1 == $max_depth ) {
|
||||
if ( !empty($args[0]['reverse_top_level']) ) {
|
||||
$elements = array_reverse( $elements );
|
||||
$oldstart = $start;
|
||||
$start = $total_top - $end;
|
||||
$end = $total_top - $oldstart;
|
||||
}
|
||||
|
||||
$empty_array = array();
|
||||
foreach ( $elements as $e ) {
|
||||
$count++;
|
||||
if ( $count < $start )
|
||||
continue;
|
||||
if ( $count >= $end )
|
||||
break;
|
||||
$this->display_element( $e, $empty_array, 1, 0, $args, $output );
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
/*
|
||||
* separate elements into two buckets: top level and children elements
|
||||
* children_elements is two dimensional array, eg.
|
||||
* children_elements[10][] contains all sub-elements whose parent is 10.
|
||||
*/
|
||||
$top_level_elements = array();
|
||||
$children_elements = array();
|
||||
foreach ( $elements as $e) {
|
||||
if ( 0 == $e->$parent_field )
|
||||
$top_level_elements[] = $e;
|
||||
else
|
||||
$children_elements[ $e->$parent_field ][] = $e;
|
||||
}
|
||||
|
||||
$total_top = count( $top_level_elements );
|
||||
if ( $paging )
|
||||
$this->max_pages = ceil($total_top / $per_page);
|
||||
else
|
||||
$end = $total_top;
|
||||
|
||||
if ( !empty($args[0]['reverse_top_level']) ) {
|
||||
$top_level_elements = array_reverse( $top_level_elements );
|
||||
$oldstart = $start;
|
||||
$start = $total_top - $end;
|
||||
$end = $total_top - $oldstart;
|
||||
}
|
||||
if ( !empty($args[0]['reverse_children']) ) {
|
||||
foreach ( $children_elements as $parent => $children )
|
||||
$children_elements[$parent] = array_reverse( $children );
|
||||
}
|
||||
|
||||
foreach ( $top_level_elements as $e ) {
|
||||
$count++;
|
||||
|
||||
//for the last page, need to unset earlier children in order to keep track of orphans
|
||||
if ( $end >= $total_top && $count < $start )
|
||||
$this->unset_children( $e, $children_elements );
|
||||
|
||||
if ( $count < $start )
|
||||
continue;
|
||||
|
||||
if ( $count >= $end )
|
||||
break;
|
||||
|
||||
$this->display_element( $e, $children_elements, $max_depth, 0, $args, $output );
|
||||
}
|
||||
|
||||
if ( $end >= $total_top && count( $children_elements ) > 0 ) {
|
||||
$empty_array = array();
|
||||
foreach ( $children_elements as $orphans )
|
||||
foreach( $orphans as $op )
|
||||
$this->display_element( $op, $empty_array, 1, 0, $args, $output );
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
function get_number_of_root_elements( $elements ){
|
||||
|
||||
$num = 0;
|
||||
$parent_field = $this->db_fields['parent'];
|
||||
|
||||
foreach ( $elements as $e) {
|
||||
if ( 0 == $e->$parent_field )
|
||||
$num++;
|
||||
}
|
||||
return $num;
|
||||
}
|
||||
|
||||
// unset all the children for a given top level element
|
||||
function unset_children( $e, &$children_elements ){
|
||||
|
||||
if ( !$e || !$children_elements )
|
||||
return;
|
||||
|
||||
$id_field = $this->db_fields['id'];
|
||||
$id = $e->$id_field;
|
||||
|
||||
if ( !empty($children_elements[$id]) && is_array($children_elements[$id]) )
|
||||
foreach ( (array) $children_elements[$id] as $child )
|
||||
$this->unset_children( $child, $children_elements );
|
||||
|
||||
if ( isset($children_elements[$id]) )
|
||||
unset( $children_elements[$id] );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,611 @@
|
||||
<?php
|
||||
/**
|
||||
* WordPress environment setup class.
|
||||
*
|
||||
* @package WordPress
|
||||
* @since 2.0.0
|
||||
*/
|
||||
class WP {
|
||||
/**
|
||||
* Public query variables.
|
||||
*
|
||||
* Long list of public query variables.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
* @var array
|
||||
*/
|
||||
var $public_query_vars = array('m', 'p', 'posts', 'w', 'cat', 'withcomments', 'withoutcomments', 's', 'search', 'exact', 'sentence', 'debug', 'calendar', 'page', 'paged', 'more', 'tb', 'pb', 'author', 'order', 'orderby', 'year', 'monthnum', 'day', 'hour', 'minute', 'second', 'name', 'category_name', 'tag', 'feed', 'author_name', 'static', 'pagename', 'page_id', 'error', 'comments_popup', 'attachment', 'attachment_id', 'subpost', 'subpost_id', 'preview', 'robots', 'taxonomy', 'term', 'cpage', 'post_type');
|
||||
|
||||
/**
|
||||
* Private query variables.
|
||||
*
|
||||
* Long list of private query variables.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @var array
|
||||
*/
|
||||
var $private_query_vars = array('offset', 'posts_per_page', 'posts_per_archive_page', 'showposts', 'nopaging', 'post_type', 'post_status', 'category__in', 'category__not_in', 'category__and', 'tag__in', 'tag__not_in', 'tag__and', 'tag_slug__in', 'tag_slug__and', 'tag_id', 'post_mime_type', 'perm', 'comments_per_page', 'post__in', 'post__not_in');
|
||||
|
||||
/**
|
||||
* Extra query variables set by the user.
|
||||
*
|
||||
* @since 2.1.0
|
||||
* @var array
|
||||
*/
|
||||
var $extra_query_vars = array();
|
||||
|
||||
/**
|
||||
* Query variables for setting up the WordPress Query Loop.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @var array
|
||||
*/
|
||||
var $query_vars;
|
||||
|
||||
/**
|
||||
* String parsed to set the query variables.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @var string
|
||||
*/
|
||||
var $query_string;
|
||||
|
||||
/**
|
||||
* Permalink or requested URI.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @var string
|
||||
*/
|
||||
var $request;
|
||||
|
||||
/**
|
||||
* Rewrite rule the request matched.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @var string
|
||||
*/
|
||||
var $matched_rule;
|
||||
|
||||
/**
|
||||
* Rewrite query the request matched.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @var string
|
||||
*/
|
||||
var $matched_query;
|
||||
|
||||
/**
|
||||
* Whether already did the permalink.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @var bool
|
||||
*/
|
||||
var $did_permalink = false;
|
||||
|
||||
/**
|
||||
* Add name to list of public query variables.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @param string $qv Query variable name.
|
||||
*/
|
||||
function add_query_var($qv) {
|
||||
if ( !in_array($qv, $this->public_query_vars) )
|
||||
$this->public_query_vars[] = $qv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of a query variable.
|
||||
*
|
||||
* @since 2.3.0
|
||||
*
|
||||
* @param string $key Query variable name.
|
||||
* @param mixed $value Query variable value.
|
||||
*/
|
||||
function set_query_var($key, $value) {
|
||||
$this->query_vars[$key] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse request to find correct WordPress query.
|
||||
*
|
||||
* Sets up the query variables based on the request. There are also many
|
||||
* filters and actions that can be used to further manipulate the result.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param array|string $extra_query_vars Set the extra query variables.
|
||||
*/
|
||||
function parse_request($extra_query_vars = '') {
|
||||
global $wp_rewrite;
|
||||
|
||||
$this->query_vars = array();
|
||||
$post_type_query_vars = array();
|
||||
|
||||
if ( is_array($extra_query_vars) )
|
||||
$this->extra_query_vars = & $extra_query_vars;
|
||||
else if (! empty($extra_query_vars))
|
||||
parse_str($extra_query_vars, $this->extra_query_vars);
|
||||
|
||||
// Process PATH_INFO, REQUEST_URI, and 404 for permalinks.
|
||||
|
||||
// Fetch the rewrite rules.
|
||||
$rewrite = $wp_rewrite->wp_rewrite_rules();
|
||||
|
||||
if ( ! empty($rewrite) ) {
|
||||
// If we match a rewrite rule, this will be cleared.
|
||||
$error = '404';
|
||||
$this->did_permalink = true;
|
||||
|
||||
if ( isset($_SERVER['PATH_INFO']) )
|
||||
$pathinfo = $_SERVER['PATH_INFO'];
|
||||
else
|
||||
$pathinfo = '';
|
||||
$pathinfo_array = explode('?', $pathinfo);
|
||||
$pathinfo = str_replace("%", "%25", $pathinfo_array[0]);
|
||||
$req_uri = $_SERVER['REQUEST_URI'];
|
||||
$req_uri_array = explode('?', $req_uri);
|
||||
$req_uri = $req_uri_array[0];
|
||||
$self = $_SERVER['PHP_SELF'];
|
||||
$home_path = parse_url(home_url());
|
||||
if ( isset($home_path['path']) )
|
||||
$home_path = $home_path['path'];
|
||||
else
|
||||
$home_path = '';
|
||||
$home_path = trim($home_path, '/');
|
||||
|
||||
// Trim path info from the end and the leading home path from the
|
||||
// front. For path info requests, this leaves us with the requesting
|
||||
// filename, if any. For 404 requests, this leaves us with the
|
||||
// requested permalink.
|
||||
$req_uri = str_replace($pathinfo, '', $req_uri);
|
||||
$req_uri = trim($req_uri, '/');
|
||||
$req_uri = preg_replace("|^$home_path|", '', $req_uri);
|
||||
$req_uri = trim($req_uri, '/');
|
||||
$pathinfo = trim($pathinfo, '/');
|
||||
$pathinfo = preg_replace("|^$home_path|", '', $pathinfo);
|
||||
$pathinfo = trim($pathinfo, '/');
|
||||
$self = trim($self, '/');
|
||||
$self = preg_replace("|^$home_path|", '', $self);
|
||||
$self = trim($self, '/');
|
||||
|
||||
// The requested permalink is in $pathinfo for path info requests and
|
||||
// $req_uri for other requests.
|
||||
if ( ! empty($pathinfo) && !preg_match('|^.*' . $wp_rewrite->index . '$|', $pathinfo) ) {
|
||||
$request = $pathinfo;
|
||||
} else {
|
||||
// If the request uri is the index, blank it out so that we don't try to match it against a rule.
|
||||
if ( $req_uri == $wp_rewrite->index )
|
||||
$req_uri = '';
|
||||
$request = $req_uri;
|
||||
}
|
||||
|
||||
$this->request = $request;
|
||||
|
||||
// Look for matches.
|
||||
$request_match = $request;
|
||||
foreach ( (array) $rewrite as $match => $query) {
|
||||
// Don't try to match against AtomPub calls
|
||||
if ( $req_uri == 'wp-app.php' )
|
||||
break;
|
||||
|
||||
// If the requesting file is the anchor of the match, prepend it
|
||||
// to the path info.
|
||||
if ( (! empty($req_uri)) && (strpos($match, $req_uri) === 0) && ($req_uri != $request) )
|
||||
$request_match = $req_uri . '/' . $request;
|
||||
|
||||
if ( preg_match("#^$match#", $request_match, $matches) ||
|
||||
preg_match("#^$match#", urldecode($request_match), $matches) ) {
|
||||
// Got a match.
|
||||
$this->matched_rule = $match;
|
||||
|
||||
// Trim the query of everything up to the '?'.
|
||||
$query = preg_replace("!^.+\?!", '', $query);
|
||||
|
||||
// Substitute the substring matches into the query.
|
||||
$query = addslashes(WP_MatchesMapRegex::apply($query, $matches));
|
||||
|
||||
$this->matched_query = $query;
|
||||
|
||||
// Parse the query.
|
||||
parse_str($query, $perma_query_vars);
|
||||
|
||||
// If we're processing a 404 request, clear the error var
|
||||
// since we found something.
|
||||
if ( isset($_GET['error']) )
|
||||
unset($_GET['error']);
|
||||
|
||||
if ( isset($error) )
|
||||
unset($error);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If req_uri is empty or if it is a request for ourself, unset error.
|
||||
if ( empty($request) || $req_uri == $self || strpos($_SERVER['PHP_SELF'], 'wp-admin/') !== false ) {
|
||||
if ( isset($_GET['error']) )
|
||||
unset($_GET['error']);
|
||||
|
||||
if ( isset($error) )
|
||||
unset($error);
|
||||
|
||||
if ( isset($perma_query_vars) && strpos($_SERVER['PHP_SELF'], 'wp-admin/') !== false )
|
||||
unset($perma_query_vars);
|
||||
|
||||
$this->did_permalink = false;
|
||||
}
|
||||
}
|
||||
|
||||
$this->public_query_vars = apply_filters('query_vars', $this->public_query_vars);
|
||||
|
||||
foreach ( $GLOBALS['wp_post_types'] as $post_type => $t )
|
||||
if ( $t->query_var )
|
||||
$post_type_query_vars[$t->query_var] = $post_type;
|
||||
|
||||
foreach ( $this->public_query_vars as $wpvar ) {
|
||||
if ( isset( $this->extra_query_vars[$wpvar] ) )
|
||||
$this->query_vars[$wpvar] = $this->extra_query_vars[$wpvar];
|
||||
elseif ( isset( $_POST[$wpvar] ) )
|
||||
$this->query_vars[$wpvar] = $_POST[$wpvar];
|
||||
elseif ( isset( $_GET[$wpvar] ) )
|
||||
$this->query_vars[$wpvar] = $_GET[$wpvar];
|
||||
elseif ( isset( $perma_query_vars[$wpvar] ) )
|
||||
$this->query_vars[$wpvar] = $perma_query_vars[$wpvar];
|
||||
|
||||
if ( !empty( $this->query_vars[$wpvar] ) ) {
|
||||
if ( ! is_array( $this->query_vars[$wpvar] ) ) {
|
||||
$this->query_vars[$wpvar] = (string) $this->query_vars[$wpvar];
|
||||
} else {
|
||||
foreach ( $this->query_vars[$wpvar] as $vkey => $v ) {
|
||||
if ( !is_object( $v ) ) {
|
||||
$this->query_vars[$wpvar][$vkey] = (string) $v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset($post_type_query_vars[$wpvar] ) ) {
|
||||
$this->query_vars['post_type'] = $post_type_query_vars[$wpvar];
|
||||
$this->query_vars['name'] = $this->query_vars[$wpvar];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Convert urldecoded spaces back into +
|
||||
foreach ( $GLOBALS['wp_taxonomies'] as $taxonomy => $t )
|
||||
if ( $t->query_var && isset( $this->query_vars[$t->query_var] ) )
|
||||
$this->query_vars[$t->query_var] = str_replace( ' ', '+', $this->query_vars[$t->query_var] );
|
||||
|
||||
// Limit publicly queried post_types to those that are publicly_queryable
|
||||
if ( isset( $this->query_vars['post_type']) ) {
|
||||
$queryable_post_types = get_post_types( array('publicly_queryable' => true) );
|
||||
if ( ! is_array( $this->query_vars['post_type'] ) ) {
|
||||
if ( ! in_array( $this->query_vars['post_type'], $queryable_post_types ) )
|
||||
unset( $this->query_vars['post_type'] );
|
||||
} else {
|
||||
$this->query_vars['post_type'] = array_intersect( $this->query_vars['post_type'], $queryable_post_types );
|
||||
}
|
||||
}
|
||||
|
||||
foreach ( (array) $this->private_query_vars as $var) {
|
||||
if ( isset($this->extra_query_vars[$var]) )
|
||||
$this->query_vars[$var] = $this->extra_query_vars[$var];
|
||||
}
|
||||
|
||||
if ( isset($error) )
|
||||
$this->query_vars['error'] = $error;
|
||||
|
||||
$this->query_vars = apply_filters('request', $this->query_vars);
|
||||
|
||||
do_action_ref_array('parse_request', array(&$this));
|
||||
}
|
||||
|
||||
/**
|
||||
* Send additional HTTP headers for caching, content type, etc.
|
||||
*
|
||||
* Sets the X-Pingback header, 404 status (if 404), Content-type. If showing
|
||||
* a feed, it will also send last-modified, etag, and 304 status if needed.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
function send_headers() {
|
||||
$headers = array('X-Pingback' => get_bloginfo('pingback_url'));
|
||||
$status = null;
|
||||
$exit_required = false;
|
||||
|
||||
if ( is_user_logged_in() )
|
||||
$headers = array_merge($headers, wp_get_nocache_headers());
|
||||
if ( !empty($this->query_vars['error']) && '404' == $this->query_vars['error'] ) {
|
||||
$status = 404;
|
||||
if ( !is_user_logged_in() )
|
||||
$headers = array_merge($headers, wp_get_nocache_headers());
|
||||
$headers['Content-Type'] = get_option('html_type') . '; charset=' . get_option('blog_charset');
|
||||
} else if ( empty($this->query_vars['feed']) ) {
|
||||
$headers['Content-Type'] = get_option('html_type') . '; charset=' . get_option('blog_charset');
|
||||
} else {
|
||||
// We're showing a feed, so WP is indeed the only thing that last changed
|
||||
if ( !empty($this->query_vars['withcomments'])
|
||||
|| ( empty($this->query_vars['withoutcomments'])
|
||||
&& ( !empty($this->query_vars['p'])
|
||||
|| !empty($this->query_vars['name'])
|
||||
|| !empty($this->query_vars['page_id'])
|
||||
|| !empty($this->query_vars['pagename'])
|
||||
|| !empty($this->query_vars['attachment'])
|
||||
|| !empty($this->query_vars['attachment_id'])
|
||||
)
|
||||
)
|
||||
)
|
||||
$wp_last_modified = mysql2date('D, d M Y H:i:s', get_lastcommentmodified('GMT'), 0).' GMT';
|
||||
else
|
||||
$wp_last_modified = mysql2date('D, d M Y H:i:s', get_lastpostmodified('GMT'), 0).' GMT';
|
||||
$wp_etag = '"' . md5($wp_last_modified) . '"';
|
||||
$headers['Last-Modified'] = $wp_last_modified;
|
||||
$headers['ETag'] = $wp_etag;
|
||||
|
||||
// Support for Conditional GET
|
||||
if (isset($_SERVER['HTTP_IF_NONE_MATCH']))
|
||||
$client_etag = stripslashes(stripslashes($_SERVER['HTTP_IF_NONE_MATCH']));
|
||||
else $client_etag = false;
|
||||
|
||||
$client_last_modified = empty($_SERVER['HTTP_IF_MODIFIED_SINCE']) ? '' : trim($_SERVER['HTTP_IF_MODIFIED_SINCE']);
|
||||
// If string is empty, return 0. If not, attempt to parse into a timestamp
|
||||
$client_modified_timestamp = $client_last_modified ? strtotime($client_last_modified) : 0;
|
||||
|
||||
// Make a timestamp for our most recent modification...
|
||||
$wp_modified_timestamp = strtotime($wp_last_modified);
|
||||
|
||||
if ( ($client_last_modified && $client_etag) ?
|
||||
(($client_modified_timestamp >= $wp_modified_timestamp) && ($client_etag == $wp_etag)) :
|
||||
(($client_modified_timestamp >= $wp_modified_timestamp) || ($client_etag == $wp_etag)) ) {
|
||||
$status = 304;
|
||||
$exit_required = true;
|
||||
}
|
||||
}
|
||||
|
||||
$headers = apply_filters('wp_headers', $headers, $this);
|
||||
|
||||
if ( ! empty( $status ) )
|
||||
status_header( $status );
|
||||
foreach( (array) $headers as $name => $field_value )
|
||||
@header("{$name}: {$field_value}");
|
||||
|
||||
if ( $exit_required )
|
||||
exit();
|
||||
|
||||
do_action_ref_array('send_headers', array(&$this));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the query string property based off of the query variable property.
|
||||
*
|
||||
* The 'query_string' filter is deprecated, but still works. Plugins should
|
||||
* use the 'request' filter instead.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
function build_query_string() {
|
||||
$this->query_string = '';
|
||||
foreach ( (array) array_keys($this->query_vars) as $wpvar) {
|
||||
if ( '' != $this->query_vars[$wpvar] ) {
|
||||
$this->query_string .= (strlen($this->query_string) < 1) ? '' : '&';
|
||||
if ( !is_scalar($this->query_vars[$wpvar]) ) // Discard non-scalars.
|
||||
continue;
|
||||
$this->query_string .= $wpvar . '=' . rawurlencode($this->query_vars[$wpvar]);
|
||||
}
|
||||
}
|
||||
|
||||
// query_string filter deprecated. Use request filter instead.
|
||||
if ( has_filter('query_string') ) { // Don't bother filtering and parsing if no plugins are hooked in.
|
||||
$this->query_string = apply_filters('query_string', $this->query_string);
|
||||
parse_str($this->query_string, $this->query_vars);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up the WordPress Globals.
|
||||
*
|
||||
* The query_vars property will be extracted to the GLOBALS. So care should
|
||||
* be taken when naming global variables that might interfere with the
|
||||
* WordPress environment.
|
||||
*
|
||||
* @global string $query_string Query string for the loop.
|
||||
* @global int $more Only set, if single page or post.
|
||||
* @global int $single If single page or post. Only set, if single page or post.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
function register_globals() {
|
||||
global $wp_query;
|
||||
// Extract updated query vars back into global namespace.
|
||||
foreach ( (array) $wp_query->query_vars as $key => $value) {
|
||||
$GLOBALS[$key] = $value;
|
||||
}
|
||||
|
||||
$GLOBALS['query_string'] = $this->query_string;
|
||||
$GLOBALS['posts'] = & $wp_query->posts;
|
||||
$GLOBALS['post'] = (isset($wp_query->post)) ? $wp_query->post : null;
|
||||
$GLOBALS['request'] = $wp_query->request;
|
||||
|
||||
if ( is_single() || is_page() ) {
|
||||
$GLOBALS['more'] = 1;
|
||||
$GLOBALS['single'] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up the current user.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
function init() {
|
||||
wp_get_current_user();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up the Loop based on the query variables.
|
||||
*
|
||||
* @uses WP::$query_vars
|
||||
* @since 2.0.0
|
||||
*/
|
||||
function query_posts() {
|
||||
global $wp_the_query;
|
||||
$this->build_query_string();
|
||||
$wp_the_query->query($this->query_vars);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Headers for 404, if nothing is found for requested URL.
|
||||
*
|
||||
* Issue a 404 if a request doesn't match any posts and doesn't match
|
||||
* any object (e.g. an existing-but-empty category, tag, author) and a 404 was not already
|
||||
* issued, and if the request was not a search or the homepage.
|
||||
*
|
||||
* Otherwise, issue a 200.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
function handle_404() {
|
||||
global $wp_query;
|
||||
|
||||
if ( !is_admin() && ( 0 == count( $wp_query->posts ) ) && !is_404() && !is_robots() && !is_search() && !is_home() ) {
|
||||
// Don't 404 for these queries if they matched an object.
|
||||
if ( ( is_tag() || is_category() || is_tax() || is_author() ) && $wp_query->get_queried_object() && !is_paged() ) {
|
||||
if ( !is_404() )
|
||||
status_header( 200 );
|
||||
return;
|
||||
}
|
||||
$wp_query->set_404();
|
||||
status_header( 404 );
|
||||
nocache_headers();
|
||||
} elseif ( !is_404() ) {
|
||||
status_header( 200 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up all of the variables required by the WordPress environment.
|
||||
*
|
||||
* The action 'wp' has one parameter that references the WP object. It
|
||||
* allows for accessing the properties and methods to further manipulate the
|
||||
* object.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param string|array $query_args Passed to {@link parse_request()}
|
||||
*/
|
||||
function main($query_args = '') {
|
||||
$this->init();
|
||||
$this->parse_request($query_args);
|
||||
$this->send_headers();
|
||||
$this->query_posts();
|
||||
$this->handle_404();
|
||||
$this->register_globals();
|
||||
do_action_ref_array('wp', array(&$this));
|
||||
}
|
||||
|
||||
/**
|
||||
* PHP4 Constructor - Does nothing.
|
||||
*
|
||||
* Call main() method when ready to run setup.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @return WP
|
||||
*/
|
||||
function WP() {
|
||||
// Empty.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper class to remove the need to use eval to replace $matches[] in query strings.
|
||||
*
|
||||
* @since 2.9.0
|
||||
*/
|
||||
class WP_MatchesMapRegex {
|
||||
/**
|
||||
* store for matches
|
||||
*
|
||||
* @access private
|
||||
* @var array
|
||||
*/
|
||||
var $_matches;
|
||||
|
||||
/**
|
||||
* store for mapping result
|
||||
*
|
||||
* @access public
|
||||
* @var string
|
||||
*/
|
||||
var $output;
|
||||
|
||||
/**
|
||||
* subject to perform mapping on (query string containing $matches[] references
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
var $_subject;
|
||||
|
||||
/**
|
||||
* regexp pattern to match $matches[] references
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
var $_pattern = '(\$matches\[[1-9]+[0-9]*\])'; // magic number
|
||||
|
||||
/**
|
||||
* constructor
|
||||
*
|
||||
* @param string $subject subject if regex
|
||||
* @param array $matches data to use in map
|
||||
* @return self
|
||||
*/
|
||||
function WP_MatchesMapRegex($subject, $matches) {
|
||||
$this->_subject = $subject;
|
||||
$this->_matches = $matches;
|
||||
$this->output = $this->_map();
|
||||
}
|
||||
|
||||
/**
|
||||
* Substitute substring matches in subject.
|
||||
*
|
||||
* static helper function to ease use
|
||||
*
|
||||
* @access public
|
||||
* @param string $subject subject
|
||||
* @param array $matches data used for subsitution
|
||||
* @return string
|
||||
*/
|
||||
function apply($subject, $matches) {
|
||||
$oSelf =& new WP_MatchesMapRegex($subject, $matches);
|
||||
return $oSelf->output;
|
||||
}
|
||||
|
||||
/**
|
||||
* do the actual mapping
|
||||
*
|
||||
* @access private
|
||||
* @return string
|
||||
*/
|
||||
function _map() {
|
||||
$callback = array(&$this, 'callback');
|
||||
return preg_replace_callback($this->_pattern, $callback, $this->_subject);
|
||||
}
|
||||
|
||||
/**
|
||||
* preg_replace_callback hook
|
||||
*
|
||||
* @access public
|
||||
* @param array $matches preg_replace regexp matches
|
||||
* @return string
|
||||
*/
|
||||
function callback($matches) {
|
||||
$index = intval(substr($matches[0], 9, -1));
|
||||
return ( isset( $this->_matches[$index] ) ? urlencode($this->_matches[$index]) : '' );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,243 @@
|
||||
<?php
|
||||
/**
|
||||
* BackPress Scripts enqueue.
|
||||
*
|
||||
* These classes were refactored from the WordPress WP_Scripts and WordPress
|
||||
* script enqueue API.
|
||||
*
|
||||
* @package BackPress
|
||||
* @since r74
|
||||
*/
|
||||
|
||||
/**
|
||||
* BackPress enqueued dependiences class.
|
||||
*
|
||||
* @package BackPress
|
||||
* @uses _WP_Dependency
|
||||
* @since r74
|
||||
*/
|
||||
class WP_Dependencies {
|
||||
var $registered = array();
|
||||
var $queue = array();
|
||||
var $to_do = array();
|
||||
var $done = array();
|
||||
var $args = array();
|
||||
var $groups = array();
|
||||
var $group = 0;
|
||||
|
||||
function WP_Dependencies() {
|
||||
$args = func_get_args();
|
||||
call_user_func_array( array(&$this, '__construct'), $args );
|
||||
}
|
||||
|
||||
function __construct() {}
|
||||
|
||||
/**
|
||||
* Do the dependencies
|
||||
*
|
||||
* Process the items passed to it or the queue. Processes all dependencies.
|
||||
*
|
||||
* @param mixed $handles (optional) items to be processed. (void) processes queue, (string) process that item, (array of strings) process those items
|
||||
* @return array Items that have been processed
|
||||
*/
|
||||
function do_items( $handles = false, $group = false ) {
|
||||
// Print the queue if nothing is passed. If a string is passed, print that script. If an array is passed, print those scripts.
|
||||
$handles = false === $handles ? $this->queue : (array) $handles;
|
||||
$this->all_deps( $handles );
|
||||
|
||||
foreach( $this->to_do as $key => $handle ) {
|
||||
if ( !in_array($handle, $this->done) && isset($this->registered[$handle]) ) {
|
||||
|
||||
if ( ! $this->registered[$handle]->src ) { // Defines a group.
|
||||
$this->done[] = $handle;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( $this->do_item( $handle, $group ) )
|
||||
$this->done[] = $handle;
|
||||
|
||||
unset( $this->to_do[$key] );
|
||||
}
|
||||
}
|
||||
|
||||
return $this->done;
|
||||
}
|
||||
|
||||
function do_item( $handle ) {
|
||||
return isset($this->registered[$handle]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines dependencies
|
||||
*
|
||||
* Recursively builds array of items to process taking dependencies into account. Does NOT catch infinite loops.
|
||||
*
|
||||
*
|
||||
* @param mixed $handles Accepts (string) dep name or (array of strings) dep names
|
||||
* @param bool $recursion Used internally when function calls itself
|
||||
*/
|
||||
function all_deps( $handles, $recursion = false, $group = false ) {
|
||||
if ( !$handles = (array) $handles )
|
||||
return false;
|
||||
|
||||
foreach ( $handles as $handle ) {
|
||||
$handle_parts = explode('?', $handle);
|
||||
$handle = $handle_parts[0];
|
||||
$queued = in_array($handle, $this->to_do, true);
|
||||
|
||||
if ( in_array($handle, $this->done, true) ) // Already done
|
||||
continue;
|
||||
|
||||
$moved = $this->set_group( $handle, $recursion, $group );
|
||||
|
||||
if ( $queued && !$moved ) // already queued and in the right group
|
||||
continue;
|
||||
|
||||
$keep_going = true;
|
||||
if ( !isset($this->registered[$handle]) )
|
||||
$keep_going = false; // Script doesn't exist
|
||||
elseif ( $this->registered[$handle]->deps && array_diff($this->registered[$handle]->deps, array_keys($this->registered)) )
|
||||
$keep_going = false; // Script requires deps which don't exist (not a necessary check. efficiency?)
|
||||
elseif ( $this->registered[$handle]->deps && !$this->all_deps( $this->registered[$handle]->deps, true, $group ) )
|
||||
$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
|
||||
continue; // We're at the top level. Move on to the next one.
|
||||
}
|
||||
|
||||
if ( $queued ) // Already grobbed it and its deps
|
||||
continue;
|
||||
|
||||
if ( isset($handle_parts[1]) )
|
||||
$this->args[$handle] = $handle_parts[1];
|
||||
|
||||
$this->to_do[] = $handle;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds item
|
||||
*
|
||||
* Adds the item only if no item of that name already exists
|
||||
*
|
||||
* @param string $handle Script name
|
||||
* @param string $src Script url
|
||||
* @param array $deps (optional) Array of script names on which this script depends
|
||||
* @param string $ver (optional) Script version (used for cache busting)
|
||||
* @return array Hierarchical array of dependencies
|
||||
*/
|
||||
function add( $handle, $src, $deps = array(), $ver = false, $args = null ) {
|
||||
if ( isset($this->registered[$handle]) )
|
||||
return false;
|
||||
$this->registered[$handle] = new _WP_Dependency( $handle, $src, $deps, $ver, $args );
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds extra data
|
||||
*
|
||||
* Adds data only if script has already been added
|
||||
*
|
||||
* @param string $handle Script name
|
||||
* @param string $data_name Name of object in which to store extra data
|
||||
* @param array $data Array of extra data
|
||||
* @return bool success
|
||||
*/
|
||||
function add_data( $handle, $data_name, $data ) {
|
||||
if ( !isset($this->registered[$handle]) )
|
||||
return false;
|
||||
return $this->registered[$handle]->add_data( $data_name, $data );
|
||||
}
|
||||
|
||||
function remove( $handles ) {
|
||||
foreach ( (array) $handles as $handle )
|
||||
unset($this->registered[$handle]);
|
||||
}
|
||||
|
||||
function enqueue( $handles ) {
|
||||
foreach ( (array) $handles as $handle ) {
|
||||
$handle = explode('?', $handle);
|
||||
if ( !in_array($handle[0], $this->queue) && isset($this->registered[$handle[0]]) ) {
|
||||
$this->queue[] = $handle[0];
|
||||
if ( isset($handle[1]) )
|
||||
$this->args[$handle[0]] = $handle[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function dequeue( $handles ) {
|
||||
foreach ( (array) $handles as $handle ) {
|
||||
$handle = explode('?', $handle);
|
||||
$key = array_search($handle[0], $this->queue);
|
||||
if ( false !== $key ) {
|
||||
unset($this->queue[$key]);
|
||||
unset($this->args[$handle[0]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function query( $handle, $list = 'registered' ) { // registered, queue, done, to_do
|
||||
switch ( $list ) :
|
||||
case 'registered':
|
||||
case 'scripts': // back compat
|
||||
if ( isset($this->registered[$handle]) )
|
||||
return $this->registered[$handle];
|
||||
break;
|
||||
case 'to_print': // back compat
|
||||
case 'printed': // back compat
|
||||
if ( 'to_print' == $list )
|
||||
$list = 'to_do';
|
||||
else
|
||||
$list = 'printed';
|
||||
default:
|
||||
if ( in_array($handle, $this->$list) )
|
||||
return true;
|
||||
break;
|
||||
endswitch;
|
||||
return false;
|
||||
}
|
||||
|
||||
function set_group( $handle, $recursion, $group ) {
|
||||
$group = (int) $group;
|
||||
|
||||
if ( $recursion )
|
||||
$group = min($this->group, $group);
|
||||
else
|
||||
$this->group = $group;
|
||||
|
||||
if ( isset($this->groups[$handle]) && $this->groups[$handle] <= $group )
|
||||
return false;
|
||||
|
||||
$this->groups[$handle] = $group;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class _WP_Dependency {
|
||||
var $handle;
|
||||
var $src;
|
||||
var $deps = array();
|
||||
var $ver = false;
|
||||
var $args = null;
|
||||
|
||||
var $extra = array();
|
||||
|
||||
function _WP_Dependency() {
|
||||
@list($this->handle, $this->src, $this->deps, $this->ver, $this->args) = func_get_args();
|
||||
if ( !is_array($this->deps) )
|
||||
$this->deps = array();
|
||||
}
|
||||
|
||||
function add_data( $name, $data ) {
|
||||
if ( !is_scalar($name) )
|
||||
return false;
|
||||
$this->extra[$name] = $data;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,205 @@
|
||||
<?php
|
||||
/**
|
||||
* BackPress Scripts enqueue.
|
||||
*
|
||||
* These classes were refactored from the WordPress WP_Scripts and WordPress
|
||||
* script enqueue API.
|
||||
*
|
||||
* @package BackPress
|
||||
* @since r16
|
||||
*/
|
||||
|
||||
/**
|
||||
* BackPress Scripts enqueue class.
|
||||
*
|
||||
* @package BackPress
|
||||
* @uses WP_Dependencies
|
||||
* @since r16
|
||||
*/
|
||||
class WP_Scripts extends WP_Dependencies {
|
||||
var $base_url; // Full URL with trailing slash
|
||||
var $content_url;
|
||||
var $default_version;
|
||||
var $in_footer = array();
|
||||
var $concat = '';
|
||||
var $concat_version = '';
|
||||
var $do_concat = false;
|
||||
var $print_html = '';
|
||||
var $print_code = '';
|
||||
var $ext_handles = '';
|
||||
var $ext_version = '';
|
||||
var $default_dirs;
|
||||
|
||||
function __construct() {
|
||||
do_action_ref_array( 'wp_default_scripts', array(&$this) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints scripts
|
||||
*
|
||||
* Prints the scripts passed to it or the print queue. Also prints all necessary dependencies.
|
||||
*
|
||||
* @param mixed $handles (optional) Scripts to be printed. (void) prints queue, (string) prints that script, (array of strings) prints those scripts.
|
||||
* @param int $group (optional) If scripts were queued in groups prints this group number.
|
||||
* @return array Scripts that have been printed
|
||||
*/
|
||||
function print_scripts( $handles = false, $group = false ) {
|
||||
return $this->do_items( $handles, $group );
|
||||
}
|
||||
|
||||
function print_scripts_l10n( $handle, $echo = true ) {
|
||||
if ( empty($this->registered[$handle]->extra['l10n']) || empty($this->registered[$handle]->extra['l10n'][0]) || !is_array($this->registered[$handle]->extra['l10n'][1]) )
|
||||
return false;
|
||||
|
||||
$object_name = $this->registered[$handle]->extra['l10n'][0];
|
||||
|
||||
$data = "var $object_name = {\n";
|
||||
$eol = '';
|
||||
foreach ( $this->registered[$handle]->extra['l10n'][1] as $var => $val ) {
|
||||
if ( 'l10n_print_after' == $var ) {
|
||||
$after = $val;
|
||||
continue;
|
||||
}
|
||||
$data .= "$eol\t$var: \"" . esc_js( $val ) . '"';
|
||||
$eol = ",\n";
|
||||
}
|
||||
$data .= "\n};\n";
|
||||
$data .= isset($after) ? "$after\n" : '';
|
||||
|
||||
if ( $echo ) {
|
||||
echo "<script type='text/javascript'>\n";
|
||||
echo "/* <![CDATA[ */\n";
|
||||
echo $data;
|
||||
echo "/* ]]> */\n";
|
||||
echo "</script>\n";
|
||||
return true;
|
||||
} else {
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
||||
function do_item( $handle, $group = false ) {
|
||||
if ( !parent::do_item($handle) )
|
||||
return false;
|
||||
|
||||
if ( 0 === $group && $this->groups[$handle] > 0 ) {
|
||||
$this->in_footer[] = $handle;
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( false === $group && in_array($handle, $this->in_footer, true) )
|
||||
$this->in_footer = array_diff( $this->in_footer, (array) $handle );
|
||||
|
||||
if ( null === $this->registered[$handle]->ver )
|
||||
$ver = '';
|
||||
else
|
||||
$ver = $this->registered[$handle]->ver ? $this->registered[$handle]->ver : $this->default_version;
|
||||
|
||||
if ( isset($this->args[$handle]) )
|
||||
$ver = $ver ? $ver . '&' . $this->args[$handle] : $this->args[$handle];
|
||||
|
||||
$src = $this->registered[$handle]->src;
|
||||
|
||||
if ( $this->do_concat ) {
|
||||
$srce = apply_filters( 'script_loader_src', $src, $handle );
|
||||
if ( $this->in_default_dir($srce) ) {
|
||||
$this->print_code .= $this->print_scripts_l10n( $handle, false );
|
||||
$this->concat .= "$handle,";
|
||||
$this->concat_version .= "$handle$ver";
|
||||
return true;
|
||||
} else {
|
||||
$this->ext_handles .= "$handle,";
|
||||
$this->ext_version .= "$handle$ver";
|
||||
}
|
||||
}
|
||||
|
||||
$this->print_scripts_l10n( $handle );
|
||||
if ( !preg_match('|^https?://|', $src) && ! ( $this->content_url && 0 === strpos($src, $this->content_url) ) ) {
|
||||
$src = $this->base_url . $src;
|
||||
}
|
||||
|
||||
if ( !empty($ver) )
|
||||
$src = add_query_arg('ver', $ver, $src);
|
||||
$src = esc_url(apply_filters( 'script_loader_src', $src, $handle ));
|
||||
|
||||
if ( $this->do_concat )
|
||||
$this->print_html .= "<script type='text/javascript' src='$src'></script>\n";
|
||||
else
|
||||
echo "<script type='text/javascript' src='$src'></script>\n";
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Localizes a script
|
||||
*
|
||||
* Localizes only if script has already been added
|
||||
*
|
||||
* @param string $handle Script name
|
||||
* @param string $object_name Name of JS object to hold l10n info
|
||||
* @param array $l10n Array of JS var name => localized string
|
||||
* @return bool Successful localization
|
||||
*/
|
||||
function localize( $handle, $object_name, $l10n ) {
|
||||
if ( !$object_name || !$l10n )
|
||||
return false;
|
||||
return $this->add_data( $handle, 'l10n', array( $object_name, $l10n ) );
|
||||
}
|
||||
|
||||
function set_group( $handle, $recursion, $group = false ) {
|
||||
$grp = isset($this->registered[$handle]->extra['group']) ? (int) $this->registered[$handle]->extra['group'] : 0;
|
||||
if ( false !== $group && $grp > $group )
|
||||
$grp = $group;
|
||||
|
||||
return parent::set_group( $handle, $recursion, $grp );
|
||||
}
|
||||
|
||||
function all_deps( $handles, $recursion = false, $group = false ) {
|
||||
$r = parent::all_deps( $handles, $recursion );
|
||||
if ( !$recursion )
|
||||
$this->to_do = apply_filters( 'print_scripts_array', $this->to_do );
|
||||
return $r;
|
||||
}
|
||||
|
||||
function do_head_items() {
|
||||
$this->do_items(false, 0);
|
||||
return $this->done;
|
||||
}
|
||||
|
||||
function do_footer_items() {
|
||||
if ( !empty($this->in_footer) ) {
|
||||
foreach( $this->in_footer as $key => $handle ) {
|
||||
if ( !in_array($handle, $this->done, true) && isset($this->registered[$handle]) ) {
|
||||
$this->do_item($handle);
|
||||
$this->done[] = $handle;
|
||||
unset( $this->in_footer[$key] );
|
||||
}
|
||||
}
|
||||
}
|
||||
return $this->done;
|
||||
}
|
||||
|
||||
function in_default_dir($src) {
|
||||
if ( ! $this->default_dirs )
|
||||
return true;
|
||||
|
||||
if ( 0 === strpos( $src, '/wp-includes/js/l10n' ) )
|
||||
return false;
|
||||
|
||||
foreach ( (array) $this->default_dirs as $test ) {
|
||||
if ( 0 === strpos($src, $test) )
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function reset() {
|
||||
$this->do_concat = false;
|
||||
$this->print_code = '';
|
||||
$this->concat = '';
|
||||
$this->concat_version = '';
|
||||
$this->print_html = '';
|
||||
$this->ext_version = '';
|
||||
$this->ext_handles = '';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
<?php
|
||||
/**
|
||||
* BackPress Styles enqueue.
|
||||
*
|
||||
* These classes were refactored from the WordPress WP_Scripts and WordPress
|
||||
* script enqueue API.
|
||||
*
|
||||
* @package BackPress
|
||||
* @since r74
|
||||
*/
|
||||
|
||||
/**
|
||||
* BackPress Styles enqueue class.
|
||||
*
|
||||
* @package BackPress
|
||||
* @uses WP_Dependencies
|
||||
* @since r74
|
||||
*/
|
||||
class WP_Styles extends WP_Dependencies {
|
||||
var $base_url;
|
||||
var $content_url;
|
||||
var $default_version;
|
||||
var $text_direction = 'ltr';
|
||||
var $concat = '';
|
||||
var $concat_version = '';
|
||||
var $do_concat = false;
|
||||
var $print_html = '';
|
||||
var $default_dirs;
|
||||
|
||||
function __construct() {
|
||||
do_action_ref_array( 'wp_default_styles', array(&$this) );
|
||||
}
|
||||
|
||||
function do_item( $handle ) {
|
||||
if ( !parent::do_item($handle) )
|
||||
return false;
|
||||
|
||||
if ( null === $this->registered[$handle]->ver )
|
||||
$ver = '';
|
||||
else
|
||||
$ver = $this->registered[$handle]->ver ? $this->registered[$handle]->ver : $this->default_version;
|
||||
|
||||
if ( isset($this->args[$handle]) )
|
||||
$ver = $ver ? $ver . '&' . $this->args[$handle] : $this->args[$handle];
|
||||
|
||||
if ( $this->do_concat ) {
|
||||
if ( $this->in_default_dir($this->registered[$handle]->src) && !isset($this->registered[$handle]->extra['conditional']) && !isset($this->registered[$handle]->extra['alt']) ) {
|
||||
$this->concat .= "$handle,";
|
||||
$this->concat_version .= "$handle$ver";
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset($this->registered[$handle]->args) )
|
||||
$media = esc_attr( $this->registered[$handle]->args );
|
||||
else
|
||||
$media = 'all';
|
||||
|
||||
$href = $this->_css_href( $this->registered[$handle]->src, $ver, $handle );
|
||||
$rel = isset($this->registered[$handle]->extra['alt']) && $this->registered[$handle]->extra['alt'] ? 'alternate stylesheet' : 'stylesheet';
|
||||
$title = isset($this->registered[$handle]->extra['title']) ? "title='" . esc_attr( $this->registered[$handle]->extra['title'] ) . "'" : '';
|
||||
|
||||
$end_cond = $tag = '';
|
||||
if ( isset($this->registered[$handle]->extra['conditional']) && $this->registered[$handle]->extra['conditional'] ) {
|
||||
$tag .= "<!--[if {$this->registered[$handle]->extra['conditional']}]>\n";
|
||||
$end_cond = "<![endif]-->\n";
|
||||
}
|
||||
|
||||
$tag .= apply_filters( 'style_loader_tag', "<link rel='$rel' id='$handle-css' $title href='$href' type='text/css' media='$media' />\n", $handle );
|
||||
if ( 'rtl' === $this->text_direction && isset($this->registered[$handle]->extra['rtl']) && $this->registered[$handle]->extra['rtl'] ) {
|
||||
if ( is_bool( $this->registered[$handle]->extra['rtl'] ) ) {
|
||||
$suffix = isset( $this->registered[$handle]->extra['suffix'] ) ? $this->registered[$handle]->extra['suffix'] : '';
|
||||
$rtl_href = str_replace( "{$suffix}.css", "-rtl{$suffix}.css", $this->_css_href( $this->registered[$handle]->src , $ver, "$handle-rtl" ));
|
||||
} else {
|
||||
$rtl_href = $this->_css_href( $this->registered[$handle]->extra['rtl'], $ver, "$handle-rtl" );
|
||||
}
|
||||
|
||||
$tag .= apply_filters( 'style_loader_tag', "<link rel='$rel' id='$handle-rtl-css' $title href='$rtl_href' type='text/css' media='$media' />\n", $handle );
|
||||
}
|
||||
|
||||
$tag .= $end_cond;
|
||||
|
||||
if ( $this->do_concat )
|
||||
$this->print_html .= $tag;
|
||||
else
|
||||
echo $tag;
|
||||
|
||||
// Could do something with $this->registered[$handle]->extra here to print out extra CSS rules
|
||||
// echo "<style type='text/css'>\n";
|
||||
// echo "/* <![CDATA[ */\n";
|
||||
// echo "/* ]]> */\n";
|
||||
// echo "</style>\n";
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function all_deps( $handles, $recursion = false, $group = false ) {
|
||||
$r = parent::all_deps( $handles, $recursion );
|
||||
if ( !$recursion )
|
||||
$this->to_do = apply_filters( 'print_styles_array', $this->to_do );
|
||||
return $r;
|
||||
}
|
||||
|
||||
function _css_href( $src, $ver, $handle ) {
|
||||
if ( !is_bool($src) && !preg_match('|^https?://|', $src) && ! ( $this->content_url && 0 === strpos($src, $this->content_url) ) ) {
|
||||
$src = $this->base_url . $src;
|
||||
}
|
||||
|
||||
if ( !empty($ver) )
|
||||
$src = add_query_arg('ver', $ver, $src);
|
||||
$src = apply_filters( 'style_loader_src', $src, $handle );
|
||||
return esc_url( $src );
|
||||
}
|
||||
|
||||
function in_default_dir($src) {
|
||||
if ( ! $this->default_dirs )
|
||||
return true;
|
||||
|
||||
foreach ( (array) $this->default_dirs as $test ) {
|
||||
if ( 0 === strpos($src, $test) )
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,170 @@
|
||||
<?php
|
||||
/**
|
||||
* WordPress implementation for PHP functions missing from older PHP versions.
|
||||
*
|
||||
* @package PHP
|
||||
* @access private
|
||||
*/
|
||||
|
||||
// Added in PHP 5.0
|
||||
|
||||
if (!function_exists('http_build_query')) {
|
||||
function http_build_query($data, $prefix=null, $sep=null) {
|
||||
return _http_build_query($data, $prefix, $sep);
|
||||
}
|
||||
}
|
||||
|
||||
// from php.net (modified by Mark Jaquith to behave like the native PHP5 function)
|
||||
function _http_build_query($data, $prefix=null, $sep=null, $key='', $urlencode=true) {
|
||||
$ret = array();
|
||||
|
||||
foreach ( (array) $data as $k => $v ) {
|
||||
if ( $urlencode)
|
||||
$k = urlencode($k);
|
||||
if ( is_int($k) && $prefix != null )
|
||||
$k = $prefix.$k;
|
||||
if ( !empty($key) )
|
||||
$k = $key . '%5B' . $k . '%5D';
|
||||
if ( $v === NULL )
|
||||
continue;
|
||||
elseif ( $v === FALSE )
|
||||
$v = '0';
|
||||
|
||||
if ( is_array($v) || is_object($v) )
|
||||
array_push($ret,_http_build_query($v, '', $sep, $k, $urlencode));
|
||||
elseif ( $urlencode )
|
||||
array_push($ret, $k.'='.urlencode($v));
|
||||
else
|
||||
array_push($ret, $k.'='.$v);
|
||||
}
|
||||
|
||||
if ( NULL === $sep )
|
||||
$sep = ini_get('arg_separator.output');
|
||||
|
||||
return implode($sep, $ret);
|
||||
}
|
||||
|
||||
if ( !function_exists('_') ) {
|
||||
function _($string) {
|
||||
return $string;
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('stripos')) {
|
||||
function stripos($haystack, $needle, $offset = 0) {
|
||||
return strpos(strtolower($haystack), strtolower($needle), $offset);
|
||||
}
|
||||
}
|
||||
|
||||
if ( !function_exists('hash_hmac') ):
|
||||
function hash_hmac($algo, $data, $key, $raw_output = false) {
|
||||
return _hash_hmac($algo, $data, $key, $raw_output);
|
||||
}
|
||||
endif;
|
||||
|
||||
function _hash_hmac($algo, $data, $key, $raw_output = false) {
|
||||
$packs = array('md5' => 'H32', 'sha1' => 'H40');
|
||||
|
||||
if ( !isset($packs[$algo]) )
|
||||
return false;
|
||||
|
||||
$pack = $packs[$algo];
|
||||
|
||||
if (strlen($key) > 64)
|
||||
$key = pack($pack, $algo($key));
|
||||
|
||||
$key = str_pad($key, 64, chr(0));
|
||||
|
||||
$ipad = (substr($key, 0, 64) ^ str_repeat(chr(0x36), 64));
|
||||
$opad = (substr($key, 0, 64) ^ str_repeat(chr(0x5C), 64));
|
||||
|
||||
$hmac = $algo($opad . pack($pack, $algo($ipad . $data)));
|
||||
|
||||
if ( $raw_output )
|
||||
return pack( $pack, $hmac );
|
||||
return $hmac;
|
||||
}
|
||||
|
||||
if ( !function_exists('mb_substr') ):
|
||||
function mb_substr( $str, $start, $length=null, $encoding=null ) {
|
||||
return _mb_substr($str, $start, $length, $encoding);
|
||||
}
|
||||
endif;
|
||||
|
||||
function _mb_substr( $str, $start, $length=null, $encoding=null ) {
|
||||
// the solution below, works only for utf-8, so in case of a different
|
||||
// charset, just use built-in substr
|
||||
$charset = get_option( 'blog_charset' );
|
||||
if ( !in_array( $charset, array('utf8', 'utf-8', 'UTF8', 'UTF-8') ) ) {
|
||||
return is_null( $length )? substr( $str, $start ) : substr( $str, $start, $length);
|
||||
}
|
||||
// use the regex unicode support to separate the UTF-8 characters into an array
|
||||
preg_match_all( '/./us', $str, $match );
|
||||
$chars = is_null( $length )? array_slice( $match[0], $start ) : array_slice( $match[0], $start, $length );
|
||||
return implode( '', $chars );
|
||||
}
|
||||
|
||||
if ( !function_exists( 'htmlspecialchars_decode' ) ) {
|
||||
// Added in PHP 5.1.0
|
||||
// Error checks from PEAR::PHP_Compat
|
||||
function htmlspecialchars_decode( $string, $quote_style = ENT_COMPAT )
|
||||
{
|
||||
if ( !is_scalar( $string ) ) {
|
||||
trigger_error( 'htmlspecialchars_decode() expects parameter 1 to be string, ' . gettype( $string ) . ' given', E_USER_WARNING );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !is_int( $quote_style ) && $quote_style !== null ) {
|
||||
trigger_error( 'htmlspecialchars_decode() expects parameter 2 to be integer, ' . gettype( $quote_style ) . ' given', E_USER_WARNING );
|
||||
return;
|
||||
}
|
||||
|
||||
return wp_specialchars_decode( $string, $quote_style );
|
||||
}
|
||||
}
|
||||
|
||||
// For PHP < 5.2.0
|
||||
if ( !function_exists('json_encode') ) {
|
||||
function json_encode( $string ) {
|
||||
global $wp_json;
|
||||
|
||||
if ( !is_a($wp_json, 'Services_JSON') ) {
|
||||
require_once( ABSPATH . WPINC . '/class-json.php' );
|
||||
$wp_json = new Services_JSON();
|
||||
}
|
||||
|
||||
return $wp_json->encodeUnsafe( $string );
|
||||
}
|
||||
}
|
||||
|
||||
if ( !function_exists('json_decode') ) {
|
||||
function json_decode( $string, $assoc_array = false ) {
|
||||
global $wp_json;
|
||||
|
||||
if ( !is_a($wp_json, 'Services_JSON') ) {
|
||||
require_once( ABSPATH . WPINC . '/class-json.php' );
|
||||
$wp_json = new Services_JSON();
|
||||
}
|
||||
|
||||
$res = $wp_json->decode( $string );
|
||||
if ( $assoc_array )
|
||||
$res = _json_decode_object_helper( $res );
|
||||
return $res;
|
||||
}
|
||||
function _json_decode_object_helper($data) {
|
||||
if ( is_object($data) )
|
||||
$data = get_object_vars($data);
|
||||
return is_array($data) ? array_map(__FUNCTION__, $data) : $data;
|
||||
}
|
||||
}
|
||||
|
||||
// pathinfo that fills 'filename' without extension like in PHP 5.2+
|
||||
function pathinfo52($path) {
|
||||
$parts = pathinfo($path);
|
||||
if ( !isset($parts['filename']) ) {
|
||||
$parts['filename'] = substr( $parts['basename'], 0, strrpos($parts['basename'], '.') );
|
||||
if ( empty($parts['filename']) ) // there's no extension
|
||||
$parts['filename'] = $parts['basename'];
|
||||
}
|
||||
return $parts;
|
||||
}
|
||||
@@ -0,0 +1,407 @@
|
||||
<?php
|
||||
/**
|
||||
* WordPress CRON API
|
||||
*
|
||||
* @package WordPress
|
||||
*/
|
||||
|
||||
/**
|
||||
* Schedules a hook to run only once.
|
||||
*
|
||||
* Schedules a hook which will be executed once by the WordPress actions core at
|
||||
* a time which you specify. The action will fire off when someone visits your
|
||||
* WordPress site, if the schedule time has passed.
|
||||
*
|
||||
* @since 2.1.0
|
||||
* @link http://codex.wordpress.org/Function_Reference/wp_schedule_single_event
|
||||
*
|
||||
* @param int $timestamp Timestamp for when to run the event.
|
||||
* @param string $hook Action hook to execute when cron is run.
|
||||
* @param array $args Optional. Arguments to pass to the hook's callback function.
|
||||
*/
|
||||
function wp_schedule_single_event( $timestamp, $hook, $args = array()) {
|
||||
// don't schedule a duplicate if there's already an identical event due in the next 10 minutes
|
||||
$next = wp_next_scheduled($hook, $args);
|
||||
if ( $next && $next <= $timestamp + 600 )
|
||||
return;
|
||||
|
||||
$crons = _get_cron_array();
|
||||
$event = (object) array( 'hook' => $hook, 'timestamp' => $timestamp, 'schedule' => false, 'args' => $args );
|
||||
$event = apply_filters('schedule_event', $event);
|
||||
|
||||
// A plugin disallowed this event
|
||||
if ( ! $event )
|
||||
return false;
|
||||
|
||||
$key = md5(serialize($event->args));
|
||||
|
||||
$crons[$event->timestamp][$event->hook][$key] = array( 'schedule' => $event->schedule, 'args' => $event->args );
|
||||
uksort( $crons, "strnatcasecmp" );
|
||||
_set_cron_array( $crons );
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule a periodic event.
|
||||
*
|
||||
* Schedules a hook which will be executed by the WordPress actions core on a
|
||||
* specific interval, specified by you. The action will trigger when someone
|
||||
* visits your WordPress site, if the scheduled time has passed.
|
||||
*
|
||||
* Valid values for the recurrence are hourly, daily and twicedaily. These can
|
||||
* be extended using the cron_schedules filter in wp_get_schedules().
|
||||
*
|
||||
* Use wp_next_scheduled() to prevent duplicates
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @param int $timestamp Timestamp for when to run the event.
|
||||
* @param string $recurrence How often the event should recur.
|
||||
* @param string $hook Action hook to execute when cron is run.
|
||||
* @param array $args Optional. Arguments to pass to the hook's callback function.
|
||||
* @return bool|null False on failure, null when complete with scheduling event.
|
||||
*/
|
||||
function wp_schedule_event( $timestamp, $recurrence, $hook, $args = array()) {
|
||||
$crons = _get_cron_array();
|
||||
$schedules = wp_get_schedules();
|
||||
|
||||
if ( !isset( $schedules[$recurrence] ) )
|
||||
return false;
|
||||
|
||||
$event = (object) array( 'hook' => $hook, 'timestamp' => $timestamp, 'schedule' => $recurrence, 'args' => $args, 'interval' => $schedules[$recurrence]['interval'] );
|
||||
$event = apply_filters('schedule_event', $event);
|
||||
|
||||
// A plugin disallowed this event
|
||||
if ( ! $event )
|
||||
return false;
|
||||
|
||||
$key = md5(serialize($event->args));
|
||||
|
||||
$crons[$event->timestamp][$event->hook][$key] = array( 'schedule' => $event->schedule, 'args' => $event->args, 'interval' => $event->interval );
|
||||
uksort( $crons, "strnatcasecmp" );
|
||||
_set_cron_array( $crons );
|
||||
}
|
||||
|
||||
/**
|
||||
* Reschedule a recurring event.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @param int $timestamp Timestamp for when to run the event.
|
||||
* @param string $recurrence How often the event should recur.
|
||||
* @param string $hook Action hook to execute when cron is run.
|
||||
* @param array $args Optional. Arguments to pass to the hook's callback function.
|
||||
* @return bool|null False on failure. Null when event is rescheduled.
|
||||
*/
|
||||
function wp_reschedule_event( $timestamp, $recurrence, $hook, $args = array()) {
|
||||
$crons = _get_cron_array();
|
||||
$schedules = wp_get_schedules();
|
||||
$key = md5(serialize($args));
|
||||
$interval = 0;
|
||||
|
||||
// First we try to get it from the schedule
|
||||
if ( 0 == $interval )
|
||||
$interval = $schedules[$recurrence]['interval'];
|
||||
// Now we try to get it from the saved interval in case the schedule disappears
|
||||
if ( 0 == $interval )
|
||||
$interval = $crons[$timestamp][$hook][$key]['interval'];
|
||||
// Now we assume something is wrong and fail to schedule
|
||||
if ( 0 == $interval )
|
||||
return false;
|
||||
|
||||
$now = time();
|
||||
|
||||
if ( $timestamp >= $now )
|
||||
$timestamp = $now + $interval;
|
||||
else
|
||||
$timestamp = $now + ($interval - (($now - $timestamp) % $interval));
|
||||
|
||||
wp_schedule_event( $timestamp, $recurrence, $hook, $args );
|
||||
}
|
||||
|
||||
/**
|
||||
* Unschedule a previously scheduled cron job.
|
||||
*
|
||||
* The $timestamp and $hook parameters are required, so that the event can be
|
||||
* identified.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @param int $timestamp Timestamp for when to run the event.
|
||||
* @param string $hook Action hook, the execution of which will be unscheduled.
|
||||
* @param array $args Arguments to pass to the hook's callback function.
|
||||
* Although not passed to a callback function, these arguments are used
|
||||
* to uniquely identify the scheduled event, so they should be the same
|
||||
* as those used when originally scheduling the event.
|
||||
*/
|
||||
function wp_unschedule_event( $timestamp, $hook, $args = array() ) {
|
||||
$crons = _get_cron_array();
|
||||
$key = md5(serialize($args));
|
||||
unset( $crons[$timestamp][$hook][$key] );
|
||||
if ( empty($crons[$timestamp][$hook]) )
|
||||
unset( $crons[$timestamp][$hook] );
|
||||
if ( empty($crons[$timestamp]) )
|
||||
unset( $crons[$timestamp] );
|
||||
_set_cron_array( $crons );
|
||||
}
|
||||
|
||||
/**
|
||||
* Unschedule all cron jobs attached to a specific hook.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @param string $hook Action hook, the execution of which will be unscheduled.
|
||||
* @param array $args Optional. Arguments that were to be pass to the hook's callback function.
|
||||
*/
|
||||
function wp_clear_scheduled_hook( $hook, $args = array() ) {
|
||||
// Backward compatibility
|
||||
// Previously this function took the arguments as discrete vars rather than an array like the rest of the API
|
||||
if ( !is_array($args) ) {
|
||||
_deprecated_argument( __FUNCTION__, '3.0', __('This argument has changed to an array to match the behavior of the other cron functions.') );
|
||||
$args = array_slice( func_get_args(), 1 );
|
||||
}
|
||||
|
||||
while ( $timestamp = wp_next_scheduled( $hook, $args ) )
|
||||
wp_unschedule_event( $timestamp, $hook, $args );
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the next timestamp for a cron event.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @param string $hook Action hook to execute when cron is run.
|
||||
* @param array $args Optional. Arguments to pass to the hook's callback function.
|
||||
* @return bool|int The UNIX timestamp of the next time the scheduled event will occur.
|
||||
*/
|
||||
function wp_next_scheduled( $hook, $args = array() ) {
|
||||
$crons = _get_cron_array();
|
||||
$key = md5(serialize($args));
|
||||
if ( empty($crons) )
|
||||
return false;
|
||||
foreach ( $crons as $timestamp => $cron ) {
|
||||
if ( isset( $cron[$hook][$key] ) )
|
||||
return $timestamp;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send request to run cron through HTTP request that doesn't halt page loading.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @return null Cron could not be spawned, because it is not needed to run.
|
||||
*/
|
||||
function spawn_cron( $local_time = 0 ) {
|
||||
|
||||
if ( !$local_time )
|
||||
$local_time = time();
|
||||
|
||||
if ( defined('DOING_CRON') || isset($_GET['doing_wp_cron']) )
|
||||
return;
|
||||
|
||||
/*
|
||||
* multiple processes on multiple web servers can run this code concurrently
|
||||
* try to make this as atomic as possible by setting doing_cron switch
|
||||
*/
|
||||
$flag = get_transient('doing_cron');
|
||||
|
||||
if ( $flag > $local_time + 10*60 )
|
||||
$flag = 0;
|
||||
|
||||
// don't run if another process is currently running it or more than once every 60 sec.
|
||||
if ( $flag + 60 > $local_time )
|
||||
return;
|
||||
|
||||
//sanity check
|
||||
$crons = _get_cron_array();
|
||||
if ( !is_array($crons) )
|
||||
return;
|
||||
|
||||
$keys = array_keys( $crons );
|
||||
if ( isset($keys[0]) && $keys[0] > $local_time )
|
||||
return;
|
||||
|
||||
if ( defined('ALTERNATE_WP_CRON') && ALTERNATE_WP_CRON ) {
|
||||
if ( !empty($_POST) || defined('DOING_AJAX') )
|
||||
return;
|
||||
|
||||
set_transient( 'doing_cron', $local_time );
|
||||
|
||||
ob_start();
|
||||
wp_redirect( add_query_arg('doing_wp_cron', '', stripslashes($_SERVER['REQUEST_URI'])) );
|
||||
echo ' ';
|
||||
|
||||
// flush any buffers and send the headers
|
||||
while ( @ob_end_flush() );
|
||||
flush();
|
||||
|
||||
WP_DEBUG ? include_once( ABSPATH . 'wp-cron.php' ) : @include_once( ABSPATH . 'wp-cron.php' );
|
||||
return;
|
||||
}
|
||||
|
||||
set_transient( 'doing_cron', $local_time );
|
||||
|
||||
$cron_url = get_option( 'siteurl' ) . '/wp-cron.php?doing_wp_cron';
|
||||
wp_remote_post( $cron_url, array('timeout' => 0.01, 'blocking' => false, 'sslverify' => apply_filters('https_local_ssl_verify', true)) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Run scheduled callbacks or spawn cron for all scheduled events.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @return null When doesn't need to run Cron.
|
||||
*/
|
||||
function wp_cron() {
|
||||
|
||||
// Prevent infinite loops caused by lack of wp-cron.php
|
||||
if ( strpos($_SERVER['REQUEST_URI'], '/wp-cron.php') !== false || ( defined('DISABLE_WP_CRON') && DISABLE_WP_CRON ) )
|
||||
return;
|
||||
|
||||
if ( false === $crons = _get_cron_array() )
|
||||
return;
|
||||
|
||||
$local_time = time();
|
||||
$keys = array_keys( $crons );
|
||||
if ( isset($keys[0]) && $keys[0] > $local_time )
|
||||
return;
|
||||
|
||||
$schedules = wp_get_schedules();
|
||||
foreach ( $crons as $timestamp => $cronhooks ) {
|
||||
if ( $timestamp > $local_time ) break;
|
||||
foreach ( (array) $cronhooks as $hook => $args ) {
|
||||
if ( isset($schedules[$hook]['callback']) && !call_user_func( $schedules[$hook]['callback'] ) )
|
||||
continue;
|
||||
spawn_cron( $local_time );
|
||||
break 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve supported and filtered Cron recurrences.
|
||||
*
|
||||
* The supported recurrences are 'hourly' and 'daily'. A plugin may add more by
|
||||
* hooking into the 'cron_schedules' filter. The filter accepts an array of
|
||||
* arrays. The outer array has a key that is the name of the schedule or for
|
||||
* example 'weekly'. The value is an array with two keys, one is 'interval' and
|
||||
* the other is 'display'.
|
||||
*
|
||||
* The 'interval' is a number in seconds of when the cron job should run. So for
|
||||
* 'hourly', the time is 3600 or 60*60. For weekly, the value would be
|
||||
* 60*60*24*7 or 604800. The value of 'interval' would then be 604800.
|
||||
*
|
||||
* The 'display' is the description. For the 'weekly' key, the 'display' would
|
||||
* be <code>__('Once Weekly')</code>.
|
||||
*
|
||||
* For your plugin, you will be passed an array. you can easily add your
|
||||
* schedule by doing the following.
|
||||
* <code>
|
||||
* // filter parameter variable name is 'array'
|
||||
* $array['weekly'] = array(
|
||||
* 'interval' => 604800,
|
||||
* 'display' => __('Once Weekly')
|
||||
* );
|
||||
* </code>
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function wp_get_schedules() {
|
||||
$schedules = array(
|
||||
'hourly' => array( 'interval' => 3600, 'display' => __('Once Hourly') ),
|
||||
'twicedaily' => array( 'interval' => 43200, 'display' => __('Twice Daily') ),
|
||||
'daily' => array( 'interval' => 86400, 'display' => __('Once Daily') ),
|
||||
);
|
||||
return array_merge( apply_filters( 'cron_schedules', array() ), $schedules );
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve Cron schedule for hook with arguments.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @param string $hook Action hook to execute when cron is run.
|
||||
* @param array $args Optional. Arguments to pass to the hook's callback function.
|
||||
* @return string|bool False, if no schedule. Schedule on success.
|
||||
*/
|
||||
function wp_get_schedule($hook, $args = array()) {
|
||||
$crons = _get_cron_array();
|
||||
$key = md5(serialize($args));
|
||||
if ( empty($crons) )
|
||||
return false;
|
||||
foreach ( $crons as $timestamp => $cron ) {
|
||||
if ( isset( $cron[$hook][$key] ) )
|
||||
return $cron[$hook][$key]['schedule'];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
// Private functions
|
||||
//
|
||||
|
||||
/**
|
||||
* Retrieve cron info array option.
|
||||
*
|
||||
* @since 2.1.0
|
||||
* @access private
|
||||
*
|
||||
* @return array CRON info array.
|
||||
*/
|
||||
function _get_cron_array() {
|
||||
$cron = get_option('cron');
|
||||
if ( ! is_array($cron) )
|
||||
return false;
|
||||
|
||||
if ( !isset($cron['version']) )
|
||||
$cron = _upgrade_cron_array($cron);
|
||||
|
||||
unset($cron['version']);
|
||||
|
||||
return $cron;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the CRON option with the new CRON array.
|
||||
*
|
||||
* @since 2.1.0
|
||||
* @access private
|
||||
*
|
||||
* @param array $cron Cron info array from {@link _get_cron_array()}.
|
||||
*/
|
||||
function _set_cron_array($cron) {
|
||||
$cron['version'] = 2;
|
||||
update_option( 'cron', $cron );
|
||||
}
|
||||
|
||||
/**
|
||||
* Upgrade a Cron info array.
|
||||
*
|
||||
* This function upgrades the Cron info array to version 2.
|
||||
*
|
||||
* @since 2.1.0
|
||||
* @access private
|
||||
*
|
||||
* @param array $cron Cron info array from {@link _get_cron_array()}.
|
||||
* @return array An upgraded Cron info array.
|
||||
*/
|
||||
function _upgrade_cron_array($cron) {
|
||||
if ( isset($cron['version']) && 2 == $cron['version'])
|
||||
return $cron;
|
||||
|
||||
$new_cron = array();
|
||||
|
||||
foreach ( (array) $cron as $timestamp => $hooks) {
|
||||
foreach ( (array) $hooks as $hook => $args ) {
|
||||
$key = md5(serialize($args['args']));
|
||||
$new_cron[$timestamp][$hook][$key] = $args;
|
||||
}
|
||||
}
|
||||
|
||||
$new_cron['version'] = 2;
|
||||
update_option( 'cron', $new_cron );
|
||||
return $new_cron;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
#wpadminbar{direction:rtl;font-family:Tahoma,Arial,sans-serif;right:0;left:auto;}#wpadminbar .quicklinks ul{text-align:right;}#wpadminbar .quicklinks ul li{float:right;}#wpadminbar .quicklinks>ul>li>a{border-left:1px solid #686868;border-right:1px solid #808080;}#wpadminbar .quicklinks>ul>li:last-child>a{border-left:none;border-right:1px solid #808080;}#wpadminbar .quicklinks>ul>li:hover>a{border-right-color:#707070;border-left-color:#686868;}#wpadminbar .quicklinks li#wp-admin-bar-my-account-with-avatar a img{margin:-2px -5px 0 23px;}#wpadminbar .quicklinks li#wp-admin-bar-my-account-with-avatar ul{left:auto;right:30px;}#wpadminbar .quicklinks .menupop li:hover>ul,#wpadminbar .quicklinks .menupop li.hover>ul{margin-right:100%;margin-left:0;}#wpadminbar .quicklinks .menupop a>span{background:url(../images/admin-bar-sprite-rtl.png?d=11122010) left -58px no-repeat;padding-right:0;padding-left:.8em;}#wpadminbar .quicklinks .menupop ul li a>span{background:url(../images/admin-bar-sprite-rtl.png?d=11122010) left -29px no-repeat;padding-right:0;padding-left:1.5em;}#wpadminbar .quicklinks a{font-family:Tahoma,Arial,Helvetica,sans-serif;}#wpadminbar .quicklinks .menupop li a img.blavatar{margin-right:0;margin-left:8px;}#wpadminbar .quicklinks li#wp-admin-bar-my-account-with-avatar>a{background:url(../images/admin-bar-sprite-rtl.png?d=11122010) top right no-repeat;}#wpadminbar .quicklinks li#wp-admin-bar-my-account>a,#wpadminbar .quicklinks li#wp-admin-bar-my-account-with-avatar>a{border-right:none;border-left:1px solid #686868;}#wpadminbar #adminbarsearch{float:left;}#wpadminbar #adminbarsearch .adminbar-input{float:right;font-family:Tahoma,Arial,Helvetica,sans-serif;margin-right:0;margin-left:3px;-moz-box-shadow:inset 2px -2px 1px #cdcdcd;-webkit-box-shadow:inset -2px 2px 1px #cdcdcd;box-shadow:inset 2px -2px 1px #cdcdcd;}#wpadminbar #adminbarsearch .adminbar-button{float:right;font-family:Tahoma,Arial,Helvetica,sans-serif;}
|
||||
@@ -0,0 +1,94 @@
|
||||
#wpadminbar {
|
||||
direction: rtl;
|
||||
font-family: Tahoma, Arial ,sans-serif;
|
||||
right: 0;
|
||||
left: auto;
|
||||
}
|
||||
|
||||
#wpadminbar .quicklinks ul {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
#wpadminbar .quicklinks ul li {
|
||||
float: right;
|
||||
}
|
||||
|
||||
#wpadminbar .quicklinks > ul > li > a {
|
||||
border-left: 1px solid #686868;
|
||||
border-right: 1px solid #808080;
|
||||
}
|
||||
|
||||
#wpadminbar .quicklinks > ul > li:last-child > a {
|
||||
border-left: none;
|
||||
border-right: 1px solid #808080;
|
||||
}
|
||||
|
||||
#wpadminbar .quicklinks > ul > li:hover > a {
|
||||
border-right-color: #707070;
|
||||
border-left-color: #686868;
|
||||
}
|
||||
|
||||
#wpadminbar .quicklinks li#wp-admin-bar-my-account-with-avatar a img {
|
||||
margin: -2px -5px 0 23px;
|
||||
}
|
||||
|
||||
#wpadminbar .quicklinks li#wp-admin-bar-my-account-with-avatar ul {
|
||||
left: auto;
|
||||
right: 30px;
|
||||
}
|
||||
|
||||
#wpadminbar .quicklinks .menupop li:hover > ul,
|
||||
#wpadminbar .quicklinks .menupop li.hover > ul {
|
||||
margin-right: 100%;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
#wpadminbar .quicklinks .menupop a > span {
|
||||
background: url(../images/admin-bar-sprite-rtl.png?d=11122010) left -58px no-repeat;
|
||||
padding-right: 0;
|
||||
padding-left: .8em;
|
||||
}
|
||||
|
||||
#wpadminbar .quicklinks .menupop ul li a > span {
|
||||
background: url(../images/admin-bar-sprite-rtl.png?d=11122010) left -29px no-repeat;
|
||||
padding-right: 0;
|
||||
padding-left: 1.5em;
|
||||
}
|
||||
|
||||
#wpadminbar .quicklinks a {
|
||||
font-family: Tahoma, Arial, Helvetica, sans-serif;
|
||||
}
|
||||
|
||||
#wpadminbar .quicklinks .menupop li a img.blavatar {
|
||||
margin-right: 0;
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
#wpadminbar .quicklinks li#wp-admin-bar-my-account-with-avatar > a {
|
||||
background: url(../images/admin-bar-sprite-rtl.png?d=11122010) top right no-repeat;
|
||||
}
|
||||
|
||||
#wpadminbar .quicklinks li#wp-admin-bar-my-account > a,
|
||||
#wpadminbar .quicklinks li#wp-admin-bar-my-account-with-avatar > a {
|
||||
border-right: none;
|
||||
border-left: 1px solid #686868;
|
||||
}
|
||||
|
||||
#wpadminbar #adminbarsearch {
|
||||
float: left;
|
||||
}
|
||||
|
||||
#wpadminbar #adminbarsearch .adminbar-input {
|
||||
float: right;
|
||||
font-family: Tahoma, Arial, Helvetica, sans-serif;
|
||||
margin-right: 0;
|
||||
margin-left: 3px;
|
||||
-moz-box-shadow: inset 2px -2px 1px #cdcdcd;
|
||||
-webkit-box-shadow: inset -2px 2px 1px #cdcdcd;
|
||||
box-shadow: inset 2px -2px 1px #cdcdcd;
|
||||
}
|
||||
|
||||
#wpadminbar #adminbarsearch .adminbar-button {
|
||||
float: right;
|
||||
font-family: Tahoma, Arial, Helvetica, sans-serif;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
#wpadminbar *{height:auto;width:auto;margin:0;padding:0;position:static;text-transform:none;letter-spacing:normal;line-height:1;}#wpadminbar :before,#wpadminbar :after{content:normal;}#wpadminbar a,#wpadminbar a:hover,#wpadminbar a img,#wpadminbar a img:hover{outline:none;border:none;text-decoration:none;background:none;}#wpadminbar{direction:ltr;background-color:#777;background-image:-moz-linear-gradient(bottom,#666,#7f7f7f);background-image:-webkit-gradient(linear,left bottom,left top,from(#666),to(#7f7f7f));color:#ddd;font:normal 12px/28px Arial,Helvetica,sans-serif;height:28px;position:fixed;top:0;left:0;width:100%;z-index:99999;min-width:960px;}#wpadminbar ul,#wpadminbar ul li{background:none;list-style:none;margin:0;padding:0;position:relative;z-index:99999;}#wpadminbar .quicklinks ul{text-align:left;}#wpadminbar .quicklinks ul li{float:left;}#wpadminbar .quicklinks>ul>li>a{border-right:1px solid #686868;border-left:1px solid #808080;}#wpadminbar .quicklinks>ul>li:last-child>a{border-right:none;}#wpadminbar .quicklinks>ul>li:hover>a{border-left-color:#707070;}#wpadminbar .quicklinks a,#wpadminbar .shortlink-input{color:#ddd;height:28px;text-shadow:#555 0 -1px 0;display:block;font:normal 13px/28px Arial,Helvetica,sans-serif;padding:0 .85em;margin:0;}#wpadminbar .quicklinks a>span{line-height:28px;}#wpadminbar .quicklinks .menupop ul,#wpadminbar .shortlink-input{-moz-box-shadow:0 4px 8px rgba(0,0,0,0.1);-webkit-box-shadow:0 4px 8px rgba(0,0,0,0.1);box-shadow:0 4px 8px rgba(0,0,0,0.1);background:#fff;background:rgba(255,255,255,0.97);display:none;position:absolute;border:1px solid #dfdfdf;border-top:none;float:none;}#wpadminbar .selected .shortlink-input{display:block;}#wpadminbar .quicklinks .menupop ul li{float:none;}#wpadminbar .quicklinks .menupop ul li a,#wpadminbar .shortlink-input{color:#555;text-shadow:none;white-space:nowrap;min-width:140px;}#wpadminbar .shortlink-input{width:200px;}#wpadminbar .quicklinks .menupop ul li:hover>a{color:#fff;text-shadow:#666 0 -1px 0;}#wpadminbar .quicklinks li:hover>ul,#wpadminbar .quicklinks li.hover>ul{display:block;}#wpadminbar .quicklinks .menupop li:hover>ul,#wpadminbar .quicklinks .menupop li.hover>ul{margin-left:100%;margin-top:-28px;}#wpadminbar .quicklinks li:hover,#wpadminbar .quicklinks .selected{background:#555;background:-moz-linear-gradient(bottom,#555,#3e3e3e);background:-webkit-gradient(linear,left bottom,left top,from(#555),to(#3e3e3e));}#wpadminbar .quicklinks .menupop li:hover{background:#888;background:-moz-linear-gradient(bottom,#888,#9d9d9d);background:-webkit-gradient(linear,left bottom,left top,from(#888),to(#9d9d9d));}#wpadminbar .quicklinks .menupop a>span{display:inline;background:url(../images/admin-bar-sprite.png?d=11122010) right -58px no-repeat;padding-right:.8em;}#wpadminbar .quicklinks .menupop ul li a>span{display:block;background:url(../images/admin-bar-sprite.png?d=11122010) right -29px no-repeat;padding-right:1.5em;}#wpadminbar .quicklinks a span#ab-awaiting-mod,#wpadminbar .quicklinks a span#ab-updates{background:#eee;color:#333;text-shadow:none;display:inline;padding:2px 5px;font-size:10px;font-weight:bold;-moz-border-radius:10px;-khtml-border-radius:10px;-webkit-border-radius:10px;border-radius:10px;}#wpadminbar .quicklinks a:hover span#ab-awaiting-mod,#wpadminbar .quicklinks a:hover span#ab-updates{background:#fff;color:#000;}#wpadminbar .quicklinks li#wp-admin-bar-my-account>a{border-left:none;}#wpadminbar .quicklinks li#wp-admin-bar-my-account-with-avatar>a{border-left:none;background:url(../images/admin-bar-sprite.png?d=11122010) top left no-repeat;}#wpadminbar .quicklinks li#wp-admin-bar-my-account-with-avatar>a img{width:16px;height:16px;display:inline;border:1px solid #999;vertical-align:middle;margin:-2px 23px 0 -5px;padding:0;background:#eee;float:none;}#wpadminbar .quicklinks li#wp-admin-bar-my-account-with-avatar ul{left:30px;}#wpadminbar .quicklinks li#wp-admin-bar-my-account-with-avatar ul ul{left:0;}#wpadminbar .quicklinks .menupop li a img.blavatar{vertical-align:middle;margin:0 8px 0 0;padding:0;}#wpadminbar #adminbarsearch{float:right;height:18px;padding:3px;margin:0;}#wpadminbar #adminbarsearch .adminbar-input{width:140px;height:auto;float:left;font:12px Arial,Helvetica,sans-serif;color:#555;text-shadow:0 1px 0 #fff;border:1px solid #626262;padding:2px 3px;margin:0 3px 0 0;background:#ddd;-moz-box-shadow:inset 2px 2px 1px #cdcdcd;-webkit-box-shadow:inset 2px 2px 1px #cdcdcd;box-shadow:inset 2px 2px 1px #cdcdcd;-webkit-border-radius:0;-khtml-border-radius:0;-moz-border-radius:0;border-radius:0;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box;outline:none;}#wpadminbar #adminbarsearch .adminbar-button{font:bold 12px Arial,Helvetica,sans-serif;color:#444;text-shadow:0 1px 0 #eee;cursor:pointer;float:left;background:#aaa;background:-moz-linear-gradient(bottom,#aaa,#cecece);background:-webkit-gradient(linear,left bottom,left top,from(#aaa),to(#cecece));-weLine truncated
|
||||
@@ -0,0 +1,304 @@
|
||||
#wpadminbar * {
|
||||
height: auto;
|
||||
width: auto;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
position: static;
|
||||
text-transform: none;
|
||||
letter-spacing: normal;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
#wpadminbar :before,
|
||||
#wpadminbar :after {
|
||||
content: normal;
|
||||
}
|
||||
|
||||
#wpadminbar a,
|
||||
#wpadminbar a:hover,
|
||||
#wpadminbar a img,
|
||||
#wpadminbar a img:hover {
|
||||
outline: none;
|
||||
border: none;
|
||||
text-decoration: none;
|
||||
background: none;
|
||||
}
|
||||
|
||||
#wpadminbar {
|
||||
direction: ltr;
|
||||
background-color: #777;
|
||||
background-image: -moz-linear-gradient(bottom, #666, #7f7f7f);
|
||||
background-image: -webkit-gradient(linear, left bottom, left top, from(#666), to(#7f7f7f));
|
||||
color: #ddd;
|
||||
font: normal 12px/28px Arial, Helvetica, sans-serif;
|
||||
height: 28px;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
z-index: 99999;
|
||||
min-width: 960px;
|
||||
}
|
||||
|
||||
#wpadminbar ul,
|
||||
#wpadminbar ul li {
|
||||
background: none;
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
position: relative;
|
||||
z-index: 99999;
|
||||
}
|
||||
|
||||
#wpadminbar .quicklinks ul {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
#wpadminbar .quicklinks ul li {
|
||||
float: left;
|
||||
}
|
||||
|
||||
#wpadminbar .quicklinks > ul > li > a {
|
||||
border-right: 1px solid #686868;
|
||||
border-left: 1px solid #808080;
|
||||
}
|
||||
|
||||
#wpadminbar .quicklinks > ul > li:last-child > a {
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
#wpadminbar .quicklinks > ul > li:hover > a {
|
||||
border-left-color: #707070;
|
||||
}
|
||||
|
||||
#wpadminbar .quicklinks a,
|
||||
#wpadminbar .shortlink-input {
|
||||
color: #ddd;
|
||||
height: 28px;
|
||||
text-shadow: #555 0px -1px 0px;
|
||||
display: block;
|
||||
font: normal 13px/28px Arial, Helvetica, sans-serif;
|
||||
padding: 0 0.85em;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#wpadminbar .quicklinks a > span {
|
||||
line-height: 28px;
|
||||
}
|
||||
|
||||
#wpadminbar .quicklinks .menupop ul,
|
||||
#wpadminbar .shortlink-input {
|
||||
-moz-box-shadow: 0 4px 8px rgba(0,0,0,0.1);
|
||||
-webkit-box-shadow: 0 4px 8px rgba(0,0,0,0.1);
|
||||
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
|
||||
background: #fff;
|
||||
background: rgba(255,255,255,0.97);
|
||||
display: none;
|
||||
position: absolute;
|
||||
border: 1px solid #dfdfdf;
|
||||
border-top: none;
|
||||
float: none;
|
||||
}
|
||||
|
||||
#wpadminbar .selected .shortlink-input {
|
||||
display: block;
|
||||
}
|
||||
|
||||
#wpadminbar .quicklinks .menupop ul li {
|
||||
float: none;
|
||||
}
|
||||
|
||||
#wpadminbar .quicklinks .menupop ul li a,
|
||||
#wpadminbar .shortlink-input {
|
||||
color: #555;
|
||||
text-shadow: none;
|
||||
white-space: nowrap;
|
||||
min-width: 140px;
|
||||
}
|
||||
|
||||
#wpadminbar .shortlink-input {
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
#wpadminbar .quicklinks .menupop ul li:hover > a {
|
||||
color: #fff;
|
||||
text-shadow: #666 0px -1px 0px;
|
||||
}
|
||||
|
||||
#wpadminbar .quicklinks li:hover > ul,
|
||||
#wpadminbar .quicklinks li.hover > ul {
|
||||
display: block;
|
||||
}
|
||||
|
||||
#wpadminbar .quicklinks .menupop li:hover > ul,
|
||||
#wpadminbar .quicklinks .menupop li.hover > ul {
|
||||
margin-left: 100%;
|
||||
margin-top: -28px;
|
||||
}
|
||||
|
||||
#wpadminbar .quicklinks li:hover,
|
||||
#wpadminbar .quicklinks .selected {
|
||||
background: #555;
|
||||
background: -moz-linear-gradient(bottom, #555, #3e3e3e);
|
||||
background: -webkit-gradient(linear, left bottom, left top, from(#555), to(#3e3e3e));
|
||||
}
|
||||
|
||||
#wpadminbar .quicklinks .menupop li:hover {
|
||||
background: #888;
|
||||
background: -moz-linear-gradient(bottom, #888, #9d9d9d);
|
||||
background: -webkit-gradient(linear, left bottom, left top, from(#888), to(#9d9d9d));
|
||||
}
|
||||
|
||||
#wpadminbar .quicklinks .menupop a > span {
|
||||
display: inline;
|
||||
background: url(../images/admin-bar-sprite.png?d=11122010) right -58px no-repeat;
|
||||
padding-right: .8em;
|
||||
}
|
||||
|
||||
#wpadminbar .quicklinks .menupop ul li a > span {
|
||||
display: block;
|
||||
background: url(../images/admin-bar-sprite.png?d=11122010) right -29px no-repeat;
|
||||
padding-right: 1.5em;
|
||||
}
|
||||
|
||||
#wpadminbar .quicklinks a span#ab-awaiting-mod,
|
||||
#wpadminbar .quicklinks a span#ab-updates {
|
||||
background: #eee;
|
||||
color: #333;
|
||||
text-shadow: none;
|
||||
display: inline;
|
||||
padding: 2px 5px;
|
||||
font-size: 10px;
|
||||
font-weight: bold;
|
||||
-moz-border-radius: 10px;
|
||||
-khtml-border-radius: 10px;
|
||||
-webkit-border-radius: 10px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
#wpadminbar .quicklinks a:hover span#ab-awaiting-mod,
|
||||
#wpadminbar .quicklinks a:hover span#ab-updates {
|
||||
background: #fff;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
#wpadminbar .quicklinks li#wp-admin-bar-my-account > a {
|
||||
border-left: none;
|
||||
}
|
||||
|
||||
#wpadminbar .quicklinks li#wp-admin-bar-my-account-with-avatar > a {
|
||||
border-left: none;
|
||||
background: url(../images/admin-bar-sprite.png?d=11122010) top left no-repeat;
|
||||
}
|
||||
|
||||
#wpadminbar .quicklinks li#wp-admin-bar-my-account-with-avatar > a img {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
display: inline;
|
||||
border: 1px solid #999;
|
||||
vertical-align: middle;
|
||||
margin: -2px 23px 0 -5px;
|
||||
padding: 0;
|
||||
background: #eee;
|
||||
float: none;
|
||||
}
|
||||
|
||||
#wpadminbar .quicklinks li#wp-admin-bar-my-account-with-avatar ul {
|
||||
left: 30px;
|
||||
}
|
||||
|
||||
#wpadminbar .quicklinks li#wp-admin-bar-my-account-with-avatar ul ul {
|
||||
left: 0;
|
||||
}
|
||||
|
||||
#wpadminbar .quicklinks .menupop li a img.blavatar {
|
||||
vertical-align: middle;
|
||||
margin: 0 8px 0 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#wpadminbar #adminbarsearch {
|
||||
float: right;
|
||||
height: 18px;
|
||||
padding: 3px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#wpadminbar #adminbarsearch .adminbar-input {
|
||||
width: 140px;
|
||||
height: auto;
|
||||
float: left;
|
||||
font: 12px Arial, Helvetica, sans-serif;
|
||||
color: #555;
|
||||
text-shadow: 0 1px 0 #fff;
|
||||
border: 1px solid #626262;
|
||||
padding: 2px 3px;
|
||||
margin: 0 3px 0 0;
|
||||
background: #ddd;
|
||||
-moz-box-shadow: inset 2px 2px 1px #cdcdcd;
|
||||
-webkit-box-shadow: inset 2px 2px 1px #cdcdcd;
|
||||
box-shadow: inset 2px 2px 1px #cdcdcd;
|
||||
-webkit-border-radius: 0;
|
||||
-khtml-border-radius: 0;
|
||||
-moz-border-radius: 0;
|
||||
border-radius: 0;
|
||||
-moz-box-sizing: border-box;
|
||||
-webkit-box-sizing: border-box;
|
||||
-ms-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
#wpadminbar #adminbarsearch .adminbar-button {
|
||||
font: bold 12px Arial, Helvetica, sans-serif;
|
||||
color: #444;
|
||||
text-shadow: 0px 1px 0px #eee;
|
||||
cursor: pointer;
|
||||
float: left;
|
||||
background: #aaa;
|
||||
background: -moz-linear-gradient(bottom, #aaa, #cecece);
|
||||
background: -webkit-gradient(linear, left bottom, left top, from(#aaa), to(#cecece));
|
||||
-webkit-border-radius: 10px;
|
||||
-khtml-border-radius: 10px;
|
||||
-moz-border-radius: 10px;
|
||||
border-radius: 10px;
|
||||
border: 1px solid #626262;
|
||||
padding: 2px 13px;
|
||||
margin: 0;
|
||||
width: auto;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
#wpadminbar #adminbarsearch .adminbar-button:active {
|
||||
background: #a0a0a0;
|
||||
background:-moz-linear-gradient(bottom, #a0a0a0, #c1c1c1);
|
||||
background:-webkit-gradient(linear, left bottom, left top, from(#a0a0a0), to(#c1c1c1));
|
||||
-moz-box-shadow: inset 1px 1px 1px #9b9b9b;
|
||||
-webkit-box-shadow: inset 1px 1px 1px #9b9b9b;
|
||||
box-shadow: inset 1px 1px 1px #9b9b9b;
|
||||
}
|
||||
|
||||
#wpadminbar #adminbarsearch .adminbar-button:hover {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
#wpadminbar #adminbarsearch .adminbar-button::-moz-focus-inner {
|
||||
border: none;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* IE 6-targeted rules
|
||||
*/
|
||||
* html #wpadminbar {
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
* html #wpadminbar .quicklinks ul li a {
|
||||
float: left;
|
||||
}
|
||||
|
||||
* html #wpadminbar .menupop a span {
|
||||
background-image: none;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
.ui-helper-hidden{display:none;}.ui-helper-hidden-accessible{position:absolute;left:-99999999px;}.ui-helper-reset{margin:0;padding:0;border:0;outline:0;line-height:1.3;text-decoration:none;font-size:100%;list-style:none;}.ui-helper-clearfix:after{content:".";display:block;height:0;clear:both;visibility:hidden;}.ui-helper-clearfix{display:inline-block;}/* required comment for clearfix to work in Opera \*/ * html .ui-helper-clearfix{height:1%;}.ui-helper-clearfix{display:block;}/* end clearfix */ .ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0);}.ui-state-disabled{cursor:default!important;}.ui-icon{display:block;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat;}.ui-widget-overlay{position:absolute;top:0;left:0;width:100%;height:100%;}.ui-resizable{position:relative;}.ui-resizable-handle{position:absolute;font-size:.1px;z-index:99999;display:block;}.ui-resizable-disabled .ui-resizable-handle,.ui-resizable-autohide .ui-resizable-handle{display:none;}.ui-resizable-n{cursor:n-resize;height:7px;width:100%;top:-5px;left:0;}.ui-resizable-s{cursor:s-resize;height:7px;width:100%;bottom:-5px;left:0;}.ui-resizable-e{cursor:e-resize;width:7px;right:-5px;top:0;height:100%;}.ui-resizable-w{cursor:w-resize;width:7px;left:-5px;top:0;height:100%;}.ui-resizable-se{cursor:se-resize;width:12px;height:12px;right:1px;bottom:1px;}.ui-resizable-sw{cursor:sw-resize;width:9px;height:9px;left:-5px;bottom:-5px;}.ui-resizable-nw{cursor:nw-resize;width:9px;height:9px;left:-5px;top:-5px;}.ui-resizable-ne{cursor:ne-resize;width:9px;height:9px;right:-5px;top:-5px;}.wp-dialog{position:absolute;width:300px;overflow:hidden;}.wp-dialog .ui-dialog-titlebar{position:relative;}.wp-dialog .ui-dialog-titlebar-close span{display:block;margin:1px;}.wp-dialog .ui-dialog-content{position:relative;border:0;padding:0;background:none;overflow:auto;zoom:1;}.wp-dialog .ui-dialog-buttonpane{text-align:left;border-width:1px 0 0 0;background-image:none;margin:.5em 0 0 0;padding:.3em 1em .5em .4em;}.wp-dialog .ui-dialog-buttonpane .ui-dialog-buttonset{float:right;}.wp-dialog .ui-dialog-buttonpane button{margin:.5em .4em .5em 0;cursor:pointer;}.wp-dialog .ui-resizable-se{width:14px;height:14px;right:3px;bottom:3px;}.ui-draggable .ui-dialog-titlebar{cursor:move;}.wp-dialog{border:1px solid #999;-moz-box-shadow:0 0 16px rgba(0,0,0,0.3);-webkit-box-shadow:0 0 16px rgba(0,0,0,0.3);box-shadow:0 0 16px rgba(0,0,0,0.3);}.wp-dialog .ui-dialog-title{display:block;text-align:center;padding:1px 0 2px;}.wp-dialog .ui-dialog-titlebar{padding:0 1em;background-color:#444;font-weight:bold;font-size:11px;line-height:18px;color:#e5e5e5;}.wp-dialog{-moz-border-radius-topleft:4px;-webkit-border-top-left-radius:4px;-khtml-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topright:4px;-webkit-border-top-right-radius:4px;-khtml-border-top-right-radius:4px;border-top-right-radius:4px;}.wp-dialog .ui-dialog-titlebar{-moz-border-radius-topleft:3px;-webkit-border-top-left-radius:3px;-khtml-border-top-left-radius:3px;border-top-left-radius:3px;-moz-border-radius-topright:3px;-webkit-border-top-right-radius:3px;-khtml-border-top-right-radius:3px;border-top-right-radius:3px;}.wp-dialog .ui-dialog-titlebar-close{position:absolute;width:29px;height:16px;top:2px;right:6px;background:url('../js/tinymce/plugins/inlinepopups/skins/clearlooks2/img/buttons.gif') no-repeat -87px -16px;padding:0;}.wp-dialog .ui-dialog-titlebar-close:hover,.wp-dialog .ui-dialog-titlebar-close:focus{background-position:-87px -32px;}.ui-widget-overlay{background-color:#000;opacity:.6;filter:alpha(opacity=60);}
|
||||
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* jQuery UI CSS Framework @VERSION
|
||||
*
|
||||
* Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
* http://jquery.org/license
|
||||
*
|
||||
* http://docs.jquery.com/UI/Theming/API
|
||||
*/
|
||||
|
||||
/* Layout helpers
|
||||
----------------------------------*/
|
||||
.ui-helper-hidden { display: none; }
|
||||
.ui-helper-hidden-accessible { position: absolute; left: -99999999px; }
|
||||
.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; }
|
||||
.ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; }
|
||||
.ui-helper-clearfix { display: inline-block; }
|
||||
/* required comment for clearfix to work in Opera \*/
|
||||
* html .ui-helper-clearfix { height:1%; }
|
||||
.ui-helper-clearfix { display:block; }
|
||||
/* end clearfix */
|
||||
.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); }
|
||||
|
||||
|
||||
/* Interaction Cues
|
||||
----------------------------------*/
|
||||
.ui-state-disabled { cursor: default !important; }
|
||||
|
||||
|
||||
/* Icons
|
||||
----------------------------------*/
|
||||
|
||||
/* states and images */
|
||||
.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; }
|
||||
|
||||
|
||||
/* Misc visuals
|
||||
----------------------------------*/
|
||||
|
||||
/* Overlays */
|
||||
.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
|
||||
|
||||
/*
|
||||
* jQuery UI Resizable
|
||||
*
|
||||
* Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
* http://jquery.org/license
|
||||
*
|
||||
* http://docs.jquery.com/UI/Resizable#theming
|
||||
*/
|
||||
.ui-resizable { position: relative;}
|
||||
.ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block;}
|
||||
.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; }
|
||||
.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; }
|
||||
.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; }
|
||||
.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; }
|
||||
.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; }
|
||||
.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; }
|
||||
.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; }
|
||||
.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; }
|
||||
.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}
|
||||
|
||||
/*
|
||||
* jQuery UI Dialog
|
||||
*
|
||||
* Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
* http://jquery.org/license
|
||||
*
|
||||
* http://docs.jquery.com/UI/Dialog#theming
|
||||
*/
|
||||
.wp-dialog { position: absolute; width: 300px; overflow: hidden; }
|
||||
.wp-dialog .ui-dialog-titlebar { position: relative; }
|
||||
.wp-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; }
|
||||
.wp-dialog .ui-dialog-content { position: relative; border: 0; padding: 0; background: none; overflow: auto; zoom: 1; }
|
||||
.wp-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; }
|
||||
.wp-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { float: right; }
|
||||
.wp-dialog .ui-dialog-buttonpane button { margin: .5em .4em .5em 0; cursor: pointer; }
|
||||
.wp-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; }
|
||||
.ui-draggable .ui-dialog-titlebar { cursor: move; }
|
||||
|
||||
|
||||
|
||||
/* WP jQuery Dialog Theme */
|
||||
.wp-dialog {
|
||||
border: 1px solid #999;
|
||||
-moz-box-shadow: 0px 0px 16px rgba( 0,0,0,0.3 );
|
||||
-webkit-box-shadow: 0px 0px 16px rgba( 0,0,0,0.3 );
|
||||
box-shadow: 0px 0px 16px rgba( 0,0,0,0.3 );
|
||||
}
|
||||
.wp-dialog .ui-dialog-title {
|
||||
display: block;
|
||||
text-align: center;
|
||||
padding: 1px 0 2px;
|
||||
}
|
||||
.wp-dialog .ui-dialog-titlebar {
|
||||
padding: 0 1em;
|
||||
background-color: #444;
|
||||
font-weight: bold;
|
||||
font-size: 11px;
|
||||
line-height: 18px;
|
||||
color: #e5e5e5;
|
||||
}
|
||||
.wp-dialog {
|
||||
-moz-border-radius-topleft: 4px;
|
||||
-webkit-border-top-left-radius: 4px;
|
||||
-khtml-border-top-left-radius: 4px;
|
||||
border-top-left-radius: 4px;
|
||||
-moz-border-radius-topright: 4px;
|
||||
-webkit-border-top-right-radius: 4px;
|
||||
-khtml-border-top-right-radius: 4px;
|
||||
border-top-right-radius: 4px;
|
||||
}
|
||||
.wp-dialog .ui-dialog-titlebar {
|
||||
-moz-border-radius-topleft: 3px;
|
||||
-webkit-border-top-left-radius: 3px;
|
||||
-khtml-border-top-left-radius: 3px;
|
||||
border-top-left-radius: 3px;
|
||||
-moz-border-radius-topright: 3px;
|
||||
-webkit-border-top-right-radius: 3px;
|
||||
-khtml-border-top-right-radius: 3px;
|
||||
border-top-right-radius: 3px;
|
||||
}
|
||||
|
||||
.wp-dialog .ui-dialog-titlebar-close {
|
||||
position: absolute;
|
||||
width: 29px;
|
||||
height: 16px;
|
||||
top: 2px;
|
||||
right: 6px;
|
||||
background: url('../js/tinymce/plugins/inlinepopups/skins/clearlooks2/img/buttons.gif') no-repeat -87px -16px;
|
||||
padding: 0;
|
||||
}
|
||||
.wp-dialog .ui-dialog-titlebar-close:hover,
|
||||
.wp-dialog .ui-dialog-titlebar-close:focus {
|
||||
background-position: -87px -32px;
|
||||
}
|
||||
.ui-widget-overlay {
|
||||
background-color: #000;
|
||||
opacity: 0.6;
|
||||
filter: alpha(opacity=60);
|
||||
}
|
||||
@@ -0,0 +1,297 @@
|
||||
<?php
|
||||
/**
|
||||
* Defines constants and global variables that can be overridden, generally in wp-config.php.
|
||||
*
|
||||
* @package WordPress
|
||||
*/
|
||||
|
||||
/**
|
||||
* Defines initial WordPress constants
|
||||
*
|
||||
* @see wp_debug_mode()
|
||||
*
|
||||
* @since 3.0.0
|
||||
*/
|
||||
function wp_initial_constants( ) {
|
||||
global $blog_id;
|
||||
|
||||
// set memory limits
|
||||
if ( !defined('WP_MEMORY_LIMIT') ) {
|
||||
if( is_multisite() ) {
|
||||
define('WP_MEMORY_LIMIT', '64M');
|
||||
} else {
|
||||
define('WP_MEMORY_LIMIT', '32M');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The $blog_id global, which you can change in the config allows you to create a simple
|
||||
* multiple blog installation using just one WordPress and changing $blog_id around.
|
||||
*
|
||||
* @global int $blog_id
|
||||
* @since 2.0.0
|
||||
*/
|
||||
if ( ! isset($blog_id) )
|
||||
$blog_id = 1;
|
||||
|
||||
// set memory limits.
|
||||
if ( function_exists('memory_get_usage') && ( (int) @ini_get('memory_limit') < abs(intval(WP_MEMORY_LIMIT)) ) )
|
||||
@ini_set('memory_limit', WP_MEMORY_LIMIT);
|
||||
|
||||
if ( !defined('WP_CONTENT_DIR') )
|
||||
define( 'WP_CONTENT_DIR', ABSPATH . 'wp-content' ); // no trailing slash, full paths only - WP_CONTENT_URL is defined further down
|
||||
|
||||
// Add define('WP_DEBUG', true); to wp-config.php to enable display of notices during development.
|
||||
if ( !defined('WP_DEBUG') )
|
||||
define( 'WP_DEBUG', false );
|
||||
|
||||
// Add define('WP_DEBUG_DISPLAY', false); to wp-config.php use the globally configured setting for display_errors and not force errors to be displayed.
|
||||
if ( !defined('WP_DEBUG_DISPLAY') )
|
||||
define( 'WP_DEBUG_DISPLAY', true );
|
||||
|
||||
// Add define('WP_DEBUG_LOG', true); to enable error logging to wp-content/debug.log.
|
||||
if ( !defined('WP_DEBUG_LOG') )
|
||||
define('WP_DEBUG_LOG', false);
|
||||
|
||||
if ( !defined('WP_CACHE') )
|
||||
define('WP_CACHE', false);
|
||||
|
||||
/**
|
||||
* Private
|
||||
*/
|
||||
if ( !defined('MEDIA_TRASH') )
|
||||
define('MEDIA_TRASH', false);
|
||||
|
||||
if ( !defined('SHORTINIT') )
|
||||
define('SHORTINIT', false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines plugin directory WordPress constants
|
||||
*
|
||||
* Defines must-use plugin directory constants, which may be overridden in the sunrise.php drop-in
|
||||
*
|
||||
* @since 3.0.0
|
||||
*/
|
||||
function wp_plugin_directory_constants( ) {
|
||||
if ( !defined('WP_CONTENT_URL') )
|
||||
define( 'WP_CONTENT_URL', get_option('siteurl') . '/wp-content'); // full url - WP_CONTENT_DIR is defined further up
|
||||
|
||||
/**
|
||||
* Allows for the plugins directory to be moved from the default location.
|
||||
*
|
||||
* @since 2.6.0
|
||||
*/
|
||||
if ( !defined('WP_PLUGIN_DIR') )
|
||||
define( 'WP_PLUGIN_DIR', WP_CONTENT_DIR . '/plugins' ); // full path, no trailing slash
|
||||
|
||||
/**
|
||||
* Allows for the plugins directory to be moved from the default location.
|
||||
*
|
||||
* @since 2.6.0
|
||||
*/
|
||||
if ( !defined('WP_PLUGIN_URL') )
|
||||
define( 'WP_PLUGIN_URL', WP_CONTENT_URL . '/plugins' ); // full url, no trailing slash
|
||||
|
||||
/**
|
||||
* Allows for the plugins directory to be moved from the default location.
|
||||
*
|
||||
* @since 2.1.0
|
||||
* @deprecated
|
||||
*/
|
||||
if ( !defined('PLUGINDIR') )
|
||||
define( 'PLUGINDIR', 'wp-content/plugins' ); // Relative to ABSPATH. For back compat.
|
||||
|
||||
/**
|
||||
* Allows for the mu-plugins directory to be moved from the default location.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*/
|
||||
if ( !defined('WPMU_PLUGIN_DIR') )
|
||||
define( 'WPMU_PLUGIN_DIR', WP_CONTENT_DIR . '/mu-plugins' ); // full path, no trailing slash
|
||||
|
||||
/**
|
||||
* Allows for the mu-plugins directory to be moved from the default location.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*/
|
||||
if ( !defined('WPMU_PLUGIN_URL') )
|
||||
define( 'WPMU_PLUGIN_URL', WP_CONTENT_URL . '/mu-plugins' ); // full url, no trailing slash
|
||||
|
||||
/**
|
||||
* Allows for the mu-plugins directory to be moved from the default location.
|
||||
*
|
||||
* @since 2.8.0
|
||||
* @deprecated
|
||||
*/
|
||||
if ( !defined( 'MUPLUGINDIR' ) )
|
||||
define( 'MUPLUGINDIR', 'wp-content/mu-plugins' ); // Relative to ABSPATH. For back compat.
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines cookie related WordPress constants
|
||||
*
|
||||
* Defines constants after multisite is loaded. Cookie-related constants may be overridden in ms_network_cookies().
|
||||
* @since 3.0.0
|
||||
*/
|
||||
function wp_cookie_constants( ) {
|
||||
global $wp_default_secret_key;
|
||||
|
||||
/**
|
||||
* Used to guarantee unique hash cookies
|
||||
* @since 1.5
|
||||
*/
|
||||
if ( !defined( 'COOKIEHASH' ) ) {
|
||||
$siteurl = get_site_option( 'siteurl' );
|
||||
if ( $siteurl )
|
||||
define( 'COOKIEHASH', md5( $siteurl ) );
|
||||
else
|
||||
define( 'COOKIEHASH', '' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Should be exactly the same as the default value of SECRET_KEY in wp-config-sample.php
|
||||
* @since 2.5.0
|
||||
*/
|
||||
$wp_default_secret_key = 'put your unique phrase here';
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
*/
|
||||
if ( !defined('USER_COOKIE') )
|
||||
define('USER_COOKIE', 'wordpressuser_' . COOKIEHASH);
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
*/
|
||||
if ( !defined('PASS_COOKIE') )
|
||||
define('PASS_COOKIE', 'wordpresspass_' . COOKIEHASH);
|
||||
|
||||
/**
|
||||
* @since 2.5.0
|
||||
*/
|
||||
if ( !defined('AUTH_COOKIE') )
|
||||
define('AUTH_COOKIE', 'wordpress_' . COOKIEHASH);
|
||||
|
||||
/**
|
||||
* @since 2.6.0
|
||||
*/
|
||||
if ( !defined('SECURE_AUTH_COOKIE') )
|
||||
define('SECURE_AUTH_COOKIE', 'wordpress_sec_' . COOKIEHASH);
|
||||
|
||||
/**
|
||||
* @since 2.6.0
|
||||
*/
|
||||
if ( !defined('LOGGED_IN_COOKIE') )
|
||||
define('LOGGED_IN_COOKIE', 'wordpress_logged_in_' . COOKIEHASH);
|
||||
|
||||
/**
|
||||
* @since 2.3.0
|
||||
*/
|
||||
if ( !defined('TEST_COOKIE') )
|
||||
define('TEST_COOKIE', 'wordpress_test_cookie');
|
||||
|
||||
/**
|
||||
* @since 1.2.0
|
||||
*/
|
||||
if ( !defined('COOKIEPATH') )
|
||||
define('COOKIEPATH', preg_replace('|https?://[^/]+|i', '', get_option('home') . '/' ) );
|
||||
|
||||
/**
|
||||
* @since 1.5.0
|
||||
*/
|
||||
if ( !defined('SITECOOKIEPATH') )
|
||||
define('SITECOOKIEPATH', preg_replace('|https?://[^/]+|i', '', get_option('siteurl') . '/' ) );
|
||||
|
||||
/**
|
||||
* @since 2.6.0
|
||||
*/
|
||||
if ( !defined('ADMIN_COOKIE_PATH') )
|
||||
define( 'ADMIN_COOKIE_PATH', SITECOOKIEPATH . 'wp-admin' );
|
||||
|
||||
/**
|
||||
* @since 2.6.0
|
||||
*/
|
||||
if ( !defined('PLUGINS_COOKIE_PATH') )
|
||||
define( 'PLUGINS_COOKIE_PATH', preg_replace('|https?://[^/]+|i', '', WP_PLUGIN_URL) );
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
*/
|
||||
if ( !defined('COOKIE_DOMAIN') )
|
||||
define('COOKIE_DOMAIN', false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines cookie related WordPress constants
|
||||
*
|
||||
* @since 3.0.0
|
||||
*/
|
||||
function wp_ssl_constants( ) {
|
||||
/**
|
||||
* @since 2.6.0
|
||||
*/
|
||||
if ( !defined('FORCE_SSL_ADMIN') )
|
||||
define('FORCE_SSL_ADMIN', false);
|
||||
force_ssl_admin(FORCE_SSL_ADMIN);
|
||||
|
||||
/**
|
||||
* @since 2.6.0
|
||||
*/
|
||||
if ( !defined('FORCE_SSL_LOGIN') )
|
||||
define('FORCE_SSL_LOGIN', false);
|
||||
force_ssl_login(FORCE_SSL_LOGIN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines functionality related WordPress constants
|
||||
*
|
||||
* @since 3.0.0
|
||||
*/
|
||||
function wp_functionality_constants( ) {
|
||||
/**
|
||||
* @since 2.5.0
|
||||
*/
|
||||
if ( !defined( 'AUTOSAVE_INTERVAL' ) )
|
||||
define( 'AUTOSAVE_INTERVAL', 60 );
|
||||
|
||||
/**
|
||||
* @since 2.9.0
|
||||
*/
|
||||
if ( !defined( 'EMPTY_TRASH_DAYS' ) )
|
||||
define( 'EMPTY_TRASH_DAYS', 30 );
|
||||
|
||||
if ( !defined('WP_POST_REVISIONS') )
|
||||
define('WP_POST_REVISIONS', true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines templating related WordPress constants
|
||||
*
|
||||
* @since 3.0.0
|
||||
*/
|
||||
function wp_templating_constants( ) {
|
||||
/**
|
||||
* Web Path to the current active template directory
|
||||
* @since 1.5.0
|
||||
*/
|
||||
define('TEMPLATEPATH', get_template_directory());
|
||||
|
||||
/**
|
||||
* Web Path to the current active template stylesheet directory
|
||||
* @since 2.1.0
|
||||
*/
|
||||
define('STYLESHEETPATH', get_stylesheet_directory());
|
||||
|
||||
/**
|
||||
* Slug of the default theme for this install.
|
||||
* Used as the default theme when installing new sites.
|
||||
* Will be used as the fallback if the current theme doesn't exist.
|
||||
* @since 3.0.0
|
||||
*/
|
||||
if ( !defined('WP_DEFAULT_THEME') )
|
||||
define( 'WP_DEFAULT_THEME', 'twentyten' );
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Default Embed Handlers
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Embeds
|
||||
*/
|
||||
|
||||
/**
|
||||
* The Google Video embed handler callback. Google Video does not support oEmbed.
|
||||
*
|
||||
* @see WP_Embed::register_handler()
|
||||
* @see WP_Embed::shortcode()
|
||||
*
|
||||
* @param array $matches The regex matches from the provided regex when calling {@link wp_embed_register_handler()}.
|
||||
* @param array $attr Embed attributes.
|
||||
* @param string $url The original URL that was matched by the regex.
|
||||
* @param array $rawattr The original unmodified attributes.
|
||||
* @return string The embed HTML.
|
||||
*/
|
||||
function wp_embed_handler_googlevideo( $matches, $attr, $url, $rawattr ) {
|
||||
// If the user supplied a fixed width AND height, use it
|
||||
if ( !empty($rawattr['width']) && !empty($rawattr['height']) ) {
|
||||
$width = (int) $rawattr['width'];
|
||||
$height = (int) $rawattr['height'];
|
||||
} else {
|
||||
list( $width, $height ) = wp_expand_dimensions( 425, 344, $attr['width'], $attr['height'] );
|
||||
}
|
||||
|
||||
return apply_filters( 'embed_googlevideo', '<embed type="application/x-shockwave-flash" src="http://video.google.com/googleplayer.swf?docid=' . esc_attr($matches[2]) . '&hl=en&fs=true" style="width:' . esc_attr($width) . 'px;height:' . esc_attr($height) . 'px" allowFullScreen="true" allowScriptAccess="always" />', $matches, $attr, $url, $rawattr );
|
||||
}
|
||||
wp_embed_register_handler( 'googlevideo', '#http://video\.google\.([A-Za-z.]{2,5})/videoplay\?docid=([\d-]+)(.*?)#i', 'wp_embed_handler_googlevideo' );
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,278 @@
|
||||
<?php
|
||||
/**
|
||||
* Sets up the default filters and actions for most
|
||||
* of the WordPress hooks.
|
||||
*
|
||||
* If you need to remove a default hook, this file will
|
||||
* give you the priority for which to use to remove the
|
||||
* hook.
|
||||
*
|
||||
* Not all of the default hooks are found in default-filters.php
|
||||
*
|
||||
* @package WordPress
|
||||
*/
|
||||
|
||||
// Strip, trim, kses, special chars for string saves
|
||||
foreach ( array( 'pre_term_name', 'pre_comment_author_name', 'pre_link_name', 'pre_link_target', 'pre_link_rel', 'pre_user_display_name', 'pre_user_first_name', 'pre_user_last_name', 'pre_user_nickname' ) as $filter ) {
|
||||
add_filter( $filter, 'sanitize_text_field' );
|
||||
add_filter( $filter, 'wp_filter_kses' );
|
||||
add_filter( $filter, '_wp_specialchars', 30 );
|
||||
}
|
||||
|
||||
// Strip, kses, special chars for string display
|
||||
foreach ( array( 'term_name', 'comment_author_name', 'link_name', 'link_target', 'link_rel', 'user_display_name', 'user_first_name', 'user_last_name', 'user_nickname' ) as $filter ) {
|
||||
if ( is_admin() ) {
|
||||
// These are expensive. Run only on admin pages for defense in depth.
|
||||
add_filter( $filter, 'sanitize_text_field' );
|
||||
add_filter( $filter, 'wp_kses_data' );
|
||||
}
|
||||
add_filter( $filter, '_wp_specialchars', 30 );
|
||||
}
|
||||
|
||||
// Kses only for textarea saves
|
||||
foreach ( array( 'pre_term_description', 'pre_link_description', 'pre_link_notes', 'pre_user_description' ) as $filter ) {
|
||||
add_filter( $filter, 'wp_filter_kses' );
|
||||
}
|
||||
|
||||
// Kses only for textarea admin displays
|
||||
if ( is_admin() ) {
|
||||
foreach ( array( 'term_description', 'link_description', 'link_notes', 'user_description' ) as $filter ) {
|
||||
add_filter( $filter, 'wp_kses_data' );
|
||||
}
|
||||
add_filter( 'comment_text', 'wp_kses_post' );
|
||||
}
|
||||
|
||||
// Email saves
|
||||
foreach ( array( 'pre_comment_author_email', 'pre_user_email' ) as $filter ) {
|
||||
add_filter( $filter, 'trim' );
|
||||
add_filter( $filter, 'sanitize_email' );
|
||||
add_filter( $filter, 'wp_filter_kses' );
|
||||
}
|
||||
|
||||
// Email admin display
|
||||
foreach ( array( 'comment_author_email', 'user_email' ) as $filter ) {
|
||||
add_filter( $filter, 'sanitize_email' );
|
||||
if ( is_admin() )
|
||||
add_filter( $filter, 'wp_kses_data' );
|
||||
}
|
||||
|
||||
// Save URL
|
||||
foreach ( array( 'pre_comment_author_url', 'pre_user_url', 'pre_link_url', 'pre_link_image',
|
||||
'pre_link_rss' ) as $filter ) {
|
||||
add_filter( $filter, 'wp_strip_all_tags' );
|
||||
add_filter( $filter, 'esc_url_raw' );
|
||||
add_filter( $filter, 'wp_filter_kses' );
|
||||
}
|
||||
|
||||
// Display URL
|
||||
foreach ( array( 'user_url', 'link_url', 'link_image', 'link_rss', 'comment_url' ) as $filter ) {
|
||||
if ( is_admin() )
|
||||
add_filter( $filter, 'wp_strip_all_tags' );
|
||||
add_filter( $filter, 'esc_url' );
|
||||
if ( is_admin() )
|
||||
add_filter( $filter, 'wp_kses_data' );
|
||||
}
|
||||
|
||||
// Slugs
|
||||
foreach ( array( 'pre_term_slug' ) as $filter ) {
|
||||
add_filter( $filter, 'sanitize_title' );
|
||||
}
|
||||
|
||||
// Keys
|
||||
foreach ( array( 'pre_post_type' ) as $filter ) {
|
||||
add_filter( $filter, 'sanitize_user' );
|
||||
}
|
||||
foreach ( array( 'pre_post_status', 'pre_post_comment_status', 'pre_post_ping_status' ) as $filter ) {
|
||||
add_filter( $filter, 'sanitize_key' );
|
||||
}
|
||||
|
||||
// Places to balance tags on input
|
||||
foreach ( array( 'content_save_pre', 'excerpt_save_pre', 'comment_save_pre', 'pre_comment_content' ) as $filter ) {
|
||||
add_filter( $filter, 'balanceTags', 50 );
|
||||
}
|
||||
|
||||
// Format strings for display.
|
||||
foreach ( array( 'comment_author', 'term_name', 'link_name', 'link_description', 'link_notes', 'bloginfo', 'wp_title', 'widget_title' ) as $filter ) {
|
||||
add_filter( $filter, 'wptexturize' );
|
||||
add_filter( $filter, 'convert_chars' );
|
||||
add_filter( $filter, 'esc_html' );
|
||||
}
|
||||
|
||||
// Format WordPress
|
||||
foreach ( array( 'the_content', 'the_title' ) as $filter )
|
||||
add_filter( $filter, 'capital_P_dangit', 11 );
|
||||
add_filter( 'comment_text', 'capital_P_dangit', 31 );
|
||||
|
||||
// Format titles
|
||||
foreach ( array( 'single_post_title', 'single_cat_title', 'single_tag_title', 'single_month_title', 'nav_menu_attr_title', 'nav_menu_description' ) as $filter ) {
|
||||
add_filter( $filter, 'wptexturize' );
|
||||
add_filter( $filter, 'strip_tags' );
|
||||
}
|
||||
|
||||
// Format text area for display.
|
||||
foreach ( array( 'term_description' ) as $filter ) {
|
||||
add_filter( $filter, 'wptexturize' );
|
||||
add_filter( $filter, 'convert_chars' );
|
||||
add_filter( $filter, 'wpautop' );
|
||||
add_filter( $filter, 'shortcode_unautop');
|
||||
}
|
||||
|
||||
// Format for RSS
|
||||
foreach ( array( 'term_name_rss' ) as $filter ) {
|
||||
add_filter( $filter, 'convert_chars' );
|
||||
}
|
||||
|
||||
// Pre save hierarchy
|
||||
add_filter( 'wp_insert_post_parent', 'wp_check_post_hierarchy_for_loops', 10, 2 );
|
||||
add_filter( 'wp_update_term_parent', 'wp_check_term_hierarchy_for_loops', 10, 3 );
|
||||
|
||||
// Display filters
|
||||
add_filter( 'the_title', 'wptexturize' );
|
||||
add_filter( 'the_title', 'convert_chars' );
|
||||
add_filter( 'the_title', 'trim' );
|
||||
|
||||
add_filter( 'the_content', 'wptexturize' );
|
||||
add_filter( 'the_content', 'convert_smilies' );
|
||||
add_filter( 'the_content', 'convert_chars' );
|
||||
add_filter( 'the_content', 'wpautop' );
|
||||
add_filter( 'the_content', 'shortcode_unautop' );
|
||||
add_filter( 'the_content', 'prepend_attachment' );
|
||||
|
||||
add_filter( 'the_excerpt', 'wptexturize' );
|
||||
add_filter( 'the_excerpt', 'convert_smilies' );
|
||||
add_filter( 'the_excerpt', 'convert_chars' );
|
||||
add_filter( 'the_excerpt', 'wpautop' );
|
||||
add_filter( 'the_excerpt', 'shortcode_unautop');
|
||||
add_filter( 'get_the_excerpt', 'wp_trim_excerpt' );
|
||||
|
||||
add_filter( 'comment_text', 'wptexturize' );
|
||||
add_filter( 'comment_text', 'convert_chars' );
|
||||
add_filter( 'comment_text', 'make_clickable', 9 );
|
||||
add_filter( 'comment_text', 'force_balance_tags', 25 );
|
||||
add_filter( 'comment_text', 'convert_smilies', 20 );
|
||||
add_filter( 'comment_text', 'wpautop', 30 );
|
||||
|
||||
add_filter( 'comment_excerpt', 'convert_chars' );
|
||||
|
||||
add_filter( 'list_cats', 'wptexturize' );
|
||||
|
||||
add_filter( 'wp_sprintf', 'wp_sprintf_l', 10, 2 );
|
||||
|
||||
// RSS filters
|
||||
add_filter( 'the_title_rss', 'strip_tags' );
|
||||
add_filter( 'the_title_rss', 'ent2ncr', 8 );
|
||||
add_filter( 'the_title_rss', 'esc_html' );
|
||||
add_filter( 'the_content_rss', 'ent2ncr', 8 );
|
||||
add_filter( 'the_excerpt_rss', 'convert_chars' );
|
||||
add_filter( 'the_excerpt_rss', 'ent2ncr', 8 );
|
||||
add_filter( 'comment_author_rss', 'ent2ncr', 8 );
|
||||
add_filter( 'comment_text_rss', 'ent2ncr', 8 );
|
||||
add_filter( 'comment_text_rss', 'esc_html' );
|
||||
add_filter( 'bloginfo_rss', 'ent2ncr', 8 );
|
||||
add_filter( 'the_author', 'ent2ncr', 8 );
|
||||
|
||||
// Misc filters
|
||||
add_filter( 'option_ping_sites', 'privacy_ping_filter' );
|
||||
add_filter( 'option_blog_charset', '_wp_specialchars' ); // IMPORTANT: This must not be wp_specialchars() or esc_html() or it'll cause an infinite loop
|
||||
add_filter( 'option_home', '_config_wp_home' );
|
||||
add_filter( 'option_siteurl', '_config_wp_siteurl' );
|
||||
add_filter( 'tiny_mce_before_init', '_mce_set_direction' );
|
||||
add_filter( 'pre_kses', 'wp_pre_kses_less_than' );
|
||||
add_filter( 'sanitize_title', 'sanitize_title_with_dashes' );
|
||||
add_action( 'check_comment_flood', 'check_comment_flood_db', 10, 3 );
|
||||
add_filter( 'comment_flood_filter', 'wp_throttle_comment_flood', 10, 3 );
|
||||
add_filter( 'pre_comment_content', 'wp_rel_nofollow', 15 );
|
||||
add_filter( 'comment_email', 'antispambot' );
|
||||
add_filter( 'option_tag_base', '_wp_filter_taxonomy_base' );
|
||||
add_filter( 'option_category_base', '_wp_filter_taxonomy_base' );
|
||||
add_filter( 'the_posts', '_close_comments_for_old_posts' );
|
||||
add_filter( 'comments_open', '_close_comments_for_old_post', 10, 2 );
|
||||
add_filter( 'pings_open', '_close_comments_for_old_post', 10, 2 );
|
||||
add_filter( 'editable_slug', 'urldecode' );
|
||||
add_filter( 'nav_menu_meta_box_object', '_wp_nav_menu_meta_box_object' );
|
||||
|
||||
// Atom SSL support
|
||||
add_filter( 'atom_service_url','atom_service_url_filter' );
|
||||
|
||||
// Actions
|
||||
add_action( 'wp_head', 'wp_enqueue_scripts', 1 );
|
||||
add_action( 'wp_head', 'feed_links', 2 );
|
||||
add_action( 'wp_head', 'feed_links_extra', 3 );
|
||||
add_action( 'wp_head', 'rsd_link' );
|
||||
add_action( 'wp_head', 'wlwmanifest_link' );
|
||||
add_action( 'wp_head', 'index_rel_link' );
|
||||
add_action( 'wp_head', 'parent_post_rel_link', 10, 0 );
|
||||
add_action( 'wp_head', 'start_post_rel_link', 10, 0 );
|
||||
add_action( 'wp_head', 'adjacent_posts_rel_link_wp_head', 10, 0 );
|
||||
add_action( 'wp_head', 'locale_stylesheet' );
|
||||
add_action( 'publish_future_post', 'check_and_publish_future_post', 10, 1 );
|
||||
add_action( 'wp_head', 'noindex', 1 );
|
||||
add_action( 'wp_head', 'wp_print_styles', 8 );
|
||||
add_action( 'wp_head', 'wp_print_head_scripts', 9 );
|
||||
add_action( 'wp_head', 'wp_generator' );
|
||||
add_action( 'wp_head', 'rel_canonical' );
|
||||
add_action( 'wp_footer', 'wp_print_footer_scripts' );
|
||||
add_action( 'wp_head', 'wp_shortlink_wp_head', 10, 0 );
|
||||
add_action( 'template_redirect', 'wp_shortlink_header', 11, 0 );
|
||||
|
||||
// Login actions
|
||||
add_action( 'login_head', 'wp_print_head_scripts', 9 );
|
||||
add_action( 'login_footer', 'wp_print_footer_scripts' );
|
||||
|
||||
// Feed Generator Tags
|
||||
foreach ( array( 'rss2_head', 'commentsrss2_head', 'rss_head', 'rdf_header', 'atom_head', 'comments_atom_head', 'opml_head', 'app_head' ) as $action ) {
|
||||
add_action( $action, 'the_generator' );
|
||||
}
|
||||
|
||||
// WP Cron
|
||||
if ( !defined( 'DOING_CRON' ) )
|
||||
add_action( 'sanitize_comment_cookies', 'wp_cron' );
|
||||
|
||||
// 2 Actions 2 Furious
|
||||
add_action( 'do_feed_rdf', 'do_feed_rdf', 10, 1 );
|
||||
add_action( 'do_feed_rss', 'do_feed_rss', 10, 1 );
|
||||
add_action( 'do_feed_rss2', 'do_feed_rss2', 10, 1 );
|
||||
add_action( 'do_feed_atom', 'do_feed_atom', 10, 1 );
|
||||
add_action( 'do_pings', 'do_all_pings', 10, 1 );
|
||||
add_action( 'do_robots', 'do_robots' );
|
||||
add_action( 'sanitize_comment_cookies', 'sanitize_comment_cookies' );
|
||||
add_action( 'admin_print_scripts', 'print_head_scripts', 20 );
|
||||
add_action( 'admin_print_footer_scripts', 'print_footer_scripts', 20 );
|
||||
add_action( 'admin_print_styles', 'print_admin_styles', 20 );
|
||||
add_action( 'init', 'smilies_init', 5 );
|
||||
add_action( 'plugins_loaded', 'wp_maybe_load_widgets', 0 );
|
||||
add_action( 'plugins_loaded', 'wp_maybe_load_embeds', 0 );
|
||||
add_action( 'shutdown', 'wp_ob_end_flush_all', 1 );
|
||||
add_action( 'pre_post_update', 'wp_save_post_revision' );
|
||||
add_action( 'publish_post', '_publish_post_hook', 5, 1 );
|
||||
add_action( 'save_post', '_save_post_hook', 5, 2 );
|
||||
add_action( 'transition_post_status', '_transition_post_status', 5, 3 );
|
||||
add_action( 'comment_form', 'wp_comment_form_unfiltered_html_nonce' );
|
||||
add_action( 'wp_scheduled_delete', 'wp_scheduled_delete' );
|
||||
|
||||
// Navigation menu actions
|
||||
add_action( 'delete_post', '_wp_delete_post_menu_item' );
|
||||
add_action( 'delete_term', '_wp_delete_tax_menu_item' );
|
||||
add_action( 'transition_post_status', '_wp_auto_add_pages_to_menu', 10, 3 );
|
||||
|
||||
// Post Thumbnail CSS class filtering
|
||||
add_action( 'begin_fetch_post_thumbnail_html', '_wp_post_thumbnail_class_filter_add' );
|
||||
add_action( 'end_fetch_post_thumbnail_html', '_wp_post_thumbnail_class_filter_remove' );
|
||||
|
||||
// Redirect Old Slugs
|
||||
add_action( 'template_redirect', 'wp_old_slug_redirect' );
|
||||
add_action( 'post_updated', 'wp_check_for_changed_slugs', 12, 3 );
|
||||
|
||||
// Nonce check for Post Previews
|
||||
add_action( 'init', '_show_post_preview' );
|
||||
|
||||
// Timezone
|
||||
add_filter( 'pre_option_gmt_offset','wp_timezone_override_offset' );
|
||||
|
||||
// Admin Color Schemes
|
||||
add_action( 'admin_init', 'register_admin_color_schemes', 1);
|
||||
add_action( 'admin_color_scheme_picker', 'admin_color_scheme_picker' );
|
||||
|
||||
unset($filter, $action);
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
/**
|
||||
* Atom Feed Template for displaying Atom Comments feed.
|
||||
*
|
||||
* @package WordPress
|
||||
*/
|
||||
|
||||
header('Content-Type: ' . feed_content_type('atom') . '; charset=' . get_option('blog_charset'), true);
|
||||
echo '<?xml version="1.0" encoding="' . get_option('blog_charset') . '" ?' . '>';
|
||||
?>
|
||||
<feed
|
||||
xmlns="http://www.w3.org/2005/Atom"
|
||||
xml:lang="<?php echo get_option('rss_language'); ?>"
|
||||
xmlns:thr="http://purl.org/syndication/thread/1.0"
|
||||
<?php do_action('atom_ns'); do_action('atom_comments_ns'); ?>
|
||||
>
|
||||
<title type="text"><?php
|
||||
if ( is_singular() )
|
||||
printf(ent2ncr(__('Comments on %s')), get_the_title_rss());
|
||||
elseif ( is_search() )
|
||||
printf(ent2ncr(__('Comments for %1$s searching on %2$s')), get_bloginfo_rss( 'name' ), get_search_query() );
|
||||
else
|
||||
printf(ent2ncr(__('Comments for %s')), get_bloginfo_rss( 'name' ) . get_wp_title_rss());
|
||||
?></title>
|
||||
<subtitle type="text"><?php bloginfo_rss('description'); ?></subtitle>
|
||||
|
||||
<updated><?php echo mysql2date('Y-m-d\TH:i:s\Z', get_lastcommentmodified('GMT'), false); ?></updated>
|
||||
|
||||
<?php if ( is_singular() ) { ?>
|
||||
<link rel="alternate" type="<?php bloginfo_rss('html_type'); ?>" href="<?php comments_link_feed(); ?>" />
|
||||
<link rel="self" type="application/atom+xml" href="<?php echo get_post_comments_feed_link('', 'atom'); ?>" />
|
||||
<id><?php echo get_post_comments_feed_link('', 'atom'); ?></id>
|
||||
<?php } elseif(is_search()) { ?>
|
||||
<link rel="alternate" type="<?php bloginfo_rss('html_type'); ?>" href="<?php echo home_url() . '?s=' . get_search_query(); ?>" />
|
||||
<link rel="self" type="application/atom+xml" href="<?php echo get_search_comments_feed_link('', 'atom'); ?>" />
|
||||
<id><?php echo get_search_comments_feed_link('', 'atom'); ?></id>
|
||||
<?php } else { ?>
|
||||
<link rel="alternate" type="<?php bloginfo_rss('html_type'); ?>" href="<?php bloginfo_rss('url'); ?>" />
|
||||
<link rel="self" type="application/atom+xml" href="<?php bloginfo_rss('comments_atom_url'); ?>" />
|
||||
<id><?php bloginfo_rss('comments_atom_url'); ?></id>
|
||||
<?php } ?>
|
||||
<?php do_action('comments_atom_head'); ?>
|
||||
<?php
|
||||
if ( have_comments() ) : while ( have_comments() ) : the_comment();
|
||||
$comment_post = get_post($comment->comment_post_ID);
|
||||
get_post_custom($comment_post->ID);
|
||||
?>
|
||||
<entry>
|
||||
<title><?php
|
||||
if ( !is_singular() ) {
|
||||
$title = get_the_title($comment_post->ID);
|
||||
$title = apply_filters('the_title_rss', $title);
|
||||
printf(ent2ncr(__('Comment on %1$s by %2$s')), $title, get_comment_author_rss());
|
||||
} else {
|
||||
printf(ent2ncr(__('By: %s')), get_comment_author_rss());
|
||||
}
|
||||
?></title>
|
||||
<link rel="alternate" href="<?php comment_link(); ?>" type="<?php bloginfo_rss('html_type'); ?>" />
|
||||
|
||||
<author>
|
||||
<name><?php comment_author_rss(); ?></name>
|
||||
<?php if (get_comment_author_url()) echo '<uri>' . get_comment_author_url() . '</uri>'; ?>
|
||||
|
||||
</author>
|
||||
|
||||
<id><?php comment_guid(); ?></id>
|
||||
<updated><?php echo mysql2date('Y-m-d\TH:i:s\Z', get_comment_time('Y-m-d H:i:s', true, false), false); ?></updated>
|
||||
<published><?php echo mysql2date('Y-m-d\TH:i:s\Z', get_comment_time('Y-m-d H:i:s', true, false), false); ?></published>
|
||||
<?php if ( post_password_required($comment_post) ) : ?>
|
||||
<content type="html" xml:base="<?php comment_link(); ?>"><![CDATA[<?php echo get_the_password_form(); ?>]]></content>
|
||||
<?php else : // post pass ?>
|
||||
<content type="html" xml:base="<?php comment_link(); ?>"><![CDATA[<?php comment_text(); ?>]]></content>
|
||||
<?php endif; // post pass
|
||||
// Return comment threading information (http://www.ietf.org/rfc/rfc4685.txt)
|
||||
if ( $comment->comment_parent == 0 ) : // This comment is top level ?>
|
||||
<thr:in-reply-to ref="<?php the_guid(); ?>" href="<?php the_permalink_rss() ?>" type="<?php bloginfo_rss('html_type'); ?>" />
|
||||
<?php else : // This comment is in reply to another comment
|
||||
$parent_comment = get_comment($comment->comment_parent);
|
||||
// The rel attribute below and the id tag above should be GUIDs, but WP doesn't create them for comments (unlike posts). Either way, its more important that they both use the same system
|
||||
?>
|
||||
<thr:in-reply-to ref="<?php comment_guid($parent_comment) ?>" href="<?php echo get_comment_link($parent_comment) ?>" type="<?php bloginfo_rss('html_type'); ?>" />
|
||||
<?php endif;
|
||||
do_action('comment_atom_entry', $comment->comment_ID, $comment_post->ID);
|
||||
?>
|
||||
</entry>
|
||||
<?php endwhile; endif; ?>
|
||||
</feed>
|
||||
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
/**
|
||||
* Atom Feed Template for displaying Atom Posts feed.
|
||||
*
|
||||
* @package WordPress
|
||||
*/
|
||||
|
||||
header('Content-Type: ' . feed_content_type('atom') . '; charset=' . get_option('blog_charset'), true);
|
||||
$more = 1;
|
||||
|
||||
echo '<?xml version="1.0" encoding="'.get_option('blog_charset').'"?'.'>'; ?>
|
||||
<feed
|
||||
xmlns="http://www.w3.org/2005/Atom"
|
||||
xmlns:thr="http://purl.org/syndication/thread/1.0"
|
||||
xml:lang="<?php echo get_option('rss_language'); ?>"
|
||||
xml:base="<?php bloginfo_rss('url') ?>/wp-atom.php"
|
||||
<?php do_action('atom_ns'); ?>
|
||||
>
|
||||
<title type="text"><?php bloginfo_rss('name'); wp_title_rss(); ?></title>
|
||||
<subtitle type="text"><?php bloginfo_rss("description") ?></subtitle>
|
||||
|
||||
<updated><?php echo mysql2date('Y-m-d\TH:i:s\Z', get_lastpostmodified('GMT'), false); ?></updated>
|
||||
|
||||
<link rel="alternate" type="text/html" href="<?php bloginfo_rss('url') ?>" />
|
||||
<id><?php bloginfo('atom_url'); ?></id>
|
||||
<link rel="self" type="application/atom+xml" href="<?php self_link(); ?>" />
|
||||
|
||||
<?php do_action('atom_head'); ?>
|
||||
<?php while (have_posts()) : the_post(); ?>
|
||||
<entry>
|
||||
<author>
|
||||
<name><?php the_author() ?></name>
|
||||
<?php $author_url = get_the_author_meta('url'); if ( !empty($author_url) ) : ?>
|
||||
<uri><?php the_author_meta('url')?></uri>
|
||||
<?php endif; ?>
|
||||
</author>
|
||||
<title type="<?php html_type_rss(); ?>"><![CDATA[<?php the_title_rss() ?>]]></title>
|
||||
<link rel="alternate" type="text/html" href="<?php the_permalink_rss() ?>" />
|
||||
<id><?php the_guid() ; ?></id>
|
||||
<updated><?php echo get_post_modified_time('Y-m-d\TH:i:s\Z', true); ?></updated>
|
||||
<published><?php echo get_post_time('Y-m-d\TH:i:s\Z', true); ?></published>
|
||||
<?php the_category_rss('atom') ?>
|
||||
<summary type="<?php html_type_rss(); ?>"><![CDATA[<?php the_excerpt_rss(); ?>]]></summary>
|
||||
<?php if ( !get_option('rss_use_excerpt') ) : ?>
|
||||
<content type="<?php html_type_rss(); ?>" xml:base="<?php the_permalink_rss() ?>"><![CDATA[<?php the_content_feed('atom') ?>]]></content>
|
||||
<?php endif; ?>
|
||||
<?php atom_enclosure(); ?>
|
||||
<?php do_action('atom_entry'); ?>
|
||||
<link rel="replies" type="text/html" href="<?php the_permalink_rss() ?>#comments" thr:count="<?php echo get_comments_number()?>"/>
|
||||
<link rel="replies" type="application/atom+xml" href="<?php echo get_post_comments_feed_link(0,'atom') ?>" thr:count="<?php echo get_comments_number()?>"/>
|
||||
<thr:total><?php echo get_comments_number()?></thr:total>
|
||||
</entry>
|
||||
<?php endwhile ; ?>
|
||||
</feed>
|
||||
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
/**
|
||||
* RSS 1 RDF Feed Template for displaying RSS 1 Posts feed.
|
||||
*
|
||||
* @package WordPress
|
||||
*/
|
||||
|
||||
header('Content-Type: ' . feed_content_type('rdf') . '; charset=' . get_option('blog_charset'), true);
|
||||
$more = 1;
|
||||
|
||||
echo '<?xml version="1.0" encoding="'.get_option('blog_charset').'"?'.'>'; ?>
|
||||
<rdf:RDF
|
||||
xmlns="http://purl.org/rss/1.0/"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
|
||||
xmlns:admin="http://webns.net/mvcb/"
|
||||
xmlns:content="http://purl.org/rss/1.0/modules/content/"
|
||||
<?php do_action('rdf_ns'); ?>
|
||||
>
|
||||
<channel rdf:about="<?php bloginfo_rss("url") ?>">
|
||||
<title><?php bloginfo_rss('name'); wp_title_rss(); ?></title>
|
||||
<link><?php bloginfo_rss('url') ?></link>
|
||||
<description><?php bloginfo_rss('description') ?></description>
|
||||
<dc:date><?php echo mysql2date('Y-m-d\TH:i:s\Z', get_lastpostmodified('GMT'), false); ?></dc:date>
|
||||
<sy:updatePeriod><?php echo apply_filters( 'rss_update_period', 'hourly' ); ?></sy:updatePeriod>
|
||||
<sy:updateFrequency><?php echo apply_filters( 'rss_update_frequency', '1' ); ?></sy:updateFrequency>
|
||||
<sy:updateBase>2000-01-01T12:00+00:00</sy:updateBase>
|
||||
<?php do_action('rdf_header'); ?>
|
||||
<items>
|
||||
<rdf:Seq>
|
||||
<?php while (have_posts()): the_post(); ?>
|
||||
<rdf:li rdf:resource="<?php the_permalink_rss() ?>"/>
|
||||
<?php endwhile; ?>
|
||||
</rdf:Seq>
|
||||
</items>
|
||||
</channel>
|
||||
<?php rewind_posts(); while (have_posts()): the_post(); ?>
|
||||
<item rdf:about="<?php the_permalink_rss() ?>">
|
||||
<title><?php the_title_rss() ?></title>
|
||||
<link><?php the_permalink_rss() ?></link>
|
||||
<dc:date><?php echo mysql2date('Y-m-d\TH:i:s\Z', $post->post_date_gmt, false); ?></dc:date>
|
||||
<dc:creator><?php the_author() ?></dc:creator>
|
||||
<?php the_category_rss('rdf') ?>
|
||||
<?php if (get_option('rss_use_excerpt')) : ?>
|
||||
<description><?php the_excerpt_rss() ?></description>
|
||||
<?php else : ?>
|
||||
<description><?php the_excerpt_rss() ?></description>
|
||||
<content:encoded><![CDATA[<?php the_content_feed('rdf') ?>]]></content:encoded>
|
||||
<?php endif; ?>
|
||||
<?php do_action('rdf_item'); ?>
|
||||
</item>
|
||||
<?php endwhile; ?>
|
||||
</rdf:RDF>
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
/**
|
||||
* RSS 0.92 Feed Template for displaying RSS 0.92 Posts feed.
|
||||
*
|
||||
* @package WordPress
|
||||
*/
|
||||
|
||||
header('Content-Type: ' . feed_content_type('rss-http') . '; charset=' . get_option('blog_charset'), true);
|
||||
$more = 1;
|
||||
|
||||
echo '<?xml version="1.0" encoding="'.get_option('blog_charset').'"?'.'>'; ?>
|
||||
<rss version="0.92">
|
||||
<channel>
|
||||
<title><?php bloginfo_rss('name'); wp_title_rss(); ?></title>
|
||||
<link><?php bloginfo_rss('url') ?></link>
|
||||
<description><?php bloginfo_rss('description') ?></description>
|
||||
<lastBuildDate><?php echo mysql2date('D, d M Y H:i:s +0000', get_lastpostmodified('GMT'), false); ?></lastBuildDate>
|
||||
<docs>http://backend.userland.com/rss092</docs>
|
||||
<language><?php echo get_option('rss_language'); ?></language>
|
||||
<?php do_action('rss_head'); ?>
|
||||
|
||||
<?php while (have_posts()) : the_post(); ?>
|
||||
<item>
|
||||
<title><?php the_title_rss() ?></title>
|
||||
<description><![CDATA[<?php the_excerpt_rss() ?>]]></description>
|
||||
<link><?php the_permalink_rss() ?></link>
|
||||
<?php do_action('rss_item'); ?>
|
||||
</item>
|
||||
<?php endwhile; ?>
|
||||
</channel>
|
||||
</rss>
|
||||
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
/**
|
||||
* RSS2 Feed Template for displaying RSS2 Comments feed.
|
||||
*
|
||||
* @package WordPress
|
||||
*/
|
||||
|
||||
header('Content-Type: ' . feed_content_type('rss-http') . '; charset=' . get_option('blog_charset'), true);
|
||||
|
||||
echo '<?xml version="1.0" encoding="'.get_option('blog_charset').'"?'.'>';
|
||||
?>
|
||||
<rss version="2.0"
|
||||
xmlns:content="http://purl.org/rss/1.0/modules/content/"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:atom="http://www.w3.org/2005/Atom"
|
||||
xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
|
||||
<?php do_action('rss2_ns'); do_action('rss2_comments_ns'); ?>
|
||||
>
|
||||
<channel>
|
||||
<title><?php
|
||||
if ( is_singular() )
|
||||
printf(ent2ncr(__('Comments on: %s')), get_the_title_rss());
|
||||
elseif ( is_search() )
|
||||
printf(ent2ncr(__('Comments for %s searching on %s')), get_bloginfo_rss( 'name' ), esc_attr($wp_query->query_vars['s']));
|
||||
else
|
||||
printf(ent2ncr(__('Comments for %s')), get_bloginfo_rss( 'name' ) . get_wp_title_rss());
|
||||
?></title>
|
||||
<atom:link href="<?php self_link(); ?>" rel="self" type="application/rss+xml" />
|
||||
<link><?php (is_single()) ? the_permalink_rss() : bloginfo_rss("url") ?></link>
|
||||
<description><?php bloginfo_rss("description") ?></description>
|
||||
<lastBuildDate><?php echo mysql2date('r', get_lastcommentmodified('GMT')); ?></lastBuildDate>
|
||||
<sy:updatePeriod><?php echo apply_filters( 'rss_update_period', 'hourly' ); ?></sy:updatePeriod>
|
||||
<sy:updateFrequency><?php echo apply_filters( 'rss_update_frequency', '1' ); ?></sy:updateFrequency>
|
||||
<?php do_action('commentsrss2_head'); ?>
|
||||
<?php
|
||||
if ( have_comments() ) : while ( have_comments() ) : the_comment();
|
||||
$comment_post = get_post($comment->comment_post_ID);
|
||||
get_post_custom($comment_post->ID);
|
||||
?>
|
||||
<item>
|
||||
<title><?php
|
||||
if ( !is_singular() ) {
|
||||
$title = get_the_title($comment_post->ID);
|
||||
$title = apply_filters('the_title_rss', $title);
|
||||
printf(ent2ncr(__('Comment on %1$s by %2$s')), $title, get_comment_author_rss());
|
||||
} else {
|
||||
printf(ent2ncr(__('By: %s')), get_comment_author_rss());
|
||||
}
|
||||
?></title>
|
||||
<link><?php comment_link() ?></link>
|
||||
<dc:creator><?php echo get_comment_author_rss() ?></dc:creator>
|
||||
<pubDate><?php echo mysql2date('D, d M Y H:i:s +0000', get_comment_time('Y-m-d H:i:s', true, false), false); ?></pubDate>
|
||||
<guid isPermaLink="false"><?php comment_guid() ?></guid>
|
||||
<?php if ( post_password_required($comment_post) ) : ?>
|
||||
<description><?php echo ent2ncr(__('Protected Comments: Please enter your password to view comments.')); ?></description>
|
||||
<content:encoded><![CDATA[<?php echo get_the_password_form() ?>]]></content:encoded>
|
||||
<?php else : // post pass ?>
|
||||
<description><?php comment_text_rss() ?></description>
|
||||
<content:encoded><![CDATA[<?php comment_text() ?>]]></content:encoded>
|
||||
<?php endif; // post pass
|
||||
do_action('commentrss2_item', $comment->comment_ID, $comment_post->ID);
|
||||
?>
|
||||
</item>
|
||||
<?php endwhile; endif; ?>
|
||||
</channel>
|
||||
</rss>
|
||||
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
/**
|
||||
* RSS2 Feed Template for displaying RSS2 Posts feed.
|
||||
*
|
||||
* @package WordPress
|
||||
*/
|
||||
|
||||
header('Content-Type: ' . feed_content_type('rss-http') . '; charset=' . get_option('blog_charset'), true);
|
||||
$more = 1;
|
||||
|
||||
echo '<?xml version="1.0" encoding="'.get_option('blog_charset').'"?'.'>'; ?>
|
||||
|
||||
<rss version="2.0"
|
||||
xmlns:content="http://purl.org/rss/1.0/modules/content/"
|
||||
xmlns:wfw="http://wellformedweb.org/CommentAPI/"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:atom="http://www.w3.org/2005/Atom"
|
||||
xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
|
||||
xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
|
||||
<?php do_action('rss2_ns'); ?>
|
||||
>
|
||||
|
||||
<channel>
|
||||
<title><?php bloginfo_rss('name'); wp_title_rss(); ?></title>
|
||||
<atom:link href="<?php self_link(); ?>" rel="self" type="application/rss+xml" />
|
||||
<link><?php bloginfo_rss('url') ?></link>
|
||||
<description><?php bloginfo_rss("description") ?></description>
|
||||
<lastBuildDate><?php echo mysql2date('D, d M Y H:i:s +0000', get_lastpostmodified('GMT'), false); ?></lastBuildDate>
|
||||
<language><?php echo get_option('rss_language'); ?></language>
|
||||
<sy:updatePeriod><?php echo apply_filters( 'rss_update_period', 'hourly' ); ?></sy:updatePeriod>
|
||||
<sy:updateFrequency><?php echo apply_filters( 'rss_update_frequency', '1' ); ?></sy:updateFrequency>
|
||||
<?php do_action('rss2_head'); ?>
|
||||
<?php while( have_posts()) : the_post(); ?>
|
||||
<item>
|
||||
<title><?php the_title_rss() ?></title>
|
||||
<link><?php the_permalink_rss() ?></link>
|
||||
<comments><?php comments_link_feed(); ?></comments>
|
||||
<pubDate><?php echo mysql2date('D, d M Y H:i:s +0000', get_post_time('Y-m-d H:i:s', true), false); ?></pubDate>
|
||||
<dc:creator><?php the_author() ?></dc:creator>
|
||||
<?php the_category_rss('rss2') ?>
|
||||
|
||||
<guid isPermaLink="false"><?php the_guid(); ?></guid>
|
||||
<?php if (get_option('rss_use_excerpt')) : ?>
|
||||
<description><![CDATA[<?php the_excerpt_rss() ?>]]></description>
|
||||
<?php else : ?>
|
||||
<description><![CDATA[<?php the_excerpt_rss() ?>]]></description>
|
||||
<?php if ( strlen( $post->post_content ) > 0 ) : ?>
|
||||
<content:encoded><![CDATA[<?php the_content_feed('rss2') ?>]]></content:encoded>
|
||||
<?php else : ?>
|
||||
<content:encoded><![CDATA[<?php the_excerpt_rss() ?>]]></content:encoded>
|
||||
<?php endif; ?>
|
||||
<?php endif; ?>
|
||||
<wfw:commentRss><?php echo esc_url( get_post_comments_feed_link(null, 'rss2') ); ?></wfw:commentRss>
|
||||
<slash:comments><?php echo get_comments_number(); ?></slash:comments>
|
||||
<?php rss_enclosure(); ?>
|
||||
<?php do_action('rss2_item'); ?>
|
||||
</item>
|
||||
<?php endwhile; ?>
|
||||
</channel>
|
||||
</rss>
|
||||
@@ -0,0 +1,546 @@
|
||||
<?php
|
||||
/**
|
||||
* WordPress Feed API
|
||||
*
|
||||
* Many of the functions used in here belong in The Loop, or The Loop for the
|
||||
* Feeds.
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Feed
|
||||
*/
|
||||
|
||||
/**
|
||||
* RSS container for the bloginfo function.
|
||||
*
|
||||
* You can retrieve anything that you can using the get_bloginfo() function.
|
||||
* Everything will be stripped of tags and characters converted, when the values
|
||||
* are retrieved for use in the feeds.
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Feed
|
||||
* @since 1.5.1
|
||||
* @uses apply_filters() Calls 'get_bloginfo_rss' hook with two parameters.
|
||||
* @see get_bloginfo() For the list of possible values to display.
|
||||
*
|
||||
* @param string $show See get_bloginfo() for possible values.
|
||||
* @return string
|
||||
*/
|
||||
function get_bloginfo_rss($show = '') {
|
||||
$info = strip_tags(get_bloginfo($show));
|
||||
return apply_filters('get_bloginfo_rss', convert_chars($info), $show);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display RSS container for the bloginfo function.
|
||||
*
|
||||
* You can retrieve anything that you can using the get_bloginfo() function.
|
||||
* Everything will be stripped of tags and characters converted, when the values
|
||||
* are retrieved for use in the feeds.
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Feed
|
||||
* @since 0.71
|
||||
* @uses apply_filters() Calls 'bloginfo_rss' hook with two parameters.
|
||||
* @see get_bloginfo() For the list of possible values to display.
|
||||
*
|
||||
* @param string $show See get_bloginfo() for possible values.
|
||||
*/
|
||||
function bloginfo_rss($show = '') {
|
||||
echo apply_filters('bloginfo_rss', get_bloginfo_rss($show), $show);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the default feed.
|
||||
*
|
||||
* The default feed is 'rss2', unless a plugin changes it through the
|
||||
* 'default_feed' filter.
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Feed
|
||||
* @since 2.5
|
||||
* @uses apply_filters() Calls 'default_feed' hook on the default feed string.
|
||||
*
|
||||
* @return string Default feed, or for example 'rss2', 'atom', etc.
|
||||
*/
|
||||
function get_default_feed() {
|
||||
return apply_filters('default_feed', 'rss2');
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the blog title for the feed title.
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Feed
|
||||
* @since 2.2.0
|
||||
* @uses apply_filters() Calls 'get_wp_title_rss' hook on title.
|
||||
* @uses wp_title() See function for $sep parameter usage.
|
||||
*
|
||||
* @param string $sep Optional.How to separate the title. See wp_title() for more info.
|
||||
* @return string Error message on failure or blog title on success.
|
||||
*/
|
||||
function get_wp_title_rss($sep = '»') {
|
||||
$title = wp_title($sep, false);
|
||||
if ( is_wp_error( $title ) )
|
||||
return $title->get_error_message();
|
||||
$title = apply_filters('get_wp_title_rss', $title);
|
||||
return $title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the blog title for display of the feed title.
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Feed
|
||||
* @since 2.2.0
|
||||
* @uses apply_filters() Calls 'wp_title_rss' on the blog title.
|
||||
* @see wp_title() $sep parameter usage.
|
||||
*
|
||||
* @param string $sep Optional.
|
||||
*/
|
||||
function wp_title_rss($sep = '»') {
|
||||
echo apply_filters('wp_title_rss', get_wp_title_rss($sep));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the current post title for the feed.
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Feed
|
||||
* @since 2.0.0
|
||||
* @uses apply_filters() Calls 'the_title_rss' on the post title.
|
||||
*
|
||||
* @return string Current post title.
|
||||
*/
|
||||
function get_the_title_rss() {
|
||||
$title = get_the_title();
|
||||
$title = apply_filters('the_title_rss', $title);
|
||||
return $title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the post title in the feed.
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Feed
|
||||
* @since 0.71
|
||||
* @uses get_the_title_rss() Used to retrieve current post title.
|
||||
*/
|
||||
function the_title_rss() {
|
||||
echo get_the_title_rss();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the post content for feeds.
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Feed
|
||||
* @since 2.9.0
|
||||
* @uses apply_filters() Calls 'the_content_feed' on the content before processing.
|
||||
* @see get_the_content()
|
||||
*
|
||||
* @param string $feed_type The type of feed. rss2 | atom | rss | rdf
|
||||
*/
|
||||
function get_the_content_feed($feed_type = null) {
|
||||
if ( !$feed_type )
|
||||
$feed_type = get_default_feed();
|
||||
|
||||
$content = apply_filters('the_content', get_the_content());
|
||||
$content = str_replace(']]>', ']]>', $content);
|
||||
return apply_filters('the_content_feed', $content, $feed_type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the post content for feeds.
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Feed
|
||||
* @since 2.9.0
|
||||
* @uses apply_filters() Calls 'the_content_feed' on the content before processing.
|
||||
* @see get_the_content()
|
||||
*
|
||||
* @param string $feed_type The type of feed. rss2 | atom | rss | rdf
|
||||
*/
|
||||
function the_content_feed($feed_type = null) {
|
||||
echo get_the_content_feed($feed_type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the post excerpt for the feed.
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Feed
|
||||
* @since 0.71
|
||||
* @uses apply_filters() Calls 'the_excerpt_rss' hook on the excerpt.
|
||||
*/
|
||||
function the_excerpt_rss() {
|
||||
$output = get_the_excerpt();
|
||||
echo apply_filters('the_excerpt_rss', $output);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the permalink to the post for use in feeds.
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Feed
|
||||
* @since 2.3.0
|
||||
* @uses apply_filters() Call 'the_permalink_rss' on the post permalink
|
||||
*/
|
||||
function the_permalink_rss() {
|
||||
echo esc_url( apply_filters('the_permalink_rss', get_permalink() ));
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs the link to the comments for the current post in an xml safe way
|
||||
*
|
||||
* @since 3.0.0
|
||||
* @return none
|
||||
*/
|
||||
function comments_link_feed() {
|
||||
echo esc_url( get_comments_link() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the feed GUID for the current comment.
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Feed
|
||||
* @since 2.5.0
|
||||
*
|
||||
* @param int|object $comment_id Optional comment object or id. Defaults to global comment object.
|
||||
*/
|
||||
function comment_guid($comment_id = null) {
|
||||
echo esc_url( get_comment_guid($comment_id) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the feed GUID for the current comment.
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Feed
|
||||
* @since 2.5.0
|
||||
*
|
||||
* @param int|object $comment_id Optional comment object or id. Defaults to global comment object.
|
||||
* @return bool|string false on failure or guid for comment on success.
|
||||
*/
|
||||
function get_comment_guid($comment_id = null) {
|
||||
$comment = get_comment($comment_id);
|
||||
|
||||
if ( !is_object($comment) )
|
||||
return false;
|
||||
|
||||
return get_the_guid($comment->comment_post_ID) . '#comment-' . $comment->comment_ID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the link to the comments.
|
||||
*
|
||||
* @since 1.5.0
|
||||
*/
|
||||
function comment_link() {
|
||||
echo esc_url( get_comment_link() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the current comment author for use in the feeds.
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Feed
|
||||
* @since 2.0.0
|
||||
* @uses apply_filters() Calls 'comment_author_rss' hook on comment author.
|
||||
* @uses get_comment_author()
|
||||
*
|
||||
* @return string Comment Author
|
||||
*/
|
||||
function get_comment_author_rss() {
|
||||
return apply_filters('comment_author_rss', get_comment_author() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the current comment author in the feed.
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Feed
|
||||
* @since 1.0.0
|
||||
*/
|
||||
function comment_author_rss() {
|
||||
echo get_comment_author_rss();
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the current comment content for use in the feeds.
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Feed
|
||||
* @since 1.0.0
|
||||
* @uses apply_filters() Calls 'comment_text_rss' filter on comment content.
|
||||
* @uses get_comment_text()
|
||||
*/
|
||||
function comment_text_rss() {
|
||||
$comment_text = get_comment_text();
|
||||
$comment_text = apply_filters('comment_text_rss', $comment_text);
|
||||
echo $comment_text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve all of the post categories, formatted for use in feeds.
|
||||
*
|
||||
* All of the categories for the current post in the feed loop, will be
|
||||
* retrieved and have feed markup added, so that they can easily be added to the
|
||||
* RSS2, Atom, or RSS1 and RSS0.91 RDF feeds.
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Feed
|
||||
* @since 2.1.0
|
||||
* @uses apply_filters()
|
||||
*
|
||||
* @param string $type Optional, default is the type returned by get_default_feed().
|
||||
* @return string All of the post categories for displaying in the feed.
|
||||
*/
|
||||
function get_the_category_rss($type = null) {
|
||||
if ( empty($type) )
|
||||
$type = get_default_feed();
|
||||
$categories = get_the_category();
|
||||
$tags = get_the_tags();
|
||||
$the_list = '';
|
||||
$cat_names = array();
|
||||
|
||||
$filter = 'rss';
|
||||
if ( 'atom' == $type )
|
||||
$filter = 'raw';
|
||||
|
||||
if ( !empty($categories) ) foreach ( (array) $categories as $category ) {
|
||||
$cat_names[] = sanitize_term_field('name', $category->name, $category->term_id, 'category', $filter);
|
||||
}
|
||||
|
||||
if ( !empty($tags) ) foreach ( (array) $tags as $tag ) {
|
||||
$cat_names[] = sanitize_term_field('name', $tag->name, $tag->term_id, 'post_tag', $filter);
|
||||
}
|
||||
|
||||
$cat_names = array_unique($cat_names);
|
||||
|
||||
foreach ( $cat_names as $cat_name ) {
|
||||
if ( 'rdf' == $type )
|
||||
$the_list .= "\t\t<dc:subject><![CDATA[$cat_name]]></dc:subject>\n";
|
||||
elseif ( 'atom' == $type )
|
||||
$the_list .= sprintf( '<category scheme="%1$s" term="%2$s" />', esc_attr( apply_filters( 'get_bloginfo_rss', get_bloginfo( 'url' ) ) ), esc_attr( $cat_name ) );
|
||||
else
|
||||
$the_list .= "\t\t<category><![CDATA[" . @html_entity_decode( $cat_name, ENT_COMPAT, get_option('blog_charset') ) . "]]></category>\n";
|
||||
}
|
||||
|
||||
return apply_filters('the_category_rss', $the_list, $type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the post categories in the feed.
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Feed
|
||||
* @since 0.71
|
||||
* @see get_the_category_rss() For better explanation.
|
||||
*
|
||||
* @param string $type Optional, default is the type returned by get_default_feed().
|
||||
*/
|
||||
function the_category_rss($type = null) {
|
||||
echo get_the_category_rss($type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the HTML type based on the blog setting.
|
||||
*
|
||||
* The two possible values are either 'xhtml' or 'html'.
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Feed
|
||||
* @since 2.2.0
|
||||
*/
|
||||
function html_type_rss() {
|
||||
$type = get_bloginfo('html_type');
|
||||
if (strpos($type, 'xhtml') !== false)
|
||||
$type = 'xhtml';
|
||||
else
|
||||
$type = 'html';
|
||||
echo $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the rss enclosure for the current post.
|
||||
*
|
||||
* Uses the global $post to check whether the post requires a password and if
|
||||
* the user has the password for the post. If not then it will return before
|
||||
* displaying.
|
||||
*
|
||||
* Also uses the function get_post_custom() to get the post's 'enclosure'
|
||||
* metadata field and parses the value to display the enclosure(s). The
|
||||
* enclosure(s) consist of enclosure HTML tag(s) with a URI and other
|
||||
* attributes.
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Template
|
||||
* @since 1.5.0
|
||||
* @uses apply_filters() Calls 'rss_enclosure' hook on rss enclosure.
|
||||
* @uses get_post_custom() To get the current post enclosure metadata.
|
||||
*/
|
||||
function rss_enclosure() {
|
||||
if ( post_password_required() )
|
||||
return;
|
||||
|
||||
foreach ( (array) get_post_custom() as $key => $val) {
|
||||
if ($key == 'enclosure') {
|
||||
foreach ( (array) $val as $enc ) {
|
||||
$enclosure = explode("\n", $enc);
|
||||
|
||||
//only get the the first element eg, audio/mpeg from 'audio/mpeg mpga mp2 mp3'
|
||||
$t = preg_split('/[ \t]/', trim($enclosure[2]) );
|
||||
$type = $t[0];
|
||||
|
||||
echo apply_filters('rss_enclosure', '<enclosure url="' . trim(htmlspecialchars($enclosure[0])) . '" length="' . trim($enclosure[1]) . '" type="' . $type . '" />' . "\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the atom enclosure for the current post.
|
||||
*
|
||||
* Uses the global $post to check whether the post requires a password and if
|
||||
* the user has the password for the post. If not then it will return before
|
||||
* displaying.
|
||||
*
|
||||
* Also uses the function get_post_custom() to get the post's 'enclosure'
|
||||
* metadata field and parses the value to display the enclosure(s). The
|
||||
* enclosure(s) consist of link HTML tag(s) with a URI and other attributes.
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Template
|
||||
* @since 2.2.0
|
||||
* @uses apply_filters() Calls 'atom_enclosure' hook on atom enclosure.
|
||||
* @uses get_post_custom() To get the current post enclosure metadata.
|
||||
*/
|
||||
function atom_enclosure() {
|
||||
if ( post_password_required() )
|
||||
return;
|
||||
|
||||
foreach ( (array) get_post_custom() as $key => $val ) {
|
||||
if ($key == 'enclosure') {
|
||||
foreach ( (array) $val as $enc ) {
|
||||
$enclosure = split("\n", $enc);
|
||||
echo apply_filters('atom_enclosure', '<link href="' . trim(htmlspecialchars($enclosure[0])) . '" rel="enclosure" length="' . trim($enclosure[1]) . '" type="' . trim($enclosure[2]) . '" />' . "\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the type of a string of data with the data formatted.
|
||||
*
|
||||
* Tell whether the type is text, html, or xhtml, per RFC 4287 section 3.1.
|
||||
*
|
||||
* In the case of WordPress, text is defined as containing no markup,
|
||||
* xhtml is defined as "well formed", and html as tag soup (i.e., the rest).
|
||||
*
|
||||
* Container div tags are added to xhtml values, per section 3.1.1.3.
|
||||
*
|
||||
* @link http://www.atomenabled.org/developers/syndication/atom-format-spec.php#rfc.section.3.1
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Feed
|
||||
* @since 2.5
|
||||
*
|
||||
* @param string $data Input string
|
||||
* @return array array(type, value)
|
||||
*/
|
||||
function prep_atom_text_construct($data) {
|
||||
if (strpos($data, '<') === false && strpos($data, '&') === false) {
|
||||
return array('text', $data);
|
||||
}
|
||||
|
||||
$parser = xml_parser_create();
|
||||
xml_parse($parser, '<div>' . $data . '</div>', true);
|
||||
$code = xml_get_error_code($parser);
|
||||
xml_parser_free($parser);
|
||||
|
||||
if (!$code) {
|
||||
if (strpos($data, '<') === false) {
|
||||
return array('text', $data);
|
||||
} else {
|
||||
$data = "<div xmlns='http://www.w3.org/1999/xhtml'>$data</div>";
|
||||
return array('xhtml', $data);
|
||||
}
|
||||
}
|
||||
|
||||
if (strpos($data, ']]>') == false) {
|
||||
return array('html', "<![CDATA[$data]]>");
|
||||
} else {
|
||||
return array('html', htmlspecialchars($data));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the link for the currently displayed feed in a XSS safe way.
|
||||
*
|
||||
* Generate a correct link for the atom:self element.
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Feed
|
||||
* @since 2.5
|
||||
*/
|
||||
function self_link() {
|
||||
$host = @parse_url(home_url());
|
||||
$host = $host['host'];
|
||||
echo esc_url(
|
||||
'http'
|
||||
. ( (isset($_SERVER['https']) && $_SERVER['https'] == 'on') ? 's' : '' ) . '://'
|
||||
. $host
|
||||
. stripslashes($_SERVER['REQUEST_URI'])
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the content type for specified feed type.
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Feed
|
||||
* @since 2.8.0
|
||||
*/
|
||||
function feed_content_type( $type = '' ) {
|
||||
if ( empty($type) )
|
||||
$type = get_default_feed();
|
||||
|
||||
$types = array(
|
||||
'rss' => 'application/rss+xml',
|
||||
'rss2' => 'application/rss+xml',
|
||||
'rss-http' => 'text/xml',
|
||||
'atom' => 'application/atom+xml',
|
||||
'rdf' => 'application/rdf+xml'
|
||||
);
|
||||
|
||||
$content_type = ( !empty($types[$type]) ) ? $types[$type] : 'application/octet-stream';
|
||||
|
||||
return apply_filters( 'feed_content_type', $content_type, $type );
|
||||
}
|
||||
|
||||
/**
|
||||
* Build SimplePie object based on RSS or Atom feed from URL.
|
||||
*
|
||||
* @since 2.8
|
||||
*
|
||||
* @param string $url URL to retrieve feed
|
||||
* @return WP_Error|SimplePie WP_Error object on failure or SimplePie object on success
|
||||
*/
|
||||
function fetch_feed($url) {
|
||||
require_once (ABSPATH . WPINC . '/class-feed.php');
|
||||
|
||||
$feed = new SimplePie();
|
||||
$feed->set_feed_url($url);
|
||||
$feed->set_cache_class('WP_Feed_Cache');
|
||||
$feed->set_file_class('WP_SimplePie_File');
|
||||
$feed->set_cache_duration(apply_filters('wp_feed_cache_transient_lifetime', 43200, $url));
|
||||
do_action_ref_array( 'wp_feed_options', array( &$feed, $url ) );
|
||||
$feed->init();
|
||||
$feed->handle_content_type();
|
||||
|
||||
if ( $feed->error() )
|
||||
return new WP_Error('simplepie-error', $feed->error());
|
||||
|
||||
return $feed;
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
<?php
|
||||
/**
|
||||
* BackPress script procedural API.
|
||||
*
|
||||
* @package BackPress
|
||||
* @since r16
|
||||
*/
|
||||
|
||||
/**
|
||||
* Prints script tags in document head.
|
||||
*
|
||||
* Called by admin-header.php and by wp_head hook. Since it is called by wp_head
|
||||
* on every page load, the function does not instantiate the WP_Scripts object
|
||||
* unless script names are explicitly passed. Does make use of already
|
||||
* instantiated $wp_scripts if present. Use provided wp_print_scripts hook to
|
||||
* register/enqueue new scripts.
|
||||
*
|
||||
* @since r16
|
||||
* @see WP_Dependencies::print_scripts()
|
||||
*/
|
||||
function wp_print_scripts( $handles = false ) {
|
||||
do_action( 'wp_print_scripts' );
|
||||
if ( '' === $handles ) // for wp_head
|
||||
$handles = false;
|
||||
|
||||
global $wp_scripts;
|
||||
if ( !is_a($wp_scripts, 'WP_Scripts') ) {
|
||||
if ( !$handles )
|
||||
return array(); // No need to instantiate if nothing's there.
|
||||
else
|
||||
$wp_scripts = new WP_Scripts();
|
||||
}
|
||||
|
||||
return $wp_scripts->do_items( $handles );
|
||||
}
|
||||
|
||||
/**
|
||||
* Register new JavaScript file.
|
||||
*
|
||||
* @since r16
|
||||
* @param string $handle Script name
|
||||
* @param string $src Script url
|
||||
* @param array $deps (optional) Array of script names on which this script depends
|
||||
* @param string|bool $ver (optional) Script version (used for cache busting), set to NULL to disable
|
||||
* @param bool $in_footer (optional) Whether to enqueue the script before </head> or before </body>
|
||||
* @return null
|
||||
*/
|
||||
function wp_register_script( $handle, $src, $deps = array(), $ver = false, $in_footer = false ) {
|
||||
global $wp_scripts;
|
||||
if ( !is_a($wp_scripts, 'WP_Scripts') )
|
||||
$wp_scripts = new WP_Scripts();
|
||||
|
||||
$wp_scripts->add( $handle, $src, $deps, $ver );
|
||||
if ( $in_footer )
|
||||
$wp_scripts->add_data( $handle, 'group', 1 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Localizes a script.
|
||||
*
|
||||
* Localizes only if script has already been added.
|
||||
*
|
||||
* @since r16
|
||||
* @see WP_Scripts::localize()
|
||||
*/
|
||||
function wp_localize_script( $handle, $object_name, $l10n ) {
|
||||
global $wp_scripts;
|
||||
if ( !is_a($wp_scripts, 'WP_Scripts') )
|
||||
return false;
|
||||
|
||||
return $wp_scripts->localize( $handle, $object_name, $l10n );
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a registered script.
|
||||
*
|
||||
* @since r16
|
||||
* @see WP_Scripts::remove() For parameter information.
|
||||
*/
|
||||
function wp_deregister_script( $handle ) {
|
||||
global $wp_scripts;
|
||||
if ( !is_a($wp_scripts, 'WP_Scripts') )
|
||||
$wp_scripts = new WP_Scripts();
|
||||
|
||||
$wp_scripts->remove( $handle );
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueues script.
|
||||
*
|
||||
* Registers the script if src provided (does NOT overwrite) and enqueues.
|
||||
*
|
||||
* @since r16
|
||||
* @see wp_register_script() For parameter information.
|
||||
*/
|
||||
function wp_enqueue_script( $handle, $src = false, $deps = array(), $ver = false, $in_footer = false ) {
|
||||
global $wp_scripts;
|
||||
if ( !is_a($wp_scripts, 'WP_Scripts') )
|
||||
$wp_scripts = new WP_Scripts();
|
||||
|
||||
if ( $src ) {
|
||||
$_handle = explode('?', $handle);
|
||||
$wp_scripts->add( $_handle[0], $src, $deps, $ver );
|
||||
if ( $in_footer )
|
||||
$wp_scripts->add_data( $_handle[0], 'group', 1 );
|
||||
}
|
||||
$wp_scripts->enqueue( $handle );
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an enqueued script.
|
||||
*
|
||||
* @since WP 3.1
|
||||
* @see WP_Scripts::dequeue() For parameter information.
|
||||
*/
|
||||
function wp_dequeue_script( $handle ) {
|
||||
global $wp_scripts;
|
||||
if ( !is_a($wp_scripts, 'WP_Scripts') )
|
||||
$wp_scripts = new WP_Scripts();
|
||||
|
||||
$wp_scripts->dequeue( $handle );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether script has been added to WordPress Scripts.
|
||||
*
|
||||
* The values for list defaults to 'queue', which is the same as enqueue for
|
||||
* scripts.
|
||||
*
|
||||
* @since WP unknown; BP unknown
|
||||
*
|
||||
* @param string $handle Handle used to add script.
|
||||
* @param string $list Optional, defaults to 'queue'. Others values are 'registered', 'queue', 'done', 'to_do'
|
||||
* @return bool
|
||||
*/
|
||||
function wp_script_is( $handle, $list = 'queue' ) {
|
||||
global $wp_scripts;
|
||||
if ( !is_a($wp_scripts, 'WP_Scripts') )
|
||||
$wp_scripts = new WP_Scripts();
|
||||
|
||||
$query = $wp_scripts->query( $handle, $list );
|
||||
|
||||
if ( is_object( $query ) )
|
||||
return true;
|
||||
|
||||
return $query;
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
<?php
|
||||
/**
|
||||
* BackPress styles procedural API.
|
||||
*
|
||||
* @package BackPress
|
||||
* @since r79
|
||||
*/
|
||||
|
||||
/**
|
||||
* Display styles that are in the queue or part of $handles.
|
||||
*
|
||||
* @since r79
|
||||
* @uses do_action() Calls 'wp_print_styles' hook.
|
||||
* @global object $wp_styles The WP_Styles object for printing styles.
|
||||
*
|
||||
* @param array|bool $handles Styles to be printed. An empty array prints the queue,
|
||||
* an array with one string prints that style, and an array of strings prints those styles.
|
||||
* @return bool True on success, false on failure.
|
||||
*/
|
||||
function wp_print_styles( $handles = false ) {
|
||||
do_action( 'wp_print_styles' );
|
||||
if ( '' === $handles ) // for wp_head
|
||||
$handles = false;
|
||||
|
||||
global $wp_styles;
|
||||
if ( !is_a($wp_styles, 'WP_Styles') ) {
|
||||
if ( !$handles )
|
||||
return array(); // No need to instantiate if nothing's there.
|
||||
else
|
||||
$wp_styles = new WP_Styles();
|
||||
}
|
||||
|
||||
return $wp_styles->do_items( $handles );
|
||||
}
|
||||
|
||||
/**
|
||||
* Register CSS style file.
|
||||
*
|
||||
* @since r79
|
||||
* @see WP_Styles::add() For additional information.
|
||||
* @global object $wp_styles The WP_Styles object for printing styles.
|
||||
* @link http://www.w3.org/TR/CSS2/media.html#media-types List of CSS media types.
|
||||
*
|
||||
* @param string $handle Name of the stylesheet.
|
||||
* @param string|bool $src Path to the stylesheet from the root directory of WordPress. Example: '/css/mystyle.css'.
|
||||
* @param array $deps Array of handles of any stylesheet that this stylesheet depends on.
|
||||
* (Stylesheets that must be loaded before this stylesheet.) Pass an empty array if there are no dependencies.
|
||||
* @param string|bool $ver String specifying the stylesheet version number. Set to NULL to disable.
|
||||
* Used to ensure that the correct version is sent to the client regardless of caching.
|
||||
* @param string $media The media for which this stylesheet has been defined.
|
||||
*/
|
||||
function wp_register_style( $handle, $src, $deps = array(), $ver = false, $media = 'all' ) {
|
||||
global $wp_styles;
|
||||
if ( !is_a($wp_styles, 'WP_Styles') )
|
||||
$wp_styles = new WP_Styles();
|
||||
|
||||
$wp_styles->add( $handle, $src, $deps, $ver, $media );
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a registered CSS file.
|
||||
*
|
||||
* @since r79
|
||||
* @see WP_Styles::remove() For additional information.
|
||||
* @global object $wp_styles The WP_Styles object for printing styles.
|
||||
*
|
||||
* @param string $handle Name of the stylesheet.
|
||||
*/
|
||||
function wp_deregister_style( $handle ) {
|
||||
global $wp_styles;
|
||||
if ( !is_a($wp_styles, 'WP_Styles') )
|
||||
$wp_styles = new WP_Styles();
|
||||
|
||||
$wp_styles->remove( $handle );
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue a CSS style file.
|
||||
*
|
||||
* Registers the style if src provided (does NOT overwrite) and enqueues.
|
||||
*
|
||||
* @since r79
|
||||
* @see WP_Styles::add(), WP_Styles::enqueue()
|
||||
* @global object $wp_styles The WP_Styles object for printing styles.
|
||||
* @link http://www.w3.org/TR/CSS2/media.html#media-types List of CSS media types.
|
||||
*
|
||||
* @param string $handle Name of the stylesheet.
|
||||
* @param string|bool $src Path to the stylesheet from the root directory of WordPress. Example: '/css/mystyle.css'.
|
||||
* @param array $deps Array of handles (names) of any stylesheet that this stylesheet depends on.
|
||||
* (Stylesheets that must be loaded before this stylesheet.) Pass an empty array if there are no dependencies.
|
||||
* @param string|bool $ver String specifying the stylesheet version number, if it has one. This parameter
|
||||
* is used to ensure that the correct version is sent to the client regardless of caching, and so should be included
|
||||
* if a version number is available and makes sense for the stylesheet.
|
||||
* @param string $media The media for which this stylesheet has been defined.
|
||||
*/
|
||||
function wp_enqueue_style( $handle, $src = false, $deps = array(), $ver = false, $media = 'all' ) {
|
||||
global $wp_styles;
|
||||
if ( !is_a($wp_styles, 'WP_Styles') )
|
||||
$wp_styles = new WP_Styles();
|
||||
|
||||
if ( $src ) {
|
||||
$_handle = explode('?', $handle);
|
||||
$wp_styles->add( $_handle[0], $src, $deps, $ver, $media );
|
||||
}
|
||||
$wp_styles->enqueue( $handle );
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an enqueued style.
|
||||
*
|
||||
* @since WP 3.1
|
||||
* @see WP_Styles::dequeue() For parameter information.
|
||||
*/
|
||||
function wp_dequeue_style( $handle ) {
|
||||
global $wp_styles;
|
||||
if ( !is_a($wp_styles, 'WP_Styles') )
|
||||
$wp_styles = new WP_Styles();
|
||||
|
||||
$wp_styles->dequeue( $handle );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether style has been added to WordPress Styles.
|
||||
*
|
||||
* The values for list defaults to 'queue', which is the same as wp_enqueue_style().
|
||||
*
|
||||
* @since WP unknown; BP unknown
|
||||
* @global object $wp_styles The WP_Styles object for printing styles.
|
||||
*
|
||||
* @param string $handle Name of the stylesheet.
|
||||
* @param string $list Values are 'registered', 'done', 'queue' and 'to_do'.
|
||||
* @return bool True on success, false on failure.
|
||||
*/
|
||||
function wp_style_is( $handle, $list = 'queue' ) {
|
||||
global $wp_styles;
|
||||
if ( !is_a($wp_styles, 'WP_Styles') )
|
||||
$wp_styles = new WP_Styles();
|
||||
|
||||
$query = $wp_styles->query( $handle, $list );
|
||||
|
||||
if ( is_object( $query ) )
|
||||
return true;
|
||||
|
||||
return $query;
|
||||
}
|
||||
@@ -0,0 +1,194 @@
|
||||
<?php
|
||||
/**
|
||||
* Simple and uniform HTTP request API.
|
||||
*
|
||||
* Will eventually replace and standardize the WordPress HTTP requests made.
|
||||
*
|
||||
* @link http://trac.wordpress.org/ticket/4779 HTTP API Proposal
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage HTTP
|
||||
* @since 2.7.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Returns the initialized WP_Http Object
|
||||
*
|
||||
* @since 2.7.0
|
||||
* @access private
|
||||
*
|
||||
* @return WP_Http HTTP Transport object.
|
||||
*/
|
||||
function &_wp_http_get_object() {
|
||||
static $http;
|
||||
|
||||
if ( is_null($http) )
|
||||
$http = new WP_Http();
|
||||
|
||||
return $http;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the raw response from the HTTP request.
|
||||
*
|
||||
* The array structure is a little complex.
|
||||
*
|
||||
* <code>
|
||||
* $res = array( 'headers' => array(), 'response' => array('code' => int, 'message' => string) );
|
||||
* </code>
|
||||
*
|
||||
* All of the headers in $res['headers'] are with the name as the key and the
|
||||
* value as the value. So to get the User-Agent, you would do the following.
|
||||
*
|
||||
* <code>
|
||||
* $user_agent = $res['headers']['user-agent'];
|
||||
* </code>
|
||||
*
|
||||
* The body is the raw response content and can be retrieved from $res['body'].
|
||||
*
|
||||
* This function is called first to make the request and there are other API
|
||||
* functions to abstract out the above convoluted setup.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @param string $url Site URL to retrieve.
|
||||
* @param array $args Optional. Override the defaults.
|
||||
* @return WP_Error|array The response or WP_Error on failure.
|
||||
*/
|
||||
function wp_remote_request($url, $args = array()) {
|
||||
$objFetchSite = _wp_http_get_object();
|
||||
return $objFetchSite->request($url, $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the raw response from the HTTP request using the GET method.
|
||||
*
|
||||
* @see wp_remote_request() For more information on the response array format.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @param string $url Site URL to retrieve.
|
||||
* @param array $args Optional. Override the defaults.
|
||||
* @return WP_Error|array The response or WP_Error on failure.
|
||||
*/
|
||||
function wp_remote_get($url, $args = array()) {
|
||||
$objFetchSite = _wp_http_get_object();
|
||||
return $objFetchSite->get($url, $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the raw response from the HTTP request using the POST method.
|
||||
*
|
||||
* @see wp_remote_request() For more information on the response array format.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @param string $url Site URL to retrieve.
|
||||
* @param array $args Optional. Override the defaults.
|
||||
* @return WP_Error|array The response or WP_Error on failure.
|
||||
*/
|
||||
function wp_remote_post($url, $args = array()) {
|
||||
$objFetchSite = _wp_http_get_object();
|
||||
return $objFetchSite->post($url, $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the raw response from the HTTP request using the HEAD method.
|
||||
*
|
||||
* @see wp_remote_request() For more information on the response array format.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @param string $url Site URL to retrieve.
|
||||
* @param array $args Optional. Override the defaults.
|
||||
* @return WP_Error|array The response or WP_Error on failure.
|
||||
*/
|
||||
function wp_remote_head($url, $args = array()) {
|
||||
$objFetchSite = _wp_http_get_object();
|
||||
return $objFetchSite->head($url, $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve only the headers from the raw response.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @param array $response HTTP response.
|
||||
* @return array The headers of the response. Empty array if incorrect parameter given.
|
||||
*/
|
||||
function wp_remote_retrieve_headers(&$response) {
|
||||
if ( is_wp_error($response) || ! isset($response['headers']) || ! is_array($response['headers']))
|
||||
return array();
|
||||
|
||||
return $response['headers'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a single header by name from the raw response.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @param array $response
|
||||
* @param string $header Header name to retrieve value from.
|
||||
* @return string The header value. Empty string on if incorrect parameter given, or if the header doesnt exist.
|
||||
*/
|
||||
function wp_remote_retrieve_header(&$response, $header) {
|
||||
if ( is_wp_error($response) || ! isset($response['headers']) || ! is_array($response['headers']))
|
||||
return '';
|
||||
|
||||
if ( array_key_exists($header, $response['headers']) )
|
||||
return $response['headers'][$header];
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve only the response code from the raw response.
|
||||
*
|
||||
* Will return an empty array if incorrect parameter value is given.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @param array $response HTTP response.
|
||||
* @return string the response code. Empty string on incorrect parameter given.
|
||||
*/
|
||||
function wp_remote_retrieve_response_code(&$response) {
|
||||
if ( is_wp_error($response) || ! isset($response['response']) || ! is_array($response['response']))
|
||||
return '';
|
||||
|
||||
return $response['response']['code'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve only the response message from the raw response.
|
||||
*
|
||||
* Will return an empty array if incorrect parameter value is given.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @param array $response HTTP response.
|
||||
* @return string The response message. Empty string on incorrect parameter given.
|
||||
*/
|
||||
function wp_remote_retrieve_response_message(&$response) {
|
||||
if ( is_wp_error($response) || ! isset($response['response']) || ! is_array($response['response']))
|
||||
return '';
|
||||
|
||||
return $response['response']['message'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve only the body from the raw response.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @param array $response HTTP response.
|
||||
* @return string The body of the response. Empty string if no body or incorrect parameter given.
|
||||
*/
|
||||
function wp_remote_retrieve_body(&$response) {
|
||||
if ( is_wp_error($response) || ! isset($response['body']) )
|
||||
return '';
|
||||
|
||||
return $response['body'];
|
||||
}
|
||||
|
||||
?>
|
||||
|
After Width: | Height: | Size: 732 B |
|
After Width: | Height: | Size: 737 B |
|
After Width: | Height: | Size: 43 B |
|
After Width: | Height: | Size: 3.0 KiB |
|
After Width: | Height: | Size: 2.6 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 638 B |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 2.7 KiB |
@@ -0,0 +1,9 @@
|
||||
Crystal Project Icons
|
||||
by Everaldo Coelho
|
||||
http://everaldo.com
|
||||
|
||||
Released under LGPL
|
||||
|
||||
Modified February 2008
|
||||
for WordPress
|
||||
http://wordpress.org
|
||||
|
After Width: | Height: | Size: 2.7 KiB |
|
After Width: | Height: | Size: 999 B |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 3.3 KiB |
|
After Width: | Height: | Size: 170 B |
|
After Width: | Height: | Size: 172 B |
|
After Width: | Height: | Size: 171 B |
|
After Width: | Height: | Size: 172 B |
|
After Width: | Height: | Size: 498 B |
|
After Width: | Height: | Size: 170 B |
|
After Width: | Height: | Size: 236 B |
|
After Width: | Height: | Size: 236 B |
|
After Width: | Height: | Size: 176 B |
|
After Width: | Height: | Size: 336 B |
|
After Width: | Height: | Size: 174 B |
|
After Width: | Height: | Size: 349 B |
|
After Width: | Height: | Size: 171 B |
|
After Width: | Height: | Size: 248 B |
|
After Width: | Height: | Size: 176 B |
|
After Width: | Height: | Size: 650 B |
|
After Width: | Height: | Size: 485 B |
|
After Width: | Height: | Size: 171 B |
|
After Width: | Height: | Size: 174 B |
|
After Width: | Height: | Size: 174 B |