mirror of
https://github.com/janunger/rheinwerk-video-training.git
synced 2026-02-06 07:05:14 +01:00
Initiale Version
This commit is contained in:
1380
Kapitel_7/Lektion_4/wordpress/wp-includes/ID3/getid3.lib.php
Executable file
1380
Kapitel_7/Lektion_4/wordpress/wp-includes/ID3/getid3.lib.php
Executable file
File diff suppressed because it is too large
Load Diff
1796
Kapitel_7/Lektion_4/wordpress/wp-includes/ID3/getid3.php
Executable file
1796
Kapitel_7/Lektion_4/wordpress/wp-includes/ID3/getid3.php
Executable file
File diff suppressed because it is too large
Load Diff
27
Kapitel_7/Lektion_4/wordpress/wp-includes/ID3/license.commercial.txt
Executable file
27
Kapitel_7/Lektion_4/wordpress/wp-includes/ID3/license.commercial.txt
Executable file
@@ -0,0 +1,27 @@
|
||||
getID3() Commercial License
|
||||
===========================
|
||||
|
||||
getID3() is licensed under the "GNU Public License" (GPL) and/or the
|
||||
"getID3() Commercial License" (gCL). This document describes the gCL.
|
||||
|
||||
---------------------------------------------------------------------
|
||||
|
||||
The license is non-exclusively granted to a single person or company,
|
||||
per payment of the license fee, for the lifetime of that person or
|
||||
company. The license is non-transferrable.
|
||||
|
||||
The gCL grants the licensee the right to use getID3() in commercial
|
||||
closed-source projects. Modifications may be made to getID3() with no
|
||||
obligation to release the modified source code. getID3() (or pieces
|
||||
thereof) may be included in any number of projects authored (in whole
|
||||
or in part) by the licensee.
|
||||
|
||||
The licensee may use any version of getID3(), past, present or future,
|
||||
as is most convenient. This license does not entitle the licensee to
|
||||
receive any technical support, updates or bugfixes, except as such are
|
||||
made publicly available to all getID3() users.
|
||||
|
||||
The licensee may not sub-license getID3() itself, meaning that any
|
||||
commercially released product containing all or parts of getID3() must
|
||||
have added functionality beyond what is available in getID3();
|
||||
getID3() itself may not be re-licensed by the licensee.
|
||||
29
Kapitel_7/Lektion_4/wordpress/wp-includes/ID3/license.txt
Executable file
29
Kapitel_7/Lektion_4/wordpress/wp-includes/ID3/license.txt
Executable file
@@ -0,0 +1,29 @@
|
||||
/////////////////////////////////////////////////////////////////
|
||||
/// getID3() by James Heinrich <info@getid3.org> //
|
||||
// available at http://getid3.sourceforge.net //
|
||||
// or http://www.getid3.org //
|
||||
// also https://github.com/JamesHeinrich/getID3 //
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
*****************************************************************
|
||||
*****************************************************************
|
||||
|
||||
getID3() is released under multiple licenses. You may choose
|
||||
from the following licenses, and use getID3 according to the
|
||||
terms of the license most suitable to your project.
|
||||
|
||||
GNU GPL: https://gnu.org/licenses/gpl.html (v3)
|
||||
https://gnu.org/licenses/old-licenses/gpl-2.0.html (v2)
|
||||
https://gnu.org/licenses/old-licenses/gpl-1.0.html (v1)
|
||||
|
||||
GNU LGPL: https://gnu.org/licenses/lgpl.html (v3)
|
||||
|
||||
Mozilla MPL: http://www.mozilla.org/MPL/2.0/ (v2)
|
||||
|
||||
getID3 Commercial License: http://getid3.org/#gCL (payment required)
|
||||
|
||||
*****************************************************************
|
||||
*****************************************************************
|
||||
|
||||
Copies of each of the above licenses are included in the 'licenses'
|
||||
directory of the getID3 distribution.
|
||||
2013
Kapitel_7/Lektion_4/wordpress/wp-includes/ID3/module.audio-video.asf.php
Executable file
2013
Kapitel_7/Lektion_4/wordpress/wp-includes/ID3/module.audio-video.asf.php
Executable file
File diff suppressed because it is too large
Load Diff
745
Kapitel_7/Lektion_4/wordpress/wp-includes/ID3/module.audio-video.flv.php
Executable file
745
Kapitel_7/Lektion_4/wordpress/wp-includes/ID3/module.audio-video.flv.php
Executable file
@@ -0,0 +1,745 @@
|
||||
<?php
|
||||
/////////////////////////////////////////////////////////////////
|
||||
/// getID3() by James Heinrich <info@getid3.org> //
|
||||
// available at http://getid3.sourceforge.net //
|
||||
// or http://www.getid3.org //
|
||||
// also https://github.com/JamesHeinrich/getID3 //
|
||||
// //
|
||||
// FLV module by Seth Kaufman <sethØwhirl-i-gig*com> //
|
||||
// //
|
||||
// * version 0.1 (26 June 2005) //
|
||||
// //
|
||||
// //
|
||||
// * version 0.1.1 (15 July 2005) //
|
||||
// minor modifications by James Heinrich <info@getid3.org> //
|
||||
// //
|
||||
// * version 0.2 (22 February 2006) //
|
||||
// Support for On2 VP6 codec and meta information //
|
||||
// by Steve Webster <steve.websterØfeaturecreep*com> //
|
||||
// //
|
||||
// * version 0.3 (15 June 2006) //
|
||||
// Modified to not read entire file into memory //
|
||||
// by James Heinrich <info@getid3.org> //
|
||||
// //
|
||||
// * version 0.4 (07 December 2007) //
|
||||
// Bugfixes for incorrectly parsed FLV dimensions //
|
||||
// and incorrect parsing of onMetaTag //
|
||||
// by Evgeny Moysevich <moysevichØgmail*com> //
|
||||
// //
|
||||
// * version 0.5 (21 May 2009) //
|
||||
// Fixed parsing of audio tags and added additional codec //
|
||||
// details. The duration is now read from onMetaTag (if //
|
||||
// exists), rather than parsing whole file //
|
||||
// by Nigel Barnes <ngbarnesØhotmail*com> //
|
||||
// //
|
||||
// * version 0.6 (24 May 2009) //
|
||||
// Better parsing of files with h264 video //
|
||||
// by Evgeny Moysevich <moysevichØgmail*com> //
|
||||
// //
|
||||
// * version 0.6.1 (30 May 2011) //
|
||||
// prevent infinite loops in expGolombUe() //
|
||||
// //
|
||||
// * version 0.7.0 (16 Jul 2013) //
|
||||
// handle GETID3_FLV_VIDEO_VP6FLV_ALPHA //
|
||||
// improved AVCSequenceParameterSetReader::readData() //
|
||||
// by Xander Schouwerwou <schouwerwouØgmail*com> //
|
||||
// //
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// module.audio-video.flv.php //
|
||||
// module for analyzing Shockwave Flash Video files //
|
||||
// dependencies: NONE //
|
||||
// ///
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
define('GETID3_FLV_TAG_AUDIO', 8);
|
||||
define('GETID3_FLV_TAG_VIDEO', 9);
|
||||
define('GETID3_FLV_TAG_META', 18);
|
||||
|
||||
define('GETID3_FLV_VIDEO_H263', 2);
|
||||
define('GETID3_FLV_VIDEO_SCREEN', 3);
|
||||
define('GETID3_FLV_VIDEO_VP6FLV', 4);
|
||||
define('GETID3_FLV_VIDEO_VP6FLV_ALPHA', 5);
|
||||
define('GETID3_FLV_VIDEO_SCREENV2', 6);
|
||||
define('GETID3_FLV_VIDEO_H264', 7);
|
||||
|
||||
define('H264_AVC_SEQUENCE_HEADER', 0);
|
||||
define('H264_PROFILE_BASELINE', 66);
|
||||
define('H264_PROFILE_MAIN', 77);
|
||||
define('H264_PROFILE_EXTENDED', 88);
|
||||
define('H264_PROFILE_HIGH', 100);
|
||||
define('H264_PROFILE_HIGH10', 110);
|
||||
define('H264_PROFILE_HIGH422', 122);
|
||||
define('H264_PROFILE_HIGH444', 144);
|
||||
define('H264_PROFILE_HIGH444_PREDICTIVE', 244);
|
||||
|
||||
class getid3_flv extends getid3_handler {
|
||||
|
||||
const magic = 'FLV';
|
||||
|
||||
public $max_frames = 100000; // break out of the loop if too many frames have been scanned; only scan this many if meta frame does not contain useful duration
|
||||
|
||||
public function Analyze() {
|
||||
$info = &$this->getid3->info;
|
||||
|
||||
$this->fseek($info['avdataoffset']);
|
||||
|
||||
$FLVdataLength = $info['avdataend'] - $info['avdataoffset'];
|
||||
$FLVheader = $this->fread(5);
|
||||
|
||||
$info['fileformat'] = 'flv';
|
||||
$info['flv']['header']['signature'] = substr($FLVheader, 0, 3);
|
||||
$info['flv']['header']['version'] = getid3_lib::BigEndian2Int(substr($FLVheader, 3, 1));
|
||||
$TypeFlags = getid3_lib::BigEndian2Int(substr($FLVheader, 4, 1));
|
||||
|
||||
if ($info['flv']['header']['signature'] != self::magic) {
|
||||
$info['error'][] = 'Expecting "'.getid3_lib::PrintHexBytes(self::magic).'" at offset '.$info['avdataoffset'].', found "'.getid3_lib::PrintHexBytes($info['flv']['header']['signature']).'"';
|
||||
unset($info['flv'], $info['fileformat']);
|
||||
return false;
|
||||
}
|
||||
|
||||
$info['flv']['header']['hasAudio'] = (bool) ($TypeFlags & 0x04);
|
||||
$info['flv']['header']['hasVideo'] = (bool) ($TypeFlags & 0x01);
|
||||
|
||||
$FrameSizeDataLength = getid3_lib::BigEndian2Int($this->fread(4));
|
||||
$FLVheaderFrameLength = 9;
|
||||
if ($FrameSizeDataLength > $FLVheaderFrameLength) {
|
||||
$this->fseek($FrameSizeDataLength - $FLVheaderFrameLength, SEEK_CUR);
|
||||
}
|
||||
$Duration = 0;
|
||||
$found_video = false;
|
||||
$found_audio = false;
|
||||
$found_meta = false;
|
||||
$found_valid_meta_playtime = false;
|
||||
$tagParseCount = 0;
|
||||
$info['flv']['framecount'] = array('total'=>0, 'audio'=>0, 'video'=>0);
|
||||
$flv_framecount = &$info['flv']['framecount'];
|
||||
while ((($this->ftell() + 16) < $info['avdataend']) && (($tagParseCount++ <= $this->max_frames) || !$found_valid_meta_playtime)) {
|
||||
$ThisTagHeader = $this->fread(16);
|
||||
|
||||
$PreviousTagLength = getid3_lib::BigEndian2Int(substr($ThisTagHeader, 0, 4));
|
||||
$TagType = getid3_lib::BigEndian2Int(substr($ThisTagHeader, 4, 1));
|
||||
$DataLength = getid3_lib::BigEndian2Int(substr($ThisTagHeader, 5, 3));
|
||||
$Timestamp = getid3_lib::BigEndian2Int(substr($ThisTagHeader, 8, 3));
|
||||
$LastHeaderByte = getid3_lib::BigEndian2Int(substr($ThisTagHeader, 15, 1));
|
||||
$NextOffset = $this->ftell() - 1 + $DataLength;
|
||||
if ($Timestamp > $Duration) {
|
||||
$Duration = $Timestamp;
|
||||
}
|
||||
|
||||
$flv_framecount['total']++;
|
||||
switch ($TagType) {
|
||||
case GETID3_FLV_TAG_AUDIO:
|
||||
$flv_framecount['audio']++;
|
||||
if (!$found_audio) {
|
||||
$found_audio = true;
|
||||
$info['flv']['audio']['audioFormat'] = ($LastHeaderByte >> 4) & 0x0F;
|
||||
$info['flv']['audio']['audioRate'] = ($LastHeaderByte >> 2) & 0x03;
|
||||
$info['flv']['audio']['audioSampleSize'] = ($LastHeaderByte >> 1) & 0x01;
|
||||
$info['flv']['audio']['audioType'] = $LastHeaderByte & 0x01;
|
||||
}
|
||||
break;
|
||||
|
||||
case GETID3_FLV_TAG_VIDEO:
|
||||
$flv_framecount['video']++;
|
||||
if (!$found_video) {
|
||||
$found_video = true;
|
||||
$info['flv']['video']['videoCodec'] = $LastHeaderByte & 0x07;
|
||||
|
||||
$FLVvideoHeader = $this->fread(11);
|
||||
|
||||
if ($info['flv']['video']['videoCodec'] == GETID3_FLV_VIDEO_H264) {
|
||||
// this code block contributed by: moysevichØgmail*com
|
||||
|
||||
$AVCPacketType = getid3_lib::BigEndian2Int(substr($FLVvideoHeader, 0, 1));
|
||||
if ($AVCPacketType == H264_AVC_SEQUENCE_HEADER) {
|
||||
// read AVCDecoderConfigurationRecord
|
||||
$configurationVersion = getid3_lib::BigEndian2Int(substr($FLVvideoHeader, 4, 1));
|
||||
$AVCProfileIndication = getid3_lib::BigEndian2Int(substr($FLVvideoHeader, 5, 1));
|
||||
$profile_compatibility = getid3_lib::BigEndian2Int(substr($FLVvideoHeader, 6, 1));
|
||||
$lengthSizeMinusOne = getid3_lib::BigEndian2Int(substr($FLVvideoHeader, 7, 1));
|
||||
$numOfSequenceParameterSets = getid3_lib::BigEndian2Int(substr($FLVvideoHeader, 8, 1));
|
||||
|
||||
if (($numOfSequenceParameterSets & 0x1F) != 0) {
|
||||
// there is at least one SequenceParameterSet
|
||||
// read size of the first SequenceParameterSet
|
||||
//$spsSize = getid3_lib::BigEndian2Int(substr($FLVvideoHeader, 9, 2));
|
||||
$spsSize = getid3_lib::LittleEndian2Int(substr($FLVvideoHeader, 9, 2));
|
||||
// read the first SequenceParameterSet
|
||||
$sps = $this->fread($spsSize);
|
||||
if (strlen($sps) == $spsSize) { // make sure that whole SequenceParameterSet was red
|
||||
$spsReader = new AVCSequenceParameterSetReader($sps);
|
||||
$spsReader->readData();
|
||||
$info['video']['resolution_x'] = $spsReader->getWidth();
|
||||
$info['video']['resolution_y'] = $spsReader->getHeight();
|
||||
}
|
||||
}
|
||||
}
|
||||
// end: moysevichØgmail*com
|
||||
|
||||
} elseif ($info['flv']['video']['videoCodec'] == GETID3_FLV_VIDEO_H263) {
|
||||
|
||||
$PictureSizeType = (getid3_lib::BigEndian2Int(substr($FLVvideoHeader, 3, 2))) >> 7;
|
||||
$PictureSizeType = $PictureSizeType & 0x0007;
|
||||
$info['flv']['header']['videoSizeType'] = $PictureSizeType;
|
||||
switch ($PictureSizeType) {
|
||||
case 0:
|
||||
//$PictureSizeEnc = getid3_lib::BigEndian2Int(substr($FLVvideoHeader, 5, 2));
|
||||
//$PictureSizeEnc <<= 1;
|
||||
//$info['video']['resolution_x'] = ($PictureSizeEnc & 0xFF00) >> 8;
|
||||
//$PictureSizeEnc = getid3_lib::BigEndian2Int(substr($FLVvideoHeader, 6, 2));
|
||||
//$PictureSizeEnc <<= 1;
|
||||
//$info['video']['resolution_y'] = ($PictureSizeEnc & 0xFF00) >> 8;
|
||||
|
||||
$PictureSizeEnc['x'] = getid3_lib::BigEndian2Int(substr($FLVvideoHeader, 4, 2)) >> 7;
|
||||
$PictureSizeEnc['y'] = getid3_lib::BigEndian2Int(substr($FLVvideoHeader, 5, 2)) >> 7;
|
||||
$info['video']['resolution_x'] = $PictureSizeEnc['x'] & 0xFF;
|
||||
$info['video']['resolution_y'] = $PictureSizeEnc['y'] & 0xFF;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
$PictureSizeEnc['x'] = getid3_lib::BigEndian2Int(substr($FLVvideoHeader, 4, 3)) >> 7;
|
||||
$PictureSizeEnc['y'] = getid3_lib::BigEndian2Int(substr($FLVvideoHeader, 6, 3)) >> 7;
|
||||
$info['video']['resolution_x'] = $PictureSizeEnc['x'] & 0xFFFF;
|
||||
$info['video']['resolution_y'] = $PictureSizeEnc['y'] & 0xFFFF;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
$info['video']['resolution_x'] = 352;
|
||||
$info['video']['resolution_y'] = 288;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
$info['video']['resolution_x'] = 176;
|
||||
$info['video']['resolution_y'] = 144;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
$info['video']['resolution_x'] = 128;
|
||||
$info['video']['resolution_y'] = 96;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
$info['video']['resolution_x'] = 320;
|
||||
$info['video']['resolution_y'] = 240;
|
||||
break;
|
||||
|
||||
case 6:
|
||||
$info['video']['resolution_x'] = 160;
|
||||
$info['video']['resolution_y'] = 120;
|
||||
break;
|
||||
|
||||
default:
|
||||
$info['video']['resolution_x'] = 0;
|
||||
$info['video']['resolution_y'] = 0;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
} elseif ($info['flv']['video']['videoCodec'] == GETID3_FLV_VIDEO_VP6FLV_ALPHA) {
|
||||
|
||||
/* contributed by schouwerwouØgmail*com */
|
||||
if (!isset($info['video']['resolution_x'])) { // only when meta data isn't set
|
||||
$PictureSizeEnc['x'] = getid3_lib::BigEndian2Int(substr($FLVvideoHeader, 6, 2));
|
||||
$PictureSizeEnc['y'] = getid3_lib::BigEndian2Int(substr($FLVvideoHeader, 7, 2));
|
||||
$info['video']['resolution_x'] = ($PictureSizeEnc['x'] & 0xFF) << 3;
|
||||
$info['video']['resolution_y'] = ($PictureSizeEnc['y'] & 0xFF) << 3;
|
||||
}
|
||||
/* end schouwerwouØgmail*com */
|
||||
|
||||
}
|
||||
if (!empty($info['video']['resolution_x']) && !empty($info['video']['resolution_y'])) {
|
||||
$info['video']['pixel_aspect_ratio'] = $info['video']['resolution_x'] / $info['video']['resolution_y'];
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// Meta tag
|
||||
case GETID3_FLV_TAG_META:
|
||||
if (!$found_meta) {
|
||||
$found_meta = true;
|
||||
$this->fseek(-1, SEEK_CUR);
|
||||
$datachunk = $this->fread($DataLength);
|
||||
$AMFstream = new AMFStream($datachunk);
|
||||
$reader = new AMFReader($AMFstream);
|
||||
$eventName = $reader->readData();
|
||||
$info['flv']['meta'][$eventName] = $reader->readData();
|
||||
unset($reader);
|
||||
|
||||
$copykeys = array('framerate'=>'frame_rate', 'width'=>'resolution_x', 'height'=>'resolution_y', 'audiodatarate'=>'bitrate', 'videodatarate'=>'bitrate');
|
||||
foreach ($copykeys as $sourcekey => $destkey) {
|
||||
if (isset($info['flv']['meta']['onMetaData'][$sourcekey])) {
|
||||
switch ($sourcekey) {
|
||||
case 'width':
|
||||
case 'height':
|
||||
$info['video'][$destkey] = intval(round($info['flv']['meta']['onMetaData'][$sourcekey]));
|
||||
break;
|
||||
case 'audiodatarate':
|
||||
$info['audio'][$destkey] = getid3_lib::CastAsInt(round($info['flv']['meta']['onMetaData'][$sourcekey] * 1000));
|
||||
break;
|
||||
case 'videodatarate':
|
||||
case 'frame_rate':
|
||||
default:
|
||||
$info['video'][$destkey] = $info['flv']['meta']['onMetaData'][$sourcekey];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!empty($info['flv']['meta']['onMetaData']['duration'])) {
|
||||
$found_valid_meta_playtime = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// noop
|
||||
break;
|
||||
}
|
||||
$this->fseek($NextOffset);
|
||||
}
|
||||
|
||||
$info['playtime_seconds'] = $Duration / 1000;
|
||||
if ($info['playtime_seconds'] > 0) {
|
||||
$info['bitrate'] = (($info['avdataend'] - $info['avdataoffset']) * 8) / $info['playtime_seconds'];
|
||||
}
|
||||
|
||||
if ($info['flv']['header']['hasAudio']) {
|
||||
$info['audio']['codec'] = self::audioFormatLookup($info['flv']['audio']['audioFormat']);
|
||||
$info['audio']['sample_rate'] = self::audioRateLookup($info['flv']['audio']['audioRate']);
|
||||
$info['audio']['bits_per_sample'] = self::audioBitDepthLookup($info['flv']['audio']['audioSampleSize']);
|
||||
|
||||
$info['audio']['channels'] = $info['flv']['audio']['audioType'] + 1; // 0=mono,1=stereo
|
||||
$info['audio']['lossless'] = ($info['flv']['audio']['audioFormat'] ? false : true); // 0=uncompressed
|
||||
$info['audio']['dataformat'] = 'flv';
|
||||
}
|
||||
if (!empty($info['flv']['header']['hasVideo'])) {
|
||||
$info['video']['codec'] = self::videoCodecLookup($info['flv']['video']['videoCodec']);
|
||||
$info['video']['dataformat'] = 'flv';
|
||||
$info['video']['lossless'] = false;
|
||||
}
|
||||
|
||||
// Set information from meta
|
||||
if (!empty($info['flv']['meta']['onMetaData']['duration'])) {
|
||||
$info['playtime_seconds'] = $info['flv']['meta']['onMetaData']['duration'];
|
||||
$info['bitrate'] = (($info['avdataend'] - $info['avdataoffset']) * 8) / $info['playtime_seconds'];
|
||||
}
|
||||
if (isset($info['flv']['meta']['onMetaData']['audiocodecid'])) {
|
||||
$info['audio']['codec'] = self::audioFormatLookup($info['flv']['meta']['onMetaData']['audiocodecid']);
|
||||
}
|
||||
if (isset($info['flv']['meta']['onMetaData']['videocodecid'])) {
|
||||
$info['video']['codec'] = self::videoCodecLookup($info['flv']['meta']['onMetaData']['videocodecid']);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public static function audioFormatLookup($id) {
|
||||
static $lookup = array(
|
||||
0 => 'Linear PCM, platform endian',
|
||||
1 => 'ADPCM',
|
||||
2 => 'mp3',
|
||||
3 => 'Linear PCM, little endian',
|
||||
4 => 'Nellymoser 16kHz mono',
|
||||
5 => 'Nellymoser 8kHz mono',
|
||||
6 => 'Nellymoser',
|
||||
7 => 'G.711A-law logarithmic PCM',
|
||||
8 => 'G.711 mu-law logarithmic PCM',
|
||||
9 => 'reserved',
|
||||
10 => 'AAC',
|
||||
11 => 'Speex',
|
||||
12 => false, // unknown?
|
||||
13 => false, // unknown?
|
||||
14 => 'mp3 8kHz',
|
||||
15 => 'Device-specific sound',
|
||||
);
|
||||
return (isset($lookup[$id]) ? $lookup[$id] : false);
|
||||
}
|
||||
|
||||
public static function audioRateLookup($id) {
|
||||
static $lookup = array(
|
||||
0 => 5500,
|
||||
1 => 11025,
|
||||
2 => 22050,
|
||||
3 => 44100,
|
||||
);
|
||||
return (isset($lookup[$id]) ? $lookup[$id] : false);
|
||||
}
|
||||
|
||||
public static function audioBitDepthLookup($id) {
|
||||
static $lookup = array(
|
||||
0 => 8,
|
||||
1 => 16,
|
||||
);
|
||||
return (isset($lookup[$id]) ? $lookup[$id] : false);
|
||||
}
|
||||
|
||||
public static function videoCodecLookup($id) {
|
||||
static $lookup = array(
|
||||
GETID3_FLV_VIDEO_H263 => 'Sorenson H.263',
|
||||
GETID3_FLV_VIDEO_SCREEN => 'Screen video',
|
||||
GETID3_FLV_VIDEO_VP6FLV => 'On2 VP6',
|
||||
GETID3_FLV_VIDEO_VP6FLV_ALPHA => 'On2 VP6 with alpha channel',
|
||||
GETID3_FLV_VIDEO_SCREENV2 => 'Screen video v2',
|
||||
GETID3_FLV_VIDEO_H264 => 'Sorenson H.264',
|
||||
);
|
||||
return (isset($lookup[$id]) ? $lookup[$id] : false);
|
||||
}
|
||||
}
|
||||
|
||||
class AMFStream {
|
||||
public $bytes;
|
||||
public $pos;
|
||||
|
||||
public function __construct(&$bytes) {
|
||||
$this->bytes =& $bytes;
|
||||
$this->pos = 0;
|
||||
}
|
||||
|
||||
public function readByte() {
|
||||
return getid3_lib::BigEndian2Int(substr($this->bytes, $this->pos++, 1));
|
||||
}
|
||||
|
||||
public function readInt() {
|
||||
return ($this->readByte() << 8) + $this->readByte();
|
||||
}
|
||||
|
||||
public function readLong() {
|
||||
return ($this->readByte() << 24) + ($this->readByte() << 16) + ($this->readByte() << 8) + $this->readByte();
|
||||
}
|
||||
|
||||
public function readDouble() {
|
||||
return getid3_lib::BigEndian2Float($this->read(8));
|
||||
}
|
||||
|
||||
public function readUTF() {
|
||||
$length = $this->readInt();
|
||||
return $this->read($length);
|
||||
}
|
||||
|
||||
public function readLongUTF() {
|
||||
$length = $this->readLong();
|
||||
return $this->read($length);
|
||||
}
|
||||
|
||||
public function read($length) {
|
||||
$val = substr($this->bytes, $this->pos, $length);
|
||||
$this->pos += $length;
|
||||
return $val;
|
||||
}
|
||||
|
||||
public function peekByte() {
|
||||
$pos = $this->pos;
|
||||
$val = $this->readByte();
|
||||
$this->pos = $pos;
|
||||
return $val;
|
||||
}
|
||||
|
||||
public function peekInt() {
|
||||
$pos = $this->pos;
|
||||
$val = $this->readInt();
|
||||
$this->pos = $pos;
|
||||
return $val;
|
||||
}
|
||||
|
||||
public function peekLong() {
|
||||
$pos = $this->pos;
|
||||
$val = $this->readLong();
|
||||
$this->pos = $pos;
|
||||
return $val;
|
||||
}
|
||||
|
||||
public function peekDouble() {
|
||||
$pos = $this->pos;
|
||||
$val = $this->readDouble();
|
||||
$this->pos = $pos;
|
||||
return $val;
|
||||
}
|
||||
|
||||
public function peekUTF() {
|
||||
$pos = $this->pos;
|
||||
$val = $this->readUTF();
|
||||
$this->pos = $pos;
|
||||
return $val;
|
||||
}
|
||||
|
||||
public function peekLongUTF() {
|
||||
$pos = $this->pos;
|
||||
$val = $this->readLongUTF();
|
||||
$this->pos = $pos;
|
||||
return $val;
|
||||
}
|
||||
}
|
||||
|
||||
class AMFReader {
|
||||
public $stream;
|
||||
|
||||
public function __construct(&$stream) {
|
||||
$this->stream =& $stream;
|
||||
}
|
||||
|
||||
public function readData() {
|
||||
$value = null;
|
||||
|
||||
$type = $this->stream->readByte();
|
||||
switch ($type) {
|
||||
|
||||
// Double
|
||||
case 0:
|
||||
$value = $this->readDouble();
|
||||
break;
|
||||
|
||||
// Boolean
|
||||
case 1:
|
||||
$value = $this->readBoolean();
|
||||
break;
|
||||
|
||||
// String
|
||||
case 2:
|
||||
$value = $this->readString();
|
||||
break;
|
||||
|
||||
// Object
|
||||
case 3:
|
||||
$value = $this->readObject();
|
||||
break;
|
||||
|
||||
// null
|
||||
case 6:
|
||||
return null;
|
||||
break;
|
||||
|
||||
// Mixed array
|
||||
case 8:
|
||||
$value = $this->readMixedArray();
|
||||
break;
|
||||
|
||||
// Array
|
||||
case 10:
|
||||
$value = $this->readArray();
|
||||
break;
|
||||
|
||||
// Date
|
||||
case 11:
|
||||
$value = $this->readDate();
|
||||
break;
|
||||
|
||||
// Long string
|
||||
case 13:
|
||||
$value = $this->readLongString();
|
||||
break;
|
||||
|
||||
// XML (handled as string)
|
||||
case 15:
|
||||
$value = $this->readXML();
|
||||
break;
|
||||
|
||||
// Typed object (handled as object)
|
||||
case 16:
|
||||
$value = $this->readTypedObject();
|
||||
break;
|
||||
|
||||
// Long string
|
||||
default:
|
||||
$value = '(unknown or unsupported data type)';
|
||||
break;
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
public function readDouble() {
|
||||
return $this->stream->readDouble();
|
||||
}
|
||||
|
||||
public function readBoolean() {
|
||||
return $this->stream->readByte() == 1;
|
||||
}
|
||||
|
||||
public function readString() {
|
||||
return $this->stream->readUTF();
|
||||
}
|
||||
|
||||
public function readObject() {
|
||||
// Get highest numerical index - ignored
|
||||
// $highestIndex = $this->stream->readLong();
|
||||
|
||||
$data = array();
|
||||
|
||||
while ($key = $this->stream->readUTF()) {
|
||||
$data[$key] = $this->readData();
|
||||
}
|
||||
// Mixed array record ends with empty string (0x00 0x00) and 0x09
|
||||
if (($key == '') && ($this->stream->peekByte() == 0x09)) {
|
||||
// Consume byte
|
||||
$this->stream->readByte();
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function readMixedArray() {
|
||||
// Get highest numerical index - ignored
|
||||
$highestIndex = $this->stream->readLong();
|
||||
|
||||
$data = array();
|
||||
|
||||
while ($key = $this->stream->readUTF()) {
|
||||
if (is_numeric($key)) {
|
||||
$key = (float) $key;
|
||||
}
|
||||
$data[$key] = $this->readData();
|
||||
}
|
||||
// Mixed array record ends with empty string (0x00 0x00) and 0x09
|
||||
if (($key == '') && ($this->stream->peekByte() == 0x09)) {
|
||||
// Consume byte
|
||||
$this->stream->readByte();
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function readArray() {
|
||||
$length = $this->stream->readLong();
|
||||
$data = array();
|
||||
|
||||
for ($i = 0; $i < $length; $i++) {
|
||||
$data[] = $this->readData();
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function readDate() {
|
||||
$timestamp = $this->stream->readDouble();
|
||||
$timezone = $this->stream->readInt();
|
||||
return $timestamp;
|
||||
}
|
||||
|
||||
public function readLongString() {
|
||||
return $this->stream->readLongUTF();
|
||||
}
|
||||
|
||||
public function readXML() {
|
||||
return $this->stream->readLongUTF();
|
||||
}
|
||||
|
||||
public function readTypedObject() {
|
||||
$className = $this->stream->readUTF();
|
||||
return $this->readObject();
|
||||
}
|
||||
}
|
||||
|
||||
class AVCSequenceParameterSetReader {
|
||||
public $sps;
|
||||
public $start = 0;
|
||||
public $currentBytes = 0;
|
||||
public $currentBits = 0;
|
||||
public $width;
|
||||
public $height;
|
||||
|
||||
public function __construct($sps) {
|
||||
$this->sps = $sps;
|
||||
}
|
||||
|
||||
public function readData() {
|
||||
$this->skipBits(8);
|
||||
$this->skipBits(8);
|
||||
$profile = $this->getBits(8); // read profile
|
||||
if ($profile > 0) {
|
||||
$this->skipBits(8);
|
||||
$level_idc = $this->getBits(8); // level_idc
|
||||
$this->expGolombUe(); // seq_parameter_set_id // sps
|
||||
$this->expGolombUe(); // log2_max_frame_num_minus4
|
||||
$picOrderType = $this->expGolombUe(); // pic_order_cnt_type
|
||||
if ($picOrderType == 0) {
|
||||
$this->expGolombUe(); // log2_max_pic_order_cnt_lsb_minus4
|
||||
} elseif ($picOrderType == 1) {
|
||||
$this->skipBits(1); // delta_pic_order_always_zero_flag
|
||||
$this->expGolombSe(); // offset_for_non_ref_pic
|
||||
$this->expGolombSe(); // offset_for_top_to_bottom_field
|
||||
$num_ref_frames_in_pic_order_cnt_cycle = $this->expGolombUe(); // num_ref_frames_in_pic_order_cnt_cycle
|
||||
for ($i = 0; $i < $num_ref_frames_in_pic_order_cnt_cycle; $i++) {
|
||||
$this->expGolombSe(); // offset_for_ref_frame[ i ]
|
||||
}
|
||||
}
|
||||
$this->expGolombUe(); // num_ref_frames
|
||||
$this->skipBits(1); // gaps_in_frame_num_value_allowed_flag
|
||||
$pic_width_in_mbs_minus1 = $this->expGolombUe(); // pic_width_in_mbs_minus1
|
||||
$pic_height_in_map_units_minus1 = $this->expGolombUe(); // pic_height_in_map_units_minus1
|
||||
|
||||
$frame_mbs_only_flag = $this->getBits(1); // frame_mbs_only_flag
|
||||
if ($frame_mbs_only_flag == 0) {
|
||||
$this->skipBits(1); // mb_adaptive_frame_field_flag
|
||||
}
|
||||
$this->skipBits(1); // direct_8x8_inference_flag
|
||||
$frame_cropping_flag = $this->getBits(1); // frame_cropping_flag
|
||||
|
||||
$frame_crop_left_offset = 0;
|
||||
$frame_crop_right_offset = 0;
|
||||
$frame_crop_top_offset = 0;
|
||||
$frame_crop_bottom_offset = 0;
|
||||
|
||||
if ($frame_cropping_flag) {
|
||||
$frame_crop_left_offset = $this->expGolombUe(); // frame_crop_left_offset
|
||||
$frame_crop_right_offset = $this->expGolombUe(); // frame_crop_right_offset
|
||||
$frame_crop_top_offset = $this->expGolombUe(); // frame_crop_top_offset
|
||||
$frame_crop_bottom_offset = $this->expGolombUe(); // frame_crop_bottom_offset
|
||||
}
|
||||
$this->skipBits(1); // vui_parameters_present_flag
|
||||
// etc
|
||||
|
||||
$this->width = (($pic_width_in_mbs_minus1 + 1) * 16) - ($frame_crop_left_offset * 2) - ($frame_crop_right_offset * 2);
|
||||
$this->height = ((2 - $frame_mbs_only_flag) * ($pic_height_in_map_units_minus1 + 1) * 16) - ($frame_crop_top_offset * 2) - ($frame_crop_bottom_offset * 2);
|
||||
}
|
||||
}
|
||||
|
||||
public function skipBits($bits) {
|
||||
$newBits = $this->currentBits + $bits;
|
||||
$this->currentBytes += (int)floor($newBits / 8);
|
||||
$this->currentBits = $newBits % 8;
|
||||
}
|
||||
|
||||
public function getBit() {
|
||||
$result = (getid3_lib::BigEndian2Int(substr($this->sps, $this->currentBytes, 1)) >> (7 - $this->currentBits)) & 0x01;
|
||||
$this->skipBits(1);
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function getBits($bits) {
|
||||
$result = 0;
|
||||
for ($i = 0; $i < $bits; $i++) {
|
||||
$result = ($result << 1) + $this->getBit();
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function expGolombUe() {
|
||||
$significantBits = 0;
|
||||
$bit = $this->getBit();
|
||||
while ($bit == 0) {
|
||||
$significantBits++;
|
||||
$bit = $this->getBit();
|
||||
|
||||
if ($significantBits > 31) {
|
||||
// something is broken, this is an emergency escape to prevent infinite loops
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return (1 << $significantBits) + $this->getBits($significantBits) - 1;
|
||||
}
|
||||
|
||||
public function expGolombSe() {
|
||||
$result = $this->expGolombUe();
|
||||
if (($result & 0x01) == 0) {
|
||||
return -($result >> 1);
|
||||
} else {
|
||||
return ($result + 1) >> 1;
|
||||
}
|
||||
}
|
||||
|
||||
public function getWidth() {
|
||||
return $this->width;
|
||||
}
|
||||
|
||||
public function getHeight() {
|
||||
return $this->height;
|
||||
}
|
||||
}
|
||||
1751
Kapitel_7/Lektion_4/wordpress/wp-includes/ID3/module.audio-video.matroska.php
Executable file
1751
Kapitel_7/Lektion_4/wordpress/wp-includes/ID3/module.audio-video.matroska.php
Executable file
File diff suppressed because it is too large
Load Diff
2246
Kapitel_7/Lektion_4/wordpress/wp-includes/ID3/module.audio-video.quicktime.php
Executable file
2246
Kapitel_7/Lektion_4/wordpress/wp-includes/ID3/module.audio-video.quicktime.php
Executable file
File diff suppressed because it is too large
Load Diff
2586
Kapitel_7/Lektion_4/wordpress/wp-includes/ID3/module.audio-video.riff.php
Executable file
2586
Kapitel_7/Lektion_4/wordpress/wp-includes/ID3/module.audio-video.riff.php
Executable file
File diff suppressed because it is too large
Load Diff
474
Kapitel_7/Lektion_4/wordpress/wp-includes/ID3/module.audio.ac3.php
Executable file
474
Kapitel_7/Lektion_4/wordpress/wp-includes/ID3/module.audio.ac3.php
Executable file
@@ -0,0 +1,474 @@
|
||||
<?php
|
||||
/////////////////////////////////////////////////////////////////
|
||||
/// getID3() by James Heinrich <info@getid3.org> //
|
||||
// available at http://getid3.sourceforge.net //
|
||||
// or http://www.getid3.org //
|
||||
// also https://github.com/JamesHeinrich/getID3 //
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// See readme.txt for more details //
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// module.audio.ac3.php //
|
||||
// module for analyzing AC-3 (aka Dolby Digital) audio files //
|
||||
// dependencies: NONE //
|
||||
// ///
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
class getid3_ac3 extends getid3_handler
|
||||
{
|
||||
private $AC3header = array();
|
||||
private $BSIoffset = 0;
|
||||
|
||||
const syncword = "\x0B\x77";
|
||||
|
||||
public function Analyze() {
|
||||
$info = &$this->getid3->info;
|
||||
|
||||
///AH
|
||||
$info['ac3']['raw']['bsi'] = array();
|
||||
$thisfile_ac3 = &$info['ac3'];
|
||||
$thisfile_ac3_raw = &$thisfile_ac3['raw'];
|
||||
$thisfile_ac3_raw_bsi = &$thisfile_ac3_raw['bsi'];
|
||||
|
||||
|
||||
// http://www.atsc.org/standards/a_52a.pdf
|
||||
|
||||
$info['fileformat'] = 'ac3';
|
||||
|
||||
// An AC-3 serial coded audio bit stream is made up of a sequence of synchronization frames
|
||||
// Each synchronization frame contains 6 coded audio blocks (AB), each of which represent 256
|
||||
// new audio samples per channel. A synchronization information (SI) header at the beginning
|
||||
// of each frame contains information needed to acquire and maintain synchronization. A
|
||||
// bit stream information (BSI) header follows SI, and contains parameters describing the coded
|
||||
// audio service. The coded audio blocks may be followed by an auxiliary data (Aux) field. At the
|
||||
// end of each frame is an error check field that includes a CRC word for error detection. An
|
||||
// additional CRC word is located in the SI header, the use of which, by a decoder, is optional.
|
||||
//
|
||||
// syncinfo() | bsi() | AB0 | AB1 | AB2 | AB3 | AB4 | AB5 | Aux | CRC
|
||||
|
||||
// syncinfo() {
|
||||
// syncword 16
|
||||
// crc1 16
|
||||
// fscod 2
|
||||
// frmsizecod 6
|
||||
// } /* end of syncinfo */
|
||||
|
||||
$this->fseek($info['avdataoffset']);
|
||||
$this->AC3header['syncinfo'] = $this->fread(5);
|
||||
|
||||
if (strpos($this->AC3header['syncinfo'], self::syncword) === 0) {
|
||||
$thisfile_ac3_raw['synchinfo']['synchword'] = self::syncword;
|
||||
$offset = 2;
|
||||
} else {
|
||||
if (!$this->isDependencyFor('matroska')) {
|
||||
unset($info['fileformat'], $info['ac3']);
|
||||
return $this->error('Expecting "'.getid3_lib::PrintHexBytes(self::syncword).'" at offset '.$info['avdataoffset'].', found "'.getid3_lib::PrintHexBytes(substr($this->AC3header['syncinfo'], 0, 2)).'"');
|
||||
}
|
||||
$offset = 0;
|
||||
$this->fseek(-2, SEEK_CUR);
|
||||
}
|
||||
|
||||
$info['audio']['dataformat'] = 'ac3';
|
||||
$info['audio']['bitrate_mode'] = 'cbr';
|
||||
$info['audio']['lossless'] = false;
|
||||
|
||||
$thisfile_ac3_raw['synchinfo']['crc1'] = getid3_lib::LittleEndian2Int(substr($this->AC3header['syncinfo'], $offset, 2));
|
||||
$ac3_synchinfo_fscod_frmsizecod = getid3_lib::LittleEndian2Int(substr($this->AC3header['syncinfo'], ($offset + 2), 1));
|
||||
$thisfile_ac3_raw['synchinfo']['fscod'] = ($ac3_synchinfo_fscod_frmsizecod & 0xC0) >> 6;
|
||||
$thisfile_ac3_raw['synchinfo']['frmsizecod'] = ($ac3_synchinfo_fscod_frmsizecod & 0x3F);
|
||||
|
||||
$thisfile_ac3['sample_rate'] = self::sampleRateCodeLookup($thisfile_ac3_raw['synchinfo']['fscod']);
|
||||
if ($thisfile_ac3_raw['synchinfo']['fscod'] <= 3) {
|
||||
$info['audio']['sample_rate'] = $thisfile_ac3['sample_rate'];
|
||||
}
|
||||
|
||||
$thisfile_ac3['frame_length'] = self::frameSizeLookup($thisfile_ac3_raw['synchinfo']['frmsizecod'], $thisfile_ac3_raw['synchinfo']['fscod']);
|
||||
$thisfile_ac3['bitrate'] = self::bitrateLookup($thisfile_ac3_raw['synchinfo']['frmsizecod']);
|
||||
$info['audio']['bitrate'] = $thisfile_ac3['bitrate'];
|
||||
|
||||
$this->AC3header['bsi'] = getid3_lib::BigEndian2Bin($this->fread(15));
|
||||
$ac3_bsi_offset = 0;
|
||||
|
||||
$thisfile_ac3_raw_bsi['bsid'] = $this->readHeaderBSI(5);
|
||||
if ($thisfile_ac3_raw_bsi['bsid'] > 8) {
|
||||
// Decoders which can decode version 8 will thus be able to decode version numbers less than 8.
|
||||
// If this standard is extended by the addition of additional elements or features, a value of bsid greater than 8 will be used.
|
||||
// Decoders built to this version of the standard will not be able to decode versions with bsid greater than 8.
|
||||
$this->error('Bit stream identification is version '.$thisfile_ac3_raw_bsi['bsid'].', but getID3() only understands up to version 8');
|
||||
unset($info['ac3']);
|
||||
return false;
|
||||
}
|
||||
|
||||
$thisfile_ac3_raw_bsi['bsmod'] = $this->readHeaderBSI(3);
|
||||
$thisfile_ac3_raw_bsi['acmod'] = $this->readHeaderBSI(3);
|
||||
|
||||
$thisfile_ac3['service_type'] = self::serviceTypeLookup($thisfile_ac3_raw_bsi['bsmod'], $thisfile_ac3_raw_bsi['acmod']);
|
||||
$ac3_coding_mode = self::audioCodingModeLookup($thisfile_ac3_raw_bsi['acmod']);
|
||||
foreach($ac3_coding_mode as $key => $value) {
|
||||
$thisfile_ac3[$key] = $value;
|
||||
}
|
||||
switch ($thisfile_ac3_raw_bsi['acmod']) {
|
||||
case 0:
|
||||
case 1:
|
||||
$info['audio']['channelmode'] = 'mono';
|
||||
break;
|
||||
case 3:
|
||||
case 4:
|
||||
$info['audio']['channelmode'] = 'stereo';
|
||||
break;
|
||||
default:
|
||||
$info['audio']['channelmode'] = 'surround';
|
||||
break;
|
||||
}
|
||||
$info['audio']['channels'] = $thisfile_ac3['num_channels'];
|
||||
|
||||
if ($thisfile_ac3_raw_bsi['acmod'] & 0x01) {
|
||||
// If the lsb of acmod is a 1, center channel is in use and cmixlev follows in the bit stream.
|
||||
$thisfile_ac3_raw_bsi['cmixlev'] = $this->readHeaderBSI(2);
|
||||
$thisfile_ac3['center_mix_level'] = self::centerMixLevelLookup($thisfile_ac3_raw_bsi['cmixlev']);
|
||||
}
|
||||
|
||||
if ($thisfile_ac3_raw_bsi['acmod'] & 0x04) {
|
||||
// If the msb of acmod is a 1, surround channels are in use and surmixlev follows in the bit stream.
|
||||
$thisfile_ac3_raw_bsi['surmixlev'] = $this->readHeaderBSI(2);
|
||||
$thisfile_ac3['surround_mix_level'] = self::surroundMixLevelLookup($thisfile_ac3_raw_bsi['surmixlev']);
|
||||
}
|
||||
|
||||
if ($thisfile_ac3_raw_bsi['acmod'] == 0x02) {
|
||||
// When operating in the two channel mode, this 2-bit code indicates whether or not the program has been encoded in Dolby Surround.
|
||||
$thisfile_ac3_raw_bsi['dsurmod'] = $this->readHeaderBSI(2);
|
||||
$thisfile_ac3['dolby_surround_mode'] = self::dolbySurroundModeLookup($thisfile_ac3_raw_bsi['dsurmod']);
|
||||
}
|
||||
|
||||
$thisfile_ac3_raw_bsi['lfeon'] = (bool) $this->readHeaderBSI(1);
|
||||
$thisfile_ac3['lfe_enabled'] = $thisfile_ac3_raw_bsi['lfeon'];
|
||||
if ($thisfile_ac3_raw_bsi['lfeon']) {
|
||||
//$info['audio']['channels']++;
|
||||
$info['audio']['channels'] .= '.1';
|
||||
}
|
||||
|
||||
$thisfile_ac3['channels_enabled'] = self::channelsEnabledLookup($thisfile_ac3_raw_bsi['acmod'], $thisfile_ac3_raw_bsi['lfeon']);
|
||||
|
||||
// This indicates how far the average dialogue level is below digital 100 percent. Valid values are 1-31.
|
||||
// The value of 0 is reserved. The values of 1 to 31 are interpreted as -1 dB to -31 dB with respect to digital 100 percent.
|
||||
$thisfile_ac3_raw_bsi['dialnorm'] = $this->readHeaderBSI(5);
|
||||
$thisfile_ac3['dialogue_normalization'] = '-'.$thisfile_ac3_raw_bsi['dialnorm'].'dB';
|
||||
|
||||
$thisfile_ac3_raw_bsi['compre_flag'] = (bool) $this->readHeaderBSI(1);
|
||||
if ($thisfile_ac3_raw_bsi['compre_flag']) {
|
||||
$thisfile_ac3_raw_bsi['compr'] = $this->readHeaderBSI(8);
|
||||
$thisfile_ac3['heavy_compression'] = self::heavyCompression($thisfile_ac3_raw_bsi['compr']);
|
||||
}
|
||||
|
||||
$thisfile_ac3_raw_bsi['langcode_flag'] = (bool) $this->readHeaderBSI(1);
|
||||
if ($thisfile_ac3_raw_bsi['langcode_flag']) {
|
||||
$thisfile_ac3_raw_bsi['langcod'] = $this->readHeaderBSI(8);
|
||||
}
|
||||
|
||||
$thisfile_ac3_raw_bsi['audprodie'] = (bool) $this->readHeaderBSI(1);
|
||||
if ($thisfile_ac3_raw_bsi['audprodie']) {
|
||||
$thisfile_ac3_raw_bsi['mixlevel'] = $this->readHeaderBSI(5);
|
||||
$thisfile_ac3_raw_bsi['roomtyp'] = $this->readHeaderBSI(2);
|
||||
|
||||
$thisfile_ac3['mixing_level'] = (80 + $thisfile_ac3_raw_bsi['mixlevel']).'dB';
|
||||
$thisfile_ac3['room_type'] = self::roomTypeLookup($thisfile_ac3_raw_bsi['roomtyp']);
|
||||
}
|
||||
|
||||
if ($thisfile_ac3_raw_bsi['acmod'] == 0x00) {
|
||||
// If acmod is 0, then two completely independent program channels (dual mono)
|
||||
// are encoded into the bit stream, and are referenced as Ch1, Ch2. In this case,
|
||||
// a number of additional items are present in BSI or audblk to fully describe Ch2.
|
||||
|
||||
// This indicates how far the average dialogue level is below digital 100 percent. Valid values are 1-31.
|
||||
// The value of 0 is reserved. The values of 1 to 31 are interpreted as -1 dB to -31 dB with respect to digital 100 percent.
|
||||
$thisfile_ac3_raw_bsi['dialnorm2'] = $this->readHeaderBSI(5);
|
||||
$thisfile_ac3['dialogue_normalization2'] = '-'.$thisfile_ac3_raw_bsi['dialnorm2'].'dB';
|
||||
|
||||
$thisfile_ac3_raw_bsi['compre_flag2'] = (bool) $this->readHeaderBSI(1);
|
||||
if ($thisfile_ac3_raw_bsi['compre_flag2']) {
|
||||
$thisfile_ac3_raw_bsi['compr2'] = $this->readHeaderBSI(8);
|
||||
$thisfile_ac3['heavy_compression2'] = self::heavyCompression($thisfile_ac3_raw_bsi['compr2']);
|
||||
}
|
||||
|
||||
$thisfile_ac3_raw_bsi['langcode_flag2'] = (bool) $this->readHeaderBSI(1);
|
||||
if ($thisfile_ac3_raw_bsi['langcode_flag2']) {
|
||||
$thisfile_ac3_raw_bsi['langcod2'] = $this->readHeaderBSI(8);
|
||||
}
|
||||
|
||||
$thisfile_ac3_raw_bsi['audprodie2'] = (bool) $this->readHeaderBSI(1);
|
||||
if ($thisfile_ac3_raw_bsi['audprodie2']) {
|
||||
$thisfile_ac3_raw_bsi['mixlevel2'] = $this->readHeaderBSI(5);
|
||||
$thisfile_ac3_raw_bsi['roomtyp2'] = $this->readHeaderBSI(2);
|
||||
|
||||
$thisfile_ac3['mixing_level2'] = (80 + $thisfile_ac3_raw_bsi['mixlevel2']).'dB';
|
||||
$thisfile_ac3['room_type2'] = self::roomTypeLookup($thisfile_ac3_raw_bsi['roomtyp2']);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$thisfile_ac3_raw_bsi['copyright'] = (bool) $this->readHeaderBSI(1);
|
||||
|
||||
$thisfile_ac3_raw_bsi['original'] = (bool) $this->readHeaderBSI(1);
|
||||
|
||||
$thisfile_ac3_raw_bsi['timecode1_flag'] = (bool) $this->readHeaderBSI(1);
|
||||
if ($thisfile_ac3_raw_bsi['timecode1_flag']) {
|
||||
$thisfile_ac3_raw_bsi['timecode1'] = $this->readHeaderBSI(14);
|
||||
}
|
||||
|
||||
$thisfile_ac3_raw_bsi['timecode2_flag'] = (bool) $this->readHeaderBSI(1);
|
||||
if ($thisfile_ac3_raw_bsi['timecode2_flag']) {
|
||||
$thisfile_ac3_raw_bsi['timecode2'] = $this->readHeaderBSI(14);
|
||||
}
|
||||
|
||||
$thisfile_ac3_raw_bsi['addbsi_flag'] = (bool) $this->readHeaderBSI(1);
|
||||
if ($thisfile_ac3_raw_bsi['addbsi_flag']) {
|
||||
$thisfile_ac3_raw_bsi['addbsi_length'] = $this->readHeaderBSI(6);
|
||||
|
||||
$this->AC3header['bsi'] .= getid3_lib::BigEndian2Bin($this->fread($thisfile_ac3_raw_bsi['addbsi_length']));
|
||||
|
||||
$thisfile_ac3_raw_bsi['addbsi_data'] = substr($this->AC3header['bsi'], $this->BSIoffset, $thisfile_ac3_raw_bsi['addbsi_length'] * 8);
|
||||
$this->BSIoffset += $thisfile_ac3_raw_bsi['addbsi_length'] * 8;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private function readHeaderBSI($length) {
|
||||
$data = substr($this->AC3header['bsi'], $this->BSIoffset, $length);
|
||||
$this->BSIoffset += $length;
|
||||
|
||||
return bindec($data);
|
||||
}
|
||||
|
||||
public static function sampleRateCodeLookup($fscod) {
|
||||
static $sampleRateCodeLookup = array(
|
||||
0 => 48000,
|
||||
1 => 44100,
|
||||
2 => 32000,
|
||||
3 => 'reserved' // If the reserved code is indicated, the decoder should not attempt to decode audio and should mute.
|
||||
);
|
||||
return (isset($sampleRateCodeLookup[$fscod]) ? $sampleRateCodeLookup[$fscod] : false);
|
||||
}
|
||||
|
||||
public static function serviceTypeLookup($bsmod, $acmod) {
|
||||
static $serviceTypeLookup = array();
|
||||
if (empty($serviceTypeLookup)) {
|
||||
for ($i = 0; $i <= 7; $i++) {
|
||||
$serviceTypeLookup[0][$i] = 'main audio service: complete main (CM)';
|
||||
$serviceTypeLookup[1][$i] = 'main audio service: music and effects (ME)';
|
||||
$serviceTypeLookup[2][$i] = 'associated service: visually impaired (VI)';
|
||||
$serviceTypeLookup[3][$i] = 'associated service: hearing impaired (HI)';
|
||||
$serviceTypeLookup[4][$i] = 'associated service: dialogue (D)';
|
||||
$serviceTypeLookup[5][$i] = 'associated service: commentary (C)';
|
||||
$serviceTypeLookup[6][$i] = 'associated service: emergency (E)';
|
||||
}
|
||||
|
||||
$serviceTypeLookup[7][1] = 'associated service: voice over (VO)';
|
||||
for ($i = 2; $i <= 7; $i++) {
|
||||
$serviceTypeLookup[7][$i] = 'main audio service: karaoke';
|
||||
}
|
||||
}
|
||||
return (isset($serviceTypeLookup[$bsmod][$acmod]) ? $serviceTypeLookup[$bsmod][$acmod] : false);
|
||||
}
|
||||
|
||||
public static function audioCodingModeLookup($acmod) {
|
||||
// array(channel configuration, # channels (not incl LFE), channel order)
|
||||
static $audioCodingModeLookup = array (
|
||||
0 => array('channel_config'=>'1+1', 'num_channels'=>2, 'channel_order'=>'Ch1,Ch2'),
|
||||
1 => array('channel_config'=>'1/0', 'num_channels'=>1, 'channel_order'=>'C'),
|
||||
2 => array('channel_config'=>'2/0', 'num_channels'=>2, 'channel_order'=>'L,R'),
|
||||
3 => array('channel_config'=>'3/0', 'num_channels'=>3, 'channel_order'=>'L,C,R'),
|
||||
4 => array('channel_config'=>'2/1', 'num_channels'=>3, 'channel_order'=>'L,R,S'),
|
||||
5 => array('channel_config'=>'3/1', 'num_channels'=>4, 'channel_order'=>'L,C,R,S'),
|
||||
6 => array('channel_config'=>'2/2', 'num_channels'=>4, 'channel_order'=>'L,R,SL,SR'),
|
||||
7 => array('channel_config'=>'3/2', 'num_channels'=>5, 'channel_order'=>'L,C,R,SL,SR'),
|
||||
);
|
||||
return (isset($audioCodingModeLookup[$acmod]) ? $audioCodingModeLookup[$acmod] : false);
|
||||
}
|
||||
|
||||
public static function centerMixLevelLookup($cmixlev) {
|
||||
static $centerMixLevelLookup;
|
||||
if (empty($centerMixLevelLookup)) {
|
||||
$centerMixLevelLookup = array(
|
||||
0 => pow(2, -3.0 / 6), // 0.707 (-3.0 dB)
|
||||
1 => pow(2, -4.5 / 6), // 0.595 (-4.5 dB)
|
||||
2 => pow(2, -6.0 / 6), // 0.500 (-6.0 dB)
|
||||
3 => 'reserved'
|
||||
);
|
||||
}
|
||||
return (isset($centerMixLevelLookup[$cmixlev]) ? $centerMixLevelLookup[$cmixlev] : false);
|
||||
}
|
||||
|
||||
public static function surroundMixLevelLookup($surmixlev) {
|
||||
static $surroundMixLevelLookup;
|
||||
if (empty($surroundMixLevelLookup)) {
|
||||
$surroundMixLevelLookup = array(
|
||||
0 => pow(2, -3.0 / 6),
|
||||
1 => pow(2, -6.0 / 6),
|
||||
2 => 0,
|
||||
3 => 'reserved'
|
||||
);
|
||||
}
|
||||
return (isset($surroundMixLevelLookup[$surmixlev]) ? $surroundMixLevelLookup[$surmixlev] : false);
|
||||
}
|
||||
|
||||
public static function dolbySurroundModeLookup($dsurmod) {
|
||||
static $dolbySurroundModeLookup = array(
|
||||
0 => 'not indicated',
|
||||
1 => 'Not Dolby Surround encoded',
|
||||
2 => 'Dolby Surround encoded',
|
||||
3 => 'reserved'
|
||||
);
|
||||
return (isset($dolbySurroundModeLookup[$dsurmod]) ? $dolbySurroundModeLookup[$dsurmod] : false);
|
||||
}
|
||||
|
||||
public static function channelsEnabledLookup($acmod, $lfeon) {
|
||||
$lookup = array(
|
||||
'ch1'=>(bool) ($acmod == 0),
|
||||
'ch2'=>(bool) ($acmod == 0),
|
||||
'left'=>(bool) ($acmod > 1),
|
||||
'right'=>(bool) ($acmod > 1),
|
||||
'center'=>(bool) ($acmod & 0x01),
|
||||
'surround_mono'=>false,
|
||||
'surround_left'=>false,
|
||||
'surround_right'=>false,
|
||||
'lfe'=>$lfeon);
|
||||
switch ($acmod) {
|
||||
case 4:
|
||||
case 5:
|
||||
$lookup['surround_mono'] = true;
|
||||
break;
|
||||
case 6:
|
||||
case 7:
|
||||
$lookup['surround_left'] = true;
|
||||
$lookup['surround_right'] = true;
|
||||
break;
|
||||
}
|
||||
return $lookup;
|
||||
}
|
||||
|
||||
public static function heavyCompression($compre) {
|
||||
// The first four bits indicate gain changes in 6.02dB increments which can be
|
||||
// implemented with an arithmetic shift operation. The following four bits
|
||||
// indicate linear gain changes, and require a 5-bit multiply.
|
||||
// We will represent the two 4-bit fields of compr as follows:
|
||||
// X0 X1 X2 X3 . Y4 Y5 Y6 Y7
|
||||
// The meaning of the X values is most simply described by considering X to represent a 4-bit
|
||||
// signed integer with values from -8 to +7. The gain indicated by X is then (X + 1) * 6.02 dB. The
|
||||
// following table shows this in detail.
|
||||
|
||||
// Meaning of 4 msb of compr
|
||||
// 7 +48.16 dB
|
||||
// 6 +42.14 dB
|
||||
// 5 +36.12 dB
|
||||
// 4 +30.10 dB
|
||||
// 3 +24.08 dB
|
||||
// 2 +18.06 dB
|
||||
// 1 +12.04 dB
|
||||
// 0 +6.02 dB
|
||||
// -1 0 dB
|
||||
// -2 -6.02 dB
|
||||
// -3 -12.04 dB
|
||||
// -4 -18.06 dB
|
||||
// -5 -24.08 dB
|
||||
// -6 -30.10 dB
|
||||
// -7 -36.12 dB
|
||||
// -8 -42.14 dB
|
||||
|
||||
$fourbit = str_pad(decbin(($compre & 0xF0) >> 4), 4, '0', STR_PAD_LEFT);
|
||||
if ($fourbit{0} == '1') {
|
||||
$log_gain = -8 + bindec(substr($fourbit, 1));
|
||||
} else {
|
||||
$log_gain = bindec(substr($fourbit, 1));
|
||||
}
|
||||
$log_gain = ($log_gain + 1) * getid3_lib::RGADamplitude2dB(2);
|
||||
|
||||
// The value of Y is a linear representation of a gain change of up to -6 dB. Y is considered to
|
||||
// be an unsigned fractional integer, with a leading value of 1, or: 0.1 Y4 Y5 Y6 Y7 (base 2). Y can
|
||||
// represent values between 0.111112 (or 31/32) and 0.100002 (or 1/2). Thus, Y can represent gain
|
||||
// changes from -0.28 dB to -6.02 dB.
|
||||
|
||||
$lin_gain = (16 + ($compre & 0x0F)) / 32;
|
||||
|
||||
// The combination of X and Y values allows compr to indicate gain changes from
|
||||
// 48.16 - 0.28 = +47.89 dB, to
|
||||
// -42.14 - 6.02 = -48.16 dB.
|
||||
|
||||
return $log_gain - $lin_gain;
|
||||
}
|
||||
|
||||
public static function roomTypeLookup($roomtyp) {
|
||||
static $roomTypeLookup = array(
|
||||
0 => 'not indicated',
|
||||
1 => 'large room, X curve monitor',
|
||||
2 => 'small room, flat monitor',
|
||||
3 => 'reserved'
|
||||
);
|
||||
return (isset($roomTypeLookup[$roomtyp]) ? $roomTypeLookup[$roomtyp] : false);
|
||||
}
|
||||
|
||||
public static function frameSizeLookup($frmsizecod, $fscod) {
|
||||
$padding = (bool) ($frmsizecod % 2);
|
||||
$framesizeid = floor($frmsizecod / 2);
|
||||
|
||||
static $frameSizeLookup = array();
|
||||
if (empty($frameSizeLookup)) {
|
||||
$frameSizeLookup = array (
|
||||
0 => array(128, 138, 192),
|
||||
1 => array(40, 160, 174, 240),
|
||||
2 => array(48, 192, 208, 288),
|
||||
3 => array(56, 224, 242, 336),
|
||||
4 => array(64, 256, 278, 384),
|
||||
5 => array(80, 320, 348, 480),
|
||||
6 => array(96, 384, 416, 576),
|
||||
7 => array(112, 448, 486, 672),
|
||||
8 => array(128, 512, 556, 768),
|
||||
9 => array(160, 640, 696, 960),
|
||||
10 => array(192, 768, 834, 1152),
|
||||
11 => array(224, 896, 974, 1344),
|
||||
12 => array(256, 1024, 1114, 1536),
|
||||
13 => array(320, 1280, 1392, 1920),
|
||||
14 => array(384, 1536, 1670, 2304),
|
||||
15 => array(448, 1792, 1950, 2688),
|
||||
16 => array(512, 2048, 2228, 3072),
|
||||
17 => array(576, 2304, 2506, 3456),
|
||||
18 => array(640, 2560, 2786, 3840)
|
||||
);
|
||||
}
|
||||
if (($fscod == 1) && $padding) {
|
||||
// frame lengths are padded by 1 word (16 bits) at 44100
|
||||
$frameSizeLookup[$frmsizecod] += 2;
|
||||
}
|
||||
return (isset($frameSizeLookup[$framesizeid][$fscod]) ? $frameSizeLookup[$framesizeid][$fscod] : false);
|
||||
}
|
||||
|
||||
public static function bitrateLookup($frmsizecod) {
|
||||
$framesizeid = floor($frmsizecod / 2);
|
||||
|
||||
static $bitrateLookup = array(
|
||||
0 => 32000,
|
||||
1 => 40000,
|
||||
2 => 48000,
|
||||
3 => 56000,
|
||||
4 => 64000,
|
||||
5 => 80000,
|
||||
6 => 96000,
|
||||
7 => 112000,
|
||||
8 => 128000,
|
||||
9 => 160000,
|
||||
10 => 192000,
|
||||
11 => 224000,
|
||||
12 => 256000,
|
||||
13 => 320000,
|
||||
14 => 384000,
|
||||
15 => 448000,
|
||||
16 => 512000,
|
||||
17 => 576000,
|
||||
18 => 640000
|
||||
);
|
||||
return (isset($bitrateLookup[$framesizeid]) ? $bitrateLookup[$framesizeid] : false);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
291
Kapitel_7/Lektion_4/wordpress/wp-includes/ID3/module.audio.dts.php
Executable file
291
Kapitel_7/Lektion_4/wordpress/wp-includes/ID3/module.audio.dts.php
Executable file
@@ -0,0 +1,291 @@
|
||||
<?php
|
||||
/////////////////////////////////////////////////////////////////
|
||||
/// getID3() by James Heinrich <info@getid3.org> //
|
||||
// available at http://getid3.sourceforge.net //
|
||||
// or http://www.getid3.org //
|
||||
// also https://github.com/JamesHeinrich/getID3 //
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// See readme.txt for more details //
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// module.audio.dts.php //
|
||||
// module for analyzing DTS Audio files //
|
||||
// dependencies: NONE //
|
||||
// //
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/**
|
||||
* @tutorial http://wiki.multimedia.cx/index.php?title=DTS
|
||||
*/
|
||||
class getid3_dts extends getid3_handler
|
||||
{
|
||||
/**
|
||||
* Default DTS syncword used in native .cpt or .dts formats
|
||||
*/
|
||||
const syncword = "\x7F\xFE\x80\x01";
|
||||
|
||||
private $readBinDataOffset = 0;
|
||||
|
||||
/**
|
||||
* Possible syncwords indicating bitstream encoding
|
||||
*/
|
||||
public static $syncwords = array(
|
||||
0 => "\x7F\xFE\x80\x01", // raw big-endian
|
||||
1 => "\xFE\x7F\x01\x80", // raw little-endian
|
||||
2 => "\x1F\xFF\xE8\x00", // 14-bit big-endian
|
||||
3 => "\xFF\x1F\x00\xE8"); // 14-bit little-endian
|
||||
|
||||
public function Analyze() {
|
||||
$info = &$this->getid3->info;
|
||||
$info['fileformat'] = 'dts';
|
||||
|
||||
$this->fseek($info['avdataoffset']);
|
||||
$DTSheader = $this->fread(20); // we only need 2 words magic + 6 words frame header, but these words may be normal 16-bit words OR 14-bit words with 2 highest bits set to zero, so 8 words can be either 8*16/8 = 16 bytes OR 8*16*(16/14)/8 = 18.3 bytes
|
||||
|
||||
// check syncword
|
||||
$sync = substr($DTSheader, 0, 4);
|
||||
if (($encoding = array_search($sync, self::$syncwords)) !== false) {
|
||||
|
||||
$info['dts']['raw']['magic'] = $sync;
|
||||
$this->readBinDataOffset = 32;
|
||||
|
||||
} elseif ($this->isDependencyFor('matroska')) {
|
||||
|
||||
// Matroska contains DTS without syncword encoded as raw big-endian format
|
||||
$encoding = 0;
|
||||
$this->readBinDataOffset = 0;
|
||||
|
||||
} else {
|
||||
|
||||
unset($info['fileformat']);
|
||||
return $this->error('Expecting "'.implode('| ', array_map('getid3_lib::PrintHexBytes', self::$syncwords)).'" at offset '.$info['avdataoffset'].', found "'.getid3_lib::PrintHexBytes($sync).'"');
|
||||
|
||||
}
|
||||
|
||||
// decode header
|
||||
$fhBS = '';
|
||||
for ($word_offset = 0; $word_offset <= strlen($DTSheader); $word_offset += 2) {
|
||||
switch ($encoding) {
|
||||
case 0: // raw big-endian
|
||||
$fhBS .= getid3_lib::BigEndian2Bin( substr($DTSheader, $word_offset, 2) );
|
||||
break;
|
||||
case 1: // raw little-endian
|
||||
$fhBS .= getid3_lib::BigEndian2Bin(strrev(substr($DTSheader, $word_offset, 2)));
|
||||
break;
|
||||
case 2: // 14-bit big-endian
|
||||
$fhBS .= substr(getid3_lib::BigEndian2Bin( substr($DTSheader, $word_offset, 2) ), 2, 14);
|
||||
break;
|
||||
case 3: // 14-bit little-endian
|
||||
$fhBS .= substr(getid3_lib::BigEndian2Bin(strrev(substr($DTSheader, $word_offset, 2))), 2, 14);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$info['dts']['raw']['frame_type'] = $this->readBinData($fhBS, 1);
|
||||
$info['dts']['raw']['deficit_samples'] = $this->readBinData($fhBS, 5);
|
||||
$info['dts']['flags']['crc_present'] = (bool) $this->readBinData($fhBS, 1);
|
||||
$info['dts']['raw']['pcm_sample_blocks'] = $this->readBinData($fhBS, 7);
|
||||
$info['dts']['raw']['frame_byte_size'] = $this->readBinData($fhBS, 14);
|
||||
$info['dts']['raw']['channel_arrangement'] = $this->readBinData($fhBS, 6);
|
||||
$info['dts']['raw']['sample_frequency'] = $this->readBinData($fhBS, 4);
|
||||
$info['dts']['raw']['bitrate'] = $this->readBinData($fhBS, 5);
|
||||
$info['dts']['flags']['embedded_downmix'] = (bool) $this->readBinData($fhBS, 1);
|
||||
$info['dts']['flags']['dynamicrange'] = (bool) $this->readBinData($fhBS, 1);
|
||||
$info['dts']['flags']['timestamp'] = (bool) $this->readBinData($fhBS, 1);
|
||||
$info['dts']['flags']['auxdata'] = (bool) $this->readBinData($fhBS, 1);
|
||||
$info['dts']['flags']['hdcd'] = (bool) $this->readBinData($fhBS, 1);
|
||||
$info['dts']['raw']['extension_audio'] = $this->readBinData($fhBS, 3);
|
||||
$info['dts']['flags']['extended_coding'] = (bool) $this->readBinData($fhBS, 1);
|
||||
$info['dts']['flags']['audio_sync_insertion'] = (bool) $this->readBinData($fhBS, 1);
|
||||
$info['dts']['raw']['lfe_effects'] = $this->readBinData($fhBS, 2);
|
||||
$info['dts']['flags']['predictor_history'] = (bool) $this->readBinData($fhBS, 1);
|
||||
if ($info['dts']['flags']['crc_present']) {
|
||||
$info['dts']['raw']['crc16'] = $this->readBinData($fhBS, 16);
|
||||
}
|
||||
$info['dts']['flags']['mri_perfect_reconst'] = (bool) $this->readBinData($fhBS, 1);
|
||||
$info['dts']['raw']['encoder_soft_version'] = $this->readBinData($fhBS, 4);
|
||||
$info['dts']['raw']['copy_history'] = $this->readBinData($fhBS, 2);
|
||||
$info['dts']['raw']['bits_per_sample'] = $this->readBinData($fhBS, 2);
|
||||
$info['dts']['flags']['surround_es'] = (bool) $this->readBinData($fhBS, 1);
|
||||
$info['dts']['flags']['front_sum_diff'] = (bool) $this->readBinData($fhBS, 1);
|
||||
$info['dts']['flags']['surround_sum_diff'] = (bool) $this->readBinData($fhBS, 1);
|
||||
$info['dts']['raw']['dialog_normalization'] = $this->readBinData($fhBS, 4);
|
||||
|
||||
|
||||
$info['dts']['bitrate'] = self::bitrateLookup($info['dts']['raw']['bitrate']);
|
||||
$info['dts']['bits_per_sample'] = self::bitPerSampleLookup($info['dts']['raw']['bits_per_sample']);
|
||||
$info['dts']['sample_rate'] = self::sampleRateLookup($info['dts']['raw']['sample_frequency']);
|
||||
$info['dts']['dialog_normalization'] = self::dialogNormalization($info['dts']['raw']['dialog_normalization'], $info['dts']['raw']['encoder_soft_version']);
|
||||
$info['dts']['flags']['lossless'] = (($info['dts']['raw']['bitrate'] == 31) ? true : false);
|
||||
$info['dts']['bitrate_mode'] = (($info['dts']['raw']['bitrate'] == 30) ? 'vbr' : 'cbr');
|
||||
$info['dts']['channels'] = self::numChannelsLookup($info['dts']['raw']['channel_arrangement']);
|
||||
$info['dts']['channel_arrangement'] = self::channelArrangementLookup($info['dts']['raw']['channel_arrangement']);
|
||||
|
||||
$info['audio']['dataformat'] = 'dts';
|
||||
$info['audio']['lossless'] = $info['dts']['flags']['lossless'];
|
||||
$info['audio']['bitrate_mode'] = $info['dts']['bitrate_mode'];
|
||||
$info['audio']['bits_per_sample'] = $info['dts']['bits_per_sample'];
|
||||
$info['audio']['sample_rate'] = $info['dts']['sample_rate'];
|
||||
$info['audio']['channels'] = $info['dts']['channels'];
|
||||
$info['audio']['bitrate'] = $info['dts']['bitrate'];
|
||||
if (isset($info['avdataend']) && !empty($info['dts']['bitrate']) && is_numeric($info['dts']['bitrate'])) {
|
||||
$info['playtime_seconds'] = ($info['avdataend'] - $info['avdataoffset']) / ($info['dts']['bitrate'] / 8);
|
||||
if (($encoding == 2) || ($encoding == 3)) {
|
||||
// 14-bit data packed into 16-bit words, so the playtime is wrong because only (14/16) of the bytes in the data portion of the file are used at the specified bitrate
|
||||
$info['playtime_seconds'] *= (14 / 16);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private function readBinData($bin, $length) {
|
||||
$data = substr($bin, $this->readBinDataOffset, $length);
|
||||
$this->readBinDataOffset += $length;
|
||||
|
||||
return bindec($data);
|
||||
}
|
||||
|
||||
public static function bitrateLookup($index) {
|
||||
static $lookup = array(
|
||||
0 => 32000,
|
||||
1 => 56000,
|
||||
2 => 64000,
|
||||
3 => 96000,
|
||||
4 => 112000,
|
||||
5 => 128000,
|
||||
6 => 192000,
|
||||
7 => 224000,
|
||||
8 => 256000,
|
||||
9 => 320000,
|
||||
10 => 384000,
|
||||
11 => 448000,
|
||||
12 => 512000,
|
||||
13 => 576000,
|
||||
14 => 640000,
|
||||
15 => 768000,
|
||||
16 => 960000,
|
||||
17 => 1024000,
|
||||
18 => 1152000,
|
||||
19 => 1280000,
|
||||
20 => 1344000,
|
||||
21 => 1408000,
|
||||
22 => 1411200,
|
||||
23 => 1472000,
|
||||
24 => 1536000,
|
||||
25 => 1920000,
|
||||
26 => 2048000,
|
||||
27 => 3072000,
|
||||
28 => 3840000,
|
||||
29 => 'open',
|
||||
30 => 'variable',
|
||||
31 => 'lossless',
|
||||
);
|
||||
return (isset($lookup[$index]) ? $lookup[$index] : false);
|
||||
}
|
||||
|
||||
public static function sampleRateLookup($index) {
|
||||
static $lookup = array(
|
||||
0 => 'invalid',
|
||||
1 => 8000,
|
||||
2 => 16000,
|
||||
3 => 32000,
|
||||
4 => 'invalid',
|
||||
5 => 'invalid',
|
||||
6 => 11025,
|
||||
7 => 22050,
|
||||
8 => 44100,
|
||||
9 => 'invalid',
|
||||
10 => 'invalid',
|
||||
11 => 12000,
|
||||
12 => 24000,
|
||||
13 => 48000,
|
||||
14 => 'invalid',
|
||||
15 => 'invalid',
|
||||
);
|
||||
return (isset($lookup[$index]) ? $lookup[$index] : false);
|
||||
}
|
||||
|
||||
public static function bitPerSampleLookup($index) {
|
||||
static $lookup = array(
|
||||
0 => 16,
|
||||
1 => 20,
|
||||
2 => 24,
|
||||
3 => 24,
|
||||
);
|
||||
return (isset($lookup[$index]) ? $lookup[$index] : false);
|
||||
}
|
||||
|
||||
public static function numChannelsLookup($index) {
|
||||
switch ($index) {
|
||||
case 0:
|
||||
return 1;
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
return 2;
|
||||
break;
|
||||
case 5:
|
||||
case 6:
|
||||
return 3;
|
||||
break;
|
||||
case 7:
|
||||
case 8:
|
||||
return 4;
|
||||
break;
|
||||
case 9:
|
||||
return 5;
|
||||
break;
|
||||
case 10:
|
||||
case 11:
|
||||
case 12:
|
||||
return 6;
|
||||
break;
|
||||
case 13:
|
||||
return 7;
|
||||
break;
|
||||
case 14:
|
||||
case 15:
|
||||
return 8;
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function channelArrangementLookup($index) {
|
||||
static $lookup = array(
|
||||
0 => 'A',
|
||||
1 => 'A + B (dual mono)',
|
||||
2 => 'L + R (stereo)',
|
||||
3 => '(L+R) + (L-R) (sum-difference)',
|
||||
4 => 'LT + RT (left and right total)',
|
||||
5 => 'C + L + R',
|
||||
6 => 'L + R + S',
|
||||
7 => 'C + L + R + S',
|
||||
8 => 'L + R + SL + SR',
|
||||
9 => 'C + L + R + SL + SR',
|
||||
10 => 'CL + CR + L + R + SL + SR',
|
||||
11 => 'C + L + R+ LR + RR + OV',
|
||||
12 => 'CF + CR + LF + RF + LR + RR',
|
||||
13 => 'CL + C + CR + L + R + SL + SR',
|
||||
14 => 'CL + CR + L + R + SL1 + SL2 + SR1 + SR2',
|
||||
15 => 'CL + C+ CR + L + R + SL + S + SR',
|
||||
);
|
||||
return (isset($lookup[$index]) ? $lookup[$index] : 'user-defined');
|
||||
}
|
||||
|
||||
public static function dialogNormalization($index, $version) {
|
||||
switch ($version) {
|
||||
case 7:
|
||||
return 0 - $index;
|
||||
break;
|
||||
case 6:
|
||||
return 0 - 16 - $index;
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
453
Kapitel_7/Lektion_4/wordpress/wp-includes/ID3/module.audio.flac.php
Executable file
453
Kapitel_7/Lektion_4/wordpress/wp-includes/ID3/module.audio.flac.php
Executable file
@@ -0,0 +1,453 @@
|
||||
<?php
|
||||
/////////////////////////////////////////////////////////////////
|
||||
/// getID3() by James Heinrich <info@getid3.org> //
|
||||
// available at http://getid3.sourceforge.net //
|
||||
// or http://www.getid3.org //
|
||||
// also https://github.com/JamesHeinrich/getID3 //
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// See readme.txt for more details //
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// module.audio.flac.php //
|
||||
// module for analyzing FLAC and OggFLAC audio files //
|
||||
// dependencies: module.audio.ogg.php //
|
||||
// ///
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.ogg.php', __FILE__, true);
|
||||
|
||||
/**
|
||||
* @tutorial http://flac.sourceforge.net/format.html
|
||||
*/
|
||||
class getid3_flac extends getid3_handler
|
||||
{
|
||||
const syncword = 'fLaC';
|
||||
|
||||
public function Analyze() {
|
||||
$info = &$this->getid3->info;
|
||||
|
||||
$this->fseek($info['avdataoffset']);
|
||||
$StreamMarker = $this->fread(4);
|
||||
if ($StreamMarker != self::syncword) {
|
||||
return $this->error('Expecting "'.getid3_lib::PrintHexBytes(self::syncword).'" at offset '.$info['avdataoffset'].', found "'.getid3_lib::PrintHexBytes($StreamMarker).'"');
|
||||
}
|
||||
$info['fileformat'] = 'flac';
|
||||
$info['audio']['dataformat'] = 'flac';
|
||||
$info['audio']['bitrate_mode'] = 'vbr';
|
||||
$info['audio']['lossless'] = true;
|
||||
|
||||
// parse flac container
|
||||
return $this->parseMETAdata();
|
||||
}
|
||||
|
||||
public function parseMETAdata() {
|
||||
$info = &$this->getid3->info;
|
||||
do {
|
||||
$BlockOffset = $this->ftell();
|
||||
$BlockHeader = $this->fread(4);
|
||||
$LBFBT = getid3_lib::BigEndian2Int(substr($BlockHeader, 0, 1));
|
||||
$LastBlockFlag = (bool) ($LBFBT & 0x80);
|
||||
$BlockType = ($LBFBT & 0x7F);
|
||||
$BlockLength = getid3_lib::BigEndian2Int(substr($BlockHeader, 1, 3));
|
||||
$BlockTypeText = self::metaBlockTypeLookup($BlockType);
|
||||
|
||||
if (($BlockOffset + 4 + $BlockLength) > $info['avdataend']) {
|
||||
$this->error('METADATA_BLOCK_HEADER.BLOCK_TYPE ('.$BlockTypeText.') at offset '.$BlockOffset.' extends beyond end of file');
|
||||
break;
|
||||
}
|
||||
if ($BlockLength < 1) {
|
||||
$this->error('METADATA_BLOCK_HEADER.BLOCK_LENGTH ('.$BlockLength.') at offset '.$BlockOffset.' is invalid');
|
||||
break;
|
||||
}
|
||||
|
||||
$info['flac'][$BlockTypeText]['raw'] = array();
|
||||
$BlockTypeText_raw = &$info['flac'][$BlockTypeText]['raw'];
|
||||
|
||||
$BlockTypeText_raw['offset'] = $BlockOffset;
|
||||
$BlockTypeText_raw['last_meta_block'] = $LastBlockFlag;
|
||||
$BlockTypeText_raw['block_type'] = $BlockType;
|
||||
$BlockTypeText_raw['block_type_text'] = $BlockTypeText;
|
||||
$BlockTypeText_raw['block_length'] = $BlockLength;
|
||||
if ($BlockTypeText_raw['block_type'] != 0x06) { // do not read attachment data automatically
|
||||
$BlockTypeText_raw['block_data'] = $this->fread($BlockLength);
|
||||
}
|
||||
|
||||
switch ($BlockTypeText) {
|
||||
case 'STREAMINFO': // 0x00
|
||||
if (!$this->parseSTREAMINFO($BlockTypeText_raw['block_data'])) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'PADDING': // 0x01
|
||||
unset($info['flac']['PADDING']); // ignore
|
||||
break;
|
||||
|
||||
case 'APPLICATION': // 0x02
|
||||
if (!$this->parseAPPLICATION($BlockTypeText_raw['block_data'])) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'SEEKTABLE': // 0x03
|
||||
if (!$this->parseSEEKTABLE($BlockTypeText_raw['block_data'])) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'VORBIS_COMMENT': // 0x04
|
||||
if (!$this->parseVORBIS_COMMENT($BlockTypeText_raw['block_data'])) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'CUESHEET': // 0x05
|
||||
if (!$this->parseCUESHEET($BlockTypeText_raw['block_data'])) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'PICTURE': // 0x06
|
||||
if (!$this->parsePICTURE()) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
$this->warning('Unhandled METADATA_BLOCK_HEADER.BLOCK_TYPE ('.$BlockType.') at offset '.$BlockOffset);
|
||||
}
|
||||
|
||||
unset($info['flac'][$BlockTypeText]['raw']);
|
||||
$info['avdataoffset'] = $this->ftell();
|
||||
}
|
||||
while ($LastBlockFlag === false);
|
||||
|
||||
// handle tags
|
||||
if (!empty($info['flac']['VORBIS_COMMENT']['comments'])) {
|
||||
$info['flac']['comments'] = $info['flac']['VORBIS_COMMENT']['comments'];
|
||||
}
|
||||
if (!empty($info['flac']['VORBIS_COMMENT']['vendor'])) {
|
||||
$info['audio']['encoder'] = str_replace('reference ', '', $info['flac']['VORBIS_COMMENT']['vendor']);
|
||||
}
|
||||
|
||||
// copy attachments to 'comments' array if nesesary
|
||||
if (isset($info['flac']['PICTURE']) && ($this->getid3->option_save_attachments !== getID3::ATTACHMENTS_NONE)) {
|
||||
foreach ($info['flac']['PICTURE'] as $entry) {
|
||||
if (!empty($entry['data'])) {
|
||||
if (!isset($info['flac']['comments']['picture'])) {
|
||||
$info['flac']['comments']['picture'] = array();
|
||||
}
|
||||
$comments_picture_data = array();
|
||||
foreach (array('data', 'image_mime', 'image_width', 'image_height', 'imagetype', 'picturetype', 'description', 'datalength') as $picture_key) {
|
||||
if (isset($entry[$picture_key])) {
|
||||
$comments_picture_data[$picture_key] = $entry[$picture_key];
|
||||
}
|
||||
}
|
||||
$info['flac']['comments']['picture'][] = $comments_picture_data;
|
||||
unset($comments_picture_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($info['flac']['STREAMINFO'])) {
|
||||
if (!$this->isDependencyFor('matroska')) {
|
||||
$info['flac']['compressed_audio_bytes'] = $info['avdataend'] - $info['avdataoffset'];
|
||||
}
|
||||
$info['flac']['uncompressed_audio_bytes'] = $info['flac']['STREAMINFO']['samples_stream'] * $info['flac']['STREAMINFO']['channels'] * ($info['flac']['STREAMINFO']['bits_per_sample'] / 8);
|
||||
if ($info['flac']['uncompressed_audio_bytes'] == 0) {
|
||||
return $this->error('Corrupt FLAC file: uncompressed_audio_bytes == zero');
|
||||
}
|
||||
if (!empty($info['flac']['compressed_audio_bytes'])) {
|
||||
$info['flac']['compression_ratio'] = $info['flac']['compressed_audio_bytes'] / $info['flac']['uncompressed_audio_bytes'];
|
||||
}
|
||||
}
|
||||
|
||||
// set md5_data_source - built into flac 0.5+
|
||||
if (isset($info['flac']['STREAMINFO']['audio_signature'])) {
|
||||
|
||||
if ($info['flac']['STREAMINFO']['audio_signature'] === str_repeat("\x00", 16)) {
|
||||
$this->warning('FLAC STREAMINFO.audio_signature is null (known issue with libOggFLAC)');
|
||||
}
|
||||
else {
|
||||
$info['md5_data_source'] = '';
|
||||
$md5 = $info['flac']['STREAMINFO']['audio_signature'];
|
||||
for ($i = 0; $i < strlen($md5); $i++) {
|
||||
$info['md5_data_source'] .= str_pad(dechex(ord($md5[$i])), 2, '00', STR_PAD_LEFT);
|
||||
}
|
||||
if (!preg_match('/^[0-9a-f]{32}$/', $info['md5_data_source'])) {
|
||||
unset($info['md5_data_source']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($info['flac']['STREAMINFO']['bits_per_sample'])) {
|
||||
$info['audio']['bits_per_sample'] = $info['flac']['STREAMINFO']['bits_per_sample'];
|
||||
if ($info['audio']['bits_per_sample'] == 8) {
|
||||
// special case
|
||||
// must invert sign bit on all data bytes before MD5'ing to match FLAC's calculated value
|
||||
// MD5sum calculates on unsigned bytes, but FLAC calculated MD5 on 8-bit audio data as signed
|
||||
$this->warning('FLAC calculates MD5 data strangely on 8-bit audio, so the stored md5_data_source value will not match the decoded WAV file');
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private function parseSTREAMINFO($BlockData) {
|
||||
$info = &$this->getid3->info;
|
||||
|
||||
$info['flac']['STREAMINFO'] = array();
|
||||
$streaminfo = &$info['flac']['STREAMINFO'];
|
||||
|
||||
$streaminfo['min_block_size'] = getid3_lib::BigEndian2Int(substr($BlockData, 0, 2));
|
||||
$streaminfo['max_block_size'] = getid3_lib::BigEndian2Int(substr($BlockData, 2, 2));
|
||||
$streaminfo['min_frame_size'] = getid3_lib::BigEndian2Int(substr($BlockData, 4, 3));
|
||||
$streaminfo['max_frame_size'] = getid3_lib::BigEndian2Int(substr($BlockData, 7, 3));
|
||||
|
||||
$SRCSBSS = getid3_lib::BigEndian2Bin(substr($BlockData, 10, 8));
|
||||
$streaminfo['sample_rate'] = getid3_lib::Bin2Dec(substr($SRCSBSS, 0, 20));
|
||||
$streaminfo['channels'] = getid3_lib::Bin2Dec(substr($SRCSBSS, 20, 3)) + 1;
|
||||
$streaminfo['bits_per_sample'] = getid3_lib::Bin2Dec(substr($SRCSBSS, 23, 5)) + 1;
|
||||
$streaminfo['samples_stream'] = getid3_lib::Bin2Dec(substr($SRCSBSS, 28, 36));
|
||||
|
||||
$streaminfo['audio_signature'] = substr($BlockData, 18, 16);
|
||||
|
||||
if (!empty($streaminfo['sample_rate'])) {
|
||||
|
||||
$info['audio']['bitrate_mode'] = 'vbr';
|
||||
$info['audio']['sample_rate'] = $streaminfo['sample_rate'];
|
||||
$info['audio']['channels'] = $streaminfo['channels'];
|
||||
$info['audio']['bits_per_sample'] = $streaminfo['bits_per_sample'];
|
||||
$info['playtime_seconds'] = $streaminfo['samples_stream'] / $streaminfo['sample_rate'];
|
||||
if ($info['playtime_seconds'] > 0) {
|
||||
if (!$this->isDependencyFor('matroska')) {
|
||||
$info['audio']['bitrate'] = (($info['avdataend'] - $info['avdataoffset']) * 8) / $info['playtime_seconds'];
|
||||
}
|
||||
else {
|
||||
$this->warning('Cannot determine audio bitrate because total stream size is unknown');
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
return $this->error('Corrupt METAdata block: STREAMINFO');
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private function parseAPPLICATION($BlockData) {
|
||||
$info = &$this->getid3->info;
|
||||
|
||||
$ApplicationID = getid3_lib::BigEndian2Int(substr($BlockData, 0, 4));
|
||||
$info['flac']['APPLICATION'][$ApplicationID]['name'] = self::applicationIDLookup($ApplicationID);
|
||||
$info['flac']['APPLICATION'][$ApplicationID]['data'] = substr($BlockData, 4);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private function parseSEEKTABLE($BlockData) {
|
||||
$info = &$this->getid3->info;
|
||||
|
||||
$offset = 0;
|
||||
$BlockLength = strlen($BlockData);
|
||||
$placeholderpattern = str_repeat("\xFF", 8);
|
||||
while ($offset < $BlockLength) {
|
||||
$SampleNumberString = substr($BlockData, $offset, 8);
|
||||
$offset += 8;
|
||||
if ($SampleNumberString == $placeholderpattern) {
|
||||
|
||||
// placeholder point
|
||||
getid3_lib::safe_inc($info['flac']['SEEKTABLE']['placeholders'], 1);
|
||||
$offset += 10;
|
||||
|
||||
} else {
|
||||
|
||||
$SampleNumber = getid3_lib::BigEndian2Int($SampleNumberString);
|
||||
$info['flac']['SEEKTABLE'][$SampleNumber]['offset'] = getid3_lib::BigEndian2Int(substr($BlockData, $offset, 8));
|
||||
$offset += 8;
|
||||
$info['flac']['SEEKTABLE'][$SampleNumber]['samples'] = getid3_lib::BigEndian2Int(substr($BlockData, $offset, 2));
|
||||
$offset += 2;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private function parseVORBIS_COMMENT($BlockData) {
|
||||
$info = &$this->getid3->info;
|
||||
|
||||
$getid3_ogg = new getid3_ogg($this->getid3);
|
||||
if ($this->isDependencyFor('matroska')) {
|
||||
$getid3_ogg->setStringMode($this->data_string);
|
||||
}
|
||||
$getid3_ogg->ParseVorbisComments();
|
||||
if (isset($info['ogg'])) {
|
||||
unset($info['ogg']['comments_raw']);
|
||||
$info['flac']['VORBIS_COMMENT'] = $info['ogg'];
|
||||
unset($info['ogg']);
|
||||
}
|
||||
|
||||
unset($getid3_ogg);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private function parseCUESHEET($BlockData) {
|
||||
$info = &$this->getid3->info;
|
||||
$offset = 0;
|
||||
$info['flac']['CUESHEET']['media_catalog_number'] = trim(substr($BlockData, $offset, 128), "\0");
|
||||
$offset += 128;
|
||||
$info['flac']['CUESHEET']['lead_in_samples'] = getid3_lib::BigEndian2Int(substr($BlockData, $offset, 8));
|
||||
$offset += 8;
|
||||
$info['flac']['CUESHEET']['flags']['is_cd'] = (bool) (getid3_lib::BigEndian2Int(substr($BlockData, $offset, 1)) & 0x80);
|
||||
$offset += 1;
|
||||
|
||||
$offset += 258; // reserved
|
||||
|
||||
$info['flac']['CUESHEET']['number_tracks'] = getid3_lib::BigEndian2Int(substr($BlockData, $offset, 1));
|
||||
$offset += 1;
|
||||
|
||||
for ($track = 0; $track < $info['flac']['CUESHEET']['number_tracks']; $track++) {
|
||||
$TrackSampleOffset = getid3_lib::BigEndian2Int(substr($BlockData, $offset, 8));
|
||||
$offset += 8;
|
||||
$TrackNumber = getid3_lib::BigEndian2Int(substr($BlockData, $offset, 1));
|
||||
$offset += 1;
|
||||
|
||||
$info['flac']['CUESHEET']['tracks'][$TrackNumber]['sample_offset'] = $TrackSampleOffset;
|
||||
|
||||
$info['flac']['CUESHEET']['tracks'][$TrackNumber]['isrc'] = substr($BlockData, $offset, 12);
|
||||
$offset += 12;
|
||||
|
||||
$TrackFlagsRaw = getid3_lib::BigEndian2Int(substr($BlockData, $offset, 1));
|
||||
$offset += 1;
|
||||
$info['flac']['CUESHEET']['tracks'][$TrackNumber]['flags']['is_audio'] = (bool) ($TrackFlagsRaw & 0x80);
|
||||
$info['flac']['CUESHEET']['tracks'][$TrackNumber]['flags']['pre_emphasis'] = (bool) ($TrackFlagsRaw & 0x40);
|
||||
|
||||
$offset += 13; // reserved
|
||||
|
||||
$info['flac']['CUESHEET']['tracks'][$TrackNumber]['index_points'] = getid3_lib::BigEndian2Int(substr($BlockData, $offset, 1));
|
||||
$offset += 1;
|
||||
|
||||
for ($index = 0; $index < $info['flac']['CUESHEET']['tracks'][$TrackNumber]['index_points']; $index++) {
|
||||
$IndexSampleOffset = getid3_lib::BigEndian2Int(substr($BlockData, $offset, 8));
|
||||
$offset += 8;
|
||||
$IndexNumber = getid3_lib::BigEndian2Int(substr($BlockData, $offset, 1));
|
||||
$offset += 1;
|
||||
|
||||
$offset += 3; // reserved
|
||||
|
||||
$info['flac']['CUESHEET']['tracks'][$TrackNumber]['indexes'][$IndexNumber] = $IndexSampleOffset;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse METADATA_BLOCK_PICTURE flac structure and extract attachment
|
||||
* External usage: audio.ogg
|
||||
*/
|
||||
public function parsePICTURE() {
|
||||
$info = &$this->getid3->info;
|
||||
|
||||
$picture['typeid'] = getid3_lib::BigEndian2Int($this->fread(4));
|
||||
$picture['picturetype'] = self::pictureTypeLookup($picture['typeid']);
|
||||
$picture['image_mime'] = $this->fread(getid3_lib::BigEndian2Int($this->fread(4)));
|
||||
$descr_length = getid3_lib::BigEndian2Int($this->fread(4));
|
||||
if ($descr_length) {
|
||||
$picture['description'] = $this->fread($descr_length);
|
||||
}
|
||||
$picture['image_width'] = getid3_lib::BigEndian2Int($this->fread(4));
|
||||
$picture['image_height'] = getid3_lib::BigEndian2Int($this->fread(4));
|
||||
$picture['color_depth'] = getid3_lib::BigEndian2Int($this->fread(4));
|
||||
$picture['colors_indexed'] = getid3_lib::BigEndian2Int($this->fread(4));
|
||||
$picture['datalength'] = getid3_lib::BigEndian2Int($this->fread(4));
|
||||
|
||||
if ($picture['image_mime'] == '-->') {
|
||||
$picture['data'] = $this->fread($picture['datalength']);
|
||||
} else {
|
||||
$picture['data'] = $this->saveAttachment(
|
||||
str_replace('/', '_', $picture['picturetype']).'_'.$this->ftell(),
|
||||
$this->ftell(),
|
||||
$picture['datalength'],
|
||||
$picture['image_mime']);
|
||||
}
|
||||
|
||||
$info['flac']['PICTURE'][] = $picture;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function metaBlockTypeLookup($blocktype) {
|
||||
static $lookup = array(
|
||||
0 => 'STREAMINFO',
|
||||
1 => 'PADDING',
|
||||
2 => 'APPLICATION',
|
||||
3 => 'SEEKTABLE',
|
||||
4 => 'VORBIS_COMMENT',
|
||||
5 => 'CUESHEET',
|
||||
6 => 'PICTURE',
|
||||
);
|
||||
return (isset($lookup[$blocktype]) ? $lookup[$blocktype] : 'reserved');
|
||||
}
|
||||
|
||||
public static function applicationIDLookup($applicationid) {
|
||||
// http://flac.sourceforge.net/id.html
|
||||
static $lookup = array(
|
||||
0x41544348 => 'FlacFile', // "ATCH"
|
||||
0x42534F4C => 'beSolo', // "BSOL"
|
||||
0x42554753 => 'Bugs Player', // "BUGS"
|
||||
0x43756573 => 'GoldWave cue points (specification)', // "Cues"
|
||||
0x46696361 => 'CUE Splitter', // "Fica"
|
||||
0x46746F6C => 'flac-tools', // "Ftol"
|
||||
0x4D4F5442 => 'MOTB MetaCzar', // "MOTB"
|
||||
0x4D505345 => 'MP3 Stream Editor', // "MPSE"
|
||||
0x4D754D4C => 'MusicML: Music Metadata Language', // "MuML"
|
||||
0x52494646 => 'Sound Devices RIFF chunk storage', // "RIFF"
|
||||
0x5346464C => 'Sound Font FLAC', // "SFFL"
|
||||
0x534F4E59 => 'Sony Creative Software', // "SONY"
|
||||
0x5351455A => 'flacsqueeze', // "SQEZ"
|
||||
0x54745776 => 'TwistedWave', // "TtWv"
|
||||
0x55495453 => 'UITS Embedding tools', // "UITS"
|
||||
0x61696666 => 'FLAC AIFF chunk storage', // "aiff"
|
||||
0x696D6167 => 'flac-image application for storing arbitrary files in APPLICATION metadata blocks', // "imag"
|
||||
0x7065656D => 'Parseable Embedded Extensible Metadata (specification)', // "peem"
|
||||
0x71667374 => 'QFLAC Studio', // "qfst"
|
||||
0x72696666 => 'FLAC RIFF chunk storage', // "riff"
|
||||
0x74756E65 => 'TagTuner', // "tune"
|
||||
0x78626174 => 'XBAT', // "xbat"
|
||||
0x786D6364 => 'xmcd', // "xmcd"
|
||||
);
|
||||
return (isset($lookup[$applicationid]) ? $lookup[$applicationid] : 'reserved');
|
||||
}
|
||||
|
||||
public static function pictureTypeLookup($type_id) {
|
||||
static $lookup = array (
|
||||
0 => 'Other',
|
||||
1 => '32x32 pixels \'file icon\' (PNG only)',
|
||||
2 => 'Other file icon',
|
||||
3 => 'Cover (front)',
|
||||
4 => 'Cover (back)',
|
||||
5 => 'Leaflet page',
|
||||
6 => 'Media (e.g. label side of CD)',
|
||||
7 => 'Lead artist/lead performer/soloist',
|
||||
8 => 'Artist/performer',
|
||||
9 => 'Conductor',
|
||||
10 => 'Band/Orchestra',
|
||||
11 => 'Composer',
|
||||
12 => 'Lyricist/text writer',
|
||||
13 => 'Recording Location',
|
||||
14 => 'During recording',
|
||||
15 => 'During performance',
|
||||
16 => 'Movie/video screen capture',
|
||||
17 => 'A bright coloured fish',
|
||||
18 => 'Illustration',
|
||||
19 => 'Band/artist logotype',
|
||||
20 => 'Publisher/Studio logotype',
|
||||
);
|
||||
return (isset($lookup[$type_id]) ? $lookup[$type_id] : 'reserved');
|
||||
}
|
||||
|
||||
}
|
||||
2012
Kapitel_7/Lektion_4/wordpress/wp-includes/ID3/module.audio.mp3.php
Executable file
2012
Kapitel_7/Lektion_4/wordpress/wp-includes/ID3/module.audio.mp3.php
Executable file
File diff suppressed because it is too large
Load Diff
839
Kapitel_7/Lektion_4/wordpress/wp-includes/ID3/module.audio.ogg.php
Executable file
839
Kapitel_7/Lektion_4/wordpress/wp-includes/ID3/module.audio.ogg.php
Executable file
@@ -0,0 +1,839 @@
|
||||
<?php
|
||||
/////////////////////////////////////////////////////////////////
|
||||
/// getID3() by James Heinrich <info@getid3.org> //
|
||||
// available at http://getid3.sourceforge.net //
|
||||
// or http://www.getid3.org //
|
||||
// also https://github.com/JamesHeinrich/getID3 //
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// See readme.txt for more details //
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// module.audio.ogg.php //
|
||||
// module for analyzing Ogg Vorbis, OggFLAC and Speex files //
|
||||
// dependencies: module.audio.flac.php //
|
||||
// ///
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.flac.php', __FILE__, true);
|
||||
|
||||
class getid3_ogg extends getid3_handler
|
||||
{
|
||||
// http://xiph.org/vorbis/doc/Vorbis_I_spec.html
|
||||
public function Analyze() {
|
||||
$info = &$this->getid3->info;
|
||||
|
||||
$info['fileformat'] = 'ogg';
|
||||
|
||||
// Warn about illegal tags - only vorbiscomments are allowed
|
||||
if (isset($info['id3v2'])) {
|
||||
$info['warning'][] = 'Illegal ID3v2 tag present.';
|
||||
}
|
||||
if (isset($info['id3v1'])) {
|
||||
$info['warning'][] = 'Illegal ID3v1 tag present.';
|
||||
}
|
||||
if (isset($info['ape'])) {
|
||||
$info['warning'][] = 'Illegal APE tag present.';
|
||||
}
|
||||
|
||||
|
||||
// Page 1 - Stream Header
|
||||
|
||||
$this->fseek($info['avdataoffset']);
|
||||
|
||||
$oggpageinfo = $this->ParseOggPageHeader();
|
||||
$info['ogg']['pageheader'][$oggpageinfo['page_seqno']] = $oggpageinfo;
|
||||
|
||||
if ($this->ftell() >= $this->getid3->fread_buffer_size()) {
|
||||
$info['error'][] = 'Could not find start of Ogg page in the first '.$this->getid3->fread_buffer_size().' bytes (this might not be an Ogg-Vorbis file?)';
|
||||
unset($info['fileformat']);
|
||||
unset($info['ogg']);
|
||||
return false;
|
||||
}
|
||||
|
||||
$filedata = $this->fread($oggpageinfo['page_length']);
|
||||
$filedataoffset = 0;
|
||||
|
||||
if (substr($filedata, 0, 4) == 'fLaC') {
|
||||
|
||||
$info['audio']['dataformat'] = 'flac';
|
||||
$info['audio']['bitrate_mode'] = 'vbr';
|
||||
$info['audio']['lossless'] = true;
|
||||
|
||||
} elseif (substr($filedata, 1, 6) == 'vorbis') {
|
||||
|
||||
$this->ParseVorbisPageHeader($filedata, $filedataoffset, $oggpageinfo);
|
||||
|
||||
} elseif (substr($filedata, 0, 8) == 'OpusHead') {
|
||||
|
||||
if( $this->ParseOpusPageHeader($filedata, $filedataoffset, $oggpageinfo) == false ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
} elseif (substr($filedata, 0, 8) == 'Speex ') {
|
||||
|
||||
// http://www.speex.org/manual/node10.html
|
||||
|
||||
$info['audio']['dataformat'] = 'speex';
|
||||
$info['mime_type'] = 'audio/speex';
|
||||
$info['audio']['bitrate_mode'] = 'abr';
|
||||
$info['audio']['lossless'] = false;
|
||||
|
||||
$info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['speex_string'] = substr($filedata, $filedataoffset, 8); // hard-coded to 'Speex '
|
||||
$filedataoffset += 8;
|
||||
$info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['speex_version'] = substr($filedata, $filedataoffset, 20);
|
||||
$filedataoffset += 20;
|
||||
$info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['speex_version_id'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4));
|
||||
$filedataoffset += 4;
|
||||
$info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['header_size'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4));
|
||||
$filedataoffset += 4;
|
||||
$info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['rate'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4));
|
||||
$filedataoffset += 4;
|
||||
$info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['mode'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4));
|
||||
$filedataoffset += 4;
|
||||
$info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['mode_bitstream_version'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4));
|
||||
$filedataoffset += 4;
|
||||
$info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['nb_channels'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4));
|
||||
$filedataoffset += 4;
|
||||
$info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['bitrate'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4));
|
||||
$filedataoffset += 4;
|
||||
$info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['framesize'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4));
|
||||
$filedataoffset += 4;
|
||||
$info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['vbr'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4));
|
||||
$filedataoffset += 4;
|
||||
$info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['frames_per_packet'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4));
|
||||
$filedataoffset += 4;
|
||||
$info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['extra_headers'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4));
|
||||
$filedataoffset += 4;
|
||||
$info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['reserved1'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4));
|
||||
$filedataoffset += 4;
|
||||
$info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['reserved2'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4));
|
||||
$filedataoffset += 4;
|
||||
|
||||
$info['speex']['speex_version'] = trim($info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['speex_version']);
|
||||
$info['speex']['sample_rate'] = $info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['rate'];
|
||||
$info['speex']['channels'] = $info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['nb_channels'];
|
||||
$info['speex']['vbr'] = (bool) $info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['vbr'];
|
||||
$info['speex']['band_type'] = $this->SpeexBandModeLookup($info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['mode']);
|
||||
|
||||
$info['audio']['sample_rate'] = $info['speex']['sample_rate'];
|
||||
$info['audio']['channels'] = $info['speex']['channels'];
|
||||
if ($info['speex']['vbr']) {
|
||||
$info['audio']['bitrate_mode'] = 'vbr';
|
||||
}
|
||||
|
||||
} elseif (substr($filedata, 0, 7) == "\x80".'theora') {
|
||||
|
||||
// http://www.theora.org/doc/Theora.pdf (section 6.2)
|
||||
|
||||
$info['ogg']['pageheader']['theora']['theora_magic'] = substr($filedata, $filedataoffset, 7); // hard-coded to "\x80.'theora'
|
||||
$filedataoffset += 7;
|
||||
$info['ogg']['pageheader']['theora']['version_major'] = getid3_lib::BigEndian2Int(substr($filedata, $filedataoffset, 1));
|
||||
$filedataoffset += 1;
|
||||
$info['ogg']['pageheader']['theora']['version_minor'] = getid3_lib::BigEndian2Int(substr($filedata, $filedataoffset, 1));
|
||||
$filedataoffset += 1;
|
||||
$info['ogg']['pageheader']['theora']['version_revision'] = getid3_lib::BigEndian2Int(substr($filedata, $filedataoffset, 1));
|
||||
$filedataoffset += 1;
|
||||
$info['ogg']['pageheader']['theora']['frame_width_macroblocks'] = getid3_lib::BigEndian2Int(substr($filedata, $filedataoffset, 2));
|
||||
$filedataoffset += 2;
|
||||
$info['ogg']['pageheader']['theora']['frame_height_macroblocks'] = getid3_lib::BigEndian2Int(substr($filedata, $filedataoffset, 2));
|
||||
$filedataoffset += 2;
|
||||
$info['ogg']['pageheader']['theora']['resolution_x'] = getid3_lib::BigEndian2Int(substr($filedata, $filedataoffset, 3));
|
||||
$filedataoffset += 3;
|
||||
$info['ogg']['pageheader']['theora']['resolution_y'] = getid3_lib::BigEndian2Int(substr($filedata, $filedataoffset, 3));
|
||||
$filedataoffset += 3;
|
||||
$info['ogg']['pageheader']['theora']['picture_offset_x'] = getid3_lib::BigEndian2Int(substr($filedata, $filedataoffset, 1));
|
||||
$filedataoffset += 1;
|
||||
$info['ogg']['pageheader']['theora']['picture_offset_y'] = getid3_lib::BigEndian2Int(substr($filedata, $filedataoffset, 1));
|
||||
$filedataoffset += 1;
|
||||
$info['ogg']['pageheader']['theora']['frame_rate_numerator'] = getid3_lib::BigEndian2Int(substr($filedata, $filedataoffset, 4));
|
||||
$filedataoffset += 4;
|
||||
$info['ogg']['pageheader']['theora']['frame_rate_denominator'] = getid3_lib::BigEndian2Int(substr($filedata, $filedataoffset, 4));
|
||||
$filedataoffset += 4;
|
||||
$info['ogg']['pageheader']['theora']['pixel_aspect_numerator'] = getid3_lib::BigEndian2Int(substr($filedata, $filedataoffset, 3));
|
||||
$filedataoffset += 3;
|
||||
$info['ogg']['pageheader']['theora']['pixel_aspect_denominator'] = getid3_lib::BigEndian2Int(substr($filedata, $filedataoffset, 3));
|
||||
$filedataoffset += 3;
|
||||
$info['ogg']['pageheader']['theora']['color_space_id'] = getid3_lib::BigEndian2Int(substr($filedata, $filedataoffset, 1));
|
||||
$filedataoffset += 1;
|
||||
$info['ogg']['pageheader']['theora']['nominal_bitrate'] = getid3_lib::BigEndian2Int(substr($filedata, $filedataoffset, 3));
|
||||
$filedataoffset += 3;
|
||||
$info['ogg']['pageheader']['theora']['flags'] = getid3_lib::BigEndian2Int(substr($filedata, $filedataoffset, 2));
|
||||
$filedataoffset += 2;
|
||||
|
||||
$info['ogg']['pageheader']['theora']['quality'] = ($info['ogg']['pageheader']['theora']['flags'] & 0xFC00) >> 10;
|
||||
$info['ogg']['pageheader']['theora']['kfg_shift'] = ($info['ogg']['pageheader']['theora']['flags'] & 0x03E0) >> 5;
|
||||
$info['ogg']['pageheader']['theora']['pixel_format_id'] = ($info['ogg']['pageheader']['theora']['flags'] & 0x0018) >> 3;
|
||||
$info['ogg']['pageheader']['theora']['reserved'] = ($info['ogg']['pageheader']['theora']['flags'] & 0x0007) >> 0; // should be 0
|
||||
$info['ogg']['pageheader']['theora']['color_space'] = self::TheoraColorSpace($info['ogg']['pageheader']['theora']['color_space_id']);
|
||||
$info['ogg']['pageheader']['theora']['pixel_format'] = self::TheoraPixelFormat($info['ogg']['pageheader']['theora']['pixel_format_id']);
|
||||
|
||||
$info['video']['dataformat'] = 'theora';
|
||||
$info['mime_type'] = 'video/ogg';
|
||||
//$info['audio']['bitrate_mode'] = 'abr';
|
||||
//$info['audio']['lossless'] = false;
|
||||
$info['video']['resolution_x'] = $info['ogg']['pageheader']['theora']['resolution_x'];
|
||||
$info['video']['resolution_y'] = $info['ogg']['pageheader']['theora']['resolution_y'];
|
||||
if ($info['ogg']['pageheader']['theora']['frame_rate_denominator'] > 0) {
|
||||
$info['video']['frame_rate'] = (float) $info['ogg']['pageheader']['theora']['frame_rate_numerator'] / $info['ogg']['pageheader']['theora']['frame_rate_denominator'];
|
||||
}
|
||||
if ($info['ogg']['pageheader']['theora']['pixel_aspect_denominator'] > 0) {
|
||||
$info['video']['pixel_aspect_ratio'] = (float) $info['ogg']['pageheader']['theora']['pixel_aspect_numerator'] / $info['ogg']['pageheader']['theora']['pixel_aspect_denominator'];
|
||||
}
|
||||
$info['warning'][] = 'Ogg Theora (v3) not fully supported in this version of getID3 ['.$this->getid3->version().'] -- bitrate, playtime and all audio data are currently unavailable';
|
||||
|
||||
|
||||
} elseif (substr($filedata, 0, 8) == "fishead\x00") {
|
||||
|
||||
// Ogg Skeleton version 3.0 Format Specification
|
||||
// http://xiph.org/ogg/doc/skeleton.html
|
||||
$filedataoffset += 8;
|
||||
$info['ogg']['skeleton']['fishead']['raw']['version_major'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 2));
|
||||
$filedataoffset += 2;
|
||||
$info['ogg']['skeleton']['fishead']['raw']['version_minor'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 2));
|
||||
$filedataoffset += 2;
|
||||
$info['ogg']['skeleton']['fishead']['raw']['presentationtime_numerator'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 8));
|
||||
$filedataoffset += 8;
|
||||
$info['ogg']['skeleton']['fishead']['raw']['presentationtime_denominator'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 8));
|
||||
$filedataoffset += 8;
|
||||
$info['ogg']['skeleton']['fishead']['raw']['basetime_numerator'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 8));
|
||||
$filedataoffset += 8;
|
||||
$info['ogg']['skeleton']['fishead']['raw']['basetime_denominator'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 8));
|
||||
$filedataoffset += 8;
|
||||
$info['ogg']['skeleton']['fishead']['raw']['utc'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 20));
|
||||
$filedataoffset += 20;
|
||||
|
||||
$info['ogg']['skeleton']['fishead']['version'] = $info['ogg']['skeleton']['fishead']['raw']['version_major'].'.'.$info['ogg']['skeleton']['fishead']['raw']['version_minor'];
|
||||
$info['ogg']['skeleton']['fishead']['presentationtime'] = $info['ogg']['skeleton']['fishead']['raw']['presentationtime_numerator'] / $info['ogg']['skeleton']['fishead']['raw']['presentationtime_denominator'];
|
||||
$info['ogg']['skeleton']['fishead']['basetime'] = $info['ogg']['skeleton']['fishead']['raw']['basetime_numerator'] / $info['ogg']['skeleton']['fishead']['raw']['basetime_denominator'];
|
||||
$info['ogg']['skeleton']['fishead']['utc'] = $info['ogg']['skeleton']['fishead']['raw']['utc'];
|
||||
|
||||
|
||||
$counter = 0;
|
||||
do {
|
||||
$oggpageinfo = $this->ParseOggPageHeader();
|
||||
$info['ogg']['pageheader'][$oggpageinfo['page_seqno'].'.'.$counter++] = $oggpageinfo;
|
||||
$filedata = $this->fread($oggpageinfo['page_length']);
|
||||
$this->fseek($oggpageinfo['page_end_offset']);
|
||||
|
||||
if (substr($filedata, 0, 8) == "fisbone\x00") {
|
||||
|
||||
$filedataoffset = 8;
|
||||
$info['ogg']['skeleton']['fisbone']['raw']['message_header_offset'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4));
|
||||
$filedataoffset += 4;
|
||||
$info['ogg']['skeleton']['fisbone']['raw']['serial_number'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4));
|
||||
$filedataoffset += 4;
|
||||
$info['ogg']['skeleton']['fisbone']['raw']['number_header_packets'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4));
|
||||
$filedataoffset += 4;
|
||||
$info['ogg']['skeleton']['fisbone']['raw']['granulerate_numerator'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 8));
|
||||
$filedataoffset += 8;
|
||||
$info['ogg']['skeleton']['fisbone']['raw']['granulerate_denominator'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 8));
|
||||
$filedataoffset += 8;
|
||||
$info['ogg']['skeleton']['fisbone']['raw']['basegranule'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 8));
|
||||
$filedataoffset += 8;
|
||||
$info['ogg']['skeleton']['fisbone']['raw']['preroll'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4));
|
||||
$filedataoffset += 4;
|
||||
$info['ogg']['skeleton']['fisbone']['raw']['granuleshift'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 1));
|
||||
$filedataoffset += 1;
|
||||
$info['ogg']['skeleton']['fisbone']['raw']['padding'] = substr($filedata, $filedataoffset, 3);
|
||||
$filedataoffset += 3;
|
||||
|
||||
} elseif (substr($filedata, 1, 6) == 'theora') {
|
||||
|
||||
$info['video']['dataformat'] = 'theora1';
|
||||
$info['error'][] = 'Ogg Theora (v1) not correctly handled in this version of getID3 ['.$this->getid3->version().']';
|
||||
//break;
|
||||
|
||||
} elseif (substr($filedata, 1, 6) == 'vorbis') {
|
||||
|
||||
$this->ParseVorbisPageHeader($filedata, $filedataoffset, $oggpageinfo);
|
||||
|
||||
} else {
|
||||
$info['error'][] = 'unexpected';
|
||||
//break;
|
||||
}
|
||||
//} while ($oggpageinfo['page_seqno'] == 0);
|
||||
} while (($oggpageinfo['page_seqno'] == 0) && (substr($filedata, 0, 8) != "fisbone\x00"));
|
||||
|
||||
$this->fseek($oggpageinfo['page_start_offset']);
|
||||
|
||||
$info['error'][] = 'Ogg Skeleton not correctly handled in this version of getID3 ['.$this->getid3->version().']';
|
||||
//return false;
|
||||
|
||||
} else {
|
||||
|
||||
$info['error'][] = 'Expecting either "Speex ", "OpusHead" or "vorbis" identifier strings, found "'.substr($filedata, 0, 8).'"';
|
||||
unset($info['ogg']);
|
||||
unset($info['mime_type']);
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
// Page 2 - Comment Header
|
||||
$oggpageinfo = $this->ParseOggPageHeader();
|
||||
$info['ogg']['pageheader'][$oggpageinfo['page_seqno']] = $oggpageinfo;
|
||||
|
||||
switch ($info['audio']['dataformat']) {
|
||||
case 'vorbis':
|
||||
$filedata = $this->fread($info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['page_length']);
|
||||
$info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['packet_type'] = getid3_lib::LittleEndian2Int(substr($filedata, 0, 1));
|
||||
$info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['stream_type'] = substr($filedata, 1, 6); // hard-coded to 'vorbis'
|
||||
|
||||
$this->ParseVorbisComments();
|
||||
break;
|
||||
|
||||
case 'flac':
|
||||
$flac = new getid3_flac($this->getid3);
|
||||
if (!$flac->parseMETAdata()) {
|
||||
$info['error'][] = 'Failed to parse FLAC headers';
|
||||
return false;
|
||||
}
|
||||
unset($flac);
|
||||
break;
|
||||
|
||||
case 'speex':
|
||||
$this->fseek($info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['page_length'], SEEK_CUR);
|
||||
$this->ParseVorbisComments();
|
||||
break;
|
||||
|
||||
case 'opus':
|
||||
$filedata = $this->fread($info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['page_length']);
|
||||
$info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['stream_type'] = substr($filedata, 0, 8); // hard-coded to 'OpusTags'
|
||||
if(substr($filedata, 0, 8) != 'OpusTags') {
|
||||
$info['error'][] = 'Expected "OpusTags" as header but got "'.substr($filedata, 0, 8).'"';
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->ParseVorbisComments();
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
// Last Page - Number of Samples
|
||||
if (!getid3_lib::intValueSupported($info['avdataend'])) {
|
||||
|
||||
$info['warning'][] = 'Unable to parse Ogg end chunk file (PHP does not support file operations beyond '.round(PHP_INT_MAX / 1073741824).'GB)';
|
||||
|
||||
} else {
|
||||
|
||||
$this->fseek(max($info['avdataend'] - $this->getid3->fread_buffer_size(), 0));
|
||||
$LastChunkOfOgg = strrev($this->fread($this->getid3->fread_buffer_size()));
|
||||
if ($LastOggSpostion = strpos($LastChunkOfOgg, 'SggO')) {
|
||||
$this->fseek($info['avdataend'] - ($LastOggSpostion + strlen('SggO')));
|
||||
$info['avdataend'] = $this->ftell();
|
||||
$info['ogg']['pageheader']['eos'] = $this->ParseOggPageHeader();
|
||||
$info['ogg']['samples'] = $info['ogg']['pageheader']['eos']['pcm_abs_position'];
|
||||
if ($info['ogg']['samples'] == 0) {
|
||||
$info['error'][] = 'Corrupt Ogg file: eos.number of samples == zero';
|
||||
return false;
|
||||
}
|
||||
if (!empty($info['audio']['sample_rate'])) {
|
||||
$info['ogg']['bitrate_average'] = (($info['avdataend'] - $info['avdataoffset']) * 8) / ($info['ogg']['samples'] / $info['audio']['sample_rate']);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!empty($info['ogg']['bitrate_average'])) {
|
||||
$info['audio']['bitrate'] = $info['ogg']['bitrate_average'];
|
||||
} elseif (!empty($info['ogg']['bitrate_nominal'])) {
|
||||
$info['audio']['bitrate'] = $info['ogg']['bitrate_nominal'];
|
||||
} elseif (!empty($info['ogg']['bitrate_min']) && !empty($info['ogg']['bitrate_max'])) {
|
||||
$info['audio']['bitrate'] = ($info['ogg']['bitrate_min'] + $info['ogg']['bitrate_max']) / 2;
|
||||
}
|
||||
if (isset($info['audio']['bitrate']) && !isset($info['playtime_seconds'])) {
|
||||
if ($info['audio']['bitrate'] == 0) {
|
||||
$info['error'][] = 'Corrupt Ogg file: bitrate_audio == zero';
|
||||
return false;
|
||||
}
|
||||
$info['playtime_seconds'] = (float) ((($info['avdataend'] - $info['avdataoffset']) * 8) / $info['audio']['bitrate']);
|
||||
}
|
||||
|
||||
if (isset($info['ogg']['vendor'])) {
|
||||
$info['audio']['encoder'] = preg_replace('/^Encoded with /', '', $info['ogg']['vendor']);
|
||||
|
||||
// Vorbis only
|
||||
if ($info['audio']['dataformat'] == 'vorbis') {
|
||||
|
||||
// Vorbis 1.0 starts with Xiph.Org
|
||||
if (preg_match('/^Xiph.Org/', $info['audio']['encoder'])) {
|
||||
|
||||
if ($info['audio']['bitrate_mode'] == 'abr') {
|
||||
|
||||
// Set -b 128 on abr files
|
||||
$info['audio']['encoder_options'] = '-b '.round($info['ogg']['bitrate_nominal'] / 1000);
|
||||
|
||||
} elseif (($info['audio']['bitrate_mode'] == 'vbr') && ($info['audio']['channels'] == 2) && ($info['audio']['sample_rate'] >= 44100) && ($info['audio']['sample_rate'] <= 48000)) {
|
||||
// Set -q N on vbr files
|
||||
$info['audio']['encoder_options'] = '-q '.$this->get_quality_from_nominal_bitrate($info['ogg']['bitrate_nominal']);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($info['audio']['encoder_options']) && !empty($info['ogg']['bitrate_nominal'])) {
|
||||
$info['audio']['encoder_options'] = 'Nominal bitrate: '.intval(round($info['ogg']['bitrate_nominal'] / 1000)).'kbps';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function ParseVorbisPageHeader(&$filedata, &$filedataoffset, &$oggpageinfo) {
|
||||
$info = &$this->getid3->info;
|
||||
$info['audio']['dataformat'] = 'vorbis';
|
||||
$info['audio']['lossless'] = false;
|
||||
|
||||
$info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['packet_type'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 1));
|
||||
$filedataoffset += 1;
|
||||
$info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['stream_type'] = substr($filedata, $filedataoffset, 6); // hard-coded to 'vorbis'
|
||||
$filedataoffset += 6;
|
||||
$info['ogg']['bitstreamversion'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4));
|
||||
$filedataoffset += 4;
|
||||
$info['ogg']['numberofchannels'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 1));
|
||||
$filedataoffset += 1;
|
||||
$info['audio']['channels'] = $info['ogg']['numberofchannels'];
|
||||
$info['ogg']['samplerate'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4));
|
||||
$filedataoffset += 4;
|
||||
if ($info['ogg']['samplerate'] == 0) {
|
||||
$info['error'][] = 'Corrupt Ogg file: sample rate == zero';
|
||||
return false;
|
||||
}
|
||||
$info['audio']['sample_rate'] = $info['ogg']['samplerate'];
|
||||
$info['ogg']['samples'] = 0; // filled in later
|
||||
$info['ogg']['bitrate_average'] = 0; // filled in later
|
||||
$info['ogg']['bitrate_max'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4));
|
||||
$filedataoffset += 4;
|
||||
$info['ogg']['bitrate_nominal'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4));
|
||||
$filedataoffset += 4;
|
||||
$info['ogg']['bitrate_min'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4));
|
||||
$filedataoffset += 4;
|
||||
$info['ogg']['blocksize_small'] = pow(2, getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 1)) & 0x0F);
|
||||
$info['ogg']['blocksize_large'] = pow(2, (getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 1)) & 0xF0) >> 4);
|
||||
$info['ogg']['stop_bit'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 1)); // must be 1, marks end of packet
|
||||
|
||||
$info['audio']['bitrate_mode'] = 'vbr'; // overridden if actually abr
|
||||
if ($info['ogg']['bitrate_max'] == 0xFFFFFFFF) {
|
||||
unset($info['ogg']['bitrate_max']);
|
||||
$info['audio']['bitrate_mode'] = 'abr';
|
||||
}
|
||||
if ($info['ogg']['bitrate_nominal'] == 0xFFFFFFFF) {
|
||||
unset($info['ogg']['bitrate_nominal']);
|
||||
}
|
||||
if ($info['ogg']['bitrate_min'] == 0xFFFFFFFF) {
|
||||
unset($info['ogg']['bitrate_min']);
|
||||
$info['audio']['bitrate_mode'] = 'abr';
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// http://tools.ietf.org/html/draft-ietf-codec-oggopus-03
|
||||
public function ParseOpusPageHeader(&$filedata, &$filedataoffset, &$oggpageinfo) {
|
||||
$info = &$this->getid3->info;
|
||||
$info['audio']['dataformat'] = 'opus';
|
||||
$info['mime_type'] = 'audio/ogg; codecs=opus';
|
||||
|
||||
/** @todo find a usable way to detect abr (vbr that is padded to be abr) */
|
||||
$info['audio']['bitrate_mode'] = 'vbr';
|
||||
|
||||
$info['audio']['lossless'] = false;
|
||||
|
||||
$info['ogg']['pageheader']['opus']['opus_magic'] = substr($filedata, $filedataoffset, 8); // hard-coded to 'OpusHead'
|
||||
$filedataoffset += 8;
|
||||
$info['ogg']['pageheader']['opus']['version'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 1));
|
||||
$filedataoffset += 1;
|
||||
|
||||
if ($info['ogg']['pageheader']['opus']['version'] < 1 || $info['ogg']['pageheader']['opus']['version'] > 15) {
|
||||
$info['error'][] = 'Unknown opus version number (only accepting 1-15)';
|
||||
return false;
|
||||
}
|
||||
|
||||
$info['ogg']['pageheader']['opus']['out_channel_count'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 1));
|
||||
$filedataoffset += 1;
|
||||
|
||||
if ($info['ogg']['pageheader']['opus']['out_channel_count'] == 0) {
|
||||
$info['error'][] = 'Invalid channel count in opus header (must not be zero)';
|
||||
return false;
|
||||
}
|
||||
|
||||
$info['ogg']['pageheader']['opus']['pre_skip'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 2));
|
||||
$filedataoffset += 2;
|
||||
|
||||
$info['ogg']['pageheader']['opus']['sample_rate'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4));
|
||||
$filedataoffset += 4;
|
||||
|
||||
//$info['ogg']['pageheader']['opus']['output_gain'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 2));
|
||||
//$filedataoffset += 2;
|
||||
|
||||
//$info['ogg']['pageheader']['opus']['channel_mapping_family'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 1));
|
||||
//$filedataoffset += 1;
|
||||
|
||||
$info['opus']['opus_version'] = $info['ogg']['pageheader']['opus']['version'];
|
||||
$info['opus']['sample_rate'] = $info['ogg']['pageheader']['opus']['sample_rate'];
|
||||
$info['opus']['out_channel_count'] = $info['ogg']['pageheader']['opus']['out_channel_count'];
|
||||
|
||||
$info['audio']['channels'] = $info['opus']['out_channel_count'];
|
||||
$info['audio']['sample_rate'] = $info['opus']['sample_rate'];
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public function ParseOggPageHeader() {
|
||||
// http://xiph.org/ogg/vorbis/doc/framing.html
|
||||
$oggheader['page_start_offset'] = $this->ftell(); // where we started from in the file
|
||||
|
||||
$filedata = $this->fread($this->getid3->fread_buffer_size());
|
||||
$filedataoffset = 0;
|
||||
while ((substr($filedata, $filedataoffset++, 4) != 'OggS')) {
|
||||
if (($this->ftell() - $oggheader['page_start_offset']) >= $this->getid3->fread_buffer_size()) {
|
||||
// should be found before here
|
||||
return false;
|
||||
}
|
||||
if ((($filedataoffset + 28) > strlen($filedata)) || (strlen($filedata) < 28)) {
|
||||
if ($this->feof() || (($filedata .= $this->fread($this->getid3->fread_buffer_size())) === false)) {
|
||||
// get some more data, unless eof, in which case fail
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
$filedataoffset += strlen('OggS') - 1; // page, delimited by 'OggS'
|
||||
|
||||
$oggheader['stream_structver'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 1));
|
||||
$filedataoffset += 1;
|
||||
$oggheader['flags_raw'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 1));
|
||||
$filedataoffset += 1;
|
||||
$oggheader['flags']['fresh'] = (bool) ($oggheader['flags_raw'] & 0x01); // fresh packet
|
||||
$oggheader['flags']['bos'] = (bool) ($oggheader['flags_raw'] & 0x02); // first page of logical bitstream (bos)
|
||||
$oggheader['flags']['eos'] = (bool) ($oggheader['flags_raw'] & 0x04); // last page of logical bitstream (eos)
|
||||
|
||||
$oggheader['pcm_abs_position'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 8));
|
||||
$filedataoffset += 8;
|
||||
$oggheader['stream_serialno'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4));
|
||||
$filedataoffset += 4;
|
||||
$oggheader['page_seqno'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4));
|
||||
$filedataoffset += 4;
|
||||
$oggheader['page_checksum'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4));
|
||||
$filedataoffset += 4;
|
||||
$oggheader['page_segments'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 1));
|
||||
$filedataoffset += 1;
|
||||
$oggheader['page_length'] = 0;
|
||||
for ($i = 0; $i < $oggheader['page_segments']; $i++) {
|
||||
$oggheader['segment_table'][$i] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 1));
|
||||
$filedataoffset += 1;
|
||||
$oggheader['page_length'] += $oggheader['segment_table'][$i];
|
||||
}
|
||||
$oggheader['header_end_offset'] = $oggheader['page_start_offset'] + $filedataoffset;
|
||||
$oggheader['page_end_offset'] = $oggheader['header_end_offset'] + $oggheader['page_length'];
|
||||
$this->fseek($oggheader['header_end_offset']);
|
||||
|
||||
return $oggheader;
|
||||
}
|
||||
|
||||
// http://xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-810005
|
||||
public function ParseVorbisComments() {
|
||||
$info = &$this->getid3->info;
|
||||
|
||||
$OriginalOffset = $this->ftell();
|
||||
$commentdataoffset = 0;
|
||||
$VorbisCommentPage = 1;
|
||||
|
||||
switch ($info['audio']['dataformat']) {
|
||||
case 'vorbis':
|
||||
case 'speex':
|
||||
case 'opus':
|
||||
$CommentStartOffset = $info['ogg']['pageheader'][$VorbisCommentPage]['page_start_offset']; // Second Ogg page, after header block
|
||||
$this->fseek($CommentStartOffset);
|
||||
$commentdataoffset = 27 + $info['ogg']['pageheader'][$VorbisCommentPage]['page_segments'];
|
||||
$commentdata = $this->fread(self::OggPageSegmentLength($info['ogg']['pageheader'][$VorbisCommentPage], 1) + $commentdataoffset);
|
||||
|
||||
if ($info['audio']['dataformat'] == 'vorbis') {
|
||||
$commentdataoffset += (strlen('vorbis') + 1);
|
||||
}
|
||||
else if ($info['audio']['dataformat'] == 'opus') {
|
||||
$commentdataoffset += strlen('OpusTags');
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'flac':
|
||||
$CommentStartOffset = $info['flac']['VORBIS_COMMENT']['raw']['offset'] + 4;
|
||||
$this->fseek($CommentStartOffset);
|
||||
$commentdata = $this->fread($info['flac']['VORBIS_COMMENT']['raw']['block_length']);
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
$VendorSize = getid3_lib::LittleEndian2Int(substr($commentdata, $commentdataoffset, 4));
|
||||
$commentdataoffset += 4;
|
||||
|
||||
$info['ogg']['vendor'] = substr($commentdata, $commentdataoffset, $VendorSize);
|
||||
$commentdataoffset += $VendorSize;
|
||||
|
||||
$CommentsCount = getid3_lib::LittleEndian2Int(substr($commentdata, $commentdataoffset, 4));
|
||||
$commentdataoffset += 4;
|
||||
$info['avdataoffset'] = $CommentStartOffset + $commentdataoffset;
|
||||
|
||||
$basicfields = array('TITLE', 'ARTIST', 'ALBUM', 'TRACKNUMBER', 'GENRE', 'DATE', 'DESCRIPTION', 'COMMENT');
|
||||
$ThisFileInfo_ogg_comments_raw = &$info['ogg']['comments_raw'];
|
||||
for ($i = 0; $i < $CommentsCount; $i++) {
|
||||
|
||||
if ($i >= 10000) {
|
||||
// https://github.com/owncloud/music/issues/212#issuecomment-43082336
|
||||
$info['warning'][] = 'Unexpectedly large number ('.$CommentsCount.') of Ogg comments - breaking after reading '.$i.' comments';
|
||||
break;
|
||||
}
|
||||
|
||||
$ThisFileInfo_ogg_comments_raw[$i]['dataoffset'] = $CommentStartOffset + $commentdataoffset;
|
||||
|
||||
if ($this->ftell() < ($ThisFileInfo_ogg_comments_raw[$i]['dataoffset'] + 4)) {
|
||||
if ($oggpageinfo = $this->ParseOggPageHeader()) {
|
||||
$info['ogg']['pageheader'][$oggpageinfo['page_seqno']] = $oggpageinfo;
|
||||
|
||||
$VorbisCommentPage++;
|
||||
|
||||
// First, save what we haven't read yet
|
||||
$AsYetUnusedData = substr($commentdata, $commentdataoffset);
|
||||
|
||||
// Then take that data off the end
|
||||
$commentdata = substr($commentdata, 0, $commentdataoffset);
|
||||
|
||||
// Add [headerlength] bytes of dummy data for the Ogg Page Header, just to keep absolute offsets correct
|
||||
$commentdata .= str_repeat("\x00", 27 + $info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['page_segments']);
|
||||
$commentdataoffset += (27 + $info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['page_segments']);
|
||||
|
||||
// Finally, stick the unused data back on the end
|
||||
$commentdata .= $AsYetUnusedData;
|
||||
|
||||
//$commentdata .= $this->fread($info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['page_length']);
|
||||
$commentdata .= $this->fread($this->OggPageSegmentLength($info['ogg']['pageheader'][$VorbisCommentPage], 1));
|
||||
}
|
||||
|
||||
}
|
||||
$ThisFileInfo_ogg_comments_raw[$i]['size'] = getid3_lib::LittleEndian2Int(substr($commentdata, $commentdataoffset, 4));
|
||||
|
||||
// replace avdataoffset with position just after the last vorbiscomment
|
||||
$info['avdataoffset'] = $ThisFileInfo_ogg_comments_raw[$i]['dataoffset'] + $ThisFileInfo_ogg_comments_raw[$i]['size'] + 4;
|
||||
|
||||
$commentdataoffset += 4;
|
||||
while ((strlen($commentdata) - $commentdataoffset) < $ThisFileInfo_ogg_comments_raw[$i]['size']) {
|
||||
if (($ThisFileInfo_ogg_comments_raw[$i]['size'] > $info['avdataend']) || ($ThisFileInfo_ogg_comments_raw[$i]['size'] < 0)) {
|
||||
$info['warning'][] = 'Invalid Ogg comment size (comment #'.$i.', claims to be '.number_format($ThisFileInfo_ogg_comments_raw[$i]['size']).' bytes) - aborting reading comments';
|
||||
break 2;
|
||||
}
|
||||
|
||||
$VorbisCommentPage++;
|
||||
|
||||
$oggpageinfo = $this->ParseOggPageHeader();
|
||||
$info['ogg']['pageheader'][$oggpageinfo['page_seqno']] = $oggpageinfo;
|
||||
|
||||
// First, save what we haven't read yet
|
||||
$AsYetUnusedData = substr($commentdata, $commentdataoffset);
|
||||
|
||||
// Then take that data off the end
|
||||
$commentdata = substr($commentdata, 0, $commentdataoffset);
|
||||
|
||||
// Add [headerlength] bytes of dummy data for the Ogg Page Header, just to keep absolute offsets correct
|
||||
$commentdata .= str_repeat("\x00", 27 + $info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['page_segments']);
|
||||
$commentdataoffset += (27 + $info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['page_segments']);
|
||||
|
||||
// Finally, stick the unused data back on the end
|
||||
$commentdata .= $AsYetUnusedData;
|
||||
|
||||
//$commentdata .= $this->fread($info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['page_length']);
|
||||
if (!isset($info['ogg']['pageheader'][$VorbisCommentPage])) {
|
||||
$info['warning'][] = 'undefined Vorbis Comment page "'.$VorbisCommentPage.'" at offset '.$this->ftell();
|
||||
break;
|
||||
}
|
||||
$readlength = self::OggPageSegmentLength($info['ogg']['pageheader'][$VorbisCommentPage], 1);
|
||||
if ($readlength <= 0) {
|
||||
$info['warning'][] = 'invalid length Vorbis Comment page "'.$VorbisCommentPage.'" at offset '.$this->ftell();
|
||||
break;
|
||||
}
|
||||
$commentdata .= $this->fread($readlength);
|
||||
|
||||
//$filebaseoffset += $oggpageinfo['header_end_offset'] - $oggpageinfo['page_start_offset'];
|
||||
}
|
||||
$ThisFileInfo_ogg_comments_raw[$i]['offset'] = $commentdataoffset;
|
||||
$commentstring = substr($commentdata, $commentdataoffset, $ThisFileInfo_ogg_comments_raw[$i]['size']);
|
||||
$commentdataoffset += $ThisFileInfo_ogg_comments_raw[$i]['size'];
|
||||
|
||||
if (!$commentstring) {
|
||||
|
||||
// no comment?
|
||||
$info['warning'][] = 'Blank Ogg comment ['.$i.']';
|
||||
|
||||
} elseif (strstr($commentstring, '=')) {
|
||||
|
||||
$commentexploded = explode('=', $commentstring, 2);
|
||||
$ThisFileInfo_ogg_comments_raw[$i]['key'] = strtoupper($commentexploded[0]);
|
||||
$ThisFileInfo_ogg_comments_raw[$i]['value'] = (isset($commentexploded[1]) ? $commentexploded[1] : '');
|
||||
|
||||
if ($ThisFileInfo_ogg_comments_raw[$i]['key'] == 'METADATA_BLOCK_PICTURE') {
|
||||
|
||||
// http://wiki.xiph.org/VorbisComment#METADATA_BLOCK_PICTURE
|
||||
// The unencoded format is that of the FLAC picture block. The fields are stored in big endian order as in FLAC, picture data is stored according to the relevant standard.
|
||||
// http://flac.sourceforge.net/format.html#metadata_block_picture
|
||||
$flac = new getid3_flac($this->getid3);
|
||||
$flac->setStringMode(base64_decode($ThisFileInfo_ogg_comments_raw[$i]['value']));
|
||||
$flac->parsePICTURE();
|
||||
$info['ogg']['comments']['picture'][] = $flac->getid3->info['flac']['PICTURE'][0];
|
||||
unset($flac);
|
||||
|
||||
} elseif ($ThisFileInfo_ogg_comments_raw[$i]['key'] == 'COVERART') {
|
||||
|
||||
$data = base64_decode($ThisFileInfo_ogg_comments_raw[$i]['value']);
|
||||
$this->notice('Found deprecated COVERART tag, it should be replaced in honor of METADATA_BLOCK_PICTURE structure');
|
||||
/** @todo use 'coverartmime' where available */
|
||||
$imageinfo = getid3_lib::GetDataImageSize($data);
|
||||
if ($imageinfo === false || !isset($imageinfo['mime'])) {
|
||||
$this->warning('COVERART vorbiscomment tag contains invalid image');
|
||||
continue;
|
||||
}
|
||||
|
||||
$ogg = new self($this->getid3);
|
||||
$ogg->setStringMode($data);
|
||||
$info['ogg']['comments']['picture'][] = array(
|
||||
'image_mime' => $imageinfo['mime'],
|
||||
'datalength' => strlen($data),
|
||||
'picturetype' => 'cover art',
|
||||
'image_height' => $imageinfo['height'],
|
||||
'image_width' => $imageinfo['width'],
|
||||
'data' => $ogg->saveAttachment('coverart', 0, strlen($data), $imageinfo['mime']),
|
||||
);
|
||||
unset($ogg);
|
||||
|
||||
} else {
|
||||
|
||||
$info['ogg']['comments'][strtolower($ThisFileInfo_ogg_comments_raw[$i]['key'])][] = $ThisFileInfo_ogg_comments_raw[$i]['value'];
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
$info['warning'][] = '[known problem with CDex >= v1.40, < v1.50b7] Invalid Ogg comment name/value pair ['.$i.']: '.$commentstring;
|
||||
|
||||
}
|
||||
unset($ThisFileInfo_ogg_comments_raw[$i]);
|
||||
}
|
||||
unset($ThisFileInfo_ogg_comments_raw);
|
||||
|
||||
|
||||
// Replay Gain Adjustment
|
||||
// http://privatewww.essex.ac.uk/~djmrob/replaygain/
|
||||
if (isset($info['ogg']['comments']) && is_array($info['ogg']['comments'])) {
|
||||
foreach ($info['ogg']['comments'] as $index => $commentvalue) {
|
||||
switch ($index) {
|
||||
case 'rg_audiophile':
|
||||
case 'replaygain_album_gain':
|
||||
$info['replay_gain']['album']['adjustment'] = (double) $commentvalue[0];
|
||||
unset($info['ogg']['comments'][$index]);
|
||||
break;
|
||||
|
||||
case 'rg_radio':
|
||||
case 'replaygain_track_gain':
|
||||
$info['replay_gain']['track']['adjustment'] = (double) $commentvalue[0];
|
||||
unset($info['ogg']['comments'][$index]);
|
||||
break;
|
||||
|
||||
case 'replaygain_album_peak':
|
||||
$info['replay_gain']['album']['peak'] = (double) $commentvalue[0];
|
||||
unset($info['ogg']['comments'][$index]);
|
||||
break;
|
||||
|
||||
case 'rg_peak':
|
||||
case 'replaygain_track_peak':
|
||||
$info['replay_gain']['track']['peak'] = (double) $commentvalue[0];
|
||||
unset($info['ogg']['comments'][$index]);
|
||||
break;
|
||||
|
||||
case 'replaygain_reference_loudness':
|
||||
$info['replay_gain']['reference_volume'] = (double) $commentvalue[0];
|
||||
unset($info['ogg']['comments'][$index]);
|
||||
break;
|
||||
|
||||
default:
|
||||
// do nothing
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->fseek($OriginalOffset);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function SpeexBandModeLookup($mode) {
|
||||
static $SpeexBandModeLookup = array();
|
||||
if (empty($SpeexBandModeLookup)) {
|
||||
$SpeexBandModeLookup[0] = 'narrow';
|
||||
$SpeexBandModeLookup[1] = 'wide';
|
||||
$SpeexBandModeLookup[2] = 'ultra-wide';
|
||||
}
|
||||
return (isset($SpeexBandModeLookup[$mode]) ? $SpeexBandModeLookup[$mode] : null);
|
||||
}
|
||||
|
||||
|
||||
public static function OggPageSegmentLength($OggInfoArray, $SegmentNumber=1) {
|
||||
for ($i = 0; $i < $SegmentNumber; $i++) {
|
||||
$segmentlength = 0;
|
||||
foreach ($OggInfoArray['segment_table'] as $key => $value) {
|
||||
$segmentlength += $value;
|
||||
if ($value < 255) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $segmentlength;
|
||||
}
|
||||
|
||||
|
||||
public static function get_quality_from_nominal_bitrate($nominal_bitrate) {
|
||||
|
||||
// decrease precision
|
||||
$nominal_bitrate = $nominal_bitrate / 1000;
|
||||
|
||||
if ($nominal_bitrate < 128) {
|
||||
// q-1 to q4
|
||||
$qval = ($nominal_bitrate - 64) / 16;
|
||||
} elseif ($nominal_bitrate < 256) {
|
||||
// q4 to q8
|
||||
$qval = $nominal_bitrate / 32;
|
||||
} elseif ($nominal_bitrate < 320) {
|
||||
// q8 to q9
|
||||
$qval = ($nominal_bitrate + 256) / 64;
|
||||
} else {
|
||||
// q9 to q10
|
||||
$qval = ($nominal_bitrate + 1300) / 180;
|
||||
}
|
||||
//return $qval; // 5.031324
|
||||
//return intval($qval); // 5
|
||||
return round($qval, 1); // 5 or 4.9
|
||||
}
|
||||
|
||||
public static function TheoraColorSpace($colorspace_id) {
|
||||
// http://www.theora.org/doc/Theora.pdf (table 6.3)
|
||||
static $TheoraColorSpaceLookup = array();
|
||||
if (empty($TheoraColorSpaceLookup)) {
|
||||
$TheoraColorSpaceLookup[0] = 'Undefined';
|
||||
$TheoraColorSpaceLookup[1] = 'Rec. 470M';
|
||||
$TheoraColorSpaceLookup[2] = 'Rec. 470BG';
|
||||
$TheoraColorSpaceLookup[3] = 'Reserved';
|
||||
}
|
||||
return (isset($TheoraColorSpaceLookup[$colorspace_id]) ? $TheoraColorSpaceLookup[$colorspace_id] : null);
|
||||
}
|
||||
|
||||
public static function TheoraPixelFormat($pixelformat_id) {
|
||||
// http://www.theora.org/doc/Theora.pdf (table 6.4)
|
||||
static $TheoraPixelFormatLookup = array();
|
||||
if (empty($TheoraPixelFormatLookup)) {
|
||||
$TheoraPixelFormatLookup[0] = '4:2:0';
|
||||
$TheoraPixelFormatLookup[1] = 'Reserved';
|
||||
$TheoraPixelFormatLookup[2] = '4:2:2';
|
||||
$TheoraPixelFormatLookup[3] = '4:4:4';
|
||||
}
|
||||
return (isset($TheoraPixelFormatLookup[$pixelformat_id]) ? $TheoraPixelFormatLookup[$pixelformat_id] : null);
|
||||
}
|
||||
|
||||
}
|
||||
412
Kapitel_7/Lektion_4/wordpress/wp-includes/ID3/module.tag.apetag.php
Executable file
412
Kapitel_7/Lektion_4/wordpress/wp-includes/ID3/module.tag.apetag.php
Executable file
@@ -0,0 +1,412 @@
|
||||
<?php
|
||||
/////////////////////////////////////////////////////////////////
|
||||
/// getID3() by James Heinrich <info@getid3.org> //
|
||||
// available at http://getid3.sourceforge.net //
|
||||
// or http://www.getid3.org //
|
||||
// also https://github.com/JamesHeinrich/getID3 //
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// See readme.txt for more details //
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// module.tag.apetag.php //
|
||||
// module for analyzing APE tags //
|
||||
// dependencies: NONE //
|
||||
// ///
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
class getid3_apetag extends getid3_handler
|
||||
{
|
||||
public $inline_attachments = true; // true: return full data for all attachments; false: return no data for all attachments; integer: return data for attachments <= than this; string: save as file to this directory
|
||||
public $overrideendoffset = 0;
|
||||
|
||||
public function Analyze() {
|
||||
$info = &$this->getid3->info;
|
||||
|
||||
if (!getid3_lib::intValueSupported($info['filesize'])) {
|
||||
$info['warning'][] = 'Unable to check for APEtags because file is larger than '.round(PHP_INT_MAX / 1073741824).'GB';
|
||||
return false;
|
||||
}
|
||||
|
||||
$id3v1tagsize = 128;
|
||||
$apetagheadersize = 32;
|
||||
$lyrics3tagsize = 10;
|
||||
|
||||
if ($this->overrideendoffset == 0) {
|
||||
|
||||
$this->fseek(0 - $id3v1tagsize - $apetagheadersize - $lyrics3tagsize, SEEK_END);
|
||||
$APEfooterID3v1 = $this->fread($id3v1tagsize + $apetagheadersize + $lyrics3tagsize);
|
||||
|
||||
//if (preg_match('/APETAGEX.{24}TAG.{125}$/i', $APEfooterID3v1)) {
|
||||
if (substr($APEfooterID3v1, strlen($APEfooterID3v1) - $id3v1tagsize - $apetagheadersize, 8) == 'APETAGEX') {
|
||||
|
||||
// APE tag found before ID3v1
|
||||
$info['ape']['tag_offset_end'] = $info['filesize'] - $id3v1tagsize;
|
||||
|
||||
//} elseif (preg_match('/APETAGEX.{24}$/i', $APEfooterID3v1)) {
|
||||
} elseif (substr($APEfooterID3v1, strlen($APEfooterID3v1) - $apetagheadersize, 8) == 'APETAGEX') {
|
||||
|
||||
// APE tag found, no ID3v1
|
||||
$info['ape']['tag_offset_end'] = $info['filesize'];
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
$this->fseek($this->overrideendoffset - $apetagheadersize);
|
||||
if ($this->fread(8) == 'APETAGEX') {
|
||||
$info['ape']['tag_offset_end'] = $this->overrideendoffset;
|
||||
}
|
||||
|
||||
}
|
||||
if (!isset($info['ape']['tag_offset_end'])) {
|
||||
|
||||
// APE tag not found
|
||||
unset($info['ape']);
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
// shortcut
|
||||
$thisfile_ape = &$info['ape'];
|
||||
|
||||
$this->fseek($thisfile_ape['tag_offset_end'] - $apetagheadersize);
|
||||
$APEfooterData = $this->fread(32);
|
||||
if (!($thisfile_ape['footer'] = $this->parseAPEheaderFooter($APEfooterData))) {
|
||||
$info['error'][] = 'Error parsing APE footer at offset '.$thisfile_ape['tag_offset_end'];
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isset($thisfile_ape['footer']['flags']['header']) && $thisfile_ape['footer']['flags']['header']) {
|
||||
$this->fseek($thisfile_ape['tag_offset_end'] - $thisfile_ape['footer']['raw']['tagsize'] - $apetagheadersize);
|
||||
$thisfile_ape['tag_offset_start'] = $this->ftell();
|
||||
$APEtagData = $this->fread($thisfile_ape['footer']['raw']['tagsize'] + $apetagheadersize);
|
||||
} else {
|
||||
$thisfile_ape['tag_offset_start'] = $thisfile_ape['tag_offset_end'] - $thisfile_ape['footer']['raw']['tagsize'];
|
||||
$this->fseek($thisfile_ape['tag_offset_start']);
|
||||
$APEtagData = $this->fread($thisfile_ape['footer']['raw']['tagsize']);
|
||||
}
|
||||
$info['avdataend'] = $thisfile_ape['tag_offset_start'];
|
||||
|
||||
if (isset($info['id3v1']['tag_offset_start']) && ($info['id3v1']['tag_offset_start'] < $thisfile_ape['tag_offset_end'])) {
|
||||
$info['warning'][] = 'ID3v1 tag information ignored since it appears to be a false synch in APEtag data';
|
||||
unset($info['id3v1']);
|
||||
foreach ($info['warning'] as $key => $value) {
|
||||
if ($value == 'Some ID3v1 fields do not use NULL characters for padding') {
|
||||
unset($info['warning'][$key]);
|
||||
sort($info['warning']);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$offset = 0;
|
||||
if (isset($thisfile_ape['footer']['flags']['header']) && $thisfile_ape['footer']['flags']['header']) {
|
||||
if ($thisfile_ape['header'] = $this->parseAPEheaderFooter(substr($APEtagData, 0, $apetagheadersize))) {
|
||||
$offset += $apetagheadersize;
|
||||
} else {
|
||||
$info['error'][] = 'Error parsing APE header at offset '.$thisfile_ape['tag_offset_start'];
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// shortcut
|
||||
$info['replay_gain'] = array();
|
||||
$thisfile_replaygain = &$info['replay_gain'];
|
||||
|
||||
for ($i = 0; $i < $thisfile_ape['footer']['raw']['tag_items']; $i++) {
|
||||
$value_size = getid3_lib::LittleEndian2Int(substr($APEtagData, $offset, 4));
|
||||
$offset += 4;
|
||||
$item_flags = getid3_lib::LittleEndian2Int(substr($APEtagData, $offset, 4));
|
||||
$offset += 4;
|
||||
if (strstr(substr($APEtagData, $offset), "\x00") === false) {
|
||||
$info['error'][] = 'Cannot find null-byte (0x00) seperator between ItemKey #'.$i.' and value. ItemKey starts '.$offset.' bytes into the APE tag, at file offset '.($thisfile_ape['tag_offset_start'] + $offset);
|
||||
return false;
|
||||
}
|
||||
$ItemKeyLength = strpos($APEtagData, "\x00", $offset) - $offset;
|
||||
$item_key = strtolower(substr($APEtagData, $offset, $ItemKeyLength));
|
||||
|
||||
// shortcut
|
||||
$thisfile_ape['items'][$item_key] = array();
|
||||
$thisfile_ape_items_current = &$thisfile_ape['items'][$item_key];
|
||||
|
||||
$thisfile_ape_items_current['offset'] = $thisfile_ape['tag_offset_start'] + $offset;
|
||||
|
||||
$offset += ($ItemKeyLength + 1); // skip 0x00 terminator
|
||||
$thisfile_ape_items_current['data'] = substr($APEtagData, $offset, $value_size);
|
||||
$offset += $value_size;
|
||||
|
||||
$thisfile_ape_items_current['flags'] = $this->parseAPEtagFlags($item_flags);
|
||||
switch ($thisfile_ape_items_current['flags']['item_contents_raw']) {
|
||||
case 0: // UTF-8
|
||||
case 2: // Locator (URL, filename, etc), UTF-8 encoded
|
||||
$thisfile_ape_items_current['data'] = explode("\x00", $thisfile_ape_items_current['data']);
|
||||
break;
|
||||
|
||||
case 1: // binary data
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (strtolower($item_key)) {
|
||||
// http://wiki.hydrogenaud.io/index.php?title=ReplayGain#MP3Gain
|
||||
case 'replaygain_track_gain':
|
||||
if (preg_match('#^[\\-\\+][0-9\\.,]{8}$#', $thisfile_ape_items_current['data'][0])) {
|
||||
$thisfile_replaygain['track']['adjustment'] = (float) str_replace(',', '.', $thisfile_ape_items_current['data'][0]); // float casting will see "0,95" as zero!
|
||||
$thisfile_replaygain['track']['originator'] = 'unspecified';
|
||||
} else {
|
||||
$info['warning'][] = 'MP3gainTrackGain value in APEtag appears invalid: "'.$thisfile_ape_items_current['data'][0].'"';
|
||||
}
|
||||
break;
|
||||
|
||||
case 'replaygain_track_peak':
|
||||
if (preg_match('#^[0-9\\.,]{8}$#', $thisfile_ape_items_current['data'][0])) {
|
||||
$thisfile_replaygain['track']['peak'] = (float) str_replace(',', '.', $thisfile_ape_items_current['data'][0]); // float casting will see "0,95" as zero!
|
||||
$thisfile_replaygain['track']['originator'] = 'unspecified';
|
||||
if ($thisfile_replaygain['track']['peak'] <= 0) {
|
||||
$info['warning'][] = 'ReplayGain Track peak from APEtag appears invalid: '.$thisfile_replaygain['track']['peak'].' (original value = "'.$thisfile_ape_items_current['data'][0].'")';
|
||||
}
|
||||
} else {
|
||||
$info['warning'][] = 'MP3gainTrackPeak value in APEtag appears invalid: "'.$thisfile_ape_items_current['data'][0].'"';
|
||||
}
|
||||
break;
|
||||
|
||||
case 'replaygain_album_gain':
|
||||
if (preg_match('#^[\\-\\+][0-9\\.,]{8}$#', $thisfile_ape_items_current['data'][0])) {
|
||||
$thisfile_replaygain['album']['adjustment'] = (float) str_replace(',', '.', $thisfile_ape_items_current['data'][0]); // float casting will see "0,95" as zero!
|
||||
$thisfile_replaygain['album']['originator'] = 'unspecified';
|
||||
} else {
|
||||
$info['warning'][] = 'MP3gainAlbumGain value in APEtag appears invalid: "'.$thisfile_ape_items_current['data'][0].'"';
|
||||
}
|
||||
break;
|
||||
|
||||
case 'replaygain_album_peak':
|
||||
if (preg_match('#^[0-9\\.,]{8}$#', $thisfile_ape_items_current['data'][0])) {
|
||||
$thisfile_replaygain['album']['peak'] = (float) str_replace(',', '.', $thisfile_ape_items_current['data'][0]); // float casting will see "0,95" as zero!
|
||||
$thisfile_replaygain['album']['originator'] = 'unspecified';
|
||||
if ($thisfile_replaygain['album']['peak'] <= 0) {
|
||||
$info['warning'][] = 'ReplayGain Album peak from APEtag appears invalid: '.$thisfile_replaygain['album']['peak'].' (original value = "'.$thisfile_ape_items_current['data'][0].'")';
|
||||
}
|
||||
} else {
|
||||
$info['warning'][] = 'MP3gainAlbumPeak value in APEtag appears invalid: "'.$thisfile_ape_items_current['data'][0].'"';
|
||||
}
|
||||
break;
|
||||
|
||||
case 'mp3gain_undo':
|
||||
if (preg_match('#^[\\-\\+][0-9]{3},[\\-\\+][0-9]{3},[NW]$#', $thisfile_ape_items_current['data'][0])) {
|
||||
list($mp3gain_undo_left, $mp3gain_undo_right, $mp3gain_undo_wrap) = explode(',', $thisfile_ape_items_current['data'][0]);
|
||||
$thisfile_replaygain['mp3gain']['undo_left'] = intval($mp3gain_undo_left);
|
||||
$thisfile_replaygain['mp3gain']['undo_right'] = intval($mp3gain_undo_right);
|
||||
$thisfile_replaygain['mp3gain']['undo_wrap'] = (($mp3gain_undo_wrap == 'Y') ? true : false);
|
||||
} else {
|
||||
$info['warning'][] = 'MP3gainUndo value in APEtag appears invalid: "'.$thisfile_ape_items_current['data'][0].'"';
|
||||
}
|
||||
break;
|
||||
|
||||
case 'mp3gain_minmax':
|
||||
if (preg_match('#^[0-9]{3},[0-9]{3}$#', $thisfile_ape_items_current['data'][0])) {
|
||||
list($mp3gain_globalgain_min, $mp3gain_globalgain_max) = explode(',', $thisfile_ape_items_current['data'][0]);
|
||||
$thisfile_replaygain['mp3gain']['globalgain_track_min'] = intval($mp3gain_globalgain_min);
|
||||
$thisfile_replaygain['mp3gain']['globalgain_track_max'] = intval($mp3gain_globalgain_max);
|
||||
} else {
|
||||
$info['warning'][] = 'MP3gainMinMax value in APEtag appears invalid: "'.$thisfile_ape_items_current['data'][0].'"';
|
||||
}
|
||||
break;
|
||||
|
||||
case 'mp3gain_album_minmax':
|
||||
if (preg_match('#^[0-9]{3},[0-9]{3}$#', $thisfile_ape_items_current['data'][0])) {
|
||||
list($mp3gain_globalgain_album_min, $mp3gain_globalgain_album_max) = explode(',', $thisfile_ape_items_current['data'][0]);
|
||||
$thisfile_replaygain['mp3gain']['globalgain_album_min'] = intval($mp3gain_globalgain_album_min);
|
||||
$thisfile_replaygain['mp3gain']['globalgain_album_max'] = intval($mp3gain_globalgain_album_max);
|
||||
} else {
|
||||
$info['warning'][] = 'MP3gainAlbumMinMax value in APEtag appears invalid: "'.$thisfile_ape_items_current['data'][0].'"';
|
||||
}
|
||||
break;
|
||||
|
||||
case 'tracknumber':
|
||||
if (is_array($thisfile_ape_items_current['data'])) {
|
||||
foreach ($thisfile_ape_items_current['data'] as $comment) {
|
||||
$thisfile_ape['comments']['track'][] = $comment;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'cover art (artist)':
|
||||
case 'cover art (back)':
|
||||
case 'cover art (band logo)':
|
||||
case 'cover art (band)':
|
||||
case 'cover art (colored fish)':
|
||||
case 'cover art (composer)':
|
||||
case 'cover art (conductor)':
|
||||
case 'cover art (front)':
|
||||
case 'cover art (icon)':
|
||||
case 'cover art (illustration)':
|
||||
case 'cover art (lead)':
|
||||
case 'cover art (leaflet)':
|
||||
case 'cover art (lyricist)':
|
||||
case 'cover art (media)':
|
||||
case 'cover art (movie scene)':
|
||||
case 'cover art (other icon)':
|
||||
case 'cover art (other)':
|
||||
case 'cover art (performance)':
|
||||
case 'cover art (publisher logo)':
|
||||
case 'cover art (recording)':
|
||||
case 'cover art (studio)':
|
||||
// list of possible cover arts from http://taglib-sharp.sourcearchive.com/documentation/2.0.3.0-2/Ape_2Tag_8cs-source.html
|
||||
if (is_array($thisfile_ape_items_current['data'])) {
|
||||
$info['warning'][] = 'APEtag "'.$item_key.'" should be flagged as Binary data, but was incorrectly flagged as UTF-8';
|
||||
$thisfile_ape_items_current['data'] = implode("\x00", $thisfile_ape_items_current['data']);
|
||||
}
|
||||
list($thisfile_ape_items_current['filename'], $thisfile_ape_items_current['data']) = explode("\x00", $thisfile_ape_items_current['data'], 2);
|
||||
$thisfile_ape_items_current['data_offset'] = $thisfile_ape_items_current['offset'] + strlen($thisfile_ape_items_current['filename']."\x00");
|
||||
$thisfile_ape_items_current['data_length'] = strlen($thisfile_ape_items_current['data']);
|
||||
|
||||
$thisfile_ape_items_current['image_mime'] = '';
|
||||
$imageinfo = array();
|
||||
$imagechunkcheck = getid3_lib::GetDataImageSize($thisfile_ape_items_current['data'], $imageinfo);
|
||||
$thisfile_ape_items_current['image_mime'] = image_type_to_mime_type($imagechunkcheck[2]);
|
||||
|
||||
do {
|
||||
if ($this->inline_attachments === false) {
|
||||
// skip entirely
|
||||
unset($thisfile_ape_items_current['data']);
|
||||
break;
|
||||
}
|
||||
if ($this->inline_attachments === true) {
|
||||
// great
|
||||
} elseif (is_int($this->inline_attachments)) {
|
||||
if ($this->inline_attachments < $thisfile_ape_items_current['data_length']) {
|
||||
// too big, skip
|
||||
$info['warning'][] = 'attachment at '.$thisfile_ape_items_current['offset'].' is too large to process inline ('.number_format($thisfile_ape_items_current['data_length']).' bytes)';
|
||||
unset($thisfile_ape_items_current['data']);
|
||||
break;
|
||||
}
|
||||
} elseif (is_string($this->inline_attachments)) {
|
||||
$this->inline_attachments = rtrim(str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $this->inline_attachments), DIRECTORY_SEPARATOR);
|
||||
if (!is_dir($this->inline_attachments) || !is_writable($this->inline_attachments)) {
|
||||
// cannot write, skip
|
||||
$info['warning'][] = 'attachment at '.$thisfile_ape_items_current['offset'].' cannot be saved to "'.$this->inline_attachments.'" (not writable)';
|
||||
unset($thisfile_ape_items_current['data']);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// if we get this far, must be OK
|
||||
if (is_string($this->inline_attachments)) {
|
||||
$destination_filename = $this->inline_attachments.DIRECTORY_SEPARATOR.md5($info['filenamepath']).'_'.$thisfile_ape_items_current['data_offset'];
|
||||
if (!file_exists($destination_filename) || is_writable($destination_filename)) {
|
||||
file_put_contents($destination_filename, $thisfile_ape_items_current['data']);
|
||||
} else {
|
||||
$info['warning'][] = 'attachment at '.$thisfile_ape_items_current['offset'].' cannot be saved to "'.$destination_filename.'" (not writable)';
|
||||
}
|
||||
$thisfile_ape_items_current['data_filename'] = $destination_filename;
|
||||
unset($thisfile_ape_items_current['data']);
|
||||
} else {
|
||||
if (!isset($info['ape']['comments']['picture'])) {
|
||||
$info['ape']['comments']['picture'] = array();
|
||||
}
|
||||
$comments_picture_data = array();
|
||||
foreach (array('data', 'image_mime', 'image_width', 'image_height', 'imagetype', 'picturetype', 'description', 'datalength') as $picture_key) {
|
||||
if (isset($thisfile_ape_items_current[$picture_key])) {
|
||||
$comments_picture_data[$picture_key] = $thisfile_ape_items_current[$picture_key];
|
||||
}
|
||||
}
|
||||
$info['ape']['comments']['picture'][] = $comments_picture_data;
|
||||
unset($comments_picture_data);
|
||||
}
|
||||
} while (false);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (is_array($thisfile_ape_items_current['data'])) {
|
||||
foreach ($thisfile_ape_items_current['data'] as $comment) {
|
||||
$thisfile_ape['comments'][strtolower($item_key)][] = $comment;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
if (empty($thisfile_replaygain)) {
|
||||
unset($info['replay_gain']);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function parseAPEheaderFooter($APEheaderFooterData) {
|
||||
// http://www.uni-jena.de/~pfk/mpp/sv8/apeheader.html
|
||||
|
||||
// shortcut
|
||||
$headerfooterinfo['raw'] = array();
|
||||
$headerfooterinfo_raw = &$headerfooterinfo['raw'];
|
||||
|
||||
$headerfooterinfo_raw['footer_tag'] = substr($APEheaderFooterData, 0, 8);
|
||||
if ($headerfooterinfo_raw['footer_tag'] != 'APETAGEX') {
|
||||
return false;
|
||||
}
|
||||
$headerfooterinfo_raw['version'] = getid3_lib::LittleEndian2Int(substr($APEheaderFooterData, 8, 4));
|
||||
$headerfooterinfo_raw['tagsize'] = getid3_lib::LittleEndian2Int(substr($APEheaderFooterData, 12, 4));
|
||||
$headerfooterinfo_raw['tag_items'] = getid3_lib::LittleEndian2Int(substr($APEheaderFooterData, 16, 4));
|
||||
$headerfooterinfo_raw['global_flags'] = getid3_lib::LittleEndian2Int(substr($APEheaderFooterData, 20, 4));
|
||||
$headerfooterinfo_raw['reserved'] = substr($APEheaderFooterData, 24, 8);
|
||||
|
||||
$headerfooterinfo['tag_version'] = $headerfooterinfo_raw['version'] / 1000;
|
||||
if ($headerfooterinfo['tag_version'] >= 2) {
|
||||
$headerfooterinfo['flags'] = $this->parseAPEtagFlags($headerfooterinfo_raw['global_flags']);
|
||||
}
|
||||
return $headerfooterinfo;
|
||||
}
|
||||
|
||||
public function parseAPEtagFlags($rawflagint) {
|
||||
// "Note: APE Tags 1.0 do not use any of the APE Tag flags.
|
||||
// All are set to zero on creation and ignored on reading."
|
||||
// http://wiki.hydrogenaud.io/index.php?title=Ape_Tags_Flags
|
||||
$flags['header'] = (bool) ($rawflagint & 0x80000000);
|
||||
$flags['footer'] = (bool) ($rawflagint & 0x40000000);
|
||||
$flags['this_is_header'] = (bool) ($rawflagint & 0x20000000);
|
||||
$flags['item_contents_raw'] = ($rawflagint & 0x00000006) >> 1;
|
||||
$flags['read_only'] = (bool) ($rawflagint & 0x00000001);
|
||||
|
||||
$flags['item_contents'] = $this->APEcontentTypeFlagLookup($flags['item_contents_raw']);
|
||||
|
||||
return $flags;
|
||||
}
|
||||
|
||||
public function APEcontentTypeFlagLookup($contenttypeid) {
|
||||
static $APEcontentTypeFlagLookup = array(
|
||||
0 => 'utf-8',
|
||||
1 => 'binary',
|
||||
2 => 'external',
|
||||
3 => 'reserved'
|
||||
);
|
||||
return (isset($APEcontentTypeFlagLookup[$contenttypeid]) ? $APEcontentTypeFlagLookup[$contenttypeid] : 'invalid');
|
||||
}
|
||||
|
||||
public function APEtagItemIsUTF8Lookup($itemkey) {
|
||||
static $APEtagItemIsUTF8Lookup = array(
|
||||
'title',
|
||||
'subtitle',
|
||||
'artist',
|
||||
'album',
|
||||
'debut album',
|
||||
'publisher',
|
||||
'conductor',
|
||||
'track',
|
||||
'composer',
|
||||
'comment',
|
||||
'copyright',
|
||||
'publicationright',
|
||||
'file',
|
||||
'year',
|
||||
'record date',
|
||||
'record location',
|
||||
'genre',
|
||||
'media',
|
||||
'related',
|
||||
'isrc',
|
||||
'abstract',
|
||||
'language',
|
||||
'bibliography'
|
||||
);
|
||||
return in_array(strtolower($itemkey), $APEtagItemIsUTF8Lookup);
|
||||
}
|
||||
|
||||
}
|
||||
360
Kapitel_7/Lektion_4/wordpress/wp-includes/ID3/module.tag.id3v1.php
Executable file
360
Kapitel_7/Lektion_4/wordpress/wp-includes/ID3/module.tag.id3v1.php
Executable file
@@ -0,0 +1,360 @@
|
||||
<?php
|
||||
/////////////////////////////////////////////////////////////////
|
||||
/// getID3() by James Heinrich <info@getid3.org> //
|
||||
// available at http://getid3.sourceforge.net //
|
||||
// or http://www.getid3.org //
|
||||
// also https://github.com/JamesHeinrich/getID3 //
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// See readme.txt for more details //
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// module.tag.id3v1.php //
|
||||
// module for analyzing ID3v1 tags //
|
||||
// dependencies: NONE //
|
||||
// ///
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
class getid3_id3v1 extends getid3_handler
|
||||
{
|
||||
|
||||
public function Analyze() {
|
||||
$info = &$this->getid3->info;
|
||||
|
||||
if (!getid3_lib::intValueSupported($info['filesize'])) {
|
||||
$info['warning'][] = 'Unable to check for ID3v1 because file is larger than '.round(PHP_INT_MAX / 1073741824).'GB';
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->fseek(-256, SEEK_END);
|
||||
$preid3v1 = $this->fread(128);
|
||||
$id3v1tag = $this->fread(128);
|
||||
|
||||
if (substr($id3v1tag, 0, 3) == 'TAG') {
|
||||
|
||||
$info['avdataend'] = $info['filesize'] - 128;
|
||||
|
||||
$ParsedID3v1['title'] = $this->cutfield(substr($id3v1tag, 3, 30));
|
||||
$ParsedID3v1['artist'] = $this->cutfield(substr($id3v1tag, 33, 30));
|
||||
$ParsedID3v1['album'] = $this->cutfield(substr($id3v1tag, 63, 30));
|
||||
$ParsedID3v1['year'] = $this->cutfield(substr($id3v1tag, 93, 4));
|
||||
$ParsedID3v1['comment'] = substr($id3v1tag, 97, 30); // can't remove nulls yet, track detection depends on them
|
||||
$ParsedID3v1['genreid'] = ord(substr($id3v1tag, 127, 1));
|
||||
|
||||
// If second-last byte of comment field is null and last byte of comment field is non-null
|
||||
// then this is ID3v1.1 and the comment field is 28 bytes long and the 30th byte is the track number
|
||||
if (($id3v1tag{125} === "\x00") && ($id3v1tag{126} !== "\x00")) {
|
||||
$ParsedID3v1['track'] = ord(substr($ParsedID3v1['comment'], 29, 1));
|
||||
$ParsedID3v1['comment'] = substr($ParsedID3v1['comment'], 0, 28);
|
||||
}
|
||||
$ParsedID3v1['comment'] = $this->cutfield($ParsedID3v1['comment']);
|
||||
|
||||
$ParsedID3v1['genre'] = $this->LookupGenreName($ParsedID3v1['genreid']);
|
||||
if (!empty($ParsedID3v1['genre'])) {
|
||||
unset($ParsedID3v1['genreid']);
|
||||
}
|
||||
if (isset($ParsedID3v1['genre']) && (empty($ParsedID3v1['genre']) || ($ParsedID3v1['genre'] == 'Unknown'))) {
|
||||
unset($ParsedID3v1['genre']);
|
||||
}
|
||||
|
||||
foreach ($ParsedID3v1 as $key => $value) {
|
||||
$ParsedID3v1['comments'][$key][0] = $value;
|
||||
}
|
||||
|
||||
// ID3v1 data is supposed to be padded with NULL characters, but some taggers pad with spaces
|
||||
$GoodFormatID3v1tag = $this->GenerateID3v1Tag(
|
||||
$ParsedID3v1['title'],
|
||||
$ParsedID3v1['artist'],
|
||||
$ParsedID3v1['album'],
|
||||
$ParsedID3v1['year'],
|
||||
(isset($ParsedID3v1['genre']) ? $this->LookupGenreID($ParsedID3v1['genre']) : false),
|
||||
$ParsedID3v1['comment'],
|
||||
(!empty($ParsedID3v1['track']) ? $ParsedID3v1['track'] : ''));
|
||||
$ParsedID3v1['padding_valid'] = true;
|
||||
if ($id3v1tag !== $GoodFormatID3v1tag) {
|
||||
$ParsedID3v1['padding_valid'] = false;
|
||||
$info['warning'][] = 'Some ID3v1 fields do not use NULL characters for padding';
|
||||
}
|
||||
|
||||
$ParsedID3v1['tag_offset_end'] = $info['filesize'];
|
||||
$ParsedID3v1['tag_offset_start'] = $ParsedID3v1['tag_offset_end'] - 128;
|
||||
|
||||
$info['id3v1'] = $ParsedID3v1;
|
||||
}
|
||||
|
||||
if (substr($preid3v1, 0, 3) == 'TAG') {
|
||||
// The way iTunes handles tags is, well, brain-damaged.
|
||||
// It completely ignores v1 if ID3v2 is present.
|
||||
// This goes as far as adding a new v1 tag *even if there already is one*
|
||||
|
||||
// A suspected double-ID3v1 tag has been detected, but it could be that
|
||||
// the "TAG" identifier is a legitimate part of an APE or Lyrics3 tag
|
||||
if (substr($preid3v1, 96, 8) == 'APETAGEX') {
|
||||
// an APE tag footer was found before the last ID3v1, assume false "TAG" synch
|
||||
} elseif (substr($preid3v1, 119, 6) == 'LYRICS') {
|
||||
// a Lyrics3 tag footer was found before the last ID3v1, assume false "TAG" synch
|
||||
} else {
|
||||
// APE and Lyrics3 footers not found - assume double ID3v1
|
||||
$info['warning'][] = 'Duplicate ID3v1 tag detected - this has been known to happen with iTunes';
|
||||
$info['avdataend'] -= 128;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function cutfield($str) {
|
||||
return trim(substr($str, 0, strcspn($str, "\x00")));
|
||||
}
|
||||
|
||||
public static function ArrayOfGenres($allowSCMPXextended=false) {
|
||||
static $GenreLookup = array(
|
||||
0 => 'Blues',
|
||||
1 => 'Classic Rock',
|
||||
2 => 'Country',
|
||||
3 => 'Dance',
|
||||
4 => 'Disco',
|
||||
5 => 'Funk',
|
||||
6 => 'Grunge',
|
||||
7 => 'Hip-Hop',
|
||||
8 => 'Jazz',
|
||||
9 => 'Metal',
|
||||
10 => 'New Age',
|
||||
11 => 'Oldies',
|
||||
12 => 'Other',
|
||||
13 => 'Pop',
|
||||
14 => 'R&B',
|
||||
15 => 'Rap',
|
||||
16 => 'Reggae',
|
||||
17 => 'Rock',
|
||||
18 => 'Techno',
|
||||
19 => 'Industrial',
|
||||
20 => 'Alternative',
|
||||
21 => 'Ska',
|
||||
22 => 'Death Metal',
|
||||
23 => 'Pranks',
|
||||
24 => 'Soundtrack',
|
||||
25 => 'Euro-Techno',
|
||||
26 => 'Ambient',
|
||||
27 => 'Trip-Hop',
|
||||
28 => 'Vocal',
|
||||
29 => 'Jazz+Funk',
|
||||
30 => 'Fusion',
|
||||
31 => 'Trance',
|
||||
32 => 'Classical',
|
||||
33 => 'Instrumental',
|
||||
34 => 'Acid',
|
||||
35 => 'House',
|
||||
36 => 'Game',
|
||||
37 => 'Sound Clip',
|
||||
38 => 'Gospel',
|
||||
39 => 'Noise',
|
||||
40 => 'Alt. Rock',
|
||||
41 => 'Bass',
|
||||
42 => 'Soul',
|
||||
43 => 'Punk',
|
||||
44 => 'Space',
|
||||
45 => 'Meditative',
|
||||
46 => 'Instrumental Pop',
|
||||
47 => 'Instrumental Rock',
|
||||
48 => 'Ethnic',
|
||||
49 => 'Gothic',
|
||||
50 => 'Darkwave',
|
||||
51 => 'Techno-Industrial',
|
||||
52 => 'Electronic',
|
||||
53 => 'Pop-Folk',
|
||||
54 => 'Eurodance',
|
||||
55 => 'Dream',
|
||||
56 => 'Southern Rock',
|
||||
57 => 'Comedy',
|
||||
58 => 'Cult',
|
||||
59 => 'Gangsta Rap',
|
||||
60 => 'Top 40',
|
||||
61 => 'Christian Rap',
|
||||
62 => 'Pop/Funk',
|
||||
63 => 'Jungle',
|
||||
64 => 'Native American',
|
||||
65 => 'Cabaret',
|
||||
66 => 'New Wave',
|
||||
67 => 'Psychedelic',
|
||||
68 => 'Rave',
|
||||
69 => 'Showtunes',
|
||||
70 => 'Trailer',
|
||||
71 => 'Lo-Fi',
|
||||
72 => 'Tribal',
|
||||
73 => 'Acid Punk',
|
||||
74 => 'Acid Jazz',
|
||||
75 => 'Polka',
|
||||
76 => 'Retro',
|
||||
77 => 'Musical',
|
||||
78 => 'Rock & Roll',
|
||||
79 => 'Hard Rock',
|
||||
80 => 'Folk',
|
||||
81 => 'Folk/Rock',
|
||||
82 => 'National Folk',
|
||||
83 => 'Swing',
|
||||
84 => 'Fast-Fusion',
|
||||
85 => 'Bebob',
|
||||
86 => 'Latin',
|
||||
87 => 'Revival',
|
||||
88 => 'Celtic',
|
||||
89 => 'Bluegrass',
|
||||
90 => 'Avantgarde',
|
||||
91 => 'Gothic Rock',
|
||||
92 => 'Progressive Rock',
|
||||
93 => 'Psychedelic Rock',
|
||||
94 => 'Symphonic Rock',
|
||||
95 => 'Slow Rock',
|
||||
96 => 'Big Band',
|
||||
97 => 'Chorus',
|
||||
98 => 'Easy Listening',
|
||||
99 => 'Acoustic',
|
||||
100 => 'Humour',
|
||||
101 => 'Speech',
|
||||
102 => 'Chanson',
|
||||
103 => 'Opera',
|
||||
104 => 'Chamber Music',
|
||||
105 => 'Sonata',
|
||||
106 => 'Symphony',
|
||||
107 => 'Booty Bass',
|
||||
108 => 'Primus',
|
||||
109 => 'Porn Groove',
|
||||
110 => 'Satire',
|
||||
111 => 'Slow Jam',
|
||||
112 => 'Club',
|
||||
113 => 'Tango',
|
||||
114 => 'Samba',
|
||||
115 => 'Folklore',
|
||||
116 => 'Ballad',
|
||||
117 => 'Power Ballad',
|
||||
118 => 'Rhythmic Soul',
|
||||
119 => 'Freestyle',
|
||||
120 => 'Duet',
|
||||
121 => 'Punk Rock',
|
||||
122 => 'Drum Solo',
|
||||
123 => 'A Cappella',
|
||||
124 => 'Euro-House',
|
||||
125 => 'Dance Hall',
|
||||
126 => 'Goa',
|
||||
127 => 'Drum & Bass',
|
||||
128 => 'Club-House',
|
||||
129 => 'Hardcore',
|
||||
130 => 'Terror',
|
||||
131 => 'Indie',
|
||||
132 => 'BritPop',
|
||||
133 => 'Negerpunk',
|
||||
134 => 'Polsk Punk',
|
||||
135 => 'Beat',
|
||||
136 => 'Christian Gangsta Rap',
|
||||
137 => 'Heavy Metal',
|
||||
138 => 'Black Metal',
|
||||
139 => 'Crossover',
|
||||
140 => 'Contemporary Christian',
|
||||
141 => 'Christian Rock',
|
||||
142 => 'Merengue',
|
||||
143 => 'Salsa',
|
||||
144 => 'Thrash Metal',
|
||||
145 => 'Anime',
|
||||
146 => 'JPop',
|
||||
147 => 'Synthpop',
|
||||
|
||||
255 => 'Unknown',
|
||||
|
||||
'CR' => 'Cover',
|
||||
'RX' => 'Remix'
|
||||
);
|
||||
|
||||
static $GenreLookupSCMPX = array();
|
||||
if ($allowSCMPXextended && empty($GenreLookupSCMPX)) {
|
||||
$GenreLookupSCMPX = $GenreLookup;
|
||||
// http://www.geocities.co.jp/SiliconValley-Oakland/3664/alittle.html#GenreExtended
|
||||
// Extended ID3v1 genres invented by SCMPX
|
||||
// Note that 255 "Japanese Anime" conflicts with standard "Unknown"
|
||||
$GenreLookupSCMPX[240] = 'Sacred';
|
||||
$GenreLookupSCMPX[241] = 'Northern Europe';
|
||||
$GenreLookupSCMPX[242] = 'Irish & Scottish';
|
||||
$GenreLookupSCMPX[243] = 'Scotland';
|
||||
$GenreLookupSCMPX[244] = 'Ethnic Europe';
|
||||
$GenreLookupSCMPX[245] = 'Enka';
|
||||
$GenreLookupSCMPX[246] = 'Children\'s Song';
|
||||
$GenreLookupSCMPX[247] = 'Japanese Sky';
|
||||
$GenreLookupSCMPX[248] = 'Japanese Heavy Rock';
|
||||
$GenreLookupSCMPX[249] = 'Japanese Doom Rock';
|
||||
$GenreLookupSCMPX[250] = 'Japanese J-POP';
|
||||
$GenreLookupSCMPX[251] = 'Japanese Seiyu';
|
||||
$GenreLookupSCMPX[252] = 'Japanese Ambient Techno';
|
||||
$GenreLookupSCMPX[253] = 'Japanese Moemoe';
|
||||
$GenreLookupSCMPX[254] = 'Japanese Tokusatsu';
|
||||
//$GenreLookupSCMPX[255] = 'Japanese Anime';
|
||||
}
|
||||
|
||||
return ($allowSCMPXextended ? $GenreLookupSCMPX : $GenreLookup);
|
||||
}
|
||||
|
||||
public static function LookupGenreName($genreid, $allowSCMPXextended=true) {
|
||||
switch ($genreid) {
|
||||
case 'RX':
|
||||
case 'CR':
|
||||
break;
|
||||
default:
|
||||
if (!is_numeric($genreid)) {
|
||||
return false;
|
||||
}
|
||||
$genreid = intval($genreid); // to handle 3 or '3' or '03'
|
||||
break;
|
||||
}
|
||||
$GenreLookup = self::ArrayOfGenres($allowSCMPXextended);
|
||||
return (isset($GenreLookup[$genreid]) ? $GenreLookup[$genreid] : false);
|
||||
}
|
||||
|
||||
public static function LookupGenreID($genre, $allowSCMPXextended=false) {
|
||||
$GenreLookup = self::ArrayOfGenres($allowSCMPXextended);
|
||||
$LowerCaseNoSpaceSearchTerm = strtolower(str_replace(' ', '', $genre));
|
||||
foreach ($GenreLookup as $key => $value) {
|
||||
if (strtolower(str_replace(' ', '', $value)) == $LowerCaseNoSpaceSearchTerm) {
|
||||
return $key;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function StandardiseID3v1GenreName($OriginalGenre) {
|
||||
if (($GenreID = self::LookupGenreID($OriginalGenre)) !== false) {
|
||||
return self::LookupGenreName($GenreID);
|
||||
}
|
||||
return $OriginalGenre;
|
||||
}
|
||||
|
||||
public static function GenerateID3v1Tag($title, $artist, $album, $year, $genreid, $comment, $track='') {
|
||||
$ID3v1Tag = 'TAG';
|
||||
$ID3v1Tag .= str_pad(trim(substr($title, 0, 30)), 30, "\x00", STR_PAD_RIGHT);
|
||||
$ID3v1Tag .= str_pad(trim(substr($artist, 0, 30)), 30, "\x00", STR_PAD_RIGHT);
|
||||
$ID3v1Tag .= str_pad(trim(substr($album, 0, 30)), 30, "\x00", STR_PAD_RIGHT);
|
||||
$ID3v1Tag .= str_pad(trim(substr($year, 0, 4)), 4, "\x00", STR_PAD_LEFT);
|
||||
if (!empty($track) && ($track > 0) && ($track <= 255)) {
|
||||
$ID3v1Tag .= str_pad(trim(substr($comment, 0, 28)), 28, "\x00", STR_PAD_RIGHT);
|
||||
$ID3v1Tag .= "\x00";
|
||||
if (gettype($track) == 'string') {
|
||||
$track = (int) $track;
|
||||
}
|
||||
$ID3v1Tag .= chr($track);
|
||||
} else {
|
||||
$ID3v1Tag .= str_pad(trim(substr($comment, 0, 30)), 30, "\x00", STR_PAD_RIGHT);
|
||||
}
|
||||
if (($genreid < 0) || ($genreid > 147)) {
|
||||
$genreid = 255; // 'unknown' genre
|
||||
}
|
||||
switch (gettype($genreid)) {
|
||||
case 'string':
|
||||
case 'integer':
|
||||
$ID3v1Tag .= chr(intval($genreid));
|
||||
break;
|
||||
default:
|
||||
$ID3v1Tag .= chr(255); // 'unknown' genre
|
||||
break;
|
||||
}
|
||||
|
||||
return $ID3v1Tag;
|
||||
}
|
||||
|
||||
}
|
||||
3627
Kapitel_7/Lektion_4/wordpress/wp-includes/ID3/module.tag.id3v2.php
Executable file
3627
Kapitel_7/Lektion_4/wordpress/wp-includes/ID3/module.tag.id3v2.php
Executable file
File diff suppressed because it is too large
Load Diff
298
Kapitel_7/Lektion_4/wordpress/wp-includes/ID3/module.tag.lyrics3.php
Executable file
298
Kapitel_7/Lektion_4/wordpress/wp-includes/ID3/module.tag.lyrics3.php
Executable file
@@ -0,0 +1,298 @@
|
||||
<?php
|
||||
/////////////////////////////////////////////////////////////////
|
||||
/// getID3() by James Heinrich <info@getid3.org> //
|
||||
// available at http://getid3.sourceforge.net //
|
||||
// or http://www.getid3.org //
|
||||
// also https://github.com/JamesHeinrich/getID3 //
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// See readme.txt for more details //
|
||||
/////////////////////////////////////////////////////////////////
|
||||
/// //
|
||||
// module.tag.lyrics3.php //
|
||||
// module for analyzing Lyrics3 tags //
|
||||
// dependencies: module.tag.apetag.php (optional) //
|
||||
// ///
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
class getid3_lyrics3 extends getid3_handler
|
||||
{
|
||||
|
||||
public function Analyze() {
|
||||
$info = &$this->getid3->info;
|
||||
|
||||
// http://www.volweb.cz/str/tags.htm
|
||||
|
||||
if (!getid3_lib::intValueSupported($info['filesize'])) {
|
||||
$info['warning'][] = 'Unable to check for Lyrics3 because file is larger than '.round(PHP_INT_MAX / 1073741824).'GB';
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->fseek((0 - 128 - 9 - 6), SEEK_END); // end - ID3v1 - "LYRICSEND" - [Lyrics3size]
|
||||
$lyrics3_id3v1 = $this->fread(128 + 9 + 6);
|
||||
$lyrics3lsz = substr($lyrics3_id3v1, 0, 6); // Lyrics3size
|
||||
$lyrics3end = substr($lyrics3_id3v1, 6, 9); // LYRICSEND or LYRICS200
|
||||
$id3v1tag = substr($lyrics3_id3v1, 15, 128); // ID3v1
|
||||
|
||||
if ($lyrics3end == 'LYRICSEND') {
|
||||
// Lyrics3v1, ID3v1, no APE
|
||||
|
||||
$lyrics3size = 5100;
|
||||
$lyrics3offset = $info['filesize'] - 128 - $lyrics3size;
|
||||
$lyrics3version = 1;
|
||||
|
||||
} elseif ($lyrics3end == 'LYRICS200') {
|
||||
// Lyrics3v2, ID3v1, no APE
|
||||
|
||||
// LSZ = lyrics + 'LYRICSBEGIN'; add 6-byte size field; add 'LYRICS200'
|
||||
$lyrics3size = $lyrics3lsz + 6 + strlen('LYRICS200');
|
||||
$lyrics3offset = $info['filesize'] - 128 - $lyrics3size;
|
||||
$lyrics3version = 2;
|
||||
|
||||
} elseif (substr(strrev($lyrics3_id3v1), 0, 9) == strrev('LYRICSEND')) {
|
||||
// Lyrics3v1, no ID3v1, no APE
|
||||
|
||||
$lyrics3size = 5100;
|
||||
$lyrics3offset = $info['filesize'] - $lyrics3size;
|
||||
$lyrics3version = 1;
|
||||
$lyrics3offset = $info['filesize'] - $lyrics3size;
|
||||
|
||||
} elseif (substr(strrev($lyrics3_id3v1), 0, 9) == strrev('LYRICS200')) {
|
||||
|
||||
// Lyrics3v2, no ID3v1, no APE
|
||||
|
||||
$lyrics3size = strrev(substr(strrev($lyrics3_id3v1), 9, 6)) + 6 + strlen('LYRICS200'); // LSZ = lyrics + 'LYRICSBEGIN'; add 6-byte size field; add 'LYRICS200'
|
||||
$lyrics3offset = $info['filesize'] - $lyrics3size;
|
||||
$lyrics3version = 2;
|
||||
|
||||
} else {
|
||||
|
||||
if (isset($info['ape']['tag_offset_start']) && ($info['ape']['tag_offset_start'] > 15)) {
|
||||
|
||||
$this->fseek($info['ape']['tag_offset_start'] - 15);
|
||||
$lyrics3lsz = $this->fread(6);
|
||||
$lyrics3end = $this->fread(9);
|
||||
|
||||
if ($lyrics3end == 'LYRICSEND') {
|
||||
// Lyrics3v1, APE, maybe ID3v1
|
||||
|
||||
$lyrics3size = 5100;
|
||||
$lyrics3offset = $info['ape']['tag_offset_start'] - $lyrics3size;
|
||||
$info['avdataend'] = $lyrics3offset;
|
||||
$lyrics3version = 1;
|
||||
$info['warning'][] = 'APE tag located after Lyrics3, will probably break Lyrics3 compatability';
|
||||
|
||||
} elseif ($lyrics3end == 'LYRICS200') {
|
||||
// Lyrics3v2, APE, maybe ID3v1
|
||||
|
||||
$lyrics3size = $lyrics3lsz + 6 + strlen('LYRICS200'); // LSZ = lyrics + 'LYRICSBEGIN'; add 6-byte size field; add 'LYRICS200'
|
||||
$lyrics3offset = $info['ape']['tag_offset_start'] - $lyrics3size;
|
||||
$lyrics3version = 2;
|
||||
$info['warning'][] = 'APE tag located after Lyrics3, will probably break Lyrics3 compatability';
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (isset($lyrics3offset)) {
|
||||
$info['avdataend'] = $lyrics3offset;
|
||||
$this->getLyrics3Data($lyrics3offset, $lyrics3version, $lyrics3size);
|
||||
|
||||
if (!isset($info['ape'])) {
|
||||
if (isset($info['lyrics3']['tag_offset_start'])) {
|
||||
$GETID3_ERRORARRAY = &$info['warning'];
|
||||
getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.tag.apetag.php', __FILE__, true);
|
||||
$getid3_temp = new getID3();
|
||||
$getid3_temp->openfile($this->getid3->filename);
|
||||
$getid3_apetag = new getid3_apetag($getid3_temp);
|
||||
$getid3_apetag->overrideendoffset = $info['lyrics3']['tag_offset_start'];
|
||||
$getid3_apetag->Analyze();
|
||||
if (!empty($getid3_temp->info['ape'])) {
|
||||
$info['ape'] = $getid3_temp->info['ape'];
|
||||
}
|
||||
if (!empty($getid3_temp->info['replay_gain'])) {
|
||||
$info['replay_gain'] = $getid3_temp->info['replay_gain'];
|
||||
}
|
||||
unset($getid3_temp, $getid3_apetag);
|
||||
} else {
|
||||
$info['warning'][] = 'Lyrics3 and APE tags appear to have become entangled (most likely due to updating the APE tags with a non-Lyrics3-aware tagger)';
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getLyrics3Data($endoffset, $version, $length) {
|
||||
// http://www.volweb.cz/str/tags.htm
|
||||
|
||||
$info = &$this->getid3->info;
|
||||
|
||||
if (!getid3_lib::intValueSupported($endoffset)) {
|
||||
$info['warning'][] = 'Unable to check for Lyrics3 because file is larger than '.round(PHP_INT_MAX / 1073741824).'GB';
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->fseek($endoffset);
|
||||
if ($length <= 0) {
|
||||
return false;
|
||||
}
|
||||
$rawdata = $this->fread($length);
|
||||
|
||||
$ParsedLyrics3['raw']['lyrics3version'] = $version;
|
||||
$ParsedLyrics3['raw']['lyrics3tagsize'] = $length;
|
||||
$ParsedLyrics3['tag_offset_start'] = $endoffset;
|
||||
$ParsedLyrics3['tag_offset_end'] = $endoffset + $length - 1;
|
||||
|
||||
if (substr($rawdata, 0, 11) != 'LYRICSBEGIN') {
|
||||
if (strpos($rawdata, 'LYRICSBEGIN') !== false) {
|
||||
|
||||
$info['warning'][] = '"LYRICSBEGIN" expected at '.$endoffset.' but actually found at '.($endoffset + strpos($rawdata, 'LYRICSBEGIN')).' - this is invalid for Lyrics3 v'.$version;
|
||||
$info['avdataend'] = $endoffset + strpos($rawdata, 'LYRICSBEGIN');
|
||||
$rawdata = substr($rawdata, strpos($rawdata, 'LYRICSBEGIN'));
|
||||
$length = strlen($rawdata);
|
||||
$ParsedLyrics3['tag_offset_start'] = $info['avdataend'];
|
||||
$ParsedLyrics3['raw']['lyrics3tagsize'] = $length;
|
||||
|
||||
} else {
|
||||
|
||||
$info['error'][] = '"LYRICSBEGIN" expected at '.$endoffset.' but found "'.substr($rawdata, 0, 11).'" instead';
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
switch ($version) {
|
||||
|
||||
case 1:
|
||||
if (substr($rawdata, strlen($rawdata) - 9, 9) == 'LYRICSEND') {
|
||||
$ParsedLyrics3['raw']['LYR'] = trim(substr($rawdata, 11, strlen($rawdata) - 11 - 9));
|
||||
$this->Lyrics3LyricsTimestampParse($ParsedLyrics3);
|
||||
} else {
|
||||
$info['error'][] = '"LYRICSEND" expected at '.($this->ftell() - 11 + $length - 9).' but found "'.substr($rawdata, strlen($rawdata) - 9, 9).'" instead';
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if (substr($rawdata, strlen($rawdata) - 9, 9) == 'LYRICS200') {
|
||||
$ParsedLyrics3['raw']['unparsed'] = substr($rawdata, 11, strlen($rawdata) - 11 - 9 - 6); // LYRICSBEGIN + LYRICS200 + LSZ
|
||||
$rawdata = $ParsedLyrics3['raw']['unparsed'];
|
||||
while (strlen($rawdata) > 0) {
|
||||
$fieldname = substr($rawdata, 0, 3);
|
||||
$fieldsize = (int) substr($rawdata, 3, 5);
|
||||
$ParsedLyrics3['raw'][$fieldname] = substr($rawdata, 8, $fieldsize);
|
||||
$rawdata = substr($rawdata, 3 + 5 + $fieldsize);
|
||||
}
|
||||
|
||||
if (isset($ParsedLyrics3['raw']['IND'])) {
|
||||
$i = 0;
|
||||
$flagnames = array('lyrics', 'timestamps', 'inhibitrandom');
|
||||
foreach ($flagnames as $flagname) {
|
||||
if (strlen($ParsedLyrics3['raw']['IND']) > $i++) {
|
||||
$ParsedLyrics3['flags'][$flagname] = $this->IntString2Bool(substr($ParsedLyrics3['raw']['IND'], $i, 1 - 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$fieldnametranslation = array('ETT'=>'title', 'EAR'=>'artist', 'EAL'=>'album', 'INF'=>'comment', 'AUT'=>'author');
|
||||
foreach ($fieldnametranslation as $key => $value) {
|
||||
if (isset($ParsedLyrics3['raw'][$key])) {
|
||||
$ParsedLyrics3['comments'][$value][] = trim($ParsedLyrics3['raw'][$key]);
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($ParsedLyrics3['raw']['IMG'])) {
|
||||
$imagestrings = explode("\r\n", $ParsedLyrics3['raw']['IMG']);
|
||||
foreach ($imagestrings as $key => $imagestring) {
|
||||
if (strpos($imagestring, '||') !== false) {
|
||||
$imagearray = explode('||', $imagestring);
|
||||
$ParsedLyrics3['images'][$key]['filename'] = (isset($imagearray[0]) ? $imagearray[0] : '');
|
||||
$ParsedLyrics3['images'][$key]['description'] = (isset($imagearray[1]) ? $imagearray[1] : '');
|
||||
$ParsedLyrics3['images'][$key]['timestamp'] = $this->Lyrics3Timestamp2Seconds(isset($imagearray[2]) ? $imagearray[2] : '');
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isset($ParsedLyrics3['raw']['LYR'])) {
|
||||
$this->Lyrics3LyricsTimestampParse($ParsedLyrics3);
|
||||
}
|
||||
} else {
|
||||
$info['error'][] = '"LYRICS200" expected at '.($this->ftell() - 11 + $length - 9).' but found "'.substr($rawdata, strlen($rawdata) - 9, 9).'" instead';
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
$info['error'][] = 'Cannot process Lyrics3 version '.$version.' (only v1 and v2)';
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (isset($info['id3v1']['tag_offset_start']) && ($info['id3v1']['tag_offset_start'] <= $ParsedLyrics3['tag_offset_end'])) {
|
||||
$info['warning'][] = 'ID3v1 tag information ignored since it appears to be a false synch in Lyrics3 tag data';
|
||||
unset($info['id3v1']);
|
||||
foreach ($info['warning'] as $key => $value) {
|
||||
if ($value == 'Some ID3v1 fields do not use NULL characters for padding') {
|
||||
unset($info['warning'][$key]);
|
||||
sort($info['warning']);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$info['lyrics3'] = $ParsedLyrics3;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function Lyrics3Timestamp2Seconds($rawtimestamp) {
|
||||
if (preg_match('#^\\[([0-9]{2}):([0-9]{2})\\]$#', $rawtimestamp, $regs)) {
|
||||
return (int) (($regs[1] * 60) + $regs[2]);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function Lyrics3LyricsTimestampParse(&$Lyrics3data) {
|
||||
$lyricsarray = explode("\r\n", $Lyrics3data['raw']['LYR']);
|
||||
foreach ($lyricsarray as $key => $lyricline) {
|
||||
$regs = array();
|
||||
unset($thislinetimestamps);
|
||||
while (preg_match('#^(\\[[0-9]{2}:[0-9]{2}\\])#', $lyricline, $regs)) {
|
||||
$thislinetimestamps[] = $this->Lyrics3Timestamp2Seconds($regs[0]);
|
||||
$lyricline = str_replace($regs[0], '', $lyricline);
|
||||
}
|
||||
$notimestamplyricsarray[$key] = $lyricline;
|
||||
if (isset($thislinetimestamps) && is_array($thislinetimestamps)) {
|
||||
sort($thislinetimestamps);
|
||||
foreach ($thislinetimestamps as $timestampkey => $timestamp) {
|
||||
if (isset($Lyrics3data['synchedlyrics'][$timestamp])) {
|
||||
// timestamps only have a 1-second resolution, it's possible that multiple lines
|
||||
// could have the same timestamp, if so, append
|
||||
$Lyrics3data['synchedlyrics'][$timestamp] .= "\r\n".$lyricline;
|
||||
} else {
|
||||
$Lyrics3data['synchedlyrics'][$timestamp] = $lyricline;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$Lyrics3data['unsynchedlyrics'] = implode("\r\n", $notimestamplyricsarray);
|
||||
if (isset($Lyrics3data['synchedlyrics']) && is_array($Lyrics3data['synchedlyrics'])) {
|
||||
ksort($Lyrics3data['synchedlyrics']);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function IntString2Bool($char) {
|
||||
if ($char == '1') {
|
||||
return true;
|
||||
} elseif ($char == '0') {
|
||||
return false;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
604
Kapitel_7/Lektion_4/wordpress/wp-includes/ID3/readme.txt
Executable file
604
Kapitel_7/Lektion_4/wordpress/wp-includes/ID3/readme.txt
Executable file
@@ -0,0 +1,604 @@
|
||||
/////////////////////////////////////////////////////////////////
|
||||
/// getID3() by James Heinrich <info@getid3.org> //
|
||||
// available at http://getid3.sourceforge.net //
|
||||
// or http://www.getid3.org //
|
||||
// also https://github.com/JamesHeinrich/getID3 //
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
*****************************************************************
|
||||
*****************************************************************
|
||||
|
||||
getID3() is released under multiple licenses. You may choose
|
||||
from the following licenses, and use getID3 according to the
|
||||
terms of the license most suitable to your project.
|
||||
|
||||
GNU GPL: https://gnu.org/licenses/gpl.html (v3)
|
||||
https://gnu.org/licenses/old-licenses/gpl-2.0.html (v2)
|
||||
https://gnu.org/licenses/old-licenses/gpl-1.0.html (v1)
|
||||
|
||||
GNU LGPL: https://gnu.org/licenses/lgpl.html (v3)
|
||||
|
||||
Mozilla MPL: http://www.mozilla.org/MPL/2.0/ (v2)
|
||||
|
||||
getID3 Commercial License: http://getid3.org/#gCL (payment required)
|
||||
|
||||
*****************************************************************
|
||||
*****************************************************************
|
||||
Copies of each of the above licenses are included in the 'licenses'
|
||||
directory of the getID3 distribution.
|
||||
|
||||
|
||||
+---------------------------------------------+
|
||||
| If you want to donate, there is a link on |
|
||||
| http://www.getid3.org for PayPal donations. |
|
||||
+---------------------------------------------+
|
||||
|
||||
|
||||
Quick Start
|
||||
===========================================================================
|
||||
|
||||
Q: How can I check that getID3() works on my server/files?
|
||||
A: Unzip getID3() to a directory, then access /demos/demo.browse.php
|
||||
|
||||
|
||||
|
||||
Support
|
||||
===========================================================================
|
||||
|
||||
Q: I have a question, or I found a bug. What do I do?
|
||||
A: The preferred method of support requests and/or bug reports is the
|
||||
forum at http://support.getid3.org/
|
||||
|
||||
|
||||
|
||||
Sourceforge Notification
|
||||
===========================================================================
|
||||
|
||||
It's highly recommended that you sign up for notification from
|
||||
Sourceforge for when new versions are released. Please visit:
|
||||
http://sourceforge.net/project/showfiles.php?group_id=55859
|
||||
and click the little "monitor package" icon/link. If you're
|
||||
previously signed up for the mailing list, be aware that it has
|
||||
been discontinued, only the automated Sourceforge notification
|
||||
will be used from now on.
|
||||
|
||||
|
||||
|
||||
What does getID3() do?
|
||||
===========================================================================
|
||||
|
||||
Reads & parses (to varying degrees):
|
||||
¤ tags:
|
||||
* APE (v1 and v2)
|
||||
* ID3v1 (& ID3v1.1)
|
||||
* ID3v2 (v2.4, v2.3, v2.2)
|
||||
* Lyrics3 (v1 & v2)
|
||||
|
||||
¤ audio-lossy:
|
||||
* MP3/MP2/MP1
|
||||
* MPC / Musepack
|
||||
* Ogg (Vorbis, OggFLAC, Speex)
|
||||
* AAC / MP4
|
||||
* AC3
|
||||
* DTS
|
||||
* RealAudio
|
||||
* Speex
|
||||
* DSS
|
||||
* VQF
|
||||
|
||||
¤ audio-lossless:
|
||||
* AIFF
|
||||
* AU
|
||||
* Bonk
|
||||
* CD-audio (*.cda)
|
||||
* FLAC
|
||||
* LA (Lossless Audio)
|
||||
* LiteWave
|
||||
* LPAC
|
||||
* MIDI
|
||||
* Monkey's Audio
|
||||
* OptimFROG
|
||||
* RKAU
|
||||
* Shorten
|
||||
* TTA
|
||||
* VOC
|
||||
* WAV (RIFF)
|
||||
* WavPack
|
||||
|
||||
¤ audio-video:
|
||||
* ASF: ASF, Windows Media Audio (WMA), Windows Media Video (WMV)
|
||||
* AVI (RIFF)
|
||||
* Flash
|
||||
* Matroska (MKV)
|
||||
* MPEG-1 / MPEG-2
|
||||
* NSV (Nullsoft Streaming Video)
|
||||
* Quicktime (including MP4)
|
||||
* RealVideo
|
||||
|
||||
¤ still image:
|
||||
* BMP
|
||||
* GIF
|
||||
* JPEG
|
||||
* PNG
|
||||
* TIFF
|
||||
* SWF (Flash)
|
||||
* PhotoCD
|
||||
|
||||
¤ data:
|
||||
* ISO-9660 CD-ROM image (directory structure)
|
||||
* SZIP (limited support)
|
||||
* ZIP (directory structure)
|
||||
* TAR
|
||||
* CUE
|
||||
|
||||
|
||||
Writes:
|
||||
* ID3v1 (& ID3v1.1)
|
||||
* ID3v2 (v2.3 & v2.4)
|
||||
* VorbisComment on OggVorbis
|
||||
* VorbisComment on FLAC (not OggFLAC)
|
||||
* APE v2
|
||||
* Lyrics3 (delete only)
|
||||
|
||||
|
||||
|
||||
Requirements
|
||||
===========================================================================
|
||||
|
||||
* PHP 4.2.0 up to 5.2.x for getID3() 1.7.x (and earlier)
|
||||
* PHP 5.0.5 (or higher) for getID3() 1.8.x (and up)
|
||||
* PHP 5.0.5 (or higher) for getID3() 2.0.x (and up)
|
||||
* at least 4MB memory for PHP. 8MB or more is highly recommended.
|
||||
12MB is required with all modules loaded.
|
||||
|
||||
|
||||
|
||||
Usage
|
||||
===========================================================================
|
||||
|
||||
See /demos/demo.basic.php for a very basic use of getID3() with no
|
||||
fancy output, just scanning one file.
|
||||
|
||||
See structure.txt for the returned data structure.
|
||||
|
||||
*> For an example of a complete directory-browsing, <*
|
||||
*> file-scanning implementation of getID3(), please run <*
|
||||
*> /demos/demo.browse.php <*
|
||||
|
||||
See /demos/demo.mysql.php for a sample recursive scanning code that
|
||||
scans every file in a given directory, and all sub-directories, stores
|
||||
the results in a database and allows various analysis / maintenance
|
||||
operations
|
||||
|
||||
To analyze remote files over HTTP or FTP you need to copy the file
|
||||
locally first before running getID3(). Your code would look something
|
||||
like this:
|
||||
|
||||
// Copy remote file locally to scan with getID3()
|
||||
$remotefilename = 'http://www.example.com/filename.mp3';
|
||||
if ($fp_remote = fopen($remotefilename, 'rb')) {
|
||||
$localtempfilename = tempnam('/tmp', 'getID3');
|
||||
if ($fp_local = fopen($localtempfilename, 'wb')) {
|
||||
while ($buffer = fread($fp_remote, 8192)) {
|
||||
fwrite($fp_local, $buffer);
|
||||
}
|
||||
fclose($fp_local);
|
||||
|
||||
// Initialize getID3 engine
|
||||
$getID3 = new getID3;
|
||||
|
||||
$ThisFileInfo = $getID3->analyze($filename);
|
||||
|
||||
// Delete temporary file
|
||||
unlink($localtempfilename);
|
||||
}
|
||||
fclose($fp_remote);
|
||||
}
|
||||
|
||||
|
||||
See /demos/demo.write.php for how to write tags.
|
||||
|
||||
|
||||
|
||||
What does the returned data structure look like?
|
||||
===========================================================================
|
||||
|
||||
See structure.txt
|
||||
|
||||
It is recommended that you look at the output of
|
||||
/demos/demo.browse.php scanning the file(s) you're interested in to
|
||||
confirm what data is actually returned for any particular filetype in
|
||||
general, and your files in particular, as the actual data returned
|
||||
may vary considerably depending on what information is available in
|
||||
the file itself.
|
||||
|
||||
|
||||
|
||||
Notes
|
||||
===========================================================================
|
||||
|
||||
getID3() 1.x:
|
||||
If the format parser encounters a critical problem, it will return
|
||||
something in $fileinfo['error'], describing the encountered error. If
|
||||
a less critical error or notice is generated it will appear in
|
||||
$fileinfo['warning']. Both keys may contain more than one warning or
|
||||
error. If something is returned in ['error'] then the file was not
|
||||
correctly parsed and returned data may or may not be correct and/or
|
||||
complete. If something is returned in ['warning'] (and not ['error'])
|
||||
then the data that is returned is OK - usually getID3() is reporting
|
||||
errors in the file that have been worked around due to known bugs in
|
||||
other programs. Some warnings may indicate that the data that is
|
||||
returned is OK but that some data could not be extracted due to
|
||||
errors in the file.
|
||||
|
||||
getID3() 2.x:
|
||||
See above except errors are thrown (so you will only get one error).
|
||||
|
||||
|
||||
|
||||
Disclaimer
|
||||
===========================================================================
|
||||
|
||||
getID3() has been tested on many systems, on many types of files,
|
||||
under many operating systems, and is generally believe to be stable
|
||||
and safe. That being said, there is still the chance there is an
|
||||
undiscovered and/or unfixed bug that may potentially corrupt your
|
||||
file, especially within the writing functions. By using getID3() you
|
||||
agree that it's not my fault if any of your files are corrupted.
|
||||
In fact, I'm not liable for anything :)
|
||||
|
||||
|
||||
|
||||
License
|
||||
===========================================================================
|
||||
|
||||
GNU General Public License - see license.txt
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to:
|
||||
Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA.
|
||||
|
||||
FAQ:
|
||||
Q: Can I use getID3() in my program? Do I need a commercial license?
|
||||
A: You're generally free to use getID3 however you see fit. The only
|
||||
case in which you would require a commercial license is if you're
|
||||
selling your closed-source program that integrates getID3. If you
|
||||
sell your program including a copy of getID3, that's fine as long
|
||||
as you include a copy of the sourcecode when you sell it. Or you
|
||||
can distribute your code without getID3 and say "download it from
|
||||
getid3.sourceforge.net"
|
||||
|
||||
|
||||
|
||||
Why is it called "getID3()" if it does so much more than just that?
|
||||
===========================================================================
|
||||
|
||||
v0.1 did in fact just do that. I don't have a copy of code that old, but I
|
||||
could essentially write it today with a one-line function:
|
||||
function getID3($filename) { return unpack('a3TAG/a30title/a30artist/a30album/a4year/a28comment/c1track/c1genreid', substr(file_get_contents($filename), -128)); }
|
||||
|
||||
|
||||
Future Plans
|
||||
===========================================================================
|
||||
http://www.getid3.org/phpBB3/viewforum.php?f=7
|
||||
|
||||
* Better support for MP4 container format
|
||||
* Scan for appended ID3v2 tag at end of file per ID3v2.4 specs (Section 5.0)
|
||||
* Support for JPEG-2000 (http://www.morgan-multimedia.com/jpeg2000_overview.htm)
|
||||
* Support for MOD (mod/stm/s3m/it/xm/mtm/ult/669)
|
||||
* Support for ACE (thanks Vince)
|
||||
* Support for Ogg other than Vorbis, Speex and OggFlac (ie. Ogg+Xvid)
|
||||
* Ability to create Xing/LAME VBR header for VBR MP3s that are missing VBR header
|
||||
* Ability to "clean" ID3v2 padding (replace invalid padding with valid padding)
|
||||
* Warn if MP3s change version mid-stream (in full-scan mode)
|
||||
* check for corrupt/broken mid-file MP3 streams in histogram scan
|
||||
* Support for lossless-compression formats
|
||||
(http://www.firstpr.com.au/audiocomp/lossless/#Links)
|
||||
(http://compression.ca/act-sound.html)
|
||||
(http://web.inter.nl.net/users/hvdh/lossless/lossless.htm)
|
||||
* Support for RIFF-INFO chunks
|
||||
* http://lotto.st-andrews.ac.uk/~njh/tag_interchange.html
|
||||
(thanks Nick Humfrey <njhØsurgeradio*co*uk>)
|
||||
* http://abcavi.narod.ru/sof/abcavi/infotags.htm
|
||||
(thanks Kibi)
|
||||
* Better support for Bink video
|
||||
* http://www.hr/josip/DSP/AudioFile2.html
|
||||
* http://www.pcisys.net/~melanson/codecs/
|
||||
* Detect mp3PRO
|
||||
* Support for PSD
|
||||
* Support for JPC
|
||||
* Support for JP2
|
||||
* Support for JPX
|
||||
* Support for JB2
|
||||
* Support for IFF
|
||||
* Support for ICO
|
||||
* Support for ANI
|
||||
* Support for EXE (comments, author, etc) (thanks p*quaedackersØplanet*nl)
|
||||
* Support for DVD-IFO (region, subtitles, aspect ratio, etc)
|
||||
(thanks p*quaedackersØplanet*nl)
|
||||
* More complete support for SWF - parsing encapsulated MP3 and/or JPEG content
|
||||
(thanks n8n8Øyahoo*com)
|
||||
* Support for a2b
|
||||
* Optional scan-through-frames for AVI verification
|
||||
(thanks rockcohenØmassive-interactive*nl)
|
||||
* Support for TTF (thanks infoØbutterflyx*com)
|
||||
* Support for DSS (http://www.getid3.org/phpBB3/viewtopic.php?t=171)
|
||||
* Support for SMAF (http://smaf-yamaha.com/what/demo.html)
|
||||
http://www.getid3.org/phpBB3/viewtopic.php?t=182
|
||||
* Support for AMR (http://www.getid3.org/phpBB3/viewtopic.php?t=195)
|
||||
* Support for 3gpp (http://www.getid3.org/phpBB3/viewtopic.php?t=195)
|
||||
* Support for ID4 (http://www.wackysoft.cjb.net grizlyY2KØhotmail*com)
|
||||
* Parse XML data returned in Ogg comments
|
||||
* Parse XML data from Quicktime SMIL metafiles (klausrathØmac*com)
|
||||
* ID3v2 genre string creator function
|
||||
* More complete parsing of JPG
|
||||
* Support for all old-style ASF packets
|
||||
* ASF/WMA/WMV tag writing
|
||||
* Parse declared T??? ID3v2 text information frames, where appropriate
|
||||
(thanks Christian Fritz for the idea)
|
||||
* Recognize encoder:
|
||||
http://www.guerillasoft.com/EncSpot2/index.html
|
||||
http://ff123.net/identify.html
|
||||
http://www.hydrogenaudio.org/?act=ST&f=16&t=9414
|
||||
http://www.hydrogenaudio.org/?showtopic=11785
|
||||
* Support for other OS/2 bitmap structures: Bitmap Array('BA'),
|
||||
Color Icon('CI'), Color Pointer('CP'), Icon('IC'), Pointer ('PT')
|
||||
http://netghost.narod.ru/gff/graphics/summary/os2bmp.htm
|
||||
* Support for WavPack RAW mode
|
||||
* ASF/WMA/WMV data packet parsing
|
||||
* ID3v2FrameFlagsLookupTagAlter()
|
||||
* ID3v2FrameFlagsLookupFileAlter()
|
||||
* obey ID3v2 tag alter/preserve/discard rules
|
||||
* http://www.geocities.com/SiliconValley/Sector/9654/Softdoc/Illyrium/Aolyr.htm
|
||||
* proper checking for LINK/LNK frame validity in ID3v2 writing
|
||||
* proper checking for ASPI-TLEN frame validity in ID3v2 writing
|
||||
* proper checking for COMR frame validity in ID3v2 writing
|
||||
* http://www.geocities.co.jp/SiliconValley-Oakland/3664/index.html
|
||||
* decode GEOB ID3v2 structure as encoded by RealJukebox,
|
||||
decode NCON ID3v2 structure as encoded by MusicMatch
|
||||
(probably won't happen - the formats are proprietary)
|
||||
|
||||
|
||||
|
||||
Known Bugs/Issues in getID3() that may be fixed eventually
|
||||
===========================================================================
|
||||
http://www.getid3.org/phpBB3/viewtopic.php?t=25
|
||||
|
||||
* Cannot determine bitrate for MPEG video with VBR video data
|
||||
(need documentation)
|
||||
* Interlace/progressive cannot be determined for MPEG video
|
||||
(need documentation)
|
||||
* MIDI playtime is sometimes inaccurate
|
||||
* AAC-RAW mode files cannot be identified
|
||||
* WavPack-RAW mode files cannot be identified
|
||||
* mp4 files report lots of "Unknown QuickTime atom type"
|
||||
(need documentation)
|
||||
* Encrypted ASF/WMA/WMV files warn about "unhandled GUID
|
||||
ASF_Content_Encryption_Object"
|
||||
* Bitrate split between audio and video cannot be calculated for
|
||||
NSV, only the total bitrate. (need documentation)
|
||||
* All Ogg formats (Vorbis, OggFLAC, Speex) are affected by the
|
||||
problem of large VorbisComments spanning multiple Ogg pages, but
|
||||
but only OggVorbis files can be processed with vorbiscomment.
|
||||
* The version of "head" supplied with Mac OS 10.2.8 (maybe other
|
||||
versions too) does only understands a single option (-n) and
|
||||
therefore fails. getID3 ignores this and returns wrong md5_data.
|
||||
|
||||
|
||||
|
||||
Known Bugs/Issues in getID3() that cannot be fixed
|
||||
--------------------------------------------------
|
||||
http://www.getid3.org/phpBB3/viewtopic.php?t=25
|
||||
|
||||
* 32-bit PHP installations only:
|
||||
Files larger than 2GB cannot always be parsed fully by getID3()
|
||||
due to limitations in the 32-bit PHP filesystem functions.
|
||||
NOTE: Since v1.7.8b3 there is partial support for larger-than-
|
||||
2GB files, most of which will parse OK, as long as no critical
|
||||
data is located beyond the 2GB offset.
|
||||
Known will-work:
|
||||
* all file formats on 64-bit PHP
|
||||
* ZIP (format doesn't support files >2GB)
|
||||
* FLAC (current encoders don't support files >2GB)
|
||||
Known will-not-work:
|
||||
* ID3v1 tags (always located at end-of-file)
|
||||
* Lyrics3 tags (always located at end-of-file)
|
||||
* APE tags (always located at end-of-file)
|
||||
Maybe-will-work:
|
||||
* Quicktime (will work if needed metadata is before 2GB offset,
|
||||
that is if the file has been hinted/optimized for streaming)
|
||||
* RIFF.WAV (should work fine, but gives warnings about not being
|
||||
able to parse all chunks)
|
||||
* RIFF.AVI (playtime will probably be wrong, is only based on
|
||||
"movi" chunk that fits in the first 2GB, should issue error
|
||||
to show that playtime is incorrect. Other data should be mostly
|
||||
correct, assuming that data is constant throughout the file)
|
||||
* PHP <= v5 on Windows cannot read UTF-8 filenames
|
||||
|
||||
|
||||
Known Bugs/Issues in other programs
|
||||
-----------------------------------
|
||||
http://www.getid3.org/phpBB3/viewtopic.php?t=25
|
||||
|
||||
* Windows Media Player (up to v11) and iTunes (up to v10+) do
|
||||
not correctly handle ID3v2.3 tags with UTF-16BE+BOM
|
||||
encoding (they assume the data is UTF-16LE+BOM and either
|
||||
crash (WMP) or output Asian character set (iTunes)
|
||||
* Winamp (up to v2.80 at least) does not support ID3v2.4 tags,
|
||||
only ID3v2.3
|
||||
see: http://forums.winamp.com/showthread.php?postid=387524
|
||||
* Some versions of Helium2 (www.helium2.com) do not write
|
||||
ID3v2.4-compliant Frame Sizes, even though the tag is marked
|
||||
as ID3v2.4) (detected by getID3())
|
||||
* MP3ext V3.3.17 places a non-compliant padding string at the end
|
||||
of the ID3v2 header. This is supposedly fixed in v3.4b21 but
|
||||
only if you manually add a registry key. This fix is not yet
|
||||
confirmed. (detected by getID3())
|
||||
* CDex v1.40 (fixed by v1.50b7) writes non-compliant Ogg comment
|
||||
strings, supposed to be in the format "NAME=value" but actually
|
||||
written just "value" (detected by getID3())
|
||||
* Oggenc 0.9-rc3 flags the encoded file as ABR whether it's
|
||||
actually ABR or VBR.
|
||||
* iTunes (versions "X v2.0.3", "v3.0.1" are known-guilty, probably
|
||||
other versions are too) writes ID3v2.3 comment tags using a
|
||||
frame name 'COM ' which is not valid for ID3v2.3+ (it's an
|
||||
ID3v2.2-style frame name) (detected by getID3())
|
||||
* MP2enc does not encode mono CBR MP2 files properly (half speed
|
||||
sound and double playtime)
|
||||
* MP2enc does not encode mono VBR MP2 files properly (actually
|
||||
encoded as stereo)
|
||||
* tooLAME does not encode mono VBR MP2 files properly (actually
|
||||
encoded as stereo)
|
||||
* AACenc encodes files in VBR mode (actually ABR) even if CBR is
|
||||
specified
|
||||
* AAC/ADIF - bitrate_mode = cbr for vbr files
|
||||
* LAME 3.90-3.92 prepends one frame of null data (space for the
|
||||
LAME/VBR header, but it never gets written) when encoding in CBR
|
||||
mode with the DLL
|
||||
* Ahead Nero encodes TwinVQF with a DSIZ value (which is supposed
|
||||
to be the filesize in bytes) of "0" for TwinVQF v1.0 and "1" for
|
||||
TwinVQF v2.0 (detected by getID3())
|
||||
* Ahead Nero encodes TwinVQF files 1 second shorter than they
|
||||
should be
|
||||
* AAC-ADTS files are always actually encoded VBR, even if CBR mode
|
||||
is specified (the CBR-mode switches on the encoder enable ABR
|
||||
mode, not CBR as such, but it's not possible to tell the
|
||||
difference between such ABR files and true VBR)
|
||||
* STREAMINFO.audio_signature in OggFLAC is always null. "The reason
|
||||
it's like that is because there is no seeking support in
|
||||
libOggFLAC yet, so it has no way to go back and write the
|
||||
computed sum after encoding. Seeking support in Ogg FLAC is the
|
||||
#1 item for the next release." - Josh Coalson (FLAC developer)
|
||||
NOTE: getID3() will calculate md5_data in a method similar to
|
||||
other file formats, but that value cannot be compared to the
|
||||
md5_data value from FLAC data in a FLAC file format.
|
||||
* STREAMINFO.audio_signature is not calculated in FLAC v0.3.0 &
|
||||
v0.4.0 - getID3() will calculate md5_data in a method similar to
|
||||
other file formats, but that value cannot be compared to the
|
||||
md5_data value from FLAC v0.5.0+
|
||||
* RioPort (various versions including 2.0 and 3.11) tags ID3v2 with
|
||||
a WCOM frame that has no data portion
|
||||
* Earlier versions of Coolplayer adds illegal ID3 tags to Ogg Vorbis
|
||||
files, thus making them corrupt.
|
||||
* Meracl ID3 Tag Writer v1.3.4 (and older) incorrectly truncates the
|
||||
last byte of data from an MP3 file when appending a new ID3v1 tag.
|
||||
(detected by getID3())
|
||||
* Lossless-Audio files encoded with and without the -noseek switch
|
||||
do actually differ internally and therefore cannot match md5_data
|
||||
* iTunes has been known to append a new ID3v1 tag on the end of an
|
||||
existing ID3v1 tag when ID3v2 tag is also present
|
||||
(detected by getID3())
|
||||
* MediaMonkey may write a blank RGAD ID3v2 frame but put actual
|
||||
replay gain adjustments in a series of user-defined TXXX frames
|
||||
(detected and handled by getID3() since v1.9.2)
|
||||
|
||||
|
||||
|
||||
|
||||
Reference material:
|
||||
===========================================================================
|
||||
|
||||
[www.id3.org material now mirrored at http://id3lib.sourceforge.net/id3/]
|
||||
* http://www.id3.org/id3v2.4.0-structure.txt
|
||||
* http://www.id3.org/id3v2.4.0-frames.txt
|
||||
* http://www.id3.org/id3v2.4.0-changes.txt
|
||||
* http://www.id3.org/id3v2.3.0.txt
|
||||
* http://www.id3.org/id3v2-00.txt
|
||||
* http://www.id3.org/mp3frame.html
|
||||
* http://minnie.tuhs.org/pipermail/mp3encoder/2001-January/001800.html <mathewhendry@hotmail.com>
|
||||
* http://www.dv.co.yu/mpgscript/mpeghdr.htm
|
||||
* http://www.mp3-tech.org/programmer/frame_header.html
|
||||
* http://users.belgacom.net/gc247244/extra/tag.html
|
||||
* http://gabriel.mp3-tech.org/mp3infotag.html
|
||||
* http://www.id3.org/iso4217.html
|
||||
* http://www.unicode.org/Public/MAPPINGS/ISO8859/8859-1.TXT
|
||||
* http://www.xiph.org/ogg/vorbis/doc/framing.html
|
||||
* http://www.xiph.org/ogg/vorbis/doc/v-comment.html
|
||||
* http://leknor.com/code/php/class.ogg.php.txt
|
||||
* http://www.id3.org/iso639-2.html
|
||||
* http://www.id3.org/lyrics3.html
|
||||
* http://www.id3.org/lyrics3200.html
|
||||
* http://www.psc.edu/general/software/packages/ieee/ieee.html
|
||||
* http://www.scri.fsu.edu/~jac/MAD3401/Backgrnd/ieee-expl.html
|
||||
* http://www.scri.fsu.edu/~jac/MAD3401/Backgrnd/binary.html
|
||||
* http://www.jmcgowan.com/avi.html
|
||||
* http://www.wotsit.org/
|
||||
* http://www.herdsoft.com/ti/davincie/davp3xo2.htm
|
||||
* http://www.mathdogs.com/vorbis-illuminated/bitstream-appendix.html
|
||||
* "Standard MIDI File Format" by Dustin Caldwell (from www.wotsit.org)
|
||||
* http://midistudio.com/Help/GMSpecs_Patches.htm
|
||||
* http://www.xiph.org/archives/vorbis/200109/0459.html
|
||||
* http://www.replaygain.org/
|
||||
* http://www.lossless-audio.com/
|
||||
* http://download.microsoft.com/download/winmediatech40/Doc/1.0/WIN98MeXP/EN-US/ASF_Specification_v.1.0.exe
|
||||
* http://mediaxw.sourceforge.net/files/doc/Active%20Streaming%20Format%20(ASF)%201.0%20Specification.pdf
|
||||
* http://www.uni-jena.de/~pfk/mpp/sv8/ (archived at http://www.hydrogenaudio.org/musepack/klemm/www.personal.uni-jena.de/~pfk/mpp/sv8/)
|
||||
* http://jfaul.de/atl/
|
||||
* http://www.uni-jena.de/~pfk/mpp/ (archived at http://www.hydrogenaudio.org/musepack/klemm/www.personal.uni-jena.de/~pfk/mpp/)
|
||||
* http://www.libpng.org/pub/png/spec/png-1.2-pdg.html
|
||||
* http://www.real.com/devzone/library/creating/rmsdk/doc/rmff.htm
|
||||
* http://www.fastgraph.com/help/bmp_os2_header_format.html
|
||||
* http://netghost.narod.ru/gff/graphics/summary/os2bmp.htm
|
||||
* http://flac.sourceforge.net/format.html
|
||||
* http://www.research.att.com/projects/mpegaudio/mpeg2.html
|
||||
* http://www.audiocoding.com/wiki/index.php?page=AAC
|
||||
* http://libmpeg.org/mpeg4/doc/w2203tfs.pdf
|
||||
* http://www.geocities.com/xhelmboyx/quicktime/formats/qtm-layout.txt
|
||||
* http://developer.apple.com/techpubs/quicktime/qtdevdocs/RM/frameset.htm
|
||||
* http://www.nullsoft.com/nsv/
|
||||
* http://www.wotsit.org/download.asp?f=iso9660
|
||||
* http://sandbox.mc.edu/~bennet/cs110/tc/tctod.html
|
||||
* http://www.cdroller.com/htm/readdata.html
|
||||
* http://www.speex.org/manual/node10.html
|
||||
* http://www.harmony-central.com/Computer/Programming/aiff-file-format.doc
|
||||
* http://www.faqs.org/rfcs/rfc2361.html
|
||||
* http://ghido.shelter.ro/
|
||||
* http://www.ebu.ch/tech_t3285.pdf
|
||||
* http://www.sr.se/utveckling/tu/bwf
|
||||
* http://ftp.aessc.org/pub/aes46-2002.pdf
|
||||
* http://cartchunk.org:8080/
|
||||
* http://www.broadcastpapers.com/radio/cartchunk01.htm
|
||||
* http://www.hr/josip/DSP/AudioFile2.html
|
||||
* http://home.attbi.com/~chris.bagwell/AudioFormats-11.html
|
||||
* http://www.pure-mac.com/extkey.html
|
||||
* http://cesnet.dl.sourceforge.net/sourceforge/bonkenc/bonk-binary-format-0.9.txt
|
||||
* http://www.headbands.com/gspot/
|
||||
* http://www.openswf.org/spec/SWFfileformat.html
|
||||
* http://j-faul.virtualave.net/
|
||||
* http://www.btinternet.com/~AnthonyJ/Atari/programming/avr_format.html
|
||||
* http://cui.unige.ch/OSG/info/AudioFormats/ap11.html
|
||||
* http://sswf.sourceforge.net/SWFalexref.html
|
||||
* http://www.geocities.com/xhelmboyx/quicktime/formats/qti-layout.txt
|
||||
* http://www-lehre.informatik.uni-osnabrueck.de/~fbstark/diplom/docs/swf/Flash_Uncovered.htm
|
||||
* http://developer.apple.com/quicktime/icefloe/dispatch012.html
|
||||
* http://www.csdn.net/Dev/Format/graphics/PCD.htm
|
||||
* http://tta.iszf.irk.ru/
|
||||
* http://www.atsc.org/standards/a_52a.pdf
|
||||
* http://www.alanwood.net/unicode/
|
||||
* http://www.freelists.org/archives/matroska-devel/07-2003/msg00010.html
|
||||
* http://www.its.msstate.edu/net/real/reports/config/tags.stats
|
||||
* http://homepages.slingshot.co.nz/~helmboy/quicktime/formats/qtm-layout.txt
|
||||
* http://brennan.young.net/Comp/LiveStage/things.html
|
||||
* http://www.multiweb.cz/twoinches/MP3inside.htm
|
||||
* http://www.geocities.co.jp/SiliconValley-Oakland/3664/alittle.html#GenreExtended
|
||||
* http://www.mactech.com/articles/mactech/Vol.06/06.01/SANENormalized/
|
||||
* http://www.unicode.org/unicode/faq/utf_bom.html
|
||||
* http://tta.corecodec.org/?menu=format
|
||||
* http://www.scvi.net/nsvformat.htm
|
||||
* http://pda.etsi.org/pda/queryform.asp
|
||||
* http://cpansearch.perl.org/src/RGIBSON/Audio-DSS-0.02/lib/Audio/DSS.pm
|
||||
* http://trac.musepack.net/trac/wiki/SV8Specification
|
||||
* http://wyday.com/cuesharp/specification.php
|
||||
* http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Nikon.html
|
||||
157
Kapitel_7/Lektion_4/wordpress/wp-includes/SimplePie/Author.php
Executable file
157
Kapitel_7/Lektion_4/wordpress/wp-includes/SimplePie/Author.php
Executable file
@@ -0,0 +1,157 @@
|
||||
<?php
|
||||
/**
|
||||
* SimplePie
|
||||
*
|
||||
* A PHP-Based RSS and Atom Feed Framework.
|
||||
* Takes the hard work out of managing a complete RSS/Atom solution.
|
||||
*
|
||||
* Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* * Neither the name of the SimplePie Team nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDERS
|
||||
* AND 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.
|
||||
*
|
||||
* @package SimplePie
|
||||
* @version 1.3.1
|
||||
* @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
|
||||
* @author Ryan Parman
|
||||
* @author Geoffrey Sneddon
|
||||
* @author Ryan McCue
|
||||
* @link http://simplepie.org/ SimplePie
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
||||
*/
|
||||
|
||||
/**
|
||||
* Manages all author-related data
|
||||
*
|
||||
* Used by {@see SimplePie_Item::get_author()} and {@see SimplePie::get_authors()}
|
||||
*
|
||||
* This class can be overloaded with {@see SimplePie::set_author_class()}
|
||||
*
|
||||
* @package SimplePie
|
||||
* @subpackage API
|
||||
*/
|
||||
class SimplePie_Author
|
||||
{
|
||||
/**
|
||||
* Author's name
|
||||
*
|
||||
* @var string
|
||||
* @see get_name()
|
||||
*/
|
||||
var $name;
|
||||
|
||||
/**
|
||||
* Author's link
|
||||
*
|
||||
* @var string
|
||||
* @see get_link()
|
||||
*/
|
||||
var $link;
|
||||
|
||||
/**
|
||||
* Author's email address
|
||||
*
|
||||
* @var string
|
||||
* @see get_email()
|
||||
*/
|
||||
var $email;
|
||||
|
||||
/**
|
||||
* Constructor, used to input the data
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $link
|
||||
* @param string $email
|
||||
*/
|
||||
public function __construct($name = null, $link = null, $email = null)
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->link = $link;
|
||||
$this->email = $email;
|
||||
}
|
||||
|
||||
/**
|
||||
* String-ified version
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
// There is no $this->data here
|
||||
return md5(serialize($this));
|
||||
}
|
||||
|
||||
/**
|
||||
* Author's name
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function get_name()
|
||||
{
|
||||
if ($this->name !== null)
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Author's link
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function get_link()
|
||||
{
|
||||
if ($this->link !== null)
|
||||
{
|
||||
return $this->link;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Author's email address
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function get_email()
|
||||
{
|
||||
if ($this->email !== null)
|
||||
{
|
||||
return $this->email;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
133
Kapitel_7/Lektion_4/wordpress/wp-includes/SimplePie/Cache.php
Executable file
133
Kapitel_7/Lektion_4/wordpress/wp-includes/SimplePie/Cache.php
Executable file
@@ -0,0 +1,133 @@
|
||||
<?php
|
||||
/**
|
||||
* SimplePie
|
||||
*
|
||||
* A PHP-Based RSS and Atom Feed Framework.
|
||||
* Takes the hard work out of managing a complete RSS/Atom solution.
|
||||
*
|
||||
* Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* * Neither the name of the SimplePie Team nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDERS
|
||||
* AND 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.
|
||||
*
|
||||
* @package SimplePie
|
||||
* @version 1.3.1
|
||||
* @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
|
||||
* @author Ryan Parman
|
||||
* @author Geoffrey Sneddon
|
||||
* @author Ryan McCue
|
||||
* @link http://simplepie.org/ SimplePie
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
||||
*/
|
||||
|
||||
/**
|
||||
* Used to create cache objects
|
||||
*
|
||||
* This class can be overloaded with {@see SimplePie::set_cache_class()},
|
||||
* although the preferred way is to create your own handler
|
||||
* via {@see register()}
|
||||
*
|
||||
* @package SimplePie
|
||||
* @subpackage Caching
|
||||
*/
|
||||
class SimplePie_Cache
|
||||
{
|
||||
/**
|
||||
* Cache handler classes
|
||||
*
|
||||
* These receive 3 parameters to their constructor, as documented in
|
||||
* {@see register()}
|
||||
* @var array
|
||||
*/
|
||||
protected static $handlers = array(
|
||||
'mysql' => 'SimplePie_Cache_MySQL',
|
||||
'memcache' => 'SimplePie_Cache_Memcache',
|
||||
);
|
||||
|
||||
/**
|
||||
* Don't call the constructor. Please.
|
||||
*/
|
||||
private function __construct() { }
|
||||
|
||||
/**
|
||||
* Create a new SimplePie_Cache object
|
||||
*
|
||||
* @param string $location URL location (scheme is used to determine handler)
|
||||
* @param string $filename Unique identifier for cache object
|
||||
* @param string $extension 'spi' or 'spc'
|
||||
* @return SimplePie_Cache_Base Type of object depends on scheme of `$location`
|
||||
*/
|
||||
public static function get_handler($location, $filename, $extension)
|
||||
{
|
||||
$type = explode(':', $location, 2);
|
||||
$type = $type[0];
|
||||
if (!empty(self::$handlers[$type]))
|
||||
{
|
||||
$class = self::$handlers[$type];
|
||||
return new $class($location, $filename, $extension);
|
||||
}
|
||||
|
||||
return new SimplePie_Cache_File($location, $filename, $extension);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new SimplePie_Cache object
|
||||
*
|
||||
* @deprecated Use {@see get_handler} instead
|
||||
*/
|
||||
public function create($location, $filename, $extension)
|
||||
{
|
||||
trigger_error('Cache::create() has been replaced with Cache::get_handler(). Switch to the registry system to use this.', E_USER_DEPRECATED);
|
||||
return self::get_handler($location, $filename, $extension);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a handler
|
||||
*
|
||||
* @param string $type DSN type to register for
|
||||
* @param string $class Name of handler class. Must implement SimplePie_Cache_Base
|
||||
*/
|
||||
public static function register($type, $class)
|
||||
{
|
||||
self::$handlers[$type] = $class;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a URL into an array
|
||||
*
|
||||
* @param string $url
|
||||
* @return array
|
||||
*/
|
||||
public static function parse_URL($url)
|
||||
{
|
||||
$params = parse_url($url);
|
||||
$params['extras'] = array();
|
||||
if (isset($params['query']))
|
||||
{
|
||||
parse_str($params['query'], $params['extras']);
|
||||
}
|
||||
return $params;
|
||||
}
|
||||
}
|
||||
114
Kapitel_7/Lektion_4/wordpress/wp-includes/SimplePie/Cache/Base.php
Executable file
114
Kapitel_7/Lektion_4/wordpress/wp-includes/SimplePie/Cache/Base.php
Executable file
@@ -0,0 +1,114 @@
|
||||
<?php
|
||||
/**
|
||||
* SimplePie
|
||||
*
|
||||
* A PHP-Based RSS and Atom Feed Framework.
|
||||
* Takes the hard work out of managing a complete RSS/Atom solution.
|
||||
*
|
||||
* Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* * Neither the name of the SimplePie Team nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDERS
|
||||
* AND 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.
|
||||
*
|
||||
* @package SimplePie
|
||||
* @version 1.3.1
|
||||
* @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
|
||||
* @author Ryan Parman
|
||||
* @author Geoffrey Sneddon
|
||||
* @author Ryan McCue
|
||||
* @link http://simplepie.org/ SimplePie
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
||||
*/
|
||||
|
||||
/**
|
||||
* Base for cache objects
|
||||
*
|
||||
* Classes to be used with {@see SimplePie_Cache::register()} are expected
|
||||
* to implement this interface.
|
||||
*
|
||||
* @package SimplePie
|
||||
* @subpackage Caching
|
||||
*/
|
||||
interface SimplePie_Cache_Base
|
||||
{
|
||||
/**
|
||||
* Feed cache type
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const TYPE_FEED = 'spc';
|
||||
|
||||
/**
|
||||
* Image cache type
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const TYPE_IMAGE = 'spi';
|
||||
|
||||
/**
|
||||
* Create a new cache object
|
||||
*
|
||||
* @param string $location Location string (from SimplePie::$cache_location)
|
||||
* @param string $name Unique ID for the cache
|
||||
* @param string $type Either TYPE_FEED for SimplePie data, or TYPE_IMAGE for image data
|
||||
*/
|
||||
public function __construct($location, $name, $type);
|
||||
|
||||
/**
|
||||
* Save data to the cache
|
||||
*
|
||||
* @param array|SimplePie $data Data to store in the cache. If passed a SimplePie object, only cache the $data property
|
||||
* @return bool Successfulness
|
||||
*/
|
||||
public function save($data);
|
||||
|
||||
/**
|
||||
* Retrieve the data saved to the cache
|
||||
*
|
||||
* @return array Data for SimplePie::$data
|
||||
*/
|
||||
public function load();
|
||||
|
||||
/**
|
||||
* Retrieve the last modified time for the cache
|
||||
*
|
||||
* @return int Timestamp
|
||||
*/
|
||||
public function mtime();
|
||||
|
||||
/**
|
||||
* Set the last modified time to the current time
|
||||
*
|
||||
* @return bool Success status
|
||||
*/
|
||||
public function touch();
|
||||
|
||||
/**
|
||||
* Remove the cache
|
||||
*
|
||||
* @return bool Success status
|
||||
*/
|
||||
public function unlink();
|
||||
}
|
||||
137
Kapitel_7/Lektion_4/wordpress/wp-includes/SimplePie/Cache/DB.php
Executable file
137
Kapitel_7/Lektion_4/wordpress/wp-includes/SimplePie/Cache/DB.php
Executable file
@@ -0,0 +1,137 @@
|
||||
<?php
|
||||
/**
|
||||
* SimplePie
|
||||
*
|
||||
* A PHP-Based RSS and Atom Feed Framework.
|
||||
* Takes the hard work out of managing a complete RSS/Atom solution.
|
||||
*
|
||||
* Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* * Neither the name of the SimplePie Team nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDERS
|
||||
* AND 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.
|
||||
*
|
||||
* @package SimplePie
|
||||
* @version 1.3.1
|
||||
* @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
|
||||
* @author Ryan Parman
|
||||
* @author Geoffrey Sneddon
|
||||
* @author Ryan McCue
|
||||
* @link http://simplepie.org/ SimplePie
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
||||
*/
|
||||
|
||||
/**
|
||||
* Base class for database-based caches
|
||||
*
|
||||
* @package SimplePie
|
||||
* @subpackage Caching
|
||||
*/
|
||||
abstract class SimplePie_Cache_DB implements SimplePie_Cache_Base
|
||||
{
|
||||
/**
|
||||
* Helper for database conversion
|
||||
*
|
||||
* Converts a given {@see SimplePie} object into data to be stored
|
||||
*
|
||||
* @param SimplePie $data
|
||||
* @return array First item is the serialized data for storage, second item is the unique ID for this item
|
||||
*/
|
||||
protected static function prepare_simplepie_object_for_cache($data)
|
||||
{
|
||||
$items = $data->get_items();
|
||||
$items_by_id = array();
|
||||
|
||||
if (!empty($items))
|
||||
{
|
||||
foreach ($items as $item)
|
||||
{
|
||||
$items_by_id[$item->get_id()] = $item;
|
||||
}
|
||||
|
||||
if (count($items_by_id) !== count($items))
|
||||
{
|
||||
$items_by_id = array();
|
||||
foreach ($items as $item)
|
||||
{
|
||||
$items_by_id[$item->get_id(true)] = $item;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($data->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]))
|
||||
{
|
||||
$channel =& $data->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0];
|
||||
}
|
||||
elseif (isset($data->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]))
|
||||
{
|
||||
$channel =& $data->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0];
|
||||
}
|
||||
elseif (isset($data->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]))
|
||||
{
|
||||
$channel =& $data->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0];
|
||||
}
|
||||
elseif (isset($data->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['channel'][0]))
|
||||
{
|
||||
$channel =& $data->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['channel'][0];
|
||||
}
|
||||
else
|
||||
{
|
||||
$channel = null;
|
||||
}
|
||||
|
||||
if ($channel !== null)
|
||||
{
|
||||
if (isset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['entry']))
|
||||
{
|
||||
unset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['entry']);
|
||||
}
|
||||
if (isset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['entry']))
|
||||
{
|
||||
unset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['entry']);
|
||||
}
|
||||
if (isset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item']))
|
||||
{
|
||||
unset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item']);
|
||||
}
|
||||
if (isset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item']))
|
||||
{
|
||||
unset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item']);
|
||||
}
|
||||
if (isset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_20]['item']))
|
||||
{
|
||||
unset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_20]['item']);
|
||||
}
|
||||
}
|
||||
if (isset($data->data['items']))
|
||||
{
|
||||
unset($data->data['items']);
|
||||
}
|
||||
if (isset($data->data['ordered_items']))
|
||||
{
|
||||
unset($data->data['ordered_items']);
|
||||
}
|
||||
}
|
||||
return array(serialize($data->data), $items_by_id);
|
||||
}
|
||||
}
|
||||
173
Kapitel_7/Lektion_4/wordpress/wp-includes/SimplePie/Cache/File.php
Executable file
173
Kapitel_7/Lektion_4/wordpress/wp-includes/SimplePie/Cache/File.php
Executable file
@@ -0,0 +1,173 @@
|
||||
<?php
|
||||
/**
|
||||
* SimplePie
|
||||
*
|
||||
* A PHP-Based RSS and Atom Feed Framework.
|
||||
* Takes the hard work out of managing a complete RSS/Atom solution.
|
||||
*
|
||||
* Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* * Neither the name of the SimplePie Team nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDERS
|
||||
* AND 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.
|
||||
*
|
||||
* @package SimplePie
|
||||
* @version 1.3.1
|
||||
* @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
|
||||
* @author Ryan Parman
|
||||
* @author Geoffrey Sneddon
|
||||
* @author Ryan McCue
|
||||
* @link http://simplepie.org/ SimplePie
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
||||
*/
|
||||
|
||||
/**
|
||||
* Caches data to the filesystem
|
||||
*
|
||||
* @package SimplePie
|
||||
* @subpackage Caching
|
||||
*/
|
||||
class SimplePie_Cache_File implements SimplePie_Cache_Base
|
||||
{
|
||||
/**
|
||||
* Location string
|
||||
*
|
||||
* @see SimplePie::$cache_location
|
||||
* @var string
|
||||
*/
|
||||
protected $location;
|
||||
|
||||
/**
|
||||
* Filename
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $filename;
|
||||
|
||||
/**
|
||||
* File extension
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $extension;
|
||||
|
||||
/**
|
||||
* File path
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $name;
|
||||
|
||||
/**
|
||||
* Create a new cache object
|
||||
*
|
||||
* @param string $location Location string (from SimplePie::$cache_location)
|
||||
* @param string $name Unique ID for the cache
|
||||
* @param string $type Either TYPE_FEED for SimplePie data, or TYPE_IMAGE for image data
|
||||
*/
|
||||
public function __construct($location, $name, $type)
|
||||
{
|
||||
$this->location = $location;
|
||||
$this->filename = $name;
|
||||
$this->extension = $type;
|
||||
$this->name = "$this->location/$this->filename.$this->extension";
|
||||
}
|
||||
|
||||
/**
|
||||
* Save data to the cache
|
||||
*
|
||||
* @param array|SimplePie $data Data to store in the cache. If passed a SimplePie object, only cache the $data property
|
||||
* @return bool Successfulness
|
||||
*/
|
||||
public function save($data)
|
||||
{
|
||||
if (file_exists($this->name) && is_writeable($this->name) || file_exists($this->location) && is_writeable($this->location))
|
||||
{
|
||||
if ($data instanceof SimplePie)
|
||||
{
|
||||
$data = $data->data;
|
||||
}
|
||||
|
||||
$data = serialize($data);
|
||||
return (bool) file_put_contents($this->name, $data);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the data saved to the cache
|
||||
*
|
||||
* @return array Data for SimplePie::$data
|
||||
*/
|
||||
public function load()
|
||||
{
|
||||
if (file_exists($this->name) && is_readable($this->name))
|
||||
{
|
||||
return unserialize(file_get_contents($this->name));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the last modified time for the cache
|
||||
*
|
||||
* @return int Timestamp
|
||||
*/
|
||||
public function mtime()
|
||||
{
|
||||
if (file_exists($this->name))
|
||||
{
|
||||
return filemtime($this->name);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the last modified time to the current time
|
||||
*
|
||||
* @return bool Success status
|
||||
*/
|
||||
public function touch()
|
||||
{
|
||||
if (file_exists($this->name))
|
||||
{
|
||||
return touch($this->name);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the cache
|
||||
*
|
||||
* @return bool Success status
|
||||
*/
|
||||
public function unlink()
|
||||
{
|
||||
if (file_exists($this->name))
|
||||
{
|
||||
return unlink($this->name);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
183
Kapitel_7/Lektion_4/wordpress/wp-includes/SimplePie/Cache/Memcache.php
Executable file
183
Kapitel_7/Lektion_4/wordpress/wp-includes/SimplePie/Cache/Memcache.php
Executable file
@@ -0,0 +1,183 @@
|
||||
<?php
|
||||
/**
|
||||
* SimplePie
|
||||
*
|
||||
* A PHP-Based RSS and Atom Feed Framework.
|
||||
* Takes the hard work out of managing a complete RSS/Atom solution.
|
||||
*
|
||||
* Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* * Neither the name of the SimplePie Team nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDERS
|
||||
* AND 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.
|
||||
*
|
||||
* @package SimplePie
|
||||
* @version 1.3.1
|
||||
* @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
|
||||
* @author Ryan Parman
|
||||
* @author Geoffrey Sneddon
|
||||
* @author Ryan McCue
|
||||
* @link http://simplepie.org/ SimplePie
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
||||
*/
|
||||
|
||||
/**
|
||||
* Caches data to memcache
|
||||
*
|
||||
* Registered for URLs with the "memcache" protocol
|
||||
*
|
||||
* For example, `memcache://localhost:11211/?timeout=3600&prefix=sp_` will
|
||||
* connect to memcache on `localhost` on port 11211. All tables will be
|
||||
* prefixed with `sp_` and data will expire after 3600 seconds
|
||||
*
|
||||
* @package SimplePie
|
||||
* @subpackage Caching
|
||||
* @uses Memcache
|
||||
*/
|
||||
class SimplePie_Cache_Memcache implements SimplePie_Cache_Base
|
||||
{
|
||||
/**
|
||||
* Memcache instance
|
||||
*
|
||||
* @var Memcache
|
||||
*/
|
||||
protected $cache;
|
||||
|
||||
/**
|
||||
* Options
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $options;
|
||||
|
||||
/**
|
||||
* Cache name
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $name;
|
||||
|
||||
/**
|
||||
* Create a new cache object
|
||||
*
|
||||
* @param string $location Location string (from SimplePie::$cache_location)
|
||||
* @param string $name Unique ID for the cache
|
||||
* @param string $type Either TYPE_FEED for SimplePie data, or TYPE_IMAGE for image data
|
||||
*/
|
||||
public function __construct($location, $name, $type)
|
||||
{
|
||||
$this->options = array(
|
||||
'host' => '127.0.0.1',
|
||||
'port' => 11211,
|
||||
'extras' => array(
|
||||
'timeout' => 3600, // one hour
|
||||
'prefix' => 'simplepie_',
|
||||
),
|
||||
);
|
||||
$parsed = SimplePie_Cache::parse_URL($location);
|
||||
$this->options['host'] = empty($parsed['host']) ? $this->options['host'] : $parsed['host'];
|
||||
$this->options['port'] = empty($parsed['port']) ? $this->options['port'] : $parsed['port'];
|
||||
$this->options['extras'] = array_merge($this->options['extras'], $parsed['extras']);
|
||||
$this->name = $this->options['extras']['prefix'] . md5("$name:$type");
|
||||
|
||||
$this->cache = new Memcache();
|
||||
$this->cache->addServer($this->options['host'], (int) $this->options['port']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save data to the cache
|
||||
*
|
||||
* @param array|SimplePie $data Data to store in the cache. If passed a SimplePie object, only cache the $data property
|
||||
* @return bool Successfulness
|
||||
*/
|
||||
public function save($data)
|
||||
{
|
||||
if ($data instanceof SimplePie)
|
||||
{
|
||||
$data = $data->data;
|
||||
}
|
||||
return $this->cache->set($this->name, serialize($data), MEMCACHE_COMPRESSED, (int) $this->options['extras']['timeout']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the data saved to the cache
|
||||
*
|
||||
* @return array Data for SimplePie::$data
|
||||
*/
|
||||
public function load()
|
||||
{
|
||||
$data = $this->cache->get($this->name);
|
||||
|
||||
if ($data !== false)
|
||||
{
|
||||
return unserialize($data);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the last modified time for the cache
|
||||
*
|
||||
* @return int Timestamp
|
||||
*/
|
||||
public function mtime()
|
||||
{
|
||||
$data = $this->cache->get($this->name);
|
||||
|
||||
if ($data !== false)
|
||||
{
|
||||
// essentially ignore the mtime because Memcache expires on it's own
|
||||
return time();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the last modified time to the current time
|
||||
*
|
||||
* @return bool Success status
|
||||
*/
|
||||
public function touch()
|
||||
{
|
||||
$data = $this->cache->get($this->name);
|
||||
|
||||
if ($data !== false)
|
||||
{
|
||||
return $this->cache->set($this->name, $data, MEMCACHE_COMPRESSED, (int) $this->duration);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the cache
|
||||
*
|
||||
* @return bool Success status
|
||||
*/
|
||||
public function unlink()
|
||||
{
|
||||
return $this->cache->delete($this->name, 0);
|
||||
}
|
||||
}
|
||||
438
Kapitel_7/Lektion_4/wordpress/wp-includes/SimplePie/Cache/MySQL.php
Executable file
438
Kapitel_7/Lektion_4/wordpress/wp-includes/SimplePie/Cache/MySQL.php
Executable file
@@ -0,0 +1,438 @@
|
||||
<?php
|
||||
/**
|
||||
* SimplePie
|
||||
*
|
||||
* A PHP-Based RSS and Atom Feed Framework.
|
||||
* Takes the hard work out of managing a complete RSS/Atom solution.
|
||||
*
|
||||
* Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* * Neither the name of the SimplePie Team nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDERS
|
||||
* AND 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.
|
||||
*
|
||||
* @package SimplePie
|
||||
* @version 1.3.1
|
||||
* @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
|
||||
* @author Ryan Parman
|
||||
* @author Geoffrey Sneddon
|
||||
* @author Ryan McCue
|
||||
* @link http://simplepie.org/ SimplePie
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
||||
*/
|
||||
|
||||
/**
|
||||
* Caches data to a MySQL database
|
||||
*
|
||||
* Registered for URLs with the "mysql" protocol
|
||||
*
|
||||
* For example, `mysql://root:password@localhost:3306/mydb?prefix=sp_` will
|
||||
* connect to the `mydb` database on `localhost` on port 3306, with the user
|
||||
* `root` and the password `password`. All tables will be prefixed with `sp_`
|
||||
*
|
||||
* @package SimplePie
|
||||
* @subpackage Caching
|
||||
*/
|
||||
class SimplePie_Cache_MySQL extends SimplePie_Cache_DB
|
||||
{
|
||||
/**
|
||||
* PDO instance
|
||||
*
|
||||
* @var PDO
|
||||
*/
|
||||
protected $mysql;
|
||||
|
||||
/**
|
||||
* Options
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $options;
|
||||
|
||||
/**
|
||||
* Cache ID
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $id;
|
||||
|
||||
/**
|
||||
* Create a new cache object
|
||||
*
|
||||
* @param string $location Location string (from SimplePie::$cache_location)
|
||||
* @param string $name Unique ID for the cache
|
||||
* @param string $type Either TYPE_FEED for SimplePie data, or TYPE_IMAGE for image data
|
||||
*/
|
||||
public function __construct($location, $name, $type)
|
||||
{
|
||||
$this->options = array(
|
||||
'user' => null,
|
||||
'pass' => null,
|
||||
'host' => '127.0.0.1',
|
||||
'port' => '3306',
|
||||
'path' => '',
|
||||
'extras' => array(
|
||||
'prefix' => '',
|
||||
),
|
||||
);
|
||||
$this->options = array_merge_recursive($this->options, SimplePie_Cache::parse_URL($location));
|
||||
|
||||
// Path is prefixed with a "/"
|
||||
$this->options['dbname'] = substr($this->options['path'], 1);
|
||||
|
||||
try
|
||||
{
|
||||
$this->mysql = new PDO("mysql:dbname={$this->options['dbname']};host={$this->options['host']};port={$this->options['port']}", $this->options['user'], $this->options['pass'], array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'));
|
||||
}
|
||||
catch (PDOException $e)
|
||||
{
|
||||
$this->mysql = null;
|
||||
return;
|
||||
}
|
||||
|
||||
$this->id = $name . $type;
|
||||
|
||||
if (!$query = $this->mysql->query('SHOW TABLES'))
|
||||
{
|
||||
$this->mysql = null;
|
||||
return;
|
||||
}
|
||||
|
||||
$db = array();
|
||||
while ($row = $query->fetchColumn())
|
||||
{
|
||||
$db[] = $row;
|
||||
}
|
||||
|
||||
if (!in_array($this->options['extras']['prefix'] . 'cache_data', $db))
|
||||
{
|
||||
$query = $this->mysql->exec('CREATE TABLE `' . $this->options['extras']['prefix'] . 'cache_data` (`id` TEXT CHARACTER SET utf8 NOT NULL, `items` SMALLINT NOT NULL DEFAULT 0, `data` BLOB NOT NULL, `mtime` INT UNSIGNED NOT NULL, UNIQUE (`id`(125)))');
|
||||
if ($query === false)
|
||||
{
|
||||
$this->mysql = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (!in_array($this->options['extras']['prefix'] . 'items', $db))
|
||||
{
|
||||
$query = $this->mysql->exec('CREATE TABLE `' . $this->options['extras']['prefix'] . 'items` (`feed_id` TEXT CHARACTER SET utf8 NOT NULL, `id` TEXT CHARACTER SET utf8 NOT NULL, `data` TEXT CHARACTER SET utf8 NOT NULL, `posted` INT UNSIGNED NOT NULL, INDEX `feed_id` (`feed_id`(125)))');
|
||||
if ($query === false)
|
||||
{
|
||||
$this->mysql = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save data to the cache
|
||||
*
|
||||
* @param array|SimplePie $data Data to store in the cache. If passed a SimplePie object, only cache the $data property
|
||||
* @return bool Successfulness
|
||||
*/
|
||||
public function save($data)
|
||||
{
|
||||
if ($this->mysql === null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($data instanceof SimplePie)
|
||||
{
|
||||
$data = clone $data;
|
||||
|
||||
$prepared = self::prepare_simplepie_object_for_cache($data);
|
||||
|
||||
$query = $this->mysql->prepare('SELECT COUNT(*) FROM `' . $this->options['extras']['prefix'] . 'cache_data` WHERE `id` = :feed');
|
||||
$query->bindValue(':feed', $this->id);
|
||||
if ($query->execute())
|
||||
{
|
||||
if ($query->fetchColumn() > 0)
|
||||
{
|
||||
$items = count($prepared[1]);
|
||||
if ($items)
|
||||
{
|
||||
$sql = 'UPDATE `' . $this->options['extras']['prefix'] . 'cache_data` SET `items` = :items, `data` = :data, `mtime` = :time WHERE `id` = :feed';
|
||||
$query = $this->mysql->prepare($sql);
|
||||
$query->bindValue(':items', $items);
|
||||
}
|
||||
else
|
||||
{
|
||||
$sql = 'UPDATE `' . $this->options['extras']['prefix'] . 'cache_data` SET `data` = :data, `mtime` = :time WHERE `id` = :feed';
|
||||
$query = $this->mysql->prepare($sql);
|
||||
}
|
||||
|
||||
$query->bindValue(':data', $prepared[0]);
|
||||
$query->bindValue(':time', time());
|
||||
$query->bindValue(':feed', $this->id);
|
||||
if (!$query->execute())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$query = $this->mysql->prepare('INSERT INTO `' . $this->options['extras']['prefix'] . 'cache_data` (`id`, `items`, `data`, `mtime`) VALUES(:feed, :count, :data, :time)');
|
||||
$query->bindValue(':feed', $this->id);
|
||||
$query->bindValue(':count', count($prepared[1]));
|
||||
$query->bindValue(':data', $prepared[0]);
|
||||
$query->bindValue(':time', time());
|
||||
if (!$query->execute())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
$ids = array_keys($prepared[1]);
|
||||
if (!empty($ids))
|
||||
{
|
||||
foreach ($ids as $id)
|
||||
{
|
||||
$database_ids[] = $this->mysql->quote($id);
|
||||
}
|
||||
|
||||
$query = $this->mysql->prepare('SELECT `id` FROM `' . $this->options['extras']['prefix'] . 'items` WHERE `id` = ' . implode(' OR `id` = ', $database_ids) . ' AND `feed_id` = :feed');
|
||||
$query->bindValue(':feed', $this->id);
|
||||
|
||||
if ($query->execute())
|
||||
{
|
||||
$existing_ids = array();
|
||||
while ($row = $query->fetchColumn())
|
||||
{
|
||||
$existing_ids[] = $row;
|
||||
}
|
||||
|
||||
$new_ids = array_diff($ids, $existing_ids);
|
||||
|
||||
foreach ($new_ids as $new_id)
|
||||
{
|
||||
if (!($date = $prepared[1][$new_id]->get_date('U')))
|
||||
{
|
||||
$date = time();
|
||||
}
|
||||
|
||||
$query = $this->mysql->prepare('INSERT INTO `' . $this->options['extras']['prefix'] . 'items` (`feed_id`, `id`, `data`, `posted`) VALUES(:feed, :id, :data, :date)');
|
||||
$query->bindValue(':feed', $this->id);
|
||||
$query->bindValue(':id', $new_id);
|
||||
$query->bindValue(':data', serialize($prepared[1][$new_id]->data));
|
||||
$query->bindValue(':date', $date);
|
||||
if (!$query->execute())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$query = $this->mysql->prepare('SELECT `id` FROM `' . $this->options['extras']['prefix'] . 'cache_data` WHERE `id` = :feed');
|
||||
$query->bindValue(':feed', $this->id);
|
||||
if ($query->execute())
|
||||
{
|
||||
if ($query->rowCount() > 0)
|
||||
{
|
||||
$query = $this->mysql->prepare('UPDATE `' . $this->options['extras']['prefix'] . 'cache_data` SET `items` = 0, `data` = :data, `mtime` = :time WHERE `id` = :feed');
|
||||
$query->bindValue(':data', serialize($data));
|
||||
$query->bindValue(':time', time());
|
||||
$query->bindValue(':feed', $this->id);
|
||||
if ($this->execute())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$query = $this->mysql->prepare('INSERT INTO `' . $this->options['extras']['prefix'] . 'cache_data` (`id`, `items`, `data`, `mtime`) VALUES(:id, 0, :data, :time)');
|
||||
$query->bindValue(':id', $this->id);
|
||||
$query->bindValue(':data', serialize($data));
|
||||
$query->bindValue(':time', time());
|
||||
if ($query->execute())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the data saved to the cache
|
||||
*
|
||||
* @return array Data for SimplePie::$data
|
||||
*/
|
||||
public function load()
|
||||
{
|
||||
if ($this->mysql === null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$query = $this->mysql->prepare('SELECT `items`, `data` FROM `' . $this->options['extras']['prefix'] . 'cache_data` WHERE `id` = :id');
|
||||
$query->bindValue(':id', $this->id);
|
||||
if ($query->execute() && ($row = $query->fetch()))
|
||||
{
|
||||
$data = unserialize($row[1]);
|
||||
|
||||
if (isset($this->options['items'][0]))
|
||||
{
|
||||
$items = (int) $this->options['items'][0];
|
||||
}
|
||||
else
|
||||
{
|
||||
$items = (int) $row[0];
|
||||
}
|
||||
|
||||
if ($items !== 0)
|
||||
{
|
||||
if (isset($data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]))
|
||||
{
|
||||
$feed =& $data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0];
|
||||
}
|
||||
elseif (isset($data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]))
|
||||
{
|
||||
$feed =& $data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0];
|
||||
}
|
||||
elseif (isset($data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]))
|
||||
{
|
||||
$feed =& $data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0];
|
||||
}
|
||||
elseif (isset($data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]))
|
||||
{
|
||||
$feed =& $data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0];
|
||||
}
|
||||
else
|
||||
{
|
||||
$feed = null;
|
||||
}
|
||||
|
||||
if ($feed !== null)
|
||||
{
|
||||
$sql = 'SELECT `data` FROM `' . $this->options['extras']['prefix'] . 'items` WHERE `feed_id` = :feed ORDER BY `posted` DESC';
|
||||
if ($items > 0)
|
||||
{
|
||||
$sql .= ' LIMIT ' . $items;
|
||||
}
|
||||
|
||||
$query = $this->mysql->prepare($sql);
|
||||
$query->bindValue(':feed', $this->id);
|
||||
if ($query->execute())
|
||||
{
|
||||
while ($row = $query->fetchColumn())
|
||||
{
|
||||
$feed['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['entry'][] = unserialize($row);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the last modified time for the cache
|
||||
*
|
||||
* @return int Timestamp
|
||||
*/
|
||||
public function mtime()
|
||||
{
|
||||
if ($this->mysql === null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$query = $this->mysql->prepare('SELECT `mtime` FROM `' . $this->options['extras']['prefix'] . 'cache_data` WHERE `id` = :id');
|
||||
$query->bindValue(':id', $this->id);
|
||||
if ($query->execute() && ($time = $query->fetchColumn()))
|
||||
{
|
||||
return $time;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the last modified time to the current time
|
||||
*
|
||||
* @return bool Success status
|
||||
*/
|
||||
public function touch()
|
||||
{
|
||||
if ($this->mysql === null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$query = $this->mysql->prepare('UPDATE `' . $this->options['extras']['prefix'] . 'cache_data` SET `mtime` = :time WHERE `id` = :id');
|
||||
$query->bindValue(':time', time());
|
||||
$query->bindValue(':id', $this->id);
|
||||
if ($query->execute() && $query->rowCount() > 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the cache
|
||||
*
|
||||
* @return bool Success status
|
||||
*/
|
||||
public function unlink()
|
||||
{
|
||||
if ($this->mysql === null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$query = $this->mysql->prepare('DELETE FROM `' . $this->options['extras']['prefix'] . 'cache_data` WHERE `id` = :id');
|
||||
$query->bindValue(':id', $this->id);
|
||||
$query2 = $this->mysql->prepare('DELETE FROM `' . $this->options['extras']['prefix'] . 'items` WHERE `feed_id` = :id');
|
||||
$query2->bindValue(':id', $this->id);
|
||||
if ($query->execute() && $query2->execute())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
210
Kapitel_7/Lektion_4/wordpress/wp-includes/SimplePie/Caption.php
Executable file
210
Kapitel_7/Lektion_4/wordpress/wp-includes/SimplePie/Caption.php
Executable file
@@ -0,0 +1,210 @@
|
||||
<?php
|
||||
/**
|
||||
* SimplePie
|
||||
*
|
||||
* A PHP-Based RSS and Atom Feed Framework.
|
||||
* Takes the hard work out of managing a complete RSS/Atom solution.
|
||||
*
|
||||
* Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* * Neither the name of the SimplePie Team nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDERS
|
||||
* AND 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.
|
||||
*
|
||||
* @package SimplePie
|
||||
* @version 1.3.1
|
||||
* @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
|
||||
* @author Ryan Parman
|
||||
* @author Geoffrey Sneddon
|
||||
* @author Ryan McCue
|
||||
* @link http://simplepie.org/ SimplePie
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Handles `<media:text>` captions as defined in Media RSS.
|
||||
*
|
||||
* Used by {@see SimplePie_Enclosure::get_caption()} and {@see SimplePie_Enclosure::get_captions()}
|
||||
*
|
||||
* This class can be overloaded with {@see SimplePie::set_caption_class()}
|
||||
*
|
||||
* @package SimplePie
|
||||
* @subpackage API
|
||||
*/
|
||||
class SimplePie_Caption
|
||||
{
|
||||
/**
|
||||
* Content type
|
||||
*
|
||||
* @var string
|
||||
* @see get_type()
|
||||
*/
|
||||
var $type;
|
||||
|
||||
/**
|
||||
* Language
|
||||
*
|
||||
* @var string
|
||||
* @see get_language()
|
||||
*/
|
||||
var $lang;
|
||||
|
||||
/**
|
||||
* Start time
|
||||
*
|
||||
* @var string
|
||||
* @see get_starttime()
|
||||
*/
|
||||
var $startTime;
|
||||
|
||||
/**
|
||||
* End time
|
||||
*
|
||||
* @var string
|
||||
* @see get_endtime()
|
||||
*/
|
||||
var $endTime;
|
||||
|
||||
/**
|
||||
* Caption text
|
||||
*
|
||||
* @var string
|
||||
* @see get_text()
|
||||
*/
|
||||
var $text;
|
||||
|
||||
/**
|
||||
* Constructor, used to input the data
|
||||
*
|
||||
* For documentation on all the parameters, see the corresponding
|
||||
* properties and their accessors
|
||||
*/
|
||||
public function __construct($type = null, $lang = null, $startTime = null, $endTime = null, $text = null)
|
||||
{
|
||||
$this->type = $type;
|
||||
$this->lang = $lang;
|
||||
$this->startTime = $startTime;
|
||||
$this->endTime = $endTime;
|
||||
$this->text = $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* String-ified version
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
// There is no $this->data here
|
||||
return md5(serialize($this));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the end time
|
||||
*
|
||||
* @return string|null Time in the format 'hh:mm:ss.SSS'
|
||||
*/
|
||||
public function get_endtime()
|
||||
{
|
||||
if ($this->endTime !== null)
|
||||
{
|
||||
return $this->endTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the language
|
||||
*
|
||||
* @link http://tools.ietf.org/html/rfc3066
|
||||
* @return string|null Language code as per RFC 3066
|
||||
*/
|
||||
public function get_language()
|
||||
{
|
||||
if ($this->lang !== null)
|
||||
{
|
||||
return $this->lang;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the start time
|
||||
*
|
||||
* @return string|null Time in the format 'hh:mm:ss.SSS'
|
||||
*/
|
||||
public function get_starttime()
|
||||
{
|
||||
if ($this->startTime !== null)
|
||||
{
|
||||
return $this->startTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the text of the caption
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function get_text()
|
||||
{
|
||||
if ($this->text !== null)
|
||||
{
|
||||
return $this->text;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the content type (not MIME type)
|
||||
*
|
||||
* @return string|null Either 'text' or 'html'
|
||||
*/
|
||||
public function get_type()
|
||||
{
|
||||
if ($this->type !== null)
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
157
Kapitel_7/Lektion_4/wordpress/wp-includes/SimplePie/Category.php
Executable file
157
Kapitel_7/Lektion_4/wordpress/wp-includes/SimplePie/Category.php
Executable file
@@ -0,0 +1,157 @@
|
||||
<?php
|
||||
/**
|
||||
* SimplePie
|
||||
*
|
||||
* A PHP-Based RSS and Atom Feed Framework.
|
||||
* Takes the hard work out of managing a complete RSS/Atom solution.
|
||||
*
|
||||
* Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* * Neither the name of the SimplePie Team nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDERS
|
||||
* AND 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.
|
||||
*
|
||||
* @package SimplePie
|
||||
* @version 1.3.1
|
||||
* @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
|
||||
* @author Ryan Parman
|
||||
* @author Geoffrey Sneddon
|
||||
* @author Ryan McCue
|
||||
* @link http://simplepie.org/ SimplePie
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
||||
*/
|
||||
|
||||
/**
|
||||
* Manages all category-related data
|
||||
*
|
||||
* Used by {@see SimplePie_Item::get_category()} and {@see SimplePie_Item::get_categories()}
|
||||
*
|
||||
* This class can be overloaded with {@see SimplePie::set_category_class()}
|
||||
*
|
||||
* @package SimplePie
|
||||
* @subpackage API
|
||||
*/
|
||||
class SimplePie_Category
|
||||
{
|
||||
/**
|
||||
* Category identifier
|
||||
*
|
||||
* @var string
|
||||
* @see get_term
|
||||
*/
|
||||
var $term;
|
||||
|
||||
/**
|
||||
* Categorization scheme identifier
|
||||
*
|
||||
* @var string
|
||||
* @see get_scheme()
|
||||
*/
|
||||
var $scheme;
|
||||
|
||||
/**
|
||||
* Human readable label
|
||||
*
|
||||
* @var string
|
||||
* @see get_label()
|
||||
*/
|
||||
var $label;
|
||||
|
||||
/**
|
||||
* Constructor, used to input the data
|
||||
*
|
||||
* @param string $term
|
||||
* @param string $scheme
|
||||
* @param string $label
|
||||
*/
|
||||
public function __construct($term = null, $scheme = null, $label = null)
|
||||
{
|
||||
$this->term = $term;
|
||||
$this->scheme = $scheme;
|
||||
$this->label = $label;
|
||||
}
|
||||
|
||||
/**
|
||||
* String-ified version
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
// There is no $this->data here
|
||||
return md5(serialize($this));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the category identifier
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function get_term()
|
||||
{
|
||||
if ($this->term !== null)
|
||||
{
|
||||
return $this->term;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the categorization scheme identifier
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function get_scheme()
|
||||
{
|
||||
if ($this->scheme !== null)
|
||||
{
|
||||
return $this->scheme;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the human readable label
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function get_label()
|
||||
{
|
||||
if ($this->label !== null)
|
||||
{
|
||||
return $this->label;
|
||||
}
|
||||
else
|
||||
{
|
||||
return $this->get_term();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
332
Kapitel_7/Lektion_4/wordpress/wp-includes/SimplePie/Content/Type/Sniffer.php
Executable file
332
Kapitel_7/Lektion_4/wordpress/wp-includes/SimplePie/Content/Type/Sniffer.php
Executable file
@@ -0,0 +1,332 @@
|
||||
<?php
|
||||
/**
|
||||
* SimplePie
|
||||
*
|
||||
* A PHP-Based RSS and Atom Feed Framework.
|
||||
* Takes the hard work out of managing a complete RSS/Atom solution.
|
||||
*
|
||||
* Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* * Neither the name of the SimplePie Team nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDERS
|
||||
* AND 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.
|
||||
*
|
||||
* @package SimplePie
|
||||
* @version 1.3.1
|
||||
* @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
|
||||
* @author Ryan Parman
|
||||
* @author Geoffrey Sneddon
|
||||
* @author Ryan McCue
|
||||
* @link http://simplepie.org/ SimplePie
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Content-type sniffing
|
||||
*
|
||||
* Based on the rules in http://tools.ietf.org/html/draft-abarth-mime-sniff-06
|
||||
*
|
||||
* This is used since we can't always trust Content-Type headers, and is based
|
||||
* upon the HTML5 parsing rules.
|
||||
*
|
||||
*
|
||||
* This class can be overloaded with {@see SimplePie::set_content_type_sniffer_class()}
|
||||
*
|
||||
* @package SimplePie
|
||||
* @subpackage HTTP
|
||||
*/
|
||||
class SimplePie_Content_Type_Sniffer
|
||||
{
|
||||
/**
|
||||
* File object
|
||||
*
|
||||
* @var SimplePie_File
|
||||
*/
|
||||
var $file;
|
||||
|
||||
/**
|
||||
* Create an instance of the class with the input file
|
||||
*
|
||||
* @param SimplePie_Content_Type_Sniffer $file Input file
|
||||
*/
|
||||
public function __construct($file)
|
||||
{
|
||||
$this->file = $file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Content-Type of the specified file
|
||||
*
|
||||
* @return string Actual Content-Type
|
||||
*/
|
||||
public function get_type()
|
||||
{
|
||||
if (isset($this->file->headers['content-type']))
|
||||
{
|
||||
if (!isset($this->file->headers['content-encoding'])
|
||||
&& ($this->file->headers['content-type'] === 'text/plain'
|
||||
|| $this->file->headers['content-type'] === 'text/plain; charset=ISO-8859-1'
|
||||
|| $this->file->headers['content-type'] === 'text/plain; charset=iso-8859-1'
|
||||
|| $this->file->headers['content-type'] === 'text/plain; charset=UTF-8'))
|
||||
{
|
||||
return $this->text_or_binary();
|
||||
}
|
||||
|
||||
if (($pos = strpos($this->file->headers['content-type'], ';')) !== false)
|
||||
{
|
||||
$official = substr($this->file->headers['content-type'], 0, $pos);
|
||||
}
|
||||
else
|
||||
{
|
||||
$official = $this->file->headers['content-type'];
|
||||
}
|
||||
$official = trim(strtolower($official));
|
||||
|
||||
if ($official === 'unknown/unknown'
|
||||
|| $official === 'application/unknown')
|
||||
{
|
||||
return $this->unknown();
|
||||
}
|
||||
elseif (substr($official, -4) === '+xml'
|
||||
|| $official === 'text/xml'
|
||||
|| $official === 'application/xml')
|
||||
{
|
||||
return $official;
|
||||
}
|
||||
elseif (substr($official, 0, 6) === 'image/')
|
||||
{
|
||||
if ($return = $this->image())
|
||||
{
|
||||
return $return;
|
||||
}
|
||||
else
|
||||
{
|
||||
return $official;
|
||||
}
|
||||
}
|
||||
elseif ($official === 'text/html')
|
||||
{
|
||||
return $this->feed_or_html();
|
||||
}
|
||||
else
|
||||
{
|
||||
return $official;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return $this->unknown();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sniff text or binary
|
||||
*
|
||||
* @return string Actual Content-Type
|
||||
*/
|
||||
public function text_or_binary()
|
||||
{
|
||||
if (substr($this->file->body, 0, 2) === "\xFE\xFF"
|
||||
|| substr($this->file->body, 0, 2) === "\xFF\xFE"
|
||||
|| substr($this->file->body, 0, 4) === "\x00\x00\xFE\xFF"
|
||||
|| substr($this->file->body, 0, 3) === "\xEF\xBB\xBF")
|
||||
{
|
||||
return 'text/plain';
|
||||
}
|
||||
elseif (preg_match('/[\x00-\x08\x0E-\x1A\x1C-\x1F]/', $this->file->body))
|
||||
{
|
||||
return 'application/octect-stream';
|
||||
}
|
||||
else
|
||||
{
|
||||
return 'text/plain';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sniff unknown
|
||||
*
|
||||
* @return string Actual Content-Type
|
||||
*/
|
||||
public function unknown()
|
||||
{
|
||||
$ws = strspn($this->file->body, "\x09\x0A\x0B\x0C\x0D\x20");
|
||||
if (strtolower(substr($this->file->body, $ws, 14)) === '<!doctype html'
|
||||
|| strtolower(substr($this->file->body, $ws, 5)) === '<html'
|
||||
|| strtolower(substr($this->file->body, $ws, 7)) === '<script')
|
||||
{
|
||||
return 'text/html';
|
||||
}
|
||||
elseif (substr($this->file->body, 0, 5) === '%PDF-')
|
||||
{
|
||||
return 'application/pdf';
|
||||
}
|
||||
elseif (substr($this->file->body, 0, 11) === '%!PS-Adobe-')
|
||||
{
|
||||
return 'application/postscript';
|
||||
}
|
||||
elseif (substr($this->file->body, 0, 6) === 'GIF87a'
|
||||
|| substr($this->file->body, 0, 6) === 'GIF89a')
|
||||
{
|
||||
return 'image/gif';
|
||||
}
|
||||
elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A")
|
||||
{
|
||||
return 'image/png';
|
||||
}
|
||||
elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF")
|
||||
{
|
||||
return 'image/jpeg';
|
||||
}
|
||||
elseif (substr($this->file->body, 0, 2) === "\x42\x4D")
|
||||
{
|
||||
return 'image/bmp';
|
||||
}
|
||||
elseif (substr($this->file->body, 0, 4) === "\x00\x00\x01\x00")
|
||||
{
|
||||
return 'image/vnd.microsoft.icon';
|
||||
}
|
||||
else
|
||||
{
|
||||
return $this->text_or_binary();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sniff images
|
||||
*
|
||||
* @return string Actual Content-Type
|
||||
*/
|
||||
public function image()
|
||||
{
|
||||
if (substr($this->file->body, 0, 6) === 'GIF87a'
|
||||
|| substr($this->file->body, 0, 6) === 'GIF89a')
|
||||
{
|
||||
return 'image/gif';
|
||||
}
|
||||
elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A")
|
||||
{
|
||||
return 'image/png';
|
||||
}
|
||||
elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF")
|
||||
{
|
||||
return 'image/jpeg';
|
||||
}
|
||||
elseif (substr($this->file->body, 0, 2) === "\x42\x4D")
|
||||
{
|
||||
return 'image/bmp';
|
||||
}
|
||||
elseif (substr($this->file->body, 0, 4) === "\x00\x00\x01\x00")
|
||||
{
|
||||
return 'image/vnd.microsoft.icon';
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sniff HTML
|
||||
*
|
||||
* @return string Actual Content-Type
|
||||
*/
|
||||
public function feed_or_html()
|
||||
{
|
||||
$len = strlen($this->file->body);
|
||||
$pos = strspn($this->file->body, "\x09\x0A\x0D\x20");
|
||||
|
||||
while ($pos < $len)
|
||||
{
|
||||
switch ($this->file->body[$pos])
|
||||
{
|
||||
case "\x09":
|
||||
case "\x0A":
|
||||
case "\x0D":
|
||||
case "\x20":
|
||||
$pos += strspn($this->file->body, "\x09\x0A\x0D\x20", $pos);
|
||||
continue 2;
|
||||
|
||||
case '<':
|
||||
$pos++;
|
||||
break;
|
||||
|
||||
default:
|
||||
return 'text/html';
|
||||
}
|
||||
|
||||
if (substr($this->file->body, $pos, 3) === '!--')
|
||||
{
|
||||
$pos += 3;
|
||||
if ($pos < $len && ($pos = strpos($this->file->body, '-->', $pos)) !== false)
|
||||
{
|
||||
$pos += 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 'text/html';
|
||||
}
|
||||
}
|
||||
elseif (substr($this->file->body, $pos, 1) === '!')
|
||||
{
|
||||
if ($pos < $len && ($pos = strpos($this->file->body, '>', $pos)) !== false)
|
||||
{
|
||||
$pos++;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 'text/html';
|
||||
}
|
||||
}
|
||||
elseif (substr($this->file->body, $pos, 1) === '?')
|
||||
{
|
||||
if ($pos < $len && ($pos = strpos($this->file->body, '?>', $pos)) !== false)
|
||||
{
|
||||
$pos += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 'text/html';
|
||||
}
|
||||
}
|
||||
elseif (substr($this->file->body, $pos, 3) === 'rss'
|
||||
|| substr($this->file->body, $pos, 7) === 'rdf:RDF')
|
||||
{
|
||||
return 'application/rss+xml';
|
||||
}
|
||||
elseif (substr($this->file->body, $pos, 4) === 'feed')
|
||||
{
|
||||
return 'application/atom+xml';
|
||||
}
|
||||
else
|
||||
{
|
||||
return 'text/html';
|
||||
}
|
||||
}
|
||||
|
||||
return 'text/html';
|
||||
}
|
||||
}
|
||||
|
||||
130
Kapitel_7/Lektion_4/wordpress/wp-includes/SimplePie/Copyright.php
Executable file
130
Kapitel_7/Lektion_4/wordpress/wp-includes/SimplePie/Copyright.php
Executable file
@@ -0,0 +1,130 @@
|
||||
<?php
|
||||
/**
|
||||
* SimplePie
|
||||
*
|
||||
* A PHP-Based RSS and Atom Feed Framework.
|
||||
* Takes the hard work out of managing a complete RSS/Atom solution.
|
||||
*
|
||||
* Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* * Neither the name of the SimplePie Team nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDERS
|
||||
* AND 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.
|
||||
*
|
||||
* @package SimplePie
|
||||
* @version 1.3.1
|
||||
* @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
|
||||
* @author Ryan Parman
|
||||
* @author Geoffrey Sneddon
|
||||
* @author Ryan McCue
|
||||
* @link http://simplepie.org/ SimplePie
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
||||
*/
|
||||
|
||||
/**
|
||||
* Manages `<media:copyright>` copyright tags as defined in Media RSS
|
||||
*
|
||||
* Used by {@see SimplePie_Enclosure::get_copyright()}
|
||||
*
|
||||
* This class can be overloaded with {@see SimplePie::set_copyright_class()}
|
||||
*
|
||||
* @package SimplePie
|
||||
* @subpackage API
|
||||
*/
|
||||
class SimplePie_Copyright
|
||||
{
|
||||
/**
|
||||
* Copyright URL
|
||||
*
|
||||
* @var string
|
||||
* @see get_url()
|
||||
*/
|
||||
var $url;
|
||||
|
||||
/**
|
||||
* Attribution
|
||||
*
|
||||
* @var string
|
||||
* @see get_attribution()
|
||||
*/
|
||||
var $label;
|
||||
|
||||
/**
|
||||
* Constructor, used to input the data
|
||||
*
|
||||
* For documentation on all the parameters, see the corresponding
|
||||
* properties and their accessors
|
||||
*/
|
||||
public function __construct($url = null, $label = null)
|
||||
{
|
||||
$this->url = $url;
|
||||
$this->label = $label;
|
||||
}
|
||||
|
||||
/**
|
||||
* String-ified version
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
// There is no $this->data here
|
||||
return md5(serialize($this));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the copyright URL
|
||||
*
|
||||
* @return string|null URL to copyright information
|
||||
*/
|
||||
public function get_url()
|
||||
{
|
||||
if ($this->url !== null)
|
||||
{
|
||||
return $this->url;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the attribution text
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function get_attribution()
|
||||
{
|
||||
if ($this->label !== null)
|
||||
{
|
||||
return $this->label;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
57
Kapitel_7/Lektion_4/wordpress/wp-includes/SimplePie/Core.php
Executable file
57
Kapitel_7/Lektion_4/wordpress/wp-includes/SimplePie/Core.php
Executable file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
/**
|
||||
* SimplePie
|
||||
*
|
||||
* A PHP-Based RSS and Atom Feed Framework.
|
||||
* Takes the hard work out of managing a complete RSS/Atom solution.
|
||||
*
|
||||
* Copyright (c) 2004-2009, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* * Neither the name of the SimplePie Team nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDERS
|
||||
* AND 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.
|
||||
*
|
||||
* @package SimplePie
|
||||
* @version 1.3.1
|
||||
* @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
|
||||
* @author Ryan Parman
|
||||
* @author Geoffrey Sneddon
|
||||
* @author Ryan McCue
|
||||
* @link http://simplepie.org/ SimplePie
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
||||
*/
|
||||
|
||||
/**
|
||||
* SimplePie class.
|
||||
*
|
||||
* Class for backward compatibility.
|
||||
*
|
||||
* @deprecated Use {@see SimplePie} directly
|
||||
* @package SimplePie
|
||||
* @subpackage API
|
||||
*/
|
||||
class SimplePie_Core extends SimplePie
|
||||
{
|
||||
|
||||
}
|
||||
156
Kapitel_7/Lektion_4/wordpress/wp-includes/SimplePie/Credit.php
Executable file
156
Kapitel_7/Lektion_4/wordpress/wp-includes/SimplePie/Credit.php
Executable file
@@ -0,0 +1,156 @@
|
||||
<?php
|
||||
/**
|
||||
* SimplePie
|
||||
*
|
||||
* A PHP-Based RSS and Atom Feed Framework.
|
||||
* Takes the hard work out of managing a complete RSS/Atom solution.
|
||||
*
|
||||
* Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* * Neither the name of the SimplePie Team nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDERS
|
||||
* AND 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.
|
||||
*
|
||||
* @package SimplePie
|
||||
* @version 1.3.1
|
||||
* @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
|
||||
* @author Ryan Parman
|
||||
* @author Geoffrey Sneddon
|
||||
* @author Ryan McCue
|
||||
* @link http://simplepie.org/ SimplePie
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
||||
*/
|
||||
|
||||
/**
|
||||
* Handles `<media:credit>` as defined in Media RSS
|
||||
*
|
||||
* Used by {@see SimplePie_Enclosure::get_credit()} and {@see SimplePie_Enclosure::get_credits()}
|
||||
*
|
||||
* This class can be overloaded with {@see SimplePie::set_credit_class()}
|
||||
*
|
||||
* @package SimplePie
|
||||
* @subpackage API
|
||||
*/
|
||||
class SimplePie_Credit
|
||||
{
|
||||
/**
|
||||
* Credited role
|
||||
*
|
||||
* @var string
|
||||
* @see get_role()
|
||||
*/
|
||||
var $role;
|
||||
|
||||
/**
|
||||
* Organizational scheme
|
||||
*
|
||||
* @var string
|
||||
* @see get_scheme()
|
||||
*/
|
||||
var $scheme;
|
||||
|
||||
/**
|
||||
* Credited name
|
||||
*
|
||||
* @var string
|
||||
* @see get_name()
|
||||
*/
|
||||
var $name;
|
||||
|
||||
/**
|
||||
* Constructor, used to input the data
|
||||
*
|
||||
* For documentation on all the parameters, see the corresponding
|
||||
* properties and their accessors
|
||||
*/
|
||||
public function __construct($role = null, $scheme = null, $name = null)
|
||||
{
|
||||
$this->role = $role;
|
||||
$this->scheme = $scheme;
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* String-ified version
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
// There is no $this->data here
|
||||
return md5(serialize($this));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the role of the person receiving credit
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function get_role()
|
||||
{
|
||||
if ($this->role !== null)
|
||||
{
|
||||
return $this->role;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the organizational scheme
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function get_scheme()
|
||||
{
|
||||
if ($this->scheme !== null)
|
||||
{
|
||||
return $this->scheme;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the credited person/entity's name
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function get_name()
|
||||
{
|
||||
if ($this->name !== null)
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
617
Kapitel_7/Lektion_4/wordpress/wp-includes/SimplePie/Decode/HTML/Entities.php
Executable file
617
Kapitel_7/Lektion_4/wordpress/wp-includes/SimplePie/Decode/HTML/Entities.php
Executable file
@@ -0,0 +1,617 @@
|
||||
<?php
|
||||
/**
|
||||
* SimplePie
|
||||
*
|
||||
* A PHP-Based RSS and Atom Feed Framework.
|
||||
* Takes the hard work out of managing a complete RSS/Atom solution.
|
||||
*
|
||||
* Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* * Neither the name of the SimplePie Team nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDERS
|
||||
* AND 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.
|
||||
*
|
||||
* @package SimplePie
|
||||
* @version 1.3.1
|
||||
* @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
|
||||
* @author Ryan Parman
|
||||
* @author Geoffrey Sneddon
|
||||
* @author Ryan McCue
|
||||
* @link http://simplepie.org/ SimplePie
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Decode HTML Entities
|
||||
*
|
||||
* This implements HTML5 as of revision 967 (2007-06-28)
|
||||
*
|
||||
* @deprecated Use DOMDocument instead!
|
||||
* @package SimplePie
|
||||
*/
|
||||
class SimplePie_Decode_HTML_Entities
|
||||
{
|
||||
/**
|
||||
* Data to be parsed
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
var $data = '';
|
||||
|
||||
/**
|
||||
* Currently consumed bytes
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
var $consumed = '';
|
||||
|
||||
/**
|
||||
* Position of the current byte being parsed
|
||||
*
|
||||
* @access private
|
||||
* @var int
|
||||
*/
|
||||
var $position = 0;
|
||||
|
||||
/**
|
||||
* Create an instance of the class with the input data
|
||||
*
|
||||
* @access public
|
||||
* @param string $data Input data
|
||||
*/
|
||||
public function __construct($data)
|
||||
{
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the input data
|
||||
*
|
||||
* @access public
|
||||
* @return string Output data
|
||||
*/
|
||||
public function parse()
|
||||
{
|
||||
while (($this->position = strpos($this->data, '&', $this->position)) !== false)
|
||||
{
|
||||
$this->consume();
|
||||
$this->entity();
|
||||
$this->consumed = '';
|
||||
}
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Consume the next byte
|
||||
*
|
||||
* @access private
|
||||
* @return mixed The next byte, or false, if there is no more data
|
||||
*/
|
||||
public function consume()
|
||||
{
|
||||
if (isset($this->data[$this->position]))
|
||||
{
|
||||
$this->consumed .= $this->data[$this->position];
|
||||
return $this->data[$this->position++];
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Consume a range of characters
|
||||
*
|
||||
* @access private
|
||||
* @param string $chars Characters to consume
|
||||
* @return mixed A series of characters that match the range, or false
|
||||
*/
|
||||
public function consume_range($chars)
|
||||
{
|
||||
if ($len = strspn($this->data, $chars, $this->position))
|
||||
{
|
||||
$data = substr($this->data, $this->position, $len);
|
||||
$this->consumed .= $data;
|
||||
$this->position += $len;
|
||||
return $data;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unconsume one byte
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
public function unconsume()
|
||||
{
|
||||
$this->consumed = substr($this->consumed, 0, -1);
|
||||
$this->position--;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode an entity
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
public function entity()
|
||||
{
|
||||
switch ($this->consume())
|
||||
{
|
||||
case "\x09":
|
||||
case "\x0A":
|
||||
case "\x0B":
|
||||
case "\x0B":
|
||||
case "\x0C":
|
||||
case "\x20":
|
||||
case "\x3C":
|
||||
case "\x26":
|
||||
case false:
|
||||
break;
|
||||
|
||||
case "\x23":
|
||||
switch ($this->consume())
|
||||
{
|
||||
case "\x78":
|
||||
case "\x58":
|
||||
$range = '0123456789ABCDEFabcdef';
|
||||
$hex = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
$range = '0123456789';
|
||||
$hex = false;
|
||||
$this->unconsume();
|
||||
break;
|
||||
}
|
||||
|
||||
if ($codepoint = $this->consume_range($range))
|
||||
{
|
||||
static $windows_1252_specials = array(0x0D => "\x0A", 0x80 => "\xE2\x82\xAC", 0x81 => "\xEF\xBF\xBD", 0x82 => "\xE2\x80\x9A", 0x83 => "\xC6\x92", 0x84 => "\xE2\x80\x9E", 0x85 => "\xE2\x80\xA6", 0x86 => "\xE2\x80\xA0", 0x87 => "\xE2\x80\xA1", 0x88 => "\xCB\x86", 0x89 => "\xE2\x80\xB0", 0x8A => "\xC5\xA0", 0x8B => "\xE2\x80\xB9", 0x8C => "\xC5\x92", 0x8D => "\xEF\xBF\xBD", 0x8E => "\xC5\xBD", 0x8F => "\xEF\xBF\xBD", 0x90 => "\xEF\xBF\xBD", 0x91 => "\xE2\x80\x98", 0x92 => "\xE2\x80\x99", 0x93 => "\xE2\x80\x9C", 0x94 => "\xE2\x80\x9D", 0x95 => "\xE2\x80\xA2", 0x96 => "\xE2\x80\x93", 0x97 => "\xE2\x80\x94", 0x98 => "\xCB\x9C", 0x99 => "\xE2\x84\xA2", 0x9A => "\xC5\xA1", 0x9B => "\xE2\x80\xBA", 0x9C => "\xC5\x93", 0x9D => "\xEF\xBF\xBD", 0x9E => "\xC5\xBE", 0x9F => "\xC5\xB8");
|
||||
|
||||
if ($hex)
|
||||
{
|
||||
$codepoint = hexdec($codepoint);
|
||||
}
|
||||
else
|
||||
{
|
||||
$codepoint = intval($codepoint);
|
||||
}
|
||||
|
||||
if (isset($windows_1252_specials[$codepoint]))
|
||||
{
|
||||
$replacement = $windows_1252_specials[$codepoint];
|
||||
}
|
||||
else
|
||||
{
|
||||
$replacement = SimplePie_Misc::codepoint_to_utf8($codepoint);
|
||||
}
|
||||
|
||||
if (!in_array($this->consume(), array(';', false), true))
|
||||
{
|
||||
$this->unconsume();
|
||||
}
|
||||
|
||||
$consumed_length = strlen($this->consumed);
|
||||
$this->data = substr_replace($this->data, $replacement, $this->position - $consumed_length, $consumed_length);
|
||||
$this->position += strlen($replacement) - $consumed_length;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
static $entities = array(
|
||||
'Aacute' => "\xC3\x81",
|
||||
'aacute' => "\xC3\xA1",
|
||||
'Aacute;' => "\xC3\x81",
|
||||
'aacute;' => "\xC3\xA1",
|
||||
'Acirc' => "\xC3\x82",
|
||||
'acirc' => "\xC3\xA2",
|
||||
'Acirc;' => "\xC3\x82",
|
||||
'acirc;' => "\xC3\xA2",
|
||||
'acute' => "\xC2\xB4",
|
||||
'acute;' => "\xC2\xB4",
|
||||
'AElig' => "\xC3\x86",
|
||||
'aelig' => "\xC3\xA6",
|
||||
'AElig;' => "\xC3\x86",
|
||||
'aelig;' => "\xC3\xA6",
|
||||
'Agrave' => "\xC3\x80",
|
||||
'agrave' => "\xC3\xA0",
|
||||
'Agrave;' => "\xC3\x80",
|
||||
'agrave;' => "\xC3\xA0",
|
||||
'alefsym;' => "\xE2\x84\xB5",
|
||||
'Alpha;' => "\xCE\x91",
|
||||
'alpha;' => "\xCE\xB1",
|
||||
'AMP' => "\x26",
|
||||
'amp' => "\x26",
|
||||
'AMP;' => "\x26",
|
||||
'amp;' => "\x26",
|
||||
'and;' => "\xE2\x88\xA7",
|
||||
'ang;' => "\xE2\x88\xA0",
|
||||
'apos;' => "\x27",
|
||||
'Aring' => "\xC3\x85",
|
||||
'aring' => "\xC3\xA5",
|
||||
'Aring;' => "\xC3\x85",
|
||||
'aring;' => "\xC3\xA5",
|
||||
'asymp;' => "\xE2\x89\x88",
|
||||
'Atilde' => "\xC3\x83",
|
||||
'atilde' => "\xC3\xA3",
|
||||
'Atilde;' => "\xC3\x83",
|
||||
'atilde;' => "\xC3\xA3",
|
||||
'Auml' => "\xC3\x84",
|
||||
'auml' => "\xC3\xA4",
|
||||
'Auml;' => "\xC3\x84",
|
||||
'auml;' => "\xC3\xA4",
|
||||
'bdquo;' => "\xE2\x80\x9E",
|
||||
'Beta;' => "\xCE\x92",
|
||||
'beta;' => "\xCE\xB2",
|
||||
'brvbar' => "\xC2\xA6",
|
||||
'brvbar;' => "\xC2\xA6",
|
||||
'bull;' => "\xE2\x80\xA2",
|
||||
'cap;' => "\xE2\x88\xA9",
|
||||
'Ccedil' => "\xC3\x87",
|
||||
'ccedil' => "\xC3\xA7",
|
||||
'Ccedil;' => "\xC3\x87",
|
||||
'ccedil;' => "\xC3\xA7",
|
||||
'cedil' => "\xC2\xB8",
|
||||
'cedil;' => "\xC2\xB8",
|
||||
'cent' => "\xC2\xA2",
|
||||
'cent;' => "\xC2\xA2",
|
||||
'Chi;' => "\xCE\xA7",
|
||||
'chi;' => "\xCF\x87",
|
||||
'circ;' => "\xCB\x86",
|
||||
'clubs;' => "\xE2\x99\xA3",
|
||||
'cong;' => "\xE2\x89\x85",
|
||||
'COPY' => "\xC2\xA9",
|
||||
'copy' => "\xC2\xA9",
|
||||
'COPY;' => "\xC2\xA9",
|
||||
'copy;' => "\xC2\xA9",
|
||||
'crarr;' => "\xE2\x86\xB5",
|
||||
'cup;' => "\xE2\x88\xAA",
|
||||
'curren' => "\xC2\xA4",
|
||||
'curren;' => "\xC2\xA4",
|
||||
'Dagger;' => "\xE2\x80\xA1",
|
||||
'dagger;' => "\xE2\x80\xA0",
|
||||
'dArr;' => "\xE2\x87\x93",
|
||||
'darr;' => "\xE2\x86\x93",
|
||||
'deg' => "\xC2\xB0",
|
||||
'deg;' => "\xC2\xB0",
|
||||
'Delta;' => "\xCE\x94",
|
||||
'delta;' => "\xCE\xB4",
|
||||
'diams;' => "\xE2\x99\xA6",
|
||||
'divide' => "\xC3\xB7",
|
||||
'divide;' => "\xC3\xB7",
|
||||
'Eacute' => "\xC3\x89",
|
||||
'eacute' => "\xC3\xA9",
|
||||
'Eacute;' => "\xC3\x89",
|
||||
'eacute;' => "\xC3\xA9",
|
||||
'Ecirc' => "\xC3\x8A",
|
||||
'ecirc' => "\xC3\xAA",
|
||||
'Ecirc;' => "\xC3\x8A",
|
||||
'ecirc;' => "\xC3\xAA",
|
||||
'Egrave' => "\xC3\x88",
|
||||
'egrave' => "\xC3\xA8",
|
||||
'Egrave;' => "\xC3\x88",
|
||||
'egrave;' => "\xC3\xA8",
|
||||
'empty;' => "\xE2\x88\x85",
|
||||
'emsp;' => "\xE2\x80\x83",
|
||||
'ensp;' => "\xE2\x80\x82",
|
||||
'Epsilon;' => "\xCE\x95",
|
||||
'epsilon;' => "\xCE\xB5",
|
||||
'equiv;' => "\xE2\x89\xA1",
|
||||
'Eta;' => "\xCE\x97",
|
||||
'eta;' => "\xCE\xB7",
|
||||
'ETH' => "\xC3\x90",
|
||||
'eth' => "\xC3\xB0",
|
||||
'ETH;' => "\xC3\x90",
|
||||
'eth;' => "\xC3\xB0",
|
||||
'Euml' => "\xC3\x8B",
|
||||
'euml' => "\xC3\xAB",
|
||||
'Euml;' => "\xC3\x8B",
|
||||
'euml;' => "\xC3\xAB",
|
||||
'euro;' => "\xE2\x82\xAC",
|
||||
'exist;' => "\xE2\x88\x83",
|
||||
'fnof;' => "\xC6\x92",
|
||||
'forall;' => "\xE2\x88\x80",
|
||||
'frac12' => "\xC2\xBD",
|
||||
'frac12;' => "\xC2\xBD",
|
||||
'frac14' => "\xC2\xBC",
|
||||
'frac14;' => "\xC2\xBC",
|
||||
'frac34' => "\xC2\xBE",
|
||||
'frac34;' => "\xC2\xBE",
|
||||
'frasl;' => "\xE2\x81\x84",
|
||||
'Gamma;' => "\xCE\x93",
|
||||
'gamma;' => "\xCE\xB3",
|
||||
'ge;' => "\xE2\x89\xA5",
|
||||
'GT' => "\x3E",
|
||||
'gt' => "\x3E",
|
||||
'GT;' => "\x3E",
|
||||
'gt;' => "\x3E",
|
||||
'hArr;' => "\xE2\x87\x94",
|
||||
'harr;' => "\xE2\x86\x94",
|
||||
'hearts;' => "\xE2\x99\xA5",
|
||||
'hellip;' => "\xE2\x80\xA6",
|
||||
'Iacute' => "\xC3\x8D",
|
||||
'iacute' => "\xC3\xAD",
|
||||
'Iacute;' => "\xC3\x8D",
|
||||
'iacute;' => "\xC3\xAD",
|
||||
'Icirc' => "\xC3\x8E",
|
||||
'icirc' => "\xC3\xAE",
|
||||
'Icirc;' => "\xC3\x8E",
|
||||
'icirc;' => "\xC3\xAE",
|
||||
'iexcl' => "\xC2\xA1",
|
||||
'iexcl;' => "\xC2\xA1",
|
||||
'Igrave' => "\xC3\x8C",
|
||||
'igrave' => "\xC3\xAC",
|
||||
'Igrave;' => "\xC3\x8C",
|
||||
'igrave;' => "\xC3\xAC",
|
||||
'image;' => "\xE2\x84\x91",
|
||||
'infin;' => "\xE2\x88\x9E",
|
||||
'int;' => "\xE2\x88\xAB",
|
||||
'Iota;' => "\xCE\x99",
|
||||
'iota;' => "\xCE\xB9",
|
||||
'iquest' => "\xC2\xBF",
|
||||
'iquest;' => "\xC2\xBF",
|
||||
'isin;' => "\xE2\x88\x88",
|
||||
'Iuml' => "\xC3\x8F",
|
||||
'iuml' => "\xC3\xAF",
|
||||
'Iuml;' => "\xC3\x8F",
|
||||
'iuml;' => "\xC3\xAF",
|
||||
'Kappa;' => "\xCE\x9A",
|
||||
'kappa;' => "\xCE\xBA",
|
||||
'Lambda;' => "\xCE\x9B",
|
||||
'lambda;' => "\xCE\xBB",
|
||||
'lang;' => "\xE3\x80\x88",
|
||||
'laquo' => "\xC2\xAB",
|
||||
'laquo;' => "\xC2\xAB",
|
||||
'lArr;' => "\xE2\x87\x90",
|
||||
'larr;' => "\xE2\x86\x90",
|
||||
'lceil;' => "\xE2\x8C\x88",
|
||||
'ldquo;' => "\xE2\x80\x9C",
|
||||
'le;' => "\xE2\x89\xA4",
|
||||
'lfloor;' => "\xE2\x8C\x8A",
|
||||
'lowast;' => "\xE2\x88\x97",
|
||||
'loz;' => "\xE2\x97\x8A",
|
||||
'lrm;' => "\xE2\x80\x8E",
|
||||
'lsaquo;' => "\xE2\x80\xB9",
|
||||
'lsquo;' => "\xE2\x80\x98",
|
||||
'LT' => "\x3C",
|
||||
'lt' => "\x3C",
|
||||
'LT;' => "\x3C",
|
||||
'lt;' => "\x3C",
|
||||
'macr' => "\xC2\xAF",
|
||||
'macr;' => "\xC2\xAF",
|
||||
'mdash;' => "\xE2\x80\x94",
|
||||
'micro' => "\xC2\xB5",
|
||||
'micro;' => "\xC2\xB5",
|
||||
'middot' => "\xC2\xB7",
|
||||
'middot;' => "\xC2\xB7",
|
||||
'minus;' => "\xE2\x88\x92",
|
||||
'Mu;' => "\xCE\x9C",
|
||||
'mu;' => "\xCE\xBC",
|
||||
'nabla;' => "\xE2\x88\x87",
|
||||
'nbsp' => "\xC2\xA0",
|
||||
'nbsp;' => "\xC2\xA0",
|
||||
'ndash;' => "\xE2\x80\x93",
|
||||
'ne;' => "\xE2\x89\xA0",
|
||||
'ni;' => "\xE2\x88\x8B",
|
||||
'not' => "\xC2\xAC",
|
||||
'not;' => "\xC2\xAC",
|
||||
'notin;' => "\xE2\x88\x89",
|
||||
'nsub;' => "\xE2\x8A\x84",
|
||||
'Ntilde' => "\xC3\x91",
|
||||
'ntilde' => "\xC3\xB1",
|
||||
'Ntilde;' => "\xC3\x91",
|
||||
'ntilde;' => "\xC3\xB1",
|
||||
'Nu;' => "\xCE\x9D",
|
||||
'nu;' => "\xCE\xBD",
|
||||
'Oacute' => "\xC3\x93",
|
||||
'oacute' => "\xC3\xB3",
|
||||
'Oacute;' => "\xC3\x93",
|
||||
'oacute;' => "\xC3\xB3",
|
||||
'Ocirc' => "\xC3\x94",
|
||||
'ocirc' => "\xC3\xB4",
|
||||
'Ocirc;' => "\xC3\x94",
|
||||
'ocirc;' => "\xC3\xB4",
|
||||
'OElig;' => "\xC5\x92",
|
||||
'oelig;' => "\xC5\x93",
|
||||
'Ograve' => "\xC3\x92",
|
||||
'ograve' => "\xC3\xB2",
|
||||
'Ograve;' => "\xC3\x92",
|
||||
'ograve;' => "\xC3\xB2",
|
||||
'oline;' => "\xE2\x80\xBE",
|
||||
'Omega;' => "\xCE\xA9",
|
||||
'omega;' => "\xCF\x89",
|
||||
'Omicron;' => "\xCE\x9F",
|
||||
'omicron;' => "\xCE\xBF",
|
||||
'oplus;' => "\xE2\x8A\x95",
|
||||
'or;' => "\xE2\x88\xA8",
|
||||
'ordf' => "\xC2\xAA",
|
||||
'ordf;' => "\xC2\xAA",
|
||||
'ordm' => "\xC2\xBA",
|
||||
'ordm;' => "\xC2\xBA",
|
||||
'Oslash' => "\xC3\x98",
|
||||
'oslash' => "\xC3\xB8",
|
||||
'Oslash;' => "\xC3\x98",
|
||||
'oslash;' => "\xC3\xB8",
|
||||
'Otilde' => "\xC3\x95",
|
||||
'otilde' => "\xC3\xB5",
|
||||
'Otilde;' => "\xC3\x95",
|
||||
'otilde;' => "\xC3\xB5",
|
||||
'otimes;' => "\xE2\x8A\x97",
|
||||
'Ouml' => "\xC3\x96",
|
||||
'ouml' => "\xC3\xB6",
|
||||
'Ouml;' => "\xC3\x96",
|
||||
'ouml;' => "\xC3\xB6",
|
||||
'para' => "\xC2\xB6",
|
||||
'para;' => "\xC2\xB6",
|
||||
'part;' => "\xE2\x88\x82",
|
||||
'permil;' => "\xE2\x80\xB0",
|
||||
'perp;' => "\xE2\x8A\xA5",
|
||||
'Phi;' => "\xCE\xA6",
|
||||
'phi;' => "\xCF\x86",
|
||||
'Pi;' => "\xCE\xA0",
|
||||
'pi;' => "\xCF\x80",
|
||||
'piv;' => "\xCF\x96",
|
||||
'plusmn' => "\xC2\xB1",
|
||||
'plusmn;' => "\xC2\xB1",
|
||||
'pound' => "\xC2\xA3",
|
||||
'pound;' => "\xC2\xA3",
|
||||
'Prime;' => "\xE2\x80\xB3",
|
||||
'prime;' => "\xE2\x80\xB2",
|
||||
'prod;' => "\xE2\x88\x8F",
|
||||
'prop;' => "\xE2\x88\x9D",
|
||||
'Psi;' => "\xCE\xA8",
|
||||
'psi;' => "\xCF\x88",
|
||||
'QUOT' => "\x22",
|
||||
'quot' => "\x22",
|
||||
'QUOT;' => "\x22",
|
||||
'quot;' => "\x22",
|
||||
'radic;' => "\xE2\x88\x9A",
|
||||
'rang;' => "\xE3\x80\x89",
|
||||
'raquo' => "\xC2\xBB",
|
||||
'raquo;' => "\xC2\xBB",
|
||||
'rArr;' => "\xE2\x87\x92",
|
||||
'rarr;' => "\xE2\x86\x92",
|
||||
'rceil;' => "\xE2\x8C\x89",
|
||||
'rdquo;' => "\xE2\x80\x9D",
|
||||
'real;' => "\xE2\x84\x9C",
|
||||
'REG' => "\xC2\xAE",
|
||||
'reg' => "\xC2\xAE",
|
||||
'REG;' => "\xC2\xAE",
|
||||
'reg;' => "\xC2\xAE",
|
||||
'rfloor;' => "\xE2\x8C\x8B",
|
||||
'Rho;' => "\xCE\xA1",
|
||||
'rho;' => "\xCF\x81",
|
||||
'rlm;' => "\xE2\x80\x8F",
|
||||
'rsaquo;' => "\xE2\x80\xBA",
|
||||
'rsquo;' => "\xE2\x80\x99",
|
||||
'sbquo;' => "\xE2\x80\x9A",
|
||||
'Scaron;' => "\xC5\xA0",
|
||||
'scaron;' => "\xC5\xA1",
|
||||
'sdot;' => "\xE2\x8B\x85",
|
||||
'sect' => "\xC2\xA7",
|
||||
'sect;' => "\xC2\xA7",
|
||||
'shy' => "\xC2\xAD",
|
||||
'shy;' => "\xC2\xAD",
|
||||
'Sigma;' => "\xCE\xA3",
|
||||
'sigma;' => "\xCF\x83",
|
||||
'sigmaf;' => "\xCF\x82",
|
||||
'sim;' => "\xE2\x88\xBC",
|
||||
'spades;' => "\xE2\x99\xA0",
|
||||
'sub;' => "\xE2\x8A\x82",
|
||||
'sube;' => "\xE2\x8A\x86",
|
||||
'sum;' => "\xE2\x88\x91",
|
||||
'sup;' => "\xE2\x8A\x83",
|
||||
'sup1' => "\xC2\xB9",
|
||||
'sup1;' => "\xC2\xB9",
|
||||
'sup2' => "\xC2\xB2",
|
||||
'sup2;' => "\xC2\xB2",
|
||||
'sup3' => "\xC2\xB3",
|
||||
'sup3;' => "\xC2\xB3",
|
||||
'supe;' => "\xE2\x8A\x87",
|
||||
'szlig' => "\xC3\x9F",
|
||||
'szlig;' => "\xC3\x9F",
|
||||
'Tau;' => "\xCE\xA4",
|
||||
'tau;' => "\xCF\x84",
|
||||
'there4;' => "\xE2\x88\xB4",
|
||||
'Theta;' => "\xCE\x98",
|
||||
'theta;' => "\xCE\xB8",
|
||||
'thetasym;' => "\xCF\x91",
|
||||
'thinsp;' => "\xE2\x80\x89",
|
||||
'THORN' => "\xC3\x9E",
|
||||
'thorn' => "\xC3\xBE",
|
||||
'THORN;' => "\xC3\x9E",
|
||||
'thorn;' => "\xC3\xBE",
|
||||
'tilde;' => "\xCB\x9C",
|
||||
'times' => "\xC3\x97",
|
||||
'times;' => "\xC3\x97",
|
||||
'TRADE;' => "\xE2\x84\xA2",
|
||||
'trade;' => "\xE2\x84\xA2",
|
||||
'Uacute' => "\xC3\x9A",
|
||||
'uacute' => "\xC3\xBA",
|
||||
'Uacute;' => "\xC3\x9A",
|
||||
'uacute;' => "\xC3\xBA",
|
||||
'uArr;' => "\xE2\x87\x91",
|
||||
'uarr;' => "\xE2\x86\x91",
|
||||
'Ucirc' => "\xC3\x9B",
|
||||
'ucirc' => "\xC3\xBB",
|
||||
'Ucirc;' => "\xC3\x9B",
|
||||
'ucirc;' => "\xC3\xBB",
|
||||
'Ugrave' => "\xC3\x99",
|
||||
'ugrave' => "\xC3\xB9",
|
||||
'Ugrave;' => "\xC3\x99",
|
||||
'ugrave;' => "\xC3\xB9",
|
||||
'uml' => "\xC2\xA8",
|
||||
'uml;' => "\xC2\xA8",
|
||||
'upsih;' => "\xCF\x92",
|
||||
'Upsilon;' => "\xCE\xA5",
|
||||
'upsilon;' => "\xCF\x85",
|
||||
'Uuml' => "\xC3\x9C",
|
||||
'uuml' => "\xC3\xBC",
|
||||
'Uuml;' => "\xC3\x9C",
|
||||
'uuml;' => "\xC3\xBC",
|
||||
'weierp;' => "\xE2\x84\x98",
|
||||
'Xi;' => "\xCE\x9E",
|
||||
'xi;' => "\xCE\xBE",
|
||||
'Yacute' => "\xC3\x9D",
|
||||
'yacute' => "\xC3\xBD",
|
||||
'Yacute;' => "\xC3\x9D",
|
||||
'yacute;' => "\xC3\xBD",
|
||||
'yen' => "\xC2\xA5",
|
||||
'yen;' => "\xC2\xA5",
|
||||
'yuml' => "\xC3\xBF",
|
||||
'Yuml;' => "\xC5\xB8",
|
||||
'yuml;' => "\xC3\xBF",
|
||||
'Zeta;' => "\xCE\x96",
|
||||
'zeta;' => "\xCE\xB6",
|
||||
'zwj;' => "\xE2\x80\x8D",
|
||||
'zwnj;' => "\xE2\x80\x8C"
|
||||
);
|
||||
|
||||
for ($i = 0, $match = null; $i < 9 && $this->consume() !== false; $i++)
|
||||
{
|
||||
$consumed = substr($this->consumed, 1);
|
||||
if (isset($entities[$consumed]))
|
||||
{
|
||||
$match = $consumed;
|
||||
}
|
||||
}
|
||||
|
||||
if ($match !== null)
|
||||
{
|
||||
$this->data = substr_replace($this->data, $entities[$match], $this->position - strlen($consumed) - 1, strlen($match) + 1);
|
||||
$this->position += strlen($entities[$match]) - strlen($consumed) - 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
1380
Kapitel_7/Lektion_4/wordpress/wp-includes/SimplePie/Enclosure.php
Executable file
1380
Kapitel_7/Lektion_4/wordpress/wp-includes/SimplePie/Enclosure.php
Executable file
File diff suppressed because it is too large
Load Diff
52
Kapitel_7/Lektion_4/wordpress/wp-includes/SimplePie/Exception.php
Executable file
52
Kapitel_7/Lektion_4/wordpress/wp-includes/SimplePie/Exception.php
Executable file
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
/**
|
||||
* SimplePie
|
||||
*
|
||||
* A PHP-Based RSS and Atom Feed Framework.
|
||||
* Takes the hard work out of managing a complete RSS/Atom solution.
|
||||
*
|
||||
* Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* * Neither the name of the SimplePie Team nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDERS
|
||||
* AND 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.
|
||||
*
|
||||
* @package SimplePie
|
||||
* @version 1.4-dev
|
||||
* @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
|
||||
* @author Ryan Parman
|
||||
* @author Geoffrey Sneddon
|
||||
* @author Ryan McCue
|
||||
* @link http://simplepie.org/ SimplePie
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
||||
*/
|
||||
|
||||
/**
|
||||
* General SimplePie exception class
|
||||
*
|
||||
* @package SimplePie
|
||||
*/
|
||||
class SimplePie_Exception extends Exception
|
||||
{
|
||||
}
|
||||
292
Kapitel_7/Lektion_4/wordpress/wp-includes/SimplePie/File.php
Executable file
292
Kapitel_7/Lektion_4/wordpress/wp-includes/SimplePie/File.php
Executable file
@@ -0,0 +1,292 @@
|
||||
<?php
|
||||
/**
|
||||
* SimplePie
|
||||
*
|
||||
* A PHP-Based RSS and Atom Feed Framework.
|
||||
* Takes the hard work out of managing a complete RSS/Atom solution.
|
||||
*
|
||||
* Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* * Neither the name of the SimplePie Team nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDERS
|
||||
* AND 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.
|
||||
*
|
||||
* @package SimplePie
|
||||
* @version 1.3.1
|
||||
* @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
|
||||
* @author Ryan Parman
|
||||
* @author Geoffrey Sneddon
|
||||
* @author Ryan McCue
|
||||
* @link http://simplepie.org/ SimplePie
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
||||
*/
|
||||
|
||||
/**
|
||||
* Used for fetching remote files and reading local files
|
||||
*
|
||||
* Supports HTTP 1.0 via cURL or fsockopen, with spotty HTTP 1.1 support
|
||||
*
|
||||
* This class can be overloaded with {@see SimplePie::set_file_class()}
|
||||
*
|
||||
* @package SimplePie
|
||||
* @subpackage HTTP
|
||||
* @todo Move to properly supporting RFC2616 (HTTP/1.1)
|
||||
*/
|
||||
class SimplePie_File
|
||||
{
|
||||
var $url;
|
||||
var $useragent;
|
||||
var $success = true;
|
||||
var $headers = array();
|
||||
var $body;
|
||||
var $status_code;
|
||||
var $redirects = 0;
|
||||
var $error;
|
||||
var $method = SIMPLEPIE_FILE_SOURCE_NONE;
|
||||
|
||||
public function __construct($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false)
|
||||
{
|
||||
if (class_exists('idna_convert'))
|
||||
{
|
||||
$idn = new idna_convert();
|
||||
$parsed = SimplePie_Misc::parse_url($url);
|
||||
$url = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
|
||||
}
|
||||
$this->url = $url;
|
||||
$this->useragent = $useragent;
|
||||
if (preg_match('/^http(s)?:\/\//i', $url))
|
||||
{
|
||||
if ($useragent === null)
|
||||
{
|
||||
$useragent = ini_get('user_agent');
|
||||
$this->useragent = $useragent;
|
||||
}
|
||||
if (!is_array($headers))
|
||||
{
|
||||
$headers = array();
|
||||
}
|
||||
if (!$force_fsockopen && function_exists('curl_exec'))
|
||||
{
|
||||
$this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_CURL;
|
||||
$fp = curl_init();
|
||||
$headers2 = array();
|
||||
foreach ($headers as $key => $value)
|
||||
{
|
||||
$headers2[] = "$key: $value";
|
||||
}
|
||||
if (version_compare(SimplePie_Misc::get_curl_version(), '7.10.5', '>='))
|
||||
{
|
||||
curl_setopt($fp, CURLOPT_ENCODING, '');
|
||||
}
|
||||
curl_setopt($fp, CURLOPT_URL, $url);
|
||||
curl_setopt($fp, CURLOPT_HEADER, 1);
|
||||
curl_setopt($fp, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($fp, CURLOPT_TIMEOUT, $timeout);
|
||||
curl_setopt($fp, CURLOPT_CONNECTTIMEOUT, $timeout);
|
||||
curl_setopt($fp, CURLOPT_REFERER, $url);
|
||||
curl_setopt($fp, CURLOPT_USERAGENT, $useragent);
|
||||
curl_setopt($fp, CURLOPT_HTTPHEADER, $headers2);
|
||||
if (!ini_get('open_basedir') && !ini_get('safe_mode') && version_compare(SimplePie_Misc::get_curl_version(), '7.15.2', '>='))
|
||||
{
|
||||
curl_setopt($fp, CURLOPT_FOLLOWLOCATION, 1);
|
||||
curl_setopt($fp, CURLOPT_MAXREDIRS, $redirects);
|
||||
}
|
||||
|
||||
$this->headers = curl_exec($fp);
|
||||
if (curl_errno($fp) === 23 || curl_errno($fp) === 61)
|
||||
{
|
||||
curl_setopt($fp, CURLOPT_ENCODING, 'none');
|
||||
$this->headers = curl_exec($fp);
|
||||
}
|
||||
if (curl_errno($fp))
|
||||
{
|
||||
$this->error = 'cURL error ' . curl_errno($fp) . ': ' . curl_error($fp);
|
||||
$this->success = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
$info = curl_getinfo($fp);
|
||||
curl_close($fp);
|
||||
$this->headers = explode("\r\n\r\n", $this->headers, $info['redirect_count'] + 1);
|
||||
$this->headers = array_pop($this->headers);
|
||||
$parser = new SimplePie_HTTP_Parser($this->headers);
|
||||
if ($parser->parse())
|
||||
{
|
||||
$this->headers = $parser->headers;
|
||||
$this->body = $parser->body;
|
||||
$this->status_code = $parser->status_code;
|
||||
if ((in_array($this->status_code, array(300, 301, 302, 303, 307)) || $this->status_code > 307 && $this->status_code < 400) && isset($this->headers['location']) && $this->redirects < $redirects)
|
||||
{
|
||||
$this->redirects++;
|
||||
$location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
|
||||
return $this->__construct($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_FSOCKOPEN;
|
||||
$url_parts = parse_url($url);
|
||||
$socket_host = $url_parts['host'];
|
||||
if (isset($url_parts['scheme']) && strtolower($url_parts['scheme']) === 'https')
|
||||
{
|
||||
$socket_host = "ssl://$url_parts[host]";
|
||||
$url_parts['port'] = 443;
|
||||
}
|
||||
if (!isset($url_parts['port']))
|
||||
{
|
||||
$url_parts['port'] = 80;
|
||||
}
|
||||
$fp = @fsockopen($socket_host, $url_parts['port'], $errno, $errstr, $timeout);
|
||||
if (!$fp)
|
||||
{
|
||||
$this->error = 'fsockopen error: ' . $errstr;
|
||||
$this->success = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
stream_set_timeout($fp, $timeout);
|
||||
if (isset($url_parts['path']))
|
||||
{
|
||||
if (isset($url_parts['query']))
|
||||
{
|
||||
$get = "$url_parts[path]?$url_parts[query]";
|
||||
}
|
||||
else
|
||||
{
|
||||
$get = $url_parts['path'];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$get = '/';
|
||||
}
|
||||
$out = "GET $get HTTP/1.1\r\n";
|
||||
$out .= "Host: $url_parts[host]\r\n";
|
||||
$out .= "User-Agent: $useragent\r\n";
|
||||
if (extension_loaded('zlib'))
|
||||
{
|
||||
$out .= "Accept-Encoding: x-gzip,gzip,deflate\r\n";
|
||||
}
|
||||
|
||||
if (isset($url_parts['user']) && isset($url_parts['pass']))
|
||||
{
|
||||
$out .= "Authorization: Basic " . base64_encode("$url_parts[user]:$url_parts[pass]") . "\r\n";
|
||||
}
|
||||
foreach ($headers as $key => $value)
|
||||
{
|
||||
$out .= "$key: $value\r\n";
|
||||
}
|
||||
$out .= "Connection: Close\r\n\r\n";
|
||||
fwrite($fp, $out);
|
||||
|
||||
$info = stream_get_meta_data($fp);
|
||||
|
||||
$this->headers = '';
|
||||
while (!$info['eof'] && !$info['timed_out'])
|
||||
{
|
||||
$this->headers .= fread($fp, 1160);
|
||||
$info = stream_get_meta_data($fp);
|
||||
}
|
||||
if (!$info['timed_out'])
|
||||
{
|
||||
$parser = new SimplePie_HTTP_Parser($this->headers);
|
||||
if ($parser->parse())
|
||||
{
|
||||
$this->headers = $parser->headers;
|
||||
$this->body = $parser->body;
|
||||
$this->status_code = $parser->status_code;
|
||||
if ((in_array($this->status_code, array(300, 301, 302, 303, 307)) || $this->status_code > 307 && $this->status_code < 400) && isset($this->headers['location']) && $this->redirects < $redirects)
|
||||
{
|
||||
$this->redirects++;
|
||||
$location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
|
||||
return $this->__construct($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
|
||||
}
|
||||
if (isset($this->headers['content-encoding']))
|
||||
{
|
||||
// Hey, we act dumb elsewhere, so let's do that here too
|
||||
switch (strtolower(trim($this->headers['content-encoding'], "\x09\x0A\x0D\x20")))
|
||||
{
|
||||
case 'gzip':
|
||||
case 'x-gzip':
|
||||
$decoder = new SimplePie_gzdecode($this->body);
|
||||
if (!$decoder->parse())
|
||||
{
|
||||
$this->error = 'Unable to decode HTTP "gzip" stream';
|
||||
$this->success = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->body = $decoder->data;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'deflate':
|
||||
if (($decompressed = gzinflate($this->body)) !== false)
|
||||
{
|
||||
$this->body = $decompressed;
|
||||
}
|
||||
else if (($decompressed = gzuncompress($this->body)) !== false)
|
||||
{
|
||||
$this->body = $decompressed;
|
||||
}
|
||||
else if (function_exists('gzdecode') && ($decompressed = gzdecode($this->body)) !== false)
|
||||
{
|
||||
$this->body = $decompressed;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->error = 'Unable to decode HTTP "deflate" stream';
|
||||
$this->success = false;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
$this->error = 'Unknown content coding';
|
||||
$this->success = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->error = 'fsocket timed out';
|
||||
$this->success = false;
|
||||
}
|
||||
fclose($fp);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->method = SIMPLEPIE_FILE_SOURCE_LOCAL | SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS;
|
||||
if (!$this->body = file_get_contents($url))
|
||||
{
|
||||
$this->error = 'file_get_contents could not read the file';
|
||||
$this->success = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
500
Kapitel_7/Lektion_4/wordpress/wp-includes/SimplePie/HTTP/Parser.php
Executable file
500
Kapitel_7/Lektion_4/wordpress/wp-includes/SimplePie/HTTP/Parser.php
Executable file
@@ -0,0 +1,500 @@
|
||||
<?php
|
||||
/**
|
||||
* SimplePie
|
||||
*
|
||||
* A PHP-Based RSS and Atom Feed Framework.
|
||||
* Takes the hard work out of managing a complete RSS/Atom solution.
|
||||
*
|
||||
* Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* * Neither the name of the SimplePie Team nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDERS
|
||||
* AND 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.
|
||||
*
|
||||
* @package SimplePie
|
||||
* @version 1.3.1
|
||||
* @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
|
||||
* @author Ryan Parman
|
||||
* @author Geoffrey Sneddon
|
||||
* @author Ryan McCue
|
||||
* @link http://simplepie.org/ SimplePie
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* HTTP Response Parser
|
||||
*
|
||||
* @package SimplePie
|
||||
* @subpackage HTTP
|
||||
*/
|
||||
class SimplePie_HTTP_Parser
|
||||
{
|
||||
/**
|
||||
* HTTP Version
|
||||
*
|
||||
* @var float
|
||||
*/
|
||||
public $http_version = 0.0;
|
||||
|
||||
/**
|
||||
* Status code
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $status_code = 0;
|
||||
|
||||
/**
|
||||
* Reason phrase
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $reason = '';
|
||||
|
||||
/**
|
||||
* Key/value pairs of the headers
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $headers = array();
|
||||
|
||||
/**
|
||||
* Body of the response
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $body = '';
|
||||
|
||||
/**
|
||||
* Current state of the state machine
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $state = 'http_version';
|
||||
|
||||
/**
|
||||
* Input data
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $data = '';
|
||||
|
||||
/**
|
||||
* Input data length (to avoid calling strlen() everytime this is needed)
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $data_length = 0;
|
||||
|
||||
/**
|
||||
* Current position of the pointer
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $position = 0;
|
||||
|
||||
/**
|
||||
* Name of the hedaer currently being parsed
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $name = '';
|
||||
|
||||
/**
|
||||
* Value of the hedaer currently being parsed
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $value = '';
|
||||
|
||||
/**
|
||||
* Create an instance of the class with the input data
|
||||
*
|
||||
* @param string $data Input data
|
||||
*/
|
||||
public function __construct($data)
|
||||
{
|
||||
$this->data = $data;
|
||||
$this->data_length = strlen($this->data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the input data
|
||||
*
|
||||
* @return bool true on success, false on failure
|
||||
*/
|
||||
public function parse()
|
||||
{
|
||||
while ($this->state && $this->state !== 'emit' && $this->has_data())
|
||||
{
|
||||
$state = $this->state;
|
||||
$this->$state();
|
||||
}
|
||||
$this->data = '';
|
||||
if ($this->state === 'emit' || $this->state === 'body')
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->http_version = '';
|
||||
$this->status_code = '';
|
||||
$this->reason = '';
|
||||
$this->headers = array();
|
||||
$this->body = '';
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether there is data beyond the pointer
|
||||
*
|
||||
* @return bool true if there is further data, false if not
|
||||
*/
|
||||
protected function has_data()
|
||||
{
|
||||
return (bool) ($this->position < $this->data_length);
|
||||
}
|
||||
|
||||
/**
|
||||
* See if the next character is LWS
|
||||
*
|
||||
* @return bool true if the next character is LWS, false if not
|
||||
*/
|
||||
protected function is_linear_whitespace()
|
||||
{
|
||||
return (bool) ($this->data[$this->position] === "\x09"
|
||||
|| $this->data[$this->position] === "\x20"
|
||||
|| ($this->data[$this->position] === "\x0A"
|
||||
&& isset($this->data[$this->position + 1])
|
||||
&& ($this->data[$this->position + 1] === "\x09" || $this->data[$this->position + 1] === "\x20")));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the HTTP version
|
||||
*/
|
||||
protected function http_version()
|
||||
{
|
||||
if (strpos($this->data, "\x0A") !== false && strtoupper(substr($this->data, 0, 5)) === 'HTTP/')
|
||||
{
|
||||
$len = strspn($this->data, '0123456789.', 5);
|
||||
$this->http_version = substr($this->data, 5, $len);
|
||||
$this->position += 5 + $len;
|
||||
if (substr_count($this->http_version, '.') <= 1)
|
||||
{
|
||||
$this->http_version = (float) $this->http_version;
|
||||
$this->position += strspn($this->data, "\x09\x20", $this->position);
|
||||
$this->state = 'status';
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->state = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->state = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the status code
|
||||
*/
|
||||
protected function status()
|
||||
{
|
||||
if ($len = strspn($this->data, '0123456789', $this->position))
|
||||
{
|
||||
$this->status_code = (int) substr($this->data, $this->position, $len);
|
||||
$this->position += $len;
|
||||
$this->state = 'reason';
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->state = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the reason phrase
|
||||
*/
|
||||
protected function reason()
|
||||
{
|
||||
$len = strcspn($this->data, "\x0A", $this->position);
|
||||
$this->reason = trim(substr($this->data, $this->position, $len), "\x09\x0D\x20");
|
||||
$this->position += $len + 1;
|
||||
$this->state = 'new_line';
|
||||
}
|
||||
|
||||
/**
|
||||
* Deal with a new line, shifting data around as needed
|
||||
*/
|
||||
protected function new_line()
|
||||
{
|
||||
$this->value = trim($this->value, "\x0D\x20");
|
||||
if ($this->name !== '' && $this->value !== '')
|
||||
{
|
||||
$this->name = strtolower($this->name);
|
||||
// We should only use the last Content-Type header. c.f. issue #1
|
||||
if (isset($this->headers[$this->name]) && $this->name !== 'content-type')
|
||||
{
|
||||
$this->headers[$this->name] .= ', ' . $this->value;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->headers[$this->name] = $this->value;
|
||||
}
|
||||
}
|
||||
$this->name = '';
|
||||
$this->value = '';
|
||||
if (substr($this->data[$this->position], 0, 2) === "\x0D\x0A")
|
||||
{
|
||||
$this->position += 2;
|
||||
$this->state = 'body';
|
||||
}
|
||||
elseif ($this->data[$this->position] === "\x0A")
|
||||
{
|
||||
$this->position++;
|
||||
$this->state = 'body';
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->state = 'name';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a header name
|
||||
*/
|
||||
protected function name()
|
||||
{
|
||||
$len = strcspn($this->data, "\x0A:", $this->position);
|
||||
if (isset($this->data[$this->position + $len]))
|
||||
{
|
||||
if ($this->data[$this->position + $len] === "\x0A")
|
||||
{
|
||||
$this->position += $len;
|
||||
$this->state = 'new_line';
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->name = substr($this->data, $this->position, $len);
|
||||
$this->position += $len + 1;
|
||||
$this->state = 'value';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->state = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse LWS, replacing consecutive LWS characters with a single space
|
||||
*/
|
||||
protected function linear_whitespace()
|
||||
{
|
||||
do
|
||||
{
|
||||
if (substr($this->data, $this->position, 2) === "\x0D\x0A")
|
||||
{
|
||||
$this->position += 2;
|
||||
}
|
||||
elseif ($this->data[$this->position] === "\x0A")
|
||||
{
|
||||
$this->position++;
|
||||
}
|
||||
$this->position += strspn($this->data, "\x09\x20", $this->position);
|
||||
} while ($this->has_data() && $this->is_linear_whitespace());
|
||||
$this->value .= "\x20";
|
||||
}
|
||||
|
||||
/**
|
||||
* See what state to move to while within non-quoted header values
|
||||
*/
|
||||
protected function value()
|
||||
{
|
||||
if ($this->is_linear_whitespace())
|
||||
{
|
||||
$this->linear_whitespace();
|
||||
}
|
||||
else
|
||||
{
|
||||
switch ($this->data[$this->position])
|
||||
{
|
||||
case '"':
|
||||
// Workaround for ETags: we have to include the quotes as
|
||||
// part of the tag.
|
||||
if (strtolower($this->name) === 'etag')
|
||||
{
|
||||
$this->value .= '"';
|
||||
$this->position++;
|
||||
$this->state = 'value_char';
|
||||
break;
|
||||
}
|
||||
$this->position++;
|
||||
$this->state = 'quote';
|
||||
break;
|
||||
|
||||
case "\x0A":
|
||||
$this->position++;
|
||||
$this->state = 'new_line';
|
||||
break;
|
||||
|
||||
default:
|
||||
$this->state = 'value_char';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a header value while outside quotes
|
||||
*/
|
||||
protected function value_char()
|
||||
{
|
||||
$len = strcspn($this->data, "\x09\x20\x0A\"", $this->position);
|
||||
$this->value .= substr($this->data, $this->position, $len);
|
||||
$this->position += $len;
|
||||
$this->state = 'value';
|
||||
}
|
||||
|
||||
/**
|
||||
* See what state to move to while within quoted header values
|
||||
*/
|
||||
protected function quote()
|
||||
{
|
||||
if ($this->is_linear_whitespace())
|
||||
{
|
||||
$this->linear_whitespace();
|
||||
}
|
||||
else
|
||||
{
|
||||
switch ($this->data[$this->position])
|
||||
{
|
||||
case '"':
|
||||
$this->position++;
|
||||
$this->state = 'value';
|
||||
break;
|
||||
|
||||
case "\x0A":
|
||||
$this->position++;
|
||||
$this->state = 'new_line';
|
||||
break;
|
||||
|
||||
case '\\':
|
||||
$this->position++;
|
||||
$this->state = 'quote_escaped';
|
||||
break;
|
||||
|
||||
default:
|
||||
$this->state = 'quote_char';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a header value while within quotes
|
||||
*/
|
||||
protected function quote_char()
|
||||
{
|
||||
$len = strcspn($this->data, "\x09\x20\x0A\"\\", $this->position);
|
||||
$this->value .= substr($this->data, $this->position, $len);
|
||||
$this->position += $len;
|
||||
$this->state = 'value';
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse an escaped character within quotes
|
||||
*/
|
||||
protected function quote_escaped()
|
||||
{
|
||||
$this->value .= $this->data[$this->position];
|
||||
$this->position++;
|
||||
$this->state = 'quote';
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the body
|
||||
*/
|
||||
protected function body()
|
||||
{
|
||||
$this->body = substr($this->data, $this->position);
|
||||
if (!empty($this->headers['transfer-encoding']))
|
||||
{
|
||||
unset($this->headers['transfer-encoding']);
|
||||
$this->state = 'chunked';
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->state = 'emit';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parsed a "Transfer-Encoding: chunked" body
|
||||
*/
|
||||
protected function chunked()
|
||||
{
|
||||
if (!preg_match('/^([0-9a-f]+)[^\r\n]*\r\n/i', trim($this->body)))
|
||||
{
|
||||
$this->state = 'emit';
|
||||
return;
|
||||
}
|
||||
|
||||
$decoded = '';
|
||||
$encoded = $this->body;
|
||||
|
||||
while (true)
|
||||
{
|
||||
$is_chunked = (bool) preg_match( '/^([0-9a-f]+)[^\r\n]*\r\n/i', $encoded, $matches );
|
||||
if (!$is_chunked)
|
||||
{
|
||||
// Looks like it's not chunked after all
|
||||
$this->state = 'emit';
|
||||
return;
|
||||
}
|
||||
|
||||
$length = hexdec(trim($matches[1]));
|
||||
if ($length === 0)
|
||||
{
|
||||
// Ignore trailer headers
|
||||
$this->state = 'emit';
|
||||
$this->body = $decoded;
|
||||
return;
|
||||
}
|
||||
|
||||
$chunk_length = strlen($matches[0]);
|
||||
$decoded .= $part = substr($encoded, $chunk_length, $length);
|
||||
$encoded = substr($encoded, $chunk_length + $length + 2);
|
||||
|
||||
if (trim($encoded) === '0' || empty($encoded))
|
||||
{
|
||||
$this->state = 'emit';
|
||||
$this->body = $decoded;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
1238
Kapitel_7/Lektion_4/wordpress/wp-includes/SimplePie/IRI.php
Executable file
1238
Kapitel_7/Lektion_4/wordpress/wp-includes/SimplePie/IRI.php
Executable file
File diff suppressed because it is too large
Load Diff
2964
Kapitel_7/Lektion_4/wordpress/wp-includes/SimplePie/Item.php
Executable file
2964
Kapitel_7/Lektion_4/wordpress/wp-includes/SimplePie/Item.php
Executable file
File diff suppressed because it is too large
Load Diff
372
Kapitel_7/Lektion_4/wordpress/wp-includes/SimplePie/Locator.php
Executable file
372
Kapitel_7/Lektion_4/wordpress/wp-includes/SimplePie/Locator.php
Executable file
@@ -0,0 +1,372 @@
|
||||
<?php
|
||||
/**
|
||||
* SimplePie
|
||||
*
|
||||
* A PHP-Based RSS and Atom Feed Framework.
|
||||
* Takes the hard work out of managing a complete RSS/Atom solution.
|
||||
*
|
||||
* Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* * Neither the name of the SimplePie Team nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDERS
|
||||
* AND 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.
|
||||
*
|
||||
* @package SimplePie
|
||||
* @version 1.3.1
|
||||
* @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
|
||||
* @author Ryan Parman
|
||||
* @author Geoffrey Sneddon
|
||||
* @author Ryan McCue
|
||||
* @link http://simplepie.org/ SimplePie
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
||||
*/
|
||||
|
||||
/**
|
||||
* Used for feed auto-discovery
|
||||
*
|
||||
*
|
||||
* This class can be overloaded with {@see SimplePie::set_locator_class()}
|
||||
*
|
||||
* @package SimplePie
|
||||
*/
|
||||
class SimplePie_Locator
|
||||
{
|
||||
var $useragent;
|
||||
var $timeout;
|
||||
var $file;
|
||||
var $local = array();
|
||||
var $elsewhere = array();
|
||||
var $cached_entities = array();
|
||||
var $http_base;
|
||||
var $base;
|
||||
var $base_location = 0;
|
||||
var $checked_feeds = 0;
|
||||
var $max_checked_feeds = 10;
|
||||
protected $registry;
|
||||
|
||||
public function __construct(SimplePie_File $file, $timeout = 10, $useragent = null, $max_checked_feeds = 10)
|
||||
{
|
||||
$this->file = $file;
|
||||
$this->useragent = $useragent;
|
||||
$this->timeout = $timeout;
|
||||
$this->max_checked_feeds = $max_checked_feeds;
|
||||
|
||||
if (class_exists('DOMDocument'))
|
||||
{
|
||||
$this->dom = new DOMDocument();
|
||||
|
||||
set_error_handler(array('SimplePie_Misc', 'silence_errors'));
|
||||
$this->dom->loadHTML($this->file->body);
|
||||
restore_error_handler();
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->dom = null;
|
||||
}
|
||||
}
|
||||
|
||||
public function set_registry(SimplePie_Registry $registry)
|
||||
{
|
||||
$this->registry = $registry;
|
||||
}
|
||||
|
||||
public function find($type = SIMPLEPIE_LOCATOR_ALL, &$working)
|
||||
{
|
||||
if ($this->is_feed($this->file))
|
||||
{
|
||||
return $this->file;
|
||||
}
|
||||
|
||||
if ($this->file->method & SIMPLEPIE_FILE_SOURCE_REMOTE)
|
||||
{
|
||||
$sniffer = $this->registry->create('Content_Type_Sniffer', array($this->file));
|
||||
if ($sniffer->get_type() !== 'text/html')
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
if ($type & ~SIMPLEPIE_LOCATOR_NONE)
|
||||
{
|
||||
$this->get_base();
|
||||
}
|
||||
|
||||
if ($type & SIMPLEPIE_LOCATOR_AUTODISCOVERY && $working = $this->autodiscovery())
|
||||
{
|
||||
return $working[0];
|
||||
}
|
||||
|
||||
if ($type & (SIMPLEPIE_LOCATOR_LOCAL_EXTENSION | SIMPLEPIE_LOCATOR_LOCAL_BODY | SIMPLEPIE_LOCATOR_REMOTE_EXTENSION | SIMPLEPIE_LOCATOR_REMOTE_BODY) && $this->get_links())
|
||||
{
|
||||
if ($type & SIMPLEPIE_LOCATOR_LOCAL_EXTENSION && $working = $this->extension($this->local))
|
||||
{
|
||||
return $working;
|
||||
}
|
||||
|
||||
if ($type & SIMPLEPIE_LOCATOR_LOCAL_BODY && $working = $this->body($this->local))
|
||||
{
|
||||
return $working;
|
||||
}
|
||||
|
||||
if ($type & SIMPLEPIE_LOCATOR_REMOTE_EXTENSION && $working = $this->extension($this->elsewhere))
|
||||
{
|
||||
return $working;
|
||||
}
|
||||
|
||||
if ($type & SIMPLEPIE_LOCATOR_REMOTE_BODY && $working = $this->body($this->elsewhere))
|
||||
{
|
||||
return $working;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function is_feed($file)
|
||||
{
|
||||
if ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE)
|
||||
{
|
||||
$sniffer = $this->registry->create('Content_Type_Sniffer', array($file));
|
||||
$sniffed = $sniffer->get_type();
|
||||
if (in_array($sniffed, array('application/rss+xml', 'application/rdf+xml', 'text/rdf', 'application/atom+xml', 'text/xml', 'application/xml')))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
elseif ($file->method & SIMPLEPIE_FILE_SOURCE_LOCAL)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_base()
|
||||
{
|
||||
if ($this->dom === null)
|
||||
{
|
||||
throw new SimplePie_Exception('DOMDocument not found, unable to use locator');
|
||||
}
|
||||
$this->http_base = $this->file->url;
|
||||
$this->base = $this->http_base;
|
||||
$elements = $this->dom->getElementsByTagName('base');
|
||||
foreach ($elements as $element)
|
||||
{
|
||||
if ($element->hasAttribute('href'))
|
||||
{
|
||||
$base = $this->registry->call('Misc', 'absolutize_url', array(trim($element->getAttribute('href')), $this->http_base));
|
||||
if ($base === false)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
$this->base = $base;
|
||||
$this->base_location = method_exists($element, 'getLineNo') ? $element->getLineNo() : 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function autodiscovery()
|
||||
{
|
||||
$done = array();
|
||||
$feeds = array();
|
||||
$feeds = array_merge($feeds, $this->search_elements_by_tag('link', $done, $feeds));
|
||||
$feeds = array_merge($feeds, $this->search_elements_by_tag('a', $done, $feeds));
|
||||
$feeds = array_merge($feeds, $this->search_elements_by_tag('area', $done, $feeds));
|
||||
|
||||
if (!empty($feeds))
|
||||
{
|
||||
return array_values($feeds);
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
protected function search_elements_by_tag($name, &$done, $feeds)
|
||||
{
|
||||
if ($this->dom === null)
|
||||
{
|
||||
throw new SimplePie_Exception('DOMDocument not found, unable to use locator');
|
||||
}
|
||||
|
||||
$links = $this->dom->getElementsByTagName($name);
|
||||
foreach ($links as $link)
|
||||
{
|
||||
if ($this->checked_feeds === $this->max_checked_feeds)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if ($link->hasAttribute('href') && $link->hasAttribute('rel'))
|
||||
{
|
||||
$rel = array_unique($this->registry->call('Misc', 'space_seperated_tokens', array(strtolower($link->getAttribute('rel')))));
|
||||
$line = method_exists($link, 'getLineNo') ? $link->getLineNo() : 1;
|
||||
|
||||
if ($this->base_location < $line)
|
||||
{
|
||||
$href = $this->registry->call('Misc', 'absolutize_url', array(trim($link->getAttribute('href')), $this->base));
|
||||
}
|
||||
else
|
||||
{
|
||||
$href = $this->registry->call('Misc', 'absolutize_url', array(trim($link->getAttribute('href')), $this->http_base));
|
||||
}
|
||||
if ($href === false)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!in_array($href, $done) && in_array('feed', $rel) || (in_array('alternate', $rel) && !in_array('stylesheet', $rel) && $link->hasAttribute('type') && in_array(strtolower($this->registry->call('Misc', 'parse_mime', array($link->getAttribute('type')))), array('application/rss+xml', 'application/atom+xml'))) && !isset($feeds[$href]))
|
||||
{
|
||||
$this->checked_feeds++;
|
||||
$headers = array(
|
||||
'Accept' => 'application/atom+xml, application/rss+xml, application/rdf+xml;q=0.9, application/xml;q=0.8, text/xml;q=0.8, text/html;q=0.7, unknown/unknown;q=0.1, application/unknown;q=0.1, */*;q=0.1',
|
||||
);
|
||||
$feed = $this->registry->create('File', array($href, $this->timeout, 5, $headers, $this->useragent));
|
||||
if ($feed->success && ($feed->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($feed->status_code === 200 || $feed->status_code > 206 && $feed->status_code < 300)) && $this->is_feed($feed))
|
||||
{
|
||||
$feeds[$href] = $feed;
|
||||
}
|
||||
}
|
||||
$done[] = $href;
|
||||
}
|
||||
}
|
||||
|
||||
return $feeds;
|
||||
}
|
||||
|
||||
public function get_links()
|
||||
{
|
||||
if ($this->dom === null)
|
||||
{
|
||||
throw new SimplePie_Exception('DOMDocument not found, unable to use locator');
|
||||
}
|
||||
|
||||
$links = $this->dom->getElementsByTagName('a');
|
||||
foreach ($links as $link)
|
||||
{
|
||||
if ($link->hasAttribute('href'))
|
||||
{
|
||||
$href = trim($link->getAttribute('href'));
|
||||
$parsed = $this->registry->call('Misc', 'parse_url', array($href));
|
||||
if ($parsed['scheme'] === '' || preg_match('/^(http(s)|feed)?$/i', $parsed['scheme']))
|
||||
{
|
||||
if (method_exists($link, 'getLineNo') && $this->base_location < $link->getLineNo())
|
||||
{
|
||||
$href = $this->registry->call('Misc', 'absolutize_url', array(trim($link->getAttribute('href')), $this->base));
|
||||
}
|
||||
else
|
||||
{
|
||||
$href = $this->registry->call('Misc', 'absolutize_url', array(trim($link->getAttribute('href')), $this->http_base));
|
||||
}
|
||||
if ($href === false)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$current = $this->registry->call('Misc', 'parse_url', array($this->file->url));
|
||||
|
||||
if ($parsed['authority'] === '' || $parsed['authority'] === $current['authority'])
|
||||
{
|
||||
$this->local[] = $href;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->elsewhere[] = $href;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->local = array_unique($this->local);
|
||||
$this->elsewhere = array_unique($this->elsewhere);
|
||||
if (!empty($this->local) || !empty($this->elsewhere))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function extension(&$array)
|
||||
{
|
||||
foreach ($array as $key => $value)
|
||||
{
|
||||
if ($this->checked_feeds === $this->max_checked_feeds)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (in_array(strtolower(strrchr($value, '.')), array('.rss', '.rdf', '.atom', '.xml')))
|
||||
{
|
||||
$this->checked_feeds++;
|
||||
|
||||
$headers = array(
|
||||
'Accept' => 'application/atom+xml, application/rss+xml, application/rdf+xml;q=0.9, application/xml;q=0.8, text/xml;q=0.8, text/html;q=0.7, unknown/unknown;q=0.1, application/unknown;q=0.1, */*;q=0.1',
|
||||
);
|
||||
$feed = $this->registry->create('File', array($value, $this->timeout, 5, $headers, $this->useragent));
|
||||
if ($feed->success && ($feed->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($feed->status_code === 200 || $feed->status_code > 206 && $feed->status_code < 300)) && $this->is_feed($feed))
|
||||
{
|
||||
return $feed;
|
||||
}
|
||||
else
|
||||
{
|
||||
unset($array[$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function body(&$array)
|
||||
{
|
||||
foreach ($array as $key => $value)
|
||||
{
|
||||
if ($this->checked_feeds === $this->max_checked_feeds)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (preg_match('/(rss|rdf|atom|xml)/i', $value))
|
||||
{
|
||||
$this->checked_feeds++;
|
||||
$headers = array(
|
||||
'Accept' => 'application/atom+xml, application/rss+xml, application/rdf+xml;q=0.9, application/xml;q=0.8, text/xml;q=0.8, text/html;q=0.7, unknown/unknown;q=0.1, application/unknown;q=0.1, */*;q=0.1',
|
||||
);
|
||||
$feed = $this->registry->create('File', array($value, $this->timeout, 5, null, $this->useragent));
|
||||
if ($feed->success && ($feed->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($feed->status_code === 200 || $feed->status_code > 206 && $feed->status_code < 300)) && $this->is_feed($feed))
|
||||
{
|
||||
return $feed;
|
||||
}
|
||||
else
|
||||
{
|
||||
unset($array[$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
2247
Kapitel_7/Lektion_4/wordpress/wp-includes/SimplePie/Misc.php
Executable file
2247
Kapitel_7/Lektion_4/wordpress/wp-includes/SimplePie/Misc.php
Executable file
File diff suppressed because it is too large
Load Diff
276
Kapitel_7/Lektion_4/wordpress/wp-includes/SimplePie/Net/IPv6.php
Executable file
276
Kapitel_7/Lektion_4/wordpress/wp-includes/SimplePie/Net/IPv6.php
Executable file
@@ -0,0 +1,276 @@
|
||||
<?php
|
||||
/**
|
||||
* SimplePie
|
||||
*
|
||||
* A PHP-Based RSS and Atom Feed Framework.
|
||||
* Takes the hard work out of managing a complete RSS/Atom solution.
|
||||
*
|
||||
* Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* * Neither the name of the SimplePie Team nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDERS
|
||||
* AND 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.
|
||||
*
|
||||
* @package SimplePie
|
||||
* @version 1.3.1
|
||||
* @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
|
||||
* @author Ryan Parman
|
||||
* @author Geoffrey Sneddon
|
||||
* @author Ryan McCue
|
||||
* @link http://simplepie.org/ SimplePie
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Class to validate and to work with IPv6 addresses.
|
||||
*
|
||||
* @package SimplePie
|
||||
* @subpackage HTTP
|
||||
* @copyright 2003-2005 The PHP Group
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php
|
||||
* @link http://pear.php.net/package/Net_IPv6
|
||||
* @author Alexander Merz <alexander.merz@web.de>
|
||||
* @author elfrink at introweb dot nl
|
||||
* @author Josh Peck <jmp at joshpeck dot org>
|
||||
* @author Geoffrey Sneddon <geoffers@gmail.com>
|
||||
*/
|
||||
class SimplePie_Net_IPv6
|
||||
{
|
||||
/**
|
||||
* Uncompresses an IPv6 address
|
||||
*
|
||||
* RFC 4291 allows you to compress concecutive zero pieces in an address to
|
||||
* '::'. This method expects a valid IPv6 address and expands the '::' to
|
||||
* the required number of zero pieces.
|
||||
*
|
||||
* Example: FF01::101 -> FF01:0:0:0:0:0:0:101
|
||||
* ::1 -> 0:0:0:0:0:0:0:1
|
||||
*
|
||||
* @author Alexander Merz <alexander.merz@web.de>
|
||||
* @author elfrink at introweb dot nl
|
||||
* @author Josh Peck <jmp at joshpeck dot org>
|
||||
* @copyright 2003-2005 The PHP Group
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php
|
||||
* @param string $ip An IPv6 address
|
||||
* @return string The uncompressed IPv6 address
|
||||
*/
|
||||
public static function uncompress($ip)
|
||||
{
|
||||
$c1 = -1;
|
||||
$c2 = -1;
|
||||
if (substr_count($ip, '::') === 1)
|
||||
{
|
||||
list($ip1, $ip2) = explode('::', $ip);
|
||||
if ($ip1 === '')
|
||||
{
|
||||
$c1 = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
$c1 = substr_count($ip1, ':');
|
||||
}
|
||||
if ($ip2 === '')
|
||||
{
|
||||
$c2 = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
$c2 = substr_count($ip2, ':');
|
||||
}
|
||||
if (strpos($ip2, '.') !== false)
|
||||
{
|
||||
$c2++;
|
||||
}
|
||||
// ::
|
||||
if ($c1 === -1 && $c2 === -1)
|
||||
{
|
||||
$ip = '0:0:0:0:0:0:0:0';
|
||||
}
|
||||
// ::xxx
|
||||
else if ($c1 === -1)
|
||||
{
|
||||
$fill = str_repeat('0:', 7 - $c2);
|
||||
$ip = str_replace('::', $fill, $ip);
|
||||
}
|
||||
// xxx::
|
||||
else if ($c2 === -1)
|
||||
{
|
||||
$fill = str_repeat(':0', 7 - $c1);
|
||||
$ip = str_replace('::', $fill, $ip);
|
||||
}
|
||||
// xxx::xxx
|
||||
else
|
||||
{
|
||||
$fill = ':' . str_repeat('0:', 6 - $c2 - $c1);
|
||||
$ip = str_replace('::', $fill, $ip);
|
||||
}
|
||||
}
|
||||
return $ip;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compresses an IPv6 address
|
||||
*
|
||||
* RFC 4291 allows you to compress concecutive zero pieces in an address to
|
||||
* '::'. This method expects a valid IPv6 address and compresses consecutive
|
||||
* zero pieces to '::'.
|
||||
*
|
||||
* Example: FF01:0:0:0:0:0:0:101 -> FF01::101
|
||||
* 0:0:0:0:0:0:0:1 -> ::1
|
||||
*
|
||||
* @see uncompress()
|
||||
* @param string $ip An IPv6 address
|
||||
* @return string The compressed IPv6 address
|
||||
*/
|
||||
public static function compress($ip)
|
||||
{
|
||||
// Prepare the IP to be compressed
|
||||
$ip = self::uncompress($ip);
|
||||
$ip_parts = self::split_v6_v4($ip);
|
||||
|
||||
// Replace all leading zeros
|
||||
$ip_parts[0] = preg_replace('/(^|:)0+([0-9])/', '\1\2', $ip_parts[0]);
|
||||
|
||||
// Find bunches of zeros
|
||||
if (preg_match_all('/(?:^|:)(?:0(?::|$))+/', $ip_parts[0], $matches, PREG_OFFSET_CAPTURE))
|
||||
{
|
||||
$max = 0;
|
||||
$pos = null;
|
||||
foreach ($matches[0] as $match)
|
||||
{
|
||||
if (strlen($match[0]) > $max)
|
||||
{
|
||||
$max = strlen($match[0]);
|
||||
$pos = $match[1];
|
||||
}
|
||||
}
|
||||
|
||||
$ip_parts[0] = substr_replace($ip_parts[0], '::', $pos, $max);
|
||||
}
|
||||
|
||||
if ($ip_parts[1] !== '')
|
||||
{
|
||||
return implode(':', $ip_parts);
|
||||
}
|
||||
else
|
||||
{
|
||||
return $ip_parts[0];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Splits an IPv6 address into the IPv6 and IPv4 representation parts
|
||||
*
|
||||
* RFC 4291 allows you to represent the last two parts of an IPv6 address
|
||||
* using the standard IPv4 representation
|
||||
*
|
||||
* Example: 0:0:0:0:0:0:13.1.68.3
|
||||
* 0:0:0:0:0:FFFF:129.144.52.38
|
||||
*
|
||||
* @param string $ip An IPv6 address
|
||||
* @return array [0] contains the IPv6 represented part, and [1] the IPv4 represented part
|
||||
*/
|
||||
private static function split_v6_v4($ip)
|
||||
{
|
||||
if (strpos($ip, '.') !== false)
|
||||
{
|
||||
$pos = strrpos($ip, ':');
|
||||
$ipv6_part = substr($ip, 0, $pos);
|
||||
$ipv4_part = substr($ip, $pos + 1);
|
||||
return array($ipv6_part, $ipv4_part);
|
||||
}
|
||||
else
|
||||
{
|
||||
return array($ip, '');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks an IPv6 address
|
||||
*
|
||||
* Checks if the given IP is a valid IPv6 address
|
||||
*
|
||||
* @param string $ip An IPv6 address
|
||||
* @return bool true if $ip is a valid IPv6 address
|
||||
*/
|
||||
public static function check_ipv6($ip)
|
||||
{
|
||||
$ip = self::uncompress($ip);
|
||||
list($ipv6, $ipv4) = self::split_v6_v4($ip);
|
||||
$ipv6 = explode(':', $ipv6);
|
||||
$ipv4 = explode('.', $ipv4);
|
||||
if (count($ipv6) === 8 && count($ipv4) === 1 || count($ipv6) === 6 && count($ipv4) === 4)
|
||||
{
|
||||
foreach ($ipv6 as $ipv6_part)
|
||||
{
|
||||
// The section can't be empty
|
||||
if ($ipv6_part === '')
|
||||
return false;
|
||||
|
||||
// Nor can it be over four characters
|
||||
if (strlen($ipv6_part) > 4)
|
||||
return false;
|
||||
|
||||
// Remove leading zeros (this is safe because of the above)
|
||||
$ipv6_part = ltrim($ipv6_part, '0');
|
||||
if ($ipv6_part === '')
|
||||
$ipv6_part = '0';
|
||||
|
||||
// Check the value is valid
|
||||
$value = hexdec($ipv6_part);
|
||||
if (dechex($value) !== strtolower($ipv6_part) || $value < 0 || $value > 0xFFFF)
|
||||
return false;
|
||||
}
|
||||
if (count($ipv4) === 4)
|
||||
{
|
||||
foreach ($ipv4 as $ipv4_part)
|
||||
{
|
||||
$value = (int) $ipv4_part;
|
||||
if ((string) $value !== $ipv4_part || $value < 0 || $value > 0xFF)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given IP is a valid IPv6 address
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @deprecated Use {@see SimplePie_Net_IPv6::check_ipv6()} instead
|
||||
* @see check_ipv6
|
||||
* @param string $ip An IPv6 address
|
||||
* @return bool true if $ip is a valid IPv6 address
|
||||
*/
|
||||
public static function checkIPv6($ip)
|
||||
{
|
||||
return self::check_ipv6($ip);
|
||||
}
|
||||
}
|
||||
984
Kapitel_7/Lektion_4/wordpress/wp-includes/SimplePie/Parse/Date.php
Executable file
984
Kapitel_7/Lektion_4/wordpress/wp-includes/SimplePie/Parse/Date.php
Executable file
@@ -0,0 +1,984 @@
|
||||
<?php
|
||||
/**
|
||||
* SimplePie
|
||||
*
|
||||
* A PHP-Based RSS and Atom Feed Framework.
|
||||
* Takes the hard work out of managing a complete RSS/Atom solution.
|
||||
*
|
||||
* Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* * Neither the name of the SimplePie Team nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDERS
|
||||
* AND 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.
|
||||
*
|
||||
* @package SimplePie
|
||||
* @version 1.3.1
|
||||
* @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
|
||||
* @author Ryan Parman
|
||||
* @author Geoffrey Sneddon
|
||||
* @author Ryan McCue
|
||||
* @link http://simplepie.org/ SimplePie
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Date Parser
|
||||
*
|
||||
* @package SimplePie
|
||||
* @subpackage Parsing
|
||||
*/
|
||||
class SimplePie_Parse_Date
|
||||
{
|
||||
/**
|
||||
* Input data
|
||||
*
|
||||
* @access protected
|
||||
* @var string
|
||||
*/
|
||||
var $date;
|
||||
|
||||
/**
|
||||
* List of days, calendar day name => ordinal day number in the week
|
||||
*
|
||||
* @access protected
|
||||
* @var array
|
||||
*/
|
||||
var $day = array(
|
||||
// English
|
||||
'mon' => 1,
|
||||
'monday' => 1,
|
||||
'tue' => 2,
|
||||
'tuesday' => 2,
|
||||
'wed' => 3,
|
||||
'wednesday' => 3,
|
||||
'thu' => 4,
|
||||
'thursday' => 4,
|
||||
'fri' => 5,
|
||||
'friday' => 5,
|
||||
'sat' => 6,
|
||||
'saturday' => 6,
|
||||
'sun' => 7,
|
||||
'sunday' => 7,
|
||||
// Dutch
|
||||
'maandag' => 1,
|
||||
'dinsdag' => 2,
|
||||
'woensdag' => 3,
|
||||
'donderdag' => 4,
|
||||
'vrijdag' => 5,
|
||||
'zaterdag' => 6,
|
||||
'zondag' => 7,
|
||||
// French
|
||||
'lundi' => 1,
|
||||
'mardi' => 2,
|
||||
'mercredi' => 3,
|
||||
'jeudi' => 4,
|
||||
'vendredi' => 5,
|
||||
'samedi' => 6,
|
||||
'dimanche' => 7,
|
||||
// German
|
||||
'montag' => 1,
|
||||
'dienstag' => 2,
|
||||
'mittwoch' => 3,
|
||||
'donnerstag' => 4,
|
||||
'freitag' => 5,
|
||||
'samstag' => 6,
|
||||
'sonnabend' => 6,
|
||||
'sonntag' => 7,
|
||||
// Italian
|
||||
'lunedì' => 1,
|
||||
'martedì' => 2,
|
||||
'mercoledì' => 3,
|
||||
'giovedì' => 4,
|
||||
'venerdì' => 5,
|
||||
'sabato' => 6,
|
||||
'domenica' => 7,
|
||||
// Spanish
|
||||
'lunes' => 1,
|
||||
'martes' => 2,
|
||||
'miércoles' => 3,
|
||||
'jueves' => 4,
|
||||
'viernes' => 5,
|
||||
'sábado' => 6,
|
||||
'domingo' => 7,
|
||||
// Finnish
|
||||
'maanantai' => 1,
|
||||
'tiistai' => 2,
|
||||
'keskiviikko' => 3,
|
||||
'torstai' => 4,
|
||||
'perjantai' => 5,
|
||||
'lauantai' => 6,
|
||||
'sunnuntai' => 7,
|
||||
// Hungarian
|
||||
'hétfő' => 1,
|
||||
'kedd' => 2,
|
||||
'szerda' => 3,
|
||||
'csütörtok' => 4,
|
||||
'péntek' => 5,
|
||||
'szombat' => 6,
|
||||
'vasárnap' => 7,
|
||||
// Greek
|
||||
'Δευ' => 1,
|
||||
'Τρι' => 2,
|
||||
'Τετ' => 3,
|
||||
'Πεμ' => 4,
|
||||
'Παρ' => 5,
|
||||
'Σαβ' => 6,
|
||||
'Κυρ' => 7,
|
||||
);
|
||||
|
||||
/**
|
||||
* List of months, calendar month name => calendar month number
|
||||
*
|
||||
* @access protected
|
||||
* @var array
|
||||
*/
|
||||
var $month = array(
|
||||
// English
|
||||
'jan' => 1,
|
||||
'january' => 1,
|
||||
'feb' => 2,
|
||||
'february' => 2,
|
||||
'mar' => 3,
|
||||
'march' => 3,
|
||||
'apr' => 4,
|
||||
'april' => 4,
|
||||
'may' => 5,
|
||||
// No long form of May
|
||||
'jun' => 6,
|
||||
'june' => 6,
|
||||
'jul' => 7,
|
||||
'july' => 7,
|
||||
'aug' => 8,
|
||||
'august' => 8,
|
||||
'sep' => 9,
|
||||
'september' => 8,
|
||||
'oct' => 10,
|
||||
'october' => 10,
|
||||
'nov' => 11,
|
||||
'november' => 11,
|
||||
'dec' => 12,
|
||||
'december' => 12,
|
||||
// Dutch
|
||||
'januari' => 1,
|
||||
'februari' => 2,
|
||||
'maart' => 3,
|
||||
'april' => 4,
|
||||
'mei' => 5,
|
||||
'juni' => 6,
|
||||
'juli' => 7,
|
||||
'augustus' => 8,
|
||||
'september' => 9,
|
||||
'oktober' => 10,
|
||||
'november' => 11,
|
||||
'december' => 12,
|
||||
// French
|
||||
'janvier' => 1,
|
||||
'février' => 2,
|
||||
'mars' => 3,
|
||||
'avril' => 4,
|
||||
'mai' => 5,
|
||||
'juin' => 6,
|
||||
'juillet' => 7,
|
||||
'août' => 8,
|
||||
'septembre' => 9,
|
||||
'octobre' => 10,
|
||||
'novembre' => 11,
|
||||
'décembre' => 12,
|
||||
// German
|
||||
'januar' => 1,
|
||||
'februar' => 2,
|
||||
'märz' => 3,
|
||||
'april' => 4,
|
||||
'mai' => 5,
|
||||
'juni' => 6,
|
||||
'juli' => 7,
|
||||
'august' => 8,
|
||||
'september' => 9,
|
||||
'oktober' => 10,
|
||||
'november' => 11,
|
||||
'dezember' => 12,
|
||||
// Italian
|
||||
'gennaio' => 1,
|
||||
'febbraio' => 2,
|
||||
'marzo' => 3,
|
||||
'aprile' => 4,
|
||||
'maggio' => 5,
|
||||
'giugno' => 6,
|
||||
'luglio' => 7,
|
||||
'agosto' => 8,
|
||||
'settembre' => 9,
|
||||
'ottobre' => 10,
|
||||
'novembre' => 11,
|
||||
'dicembre' => 12,
|
||||
// Spanish
|
||||
'enero' => 1,
|
||||
'febrero' => 2,
|
||||
'marzo' => 3,
|
||||
'abril' => 4,
|
||||
'mayo' => 5,
|
||||
'junio' => 6,
|
||||
'julio' => 7,
|
||||
'agosto' => 8,
|
||||
'septiembre' => 9,
|
||||
'setiembre' => 9,
|
||||
'octubre' => 10,
|
||||
'noviembre' => 11,
|
||||
'diciembre' => 12,
|
||||
// Finnish
|
||||
'tammikuu' => 1,
|
||||
'helmikuu' => 2,
|
||||
'maaliskuu' => 3,
|
||||
'huhtikuu' => 4,
|
||||
'toukokuu' => 5,
|
||||
'kesäkuu' => 6,
|
||||
'heinäkuu' => 7,
|
||||
'elokuu' => 8,
|
||||
'suuskuu' => 9,
|
||||
'lokakuu' => 10,
|
||||
'marras' => 11,
|
||||
'joulukuu' => 12,
|
||||
// Hungarian
|
||||
'január' => 1,
|
||||
'február' => 2,
|
||||
'március' => 3,
|
||||
'április' => 4,
|
||||
'május' => 5,
|
||||
'június' => 6,
|
||||
'július' => 7,
|
||||
'augusztus' => 8,
|
||||
'szeptember' => 9,
|
||||
'október' => 10,
|
||||
'november' => 11,
|
||||
'december' => 12,
|
||||
// Greek
|
||||
'Ιαν' => 1,
|
||||
'Φεβ' => 2,
|
||||
'Μάώ' => 3,
|
||||
'Μαώ' => 3,
|
||||
'Απρ' => 4,
|
||||
'Μάι' => 5,
|
||||
'Μαϊ' => 5,
|
||||
'Μαι' => 5,
|
||||
'Ιούν' => 6,
|
||||
'Ιον' => 6,
|
||||
'Ιούλ' => 7,
|
||||
'Ιολ' => 7,
|
||||
'Αύγ' => 8,
|
||||
'Αυγ' => 8,
|
||||
'Σεπ' => 9,
|
||||
'Οκτ' => 10,
|
||||
'Νοέ' => 11,
|
||||
'Δεκ' => 12,
|
||||
);
|
||||
|
||||
/**
|
||||
* List of timezones, abbreviation => offset from UTC
|
||||
*
|
||||
* @access protected
|
||||
* @var array
|
||||
*/
|
||||
var $timezone = array(
|
||||
'ACDT' => 37800,
|
||||
'ACIT' => 28800,
|
||||
'ACST' => 34200,
|
||||
'ACT' => -18000,
|
||||
'ACWDT' => 35100,
|
||||
'ACWST' => 31500,
|
||||
'AEDT' => 39600,
|
||||
'AEST' => 36000,
|
||||
'AFT' => 16200,
|
||||
'AKDT' => -28800,
|
||||
'AKST' => -32400,
|
||||
'AMDT' => 18000,
|
||||
'AMT' => -14400,
|
||||
'ANAST' => 46800,
|
||||
'ANAT' => 43200,
|
||||
'ART' => -10800,
|
||||
'AZOST' => -3600,
|
||||
'AZST' => 18000,
|
||||
'AZT' => 14400,
|
||||
'BIOT' => 21600,
|
||||
'BIT' => -43200,
|
||||
'BOT' => -14400,
|
||||
'BRST' => -7200,
|
||||
'BRT' => -10800,
|
||||
'BST' => 3600,
|
||||
'BTT' => 21600,
|
||||
'CAST' => 18000,
|
||||
'CAT' => 7200,
|
||||
'CCT' => 23400,
|
||||
'CDT' => -18000,
|
||||
'CEDT' => 7200,
|
||||
'CEST' => 7200,
|
||||
'CET' => 3600,
|
||||
'CGST' => -7200,
|
||||
'CGT' => -10800,
|
||||
'CHADT' => 49500,
|
||||
'CHAST' => 45900,
|
||||
'CIST' => -28800,
|
||||
'CKT' => -36000,
|
||||
'CLDT' => -10800,
|
||||
'CLST' => -14400,
|
||||
'COT' => -18000,
|
||||
'CST' => -21600,
|
||||
'CVT' => -3600,
|
||||
'CXT' => 25200,
|
||||
'DAVT' => 25200,
|
||||
'DTAT' => 36000,
|
||||
'EADT' => -18000,
|
||||
'EAST' => -21600,
|
||||
'EAT' => 10800,
|
||||
'ECT' => -18000,
|
||||
'EDT' => -14400,
|
||||
'EEST' => 10800,
|
||||
'EET' => 7200,
|
||||
'EGT' => -3600,
|
||||
'EKST' => 21600,
|
||||
'EST' => -18000,
|
||||
'FJT' => 43200,
|
||||
'FKDT' => -10800,
|
||||
'FKST' => -14400,
|
||||
'FNT' => -7200,
|
||||
'GALT' => -21600,
|
||||
'GEDT' => 14400,
|
||||
'GEST' => 10800,
|
||||
'GFT' => -10800,
|
||||
'GILT' => 43200,
|
||||
'GIT' => -32400,
|
||||
'GST' => 14400,
|
||||
'GST' => -7200,
|
||||
'GYT' => -14400,
|
||||
'HAA' => -10800,
|
||||
'HAC' => -18000,
|
||||
'HADT' => -32400,
|
||||
'HAE' => -14400,
|
||||
'HAP' => -25200,
|
||||
'HAR' => -21600,
|
||||
'HAST' => -36000,
|
||||
'HAT' => -9000,
|
||||
'HAY' => -28800,
|
||||
'HKST' => 28800,
|
||||
'HMT' => 18000,
|
||||
'HNA' => -14400,
|
||||
'HNC' => -21600,
|
||||
'HNE' => -18000,
|
||||
'HNP' => -28800,
|
||||
'HNR' => -25200,
|
||||
'HNT' => -12600,
|
||||
'HNY' => -32400,
|
||||
'IRDT' => 16200,
|
||||
'IRKST' => 32400,
|
||||
'IRKT' => 28800,
|
||||
'IRST' => 12600,
|
||||
'JFDT' => -10800,
|
||||
'JFST' => -14400,
|
||||
'JST' => 32400,
|
||||
'KGST' => 21600,
|
||||
'KGT' => 18000,
|
||||
'KOST' => 39600,
|
||||
'KOVST' => 28800,
|
||||
'KOVT' => 25200,
|
||||
'KRAST' => 28800,
|
||||
'KRAT' => 25200,
|
||||
'KST' => 32400,
|
||||
'LHDT' => 39600,
|
||||
'LHST' => 37800,
|
||||
'LINT' => 50400,
|
||||
'LKT' => 21600,
|
||||
'MAGST' => 43200,
|
||||
'MAGT' => 39600,
|
||||
'MAWT' => 21600,
|
||||
'MDT' => -21600,
|
||||
'MESZ' => 7200,
|
||||
'MEZ' => 3600,
|
||||
'MHT' => 43200,
|
||||
'MIT' => -34200,
|
||||
'MNST' => 32400,
|
||||
'MSDT' => 14400,
|
||||
'MSST' => 10800,
|
||||
'MST' => -25200,
|
||||
'MUT' => 14400,
|
||||
'MVT' => 18000,
|
||||
'MYT' => 28800,
|
||||
'NCT' => 39600,
|
||||
'NDT' => -9000,
|
||||
'NFT' => 41400,
|
||||
'NMIT' => 36000,
|
||||
'NOVST' => 25200,
|
||||
'NOVT' => 21600,
|
||||
'NPT' => 20700,
|
||||
'NRT' => 43200,
|
||||
'NST' => -12600,
|
||||
'NUT' => -39600,
|
||||
'NZDT' => 46800,
|
||||
'NZST' => 43200,
|
||||
'OMSST' => 25200,
|
||||
'OMST' => 21600,
|
||||
'PDT' => -25200,
|
||||
'PET' => -18000,
|
||||
'PETST' => 46800,
|
||||
'PETT' => 43200,
|
||||
'PGT' => 36000,
|
||||
'PHOT' => 46800,
|
||||
'PHT' => 28800,
|
||||
'PKT' => 18000,
|
||||
'PMDT' => -7200,
|
||||
'PMST' => -10800,
|
||||
'PONT' => 39600,
|
||||
'PST' => -28800,
|
||||
'PWT' => 32400,
|
||||
'PYST' => -10800,
|
||||
'PYT' => -14400,
|
||||
'RET' => 14400,
|
||||
'ROTT' => -10800,
|
||||
'SAMST' => 18000,
|
||||
'SAMT' => 14400,
|
||||
'SAST' => 7200,
|
||||
'SBT' => 39600,
|
||||
'SCDT' => 46800,
|
||||
'SCST' => 43200,
|
||||
'SCT' => 14400,
|
||||
'SEST' => 3600,
|
||||
'SGT' => 28800,
|
||||
'SIT' => 28800,
|
||||
'SRT' => -10800,
|
||||
'SST' => -39600,
|
||||
'SYST' => 10800,
|
||||
'SYT' => 7200,
|
||||
'TFT' => 18000,
|
||||
'THAT' => -36000,
|
||||
'TJT' => 18000,
|
||||
'TKT' => -36000,
|
||||
'TMT' => 18000,
|
||||
'TOT' => 46800,
|
||||
'TPT' => 32400,
|
||||
'TRUT' => 36000,
|
||||
'TVT' => 43200,
|
||||
'TWT' => 28800,
|
||||
'UYST' => -7200,
|
||||
'UYT' => -10800,
|
||||
'UZT' => 18000,
|
||||
'VET' => -14400,
|
||||
'VLAST' => 39600,
|
||||
'VLAT' => 36000,
|
||||
'VOST' => 21600,
|
||||
'VUT' => 39600,
|
||||
'WAST' => 7200,
|
||||
'WAT' => 3600,
|
||||
'WDT' => 32400,
|
||||
'WEST' => 3600,
|
||||
'WFT' => 43200,
|
||||
'WIB' => 25200,
|
||||
'WIT' => 32400,
|
||||
'WITA' => 28800,
|
||||
'WKST' => 18000,
|
||||
'WST' => 28800,
|
||||
'YAKST' => 36000,
|
||||
'YAKT' => 32400,
|
||||
'YAPT' => 36000,
|
||||
'YEKST' => 21600,
|
||||
'YEKT' => 18000,
|
||||
);
|
||||
|
||||
/**
|
||||
* Cached PCRE for SimplePie_Parse_Date::$day
|
||||
*
|
||||
* @access protected
|
||||
* @var string
|
||||
*/
|
||||
var $day_pcre;
|
||||
|
||||
/**
|
||||
* Cached PCRE for SimplePie_Parse_Date::$month
|
||||
*
|
||||
* @access protected
|
||||
* @var string
|
||||
*/
|
||||
var $month_pcre;
|
||||
|
||||
/**
|
||||
* Array of user-added callback methods
|
||||
*
|
||||
* @access private
|
||||
* @var array
|
||||
*/
|
||||
var $built_in = array();
|
||||
|
||||
/**
|
||||
* Array of user-added callback methods
|
||||
*
|
||||
* @access private
|
||||
* @var array
|
||||
*/
|
||||
var $user = array();
|
||||
|
||||
/**
|
||||
* Create new SimplePie_Parse_Date object, and set self::day_pcre,
|
||||
* self::month_pcre, and self::built_in
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->day_pcre = '(' . implode(array_keys($this->day), '|') . ')';
|
||||
$this->month_pcre = '(' . implode(array_keys($this->month), '|') . ')';
|
||||
|
||||
static $cache;
|
||||
if (!isset($cache[get_class($this)]))
|
||||
{
|
||||
$all_methods = get_class_methods($this);
|
||||
|
||||
foreach ($all_methods as $method)
|
||||
{
|
||||
if (strtolower(substr($method, 0, 5)) === 'date_')
|
||||
{
|
||||
$cache[get_class($this)][] = $method;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($cache[get_class($this)] as $method)
|
||||
{
|
||||
$this->built_in[] = $method;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the object
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public static function get()
|
||||
{
|
||||
static $object;
|
||||
if (!$object)
|
||||
{
|
||||
$object = new SimplePie_Parse_Date;
|
||||
}
|
||||
return $object;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a date
|
||||
*
|
||||
* @final
|
||||
* @access public
|
||||
* @param string $date Date to parse
|
||||
* @return int Timestamp corresponding to date string, or false on failure
|
||||
*/
|
||||
public function parse($date)
|
||||
{
|
||||
foreach ($this->user as $method)
|
||||
{
|
||||
if (($returned = call_user_func($method, $date)) !== false)
|
||||
{
|
||||
return $returned;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->built_in as $method)
|
||||
{
|
||||
if (($returned = call_user_func(array($this, $method), $date)) !== false)
|
||||
{
|
||||
return $returned;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a callback method to parse a date
|
||||
*
|
||||
* @final
|
||||
* @access public
|
||||
* @param callable $callback
|
||||
*/
|
||||
public function add_callback($callback)
|
||||
{
|
||||
if (is_callable($callback))
|
||||
{
|
||||
$this->user[] = $callback;
|
||||
}
|
||||
else
|
||||
{
|
||||
trigger_error('User-supplied function must be a valid callback', E_USER_WARNING);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a superset of W3C-DTF (allows hyphens and colons to be omitted, as
|
||||
* well as allowing any of upper or lower case "T", horizontal tabs, or
|
||||
* spaces to be used as the time seperator (including more than one))
|
||||
*
|
||||
* @access protected
|
||||
* @return int Timestamp
|
||||
*/
|
||||
public function date_w3cdtf($date)
|
||||
{
|
||||
static $pcre;
|
||||
if (!$pcre)
|
||||
{
|
||||
$year = '([0-9]{4})';
|
||||
$month = $day = $hour = $minute = $second = '([0-9]{2})';
|
||||
$decimal = '([0-9]*)';
|
||||
$zone = '(?:(Z)|([+\-])([0-9]{1,2}):?([0-9]{1,2}))';
|
||||
$pcre = '/^' . $year . '(?:-?' . $month . '(?:-?' . $day . '(?:[Tt\x09\x20]+' . $hour . '(?::?' . $minute . '(?::?' . $second . '(?:.' . $decimal . ')?)?)?' . $zone . ')?)?)?$/';
|
||||
}
|
||||
if (preg_match($pcre, $date, $match))
|
||||
{
|
||||
/*
|
||||
Capturing subpatterns:
|
||||
1: Year
|
||||
2: Month
|
||||
3: Day
|
||||
4: Hour
|
||||
5: Minute
|
||||
6: Second
|
||||
7: Decimal fraction of a second
|
||||
8: Zulu
|
||||
9: Timezone ±
|
||||
10: Timezone hours
|
||||
11: Timezone minutes
|
||||
*/
|
||||
|
||||
// Fill in empty matches
|
||||
for ($i = count($match); $i <= 3; $i++)
|
||||
{
|
||||
$match[$i] = '1';
|
||||
}
|
||||
|
||||
for ($i = count($match); $i <= 7; $i++)
|
||||
{
|
||||
$match[$i] = '0';
|
||||
}
|
||||
|
||||
// Numeric timezone
|
||||
if (isset($match[9]) && $match[9] !== '')
|
||||
{
|
||||
$timezone = $match[10] * 3600;
|
||||
$timezone += $match[11] * 60;
|
||||
if ($match[9] === '-')
|
||||
{
|
||||
$timezone = 0 - $timezone;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$timezone = 0;
|
||||
}
|
||||
|
||||
// Convert the number of seconds to an integer, taking decimals into account
|
||||
$second = round($match[6] + $match[7] / pow(10, strlen($match[7])));
|
||||
|
||||
return gmmktime($match[4], $match[5], $second, $match[2], $match[3], $match[1]) - $timezone;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove RFC822 comments
|
||||
*
|
||||
* @access protected
|
||||
* @param string $data Data to strip comments from
|
||||
* @return string Comment stripped string
|
||||
*/
|
||||
public function remove_rfc2822_comments($string)
|
||||
{
|
||||
$string = (string) $string;
|
||||
$position = 0;
|
||||
$length = strlen($string);
|
||||
$depth = 0;
|
||||
|
||||
$output = '';
|
||||
|
||||
while ($position < $length && ($pos = strpos($string, '(', $position)) !== false)
|
||||
{
|
||||
$output .= substr($string, $position, $pos - $position);
|
||||
$position = $pos + 1;
|
||||
if ($string[$pos - 1] !== '\\')
|
||||
{
|
||||
$depth++;
|
||||
while ($depth && $position < $length)
|
||||
{
|
||||
$position += strcspn($string, '()', $position);
|
||||
if ($string[$position - 1] === '\\')
|
||||
{
|
||||
$position++;
|
||||
continue;
|
||||
}
|
||||
elseif (isset($string[$position]))
|
||||
{
|
||||
switch ($string[$position])
|
||||
{
|
||||
case '(':
|
||||
$depth++;
|
||||
break;
|
||||
|
||||
case ')':
|
||||
$depth--;
|
||||
break;
|
||||
}
|
||||
$position++;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$output .= '(';
|
||||
}
|
||||
}
|
||||
$output .= substr($string, $position);
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse RFC2822's date format
|
||||
*
|
||||
* @access protected
|
||||
* @return int Timestamp
|
||||
*/
|
||||
public function date_rfc2822($date)
|
||||
{
|
||||
static $pcre;
|
||||
if (!$pcre)
|
||||
{
|
||||
$wsp = '[\x09\x20]';
|
||||
$fws = '(?:' . $wsp . '+|' . $wsp . '*(?:\x0D\x0A' . $wsp . '+)+)';
|
||||
$optional_fws = $fws . '?';
|
||||
$day_name = $this->day_pcre;
|
||||
$month = $this->month_pcre;
|
||||
$day = '([0-9]{1,2})';
|
||||
$hour = $minute = $second = '([0-9]{2})';
|
||||
$year = '([0-9]{2,4})';
|
||||
$num_zone = '([+\-])([0-9]{2})([0-9]{2})';
|
||||
$character_zone = '([A-Z]{1,5})';
|
||||
$zone = '(?:' . $num_zone . '|' . $character_zone . ')';
|
||||
$pcre = '/(?:' . $optional_fws . $day_name . $optional_fws . ',)?' . $optional_fws . $day . $fws . $month . $fws . $year . $fws . $hour . $optional_fws . ':' . $optional_fws . $minute . '(?:' . $optional_fws . ':' . $optional_fws . $second . ')?' . $fws . $zone . '/i';
|
||||
}
|
||||
if (preg_match($pcre, $this->remove_rfc2822_comments($date), $match))
|
||||
{
|
||||
/*
|
||||
Capturing subpatterns:
|
||||
1: Day name
|
||||
2: Day
|
||||
3: Month
|
||||
4: Year
|
||||
5: Hour
|
||||
6: Minute
|
||||
7: Second
|
||||
8: Timezone ±
|
||||
9: Timezone hours
|
||||
10: Timezone minutes
|
||||
11: Alphabetic timezone
|
||||
*/
|
||||
|
||||
// Find the month number
|
||||
$month = $this->month[strtolower($match[3])];
|
||||
|
||||
// Numeric timezone
|
||||
if ($match[8] !== '')
|
||||
{
|
||||
$timezone = $match[9] * 3600;
|
||||
$timezone += $match[10] * 60;
|
||||
if ($match[8] === '-')
|
||||
{
|
||||
$timezone = 0 - $timezone;
|
||||
}
|
||||
}
|
||||
// Character timezone
|
||||
elseif (isset($this->timezone[strtoupper($match[11])]))
|
||||
{
|
||||
$timezone = $this->timezone[strtoupper($match[11])];
|
||||
}
|
||||
// Assume everything else to be -0000
|
||||
else
|
||||
{
|
||||
$timezone = 0;
|
||||
}
|
||||
|
||||
// Deal with 2/3 digit years
|
||||
if ($match[4] < 50)
|
||||
{
|
||||
$match[4] += 2000;
|
||||
}
|
||||
elseif ($match[4] < 1000)
|
||||
{
|
||||
$match[4] += 1900;
|
||||
}
|
||||
|
||||
// Second is optional, if it is empty set it to zero
|
||||
if ($match[7] !== '')
|
||||
{
|
||||
$second = $match[7];
|
||||
}
|
||||
else
|
||||
{
|
||||
$second = 0;
|
||||
}
|
||||
|
||||
return gmmktime($match[5], $match[6], $second, $month, $match[2], $match[4]) - $timezone;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse RFC850's date format
|
||||
*
|
||||
* @access protected
|
||||
* @return int Timestamp
|
||||
*/
|
||||
public function date_rfc850($date)
|
||||
{
|
||||
static $pcre;
|
||||
if (!$pcre)
|
||||
{
|
||||
$space = '[\x09\x20]+';
|
||||
$day_name = $this->day_pcre;
|
||||
$month = $this->month_pcre;
|
||||
$day = '([0-9]{1,2})';
|
||||
$year = $hour = $minute = $second = '([0-9]{2})';
|
||||
$zone = '([A-Z]{1,5})';
|
||||
$pcre = '/^' . $day_name . ',' . $space . $day . '-' . $month . '-' . $year . $space . $hour . ':' . $minute . ':' . $second . $space . $zone . '$/i';
|
||||
}
|
||||
if (preg_match($pcre, $date, $match))
|
||||
{
|
||||
/*
|
||||
Capturing subpatterns:
|
||||
1: Day name
|
||||
2: Day
|
||||
3: Month
|
||||
4: Year
|
||||
5: Hour
|
||||
6: Minute
|
||||
7: Second
|
||||
8: Timezone
|
||||
*/
|
||||
|
||||
// Month
|
||||
$month = $this->month[strtolower($match[3])];
|
||||
|
||||
// Character timezone
|
||||
if (isset($this->timezone[strtoupper($match[8])]))
|
||||
{
|
||||
$timezone = $this->timezone[strtoupper($match[8])];
|
||||
}
|
||||
// Assume everything else to be -0000
|
||||
else
|
||||
{
|
||||
$timezone = 0;
|
||||
}
|
||||
|
||||
// Deal with 2 digit year
|
||||
if ($match[4] < 50)
|
||||
{
|
||||
$match[4] += 2000;
|
||||
}
|
||||
else
|
||||
{
|
||||
$match[4] += 1900;
|
||||
}
|
||||
|
||||
return gmmktime($match[5], $match[6], $match[7], $month, $match[2], $match[4]) - $timezone;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse C99's asctime()'s date format
|
||||
*
|
||||
* @access protected
|
||||
* @return int Timestamp
|
||||
*/
|
||||
public function date_asctime($date)
|
||||
{
|
||||
static $pcre;
|
||||
if (!$pcre)
|
||||
{
|
||||
$space = '[\x09\x20]+';
|
||||
$wday_name = $this->day_pcre;
|
||||
$mon_name = $this->month_pcre;
|
||||
$day = '([0-9]{1,2})';
|
||||
$hour = $sec = $min = '([0-9]{2})';
|
||||
$year = '([0-9]{4})';
|
||||
$terminator = '\x0A?\x00?';
|
||||
$pcre = '/^' . $wday_name . $space . $mon_name . $space . $day . $space . $hour . ':' . $min . ':' . $sec . $space . $year . $terminator . '$/i';
|
||||
}
|
||||
if (preg_match($pcre, $date, $match))
|
||||
{
|
||||
/*
|
||||
Capturing subpatterns:
|
||||
1: Day name
|
||||
2: Month
|
||||
3: Day
|
||||
4: Hour
|
||||
5: Minute
|
||||
6: Second
|
||||
7: Year
|
||||
*/
|
||||
|
||||
$month = $this->month[strtolower($match[2])];
|
||||
return gmmktime($match[4], $match[5], $match[6], $month, $match[3], $match[7]);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse dates using strtotime()
|
||||
*
|
||||
* @access protected
|
||||
* @return int Timestamp
|
||||
*/
|
||||
public function date_strtotime($date)
|
||||
{
|
||||
$strtotime = strtotime($date);
|
||||
if ($strtotime === -1 || $strtotime === false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return $strtotime;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
407
Kapitel_7/Lektion_4/wordpress/wp-includes/SimplePie/Parser.php
Executable file
407
Kapitel_7/Lektion_4/wordpress/wp-includes/SimplePie/Parser.php
Executable file
@@ -0,0 +1,407 @@
|
||||
<?php
|
||||
/**
|
||||
* SimplePie
|
||||
*
|
||||
* A PHP-Based RSS and Atom Feed Framework.
|
||||
* Takes the hard work out of managing a complete RSS/Atom solution.
|
||||
*
|
||||
* Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* * Neither the name of the SimplePie Team nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDERS
|
||||
* AND 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.
|
||||
*
|
||||
* @package SimplePie
|
||||
* @version 1.3.1
|
||||
* @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
|
||||
* @author Ryan Parman
|
||||
* @author Geoffrey Sneddon
|
||||
* @author Ryan McCue
|
||||
* @link http://simplepie.org/ SimplePie
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
||||
*/
|
||||
|
||||
/**
|
||||
* Parses XML into something sane
|
||||
*
|
||||
*
|
||||
* This class can be overloaded with {@see SimplePie::set_parser_class()}
|
||||
*
|
||||
* @package SimplePie
|
||||
* @subpackage Parsing
|
||||
*/
|
||||
class SimplePie_Parser
|
||||
{
|
||||
var $error_code;
|
||||
var $error_string;
|
||||
var $current_line;
|
||||
var $current_column;
|
||||
var $current_byte;
|
||||
var $separator = ' ';
|
||||
var $namespace = array('');
|
||||
var $element = array('');
|
||||
var $xml_base = array('');
|
||||
var $xml_base_explicit = array(false);
|
||||
var $xml_lang = array('');
|
||||
var $data = array();
|
||||
var $datas = array(array());
|
||||
var $current_xhtml_construct = -1;
|
||||
var $encoding;
|
||||
protected $registry;
|
||||
|
||||
public function set_registry(SimplePie_Registry $registry)
|
||||
{
|
||||
$this->registry = $registry;
|
||||
}
|
||||
|
||||
public function parse(&$data, $encoding)
|
||||
{
|
||||
// Use UTF-8 if we get passed US-ASCII, as every US-ASCII character is a UTF-8 character
|
||||
if (strtoupper($encoding) === 'US-ASCII')
|
||||
{
|
||||
$this->encoding = 'UTF-8';
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->encoding = $encoding;
|
||||
}
|
||||
|
||||
// Strip BOM:
|
||||
// UTF-32 Big Endian BOM
|
||||
if (substr($data, 0, 4) === "\x00\x00\xFE\xFF")
|
||||
{
|
||||
$data = substr($data, 4);
|
||||
}
|
||||
// UTF-32 Little Endian BOM
|
||||
elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00")
|
||||
{
|
||||
$data = substr($data, 4);
|
||||
}
|
||||
// UTF-16 Big Endian BOM
|
||||
elseif (substr($data, 0, 2) === "\xFE\xFF")
|
||||
{
|
||||
$data = substr($data, 2);
|
||||
}
|
||||
// UTF-16 Little Endian BOM
|
||||
elseif (substr($data, 0, 2) === "\xFF\xFE")
|
||||
{
|
||||
$data = substr($data, 2);
|
||||
}
|
||||
// UTF-8 BOM
|
||||
elseif (substr($data, 0, 3) === "\xEF\xBB\xBF")
|
||||
{
|
||||
$data = substr($data, 3);
|
||||
}
|
||||
|
||||
if (substr($data, 0, 5) === '<?xml' && strspn(substr($data, 5, 1), "\x09\x0A\x0D\x20") && ($pos = strpos($data, '?>')) !== false)
|
||||
{
|
||||
$declaration = $this->registry->create('XML_Declaration_Parser', array(substr($data, 5, $pos - 5)));
|
||||
if ($declaration->parse())
|
||||
{
|
||||
$data = substr($data, $pos + 2);
|
||||
$data = '<?xml version="' . $declaration->version . '" encoding="' . $encoding . '" standalone="' . (($declaration->standalone) ? 'yes' : 'no') . '"?>' . $data;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->error_string = 'SimplePie bug! Please report this!';
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
$return = true;
|
||||
|
||||
static $xml_is_sane = null;
|
||||
if ($xml_is_sane === null)
|
||||
{
|
||||
$parser_check = xml_parser_create();
|
||||
xml_parse_into_struct($parser_check, '<foo>&</foo>', $values);
|
||||
xml_parser_free($parser_check);
|
||||
$xml_is_sane = isset($values[0]['value']);
|
||||
}
|
||||
|
||||
// Create the parser
|
||||
if ($xml_is_sane)
|
||||
{
|
||||
$xml = xml_parser_create_ns($this->encoding, $this->separator);
|
||||
xml_parser_set_option($xml, XML_OPTION_SKIP_WHITE, 1);
|
||||
xml_parser_set_option($xml, XML_OPTION_CASE_FOLDING, 0);
|
||||
xml_set_object($xml, $this);
|
||||
xml_set_character_data_handler($xml, 'cdata');
|
||||
xml_set_element_handler($xml, 'tag_open', 'tag_close');
|
||||
|
||||
// Parse!
|
||||
if (!xml_parse($xml, $data, true))
|
||||
{
|
||||
$this->error_code = xml_get_error_code($xml);
|
||||
$this->error_string = xml_error_string($this->error_code);
|
||||
$return = false;
|
||||
}
|
||||
$this->current_line = xml_get_current_line_number($xml);
|
||||
$this->current_column = xml_get_current_column_number($xml);
|
||||
$this->current_byte = xml_get_current_byte_index($xml);
|
||||
xml_parser_free($xml);
|
||||
return $return;
|
||||
}
|
||||
else
|
||||
{
|
||||
libxml_clear_errors();
|
||||
$xml = new XMLReader();
|
||||
$xml->xml($data);
|
||||
while (@$xml->read())
|
||||
{
|
||||
switch ($xml->nodeType)
|
||||
{
|
||||
|
||||
case constant('XMLReader::END_ELEMENT'):
|
||||
if ($xml->namespaceURI !== '')
|
||||
{
|
||||
$tagName = $xml->namespaceURI . $this->separator . $xml->localName;
|
||||
}
|
||||
else
|
||||
{
|
||||
$tagName = $xml->localName;
|
||||
}
|
||||
$this->tag_close(null, $tagName);
|
||||
break;
|
||||
case constant('XMLReader::ELEMENT'):
|
||||
$empty = $xml->isEmptyElement;
|
||||
if ($xml->namespaceURI !== '')
|
||||
{
|
||||
$tagName = $xml->namespaceURI . $this->separator . $xml->localName;
|
||||
}
|
||||
else
|
||||
{
|
||||
$tagName = $xml->localName;
|
||||
}
|
||||
$attributes = array();
|
||||
while ($xml->moveToNextAttribute())
|
||||
{
|
||||
if ($xml->namespaceURI !== '')
|
||||
{
|
||||
$attrName = $xml->namespaceURI . $this->separator . $xml->localName;
|
||||
}
|
||||
else
|
||||
{
|
||||
$attrName = $xml->localName;
|
||||
}
|
||||
$attributes[$attrName] = $xml->value;
|
||||
}
|
||||
$this->tag_open(null, $tagName, $attributes);
|
||||
if ($empty)
|
||||
{
|
||||
$this->tag_close(null, $tagName);
|
||||
}
|
||||
break;
|
||||
case constant('XMLReader::TEXT'):
|
||||
|
||||
case constant('XMLReader::CDATA'):
|
||||
$this->cdata(null, $xml->value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($error = libxml_get_last_error())
|
||||
{
|
||||
$this->error_code = $error->code;
|
||||
$this->error_string = $error->message;
|
||||
$this->current_line = $error->line;
|
||||
$this->current_column = $error->column;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function get_error_code()
|
||||
{
|
||||
return $this->error_code;
|
||||
}
|
||||
|
||||
public function get_error_string()
|
||||
{
|
||||
return $this->error_string;
|
||||
}
|
||||
|
||||
public function get_current_line()
|
||||
{
|
||||
return $this->current_line;
|
||||
}
|
||||
|
||||
public function get_current_column()
|
||||
{
|
||||
return $this->current_column;
|
||||
}
|
||||
|
||||
public function get_current_byte()
|
||||
{
|
||||
return $this->current_byte;
|
||||
}
|
||||
|
||||
public function get_data()
|
||||
{
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
public function tag_open($parser, $tag, $attributes)
|
||||
{
|
||||
list($this->namespace[], $this->element[]) = $this->split_ns($tag);
|
||||
|
||||
$attribs = array();
|
||||
foreach ($attributes as $name => $value)
|
||||
{
|
||||
list($attrib_namespace, $attribute) = $this->split_ns($name);
|
||||
$attribs[$attrib_namespace][$attribute] = $value;
|
||||
}
|
||||
|
||||
if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['base']))
|
||||
{
|
||||
$base = $this->registry->call('Misc', 'absolutize_url', array($attribs[SIMPLEPIE_NAMESPACE_XML]['base'], end($this->xml_base)));
|
||||
if ($base !== false)
|
||||
{
|
||||
$this->xml_base[] = $base;
|
||||
$this->xml_base_explicit[] = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->xml_base[] = end($this->xml_base);
|
||||
$this->xml_base_explicit[] = end($this->xml_base_explicit);
|
||||
}
|
||||
|
||||
if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['lang']))
|
||||
{
|
||||
$this->xml_lang[] = $attribs[SIMPLEPIE_NAMESPACE_XML]['lang'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->xml_lang[] = end($this->xml_lang);
|
||||
}
|
||||
|
||||
if ($this->current_xhtml_construct >= 0)
|
||||
{
|
||||
$this->current_xhtml_construct++;
|
||||
if (end($this->namespace) === SIMPLEPIE_NAMESPACE_XHTML)
|
||||
{
|
||||
$this->data['data'] .= '<' . end($this->element);
|
||||
if (isset($attribs['']))
|
||||
{
|
||||
foreach ($attribs[''] as $name => $value)
|
||||
{
|
||||
$this->data['data'] .= ' ' . $name . '="' . htmlspecialchars($value, ENT_COMPAT, $this->encoding) . '"';
|
||||
}
|
||||
}
|
||||
$this->data['data'] .= '>';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->datas[] =& $this->data;
|
||||
$this->data =& $this->data['child'][end($this->namespace)][end($this->element)][];
|
||||
$this->data = array('data' => '', 'attribs' => $attribs, 'xml_base' => end($this->xml_base), 'xml_base_explicit' => end($this->xml_base_explicit), 'xml_lang' => end($this->xml_lang));
|
||||
if ((end($this->namespace) === SIMPLEPIE_NAMESPACE_ATOM_03 && in_array(end($this->element), array('title', 'tagline', 'copyright', 'info', 'summary', 'content')) && isset($attribs['']['mode']) && $attribs['']['mode'] === 'xml')
|
||||
|| (end($this->namespace) === SIMPLEPIE_NAMESPACE_ATOM_10 && in_array(end($this->element), array('rights', 'subtitle', 'summary', 'info', 'title', 'content')) && isset($attribs['']['type']) && $attribs['']['type'] === 'xhtml')
|
||||
|| (end($this->namespace) === SIMPLEPIE_NAMESPACE_RSS_20 && in_array(end($this->element), array('title')))
|
||||
|| (end($this->namespace) === SIMPLEPIE_NAMESPACE_RSS_090 && in_array(end($this->element), array('title')))
|
||||
|| (end($this->namespace) === SIMPLEPIE_NAMESPACE_RSS_10 && in_array(end($this->element), array('title'))))
|
||||
{
|
||||
$this->current_xhtml_construct = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function cdata($parser, $cdata)
|
||||
{
|
||||
if ($this->current_xhtml_construct >= 0)
|
||||
{
|
||||
$this->data['data'] .= htmlspecialchars($cdata, ENT_QUOTES, $this->encoding);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->data['data'] .= $cdata;
|
||||
}
|
||||
}
|
||||
|
||||
public function tag_close($parser, $tag)
|
||||
{
|
||||
if ($this->current_xhtml_construct >= 0)
|
||||
{
|
||||
$this->current_xhtml_construct--;
|
||||
if (end($this->namespace) === SIMPLEPIE_NAMESPACE_XHTML && !in_array(end($this->element), array('area', 'base', 'basefont', 'br', 'col', 'frame', 'hr', 'img', 'input', 'isindex', 'link', 'meta', 'param')))
|
||||
{
|
||||
$this->data['data'] .= '</' . end($this->element) . '>';
|
||||
}
|
||||
}
|
||||
if ($this->current_xhtml_construct === -1)
|
||||
{
|
||||
$this->data =& $this->datas[count($this->datas) - 1];
|
||||
array_pop($this->datas);
|
||||
}
|
||||
|
||||
array_pop($this->element);
|
||||
array_pop($this->namespace);
|
||||
array_pop($this->xml_base);
|
||||
array_pop($this->xml_base_explicit);
|
||||
array_pop($this->xml_lang);
|
||||
}
|
||||
|
||||
public function split_ns($string)
|
||||
{
|
||||
static $cache = array();
|
||||
if (!isset($cache[$string]))
|
||||
{
|
||||
if ($pos = strpos($string, $this->separator))
|
||||
{
|
||||
static $separator_length;
|
||||
if (!$separator_length)
|
||||
{
|
||||
$separator_length = strlen($this->separator);
|
||||
}
|
||||
$namespace = substr($string, 0, $pos);
|
||||
$local_name = substr($string, $pos + $separator_length);
|
||||
if (strtolower($namespace) === SIMPLEPIE_NAMESPACE_ITUNES)
|
||||
{
|
||||
$namespace = SIMPLEPIE_NAMESPACE_ITUNES;
|
||||
}
|
||||
|
||||
// Normalize the Media RSS namespaces
|
||||
if ($namespace === SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG ||
|
||||
$namespace === SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG2 ||
|
||||
$namespace === SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG3 ||
|
||||
$namespace === SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG4 ||
|
||||
$namespace === SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG5 )
|
||||
{
|
||||
$namespace = SIMPLEPIE_NAMESPACE_MEDIARSS;
|
||||
}
|
||||
$cache[$string] = array($namespace, $local_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
$cache[$string] = array('', $string);
|
||||
}
|
||||
}
|
||||
return $cache[$string];
|
||||
}
|
||||
}
|
||||
129
Kapitel_7/Lektion_4/wordpress/wp-includes/SimplePie/Rating.php
Executable file
129
Kapitel_7/Lektion_4/wordpress/wp-includes/SimplePie/Rating.php
Executable file
@@ -0,0 +1,129 @@
|
||||
<?php
|
||||
/**
|
||||
* SimplePie
|
||||
*
|
||||
* A PHP-Based RSS and Atom Feed Framework.
|
||||
* Takes the hard work out of managing a complete RSS/Atom solution.
|
||||
*
|
||||
* Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* * Neither the name of the SimplePie Team nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDERS
|
||||
* AND 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.
|
||||
*
|
||||
* @package SimplePie
|
||||
* @version 1.3.1
|
||||
* @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
|
||||
* @author Ryan Parman
|
||||
* @author Geoffrey Sneddon
|
||||
* @author Ryan McCue
|
||||
* @link http://simplepie.org/ SimplePie
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
||||
*/
|
||||
|
||||
/**
|
||||
* Handles `<media:rating>` or `<itunes:explicit>` tags as defined in Media RSS and iTunes RSS respectively
|
||||
*
|
||||
* Used by {@see SimplePie_Enclosure::get_rating()} and {@see SimplePie_Enclosure::get_ratings()}
|
||||
*
|
||||
* This class can be overloaded with {@see SimplePie::set_rating_class()}
|
||||
*
|
||||
* @package SimplePie
|
||||
* @subpackage API
|
||||
*/
|
||||
class SimplePie_Rating
|
||||
{
|
||||
/**
|
||||
* Rating scheme
|
||||
*
|
||||
* @var string
|
||||
* @see get_scheme()
|
||||
*/
|
||||
var $scheme;
|
||||
|
||||
/**
|
||||
* Rating value
|
||||
*
|
||||
* @var string
|
||||
* @see get_value()
|
||||
*/
|
||||
var $value;
|
||||
|
||||
/**
|
||||
* Constructor, used to input the data
|
||||
*
|
||||
* For documentation on all the parameters, see the corresponding
|
||||
* properties and their accessors
|
||||
*/
|
||||
public function __construct($scheme = null, $value = null)
|
||||
{
|
||||
$this->scheme = $scheme;
|
||||
$this->value = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* String-ified version
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
// There is no $this->data here
|
||||
return md5(serialize($this));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the organizational scheme for the rating
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function get_scheme()
|
||||
{
|
||||
if ($this->scheme !== null)
|
||||
{
|
||||
return $this->scheme;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of the rating
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function get_value()
|
||||
{
|
||||
if ($this->value !== null)
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
225
Kapitel_7/Lektion_4/wordpress/wp-includes/SimplePie/Registry.php
Executable file
225
Kapitel_7/Lektion_4/wordpress/wp-includes/SimplePie/Registry.php
Executable file
@@ -0,0 +1,225 @@
|
||||
<?php
|
||||
/**
|
||||
* SimplePie
|
||||
*
|
||||
* A PHP-Based RSS and Atom Feed Framework.
|
||||
* Takes the hard work out of managing a complete RSS/Atom solution.
|
||||
*
|
||||
* Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* * Neither the name of the SimplePie Team nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDERS
|
||||
* AND 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.
|
||||
*
|
||||
* @package SimplePie
|
||||
* @version 1.3.1
|
||||
* @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
|
||||
* @author Ryan Parman
|
||||
* @author Geoffrey Sneddon
|
||||
* @author Ryan McCue
|
||||
* @link http://simplepie.org/ SimplePie
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
||||
*/
|
||||
|
||||
/**
|
||||
* Handles creating objects and calling methods
|
||||
*
|
||||
* Access this via {@see SimplePie::get_registry()}
|
||||
*
|
||||
* @package SimplePie
|
||||
*/
|
||||
class SimplePie_Registry
|
||||
{
|
||||
/**
|
||||
* Default class mapping
|
||||
*
|
||||
* Overriding classes *must* subclass these.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $default = array(
|
||||
'Cache' => 'SimplePie_Cache',
|
||||
'Locator' => 'SimplePie_Locator',
|
||||
'Parser' => 'SimplePie_Parser',
|
||||
'File' => 'SimplePie_File',
|
||||
'Sanitize' => 'SimplePie_Sanitize',
|
||||
'Item' => 'SimplePie_Item',
|
||||
'Author' => 'SimplePie_Author',
|
||||
'Category' => 'SimplePie_Category',
|
||||
'Enclosure' => 'SimplePie_Enclosure',
|
||||
'Caption' => 'SimplePie_Caption',
|
||||
'Copyright' => 'SimplePie_Copyright',
|
||||
'Credit' => 'SimplePie_Credit',
|
||||
'Rating' => 'SimplePie_Rating',
|
||||
'Restriction' => 'SimplePie_Restriction',
|
||||
'Content_Type_Sniffer' => 'SimplePie_Content_Type_Sniffer',
|
||||
'Source' => 'SimplePie_Source',
|
||||
'Misc' => 'SimplePie_Misc',
|
||||
'XML_Declaration_Parser' => 'SimplePie_XML_Declaration_Parser',
|
||||
'Parse_Date' => 'SimplePie_Parse_Date',
|
||||
);
|
||||
|
||||
/**
|
||||
* Class mapping
|
||||
*
|
||||
* @see register()
|
||||
* @var array
|
||||
*/
|
||||
protected $classes = array();
|
||||
|
||||
/**
|
||||
* Legacy classes
|
||||
*
|
||||
* @see register()
|
||||
* @var array
|
||||
*/
|
||||
protected $legacy = array();
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* No-op
|
||||
*/
|
||||
public function __construct() { }
|
||||
|
||||
/**
|
||||
* Register a class
|
||||
*
|
||||
* @param string $type See {@see $default} for names
|
||||
* @param string $class Class name, must subclass the corresponding default
|
||||
* @param bool $legacy Whether to enable legacy support for this class
|
||||
* @return bool Successfulness
|
||||
*/
|
||||
public function register($type, $class, $legacy = false)
|
||||
{
|
||||
if (!is_subclass_of($class, $this->default[$type]))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->classes[$type] = $class;
|
||||
|
||||
if ($legacy)
|
||||
{
|
||||
$this->legacy[] = $class;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the class registered for a type
|
||||
*
|
||||
* Where possible, use {@see create()} or {@see call()} instead
|
||||
*
|
||||
* @param string $type
|
||||
* @return string|null
|
||||
*/
|
||||
public function get_class($type)
|
||||
{
|
||||
if (!empty($this->classes[$type]))
|
||||
{
|
||||
return $this->classes[$type];
|
||||
}
|
||||
if (!empty($this->default[$type]))
|
||||
{
|
||||
return $this->default[$type];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance of a given type
|
||||
*
|
||||
* @param string $type
|
||||
* @param array $parameters Parameters to pass to the constructor
|
||||
* @return object Instance of class
|
||||
*/
|
||||
public function &create($type, $parameters = array())
|
||||
{
|
||||
$class = $this->get_class($type);
|
||||
|
||||
if (in_array($class, $this->legacy))
|
||||
{
|
||||
switch ($type)
|
||||
{
|
||||
case 'locator':
|
||||
// Legacy: file, timeout, useragent, file_class, max_checked_feeds, content_type_sniffer_class
|
||||
// Specified: file, timeout, useragent, max_checked_feeds
|
||||
$replacement = array($this->get_class('file'), $parameters[3], $this->get_class('content_type_sniffer'));
|
||||
array_splice($parameters, 3, 1, $replacement);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!method_exists($class, '__construct'))
|
||||
{
|
||||
$instance = new $class;
|
||||
}
|
||||
else
|
||||
{
|
||||
$reflector = new ReflectionClass($class);
|
||||
$instance = $reflector->newInstanceArgs($parameters);
|
||||
}
|
||||
|
||||
if (method_exists($instance, 'set_registry'))
|
||||
{
|
||||
$instance->set_registry($this);
|
||||
}
|
||||
return $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call a static method for a type
|
||||
*
|
||||
* @param string $type
|
||||
* @param string $method
|
||||
* @param array $parameters
|
||||
* @return mixed
|
||||
*/
|
||||
public function &call($type, $method, $parameters = array())
|
||||
{
|
||||
$class = $this->get_class($type);
|
||||
|
||||
if (in_array($class, $this->legacy))
|
||||
{
|
||||
switch ($type)
|
||||
{
|
||||
case 'Cache':
|
||||
// For backwards compatibility with old non-static
|
||||
// Cache::create() methods
|
||||
if ($method === 'get_handler')
|
||||
{
|
||||
$result = @call_user_func_array(array($class, 'create'), $parameters);
|
||||
return $result;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$result = call_user_func_array(array($class, $method), $parameters);
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
155
Kapitel_7/Lektion_4/wordpress/wp-includes/SimplePie/Restriction.php
Executable file
155
Kapitel_7/Lektion_4/wordpress/wp-includes/SimplePie/Restriction.php
Executable file
@@ -0,0 +1,155 @@
|
||||
<?php
|
||||
/**
|
||||
* SimplePie
|
||||
*
|
||||
* A PHP-Based RSS and Atom Feed Framework.
|
||||
* Takes the hard work out of managing a complete RSS/Atom solution.
|
||||
*
|
||||
* Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* * Neither the name of the SimplePie Team nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDERS
|
||||
* AND 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.
|
||||
*
|
||||
* @package SimplePie
|
||||
* @version 1.3.1
|
||||
* @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
|
||||
* @author Ryan Parman
|
||||
* @author Geoffrey Sneddon
|
||||
* @author Ryan McCue
|
||||
* @link http://simplepie.org/ SimplePie
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
||||
*/
|
||||
|
||||
/**
|
||||
* Handles `<media:restriction>` as defined in Media RSS
|
||||
*
|
||||
* Used by {@see SimplePie_Enclosure::get_restriction()} and {@see SimplePie_Enclosure::get_restrictions()}
|
||||
*
|
||||
* This class can be overloaded with {@see SimplePie::set_restriction_class()}
|
||||
*
|
||||
* @package SimplePie
|
||||
* @subpackage API
|
||||
*/
|
||||
class SimplePie_Restriction
|
||||
{
|
||||
/**
|
||||
* Relationship ('allow'/'deny')
|
||||
*
|
||||
* @var string
|
||||
* @see get_relationship()
|
||||
*/
|
||||
var $relationship;
|
||||
|
||||
/**
|
||||
* Type of restriction
|
||||
*
|
||||
* @var string
|
||||
* @see get_type()
|
||||
*/
|
||||
var $type;
|
||||
|
||||
/**
|
||||
* Restricted values
|
||||
*
|
||||
* @var string
|
||||
* @see get_value()
|
||||
*/
|
||||
var $value;
|
||||
|
||||
/**
|
||||
* Constructor, used to input the data
|
||||
*
|
||||
* For documentation on all the parameters, see the corresponding
|
||||
* properties and their accessors
|
||||
*/
|
||||
public function __construct($relationship = null, $type = null, $value = null)
|
||||
{
|
||||
$this->relationship = $relationship;
|
||||
$this->type = $type;
|
||||
$this->value = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* String-ified version
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
// There is no $this->data here
|
||||
return md5(serialize($this));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the relationship
|
||||
*
|
||||
* @return string|null Either 'allow' or 'deny'
|
||||
*/
|
||||
public function get_relationship()
|
||||
{
|
||||
if ($this->relationship !== null)
|
||||
{
|
||||
return $this->relationship;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the type
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function get_type()
|
||||
{
|
||||
if ($this->type !== null)
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of restricted things
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function get_value()
|
||||
{
|
||||
if ($this->value !== null)
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
554
Kapitel_7/Lektion_4/wordpress/wp-includes/SimplePie/Sanitize.php
Executable file
554
Kapitel_7/Lektion_4/wordpress/wp-includes/SimplePie/Sanitize.php
Executable file
@@ -0,0 +1,554 @@
|
||||
<?php
|
||||
/**
|
||||
* SimplePie
|
||||
*
|
||||
* A PHP-Based RSS and Atom Feed Framework.
|
||||
* Takes the hard work out of managing a complete RSS/Atom solution.
|
||||
*
|
||||
* Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* * Neither the name of the SimplePie Team nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDERS
|
||||
* AND 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.
|
||||
*
|
||||
* @package SimplePie
|
||||
* @version 1.3.1
|
||||
* @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
|
||||
* @author Ryan Parman
|
||||
* @author Geoffrey Sneddon
|
||||
* @author Ryan McCue
|
||||
* @link http://simplepie.org/ SimplePie
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
||||
*/
|
||||
|
||||
/**
|
||||
* Used for data cleanup and post-processing
|
||||
*
|
||||
*
|
||||
* This class can be overloaded with {@see SimplePie::set_sanitize_class()}
|
||||
*
|
||||
* @package SimplePie
|
||||
* @todo Move to using an actual HTML parser (this will allow tags to be properly stripped, and to switch between HTML and XHTML), this will also make it easier to shorten a string while preserving HTML tags
|
||||
*/
|
||||
class SimplePie_Sanitize
|
||||
{
|
||||
// Private vars
|
||||
var $base;
|
||||
|
||||
// Options
|
||||
var $remove_div = true;
|
||||
var $image_handler = '';
|
||||
var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
|
||||
var $encode_instead_of_strip = false;
|
||||
var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
|
||||
var $strip_comments = false;
|
||||
var $output_encoding = 'UTF-8';
|
||||
var $enable_cache = true;
|
||||
var $cache_location = './cache';
|
||||
var $cache_name_function = 'md5';
|
||||
var $timeout = 10;
|
||||
var $useragent = '';
|
||||
var $force_fsockopen = false;
|
||||
var $replace_url_attributes = null;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
// Set defaults
|
||||
$this->set_url_replacements(null);
|
||||
}
|
||||
|
||||
public function remove_div($enable = true)
|
||||
{
|
||||
$this->remove_div = (bool) $enable;
|
||||
}
|
||||
|
||||
public function set_image_handler($page = false)
|
||||
{
|
||||
if ($page)
|
||||
{
|
||||
$this->image_handler = (string) $page;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->image_handler = false;
|
||||
}
|
||||
}
|
||||
|
||||
public function set_registry(SimplePie_Registry $registry)
|
||||
{
|
||||
$this->registry = $registry;
|
||||
}
|
||||
|
||||
public function pass_cache_data($enable_cache = true, $cache_location = './cache', $cache_name_function = 'md5', $cache_class = 'SimplePie_Cache')
|
||||
{
|
||||
if (isset($enable_cache))
|
||||
{
|
||||
$this->enable_cache = (bool) $enable_cache;
|
||||
}
|
||||
|
||||
if ($cache_location)
|
||||
{
|
||||
$this->cache_location = (string) $cache_location;
|
||||
}
|
||||
|
||||
if ($cache_name_function)
|
||||
{
|
||||
$this->cache_name_function = (string) $cache_name_function;
|
||||
}
|
||||
}
|
||||
|
||||
public function pass_file_data($file_class = 'SimplePie_File', $timeout = 10, $useragent = '', $force_fsockopen = false)
|
||||
{
|
||||
if ($timeout)
|
||||
{
|
||||
$this->timeout = (string) $timeout;
|
||||
}
|
||||
|
||||
if ($useragent)
|
||||
{
|
||||
$this->useragent = (string) $useragent;
|
||||
}
|
||||
|
||||
if ($force_fsockopen)
|
||||
{
|
||||
$this->force_fsockopen = (string) $force_fsockopen;
|
||||
}
|
||||
}
|
||||
|
||||
public function strip_htmltags($tags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style'))
|
||||
{
|
||||
if ($tags)
|
||||
{
|
||||
if (is_array($tags))
|
||||
{
|
||||
$this->strip_htmltags = $tags;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->strip_htmltags = explode(',', $tags);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->strip_htmltags = false;
|
||||
}
|
||||
}
|
||||
|
||||
public function encode_instead_of_strip($encode = false)
|
||||
{
|
||||
$this->encode_instead_of_strip = (bool) $encode;
|
||||
}
|
||||
|
||||
public function strip_attributes($attribs = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc'))
|
||||
{
|
||||
if ($attribs)
|
||||
{
|
||||
if (is_array($attribs))
|
||||
{
|
||||
$this->strip_attributes = $attribs;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->strip_attributes = explode(',', $attribs);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->strip_attributes = false;
|
||||
}
|
||||
}
|
||||
|
||||
public function strip_comments($strip = false)
|
||||
{
|
||||
$this->strip_comments = (bool) $strip;
|
||||
}
|
||||
|
||||
public function set_output_encoding($encoding = 'UTF-8')
|
||||
{
|
||||
$this->output_encoding = (string) $encoding;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set element/attribute key/value pairs of HTML attributes
|
||||
* containing URLs that need to be resolved relative to the feed
|
||||
*
|
||||
* Defaults to |a|@href, |area|@href, |blockquote|@cite, |del|@cite,
|
||||
* |form|@action, |img|@longdesc, |img|@src, |input|@src, |ins|@cite,
|
||||
* |q|@cite
|
||||
*
|
||||
* @since 1.0
|
||||
* @param array|null $element_attribute Element/attribute key/value pairs, null for default
|
||||
*/
|
||||
public function set_url_replacements($element_attribute = null)
|
||||
{
|
||||
if ($element_attribute === null)
|
||||
{
|
||||
$element_attribute = array(
|
||||
'a' => 'href',
|
||||
'area' => 'href',
|
||||
'blockquote' => 'cite',
|
||||
'del' => 'cite',
|
||||
'form' => 'action',
|
||||
'img' => array(
|
||||
'longdesc',
|
||||
'src'
|
||||
),
|
||||
'input' => 'src',
|
||||
'ins' => 'cite',
|
||||
'q' => 'cite'
|
||||
);
|
||||
}
|
||||
$this->replace_url_attributes = (array) $element_attribute;
|
||||
}
|
||||
|
||||
public function sanitize($data, $type, $base = '')
|
||||
{
|
||||
$data = trim($data);
|
||||
if ($data !== '' || $type & SIMPLEPIE_CONSTRUCT_IRI)
|
||||
{
|
||||
if ($type & SIMPLEPIE_CONSTRUCT_MAYBE_HTML)
|
||||
{
|
||||
if (preg_match('/(&(#(x[0-9a-fA-F]+|[0-9]+)|[a-zA-Z0-9]+)|<\/[A-Za-z][^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3E]*' . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . '>)/', $data))
|
||||
{
|
||||
$type |= SIMPLEPIE_CONSTRUCT_HTML;
|
||||
}
|
||||
else
|
||||
{
|
||||
$type |= SIMPLEPIE_CONSTRUCT_TEXT;
|
||||
}
|
||||
}
|
||||
|
||||
if ($type & SIMPLEPIE_CONSTRUCT_BASE64)
|
||||
{
|
||||
$data = base64_decode($data);
|
||||
}
|
||||
|
||||
if ($type & (SIMPLEPIE_CONSTRUCT_HTML | SIMPLEPIE_CONSTRUCT_XHTML))
|
||||
{
|
||||
|
||||
if (!class_exists('DOMDocument'))
|
||||
{
|
||||
$this->registry->call('Misc', 'error', array('DOMDocument not found, unable to use sanitizer', E_USER_WARNING, __FILE__, __LINE__));
|
||||
return '';
|
||||
}
|
||||
$document = new DOMDocument();
|
||||
$document->encoding = 'UTF-8';
|
||||
$data = $this->preprocess($data, $type);
|
||||
|
||||
set_error_handler(array('SimplePie_Misc', 'silence_errors'));
|
||||
$document->loadHTML($data);
|
||||
restore_error_handler();
|
||||
|
||||
// Strip comments
|
||||
if ($this->strip_comments)
|
||||
{
|
||||
$xpath = new DOMXPath($document);
|
||||
$comments = $xpath->query('//comment()');
|
||||
|
||||
foreach ($comments as $comment)
|
||||
{
|
||||
$comment->parentNode->removeChild($comment);
|
||||
}
|
||||
}
|
||||
|
||||
// Strip out HTML tags and attributes that might cause various security problems.
|
||||
// Based on recommendations by Mark Pilgrim at:
|
||||
// http://diveintomark.org/archives/2003/06/12/how_to_consume_rss_safely
|
||||
if ($this->strip_htmltags)
|
||||
{
|
||||
foreach ($this->strip_htmltags as $tag)
|
||||
{
|
||||
$this->strip_tag($tag, $document, $type);
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->strip_attributes)
|
||||
{
|
||||
foreach ($this->strip_attributes as $attrib)
|
||||
{
|
||||
$this->strip_attr($attrib, $document);
|
||||
}
|
||||
}
|
||||
|
||||
// Replace relative URLs
|
||||
$this->base = $base;
|
||||
foreach ($this->replace_url_attributes as $element => $attributes)
|
||||
{
|
||||
$this->replace_urls($document, $element, $attributes);
|
||||
}
|
||||
|
||||
// If image handling (caching, etc.) is enabled, cache and rewrite all the image tags.
|
||||
if (isset($this->image_handler) && ((string) $this->image_handler) !== '' && $this->enable_cache)
|
||||
{
|
||||
$images = $document->getElementsByTagName('img');
|
||||
foreach ($images as $img)
|
||||
{
|
||||
if ($img->hasAttribute('src'))
|
||||
{
|
||||
$image_url = call_user_func($this->cache_name_function, $img->getAttribute('src'));
|
||||
$cache = $this->registry->call('Cache', 'get_handler', array($this->cache_location, $image_url, 'spi'));
|
||||
|
||||
if ($cache->load())
|
||||
{
|
||||
$img->setAttribute('src', $this->image_handler . $image_url);
|
||||
}
|
||||
else
|
||||
{
|
||||
$file = $this->registry->create('File', array($img->getAttribute('src'), $this->timeout, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen));
|
||||
$headers = $file->headers;
|
||||
|
||||
if ($file->success && ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($file->status_code === 200 || $file->status_code > 206 && $file->status_code < 300)))
|
||||
{
|
||||
if ($cache->save(array('headers' => $file->headers, 'body' => $file->body)))
|
||||
{
|
||||
$img->setAttribute('src', $this->image_handler . $image_url);
|
||||
}
|
||||
else
|
||||
{
|
||||
trigger_error("$this->cache_location is not writeable. Make sure you've set the correct relative or absolute path, and that the location is server-writable.", E_USER_WARNING);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Remove the DOCTYPE
|
||||
// Seems to cause segfaulting if we don't do this
|
||||
if ($document->firstChild instanceof DOMDocumentType)
|
||||
{
|
||||
$document->removeChild($document->firstChild);
|
||||
}
|
||||
|
||||
// Move everything from the body to the root
|
||||
$real_body = $document->getElementsByTagName('body')->item(0)->childNodes->item(0);
|
||||
$document->replaceChild($real_body, $document->firstChild);
|
||||
|
||||
// Finally, convert to a HTML string
|
||||
$data = trim($document->saveHTML());
|
||||
|
||||
if ($this->remove_div)
|
||||
{
|
||||
$data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '', $data);
|
||||
$data = preg_replace('/<\/div>$/', '', $data);
|
||||
}
|
||||
else
|
||||
{
|
||||
$data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '<div>', $data);
|
||||
}
|
||||
}
|
||||
|
||||
if ($type & SIMPLEPIE_CONSTRUCT_IRI)
|
||||
{
|
||||
$absolute = $this->registry->call('Misc', 'absolutize_url', array($data, $base));
|
||||
if ($absolute !== false)
|
||||
{
|
||||
$data = $absolute;
|
||||
}
|
||||
}
|
||||
|
||||
if ($type & (SIMPLEPIE_CONSTRUCT_TEXT | SIMPLEPIE_CONSTRUCT_IRI))
|
||||
{
|
||||
$data = htmlspecialchars($data, ENT_COMPAT, 'UTF-8');
|
||||
}
|
||||
|
||||
if ($this->output_encoding !== 'UTF-8')
|
||||
{
|
||||
$data = $this->registry->call('Misc', 'change_encoding', array($data, 'UTF-8', $this->output_encoding));
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
protected function preprocess($html, $type)
|
||||
{
|
||||
$ret = '';
|
||||
if ($type & ~SIMPLEPIE_CONSTRUCT_XHTML)
|
||||
{
|
||||
// Atom XHTML constructs are wrapped with a div by default
|
||||
// Note: No protection if $html contains a stray </div>!
|
||||
$html = '<div>' . $html . '</div>';
|
||||
$ret .= '<!DOCTYPE html>';
|
||||
$content_type = 'text/html';
|
||||
}
|
||||
else
|
||||
{
|
||||
$ret .= '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">';
|
||||
$content_type = 'application/xhtml+xml';
|
||||
}
|
||||
|
||||
$ret .= '<html><head>';
|
||||
$ret .= '<meta http-equiv="Content-Type" content="' . $content_type . '; charset=utf-8" />';
|
||||
$ret .= '</head><body>' . $html . '</body></html>';
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function replace_urls($document, $tag, $attributes)
|
||||
{
|
||||
if (!is_array($attributes))
|
||||
{
|
||||
$attributes = array($attributes);
|
||||
}
|
||||
|
||||
if (!is_array($this->strip_htmltags) || !in_array($tag, $this->strip_htmltags))
|
||||
{
|
||||
$elements = $document->getElementsByTagName($tag);
|
||||
foreach ($elements as $element)
|
||||
{
|
||||
foreach ($attributes as $attribute)
|
||||
{
|
||||
if ($element->hasAttribute($attribute))
|
||||
{
|
||||
$value = $this->registry->call('Misc', 'absolutize_url', array($element->getAttribute($attribute), $this->base));
|
||||
if ($value !== false)
|
||||
{
|
||||
$element->setAttribute($attribute, $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function do_strip_htmltags($match)
|
||||
{
|
||||
if ($this->encode_instead_of_strip)
|
||||
{
|
||||
if (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))
|
||||
{
|
||||
$match[1] = htmlspecialchars($match[1], ENT_COMPAT, 'UTF-8');
|
||||
$match[2] = htmlspecialchars($match[2], ENT_COMPAT, 'UTF-8');
|
||||
return "<$match[1]$match[2]>$match[3]</$match[1]>";
|
||||
}
|
||||
else
|
||||
{
|
||||
return htmlspecialchars($match[0], ENT_COMPAT, 'UTF-8');
|
||||
}
|
||||
}
|
||||
elseif (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))
|
||||
{
|
||||
return $match[4];
|
||||
}
|
||||
else
|
||||
{
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
protected function strip_tag($tag, $document, $type)
|
||||
{
|
||||
$xpath = new DOMXPath($document);
|
||||
$elements = $xpath->query('body//' . $tag);
|
||||
if ($this->encode_instead_of_strip)
|
||||
{
|
||||
foreach ($elements as $element)
|
||||
{
|
||||
$fragment = $document->createDocumentFragment();
|
||||
|
||||
// For elements which aren't script or style, include the tag itself
|
||||
if (!in_array($tag, array('script', 'style')))
|
||||
{
|
||||
$text = '<' . $tag;
|
||||
if ($element->hasAttributes())
|
||||
{
|
||||
$attrs = array();
|
||||
foreach ($element->attributes as $name => $attr)
|
||||
{
|
||||
$value = $attr->value;
|
||||
|
||||
// In XHTML, empty values should never exist, so we repeat the value
|
||||
if (empty($value) && ($type & SIMPLEPIE_CONSTRUCT_XHTML))
|
||||
{
|
||||
$value = $name;
|
||||
}
|
||||
// For HTML, empty is fine
|
||||
elseif (empty($value) && ($type & SIMPLEPIE_CONSTRUCT_HTML))
|
||||
{
|
||||
$attrs[] = $name;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Standard attribute text
|
||||
$attrs[] = $name . '="' . $attr->value . '"';
|
||||
}
|
||||
$text .= ' ' . implode(' ', $attrs);
|
||||
}
|
||||
$text .= '>';
|
||||
$fragment->appendChild(new DOMText($text));
|
||||
}
|
||||
|
||||
$number = $element->childNodes->length;
|
||||
for ($i = $number; $i > 0; $i--)
|
||||
{
|
||||
$child = $element->childNodes->item(0);
|
||||
$fragment->appendChild($child);
|
||||
}
|
||||
|
||||
if (!in_array($tag, array('script', 'style')))
|
||||
{
|
||||
$fragment->appendChild(new DOMText('</' . $tag . '>'));
|
||||
}
|
||||
|
||||
$element->parentNode->replaceChild($fragment, $element);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
elseif (in_array($tag, array('script', 'style')))
|
||||
{
|
||||
foreach ($elements as $element)
|
||||
{
|
||||
$element->parentNode->removeChild($element);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach ($elements as $element)
|
||||
{
|
||||
$fragment = $document->createDocumentFragment();
|
||||
$number = $element->childNodes->length;
|
||||
for ($i = $number; $i > 0; $i--)
|
||||
{
|
||||
$child = $element->childNodes->item(0);
|
||||
$fragment->appendChild($child);
|
||||
}
|
||||
|
||||
$element->parentNode->replaceChild($fragment, $element);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function strip_attr($attrib, $document)
|
||||
{
|
||||
$xpath = new DOMXPath($document);
|
||||
$elements = $xpath->query('//*[@' . $attrib . ']');
|
||||
|
||||
foreach ($elements as $element)
|
||||
{
|
||||
$element->removeAttribute($attrib);
|
||||
}
|
||||
}
|
||||
}
|
||||
611
Kapitel_7/Lektion_4/wordpress/wp-includes/SimplePie/Source.php
Executable file
611
Kapitel_7/Lektion_4/wordpress/wp-includes/SimplePie/Source.php
Executable file
@@ -0,0 +1,611 @@
|
||||
<?php
|
||||
/**
|
||||
* SimplePie
|
||||
*
|
||||
* A PHP-Based RSS and Atom Feed Framework.
|
||||
* Takes the hard work out of managing a complete RSS/Atom solution.
|
||||
*
|
||||
* Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* * Neither the name of the SimplePie Team nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDERS
|
||||
* AND 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.
|
||||
*
|
||||
* @package SimplePie
|
||||
* @version 1.3.1
|
||||
* @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
|
||||
* @author Ryan Parman
|
||||
* @author Geoffrey Sneddon
|
||||
* @author Ryan McCue
|
||||
* @link http://simplepie.org/ SimplePie
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
||||
*/
|
||||
|
||||
/**
|
||||
* Handles `<atom:source>`
|
||||
*
|
||||
* Used by {@see SimplePie_Item::get_source()}
|
||||
*
|
||||
* This class can be overloaded with {@see SimplePie::set_source_class()}
|
||||
*
|
||||
* @package SimplePie
|
||||
* @subpackage API
|
||||
*/
|
||||
class SimplePie_Source
|
||||
{
|
||||
var $item;
|
||||
var $data = array();
|
||||
protected $registry;
|
||||
|
||||
public function __construct($item, $data)
|
||||
{
|
||||
$this->item = $item;
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
public function set_registry(SimplePie_Registry $registry)
|
||||
{
|
||||
$this->registry = $registry;
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return md5(serialize($this->data));
|
||||
}
|
||||
|
||||
public function get_source_tags($namespace, $tag)
|
||||
{
|
||||
if (isset($this->data['child'][$namespace][$tag]))
|
||||
{
|
||||
return $this->data['child'][$namespace][$tag];
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_base($element = array())
|
||||
{
|
||||
return $this->item->get_base($element);
|
||||
}
|
||||
|
||||
public function sanitize($data, $type, $base = '')
|
||||
{
|
||||
return $this->item->sanitize($data, $type, $base);
|
||||
}
|
||||
|
||||
public function get_item()
|
||||
{
|
||||
return $this->item;
|
||||
}
|
||||
|
||||
public function get_title()
|
||||
{
|
||||
if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
|
||||
{
|
||||
return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_10_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
|
||||
}
|
||||
elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
|
||||
{
|
||||
return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_03_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
|
||||
}
|
||||
elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
|
||||
{
|
||||
return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
|
||||
}
|
||||
elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
|
||||
{
|
||||
return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
|
||||
}
|
||||
elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title'))
|
||||
{
|
||||
return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
|
||||
}
|
||||
elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
|
||||
{
|
||||
return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
|
||||
}
|
||||
elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
|
||||
{
|
||||
return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_category($key = 0)
|
||||
{
|
||||
$categories = $this->get_categories();
|
||||
if (isset($categories[$key]))
|
||||
{
|
||||
return $categories[$key];
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_categories()
|
||||
{
|
||||
$categories = array();
|
||||
|
||||
foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
|
||||
{
|
||||
$term = null;
|
||||
$scheme = null;
|
||||
$label = null;
|
||||
if (isset($category['attribs']['']['term']))
|
||||
{
|
||||
$term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
|
||||
}
|
||||
if (isset($category['attribs']['']['scheme']))
|
||||
{
|
||||
$scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
|
||||
}
|
||||
if (isset($category['attribs']['']['label']))
|
||||
{
|
||||
$label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
|
||||
}
|
||||
$categories[] = $this->registry->create('Category', array($term, $scheme, $label));
|
||||
}
|
||||
foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'category') as $category)
|
||||
{
|
||||
// This is really the label, but keep this as the term also for BC.
|
||||
// Label will also work on retrieving because that falls back to term.
|
||||
$term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
|
||||
if (isset($category['attribs']['']['domain']))
|
||||
{
|
||||
$scheme = $this->sanitize($category['attribs']['']['domain'], SIMPLEPIE_CONSTRUCT_TEXT);
|
||||
}
|
||||
else
|
||||
{
|
||||
$scheme = null;
|
||||
}
|
||||
$categories[] = $this->registry->create('Category', array($term, $scheme, null));
|
||||
}
|
||||
foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
|
||||
{
|
||||
$categories[] = $this->registry->create('Category', array($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null));
|
||||
}
|
||||
foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
|
||||
{
|
||||
$categories[] = $this->registry->create('Category', array($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null));
|
||||
}
|
||||
|
||||
if (!empty($categories))
|
||||
{
|
||||
return array_unique($categories);
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_author($key = 0)
|
||||
{
|
||||
$authors = $this->get_authors();
|
||||
if (isset($authors[$key]))
|
||||
{
|
||||
return $authors[$key];
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_authors()
|
||||
{
|
||||
$authors = array();
|
||||
foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
|
||||
{
|
||||
$name = null;
|
||||
$uri = null;
|
||||
$email = null;
|
||||
if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
|
||||
{
|
||||
$name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
|
||||
}
|
||||
if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
|
||||
{
|
||||
$uri = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]));
|
||||
}
|
||||
if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
|
||||
{
|
||||
$email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
|
||||
}
|
||||
if ($name !== null || $email !== null || $uri !== null)
|
||||
{
|
||||
$authors[] = $this->registry->create('Author', array($name, $uri, $email));
|
||||
}
|
||||
}
|
||||
if ($author = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
|
||||
{
|
||||
$name = null;
|
||||
$url = null;
|
||||
$email = null;
|
||||
if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
|
||||
{
|
||||
$name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
|
||||
}
|
||||
if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
|
||||
{
|
||||
$url = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]));
|
||||
}
|
||||
if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
|
||||
{
|
||||
$email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
|
||||
}
|
||||
if ($name !== null || $email !== null || $url !== null)
|
||||
{
|
||||
$authors[] = $this->registry->create('Author', array($name, $url, $email));
|
||||
}
|
||||
}
|
||||
foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
|
||||
{
|
||||
$authors[] = $this->registry->create('Author', array($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null));
|
||||
}
|
||||
foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
|
||||
{
|
||||
$authors[] = $this->registry->create('Author', array($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null));
|
||||
}
|
||||
foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
|
||||
{
|
||||
$authors[] = $this->registry->create('Author', array($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null));
|
||||
}
|
||||
|
||||
if (!empty($authors))
|
||||
{
|
||||
return array_unique($authors);
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_contributor($key = 0)
|
||||
{
|
||||
$contributors = $this->get_contributors();
|
||||
if (isset($contributors[$key]))
|
||||
{
|
||||
return $contributors[$key];
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_contributors()
|
||||
{
|
||||
$contributors = array();
|
||||
foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
|
||||
{
|
||||
$name = null;
|
||||
$uri = null;
|
||||
$email = null;
|
||||
if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
|
||||
{
|
||||
$name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
|
||||
}
|
||||
if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
|
||||
{
|
||||
$uri = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]));
|
||||
}
|
||||
if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
|
||||
{
|
||||
$email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
|
||||
}
|
||||
if ($name !== null || $email !== null || $uri !== null)
|
||||
{
|
||||
$contributors[] = $this->registry->create('Author', array($name, $uri, $email));
|
||||
}
|
||||
}
|
||||
foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
|
||||
{
|
||||
$name = null;
|
||||
$url = null;
|
||||
$email = null;
|
||||
if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
|
||||
{
|
||||
$name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
|
||||
}
|
||||
if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
|
||||
{
|
||||
$url = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]));
|
||||
}
|
||||
if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
|
||||
{
|
||||
$email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
|
||||
}
|
||||
if ($name !== null || $email !== null || $url !== null)
|
||||
{
|
||||
$contributors[] = $this->registry->create('Author', array($name, $url, $email));
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($contributors))
|
||||
{
|
||||
return array_unique($contributors);
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_link($key = 0, $rel = 'alternate')
|
||||
{
|
||||
$links = $this->get_links($rel);
|
||||
if (isset($links[$key]))
|
||||
{
|
||||
return $links[$key];
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Added for parity between the parent-level and the item/entry-level.
|
||||
*/
|
||||
public function get_permalink()
|
||||
{
|
||||
return $this->get_link(0);
|
||||
}
|
||||
|
||||
public function get_links($rel = 'alternate')
|
||||
{
|
||||
if (!isset($this->data['links']))
|
||||
{
|
||||
$this->data['links'] = array();
|
||||
if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link'))
|
||||
{
|
||||
foreach ($links as $link)
|
||||
{
|
||||
if (isset($link['attribs']['']['href']))
|
||||
{
|
||||
$link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
|
||||
$this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'))
|
||||
{
|
||||
foreach ($links as $link)
|
||||
{
|
||||
if (isset($link['attribs']['']['href']))
|
||||
{
|
||||
$link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
|
||||
$this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
|
||||
{
|
||||
$this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
|
||||
}
|
||||
if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
|
||||
{
|
||||
$this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
|
||||
}
|
||||
if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link'))
|
||||
{
|
||||
$this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
|
||||
}
|
||||
|
||||
$keys = array_keys($this->data['links']);
|
||||
foreach ($keys as $key)
|
||||
{
|
||||
if ($this->registry->call('Misc', 'is_isegment_nz_nc', array($key)))
|
||||
{
|
||||
if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
|
||||
{
|
||||
$this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
|
||||
$this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
|
||||
}
|
||||
}
|
||||
elseif (substr($key, 0, 41) === SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
|
||||
{
|
||||
$this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
|
||||
}
|
||||
$this->data['links'][$key] = array_unique($this->data['links'][$key]);
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($this->data['links'][$rel]))
|
||||
{
|
||||
return $this->data['links'][$rel];
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_description()
|
||||
{
|
||||
if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle'))
|
||||
{
|
||||
return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_10_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
|
||||
}
|
||||
elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline'))
|
||||
{
|
||||
return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_03_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
|
||||
}
|
||||
elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
|
||||
{
|
||||
return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
|
||||
}
|
||||
elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
|
||||
{
|
||||
return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
|
||||
}
|
||||
elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'description'))
|
||||
{
|
||||
return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
|
||||
}
|
||||
elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
|
||||
{
|
||||
return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
|
||||
}
|
||||
elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
|
||||
{
|
||||
return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
|
||||
}
|
||||
elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
|
||||
{
|
||||
return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
|
||||
}
|
||||
elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
|
||||
{
|
||||
return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_copyright()
|
||||
{
|
||||
if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
|
||||
{
|
||||
return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_10_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
|
||||
}
|
||||
elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright'))
|
||||
{
|
||||
return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_03_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
|
||||
}
|
||||
elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'copyright'))
|
||||
{
|
||||
return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
|
||||
}
|
||||
elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
|
||||
{
|
||||
return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
|
||||
}
|
||||
elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
|
||||
{
|
||||
return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_language()
|
||||
{
|
||||
if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'language'))
|
||||
{
|
||||
return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
|
||||
}
|
||||
elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language'))
|
||||
{
|
||||
return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
|
||||
}
|
||||
elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language'))
|
||||
{
|
||||
return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
|
||||
}
|
||||
elseif (isset($this->data['xml_lang']))
|
||||
{
|
||||
return $this->sanitize($this->data['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_latitude()
|
||||
{
|
||||
if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
|
||||
{
|
||||
return (float) $return[0]['data'];
|
||||
}
|
||||
elseif (($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match))
|
||||
{
|
||||
return (float) $match[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_longitude()
|
||||
{
|
||||
if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
|
||||
{
|
||||
return (float) $return[0]['data'];
|
||||
}
|
||||
elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
|
||||
{
|
||||
return (float) $return[0]['data'];
|
||||
}
|
||||
elseif (($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match))
|
||||
{
|
||||
return (float) $match[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_image_url()
|
||||
{
|
||||
if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image'))
|
||||
{
|
||||
return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI);
|
||||
}
|
||||
elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo'))
|
||||
{
|
||||
return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
|
||||
}
|
||||
elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
|
||||
{
|
||||
return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
362
Kapitel_7/Lektion_4/wordpress/wp-includes/SimplePie/XML/Declaration/Parser.php
Executable file
362
Kapitel_7/Lektion_4/wordpress/wp-includes/SimplePie/XML/Declaration/Parser.php
Executable file
@@ -0,0 +1,362 @@
|
||||
<?php
|
||||
/**
|
||||
* SimplePie
|
||||
*
|
||||
* A PHP-Based RSS and Atom Feed Framework.
|
||||
* Takes the hard work out of managing a complete RSS/Atom solution.
|
||||
*
|
||||
* Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* * Neither the name of the SimplePie Team nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDERS
|
||||
* AND 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.
|
||||
*
|
||||
* @package SimplePie
|
||||
* @version 1.3.1
|
||||
* @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
|
||||
* @author Ryan Parman
|
||||
* @author Geoffrey Sneddon
|
||||
* @author Ryan McCue
|
||||
* @link http://simplepie.org/ SimplePie
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Parses the XML Declaration
|
||||
*
|
||||
* @package SimplePie
|
||||
* @subpackage Parsing
|
||||
*/
|
||||
class SimplePie_XML_Declaration_Parser
|
||||
{
|
||||
/**
|
||||
* XML Version
|
||||
*
|
||||
* @access public
|
||||
* @var string
|
||||
*/
|
||||
var $version = '1.0';
|
||||
|
||||
/**
|
||||
* Encoding
|
||||
*
|
||||
* @access public
|
||||
* @var string
|
||||
*/
|
||||
var $encoding = 'UTF-8';
|
||||
|
||||
/**
|
||||
* Standalone
|
||||
*
|
||||
* @access public
|
||||
* @var bool
|
||||
*/
|
||||
var $standalone = false;
|
||||
|
||||
/**
|
||||
* Current state of the state machine
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
var $state = 'before_version_name';
|
||||
|
||||
/**
|
||||
* Input data
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
var $data = '';
|
||||
|
||||
/**
|
||||
* Input data length (to avoid calling strlen() everytime this is needed)
|
||||
*
|
||||
* @access private
|
||||
* @var int
|
||||
*/
|
||||
var $data_length = 0;
|
||||
|
||||
/**
|
||||
* Current position of the pointer
|
||||
*
|
||||
* @var int
|
||||
* @access private
|
||||
*/
|
||||
var $position = 0;
|
||||
|
||||
/**
|
||||
* Create an instance of the class with the input data
|
||||
*
|
||||
* @access public
|
||||
* @param string $data Input data
|
||||
*/
|
||||
public function __construct($data)
|
||||
{
|
||||
$this->data = $data;
|
||||
$this->data_length = strlen($this->data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the input data
|
||||
*
|
||||
* @access public
|
||||
* @return bool true on success, false on failure
|
||||
*/
|
||||
public function parse()
|
||||
{
|
||||
while ($this->state && $this->state !== 'emit' && $this->has_data())
|
||||
{
|
||||
$state = $this->state;
|
||||
$this->$state();
|
||||
}
|
||||
$this->data = '';
|
||||
if ($this->state === 'emit')
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->version = '';
|
||||
$this->encoding = '';
|
||||
$this->standalone = '';
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether there is data beyond the pointer
|
||||
*
|
||||
* @access private
|
||||
* @return bool true if there is further data, false if not
|
||||
*/
|
||||
public function has_data()
|
||||
{
|
||||
return (bool) ($this->position < $this->data_length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Advance past any whitespace
|
||||
*
|
||||
* @return int Number of whitespace characters passed
|
||||
*/
|
||||
public function skip_whitespace()
|
||||
{
|
||||
$whitespace = strspn($this->data, "\x09\x0A\x0D\x20", $this->position);
|
||||
$this->position += $whitespace;
|
||||
return $whitespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read value
|
||||
*/
|
||||
public function get_value()
|
||||
{
|
||||
$quote = substr($this->data, $this->position, 1);
|
||||
if ($quote === '"' || $quote === "'")
|
||||
{
|
||||
$this->position++;
|
||||
$len = strcspn($this->data, $quote, $this->position);
|
||||
if ($this->has_data())
|
||||
{
|
||||
$value = substr($this->data, $this->position, $len);
|
||||
$this->position += $len + 1;
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function before_version_name()
|
||||
{
|
||||
if ($this->skip_whitespace())
|
||||
{
|
||||
$this->state = 'version_name';
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->state = false;
|
||||
}
|
||||
}
|
||||
|
||||
public function version_name()
|
||||
{
|
||||
if (substr($this->data, $this->position, 7) === 'version')
|
||||
{
|
||||
$this->position += 7;
|
||||
$this->skip_whitespace();
|
||||
$this->state = 'version_equals';
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->state = false;
|
||||
}
|
||||
}
|
||||
|
||||
public function version_equals()
|
||||
{
|
||||
if (substr($this->data, $this->position, 1) === '=')
|
||||
{
|
||||
$this->position++;
|
||||
$this->skip_whitespace();
|
||||
$this->state = 'version_value';
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->state = false;
|
||||
}
|
||||
}
|
||||
|
||||
public function version_value()
|
||||
{
|
||||
if ($this->version = $this->get_value())
|
||||
{
|
||||
$this->skip_whitespace();
|
||||
if ($this->has_data())
|
||||
{
|
||||
$this->state = 'encoding_name';
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->state = 'emit';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->state = false;
|
||||
}
|
||||
}
|
||||
|
||||
public function encoding_name()
|
||||
{
|
||||
if (substr($this->data, $this->position, 8) === 'encoding')
|
||||
{
|
||||
$this->position += 8;
|
||||
$this->skip_whitespace();
|
||||
$this->state = 'encoding_equals';
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->state = 'standalone_name';
|
||||
}
|
||||
}
|
||||
|
||||
public function encoding_equals()
|
||||
{
|
||||
if (substr($this->data, $this->position, 1) === '=')
|
||||
{
|
||||
$this->position++;
|
||||
$this->skip_whitespace();
|
||||
$this->state = 'encoding_value';
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->state = false;
|
||||
}
|
||||
}
|
||||
|
||||
public function encoding_value()
|
||||
{
|
||||
if ($this->encoding = $this->get_value())
|
||||
{
|
||||
$this->skip_whitespace();
|
||||
if ($this->has_data())
|
||||
{
|
||||
$this->state = 'standalone_name';
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->state = 'emit';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->state = false;
|
||||
}
|
||||
}
|
||||
|
||||
public function standalone_name()
|
||||
{
|
||||
if (substr($this->data, $this->position, 10) === 'standalone')
|
||||
{
|
||||
$this->position += 10;
|
||||
$this->skip_whitespace();
|
||||
$this->state = 'standalone_equals';
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->state = false;
|
||||
}
|
||||
}
|
||||
|
||||
public function standalone_equals()
|
||||
{
|
||||
if (substr($this->data, $this->position, 1) === '=')
|
||||
{
|
||||
$this->position++;
|
||||
$this->skip_whitespace();
|
||||
$this->state = 'standalone_value';
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->state = false;
|
||||
}
|
||||
}
|
||||
|
||||
public function standalone_value()
|
||||
{
|
||||
if ($standalone = $this->get_value())
|
||||
{
|
||||
switch ($standalone)
|
||||
{
|
||||
case 'yes':
|
||||
$this->standalone = true;
|
||||
break;
|
||||
|
||||
case 'no':
|
||||
$this->standalone = false;
|
||||
break;
|
||||
|
||||
default:
|
||||
$this->state = false;
|
||||
return;
|
||||
}
|
||||
|
||||
$this->skip_whitespace();
|
||||
if ($this->has_data())
|
||||
{
|
||||
$this->state = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->state = 'emit';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->state = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
371
Kapitel_7/Lektion_4/wordpress/wp-includes/SimplePie/gzdecode.php
Executable file
371
Kapitel_7/Lektion_4/wordpress/wp-includes/SimplePie/gzdecode.php
Executable file
@@ -0,0 +1,371 @@
|
||||
<?php
|
||||
/**
|
||||
* SimplePie
|
||||
*
|
||||
* A PHP-Based RSS and Atom Feed Framework.
|
||||
* Takes the hard work out of managing a complete RSS/Atom solution.
|
||||
*
|
||||
* Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* * Neither the name of the SimplePie Team nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDERS
|
||||
* AND 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.
|
||||
*
|
||||
* @package SimplePie
|
||||
* @version 1.3.1
|
||||
* @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
|
||||
* @author Ryan Parman
|
||||
* @author Geoffrey Sneddon
|
||||
* @author Ryan McCue
|
||||
* @link http://simplepie.org/ SimplePie
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Decode 'gzip' encoded HTTP data
|
||||
*
|
||||
* @package SimplePie
|
||||
* @subpackage HTTP
|
||||
* @link http://www.gzip.org/format.txt
|
||||
*/
|
||||
class SimplePie_gzdecode
|
||||
{
|
||||
/**
|
||||
* Compressed data
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
* @see gzdecode::$data
|
||||
*/
|
||||
var $compressed_data;
|
||||
|
||||
/**
|
||||
* Size of compressed data
|
||||
*
|
||||
* @access private
|
||||
* @var int
|
||||
*/
|
||||
var $compressed_size;
|
||||
|
||||
/**
|
||||
* Minimum size of a valid gzip string
|
||||
*
|
||||
* @access private
|
||||
* @var int
|
||||
*/
|
||||
var $min_compressed_size = 18;
|
||||
|
||||
/**
|
||||
* Current position of pointer
|
||||
*
|
||||
* @access private
|
||||
* @var int
|
||||
*/
|
||||
var $position = 0;
|
||||
|
||||
/**
|
||||
* Flags (FLG)
|
||||
*
|
||||
* @access private
|
||||
* @var int
|
||||
*/
|
||||
var $flags;
|
||||
|
||||
/**
|
||||
* Uncompressed data
|
||||
*
|
||||
* @access public
|
||||
* @see gzdecode::$compressed_data
|
||||
* @var string
|
||||
*/
|
||||
var $data;
|
||||
|
||||
/**
|
||||
* Modified time
|
||||
*
|
||||
* @access public
|
||||
* @var int
|
||||
*/
|
||||
var $MTIME;
|
||||
|
||||
/**
|
||||
* Extra Flags
|
||||
*
|
||||
* @access public
|
||||
* @var int
|
||||
*/
|
||||
var $XFL;
|
||||
|
||||
/**
|
||||
* Operating System
|
||||
*
|
||||
* @access public
|
||||
* @var int
|
||||
*/
|
||||
var $OS;
|
||||
|
||||
/**
|
||||
* Subfield ID 1
|
||||
*
|
||||
* @access public
|
||||
* @see gzdecode::$extra_field
|
||||
* @see gzdecode::$SI2
|
||||
* @var string
|
||||
*/
|
||||
var $SI1;
|
||||
|
||||
/**
|
||||
* Subfield ID 2
|
||||
*
|
||||
* @access public
|
||||
* @see gzdecode::$extra_field
|
||||
* @see gzdecode::$SI1
|
||||
* @var string
|
||||
*/
|
||||
var $SI2;
|
||||
|
||||
/**
|
||||
* Extra field content
|
||||
*
|
||||
* @access public
|
||||
* @see gzdecode::$SI1
|
||||
* @see gzdecode::$SI2
|
||||
* @var string
|
||||
*/
|
||||
var $extra_field;
|
||||
|
||||
/**
|
||||
* Original filename
|
||||
*
|
||||
* @access public
|
||||
* @var string
|
||||
*/
|
||||
var $filename;
|
||||
|
||||
/**
|
||||
* Human readable comment
|
||||
*
|
||||
* @access public
|
||||
* @var string
|
||||
*/
|
||||
var $comment;
|
||||
|
||||
/**
|
||||
* Don't allow anything to be set
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function __set($name, $value)
|
||||
{
|
||||
trigger_error("Cannot write property $name", E_USER_ERROR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the compressed string and related properties
|
||||
*
|
||||
* @param string $data
|
||||
*/
|
||||
public function __construct($data)
|
||||
{
|
||||
$this->compressed_data = $data;
|
||||
$this->compressed_size = strlen($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode the GZIP stream
|
||||
*
|
||||
* @return bool Successfulness
|
||||
*/
|
||||
public function parse()
|
||||
{
|
||||
if ($this->compressed_size >= $this->min_compressed_size)
|
||||
{
|
||||
// Check ID1, ID2, and CM
|
||||
if (substr($this->compressed_data, 0, 3) !== "\x1F\x8B\x08")
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the FLG (FLaGs)
|
||||
$this->flags = ord($this->compressed_data[3]);
|
||||
|
||||
// FLG bits above (1 << 4) are reserved
|
||||
if ($this->flags > 0x1F)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Advance the pointer after the above
|
||||
$this->position += 4;
|
||||
|
||||
// MTIME
|
||||
$mtime = substr($this->compressed_data, $this->position, 4);
|
||||
// Reverse the string if we're on a big-endian arch because l is the only signed long and is machine endianness
|
||||
if (current(unpack('S', "\x00\x01")) === 1)
|
||||
{
|
||||
$mtime = strrev($mtime);
|
||||
}
|
||||
$this->MTIME = current(unpack('l', $mtime));
|
||||
$this->position += 4;
|
||||
|
||||
// Get the XFL (eXtra FLags)
|
||||
$this->XFL = ord($this->compressed_data[$this->position++]);
|
||||
|
||||
// Get the OS (Operating System)
|
||||
$this->OS = ord($this->compressed_data[$this->position++]);
|
||||
|
||||
// Parse the FEXTRA
|
||||
if ($this->flags & 4)
|
||||
{
|
||||
// Read subfield IDs
|
||||
$this->SI1 = $this->compressed_data[$this->position++];
|
||||
$this->SI2 = $this->compressed_data[$this->position++];
|
||||
|
||||
// SI2 set to zero is reserved for future use
|
||||
if ($this->SI2 === "\x00")
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the length of the extra field
|
||||
$len = current(unpack('v', substr($this->compressed_data, $this->position, 2)));
|
||||
$this->position += 2;
|
||||
|
||||
// Check the length of the string is still valid
|
||||
$this->min_compressed_size += $len + 4;
|
||||
if ($this->compressed_size >= $this->min_compressed_size)
|
||||
{
|
||||
// Set the extra field to the given data
|
||||
$this->extra_field = substr($this->compressed_data, $this->position, $len);
|
||||
$this->position += $len;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Parse the FNAME
|
||||
if ($this->flags & 8)
|
||||
{
|
||||
// Get the length of the filename
|
||||
$len = strcspn($this->compressed_data, "\x00", $this->position);
|
||||
|
||||
// Check the length of the string is still valid
|
||||
$this->min_compressed_size += $len + 1;
|
||||
if ($this->compressed_size >= $this->min_compressed_size)
|
||||
{
|
||||
// Set the original filename to the given string
|
||||
$this->filename = substr($this->compressed_data, $this->position, $len);
|
||||
$this->position += $len + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Parse the FCOMMENT
|
||||
if ($this->flags & 16)
|
||||
{
|
||||
// Get the length of the comment
|
||||
$len = strcspn($this->compressed_data, "\x00", $this->position);
|
||||
|
||||
// Check the length of the string is still valid
|
||||
$this->min_compressed_size += $len + 1;
|
||||
if ($this->compressed_size >= $this->min_compressed_size)
|
||||
{
|
||||
// Set the original comment to the given string
|
||||
$this->comment = substr($this->compressed_data, $this->position, $len);
|
||||
$this->position += $len + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Parse the FHCRC
|
||||
if ($this->flags & 2)
|
||||
{
|
||||
// Check the length of the string is still valid
|
||||
$this->min_compressed_size += $len + 2;
|
||||
if ($this->compressed_size >= $this->min_compressed_size)
|
||||
{
|
||||
// Read the CRC
|
||||
$crc = current(unpack('v', substr($this->compressed_data, $this->position, 2)));
|
||||
|
||||
// Check the CRC matches
|
||||
if ((crc32(substr($this->compressed_data, 0, $this->position)) & 0xFFFF) === $crc)
|
||||
{
|
||||
$this->position += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Decompress the actual data
|
||||
if (($this->data = gzinflate(substr($this->compressed_data, $this->position, -8))) === false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->position = $this->compressed_size - 8;
|
||||
}
|
||||
|
||||
// Check CRC of data
|
||||
$crc = current(unpack('V', substr($this->compressed_data, $this->position, 4)));
|
||||
$this->position += 4;
|
||||
/*if (extension_loaded('hash') && sprintf('%u', current(unpack('V', hash('crc32b', $this->data)))) !== sprintf('%u', $crc))
|
||||
{
|
||||
return false;
|
||||
}*/
|
||||
|
||||
// Check ISIZE of data
|
||||
$isize = current(unpack('V', substr($this->compressed_data, $this->position, 4)));
|
||||
$this->position += 4;
|
||||
if (sprintf('%u', strlen($this->data) & 0xFFFFFFFF) !== sprintf('%u', $isize))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Wow, against all odds, we've actually got a valid gzip string
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
506
Kapitel_7/Lektion_4/wordpress/wp-includes/Text/Diff.php
Executable file
506
Kapitel_7/Lektion_4/wordpress/wp-includes/Text/Diff.php
Executable file
@@ -0,0 +1,506 @@
|
||||
<?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 __construct( $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);
|
||||
}
|
||||
|
||||
/**
|
||||
* PHP4 constructor.
|
||||
*/
|
||||
public function Text_Diff( $engine, $params ) {
|
||||
self::__construct( $engine, $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.
|
||||
*/
|
||||
static 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 __construct($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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* PHP4 constructor.
|
||||
*/
|
||||
public function Text_MappedDiff( $from_lines, $to_lines,
|
||||
$mapped_from_lines, $mapped_to_lines ) {
|
||||
self::__construct( $from_lines, $to_lines,
|
||||
$mapped_from_lines, $mapped_to_lines );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 {
|
||||
|
||||
/**
|
||||
* PHP5 constructor.
|
||||
*/
|
||||
function __construct( $orig, $final = false )
|
||||
{
|
||||
if (!is_array($final)) {
|
||||
$final = $orig;
|
||||
}
|
||||
$this->orig = $orig;
|
||||
$this->final = $final;
|
||||
}
|
||||
|
||||
/**
|
||||
* PHP4 constructor.
|
||||
*/
|
||||
public function Text_Diff_Op_copy( $orig, $final = false ) {
|
||||
self::__construct( $orig, $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 {
|
||||
|
||||
/**
|
||||
* PHP5 constructor.
|
||||
*/
|
||||
function __construct( $lines )
|
||||
{
|
||||
$this->orig = $lines;
|
||||
$this->final = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* PHP4 constructor.
|
||||
*/
|
||||
public function Text_Diff_Op_delete( $lines ) {
|
||||
self::__construct( $lines );
|
||||
}
|
||||
|
||||
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 {
|
||||
|
||||
/**
|
||||
* PHP5 constructor.
|
||||
*/
|
||||
function __construct( $lines )
|
||||
{
|
||||
$this->final = $lines;
|
||||
$this->orig = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* PHP4 constructor.
|
||||
*/
|
||||
public function Text_Diff_Op_add( $lines ) {
|
||||
self::__construct( $lines );
|
||||
}
|
||||
|
||||
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 {
|
||||
|
||||
/**
|
||||
* PHP5 constructor.
|
||||
*/
|
||||
function __construct( $orig, $final )
|
||||
{
|
||||
$this->orig = $orig;
|
||||
$this->final = $final;
|
||||
}
|
||||
|
||||
/**
|
||||
* PHP4 constructor.
|
||||
*/
|
||||
public function Text_Diff_Op_change( $orig, $final ) {
|
||||
self::__construct( $orig, $final );
|
||||
}
|
||||
|
||||
function &reverse()
|
||||
{
|
||||
$reverse = new Text_Diff_Op_change($this->final, $this->orig);
|
||||
return $reverse;
|
||||
}
|
||||
|
||||
}
|
||||
436
Kapitel_7/Lektion_4/wordpress/wp-includes/Text/Diff/Engine/native.php
Executable file
436
Kapitel_7/Lektion_4/wordpress/wp-includes/Text/Diff/Engine/native.php
Executable file
@@ -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]');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
162
Kapitel_7/Lektion_4/wordpress/wp-includes/Text/Diff/Engine/shell.php
Executable file
162
Kapitel_7/Lektion_4/wordpress/wp-includes/Text/Diff/Engine/shell.php
Executable file
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
248
Kapitel_7/Lektion_4/wordpress/wp-includes/Text/Diff/Engine/string.php
Executable file
248
Kapitel_7/Lektion_4/wordpress/wp-includes/Text/Diff/Engine/string.php
Executable file
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
64
Kapitel_7/Lektion_4/wordpress/wp-includes/Text/Diff/Engine/xdiff.php
Executable file
64
Kapitel_7/Lektion_4/wordpress/wp-includes/Text/Diff/Engine/xdiff.php
Executable file
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
242
Kapitel_7/Lektion_4/wordpress/wp-includes/Text/Diff/Renderer.php
Executable file
242
Kapitel_7/Lektion_4/wordpress/wp-includes/Text/Diff/Renderer.php
Executable file
@@ -0,0 +1,242 @@
|
||||
<?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 __construct( $params = array() )
|
||||
{
|
||||
foreach ($params as $param => $value) {
|
||||
$v = '_' . $param;
|
||||
if (isset($this->$v)) {
|
||||
$this->$v = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* PHP4 constructor.
|
||||
*/
|
||||
public function Text_Diff_Renderer( $params = array() ) {
|
||||
self::__construct( $params );
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
}
|
||||
206
Kapitel_7/Lektion_4/wordpress/wp-includes/Text/Diff/Renderer/inline.php
Executable file
206
Kapitel_7/Lektion_4/wordpress/wp-includes/Text/Diff/Renderer/inline.php
Executable file
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
955
Kapitel_7/Lektion_4/wordpress/wp-includes/admin-bar.php
Executable file
955
Kapitel_7/Lektion_4/wordpress/wp-includes/admin-bar.php
Executable file
@@ -0,0 +1,955 @@
|
||||
<?php
|
||||
/**
|
||||
* Toolbar API: Top-level Toolbar functionality
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Toolbar
|
||||
* @since 3.1.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Instantiate the admin bar object and set it up as a global for access elsewhere.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* @global WP_Admin_Bar $wp_admin_bar
|
||||
*
|
||||
* @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_once( ABSPATH . WPINC . '/class-wp-admin-bar.php' );
|
||||
|
||||
/* Instantiate the admin bar */
|
||||
|
||||
/**
|
||||
* Filter the admin bar class to instantiate.
|
||||
*
|
||||
* @since 3.1.0
|
||||
*
|
||||
* @param string $wp_admin_bar_class Admin bar class to use. Default 'WP_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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*
|
||||
* @global WP_Admin_Bar $wp_admin_bar
|
||||
*/
|
||||
function wp_admin_bar_render() {
|
||||
global $wp_admin_bar;
|
||||
|
||||
if ( ! is_admin_bar_showing() || ! is_object( $wp_admin_bar ) )
|
||||
return;
|
||||
|
||||
/**
|
||||
* Load all necessary admin bar items.
|
||||
*
|
||||
* This is the hook used to add, remove, or manipulate admin bar items.
|
||||
*
|
||||
* @since 3.1.0
|
||||
*
|
||||
* @param WP_Admin_Bar $wp_admin_bar WP_Admin_Bar instance, passed by reference
|
||||
*/
|
||||
do_action_ref_array( 'admin_bar_menu', array( &$wp_admin_bar ) );
|
||||
|
||||
/**
|
||||
* Fires before the admin bar is rendered.
|
||||
*
|
||||
* @since 3.1.0
|
||||
*/
|
||||
do_action( 'wp_before_admin_bar_render' );
|
||||
|
||||
$wp_admin_bar->render();
|
||||
|
||||
/**
|
||||
* Fires after the admin bar is rendered.
|
||||
*
|
||||
* @since 3.1.0
|
||||
*/
|
||||
do_action( 'wp_after_admin_bar_render' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the WordPress logo menu.
|
||||
*
|
||||
* @since 3.3.0
|
||||
*
|
||||
* @param WP_Admin_Bar $wp_admin_bar
|
||||
*/
|
||||
function wp_admin_bar_wp_menu( $wp_admin_bar ) {
|
||||
$wp_admin_bar->add_menu( array(
|
||||
'id' => 'wp-logo',
|
||||
'title' => '<span class="ab-icon"></span><span class="screen-reader-text">' . __( 'About WordPress' ) . '</span>',
|
||||
'href' => self_admin_url( 'about.php' ),
|
||||
) );
|
||||
|
||||
if ( is_user_logged_in() ) {
|
||||
// Add "About WordPress" link
|
||||
$wp_admin_bar->add_menu( array(
|
||||
'parent' => 'wp-logo',
|
||||
'id' => 'about',
|
||||
'title' => __('About WordPress'),
|
||||
'href' => self_admin_url( 'about.php' ),
|
||||
) );
|
||||
}
|
||||
|
||||
// Add WordPress.org link
|
||||
$wp_admin_bar->add_menu( array(
|
||||
'parent' => 'wp-logo-external',
|
||||
'id' => 'wporg',
|
||||
'title' => __('WordPress.org'),
|
||||
'href' => __('https://wordpress.org/'),
|
||||
) );
|
||||
|
||||
// Add codex link
|
||||
$wp_admin_bar->add_menu( array(
|
||||
'parent' => 'wp-logo-external',
|
||||
'id' => 'documentation',
|
||||
'title' => __('Documentation'),
|
||||
'href' => __('https://codex.wordpress.org/'),
|
||||
) );
|
||||
|
||||
// Add forums link
|
||||
$wp_admin_bar->add_menu( array(
|
||||
'parent' => 'wp-logo-external',
|
||||
'id' => 'support-forums',
|
||||
'title' => __('Support Forums'),
|
||||
'href' => __('https://wordpress.org/support/'),
|
||||
) );
|
||||
|
||||
// Add feedback link
|
||||
$wp_admin_bar->add_menu( array(
|
||||
'parent' => 'wp-logo-external',
|
||||
'id' => 'feedback',
|
||||
'title' => __('Feedback'),
|
||||
'href' => __('https://wordpress.org/support/forum/requests-and-feedback'),
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the sidebar toggle button.
|
||||
*
|
||||
* @since 3.8.0
|
||||
*
|
||||
* @param WP_Admin_Bar $wp_admin_bar
|
||||
*/
|
||||
function wp_admin_bar_sidebar_toggle( $wp_admin_bar ) {
|
||||
if ( is_admin() ) {
|
||||
$wp_admin_bar->add_menu( array(
|
||||
'id' => 'menu-toggle',
|
||||
'title' => '<span class="ab-icon"></span><span class="screen-reader-text">' . __( 'Menu' ) . '</span>',
|
||||
'href' => '#',
|
||||
) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the "My Account" item.
|
||||
*
|
||||
* @since 3.3.0
|
||||
*
|
||||
* @param WP_Admin_Bar $wp_admin_bar
|
||||
*/
|
||||
function wp_admin_bar_my_account_item( $wp_admin_bar ) {
|
||||
$user_id = get_current_user_id();
|
||||
$current_user = wp_get_current_user();
|
||||
|
||||
if ( ! $user_id )
|
||||
return;
|
||||
|
||||
if ( current_user_can( 'read' ) ) {
|
||||
$profile_url = get_edit_profile_url( $user_id );
|
||||
} elseif ( is_multisite() ) {
|
||||
$profile_url = get_dashboard_url( $user_id, 'profile.php' );
|
||||
} else {
|
||||
$profile_url = false;
|
||||
}
|
||||
|
||||
$avatar = get_avatar( $user_id, 26 );
|
||||
$howdy = sprintf( __('Howdy, %1$s'), $current_user->display_name );
|
||||
$class = empty( $avatar ) ? '' : 'with-avatar';
|
||||
|
||||
$wp_admin_bar->add_menu( array(
|
||||
'id' => 'my-account',
|
||||
'parent' => 'top-secondary',
|
||||
'title' => $howdy . $avatar,
|
||||
'href' => $profile_url,
|
||||
'meta' => array(
|
||||
'class' => $class,
|
||||
),
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the "My Account" submenu items.
|
||||
*
|
||||
* @since 3.1.0
|
||||
*
|
||||
* @param WP_Admin_Bar $wp_admin_bar
|
||||
*/
|
||||
function wp_admin_bar_my_account_menu( $wp_admin_bar ) {
|
||||
$user_id = get_current_user_id();
|
||||
$current_user = wp_get_current_user();
|
||||
|
||||
if ( ! $user_id )
|
||||
return;
|
||||
|
||||
if ( current_user_can( 'read' ) ) {
|
||||
$profile_url = get_edit_profile_url( $user_id );
|
||||
} elseif ( is_multisite() ) {
|
||||
$profile_url = get_dashboard_url( $user_id, 'profile.php' );
|
||||
} else {
|
||||
$profile_url = false;
|
||||
}
|
||||
|
||||
$wp_admin_bar->add_group( array(
|
||||
'parent' => 'my-account',
|
||||
'id' => 'user-actions',
|
||||
) );
|
||||
|
||||
$user_info = get_avatar( $user_id, 64 );
|
||||
$user_info .= "<span class='display-name'>{$current_user->display_name}</span>";
|
||||
|
||||
if ( $current_user->display_name !== $current_user->user_login )
|
||||
$user_info .= "<span class='username'>{$current_user->user_login}</span>";
|
||||
|
||||
$wp_admin_bar->add_menu( array(
|
||||
'parent' => 'user-actions',
|
||||
'id' => 'user-info',
|
||||
'title' => $user_info,
|
||||
'href' => $profile_url,
|
||||
'meta' => array(
|
||||
'tabindex' => -1,
|
||||
),
|
||||
) );
|
||||
|
||||
if ( false !== $profile_url ) {
|
||||
$wp_admin_bar->add_menu( array(
|
||||
'parent' => 'user-actions',
|
||||
'id' => 'edit-profile',
|
||||
'title' => __( 'Edit My Profile' ),
|
||||
'href' => $profile_url,
|
||||
) );
|
||||
}
|
||||
|
||||
$wp_admin_bar->add_menu( array(
|
||||
'parent' => 'user-actions',
|
||||
'id' => 'logout',
|
||||
'title' => __( 'Log Out' ),
|
||||
'href' => wp_logout_url(),
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the "Site Name" menu.
|
||||
*
|
||||
* @since 3.3.0
|
||||
*
|
||||
* @param WP_Admin_Bar $wp_admin_bar
|
||||
*/
|
||||
function wp_admin_bar_site_menu( $wp_admin_bar ) {
|
||||
// Don't show for logged out users.
|
||||
if ( ! is_user_logged_in() )
|
||||
return;
|
||||
|
||||
// Show only when the user is a member of this site, or they're a super admin.
|
||||
if ( ! is_user_member_of_blog() && ! is_super_admin() )
|
||||
return;
|
||||
|
||||
$blogname = get_bloginfo('name');
|
||||
|
||||
if ( ! $blogname ) {
|
||||
$blogname = preg_replace( '#^(https?://)?(www.)?#', '', get_home_url() );
|
||||
}
|
||||
|
||||
if ( is_network_admin() ) {
|
||||
$blogname = sprintf( __('Network Admin: %s'), esc_html( get_current_site()->site_name ) );
|
||||
} elseif ( is_user_admin() ) {
|
||||
$blogname = sprintf( __('User Dashboard: %s'), esc_html( get_current_site()->site_name ) );
|
||||
}
|
||||
|
||||
$title = wp_html_excerpt( $blogname, 40, '…' );
|
||||
|
||||
$wp_admin_bar->add_menu( array(
|
||||
'id' => 'site-name',
|
||||
'title' => $title,
|
||||
'href' => ( is_admin() || ! current_user_can( 'read' ) ) ? home_url( '/' ) : admin_url(),
|
||||
) );
|
||||
|
||||
// Create submenu items.
|
||||
|
||||
if ( is_admin() ) {
|
||||
// Add an option to visit the site.
|
||||
$wp_admin_bar->add_menu( array(
|
||||
'parent' => 'site-name',
|
||||
'id' => 'view-site',
|
||||
'title' => __( 'Visit Site' ),
|
||||
'href' => home_url( '/' ),
|
||||
) );
|
||||
|
||||
if ( is_blog_admin() && is_multisite() && current_user_can( 'manage_sites' ) ) {
|
||||
$wp_admin_bar->add_menu( array(
|
||||
'parent' => 'site-name',
|
||||
'id' => 'edit-site',
|
||||
'title' => __( 'Edit Site' ),
|
||||
'href' => network_admin_url( 'site-info.php?id=' . get_current_blog_id() ),
|
||||
) );
|
||||
}
|
||||
|
||||
} else if ( current_user_can( 'read' ) ) {
|
||||
// We're on the front end, link to the Dashboard.
|
||||
$wp_admin_bar->add_menu( array(
|
||||
'parent' => 'site-name',
|
||||
'id' => 'dashboard',
|
||||
'title' => __( 'Dashboard' ),
|
||||
'href' => admin_url(),
|
||||
) );
|
||||
|
||||
// Add the appearance submenu items.
|
||||
wp_admin_bar_appearance_menu( $wp_admin_bar );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the "Customize" link to the Toolbar.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*
|
||||
* @param WP_Admin_Bar $wp_admin_bar WP_Admin_Bar instance.
|
||||
*/
|
||||
function wp_admin_bar_customize_menu( $wp_admin_bar ) {
|
||||
// Don't show for users who can't access the customizer or when in the admin.
|
||||
if ( ! current_user_can( 'customize' ) || is_admin() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$current_url = ( is_ssl() ? 'https://' : 'http://' ) . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
|
||||
$customize_url = add_query_arg( 'url', urlencode( $current_url ), wp_customize_url() );
|
||||
|
||||
$wp_admin_bar->add_menu( array(
|
||||
'id' => 'customize',
|
||||
'title' => __( 'Customize' ),
|
||||
'href' => $customize_url,
|
||||
'meta' => array(
|
||||
'class' => 'hide-if-no-customize',
|
||||
),
|
||||
) );
|
||||
add_action( 'wp_before_admin_bar_render', 'wp_customize_support_script' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the "My Sites/[Site Name]" menu and all submenus.
|
||||
*
|
||||
* @since 3.1.0
|
||||
*
|
||||
* @param WP_Admin_Bar $wp_admin_bar
|
||||
*/
|
||||
function wp_admin_bar_my_sites_menu( $wp_admin_bar ) {
|
||||
// Don't show for logged out users or single site mode.
|
||||
if ( ! is_user_logged_in() || ! is_multisite() )
|
||||
return;
|
||||
|
||||
// Show only when the user has at least one site, or they're a super admin.
|
||||
if ( count( $wp_admin_bar->user->blogs ) < 1 && ! is_super_admin() )
|
||||
return;
|
||||
|
||||
if ( $wp_admin_bar->user->active_blog ) {
|
||||
$my_sites_url = get_admin_url( $wp_admin_bar->user->active_blog->blog_id, 'my-sites.php' );
|
||||
} else {
|
||||
$my_sites_url = admin_url( 'my-sites.php' );
|
||||
}
|
||||
|
||||
$wp_admin_bar->add_menu( array(
|
||||
'id' => 'my-sites',
|
||||
'title' => __( 'My Sites' ),
|
||||
'href' => $my_sites_url,
|
||||
) );
|
||||
|
||||
if ( is_super_admin() ) {
|
||||
$wp_admin_bar->add_group( array(
|
||||
'parent' => 'my-sites',
|
||||
'id' => 'my-sites-super-admin',
|
||||
) );
|
||||
|
||||
$wp_admin_bar->add_menu( array(
|
||||
'parent' => 'my-sites-super-admin',
|
||||
'id' => 'network-admin',
|
||||
'title' => __('Network Admin'),
|
||||
'href' => network_admin_url(),
|
||||
) );
|
||||
|
||||
$wp_admin_bar->add_menu( array(
|
||||
'parent' => 'network-admin',
|
||||
'id' => 'network-admin-d',
|
||||
'title' => __( 'Dashboard' ),
|
||||
'href' => network_admin_url(),
|
||||
) );
|
||||
$wp_admin_bar->add_menu( array(
|
||||
'parent' => 'network-admin',
|
||||
'id' => 'network-admin-s',
|
||||
'title' => __( 'Sites' ),
|
||||
'href' => network_admin_url( 'sites.php' ),
|
||||
) );
|
||||
$wp_admin_bar->add_menu( array(
|
||||
'parent' => 'network-admin',
|
||||
'id' => 'network-admin-u',
|
||||
'title' => __( 'Users' ),
|
||||
'href' => network_admin_url( 'users.php' ),
|
||||
) );
|
||||
$wp_admin_bar->add_menu( array(
|
||||
'parent' => 'network-admin',
|
||||
'id' => 'network-admin-t',
|
||||
'title' => __( 'Themes' ),
|
||||
'href' => network_admin_url( 'themes.php' ),
|
||||
) );
|
||||
$wp_admin_bar->add_menu( array(
|
||||
'parent' => 'network-admin',
|
||||
'id' => 'network-admin-p',
|
||||
'title' => __( 'Plugins' ),
|
||||
'href' => network_admin_url( 'plugins.php' ),
|
||||
) );
|
||||
$wp_admin_bar->add_menu( array(
|
||||
'parent' => 'network-admin',
|
||||
'id' => 'network-admin-o',
|
||||
'title' => __( 'Settings' ),
|
||||
'href' => network_admin_url( 'settings.php' ),
|
||||
) );
|
||||
}
|
||||
|
||||
// Add site links
|
||||
$wp_admin_bar->add_group( array(
|
||||
'parent' => 'my-sites',
|
||||
'id' => 'my-sites-list',
|
||||
'meta' => array(
|
||||
'class' => is_super_admin() ? 'ab-sub-secondary' : '',
|
||||
),
|
||||
) );
|
||||
|
||||
foreach ( (array) $wp_admin_bar->user->blogs as $blog ) {
|
||||
switch_to_blog( $blog->userblog_id );
|
||||
|
||||
$blavatar = '<div class="blavatar"></div>';
|
||||
|
||||
$blogname = $blog->blogname;
|
||||
|
||||
if ( ! $blogname ) {
|
||||
$blogname = preg_replace( '#^(https?://)?(www.)?#', '', get_home_url() );
|
||||
}
|
||||
|
||||
$menu_id = 'blog-' . $blog->userblog_id;
|
||||
|
||||
$wp_admin_bar->add_menu( array(
|
||||
'parent' => 'my-sites-list',
|
||||
'id' => $menu_id,
|
||||
'title' => $blavatar . $blogname,
|
||||
'href' => admin_url(),
|
||||
) );
|
||||
|
||||
$wp_admin_bar->add_menu( array(
|
||||
'parent' => $menu_id,
|
||||
'id' => $menu_id . '-d',
|
||||
'title' => __( 'Dashboard' ),
|
||||
'href' => admin_url(),
|
||||
) );
|
||||
|
||||
if ( current_user_can( get_post_type_object( 'post' )->cap->create_posts ) ) {
|
||||
$wp_admin_bar->add_menu( array(
|
||||
'parent' => $menu_id,
|
||||
'id' => $menu_id . '-n',
|
||||
'title' => __( 'New Post' ),
|
||||
'href' => admin_url( 'post-new.php' ),
|
||||
) );
|
||||
}
|
||||
|
||||
if ( current_user_can( 'edit_posts' ) ) {
|
||||
$wp_admin_bar->add_menu( array(
|
||||
'parent' => $menu_id,
|
||||
'id' => $menu_id . '-c',
|
||||
'title' => __( 'Manage Comments' ),
|
||||
'href' => admin_url( 'edit-comments.php' ),
|
||||
) );
|
||||
}
|
||||
|
||||
$wp_admin_bar->add_menu( array(
|
||||
'parent' => $menu_id,
|
||||
'id' => $menu_id . '-v',
|
||||
'title' => __( 'Visit Site' ),
|
||||
'href' => home_url( '/' ),
|
||||
) );
|
||||
|
||||
restore_current_blog();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a shortlink.
|
||||
*
|
||||
* @since 3.1.0
|
||||
*
|
||||
* @param WP_Admin_Bar $wp_admin_bar
|
||||
*/
|
||||
function wp_admin_bar_shortlink_menu( $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
|
||||
*
|
||||
* @global WP_Term $tag
|
||||
* @global WP_Query $wp_the_query
|
||||
*
|
||||
* @param WP_Admin_Bar $wp_admin_bar
|
||||
*/
|
||||
function wp_admin_bar_edit_menu( $wp_admin_bar ) {
|
||||
global $tag, $wp_the_query;
|
||||
|
||||
if ( is_admin() ) {
|
||||
$current_screen = get_current_screen();
|
||||
$post = get_post();
|
||||
|
||||
if ( 'post' == $current_screen->base
|
||||
&& 'add' != $current_screen->action
|
||||
&& ( $post_type_object = get_post_type_object( $post->post_type ) )
|
||||
&& current_user_can( 'read_post', $post->ID )
|
||||
&& ( $post_type_object->public )
|
||||
&& ( $post_type_object->show_in_admin_bar ) )
|
||||
{
|
||||
if ( 'draft' == $post->post_status ) {
|
||||
$preview_link = get_preview_post_link( $post );
|
||||
$wp_admin_bar->add_menu( array(
|
||||
'id' => 'preview',
|
||||
'title' => $post_type_object->labels->view_item,
|
||||
'href' => esc_url( $preview_link ),
|
||||
'meta' => array( 'target' => 'wp-preview-' . $post->ID ),
|
||||
) );
|
||||
} else {
|
||||
$wp_admin_bar->add_menu( array(
|
||||
'id' => 'view',
|
||||
'title' => $post_type_object->labels->view_item,
|
||||
'href' => get_permalink( $post->ID )
|
||||
) );
|
||||
}
|
||||
} elseif ( 'term' == $current_screen->base
|
||||
&& isset( $tag ) && is_object( $tag ) && ! is_wp_error( $tag )
|
||||
&& ( $tax = get_taxonomy( $tag->taxonomy ) )
|
||||
&& $tax->public )
|
||||
{
|
||||
$wp_admin_bar->add_menu( array(
|
||||
'id' => 'view',
|
||||
'title' => $tax->labels->view_item,
|
||||
'href' => get_term_link( $tag )
|
||||
) );
|
||||
}
|
||||
} else {
|
||||
$current_object = $wp_the_query->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( 'edit_post', $current_object->ID )
|
||||
&& $post_type_object->show_in_admin_bar
|
||||
&& $edit_post_link = get_edit_post_link( $current_object->ID ) )
|
||||
{
|
||||
$wp_admin_bar->add_menu( array(
|
||||
'id' => 'edit',
|
||||
'title' => $post_type_object->labels->edit_item,
|
||||
'href' => $edit_post_link
|
||||
) );
|
||||
} elseif ( ! empty( $current_object->taxonomy )
|
||||
&& ( $tax = get_taxonomy( $current_object->taxonomy ) )
|
||||
&& current_user_can( $tax->cap->edit_terms )
|
||||
&& $edit_term_link = get_edit_term_link( $current_object->term_id, $current_object->taxonomy ) )
|
||||
{
|
||||
$wp_admin_bar->add_menu( array(
|
||||
'id' => 'edit',
|
||||
'title' => $tax->labels->edit_item,
|
||||
'href' => $edit_term_link
|
||||
) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add "Add New" menu.
|
||||
*
|
||||
* @since 3.1.0
|
||||
*
|
||||
* @param WP_Admin_Bar $wp_admin_bar
|
||||
*/
|
||||
function wp_admin_bar_new_content_menu( $wp_admin_bar ) {
|
||||
$actions = array();
|
||||
|
||||
$cpts = (array) get_post_types( array( 'show_in_admin_bar' => true ), 'objects' );
|
||||
|
||||
if ( isset( $cpts['post'] ) && current_user_can( $cpts['post']->cap->create_posts ) )
|
||||
$actions[ 'post-new.php' ] = array( $cpts['post']->labels->name_admin_bar, 'new-post' );
|
||||
|
||||
if ( isset( $cpts['attachment'] ) && current_user_can( 'upload_files' ) )
|
||||
$actions[ 'media-new.php' ] = array( $cpts['attachment']->labels->name_admin_bar, 'new-media' );
|
||||
|
||||
if ( current_user_can( 'manage_links' ) )
|
||||
$actions[ 'link-add.php' ] = array( _x( 'Link', 'add new from admin bar' ), 'new-link' );
|
||||
|
||||
if ( isset( $cpts['page'] ) && current_user_can( $cpts['page']->cap->create_posts ) )
|
||||
$actions[ 'post-new.php?post_type=page' ] = array( $cpts['page']->labels->name_admin_bar, 'new-page' );
|
||||
|
||||
unset( $cpts['post'], $cpts['page'], $cpts['attachment'] );
|
||||
|
||||
// Add any additional custom post types.
|
||||
foreach ( $cpts as $cpt ) {
|
||||
if ( ! current_user_can( $cpt->cap->create_posts ) )
|
||||
continue;
|
||||
|
||||
$key = 'post-new.php?post_type=' . $cpt->name;
|
||||
$actions[ $key ] = array( $cpt->labels->name_admin_bar, 'new-' . $cpt->name );
|
||||
}
|
||||
// Avoid clash with parent node and a 'content' post type.
|
||||
if ( isset( $actions['post-new.php?post_type=content'] ) )
|
||||
$actions['post-new.php?post_type=content'][1] = 'add-new-content';
|
||||
|
||||
if ( current_user_can( 'create_users' ) || current_user_can( 'promote_users' ) )
|
||||
$actions[ 'user-new.php' ] = array( _x( 'User', 'add new from admin bar' ), 'new-user' );
|
||||
|
||||
if ( ! $actions )
|
||||
return;
|
||||
|
||||
$title = '<span class="ab-icon"></span><span class="ab-label">' . _x( 'New', 'admin bar menu group label' ) . '</span>';
|
||||
|
||||
$wp_admin_bar->add_menu( array(
|
||||
'id' => 'new-content',
|
||||
'title' => $title,
|
||||
'href' => admin_url( current( array_keys( $actions ) ) ),
|
||||
) );
|
||||
|
||||
foreach ( $actions as $link => $action ) {
|
||||
list( $title, $id ) = $action;
|
||||
|
||||
$wp_admin_bar->add_menu( array(
|
||||
'parent' => 'new-content',
|
||||
'id' => $id,
|
||||
'title' => $title,
|
||||
'href' => admin_url( $link )
|
||||
) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add edit comments link with awaiting moderation count bubble.
|
||||
*
|
||||
* @since 3.1.0
|
||||
*
|
||||
* @param WP_Admin_Bar $wp_admin_bar
|
||||
*/
|
||||
function wp_admin_bar_comments_menu( $wp_admin_bar ) {
|
||||
if ( !current_user_can('edit_posts') )
|
||||
return;
|
||||
|
||||
$awaiting_mod = wp_count_comments();
|
||||
$awaiting_mod = $awaiting_mod->moderated;
|
||||
$awaiting_text = sprintf( _n( '%s comment awaiting moderation', '%s comments awaiting moderation', $awaiting_mod ), number_format_i18n( $awaiting_mod ) );
|
||||
|
||||
$icon = '<span class="ab-icon"></span>';
|
||||
$title = '<span id="ab-awaiting-mod" class="ab-label awaiting-mod pending-count count-' . $awaiting_mod . '" aria-hidden="true">' . number_format_i18n( $awaiting_mod ) . '</span>';
|
||||
$title .= '<span class="screen-reader-text">' . $awaiting_text . '</span>';
|
||||
|
||||
$wp_admin_bar->add_menu( array(
|
||||
'id' => 'comments',
|
||||
'title' => $icon . $title,
|
||||
'href' => admin_url('edit-comments.php'),
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add appearance submenu items to the "Site Name" menu.
|
||||
*
|
||||
* @since 3.1.0
|
||||
*
|
||||
* @param WP_Admin_Bar $wp_admin_bar
|
||||
*/
|
||||
function wp_admin_bar_appearance_menu( $wp_admin_bar ) {
|
||||
$wp_admin_bar->add_group( array( 'parent' => 'site-name', 'id' => 'appearance' ) );
|
||||
|
||||
if ( current_user_can( 'switch_themes' ) ) {
|
||||
$wp_admin_bar->add_menu( array(
|
||||
'parent' => 'appearance',
|
||||
'id' => 'themes',
|
||||
'title' => __( 'Themes' ),
|
||||
'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') ) );
|
||||
|
||||
if ( current_theme_supports( 'custom-background' ) ) {
|
||||
$wp_admin_bar->add_menu( array(
|
||||
'parent' => 'appearance',
|
||||
'id' => 'background',
|
||||
'title' => __( 'Background' ),
|
||||
'href' => admin_url( 'themes.php?page=custom-background' ),
|
||||
'meta' => array(
|
||||
'class' => 'hide-if-customize',
|
||||
),
|
||||
) );
|
||||
}
|
||||
|
||||
if ( current_theme_supports( 'custom-header' ) ) {
|
||||
$wp_admin_bar->add_menu( array(
|
||||
'parent' => 'appearance',
|
||||
'id' => 'header',
|
||||
'title' => __( 'Header' ),
|
||||
'href' => admin_url( 'themes.php?page=custom-header' ),
|
||||
'meta' => array(
|
||||
'class' => 'hide-if-customize',
|
||||
),
|
||||
) );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide an update link if theme/plugin/core updates are available.
|
||||
*
|
||||
* @since 3.1.0
|
||||
*
|
||||
* @param WP_Admin_Bar $wp_admin_bar
|
||||
*/
|
||||
function wp_admin_bar_updates_menu( $wp_admin_bar ) {
|
||||
|
||||
$update_data = wp_get_update_data();
|
||||
|
||||
if ( !$update_data['counts']['total'] )
|
||||
return;
|
||||
|
||||
$title = '<span class="ab-icon"></span><span class="ab-label">' . number_format_i18n( $update_data['counts']['total'] ) . '</span>';
|
||||
$title .= '<span class="screen-reader-text">' . $update_data['title'] . '</span>';
|
||||
|
||||
$wp_admin_bar->add_menu( array(
|
||||
'id' => 'updates',
|
||||
'title' => $title,
|
||||
'href' => network_admin_url( 'update-core.php' ),
|
||||
'meta' => array(
|
||||
'title' => $update_data['title'],
|
||||
),
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add search form.
|
||||
*
|
||||
* @since 3.3.0
|
||||
*
|
||||
* @param WP_Admin_Bar $wp_admin_bar
|
||||
*/
|
||||
function wp_admin_bar_search_menu( $wp_admin_bar ) {
|
||||
if ( is_admin() )
|
||||
return;
|
||||
|
||||
$form = '<form action="' . esc_url( home_url( '/' ) ) . '" method="get" id="adminbarsearch">';
|
||||
$form .= '<input class="adminbar-input" name="s" id="adminbar-search" type="text" value="" maxlength="150" />';
|
||||
$form .= '<label for="adminbar-search" class="screen-reader-text">' . __( 'Search' ) . '</label>';
|
||||
$form .= '<input type="submit" class="adminbar-button" value="' . __('Search') . '"/>';
|
||||
$form .= '</form>';
|
||||
|
||||
$wp_admin_bar->add_menu( array(
|
||||
'parent' => 'top-secondary',
|
||||
'id' => 'search',
|
||||
'title' => $form,
|
||||
'meta' => array(
|
||||
'class' => 'admin-bar-search',
|
||||
'tabindex' => -1,
|
||||
)
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add secondary menus.
|
||||
*
|
||||
* @since 3.3.0
|
||||
*
|
||||
* @param WP_Admin_Bar $wp_admin_bar
|
||||
*/
|
||||
function wp_admin_bar_add_secondary_groups( $wp_admin_bar ) {
|
||||
$wp_admin_bar->add_group( array(
|
||||
'id' => 'top-secondary',
|
||||
'meta' => array(
|
||||
'class' => 'ab-top-secondary',
|
||||
),
|
||||
) );
|
||||
|
||||
$wp_admin_bar->add_group( array(
|
||||
'parent' => 'wp-logo',
|
||||
'id' => 'wp-logo-external',
|
||||
'meta' => array(
|
||||
'class' => 'ab-sub-secondary',
|
||||
),
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* 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" media="screen">
|
||||
html { margin-top: 32px !important; }
|
||||
* html body { margin-top: 32px !important; }
|
||||
@media screen and ( max-width: 782px ) {
|
||||
html { margin-top: 46px !important; }
|
||||
* html body { margin-top: 46px !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
|
||||
*
|
||||
* @global bool $show_admin_bar
|
||||
*
|
||||
* @param bool $show Whether to allow the admin bar to show.
|
||||
*/
|
||||
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
|
||||
*
|
||||
* @global bool $show_admin_bar
|
||||
* @global string $pagenow
|
||||
*
|
||||
* @return bool Whether the admin bar should be showing.
|
||||
*/
|
||||
function is_admin_bar_showing() {
|
||||
global $show_admin_bar, $pagenow;
|
||||
|
||||
// For all these types of requests, we never want an admin bar.
|
||||
if ( defined('XMLRPC_REQUEST') || defined('DOING_AJAX') || defined('IFRAME_REQUEST') )
|
||||
return false;
|
||||
|
||||
if ( is_embed() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Integrated into the admin.
|
||||
if ( is_admin() )
|
||||
return true;
|
||||
|
||||
if ( ! isset( $show_admin_bar ) ) {
|
||||
if ( ! is_user_logged_in() || 'wp-login.php' == $pagenow ) {
|
||||
$show_admin_bar = false;
|
||||
} else {
|
||||
$show_admin_bar = _get_admin_bar_pref();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter whether to show the admin bar.
|
||||
*
|
||||
* Returning false to this hook is the recommended way to hide the admin bar.
|
||||
* The user's display preference is used for logged in users.
|
||||
*
|
||||
* @since 3.1.0
|
||||
*
|
||||
* @param bool $show_admin_bar Whether the admin bar should be shown. Default false.
|
||||
*/
|
||||
$show_admin_bar = apply_filters( 'show_admin_bar', $show_admin_bar );
|
||||
|
||||
return $show_admin_bar;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the admin bar display preference of a user.
|
||||
*
|
||||
* @since 3.1.0
|
||||
* @access private
|
||||
*
|
||||
* @param string $context Context of this preference check. Defaults to 'front'. The 'admin'
|
||||
* preference is no longer used.
|
||||
* @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 = 'front', $user = 0 ) {
|
||||
$pref = get_user_option( "show_admin_bar_{$context}", $user );
|
||||
if ( false === $pref )
|
||||
return true;
|
||||
|
||||
return 'true' === $pref;
|
||||
}
|
||||
363
Kapitel_7/Lektion_4/wordpress/wp-includes/atomlib.php
Executable file
363
Kapitel_7/Lektion_4/wordpress/wp-includes/atomlib.php
Executable file
@@ -0,0 +1,363 @@
|
||||
<?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.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* PHP5 constructor.
|
||||
*/
|
||||
function __construct() {
|
||||
|
||||
$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]}\"";');
|
||||
}
|
||||
|
||||
/**
|
||||
* PHP4 constructor.
|
||||
*/
|
||||
public function AtomParser() {
|
||||
self::__construct();
|
||||
}
|
||||
|
||||
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))) {
|
||||
/* translators: 1: error message, 2: line number */
|
||||
trigger_error(sprintf(__('XML Error: %1$s at line %2$s')."\n",
|
||||
xml_error_string(xml_get_error_code($parser)),
|
||||
xml_get_current_line_number($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 );
|
||||
}
|
||||
}
|
||||
499
Kapitel_7/Lektion_4/wordpress/wp-includes/author-template.php
Executable file
499
Kapitel_7/Lektion_4/wordpress/wp-includes/author-template.php
Executable file
@@ -0,0 +1,499 @@
|
||||
<?php
|
||||
/**
|
||||
* Author Template functions for use in themes.
|
||||
*
|
||||
* These functions must be used within the WordPress Loop.
|
||||
*
|
||||
* @link https://codex.wordpress.org/Author_Templates
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Template
|
||||
*/
|
||||
|
||||
/**
|
||||
* Retrieve the author of the current post.
|
||||
*
|
||||
* @since 1.5.0
|
||||
*
|
||||
* @global object $authordata The current author's DB object.
|
||||
*
|
||||
* @param string $deprecated Deprecated.
|
||||
* @return string|null The author's display name.
|
||||
*/
|
||||
function get_the_author($deprecated = '') {
|
||||
global $authordata;
|
||||
|
||||
if ( !empty( $deprecated ) )
|
||||
_deprecated_argument( __FUNCTION__, '2.1' );
|
||||
|
||||
/**
|
||||
* Filter the display name of the current post's author.
|
||||
*
|
||||
* @since 2.9.0
|
||||
*
|
||||
* @param string $authordata->display_name The author's display name.
|
||||
*/
|
||||
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 compatibility has to be maintained.
|
||||
*
|
||||
* @since 0.71
|
||||
* @see get_the_author()
|
||||
* @link https://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|null 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 ( true !== $deprecated_echo ) {
|
||||
_deprecated_argument( __FUNCTION__, '1.5',
|
||||
/* translators: %s: get_the_author() */
|
||||
sprintf( __( 'Use %s instead if you do not want the value echoed.' ),
|
||||
'<code>get_the_author()</code>'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if ( $deprecated_echo ) {
|
||||
echo get_the_author();
|
||||
}
|
||||
|
||||
return get_the_author();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the author who last edited the current post.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @return string|void The author's display name.
|
||||
*/
|
||||
function get_the_modified_author() {
|
||||
if ( $last_id = get_post_meta( get_post()->ID, '_edit_last', true) ) {
|
||||
$last_user = get_userdata($last_id);
|
||||
|
||||
/**
|
||||
* Filter the display name of the author who last edited the current post.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @param string $last_user->display_name The author's display name.
|
||||
*/
|
||||
return apply_filters('the_modified_author', $last_user->display_name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the name of the author who last edited the current post,
|
||||
* if the author's ID is available.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @see get_the_author()
|
||||
*/
|
||||
function the_modified_author() {
|
||||
echo get_the_modified_author();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the requested data of the author of the current post.
|
||||
* @link https://codex.wordpress.org/Template_Tags/the_author_meta
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @global object $authordata The current author's DB object.
|
||||
*
|
||||
* @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 ) {
|
||||
$original_user_id = $user_id;
|
||||
|
||||
if ( ! $user_id ) {
|
||||
global $authordata;
|
||||
$user_id = isset( $authordata->ID ) ? $authordata->ID : 0;
|
||||
} else {
|
||||
$authordata = get_userdata( $user_id );
|
||||
}
|
||||
|
||||
if ( in_array( $field, array( 'login', 'pass', 'nicename', 'email', 'url', 'registered', 'activation_key', 'status' ) ) )
|
||||
$field = 'user_' . $field;
|
||||
|
||||
$value = isset( $authordata->$field ) ? $authordata->$field : '';
|
||||
|
||||
/**
|
||||
* Filter the value of the requested user metadata.
|
||||
*
|
||||
* The filter name is dynamic and depends on the $field parameter of the function.
|
||||
*
|
||||
* @since 2.8.0
|
||||
* @since 4.3.0 The `$original_user_id` parameter was added.
|
||||
*
|
||||
* @param string $value The value of the metadata.
|
||||
* @param int $user_id The user ID for the value.
|
||||
* @param int|bool $original_user_id The original user ID, as passed to the function.
|
||||
*/
|
||||
return apply_filters( 'get_the_author_' . $field, $value, $user_id, $original_user_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs the field from the user's DB object. Defaults to current post's author.
|
||||
*
|
||||
* @link https://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.
|
||||
*/
|
||||
function the_author_meta( $field = '', $user_id = false ) {
|
||||
$author_meta = get_the_author_meta( $field, $user_id );
|
||||
|
||||
/**
|
||||
* The value of the requested user metadata.
|
||||
*
|
||||
* The filter name is dynamic and depends on the $field parameter of the function.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @param string $author_meta The value of the metadata.
|
||||
* @param int $user_id The user ID.
|
||||
*/
|
||||
echo apply_filters( 'the_author_' . $field, $author_meta, $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.
|
||||
*
|
||||
* @return string|null An HTML link if the author's url exist in user meta,
|
||||
* else the result of get_the_author().
|
||||
*/
|
||||
function get_the_author_link() {
|
||||
if ( get_the_author_meta('url') ) {
|
||||
return '<a href="' . esc_url( get_the_author_meta('url') ) . '" title="' . esc_attr( sprintf(__("Visit %s’s website"), get_the_author()) ) . '" rel="author 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 https://codex.wordpress.org/Template_Tags/the_author_link
|
||||
*
|
||||
* @since 2.1.0
|
||||
*/
|
||||
function the_author_link() {
|
||||
echo get_the_author_link();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the number of posts by the author of the current post.
|
||||
*
|
||||
* @since 1.5.0
|
||||
*
|
||||
* @return int The number of posts by the author.
|
||||
*/
|
||||
function get_the_author_posts() {
|
||||
$post = get_post();
|
||||
if ( ! $post ) {
|
||||
return 0;
|
||||
}
|
||||
return count_user_posts( $post->post_author, $post->post_type );
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the number of posts by the author of the current post.
|
||||
*
|
||||
* @link https://codex.wordpress.org/Template_Tags/the_author_posts
|
||||
* @since 0.71
|
||||
*/
|
||||
function the_author_posts() {
|
||||
echo get_the_author_posts();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves an HTML link to the author page of the current post's author.
|
||||
*
|
||||
* Returns an HTML-formatted link using get_author_posts_url().
|
||||
*
|
||||
* @since 4.4.0
|
||||
*
|
||||
* @global object $authordata The current author's DB object.
|
||||
*
|
||||
* @return string An HTML link to the author page.
|
||||
*/
|
||||
function get_the_author_posts_link() {
|
||||
global $authordata;
|
||||
if ( ! is_object( $authordata ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$link = sprintf(
|
||||
'<a href="%1$s" title="%2$s" rel="author">%3$s</a>',
|
||||
esc_url( get_author_posts_url( $authordata->ID, $authordata->user_nicename ) ),
|
||||
esc_attr( sprintf( __( 'Posts by %s' ), get_the_author() ) ),
|
||||
get_the_author()
|
||||
);
|
||||
|
||||
/**
|
||||
* Filter the link to the author page of the author of the current post.
|
||||
*
|
||||
* @since 2.9.0
|
||||
*
|
||||
* @param string $link HTML link.
|
||||
*/
|
||||
return apply_filters( 'the_author_posts_link', $link );
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays an HTML link to the author page of the current post's author.
|
||||
*
|
||||
* @since 1.2.0
|
||||
* @since 4.4.0 Converted into a wrapper for get_the_author_posts_link()
|
||||
*
|
||||
* @param string $deprecated Unused.
|
||||
*/
|
||||
function the_author_posts_link( $deprecated = '' ) {
|
||||
if ( ! empty( $deprecated ) ) {
|
||||
_deprecated_argument( __FUNCTION__, '2.1' );
|
||||
}
|
||||
echo get_the_author_posts_link();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the URL to the author page for the user with the ID provided.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @global WP_Rewrite $wp_rewrite
|
||||
*
|
||||
* @param int $author_id Author ID.
|
||||
* @param string $author_nicename Optional. The author's nicename (slug). Default empty.
|
||||
* @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 ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter the URL to the author's page.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @param string $link The URL to the author's page.
|
||||
* @param int $author_id The author's id.
|
||||
* @param string $author_nicename The author's nice name.
|
||||
*/
|
||||
$link = apply_filters( 'author_link', $link, $author_id, $author_nicename );
|
||||
|
||||
return $link;
|
||||
}
|
||||
|
||||
/**
|
||||
* List all the authors of the site, with several options available.
|
||||
*
|
||||
* @link https://codex.wordpress.org/Template_Tags/wp_list_authors
|
||||
*
|
||||
* @since 1.2.0
|
||||
*
|
||||
* @global wpdb $wpdb WordPress database abstraction object.
|
||||
*
|
||||
* @param string|array $args {
|
||||
* Optional. Array or string of default arguments.
|
||||
*
|
||||
* @type string $orderby How to sort the authors. Accepts 'nicename', 'email', 'url', 'registered',
|
||||
* 'user_nicename', 'user_email', 'user_url', 'user_registered', 'name',
|
||||
* 'display_name', 'post_count', 'ID', 'meta_value', 'user_login'. Default 'name'.
|
||||
* @type string $order Sorting direction for $orderby. Accepts 'ASC', 'DESC'. Default 'ASC'.
|
||||
* @type int $number Maximum authors to return or display. Default empty (all authors).
|
||||
* @type bool $optioncount Show the count in parenthesis next to the author's name. Default false.
|
||||
* @type bool $exclude_admin Whether to exclude the 'admin' account, if it exists. Default false.
|
||||
* @type bool $show_fullname Whether to show the author's full name. Default false.
|
||||
* @type bool $hide_empty Whether to hide any authors with no posts. Default true.
|
||||
* @type string $feed If not empty, show a link to the author's feed and use this text as the alt
|
||||
* parameter of the link. Default empty.
|
||||
* @type string $feed_image If not empty, show a link to the author's feed and use this image URL as
|
||||
* clickable anchor. Default empty.
|
||||
* @type string $feed_type The feed type to link to, such as 'rss2'. Defaults to default feed type.
|
||||
* @type bool $echo Whether to output the result or instead return it. Default true.
|
||||
* @type string $style If 'list', each author is wrapped in an `<li>` element, otherwise the authors
|
||||
* will be separated by commas.
|
||||
* @type bool $html Whether to list the items in HTML form or plaintext. Default true.
|
||||
* @type string $exclude An array, comma-, or space-separated list of author IDs to exclude. Default empty.
|
||||
* @type string $exclude An array, comma-, or space-separated list of author IDs to include. Default empty.
|
||||
* }
|
||||
* @return string|void 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, 'exclude' => '', 'include' => ''
|
||||
);
|
||||
|
||||
$args = wp_parse_args( $args, $defaults );
|
||||
|
||||
$return = '';
|
||||
|
||||
$query_args = wp_array_slice_assoc( $args, array( 'orderby', 'order', 'number', 'exclude', 'include' ) );
|
||||
$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 " . 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 ( $args['exclude_admin'] && 'admin' == $author->display_name ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$posts = isset( $author_count[$author->ID] ) ? $author_count[$author->ID] : 0;
|
||||
|
||||
if ( ! $posts && $args['hide_empty'] ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( $args['show_fullname'] && $author->first_name && $author->last_name ) {
|
||||
$name = "$author->first_name $author->last_name";
|
||||
} else {
|
||||
$name = $author->display_name;
|
||||
}
|
||||
|
||||
if ( ! $args['html'] ) {
|
||||
$return .= $name . ', ';
|
||||
|
||||
continue; // No need to go further to process HTML.
|
||||
}
|
||||
|
||||
if ( 'list' == $args['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( $args['feed_image'] ) || ! empty( $args['feed'] ) ) {
|
||||
$link .= ' ';
|
||||
if ( empty( $args['feed_image'] ) ) {
|
||||
$link .= '(';
|
||||
}
|
||||
|
||||
$link .= '<a href="' . get_author_feed_link( $author->ID, $args['feed_type'] ) . '"';
|
||||
|
||||
$alt = '';
|
||||
if ( ! empty( $args['feed'] ) ) {
|
||||
$alt = ' alt="' . esc_attr( $args['feed'] ) . '"';
|
||||
$name = $args['feed'];
|
||||
}
|
||||
|
||||
$link .= '>';
|
||||
|
||||
if ( ! empty( $args['feed_image'] ) ) {
|
||||
$link .= '<img src="' . esc_url( $args['feed_image'] ) . '" style="border: none;"' . $alt . ' />';
|
||||
} else {
|
||||
$link .= $name;
|
||||
}
|
||||
|
||||
$link .= '</a>';
|
||||
|
||||
if ( empty( $args['feed_image'] ) ) {
|
||||
$link .= ')';
|
||||
}
|
||||
}
|
||||
|
||||
if ( $args['optioncount'] ) {
|
||||
$link .= ' ('. $posts . ')';
|
||||
}
|
||||
|
||||
$return .= $link;
|
||||
$return .= ( 'list' == $args['style'] ) ? '</li>' : ', ';
|
||||
}
|
||||
|
||||
$return = rtrim( $return, ', ' );
|
||||
|
||||
if ( ! $args['echo'] ) {
|
||||
return $return;
|
||||
}
|
||||
echo $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this site have more than one author
|
||||
*
|
||||
* Checks to see if more than one author has published posts.
|
||||
*
|
||||
* @since 3.2.0
|
||||
*
|
||||
* @global wpdb $wpdb WordPress database abstraction object.
|
||||
*
|
||||
* @return bool Whether or not we have more than one author
|
||||
*/
|
||||
function is_multi_author() {
|
||||
global $wpdb;
|
||||
|
||||
if ( false === ( $is_multi_author = get_transient( 'is_multi_author' ) ) ) {
|
||||
$rows = (array) $wpdb->get_col("SELECT DISTINCT post_author FROM $wpdb->posts WHERE post_type = 'post' AND post_status = 'publish' LIMIT 2");
|
||||
$is_multi_author = 1 < count( $rows ) ? 1 : 0;
|
||||
set_transient( 'is_multi_author', $is_multi_author );
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter whether the site has more than one author with published posts.
|
||||
*
|
||||
* @since 3.2.0
|
||||
*
|
||||
* @param bool $is_multi_author Whether $is_multi_author should evaluate as true.
|
||||
*/
|
||||
return apply_filters( 'is_multi_author', (bool) $is_multi_author );
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to clear the cache for number of authors.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
function __clear_multi_author_cache() {
|
||||
delete_transient( 'is_multi_author' );
|
||||
}
|
||||
304
Kapitel_7/Lektion_4/wordpress/wp-includes/bookmark-template.php
Executable file
304
Kapitel_7/Lektion_4/wordpress/wp-includes/bookmark-template.php
Executable file
@@ -0,0 +1,304 @@
|
||||
<?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.
|
||||
*
|
||||
* @since 2.1.0
|
||||
* @access private
|
||||
*
|
||||
* @param array $bookmarks List of bookmarks to traverse.
|
||||
* @param string|array $args {
|
||||
* Optional. Bookmarks arguments.
|
||||
*
|
||||
* @type int|bool $show_updated Whether to show the time the bookmark was last updated.
|
||||
* Accepts 1|true or 0|false. Default 0|false.
|
||||
* @type int|bool $show_description Whether to show the bookmakr description. Accepts 1|true,
|
||||
* Accepts 1|true or 0|false. Default 0|false.
|
||||
* @type int|bool $show_images Whether to show the link image if available. Accepts 1|true
|
||||
* or 0|false. Default 1|true.
|
||||
* @type int|bool $show_name Whether to show link name if available. Accepts 1|true or
|
||||
* 0|false. Default 0|false.
|
||||
* @type string $before The HTML or text to prepend to each bookmark. Default `<li>`.
|
||||
* @type string $after The HTML or text to append to each bookmark. Default `</li>`.
|
||||
* @type string $link_before The HTML or text to prepend to each bookmark inside the anchor
|
||||
* tags. Default empty.
|
||||
* @type string $link_after The HTML or text to append to each bookmark inside the anchor
|
||||
* tags. Default empty.
|
||||
* @type string $between The string for use in between the link, description, and image.
|
||||
* Default "\n".
|
||||
* @type int|bool $show_rating Whether to show the link rating. Accepts 1|true or 0|false.
|
||||
* Default 0|false.
|
||||
*
|
||||
* }
|
||||
* @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 );
|
||||
|
||||
$output = ''; // Blank string to start with.
|
||||
|
||||
foreach ( (array) $bookmarks as $bookmark ) {
|
||||
if ( ! isset( $bookmark->recently_updated ) ) {
|
||||
$bookmark->recently_updated = false;
|
||||
}
|
||||
$output .= $r['before'];
|
||||
if ( $r['show_updated'] && $bookmark->recently_updated ) {
|
||||
$output .= '<em>';
|
||||
}
|
||||
$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 ( $r['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' ) * HOUR_IN_SECONDS )
|
||||
)
|
||||
);
|
||||
$title .= ')';
|
||||
}
|
||||
}
|
||||
$alt = ' alt="' . $name . ( $r['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 .= $r['link_before'];
|
||||
|
||||
if ( $bookmark->link_image != null && $r['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 ( $r['show_name'] ) {
|
||||
$output .= " $name";
|
||||
}
|
||||
} else {
|
||||
$output .= $name;
|
||||
}
|
||||
|
||||
$output .= $r['link_after'];
|
||||
|
||||
$output .= '</a>';
|
||||
|
||||
if ( $r['show_updated'] && $bookmark->recently_updated ) {
|
||||
$output .= '</em>';
|
||||
}
|
||||
|
||||
if ( $r['show_description'] && '' != $desc ) {
|
||||
$output .= $r['between'] . $desc;
|
||||
}
|
||||
|
||||
if ( $r['show_rating'] ) {
|
||||
$output .= $r['between'] . sanitize_bookmark_field(
|
||||
'link_rating',
|
||||
$bookmark->link_rating,
|
||||
$bookmark->link_id,
|
||||
'display'
|
||||
);
|
||||
}
|
||||
$output .= $r['after'] . "\n";
|
||||
} // end while
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve or echo all of the bookmarks.
|
||||
*
|
||||
* List of default arguments are as follows:
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @see _walk_bookmarks()
|
||||
*
|
||||
* @param string|array $args {
|
||||
* Optional. String or array of arguments to list bookmarks.
|
||||
*
|
||||
* @type string $orderby How to order the links by. Accepts post fields. Default 'name'.
|
||||
* @type string $order Whether to order bookmarks in ascending or descending order.
|
||||
* Accepts 'ASC' (ascending) or 'DESC' (descending). Default 'ASC'.
|
||||
* @type int $limit Amount of bookmarks to display. Accepts 1+ or -1 for all.
|
||||
* Default -1.
|
||||
* @type string $category Comma-separated list of category ids to include links from.
|
||||
* Default empty.
|
||||
* @type string $category_name Category to retrieve links for by name. Default empty.
|
||||
* @type int|bool $hide_invisible Whether to show or hide links marked as 'invisible'. Accepts
|
||||
* 1|true or 0|false. Default 1|true.
|
||||
* @type int|bool $show_updated Whether to display the time the bookmark was last updated.
|
||||
* Accepts 1|true or 0|false. Default 0|false.
|
||||
* @type int|bool $echo Whether to echo or return the formatted bookmarks. Accepts
|
||||
* 1|true (echo) or 0|false (return). Default 1|true.
|
||||
* @type int|bool $categorize Whether to show links listed by category or in a single column.
|
||||
* Accepts 1|true (by category) or 0|false (one column). Default 1|true.
|
||||
* @type int|bool $show_description Whether to show the bookmark descriptions. Accepts 1|true or 0|false.
|
||||
* Default 0|false.
|
||||
* @type string $title_li What to show before the links appear. Default 'Bookmarks'.
|
||||
* @type string $title_before The HTML or text to prepend to the $title_li string. Default '<h2>'.
|
||||
* @type string $title_after The HTML or text to append to the $title_li string. Default '</h2>'.
|
||||
* @type string $class The CSS class to use for the $title_li. Default 'linkcat'.
|
||||
* @type string $category_before The HTML or text to prepend to $title_before if $categorize is true.
|
||||
* String must contain '%id' and '%class' to inherit the category ID and
|
||||
* the $class argument used for formatting in themes.
|
||||
* Default '<li id="%id" class="%class">'.
|
||||
* @type string $category_after The HTML or text to append to $title_after if $categorize is true.
|
||||
* Default '</li>'.
|
||||
* @type string $category_orderby How to order the bookmark category based on term scheme if $categorize
|
||||
* is true. Default 'name'.
|
||||
* @type string $category_order Whether to order categories in ascending or descending order if
|
||||
* $categorize is true. Accepts 'ASC' (ascending) or 'DESC' (descending).
|
||||
* Default 'ASC'.
|
||||
* }
|
||||
* @return string|void 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 );
|
||||
|
||||
$output = '';
|
||||
|
||||
if ( ! is_array( $r['class'] ) ) {
|
||||
$r['class'] = explode( ' ', $r['class'] );
|
||||
}
|
||||
$r['class'] = array_map( 'sanitize_html_class', $r['class'] );
|
||||
$r['class'] = trim( join( ' ', $r['class'] ) );
|
||||
|
||||
if ( $r['categorize'] ) {
|
||||
$cats = get_terms( 'link_category', array(
|
||||
'name__like' => $r['category_name'],
|
||||
'include' => $r['category'],
|
||||
'exclude' => $r['exclude_category'],
|
||||
'orderby' => $r['category_orderby'],
|
||||
'order' => $r['category_order'],
|
||||
'hierarchical' => 0
|
||||
) );
|
||||
if ( empty( $cats ) ) {
|
||||
$r['categorize'] = false;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $r['categorize'] ) {
|
||||
// Split the bookmarks into ul's for each category
|
||||
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", $r['class'] ),
|
||||
$r['category_before']
|
||||
);
|
||||
/**
|
||||
* Filter the bookmarks category name.
|
||||
*
|
||||
* @since 2.2.0
|
||||
*
|
||||
* @param string $cat_name The category name of bookmarks.
|
||||
*/
|
||||
$catname = apply_filters( 'link_category', $cat->name );
|
||||
|
||||
$output .= $r['title_before'];
|
||||
$output .= $catname;
|
||||
$output .= $r['title_after'];
|
||||
$output .= "\n\t<ul class='xoxo blogroll'>\n";
|
||||
$output .= _walk_bookmarks( $bookmarks, $r );
|
||||
$output .= "\n\t</ul>\n";
|
||||
$output .= $r['category_after'] . "\n";
|
||||
}
|
||||
} else {
|
||||
//output one single list using title_li for the title
|
||||
$bookmarks = get_bookmarks( $r );
|
||||
|
||||
if ( ! empty( $bookmarks ) ) {
|
||||
if ( ! empty( $r['title_li'] ) ) {
|
||||
$output .= str_replace(
|
||||
array( '%id', '%class' ),
|
||||
array( "linkcat-" . $r['category'], $r['class'] ),
|
||||
$r['category_before']
|
||||
);
|
||||
$output .= $r['title_before'];
|
||||
$output .= $r['title_li'];
|
||||
$output .= $r['title_after'];
|
||||
$output .= "\n\t<ul class='xoxo blogroll'>\n";
|
||||
$output .= _walk_bookmarks( $bookmarks, $r );
|
||||
$output .= "\n\t</ul>\n";
|
||||
$output .= $r['category_after'] . "\n";
|
||||
} else {
|
||||
$output .= _walk_bookmarks( $bookmarks, $r );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter the bookmarks list before it is echoed or returned.
|
||||
*
|
||||
* @since 2.5.0
|
||||
*
|
||||
* @param string $html The HTML list of bookmarks.
|
||||
*/
|
||||
$html = apply_filters( 'wp_list_bookmarks', $output );
|
||||
|
||||
if ( ! $r['echo'] ) {
|
||||
return $html;
|
||||
}
|
||||
echo $html;
|
||||
}
|
||||
417
Kapitel_7/Lektion_4/wordpress/wp-includes/bookmark.php
Executable file
417
Kapitel_7/Lektion_4/wordpress/wp-includes/bookmark.php
Executable file
@@ -0,0 +1,417 @@
|
||||
<?php
|
||||
/**
|
||||
* Link/Bookmark API
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Bookmark
|
||||
*/
|
||||
|
||||
/**
|
||||
* Retrieve Bookmark data
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @global wpdb $wpdb WordPress database abstraction object.
|
||||
*
|
||||
* @param int|stdClass $bookmark
|
||||
* @param string $output Optional. Either OBJECT, ARRAY_N, or ARRAY_A constant
|
||||
* @param string $filter Optional, default is 'raw'.
|
||||
* @return array|object|null 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));
|
||||
if ( $_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' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! $_bookmark )
|
||||
return $_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
|
||||
*
|
||||
* @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|WP_Error
|
||||
*/
|
||||
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.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @global wpdb $wpdb WordPress database abstraction object.
|
||||
*
|
||||
* @param string|array $args {
|
||||
* Optional. String or array of arguments to retrieve bookmarks.
|
||||
*
|
||||
* @type string $orderby How to order the links by. Accepts post fields. Default 'name'.
|
||||
* @type string $order Whether to order bookmarks in ascending or descending order.
|
||||
* Accepts 'ASC' (ascending) or 'DESC' (descending). Default 'ASC'.
|
||||
* @type int $limit Amount of bookmarks to display. Accepts 1+ or -1 for all.
|
||||
* Default -1.
|
||||
* @type string $category Comma-separated list of category ids to include links from.
|
||||
* Default empty.
|
||||
* @type string $category_name Category to retrieve links for by name. Default empty.
|
||||
* @type int|bool $hide_invisible Whether to show or hide links marked as 'invisible'. Accepts
|
||||
* 1|true or 0|false. Default 1|true.
|
||||
* @type int|bool $show_updated Whether to display the time the bookmark was last updated.
|
||||
* Accepts 1|true or 0|false. Default 0|false.
|
||||
* @type string $include Comma-separated list of bookmark IDs to include. Default empty.
|
||||
* @type string $exclude Comma-separated list of bookmark IDs to exclude. Default empty.
|
||||
* }
|
||||
* @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 );
|
||||
|
||||
$key = md5( serialize( $r ) );
|
||||
if ( $cache = wp_cache_get( 'get_bookmarks', 'bookmark' ) ) {
|
||||
if ( is_array( $cache ) && isset( $cache[ $key ] ) ) {
|
||||
$bookmarks = $cache[ $key ];
|
||||
/**
|
||||
* Filter the returned list of bookmarks.
|
||||
*
|
||||
* The first time the hook is evaluated in this file, it returns the cached
|
||||
* bookmarks list. The second evaluation returns a cached bookmarks list if the
|
||||
* link category is passed but does not exist. The third evaluation returns
|
||||
* the full cached results.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @see get_bookmarks()
|
||||
*
|
||||
* @param array $bookmarks List of the cached bookmarks.
|
||||
* @param array $r An array of bookmark query arguments.
|
||||
*/
|
||||
return apply_filters( 'get_bookmarks', $bookmarks, $r );
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! is_array( $cache ) ) {
|
||||
$cache = array();
|
||||
}
|
||||
|
||||
$inclusions = '';
|
||||
if ( ! empty( $r['include'] ) ) {
|
||||
$r['exclude'] = ''; //ignore exclude, category, and category_name params if using include
|
||||
$r['category'] = '';
|
||||
$r['category_name'] = '';
|
||||
$inclinks = preg_split( '/[\s,]+/', $r['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( $r['exclude'] ) ) {
|
||||
$exlinks = preg_split( '/[\s,]+/', $r['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( $r['category_name'] ) ) {
|
||||
if ( $r['category'] = get_term_by('name', $r['category_name'], 'link_category') ) {
|
||||
$r['category'] = $r['category']->term_id;
|
||||
} else {
|
||||
$cache[ $key ] = array();
|
||||
wp_cache_set( 'get_bookmarks', $cache, 'bookmark' );
|
||||
/** This filter is documented in wp-includes/bookmark.php */
|
||||
return apply_filters( 'get_bookmarks', array(), $r );
|
||||
}
|
||||
}
|
||||
|
||||
$search = '';
|
||||
if ( ! empty( $r['search'] ) ) {
|
||||
$like = '%' . $wpdb->esc_like( $r['search'] ) . '%';
|
||||
$search = $wpdb->prepare(" AND ( (link_url LIKE %s) OR (link_name LIKE %s) OR (link_description LIKE %s) ) ", $like, $like, $like );
|
||||
}
|
||||
|
||||
$category_query = '';
|
||||
$join = '';
|
||||
if ( ! empty( $r['category'] ) ) {
|
||||
$incategories = preg_split( '/[\s,]+/', $r['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 ( $r['show_updated'] ) {
|
||||
$recently_updated_test = ", IF (DATE_ADD(link_updated, INTERVAL 120 MINUTE) >= NOW(), 1,0) as recently_updated ";
|
||||
} else {
|
||||
$recently_updated_test = '';
|
||||
}
|
||||
|
||||
$get_updated = ( $r['show_updated'] ) ? ', UNIX_TIMESTAMP(link_updated) AS link_updated_f ' : '';
|
||||
|
||||
$orderby = strtolower( $r['orderby'] );
|
||||
$length = '';
|
||||
switch ( $orderby ) {
|
||||
case 'length':
|
||||
$length = ", CHAR_LENGTH(link_name) AS length";
|
||||
break;
|
||||
case 'rand':
|
||||
$orderby = 'rand()';
|
||||
break;
|
||||
case 'link_id':
|
||||
$orderby = "$wpdb->links.link_id";
|
||||
break;
|
||||
default:
|
||||
$orderparams = array();
|
||||
$keys = array( 'link_id', 'link_name', 'link_url', 'link_visible', 'link_rating', 'link_owner', 'link_updated', 'link_notes', 'link_description' );
|
||||
foreach ( explode( ',', $orderby ) as $ordparam ) {
|
||||
$ordparam = trim( $ordparam );
|
||||
|
||||
if ( in_array( 'link_' . $ordparam, $keys ) ) {
|
||||
$orderparams[] = 'link_' . $ordparam;
|
||||
} elseif ( in_array( $ordparam, $keys ) ) {
|
||||
$orderparams[] = $ordparam;
|
||||
}
|
||||
}
|
||||
$orderby = implode( ',', $orderparams );
|
||||
}
|
||||
|
||||
if ( empty( $orderby ) ) {
|
||||
$orderby = 'link_name';
|
||||
}
|
||||
|
||||
$order = strtoupper( $r['order'] );
|
||||
if ( '' !== $order && ! in_array( $order, array( 'ASC', 'DESC' ) ) ) {
|
||||
$order = 'ASC';
|
||||
}
|
||||
|
||||
$visible = '';
|
||||
if ( $r['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 ( $r['limit'] != -1 ) {
|
||||
$query .= ' LIMIT ' . $r['limit'];
|
||||
}
|
||||
|
||||
$results = $wpdb->get_results( $query );
|
||||
|
||||
$cache[ $key ] = $results;
|
||||
wp_cache_set( 'get_bookmarks', $cache, 'bookmark' );
|
||||
|
||||
/** This filter is documented in wp-includes/bookmark.php */
|
||||
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;
|
||||
|
||||
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 ) {
|
||||
/** This filter is documented in wp-includes/post.php */
|
||||
$value = apply_filters( "edit_$field", $value, $bookmark_id );
|
||||
|
||||
if ( 'link_notes' == $field ) {
|
||||
$value = esc_html( $value ); // textarea_escaped
|
||||
} else {
|
||||
$value = esc_attr($value);
|
||||
}
|
||||
} elseif ( 'db' == $context ) {
|
||||
/** This filter is documented in wp-includes/post.php */
|
||||
$value = apply_filters( "pre_$field", $value );
|
||||
} else {
|
||||
/** This filter is documented in wp-includes/post.php */
|
||||
$value = apply_filters( $field, $value, $bookmark_id, $context );
|
||||
|
||||
if ( 'attribute' == $context ) {
|
||||
$value = esc_attr( $value );
|
||||
} elseif ( 'js' == $context ) {
|
||||
$value = esc_js( $value );
|
||||
}
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the bookmark cache.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @param int $bookmark_id Bookmark ID.
|
||||
*/
|
||||
function clean_bookmark_cache( $bookmark_id ) {
|
||||
wp_cache_delete( $bookmark_id, 'bookmark' );
|
||||
wp_cache_delete( 'get_bookmarks', 'bookmark' );
|
||||
clean_object_term_cache( $bookmark_id, 'link');
|
||||
}
|
||||
761
Kapitel_7/Lektion_4/wordpress/wp-includes/cache.php
Executable file
761
Kapitel_7/Lektion_4/wordpress/wp-includes/cache.php
Executable file
@@ -0,0 +1,761 @@
|
||||
<?php
|
||||
/**
|
||||
* Object Cache API
|
||||
*
|
||||
* @link https://codex.wordpress.org/Function_Reference/WP_Cache
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Cache
|
||||
*/
|
||||
|
||||
/**
|
||||
* Adds data to the cache, if the cache key doesn't already exist.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @see WP_Object_Cache::add()
|
||||
* @global WP_Object_Cache $wp_object_cache Object cache global instance.
|
||||
*
|
||||
* @param int|string $key The cache key to use for retrieval later.
|
||||
* @param mixed $data The data to add to the cache.
|
||||
* @param string $group Optional. The group to add the cache to. Enables the same key
|
||||
* to be used across groups. Default empty.
|
||||
* @param int $expire Optional. When the cache data should expire, in seconds.
|
||||
* Default 0 (no expiration).
|
||||
* @return bool False if cache key and group already exist, true on success.
|
||||
*/
|
||||
function wp_cache_add( $key, $data, $group = '', $expire = 0 ) {
|
||||
global $wp_object_cache;
|
||||
|
||||
return $wp_object_cache->add( $key, $data, $group, (int) $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 persistent 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 true Always returns true.
|
||||
*/
|
||||
function wp_cache_close() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrements numeric cache item's value.
|
||||
*
|
||||
* @since 3.3.0
|
||||
*
|
||||
* @see WP_Object_Cache::decr()
|
||||
* @global WP_Object_Cache $wp_object_cache Object cache global instance.
|
||||
*
|
||||
* @param int|string $key The cache key to decrement.
|
||||
* @param int $offset Optional. The amount by which to decrement the item's value. Default 1.
|
||||
* @param string $group Optional. The group the key is in. Default empty.
|
||||
* @return false|int False on failure, the item's new value on success.
|
||||
*/
|
||||
function wp_cache_decr( $key, $offset = 1, $group = '' ) {
|
||||
global $wp_object_cache;
|
||||
|
||||
return $wp_object_cache->decr( $key, $offset, $group );
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the cache contents matching key and group.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @see WP_Object_Cache::delete()
|
||||
* @global WP_Object_Cache $wp_object_cache Object cache global instance.
|
||||
*
|
||||
* @param int|string $key What the contents in the cache are called.
|
||||
* @param string $group Optional. Where the cache contents are grouped. Default empty.
|
||||
* @return bool True on successful removal, false on failure.
|
||||
*/
|
||||
function wp_cache_delete( $key, $group = '' ) {
|
||||
global $wp_object_cache;
|
||||
|
||||
return $wp_object_cache->delete($key, $group);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all cache items.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @see WP_Object_Cache::flush()
|
||||
* @global WP_Object_Cache $wp_object_cache Object cache global instance.
|
||||
*
|
||||
* @return bool False on failure, true on success
|
||||
*/
|
||||
function wp_cache_flush() {
|
||||
global $wp_object_cache;
|
||||
|
||||
return $wp_object_cache->flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the cache contents from the cache by key and group.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @see WP_Object_Cache::get()
|
||||
* @global WP_Object_Cache $wp_object_cache Object cache global instance.
|
||||
*
|
||||
* @param int|string $key The key under which the cache contents are stored.
|
||||
* @param string $group Optional. Where the cache contents are grouped. Default empty.
|
||||
* @param bool $force Optional. Whether to force an update of the local cache from the persistent
|
||||
* cache. Default false.
|
||||
* @param bool $found Optional. Whether the key was found in the cache. Disambiguates a return of false,
|
||||
* a storable value. Passed by reference. Default null.
|
||||
* @return bool|mixed False on failure to retrieve contents or the cache
|
||||
* contents on success
|
||||
*/
|
||||
function wp_cache_get( $key, $group = '', $force = false, &$found = null ) {
|
||||
global $wp_object_cache;
|
||||
|
||||
return $wp_object_cache->get( $key, $group, $force, $found );
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment numeric cache item's value
|
||||
*
|
||||
* @since 3.3.0
|
||||
*
|
||||
* @see WP_Object_Cache::incr()
|
||||
* @global WP_Object_Cache $wp_object_cache Object cache global instance.
|
||||
*
|
||||
* @param int|string $key The key for the cache contents that should be incremented.
|
||||
* @param int $offset Optional. The amount by which to increment the item's value. Default 1.
|
||||
* @param string $group Optional. The group the key is in. Default empty.
|
||||
* @return false|int False on failure, the item's new value on success.
|
||||
*/
|
||||
function wp_cache_incr( $key, $offset = 1, $group = '' ) {
|
||||
global $wp_object_cache;
|
||||
|
||||
return $wp_object_cache->incr( $key, $offset, $group );
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up Object Cache Global and assigns it.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @global WP_Object_Cache $wp_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
|
||||
*
|
||||
* @see WP_Object_Cache::replace()
|
||||
* @global WP_Object_Cache $wp_object_cache Object cache global instance.
|
||||
*
|
||||
* @param int|string $key The key for the cache data that should be replaced.
|
||||
* @param mixed $data The new data to store in the cache.
|
||||
* @param string $group Optional. The group for the cache data that should be replaced.
|
||||
* Default empty.
|
||||
* @param int $expire Optional. When to expire the cache contents, in seconds.
|
||||
* Default 0 (no expiration).
|
||||
* @return bool False if original value does not exist, true if contents were replaced
|
||||
*/
|
||||
function wp_cache_replace( $key, $data, $group = '', $expire = 0 ) {
|
||||
global $wp_object_cache;
|
||||
|
||||
return $wp_object_cache->replace( $key, $data, $group, (int) $expire );
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the data to the cache.
|
||||
*
|
||||
* Differs from wp_cache_add() and wp_cache_replace() in that it will always write data.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @see WP_Object_Cache::set()
|
||||
* @global WP_Object_Cache $wp_object_cache Object cache global instance.
|
||||
*
|
||||
* @param int|string $key The cache key to use for retrieval later.
|
||||
* @param mixed $data The contents to store in the cache.
|
||||
* @param string $group Optional. Where to group the cache contents. Enables the same key
|
||||
* to be used across groups. Default empty.
|
||||
* @param int $expire Optional. When to expire the cache contents, in seconds.
|
||||
* Default 0 (no expiration).
|
||||
* @return bool False on failure, true on success
|
||||
*/
|
||||
function wp_cache_set( $key, $data, $group = '', $expire = 0 ) {
|
||||
global $wp_object_cache;
|
||||
|
||||
return $wp_object_cache->set( $key, $data, $group, (int) $expire );
|
||||
}
|
||||
|
||||
/**
|
||||
* Switches the interal blog ID.
|
||||
*
|
||||
* This changes the blog id used to create keys in blog specific groups.
|
||||
*
|
||||
* @since 3.5.0
|
||||
*
|
||||
* @see WP_Object_Cache::switch_to_blog()
|
||||
* @global WP_Object_Cache $wp_object_cache Object cache global instance.
|
||||
*
|
||||
* @param int $blog_id Site ID.
|
||||
*/
|
||||
function wp_cache_switch_to_blog( $blog_id ) {
|
||||
global $wp_object_cache;
|
||||
|
||||
$wp_object_cache->switch_to_blog( $blog_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a group or set of groups to the list of global groups.
|
||||
*
|
||||
* @since 2.6.0
|
||||
*
|
||||
* @see WP_Object_Cache::add_global_groups()
|
||||
* @global WP_Object_Cache $wp_object_cache Object cache global instance.
|
||||
*
|
||||
* @param string|array $groups A group or an array of groups to add.
|
||||
*/
|
||||
function wp_cache_add_global_groups( $groups ) {
|
||||
global $wp_object_cache;
|
||||
|
||||
$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.
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset internal cache keys and structures.
|
||||
*
|
||||
* If the cache back end uses global blog or site IDs as part of its cache keys,
|
||||
* this function instructs the back end to reset those keys and perform any cleanup
|
||||
* since blog or site IDs have changed since cache init.
|
||||
*
|
||||
* This function is deprecated. Use wp_cache_switch_to_blog() instead of this
|
||||
* function when preparing the cache for a blog switch. For clearing the cache
|
||||
* during unit tests, consider using wp_cache_init(). wp_cache_init() is not
|
||||
* recommended outside of unit tests as the performance penality for using it is
|
||||
* high.
|
||||
*
|
||||
* @since 2.6.0
|
||||
* @deprecated 3.5.0 WP_Object_Cache::reset()
|
||||
* @see WP_Object_Cache::reset()
|
||||
*
|
||||
* @global WP_Object_Cache $wp_object_cache Object cache global instance.
|
||||
*/
|
||||
function wp_cache_reset() {
|
||||
_deprecated_function( __FUNCTION__, '3.5' );
|
||||
|
||||
global $wp_object_cache;
|
||||
|
||||
$wp_object_cache->reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Core class that implements an 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.0
|
||||
*/
|
||||
class WP_Object_Cache {
|
||||
|
||||
/**
|
||||
* Holds the cached objects.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access private
|
||||
* @var array
|
||||
*/
|
||||
private $cache = array();
|
||||
|
||||
/**
|
||||
* The amount of times the cache data was already stored in the cache.
|
||||
*
|
||||
* @since 2.5.0
|
||||
* @access private
|
||||
* @var int
|
||||
*/
|
||||
private $cache_hits = 0;
|
||||
|
||||
/**
|
||||
* Amount of times the cache did not have the request in cache.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
* @var int
|
||||
*/
|
||||
public $cache_misses = 0;
|
||||
|
||||
/**
|
||||
* List of global cache groups.
|
||||
*
|
||||
* @since 3.0.0
|
||||
* @access protected
|
||||
* @var array
|
||||
*/
|
||||
protected $global_groups = array();
|
||||
|
||||
/**
|
||||
* The blog prefix to prepend to keys in non-global groups.
|
||||
*
|
||||
* @since 3.5.0
|
||||
* @access private
|
||||
* @var int
|
||||
*/
|
||||
private $blog_prefix;
|
||||
|
||||
/**
|
||||
* Holds the value of is_multisite().
|
||||
*
|
||||
* @since 3.5.0
|
||||
* @access private
|
||||
* @var bool
|
||||
*/
|
||||
private $multisite;
|
||||
|
||||
/**
|
||||
* Makes private properties readable for backwards compatibility.
|
||||
*
|
||||
* @since 4.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $name Property to get.
|
||||
* @return mixed Property.
|
||||
*/
|
||||
public function __get( $name ) {
|
||||
return $this->$name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes private properties settable for backwards compatibility.
|
||||
*
|
||||
* @since 4.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $name Property to set.
|
||||
* @param mixed $value Property value.
|
||||
* @return mixed Newly-set property.
|
||||
*/
|
||||
public function __set( $name, $value ) {
|
||||
return $this->$name = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes private properties checkable for backwards compatibility.
|
||||
*
|
||||
* @since 4.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $name Property to check if set.
|
||||
* @return bool Whether the property is set.
|
||||
*/
|
||||
public function __isset( $name ) {
|
||||
return isset( $this->$name );
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes private properties un-settable for backwards compatibility.
|
||||
*
|
||||
* @since 4.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $name Property to unset.
|
||||
*/
|
||||
public function __unset( $name ) {
|
||||
unset( $this->$name );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds data to the cache if it doesn't already exist.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
*
|
||||
* @uses WP_Object_Cache::_exists() Checks to see if the cache already has data.
|
||||
* @uses WP_Object_Cache::set() Sets the data after the checking the cache
|
||||
* contents existence.
|
||||
*
|
||||
* @param int|string $key What to call the contents in the cache.
|
||||
* @param mixed $data The contents to store in the cache.
|
||||
* @param string $group Optional. Where to group the cache contents. Default 'default'.
|
||||
* @param int $expire Optional. When to expire the cache contents. Default 0 (no expiration).
|
||||
* @return bool False if cache key and group already exist, true on success
|
||||
*/
|
||||
public function add( $key, $data, $group = 'default', $expire = 0 ) {
|
||||
if ( wp_suspend_cache_addition() )
|
||||
return false;
|
||||
|
||||
if ( empty( $group ) )
|
||||
$group = 'default';
|
||||
|
||||
$id = $key;
|
||||
if ( $this->multisite && ! isset( $this->global_groups[ $group ] ) )
|
||||
$id = $this->blog_prefix . $key;
|
||||
|
||||
if ( $this->_exists( $id, $group ) )
|
||||
return false;
|
||||
|
||||
return $this->set( $key, $data, $group, (int) $expire );
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the list of global cache groups.
|
||||
*
|
||||
* @since 3.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param array $groups List of groups that are global.
|
||||
*/
|
||||
public function add_global_groups( $groups ) {
|
||||
$groups = (array) $groups;
|
||||
|
||||
$groups = array_fill_keys( $groups, true );
|
||||
$this->global_groups = array_merge( $this->global_groups, $groups );
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrements numeric cache item's value.
|
||||
*
|
||||
* @since 3.3.0
|
||||
* @access public
|
||||
*
|
||||
* @param int|string $key The cache key to decrement.
|
||||
* @param int $offset Optional. The amount by which to decrement the item's value. Default 1.
|
||||
* @param string $group Optional. The group the key is in. Default 'default'.
|
||||
* @return false|int False on failure, the item's new value on success.
|
||||
*/
|
||||
public function decr( $key, $offset = 1, $group = 'default' ) {
|
||||
if ( empty( $group ) )
|
||||
$group = 'default';
|
||||
|
||||
if ( $this->multisite && ! isset( $this->global_groups[ $group ] ) )
|
||||
$key = $this->blog_prefix . $key;
|
||||
|
||||
if ( ! $this->_exists( $key, $group ) )
|
||||
return false;
|
||||
|
||||
if ( ! is_numeric( $this->cache[ $group ][ $key ] ) )
|
||||
$this->cache[ $group ][ $key ] = 0;
|
||||
|
||||
$offset = (int) $offset;
|
||||
|
||||
$this->cache[ $group ][ $key ] -= $offset;
|
||||
|
||||
if ( $this->cache[ $group ][ $key ] < 0 )
|
||||
$this->cache[ $group ][ $key ] = 0;
|
||||
|
||||
return $this->cache[ $group ][ $key ];
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the contents of the cache key in the group.
|
||||
*
|
||||
* If the cache key does not exist in the group, then nothing will happen.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param int|string $key What the contents in the cache are called.
|
||||
* @param string $group Optional. Where the cache contents are grouped. Default 'default'.
|
||||
* @param bool $deprecated Optional. Unused. Default false.
|
||||
* @return bool False if the contents weren't deleted and true on success.
|
||||
*/
|
||||
public function delete( $key, $group = 'default', $deprecated = false ) {
|
||||
if ( empty( $group ) )
|
||||
$group = 'default';
|
||||
|
||||
if ( $this->multisite && ! isset( $this->global_groups[ $group ] ) )
|
||||
$key = $this->blog_prefix . $key;
|
||||
|
||||
if ( ! $this->_exists( $key, $group ) )
|
||||
return false;
|
||||
|
||||
unset( $this->cache[$group][$key] );
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the object cache of all data.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return true Always returns true.
|
||||
*/
|
||||
public 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
|
||||
* key in the cache group. If the cache is hit (success) then the contents
|
||||
* are returned.
|
||||
*
|
||||
* On failure, the number of cache misses will be incremented.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param int|string $key What the contents in the cache are called.
|
||||
* @param string $group Optional. Where the cache contents are grouped. Default 'default'.
|
||||
* @param string $force Optional. Unused. Whether to force a refetch rather than relying on the local
|
||||
* cache. Default false.
|
||||
* @param bool $found Optional. Whether the key was found in the cache. Disambiguates a return of
|
||||
* false, a storable value. Passed by reference. Default null.
|
||||
* @return false|mixed False on failure to retrieve contents or the cache contents on success.
|
||||
*/
|
||||
public function get( $key, $group = 'default', $force = false, &$found = null ) {
|
||||
if ( empty( $group ) )
|
||||
$group = 'default';
|
||||
|
||||
if ( $this->multisite && ! isset( $this->global_groups[ $group ] ) )
|
||||
$key = $this->blog_prefix . $key;
|
||||
|
||||
if ( $this->_exists( $key, $group ) ) {
|
||||
$found = true;
|
||||
$this->cache_hits += 1;
|
||||
if ( is_object($this->cache[$group][$key]) )
|
||||
return clone $this->cache[$group][$key];
|
||||
else
|
||||
return $this->cache[$group][$key];
|
||||
}
|
||||
|
||||
$found = false;
|
||||
$this->cache_misses += 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increments numeric cache item's value.
|
||||
*
|
||||
* @since 3.3.0
|
||||
* @access public
|
||||
*
|
||||
* @param int|string $key The cache key to increment
|
||||
* @param int $offset Optional. The amount by which to increment the item's value. Default 1.
|
||||
* @param string $group Optional. The group the key is in. Default 'default'.
|
||||
* @return false|int False on failure, the item's new value on success.
|
||||
*/
|
||||
public function incr( $key, $offset = 1, $group = 'default' ) {
|
||||
if ( empty( $group ) )
|
||||
$group = 'default';
|
||||
|
||||
if ( $this->multisite && ! isset( $this->global_groups[ $group ] ) )
|
||||
$key = $this->blog_prefix . $key;
|
||||
|
||||
if ( ! $this->_exists( $key, $group ) )
|
||||
return false;
|
||||
|
||||
if ( ! is_numeric( $this->cache[ $group ][ $key ] ) )
|
||||
$this->cache[ $group ][ $key ] = 0;
|
||||
|
||||
$offset = (int) $offset;
|
||||
|
||||
$this->cache[ $group ][ $key ] += $offset;
|
||||
|
||||
if ( $this->cache[ $group ][ $key ] < 0 )
|
||||
$this->cache[ $group ][ $key ] = 0;
|
||||
|
||||
return $this->cache[ $group ][ $key ];
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces the contents in the cache, if contents already exist.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
*
|
||||
* @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 $group Optional. Where to group the cache contents. Default 'default'.
|
||||
* @param int $expire Optional. When to expire the cache contents. Default 0 (no expiration).
|
||||
* @return bool False if not exists, true if contents were replaced.
|
||||
*/
|
||||
public function replace( $key, $data, $group = 'default', $expire = 0 ) {
|
||||
if ( empty( $group ) )
|
||||
$group = 'default';
|
||||
|
||||
$id = $key;
|
||||
if ( $this->multisite && ! isset( $this->global_groups[ $group ] ) )
|
||||
$id = $this->blog_prefix . $key;
|
||||
|
||||
if ( ! $this->_exists( $id, $group ) )
|
||||
return false;
|
||||
|
||||
return $this->set( $key, $data, $group, (int) $expire );
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets cache keys.
|
||||
*
|
||||
* @since 3.0.0
|
||||
* @access public
|
||||
*
|
||||
* @deprecated 3.5.0 Use switch_to_blog()
|
||||
* @see switch_to_blog()
|
||||
*/
|
||||
public function reset() {
|
||||
_deprecated_function( __FUNCTION__, '3.5', 'switch_to_blog()' );
|
||||
|
||||
// Clear out non-global caches since the blog ID has changed.
|
||||
foreach ( array_keys( $this->cache ) as $group ) {
|
||||
if ( ! isset( $this->global_groups[ $group ] ) )
|
||||
unset( $this->cache[ $group ] );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the data contents into the cache.
|
||||
*
|
||||
* The cache contents is grouped by the $group parameter followed by the
|
||||
* $key. 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
|
||||
* @access public
|
||||
*
|
||||
* @param int|string $key What to call the contents in the cache.
|
||||
* @param mixed $data The contents to store in the cache.
|
||||
* @param string $group Optional. Where to group the cache contents. Default 'default'.
|
||||
* @param int $expire Not Used.
|
||||
* @return true Always returns true.
|
||||
*/
|
||||
public function set( $key, $data, $group = 'default', $expire = 0 ) {
|
||||
if ( empty( $group ) )
|
||||
$group = 'default';
|
||||
|
||||
if ( $this->multisite && ! isset( $this->global_groups[ $group ] ) )
|
||||
$key = $this->blog_prefix . $key;
|
||||
|
||||
if ( is_object( $data ) )
|
||||
$data = clone $data;
|
||||
|
||||
$this->cache[$group][$key] = $data;
|
||||
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
|
||||
* @access public
|
||||
*/
|
||||
public 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 ) ) / KB_IN_BYTES, 2 ) . 'k )</li>';
|
||||
}
|
||||
echo '</ul>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Switches the interal blog ID.
|
||||
*
|
||||
* This changes the blog ID used to create keys in blog specific groups.
|
||||
*
|
||||
* @since 3.5.0
|
||||
* @access public
|
||||
*
|
||||
* @param int $blog_id Blog ID.
|
||||
*/
|
||||
public function switch_to_blog( $blog_id ) {
|
||||
$blog_id = (int) $blog_id;
|
||||
$this->blog_prefix = $this->multisite ? $blog_id . ':' : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Serves as a utility function to determine whether a key exists in the cache.
|
||||
*
|
||||
* @since 3.4.0
|
||||
* @access protected
|
||||
*
|
||||
* @param int|string $key Cache key to check for existence.
|
||||
* @param string $group Cache group for the key existence check.
|
||||
* @return bool Whether the key exists in the cache for the given group.
|
||||
*/
|
||||
protected function _exists( $key, $group ) {
|
||||
return isset( $this->cache[ $group ] ) && ( isset( $this->cache[ $group ][ $key ] ) || array_key_exists( $key, $this->cache[ $group ] ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up object properties; PHP 5 style constructor.
|
||||
*
|
||||
* @since 2.0.8
|
||||
*
|
||||
* @global int $blog_id Global blog ID.
|
||||
*/
|
||||
public function __construct() {
|
||||
global $blog_id;
|
||||
|
||||
$this->multisite = is_multisite();
|
||||
$this->blog_prefix = $this->multisite ? $blog_id . ':' : '';
|
||||
|
||||
|
||||
/**
|
||||
* @todo This should be moved to the PHP4 style constructor, PHP5
|
||||
* already calls __destruct()
|
||||
*/
|
||||
register_shutdown_function( array( $this, '__destruct' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the object cache before object is completely destroyed.
|
||||
*
|
||||
* Called upon object destruction, which should be when PHP ends.
|
||||
*
|
||||
* @since 2.0.8
|
||||
*
|
||||
* @return true Always returns true.
|
||||
*/
|
||||
public function __destruct() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
648
Kapitel_7/Lektion_4/wordpress/wp-includes/canonical.php
Executable file
648
Kapitel_7/Lektion_4/wordpress/wp-includes/canonical.php
Executable file
@@ -0,0 +1,648 @@
|
||||
<?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 penalty for duplicate content by redirecting all incoming links to
|
||||
* one or the other.
|
||||
*
|
||||
* Prevents redirection for feeds, trackbacks, searches, and
|
||||
* admin URLs. Does not redirect on non-pretty-permalink-supporting IIS 7+,
|
||||
* page/post previews, WP admin, Trackbacks, robots.txt, searches, or on POST
|
||||
* requests.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* @global WP_Rewrite $wp_rewrite
|
||||
* @global bool $is_IIS
|
||||
* @global WP_Query $wp_query
|
||||
* @global wpdb $wpdb WordPress database abstraction object.
|
||||
*
|
||||
* @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 string|void The string of the URL, if redirect needed.
|
||||
*/
|
||||
function redirect_canonical( $requested_url = null, $do_redirect = true ) {
|
||||
global $wp_rewrite, $is_IIS, $wp_query, $wpdb, $wp;
|
||||
|
||||
if ( isset( $_SERVER['REQUEST_METHOD'] ) && ! in_array( strtoupper( $_SERVER['REQUEST_METHOD'] ), array( 'GET', 'HEAD' ) ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If we're not in wp-admin and the post has been published and preview nonce
|
||||
// is non-existent or invalid then no need for preview in query
|
||||
if ( is_preview() && get_query_var( 'p' ) && 'publish' == get_post_status( get_query_var( 'p' ) ) ) {
|
||||
if ( ! isset( $_GET['preview_id'] )
|
||||
|| ! isset( $_GET['preview_nonce'] )
|
||||
|| ! wp_verify_nonce( $_GET['preview_nonce'], 'post_preview_' . (int) $_GET['preview_id'] ) ) {
|
||||
$wp_query->is_preview = false;
|
||||
}
|
||||
}
|
||||
|
||||
if ( is_trackback() || is_search() || is_admin() || is_preview() || is_robots() || ( $is_IIS && !iis7_supports_permalinks() ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! $requested_url && isset( $_SERVER['HTTP_HOST'] ) ) {
|
||||
// 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;
|
||||
}
|
||||
|
||||
$redirect = $original;
|
||||
$redirect_url = false;
|
||||
|
||||
// Notice fixing
|
||||
if ( !isset($redirect['path']) )
|
||||
$redirect['path'] = '';
|
||||
if ( !isset($redirect['query']) )
|
||||
$redirect['query'] = '';
|
||||
|
||||
// If the original URL ended with non-breaking spaces, they were almost
|
||||
// certainly inserted by accident. Let's remove them, so the reader doesn't
|
||||
// see a 404 error with no obvious cause.
|
||||
$redirect['path'] = preg_replace( '|(%C2%A0)+$|i', '', $redirect['path'] );
|
||||
|
||||
// It's not a preview, so remove it from URL
|
||||
if ( get_query_var( 'preview' ) ) {
|
||||
$redirect['query'] = remove_query_arg( 'preview', $redirect['query'] );
|
||||
}
|
||||
|
||||
if ( is_feed() && ( $id = get_query_var( 'p' ) ) ) {
|
||||
if ( $redirect_url = get_post_comments_feed_link( $id, get_query_var( 'feed' ) ) ) {
|
||||
$redirect['query'] = _remove_qs_args_if_not_in_url( $redirect['query'], array( 'p', 'page_id', 'attachment_id', 'pagename', 'name', 'post_type', 'feed'), $redirect_url );
|
||||
$redirect['path'] = parse_url( $redirect_url, PHP_URL_PATH );
|
||||
}
|
||||
}
|
||||
|
||||
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_qs_args_if_not_in_url( $redirect['query'], array( 'p', 'page_id', 'attachment_id', 'pagename', 'name', 'post_type' ), $redirect_url );
|
||||
}
|
||||
}
|
||||
|
||||
// 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 && 'auto-draft' != $redirect_post->post_status ) {
|
||||
$redirect_url = get_permalink($redirect_post);
|
||||
$redirect['query'] = _remove_qs_args_if_not_in_url( $redirect['query'], array( 'p', 'page_id', 'attachment_id', 'pagename', 'name', 'post_type' ), $redirect_url );
|
||||
}
|
||||
}
|
||||
|
||||
if ( get_query_var( 'day' ) && get_query_var( 'monthnum' ) && get_query_var( 'year' ) ) {
|
||||
$year = get_query_var( 'year' );
|
||||
$month = get_query_var( 'monthnum' );
|
||||
$day = get_query_var( 'day' );
|
||||
$date = sprintf( '%04d-%02d-%02d', $year, $month, $day );
|
||||
if ( ! wp_checkdate( $month, $day, $year, $date ) ) {
|
||||
$redirect_url = get_month_link( $year, $month );
|
||||
$redirect['query'] = _remove_qs_args_if_not_in_url( $redirect['query'], array( 'year', 'monthnum', 'day' ), $redirect_url );
|
||||
}
|
||||
} elseif ( get_query_var( 'monthnum' ) && get_query_var( 'year' ) && 12 < get_query_var( 'monthnum' ) ) {
|
||||
$redirect_url = get_year_link( get_query_var( 'year' ) );
|
||||
$redirect['query'] = _remove_qs_args_if_not_in_url( $redirect['query'], array( 'year', 'monthnum' ), $redirect_url );
|
||||
}
|
||||
|
||||
if ( ! $redirect_url ) {
|
||||
if ( $redirect_url = redirect_guess_404_permalink() ) {
|
||||
$redirect['query'] = _remove_qs_args_if_not_in_url( $redirect['query'], array( 'page', 'feed', 'p', 'page_id', 'attachment_id', 'pagename', 'name', 'post_type' ), $redirect_url );
|
||||
}
|
||||
}
|
||||
|
||||
if ( get_query_var( 'page' ) && $wp_query->post &&
|
||||
false !== strpos( $wp_query->post->post_content, '<!--nextpage-->' ) ) {
|
||||
$redirect['path'] = rtrim( $redirect['path'], (int) get_query_var( 'page' ) . '/' );
|
||||
$redirect['query'] = remove_query_arg( 'page', $redirect['query'] );
|
||||
$redirect_url = get_permalink( $wp_query->post->ID );
|
||||
}
|
||||
|
||||
} elseif ( is_object($wp_rewrite) && $wp_rewrite->using_permalinks() ) {
|
||||
// rewriting of old ?p=X, ?m=2004, ?m=200401, ?m=20040101
|
||||
if ( is_attachment() &&
|
||||
! array_diff( array_keys( $wp->query_vars ), array( 'attachment', 'attachment_id' ) ) &&
|
||||
! $redirect_url ) {
|
||||
if ( ! empty( $_GET['attachment_id'] ) ) {
|
||||
$redirect_url = get_attachment_link( get_query_var( 'attachment_id' ) );
|
||||
if ( $redirect_url ) {
|
||||
$redirect['query'] = remove_query_arg( 'attachment_id', $redirect['query'] );
|
||||
}
|
||||
} else {
|
||||
$redirect_url = get_attachment_link();
|
||||
}
|
||||
} 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() && 'page' == get_option('show_on_front') && get_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 ) && $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE $wpdb->posts.post_author = %d AND $wpdb->posts.post_status = 'publish' LIMIT 1", $author->ID ) ) ) {
|
||||
if ( $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->queried_terms 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) ) {
|
||||
if ( !empty($redirect['query']) ) {
|
||||
// Strip taxonomy query vars off the url.
|
||||
$qv_remove = array( 'term', 'taxonomy');
|
||||
if ( is_category() ) {
|
||||
$qv_remove[] = 'category_name';
|
||||
$qv_remove[] = 'cat';
|
||||
} elseif ( is_tag() ) {
|
||||
$qv_remove[] = 'tag';
|
||||
$qv_remove[] = 'tag_id';
|
||||
} else { // Custom taxonomies will have a custom query var, remove those too:
|
||||
$tax_obj = get_taxonomy( $obj->taxonomy );
|
||||
if ( false !== $tax_obj->query_var )
|
||||
$qv_remove[] = $tax_obj->query_var;
|
||||
}
|
||||
|
||||
$rewrite_vars = array_diff( array_keys($wp_query->query), array_keys($_GET) );
|
||||
|
||||
if ( !array_diff($rewrite_vars, array_keys($_GET)) ) { // Check to see if all the Query vars are coming from the rewrite, none are set via $_GET
|
||||
$redirect['query'] = remove_query_arg($qv_remove, $redirect['query']); //Remove all of the per-tax qv's
|
||||
|
||||
// Create the destination url for this taxonomy
|
||||
$tax_url = parse_url($tax_url);
|
||||
if ( ! empty($tax_url['query']) ) { // Taxonomy accessible via ?taxonomy=..&term=.. or any custom qv..
|
||||
parse_str($tax_url['query'], $query_vars);
|
||||
$redirect['query'] = add_query_arg($query_vars, $redirect['query']);
|
||||
} else { // Taxonomy is accessible via a "pretty-URL"
|
||||
$redirect['path'] = $tax_url['path'];
|
||||
}
|
||||
|
||||
} else { // Some query vars are set via $_GET. Unset those from $_GET that exist via the rewrite
|
||||
foreach ( $qv_remove as $_qv ) {
|
||||
if ( isset($rewrite_vars[$_qv]) )
|
||||
$redirect['query'] = remove_query_arg($_qv, $redirect['query']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
} elseif ( is_single() && strpos($wp_rewrite->permalink_structure, '%category%') !== false && $cat = get_query_var( 'category_name' ) ) {
|
||||
$category = get_category_by_path( $cat );
|
||||
$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') ) {
|
||||
if ( !$redirect_url )
|
||||
$redirect_url = get_permalink( get_queried_object_id() );
|
||||
|
||||
$page = get_query_var( 'page' );
|
||||
if ( $page > 1 ) {
|
||||
if ( is_front_page() ) {
|
||||
$redirect_url = trailingslashit( $redirect_url ) . user_trailingslashit( "$wp_rewrite->pagination_base/$page", 'paged' );
|
||||
} else {
|
||||
$redirect_url = trailingslashit( $redirect_url ) . user_trailingslashit( $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( "#/{$wp_rewrite->comments_pagination_base}-[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("#/{$wp_rewrite->comments_pagination_base}-[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 ( !is_singular() && get_query_var( 'withcomments' ) )
|
||||
$addl_path .= 'comments/';
|
||||
if ( ( 'rss' == get_default_feed() && 'feed' == get_query_var('feed') ) || 'rss' == get_query_var('feed') )
|
||||
$addl_path .= user_trailingslashit( 'feed/' . ( ( get_default_feed() == 'rss2' ) ? '' : 'rss2' ), 'feed' );
|
||||
else
|
||||
$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'] );
|
||||
} elseif ( is_feed() && 'old' == get_query_var('feed') ) {
|
||||
$old_feed_files = array(
|
||||
'wp-atom.php' => 'atom',
|
||||
'wp-commentsrss2.php' => 'comments_rss2',
|
||||
'wp-feed.php' => get_default_feed(),
|
||||
'wp-rdf.php' => 'rdf',
|
||||
'wp-rss.php' => 'rss2',
|
||||
'wp-rss2.php' => 'rss2',
|
||||
);
|
||||
if ( isset( $old_feed_files[ basename( $redirect['path'] ) ] ) ) {
|
||||
$redirect_url = get_feed_link( $old_feed_files[ basename( $redirect['path'] ) ] );
|
||||
wp_redirect( $redirect_url, 301 );
|
||||
die();
|
||||
}
|
||||
}
|
||||
|
||||
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( $wp_rewrite->comments_pagination_base . '-' . get_query_var('cpage'), 'commentpaged' );
|
||||
$redirect['query'] = remove_query_arg( 'cpage', $redirect['query'] );
|
||||
}
|
||||
|
||||
$redirect['path'] = user_trailingslashit( preg_replace('|/' . preg_quote( $wp_rewrite->index, '|' ) . '/?$|', '/', $redirect['path']) ); // strip off trailing /index.php/
|
||||
if ( !empty( $addl_path ) && $wp_rewrite->using_index_permalinks() && strpos($redirect['path'], '/' . $wp_rewrite->index . '/') === false )
|
||||
$redirect['path'] = trailingslashit($redirect['path']) . $wp_rewrite->index . '/';
|
||||
if ( !empty( $addl_path ) )
|
||||
$redirect['path'] = trailingslashit($redirect['path']) . $addl_path;
|
||||
$redirect_url = $redirect['scheme'] . '://' . $redirect['host'] . $redirect['path'];
|
||||
}
|
||||
|
||||
if ( 'wp-register.php' == basename( $redirect['path'] ) ) {
|
||||
if ( is_multisite() ) {
|
||||
/** This filter is documented in wp-login.php */
|
||||
$redirect_url = apply_filters( 'wp_signup_location', network_site_url( 'wp-signup.php' ) );
|
||||
} else {
|
||||
$redirect_url = wp_registration_url();
|
||||
}
|
||||
|
||||
wp_redirect( $redirect_url, 301 );
|
||||
die();
|
||||
}
|
||||
}
|
||||
|
||||
// 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'] );
|
||||
}
|
||||
|
||||
$_parsed_query = rawurlencode_deep( $_parsed_query );
|
||||
$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('|/' . preg_quote( $wp_rewrite->index, '|' ) . '/*?$|', '/', $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']), '&');
|
||||
|
||||
// Redirect obsolete feeds
|
||||
$redirect['query'] = preg_replace( '#(^|&)feed=rss(&|$)#', '$1feed=rss2$2', $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( '/' . $wp_rewrite->index . '/', '/', $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;
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter the canonical redirect URL.
|
||||
*
|
||||
* Returning false to this filter will cancel the redirect.
|
||||
*
|
||||
* @since 2.3.0
|
||||
*
|
||||
* @param string $redirect_url The redirect URL.
|
||||
* @param string $requested_url The requested URL.
|
||||
*/
|
||||
$redirect_url = apply_filters( 'redirect_canonical', $redirect_url, $requested_url );
|
||||
|
||||
// yes, again -- in case the filter aborted the request
|
||||
if ( ! $redirect_url || strip_fragment_from_url( $redirect_url ) == strip_fragment_from_url( $requested_url ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
} else {
|
||||
return $redirect_url;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes arguments from a query string if they are not present in a URL
|
||||
* DO NOT use this in plugin code.
|
||||
*
|
||||
* @since 3.4.0
|
||||
* @access private
|
||||
*
|
||||
* @param string $query_string
|
||||
* @param array $args_to_check
|
||||
* @param string $url
|
||||
* @return string The altered query string
|
||||
*/
|
||||
function _remove_qs_args_if_not_in_url( $query_string, Array $args_to_check, $url ) {
|
||||
$parsed_url = @parse_url( $url );
|
||||
if ( ! empty( $parsed_url['query'] ) ) {
|
||||
parse_str( $parsed_url['query'], $parsed_query );
|
||||
foreach ( $args_to_check as $qv ) {
|
||||
if ( !isset( $parsed_query[$qv] ) )
|
||||
$query_string = remove_query_arg( $qv, $query_string );
|
||||
}
|
||||
} else {
|
||||
$query_string = remove_query_arg( $args_to_check, $query_string );
|
||||
}
|
||||
return $query_string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Strips the #fragment from a URL, if one is present.
|
||||
*
|
||||
* @since 4.4.0
|
||||
*
|
||||
* @param string $url The URL to strip.
|
||||
* @return string The altered URL.
|
||||
*/
|
||||
function strip_fragment_from_url( $url ) {
|
||||
$parsed_url = @parse_url( $url );
|
||||
if ( ! empty( $parsed_url['host'] ) ) {
|
||||
// This mirrors code in redirect_canonical(). It does not handle every case.
|
||||
$url = $parsed_url['scheme'] . '://' . $parsed_url['host'];
|
||||
if ( ! empty( $parsed_url['port'] ) ) {
|
||||
$url .= ':' . $parsed_url['port'];
|
||||
}
|
||||
$url .= $parsed_url['path'];
|
||||
if ( ! empty( $parsed_url['query'] ) ) {
|
||||
$url .= '?' . $parsed_url['query'];
|
||||
}
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to guess the correct URL based on query vars
|
||||
*
|
||||
* @since 2.3.0
|
||||
*
|
||||
* @global wpdb $wpdb WordPress database abstraction object.
|
||||
*
|
||||
* @return false|string The correct URL if one is found. False on failure.
|
||||
*/
|
||||
function redirect_guess_404_permalink() {
|
||||
global $wpdb;
|
||||
|
||||
if ( get_query_var('name') ) {
|
||||
$where = $wpdb->prepare("post_name LIKE %s", $wpdb->esc_like( 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'));
|
||||
else
|
||||
$where .= " AND post_type IN ('" . implode( "', '", get_post_types( array( 'public' => true ) ) ) . "')";
|
||||
|
||||
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;
|
||||
if ( get_query_var( 'feed' ) )
|
||||
return get_post_comments_feed_link( $post_id, get_query_var( 'feed' ) );
|
||||
elseif ( get_query_var( 'page' ) && 1 < get_query_var( 'page' ) )
|
||||
return trailingslashit( get_permalink( $post_id ) ) . user_trailingslashit( get_query_var( 'page' ), 'single_paged' );
|
||||
else
|
||||
return get_permalink( $post_id );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirects a variety of shorthand URLs to the admin.
|
||||
*
|
||||
* If a user visits example.com/admin, they'll be redirected to /wp-admin.
|
||||
* Visiting /login redirects to /wp-login.php, and so on.
|
||||
*
|
||||
* @since 3.4.0
|
||||
*
|
||||
* @global WP_Rewrite $wp_rewrite
|
||||
*/
|
||||
function wp_redirect_admin_locations() {
|
||||
global $wp_rewrite;
|
||||
if ( ! ( is_404() && $wp_rewrite->using_permalinks() ) )
|
||||
return;
|
||||
|
||||
$admins = array(
|
||||
home_url( 'wp-admin', 'relative' ),
|
||||
home_url( 'dashboard', 'relative' ),
|
||||
home_url( 'admin', 'relative' ),
|
||||
site_url( 'dashboard', 'relative' ),
|
||||
site_url( 'admin', 'relative' ),
|
||||
);
|
||||
if ( in_array( untrailingslashit( $_SERVER['REQUEST_URI'] ), $admins ) ) {
|
||||
wp_redirect( admin_url() );
|
||||
exit;
|
||||
}
|
||||
|
||||
$logins = array(
|
||||
home_url( 'wp-login.php', 'relative' ),
|
||||
home_url( 'login', 'relative' ),
|
||||
site_url( 'login', 'relative' ),
|
||||
);
|
||||
if ( in_array( untrailingslashit( $_SERVER['REQUEST_URI'] ), $logins ) ) {
|
||||
wp_redirect( wp_login_url() );
|
||||
exit;
|
||||
}
|
||||
}
|
||||
621
Kapitel_7/Lektion_4/wordpress/wp-includes/capabilities.php
Executable file
621
Kapitel_7/Lektion_4/wordpress/wp-includes/capabilities.php
Executable file
@@ -0,0 +1,621 @@
|
||||
<?php
|
||||
/**
|
||||
* Core User Role & Capabilities API
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Users
|
||||
*/
|
||||
|
||||
/**
|
||||
* Map meta capabilities to primitive capabilities.
|
||||
*
|
||||
* This does not actually compare whether the user ID has the actual capability,
|
||||
* just what the capability or capabilities are. Meta capability list value can
|
||||
* be 'delete_user', 'edit_user', 'remove_user', 'promote_user', 'delete_post',
|
||||
* 'delete_page', 'edit_post', 'edit_page', 'read_post', or 'read_page'.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @global array $post_type_meta_caps Used to get post type meta capabilities.
|
||||
*
|
||||
* @param string $cap Capability name.
|
||||
* @param int $user_id User ID.
|
||||
* @param int $object_id Optional. ID of the specific object to check against if `$cap` is a "meta" cap.
|
||||
* "Meta" capabilities, e.g. 'edit_post', 'edit_user', etc., are capabilities used
|
||||
* by map_meta_cap() to map to other "primitive" capabilities, e.g. 'edit_posts',
|
||||
* 'edit_others_posts', etc. The parameter is accessed via func_get_args().
|
||||
* @return array Actual capabilities for meta capability.
|
||||
*/
|
||||
function map_meta_cap( $cap, $user_id ) {
|
||||
$args = array_slice( func_get_args(), 2 );
|
||||
$caps = array();
|
||||
|
||||
switch ( $cap ) {
|
||||
case 'remove_user':
|
||||
$caps[] = 'remove_users';
|
||||
break;
|
||||
case 'promote_user':
|
||||
case 'add_users':
|
||||
$caps[] = 'promote_users';
|
||||
break;
|
||||
case 'edit_user':
|
||||
case 'edit_users':
|
||||
// Allow user to edit itself
|
||||
if ( 'edit_user' == $cap && isset( $args[0] ) && $user_id == $args[0] )
|
||||
break;
|
||||
|
||||
// In multisite the user must have manage_network_users caps. If editing a super admin, the user must be a super admin.
|
||||
if ( is_multisite() && ( ( ! is_super_admin( $user_id ) && 'edit_user' === $cap && is_super_admin( $args[0] ) ) || ! user_can( $user_id, 'manage_network_users' ) ) ) {
|
||||
$caps[] = 'do_not_allow';
|
||||
} else {
|
||||
$caps[] = 'edit_users'; // edit_user maps to edit_users.
|
||||
}
|
||||
break;
|
||||
case 'delete_post':
|
||||
case 'delete_page':
|
||||
$post = get_post( $args[0] );
|
||||
if ( ! $post ) {
|
||||
$caps[] = 'do_not_allow';
|
||||
break;
|
||||
}
|
||||
|
||||
if ( 'revision' == $post->post_type ) {
|
||||
$post = get_post( $post->post_parent );
|
||||
if ( ! $post ) {
|
||||
$caps[] = 'do_not_allow';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$post_type = get_post_type_object( $post->post_type );
|
||||
if ( ! $post_type ) {
|
||||
/* translators: 1: post type, 2: capability name */
|
||||
_doing_it_wrong( __FUNCTION__, sprintf( __( 'The post type %1$s is not registered, so it may not be reliable to check the capability "%2$s" against a post of that type.' ), $post->post_type, $cap ), '4.4.0' );
|
||||
$caps[] = 'edit_others_posts';
|
||||
break;
|
||||
}
|
||||
|
||||
if ( ! $post_type->map_meta_cap ) {
|
||||
$caps[] = $post_type->cap->$cap;
|
||||
// Prior to 3.1 we would re-call map_meta_cap here.
|
||||
if ( 'delete_post' == $cap )
|
||||
$cap = $post_type->cap->$cap;
|
||||
break;
|
||||
}
|
||||
|
||||
// If the post author is set and the user is the author...
|
||||
if ( $post->post_author && $user_id == $post->post_author ) {
|
||||
// If the post is published or scheduled...
|
||||
if ( in_array( $post->post_status, array( 'publish', 'future' ), true ) ) {
|
||||
$caps[] = $post_type->cap->delete_published_posts;
|
||||
} elseif ( 'trash' == $post->post_status ) {
|
||||
$status = get_post_meta( $post->ID, '_wp_trash_meta_status', true );
|
||||
if ( in_array( $status, array( 'publish', 'future' ), true ) ) {
|
||||
$caps[] = $post_type->cap->delete_published_posts;
|
||||
} else {
|
||||
$caps[] = $post_type->cap->delete_posts;
|
||||
}
|
||||
} else {
|
||||
// If the post is draft...
|
||||
$caps[] = $post_type->cap->delete_posts;
|
||||
}
|
||||
} else {
|
||||
// The user is trying to edit someone else's post.
|
||||
$caps[] = $post_type->cap->delete_others_posts;
|
||||
// The post is published or scheduled, extra cap required.
|
||||
if ( in_array( $post->post_status, array( 'publish', 'future' ), true ) ) {
|
||||
$caps[] = $post_type->cap->delete_published_posts;
|
||||
} elseif ( 'private' == $post->post_status ) {
|
||||
$caps[] = $post_type->cap->delete_private_posts;
|
||||
}
|
||||
}
|
||||
break;
|
||||
// edit_post breaks down to edit_posts, edit_published_posts, or
|
||||
// edit_others_posts
|
||||
case 'edit_post':
|
||||
case 'edit_page':
|
||||
$post = get_post( $args[0] );
|
||||
if ( ! $post ) {
|
||||
$caps[] = 'do_not_allow';
|
||||
break;
|
||||
}
|
||||
|
||||
if ( 'revision' == $post->post_type ) {
|
||||
$post = get_post( $post->post_parent );
|
||||
if ( ! $post ) {
|
||||
$caps[] = 'do_not_allow';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$post_type = get_post_type_object( $post->post_type );
|
||||
if ( ! $post_type ) {
|
||||
/* translators: 1: post type, 2: capability name */
|
||||
_doing_it_wrong( __FUNCTION__, sprintf( __( 'The post type %1$s is not registered, so it may not be reliable to check the capability "%2$s" against a post of that type.' ), $post->post_type, $cap ), '4.4.0' );
|
||||
$caps[] = 'edit_others_posts';
|
||||
break;
|
||||
}
|
||||
|
||||
if ( ! $post_type->map_meta_cap ) {
|
||||
$caps[] = $post_type->cap->$cap;
|
||||
// Prior to 3.1 we would re-call map_meta_cap here.
|
||||
if ( 'edit_post' == $cap )
|
||||
$cap = $post_type->cap->$cap;
|
||||
break;
|
||||
}
|
||||
|
||||
// If the post author is set and the user is the author...
|
||||
if ( $post->post_author && $user_id == $post->post_author ) {
|
||||
// If the post is published or scheduled...
|
||||
if ( in_array( $post->post_status, array( 'publish', 'future' ), true ) ) {
|
||||
$caps[] = $post_type->cap->edit_published_posts;
|
||||
} elseif ( 'trash' == $post->post_status ) {
|
||||
$status = get_post_meta( $post->ID, '_wp_trash_meta_status', true );
|
||||
if ( in_array( $status, array( 'publish', 'future' ), true ) ) {
|
||||
$caps[] = $post_type->cap->edit_published_posts;
|
||||
} else {
|
||||
$caps[] = $post_type->cap->edit_posts;
|
||||
}
|
||||
} else {
|
||||
// If the post is draft...
|
||||
$caps[] = $post_type->cap->edit_posts;
|
||||
}
|
||||
} else {
|
||||
// The user is trying to edit someone else's post.
|
||||
$caps[] = $post_type->cap->edit_others_posts;
|
||||
// The post is published or scheduled, extra cap required.
|
||||
if ( in_array( $post->post_status, array( 'publish', 'future' ), true ) ) {
|
||||
$caps[] = $post_type->cap->edit_published_posts;
|
||||
} elseif ( 'private' == $post->post_status ) {
|
||||
$caps[] = $post_type->cap->edit_private_posts;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'read_post':
|
||||
case 'read_page':
|
||||
$post = get_post( $args[0] );
|
||||
if ( ! $post ) {
|
||||
$caps[] = 'do_not_allow';
|
||||
break;
|
||||
}
|
||||
|
||||
if ( 'revision' == $post->post_type ) {
|
||||
$post = get_post( $post->post_parent );
|
||||
if ( ! $post ) {
|
||||
$caps[] = 'do_not_allow';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$post_type = get_post_type_object( $post->post_type );
|
||||
if ( ! $post_type ) {
|
||||
/* translators: 1: post type, 2: capability name */
|
||||
_doing_it_wrong( __FUNCTION__, sprintf( __( 'The post type %1$s is not registered, so it may not be reliable to check the capability "%2$s" against a post of that type.' ), $post->post_type, $cap ), '4.4.0' );
|
||||
$caps[] = 'edit_others_posts';
|
||||
break;
|
||||
}
|
||||
|
||||
if ( ! $post_type->map_meta_cap ) {
|
||||
$caps[] = $post_type->cap->$cap;
|
||||
// Prior to 3.1 we would re-call map_meta_cap here.
|
||||
if ( 'read_post' == $cap )
|
||||
$cap = $post_type->cap->$cap;
|
||||
break;
|
||||
}
|
||||
|
||||
$status_obj = get_post_status_object( $post->post_status );
|
||||
if ( $status_obj->public ) {
|
||||
$caps[] = $post_type->cap->read;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( $post->post_author && $user_id == $post->post_author ) {
|
||||
$caps[] = $post_type->cap->read;
|
||||
} elseif ( $status_obj->private ) {
|
||||
$caps[] = $post_type->cap->read_private_posts;
|
||||
} else {
|
||||
$caps = map_meta_cap( 'edit_post', $user_id, $post->ID );
|
||||
}
|
||||
break;
|
||||
case 'publish_post':
|
||||
$post = get_post( $args[0] );
|
||||
if ( ! $post ) {
|
||||
$caps[] = 'do_not_allow';
|
||||
break;
|
||||
}
|
||||
|
||||
$post_type = get_post_type_object( $post->post_type );
|
||||
if ( ! $post_type ) {
|
||||
/* translators: 1: post type, 2: capability name */
|
||||
_doing_it_wrong( __FUNCTION__, sprintf( __( 'The post type %1$s is not registered, so it may not be reliable to check the capability "%2$s" against a post of that type.' ), $post->post_type, $cap ), '4.4.0' );
|
||||
$caps[] = 'edit_others_posts';
|
||||
break;
|
||||
}
|
||||
|
||||
$caps[] = $post_type->cap->publish_posts;
|
||||
break;
|
||||
case 'edit_post_meta':
|
||||
case 'delete_post_meta':
|
||||
case 'add_post_meta':
|
||||
$post = get_post( $args[0] );
|
||||
if ( ! $post ) {
|
||||
$caps[] = 'do_not_allow';
|
||||
break;
|
||||
}
|
||||
|
||||
$caps = map_meta_cap( 'edit_post', $user_id, $post->ID );
|
||||
|
||||
$meta_key = isset( $args[ 1 ] ) ? $args[ 1 ] : false;
|
||||
|
||||
if ( $meta_key && has_filter( "auth_post_meta_{$meta_key}" ) ) {
|
||||
/**
|
||||
* Filter whether the user is allowed to add post meta to a post.
|
||||
*
|
||||
* The dynamic portion of the hook name, `$meta_key`, refers to the
|
||||
* meta key passed to {@see map_meta_cap()}.
|
||||
*
|
||||
* @since 3.3.0
|
||||
*
|
||||
* @param bool $allowed Whether the user can add the post meta. Default false.
|
||||
* @param string $meta_key The meta key.
|
||||
* @param int $post_id Post ID.
|
||||
* @param int $user_id User ID.
|
||||
* @param string $cap Capability name.
|
||||
* @param array $caps User capabilities.
|
||||
*/
|
||||
$allowed = apply_filters( "auth_post_meta_{$meta_key}", false, $meta_key, $post->ID, $user_id, $cap, $caps );
|
||||
if ( ! $allowed )
|
||||
$caps[] = $cap;
|
||||
} elseif ( $meta_key && is_protected_meta( $meta_key, 'post' ) ) {
|
||||
$caps[] = $cap;
|
||||
}
|
||||
break;
|
||||
case 'edit_comment':
|
||||
$comment = get_comment( $args[0] );
|
||||
if ( ! $comment ) {
|
||||
$caps[] = 'do_not_allow';
|
||||
break;
|
||||
}
|
||||
|
||||
$post = get_post( $comment->comment_post_ID );
|
||||
|
||||
/*
|
||||
* If the post doesn't exist, we have an orphaned comment.
|
||||
* Fall back to the edit_posts capability, instead.
|
||||
*/
|
||||
if ( $post ) {
|
||||
$caps = map_meta_cap( 'edit_post', $user_id, $post->ID );
|
||||
} else {
|
||||
$caps = map_meta_cap( 'edit_posts', $user_id );
|
||||
}
|
||||
break;
|
||||
case 'unfiltered_upload':
|
||||
if ( defined('ALLOW_UNFILTERED_UPLOADS') && ALLOW_UNFILTERED_UPLOADS && ( !is_multisite() || is_super_admin( $user_id ) ) )
|
||||
$caps[] = $cap;
|
||||
else
|
||||
$caps[] = 'do_not_allow';
|
||||
break;
|
||||
case 'unfiltered_html' :
|
||||
// Disallow unfiltered_html for all users, even admins and super admins.
|
||||
if ( defined( 'DISALLOW_UNFILTERED_HTML' ) && DISALLOW_UNFILTERED_HTML )
|
||||
$caps[] = 'do_not_allow';
|
||||
elseif ( is_multisite() && ! is_super_admin( $user_id ) )
|
||||
$caps[] = 'do_not_allow';
|
||||
else
|
||||
$caps[] = $cap;
|
||||
break;
|
||||
case 'edit_files':
|
||||
case 'edit_plugins':
|
||||
case 'edit_themes':
|
||||
// Disallow the file editors.
|
||||
if ( defined( 'DISALLOW_FILE_EDIT' ) && DISALLOW_FILE_EDIT )
|
||||
$caps[] = 'do_not_allow';
|
||||
elseif ( defined( 'DISALLOW_FILE_MODS' ) && DISALLOW_FILE_MODS )
|
||||
$caps[] = 'do_not_allow';
|
||||
elseif ( is_multisite() && ! is_super_admin( $user_id ) )
|
||||
$caps[] = 'do_not_allow';
|
||||
else
|
||||
$caps[] = $cap;
|
||||
break;
|
||||
case 'update_plugins':
|
||||
case 'delete_plugins':
|
||||
case 'install_plugins':
|
||||
case 'upload_plugins':
|
||||
case 'update_themes':
|
||||
case 'delete_themes':
|
||||
case 'install_themes':
|
||||
case 'upload_themes':
|
||||
case 'update_core':
|
||||
// Disallow anything that creates, deletes, or updates core, plugin, or theme files.
|
||||
// Files in uploads are excepted.
|
||||
if ( defined( 'DISALLOW_FILE_MODS' ) && DISALLOW_FILE_MODS ) {
|
||||
$caps[] = 'do_not_allow';
|
||||
} elseif ( is_multisite() && ! is_super_admin( $user_id ) ) {
|
||||
$caps[] = 'do_not_allow';
|
||||
} elseif ( 'upload_themes' === $cap ) {
|
||||
$caps[] = 'install_themes';
|
||||
} elseif ( 'upload_plugins' === $cap ) {
|
||||
$caps[] = 'install_plugins';
|
||||
} else {
|
||||
$caps[] = $cap;
|
||||
}
|
||||
break;
|
||||
case 'activate_plugins':
|
||||
$caps[] = $cap;
|
||||
if ( is_multisite() ) {
|
||||
// update_, install_, and delete_ are handled above with is_super_admin().
|
||||
$menu_perms = get_site_option( 'menu_items', array() );
|
||||
if ( empty( $menu_perms['plugins'] ) )
|
||||
$caps[] = 'manage_network_plugins';
|
||||
}
|
||||
break;
|
||||
case 'delete_user':
|
||||
case 'delete_users':
|
||||
// If multisite only super admins can delete users.
|
||||
if ( is_multisite() && ! is_super_admin( $user_id ) )
|
||||
$caps[] = 'do_not_allow';
|
||||
else
|
||||
$caps[] = 'delete_users'; // delete_user maps to delete_users.
|
||||
break;
|
||||
case 'create_users':
|
||||
if ( !is_multisite() )
|
||||
$caps[] = $cap;
|
||||
elseif ( is_super_admin( $user_id ) || get_site_option( 'add_new_users' ) )
|
||||
$caps[] = $cap;
|
||||
else
|
||||
$caps[] = 'do_not_allow';
|
||||
break;
|
||||
case 'manage_links' :
|
||||
if ( get_option( 'link_manager_enabled' ) )
|
||||
$caps[] = $cap;
|
||||
else
|
||||
$caps[] = 'do_not_allow';
|
||||
break;
|
||||
case 'customize' :
|
||||
$caps[] = 'edit_theme_options';
|
||||
break;
|
||||
case 'delete_site':
|
||||
$caps[] = 'manage_options';
|
||||
break;
|
||||
default:
|
||||
// Handle meta capabilities for custom post types.
|
||||
global $post_type_meta_caps;
|
||||
if ( isset( $post_type_meta_caps[ $cap ] ) ) {
|
||||
$args = array_merge( array( $post_type_meta_caps[ $cap ], $user_id ), $args );
|
||||
return call_user_func_array( 'map_meta_cap', $args );
|
||||
}
|
||||
|
||||
// If no meta caps match, return the original cap.
|
||||
$caps[] = $cap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter a user's capabilities depending on specific context and/or privilege.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @param array $caps Returns the user's actual capabilities.
|
||||
* @param string $cap Capability name.
|
||||
* @param int $user_id The user ID.
|
||||
* @param array $args Adds the context to the cap. Typically the object ID.
|
||||
*/
|
||||
return apply_filters( 'map_meta_cap', $caps, $cap, $user_id, $args );
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the current user has a specific capability.
|
||||
*
|
||||
* While checking against particular roles in place of a capability is supported
|
||||
* in part, this practice is discouraged as it may produce unreliable results.
|
||||
*
|
||||
* Note: Will always return true if the current user is a super admin, unless specifically denied.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @see WP_User::has_cap()
|
||||
* @see map_meta_cap()
|
||||
*
|
||||
* @param string $capability Capability name.
|
||||
* @param int $object_id Optional. ID of the specific object to check against if `$capability` is a "meta" cap.
|
||||
* "Meta" capabilities, e.g. 'edit_post', 'edit_user', etc., are capabilities used
|
||||
* by map_meta_cap() to map to other "primitive" capabilities, e.g. 'edit_posts',
|
||||
* 'edit_others_posts', etc. Accessed via func_get_args() and passed to WP_User::has_cap(),
|
||||
* then map_meta_cap().
|
||||
* @return bool Whether the current user has the given capability. If `$capability` is a meta cap and `$object_id` is
|
||||
* passed, whether the current user has the given meta capability for the given object.
|
||||
*/
|
||||
function current_user_can( $capability ) {
|
||||
$current_user = wp_get_current_user();
|
||||
|
||||
if ( empty( $current_user ) )
|
||||
return false;
|
||||
|
||||
$args = array_slice( func_get_args(), 1 );
|
||||
$args = array_merge( array( $capability ), $args );
|
||||
|
||||
return call_user_func_array( array( $current_user, 'has_cap' ), $args );
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether current user has a capability or role for a given site.
|
||||
*
|
||||
* @since 3.0.0
|
||||
*
|
||||
* @param int $blog_id Site ID.
|
||||
* @param string $capability Capability or role name.
|
||||
* @return bool
|
||||
*/
|
||||
function current_user_can_for_blog( $blog_id, $capability ) {
|
||||
$switched = is_multisite() ? switch_to_blog( $blog_id ) : false;
|
||||
|
||||
$current_user = wp_get_current_user();
|
||||
|
||||
if ( empty( $current_user ) ) {
|
||||
if ( $switched ) {
|
||||
restore_current_blog();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
$args = array_slice( func_get_args(), 2 );
|
||||
$args = array_merge( array( $capability ), $args );
|
||||
|
||||
$can = call_user_func_array( array( $current_user, 'has_cap' ), $args );
|
||||
|
||||
if ( $switched ) {
|
||||
restore_current_blog();
|
||||
}
|
||||
|
||||
return $can;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether author of supplied post has capability or role.
|
||||
*
|
||||
* @since 2.9.0
|
||||
*
|
||||
* @param int|object $post Post ID or post object.
|
||||
* @param string $capability Capability or role name.
|
||||
* @return bool
|
||||
*/
|
||||
function author_can( $post, $capability ) {
|
||||
if ( !$post = get_post($post) )
|
||||
return false;
|
||||
|
||||
$author = get_userdata( $post->post_author );
|
||||
|
||||
if ( ! $author )
|
||||
return false;
|
||||
|
||||
$args = array_slice( func_get_args(), 2 );
|
||||
$args = array_merge( array( $capability ), $args );
|
||||
|
||||
return call_user_func_array( array( $author, 'has_cap' ), $args );
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether a particular user has capability or role.
|
||||
*
|
||||
* @since 3.1.0
|
||||
*
|
||||
* @param int|object $user User ID or object.
|
||||
* @param string $capability Capability or role name.
|
||||
* @return bool
|
||||
*/
|
||||
function user_can( $user, $capability ) {
|
||||
if ( ! is_object( $user ) )
|
||||
$user = get_userdata( $user );
|
||||
|
||||
if ( ! $user || ! $user->exists() )
|
||||
return false;
|
||||
|
||||
$args = array_slice( func_get_args(), 2 );
|
||||
$args = array_merge( array( $capability ), $args );
|
||||
|
||||
return call_user_func_array( array( $user, 'has_cap' ), $args );
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the global WP_Roles instance and instantiates it if necessary.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*
|
||||
* @global WP_Roles $wp_roles WP_Roles global instance.
|
||||
*
|
||||
* @return WP_Roles WP_Roles global instance if not already instantiated.
|
||||
*/
|
||||
function wp_roles() {
|
||||
global $wp_roles;
|
||||
|
||||
if ( ! isset( $wp_roles ) ) {
|
||||
$wp_roles = new WP_Roles();
|
||||
}
|
||||
return $wp_roles;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve role object.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param string $role Role name.
|
||||
* @return WP_Role|null WP_Role object if found, null if the role does not exist.
|
||||
*/
|
||||
function get_role( $role ) {
|
||||
return wp_roles()->get_role( $role );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add role, if it does not exist.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param string $role Role name.
|
||||
* @param string $display_name Display name for role.
|
||||
* @param array $capabilities List of capabilities, e.g. array( 'edit_posts' => true, 'delete_posts' => false );
|
||||
* @return WP_Role|null WP_Role object if role is added, null if already exists.
|
||||
*/
|
||||
function add_role( $role, $display_name, $capabilities = array() ) {
|
||||
if ( empty( $role ) ) {
|
||||
return;
|
||||
}
|
||||
return wp_roles()->add_role( $role, $display_name, $capabilities );
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove role, if it exists.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param string $role Role name.
|
||||
*/
|
||||
function remove_role( $role ) {
|
||||
wp_roles()->remove_role( $role );
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a list of super admins.
|
||||
*
|
||||
* @since 3.0.0
|
||||
*
|
||||
* @global array $super_admins
|
||||
*
|
||||
* @return array List of super admin logins
|
||||
*/
|
||||
function get_super_admins() {
|
||||
global $super_admins;
|
||||
|
||||
if ( isset($super_admins) )
|
||||
return $super_admins;
|
||||
else
|
||||
return get_site_option( 'site_admins', array('admin') );
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if user is a site admin.
|
||||
*
|
||||
* @since 3.0.0
|
||||
*
|
||||
* @param int $user_id (Optional) The ID of a user. Defaults to the current user.
|
||||
* @return bool True if the user is a site admin.
|
||||
*/
|
||||
function is_super_admin( $user_id = false ) {
|
||||
if ( ! $user_id || $user_id == get_current_user_id() )
|
||||
$user = wp_get_current_user();
|
||||
else
|
||||
$user = get_userdata( $user_id );
|
||||
|
||||
if ( ! $user || ! $user->exists() )
|
||||
return false;
|
||||
|
||||
if ( is_multisite() ) {
|
||||
$super_admins = get_super_admins();
|
||||
if ( is_array( $super_admins ) && in_array( $user->user_login, $super_admins ) )
|
||||
return true;
|
||||
} else {
|
||||
if ( $user->has_cap('delete_users') )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
1340
Kapitel_7/Lektion_4/wordpress/wp-includes/category-template.php
Executable file
1340
Kapitel_7/Lektion_4/wordpress/wp-includes/category-template.php
Executable file
File diff suppressed because it is too large
Load Diff
357
Kapitel_7/Lektion_4/wordpress/wp-includes/category.php
Executable file
357
Kapitel_7/Lektion_4/wordpress/wp-includes/category.php
Executable file
@@ -0,0 +1,357 @@
|
||||
<?php
|
||||
/**
|
||||
* Taxonomy API: Core category-specific functionality
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Taxonomy
|
||||
*/
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @param string|array $args {
|
||||
* Optional. Arguments to retrieve categories. See {@see get_terms()} for additional options.
|
||||
*
|
||||
* @type string $taxonomy Taxonomy to retrieve terms for. In this case, default 'category'.
|
||||
* }
|
||||
* @return array List of categories.
|
||||
*/
|
||||
function get_categories( $args = '' ) {
|
||||
$defaults = array( 'taxonomy' => 'category' );
|
||||
$args = wp_parse_args( $args, $defaults );
|
||||
|
||||
$taxonomy = $args['taxonomy'];
|
||||
|
||||
/**
|
||||
* Filter the taxonomy used to retrieve terms when calling {@see get_categories()}.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @param string $taxonomy Taxonomy to retrieve terms from.
|
||||
* @param array $args An array of arguments. See {@see get_terms()}.
|
||||
*/
|
||||
$taxonomy = apply_filters( 'get_categories_taxonomy', $taxonomy, $args );
|
||||
|
||||
// Back compat
|
||||
if ( isset($args['type']) && 'link' == $args['type'] ) {
|
||||
/* translators: 1: "type => link", 2: "taxonomy => link_category" alternative */
|
||||
_deprecated_argument( __FUNCTION__, '3.0',
|
||||
sprintf( __( '%1$s is deprecated. Use %2$s instead.' ),
|
||||
'<code>type => link</code>',
|
||||
'<code>taxonomy => link_category</code>'
|
||||
)
|
||||
);
|
||||
$taxonomy = $args['taxonomy'] = 'link_category';
|
||||
}
|
||||
|
||||
$categories = get_terms( $taxonomy, $args );
|
||||
|
||||
if ( is_wp_error( $categories ) ) {
|
||||
$categories = array();
|
||||
} else {
|
||||
$categories = (array) $categories;
|
||||
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
|
||||
*
|
||||
* @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 object|array|WP_Error|null Category data in type defined by $output parameter.
|
||||
* WP_Error if $category is empty, null if it does not exist.
|
||||
*/
|
||||
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 object|array|WP_Error|void 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;
|
||||
}
|
||||
|
||||
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 ) {
|
||||
$category = get_term( $category->term_id, 'category', $output );
|
||||
_make_cat_compat( $category );
|
||||
return $category;
|
||||
}
|
||||
}
|
||||
|
||||
// If full matching is not required, return the first cat that matches the leaf.
|
||||
if ( ! $full_match ) {
|
||||
$category = get_term( reset( $categories )->term_id, 'category', $output );
|
||||
_make_cat_compat( $category );
|
||||
return $category;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 Category name.
|
||||
* @return int 0, if failure and ID of category on success.
|
||||
*/
|
||||
function get_cat_ID( $cat_name ) {
|
||||
$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_term( $cat_id, 'category' );
|
||||
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 ) {
|
||||
return term_is_ancestor_of( $cat1, $cat2, 'category' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitizes category data based on context.
|
||||
*
|
||||
* @since 2.3.0
|
||||
*
|
||||
* @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
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
* @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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter the array of term objects returned for the 'post_tag' taxonomy.
|
||||
*
|
||||
* @since 2.3.0
|
||||
*
|
||||
* @param array $tags Array of 'post_tag' term objects.
|
||||
* @param array $args An array of arguments. @see get_terms()
|
||||
*/
|
||||
$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|WP_Error|null Tag data in type defined by $output parameter. WP_Error if $tag is empty, null if it does not exist.
|
||||
*/
|
||||
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
|
||||
*
|
||||
* @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
|
||||
* @since 4.4.0 The `$category` parameter now also accepts a WP_Term object.
|
||||
* @access private
|
||||
*
|
||||
* @param array|object|WP_Term $category Category Row object or array
|
||||
*/
|
||||
function _make_cat_compat( &$category ) {
|
||||
if ( is_object( $category ) && ! is_wp_error( $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'];
|
||||
}
|
||||
}
|
||||
4327
Kapitel_7/Lektion_4/wordpress/wp-includes/certificates/ca-bundle.crt
Executable file
4327
Kapitel_7/Lektion_4/wordpress/wp-includes/certificates/ca-bundle.crt
Executable file
File diff suppressed because it is too large
Load Diff
1222
Kapitel_7/Lektion_4/wordpress/wp-includes/class-IXR.php
Executable file
1222
Kapitel_7/Lektion_4/wordpress/wp-includes/class-IXR.php
Executable file
File diff suppressed because it is too large
Load Diff
171
Kapitel_7/Lektion_4/wordpress/wp-includes/class-feed.php
Executable file
171
Kapitel_7/Lektion_4/wordpress/wp-includes/class-feed.php
Executable file
@@ -0,0 +1,171 @@
|
||||
<?php
|
||||
|
||||
if ( ! class_exists( 'SimplePie', false ) )
|
||||
require_once( ABSPATH . WPINC . '/class-simplepie.php' );
|
||||
|
||||
class WP_Feed_Cache extends SimplePie_Cache {
|
||||
/**
|
||||
* Create a new SimplePie_Cache object
|
||||
*
|
||||
* @static
|
||||
* @access public
|
||||
*
|
||||
* @param string $location URL location (scheme is used to determine handler).
|
||||
* @param string $filename Unique identifier for cache object.
|
||||
* @param string $extension 'spi' or 'spc'.
|
||||
* @return WP_Feed_Cache_Transient Feed cache handler object that uses transients.
|
||||
*/
|
||||
public function create($location, $filename, $extension) {
|
||||
return new WP_Feed_Cache_Transient($location, $filename, $extension);
|
||||
}
|
||||
}
|
||||
|
||||
class WP_Feed_Cache_Transient {
|
||||
public $name;
|
||||
public $mod_name;
|
||||
public $lifetime = 43200; //Default lifetime in cache of 12 hours
|
||||
|
||||
/**
|
||||
* Class instantiator.
|
||||
*
|
||||
* @param string $location URL location (scheme is used to determine handler).
|
||||
* @param string $filename Unique identifier for cache object.
|
||||
* @param string $extension 'spi' or 'spc'.
|
||||
*/
|
||||
public function __construct($location, $filename, $extension) {
|
||||
$this->name = 'feed_' . $filename;
|
||||
$this->mod_name = 'feed_mod_' . $filename;
|
||||
|
||||
$lifetime = $this->lifetime;
|
||||
/**
|
||||
* Filter the transient lifetime of the feed cache.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @param int $lifetime Cache duration in seconds. Default is 43200 seconds (12 hours).
|
||||
* @param string $filename Unique identifier for the cache object.
|
||||
*/
|
||||
$this->lifetime = apply_filters( 'wp_feed_cache_transient_lifetime', $lifetime, $filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* @access public
|
||||
*
|
||||
* @param SimplePie $data Data to save.
|
||||
* @return true Always true.
|
||||
*/
|
||||
public function save($data) {
|
||||
if ( $data instanceof SimplePie ) {
|
||||
$data = $data->data;
|
||||
}
|
||||
|
||||
set_transient($this->name, $data, $this->lifetime);
|
||||
set_transient($this->mod_name, time(), $this->lifetime);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @access public
|
||||
*/
|
||||
public function load() {
|
||||
return get_transient($this->name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @access public
|
||||
*/
|
||||
public function mtime() {
|
||||
return get_transient($this->mod_name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @access public
|
||||
*/
|
||||
public function touch() {
|
||||
return set_transient($this->mod_name, time(), $this->lifetime);
|
||||
}
|
||||
|
||||
/**
|
||||
* @access public
|
||||
*/
|
||||
public function unlink() {
|
||||
delete_transient($this->name);
|
||||
delete_transient($this->mod_name);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class WP_SimplePie_File extends SimplePie_File {
|
||||
|
||||
public function __construct($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_safe_remote_request($url, $args);
|
||||
|
||||
if ( is_wp_error($res) ) {
|
||||
$this->error = 'WP HTTP Error: ' . $res->get_error_message();
|
||||
$this->success = false;
|
||||
} else {
|
||||
$this->headers = wp_remote_retrieve_headers( $res );
|
||||
$this->body = wp_remote_retrieve_body( $res );
|
||||
$this->status_code = wp_remote_retrieve_response_code( $res );
|
||||
}
|
||||
} else {
|
||||
$this->error = '';
|
||||
$this->success = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* WordPress SimplePie Sanitization Class
|
||||
*
|
||||
* Extension of the SimplePie_Sanitize class to use KSES, because
|
||||
* we cannot universally count on DOMDocument being available
|
||||
*
|
||||
* @package WordPress
|
||||
* @since 3.5.0
|
||||
*/
|
||||
class WP_SimplePie_Sanitize_KSES extends SimplePie_Sanitize {
|
||||
public function sanitize( $data, $type, $base = '' ) {
|
||||
$data = trim( $data );
|
||||
if ( $type & SIMPLEPIE_CONSTRUCT_MAYBE_HTML ) {
|
||||
if (preg_match('/(&(#(x[0-9a-fA-F]+|[0-9]+)|[a-zA-Z0-9]+)|<\/[A-Za-z][^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3E]*' . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . '>)/', $data)) {
|
||||
$type |= SIMPLEPIE_CONSTRUCT_HTML;
|
||||
}
|
||||
else {
|
||||
$type |= SIMPLEPIE_CONSTRUCT_TEXT;
|
||||
}
|
||||
}
|
||||
if ( $type & SIMPLEPIE_CONSTRUCT_BASE64 ) {
|
||||
$data = base64_decode( $data );
|
||||
}
|
||||
if ( $type & ( SIMPLEPIE_CONSTRUCT_HTML | SIMPLEPIE_CONSTRUCT_XHTML ) ) {
|
||||
$data = wp_kses_post( $data );
|
||||
if ( $this->output_encoding !== 'UTF-8' ) {
|
||||
$data = $this->registry->call( 'Misc', 'change_encoding', array( $data, 'UTF-8', $this->output_encoding ) );
|
||||
}
|
||||
return $data;
|
||||
} else {
|
||||
return parent::sanitize( $data, $type, $base );
|
||||
}
|
||||
}
|
||||
}
|
||||
921
Kapitel_7/Lektion_4/wordpress/wp-includes/class-http.php
Executable file
921
Kapitel_7/Lektion_4/wordpress/wp-includes/class-http.php
Executable file
@@ -0,0 +1,921 @@
|
||||
<?php
|
||||
/**
|
||||
* HTTP API: WP_Http class
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage HTTP
|
||||
* @since 2.7.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Core class used for managing HTTP transports and making HTTP requests.
|
||||
*
|
||||
* This class is used to consistently make outgoing HTTP requests easy for developers
|
||||
* while still being compatible with the many PHP configurations under which
|
||||
* WordPress runs.
|
||||
*
|
||||
* Debugging includes several actions, which pass different variables for debugging the HTTP API.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*/
|
||||
class WP_Http {
|
||||
|
||||
// Aliases for HTTP response codes.
|
||||
const HTTP_CONTINUE = 100;
|
||||
const SWITCHING_PROTOCOLS = 101;
|
||||
const PROCESSING = 102;
|
||||
|
||||
const OK = 200;
|
||||
const CREATED = 201;
|
||||
const ACCEPTED = 202;
|
||||
const NON_AUTHORITATIVE_INFORMATION = 203;
|
||||
const NO_CONTENT = 204;
|
||||
const RESET_CONTENT = 205;
|
||||
const PARTIAL_CONTENT = 206;
|
||||
const MULTI_STATUS = 207;
|
||||
const IM_USED = 226;
|
||||
|
||||
const MULTIPLE_CHOICES = 300;
|
||||
const MOVED_PERMANENTLY = 301;
|
||||
const FOUND = 302;
|
||||
const SEE_OTHER = 303;
|
||||
const NOT_MODIFIED = 304;
|
||||
const USE_PROXY = 305;
|
||||
const RESERVED = 306;
|
||||
const TEMPORARY_REDIRECT = 307;
|
||||
const PERMANENT_REDIRECT = 308;
|
||||
|
||||
const BAD_REQUEST = 400;
|
||||
const UNAUTHORIZED = 401;
|
||||
const PAYMENT_REQUIRED = 402;
|
||||
const FORBIDDEN = 403;
|
||||
const NOT_FOUND = 404;
|
||||
const METHOD_NOT_ALLOWED = 405;
|
||||
const NOT_ACCEPTABLE = 406;
|
||||
const PROXY_AUTHENTICATION_REQUIRED = 407;
|
||||
const REQUEST_TIMEOUT = 408;
|
||||
const CONFLICT = 409;
|
||||
const GONE = 410;
|
||||
const LENGTH_REQUIRED = 411;
|
||||
const PRECONDITION_FAILED = 412;
|
||||
const REQUEST_ENTITY_TOO_LARGE = 413;
|
||||
const REQUEST_URI_TOO_LONG = 414;
|
||||
const UNSUPPORTED_MEDIA_TYPE = 415;
|
||||
const REQUESTED_RANGE_NOT_SATISFIABLE = 416;
|
||||
const EXPECTATION_FAILED = 417;
|
||||
const IM_A_TEAPOT = 418;
|
||||
const MISDIRECTED_REQUEST = 421;
|
||||
const UNPROCESSABLE_ENTITY = 422;
|
||||
const LOCKED = 423;
|
||||
const FAILED_DEPENDENCY = 424;
|
||||
const UPGRADE_REQUIRED = 426;
|
||||
const PRECONDITION_REQUIRED = 428;
|
||||
const TOO_MANY_REQUESTS = 429;
|
||||
const REQUEST_HEADER_FIELDS_TOO_LARGE = 431;
|
||||
const UNAVAILABLE_FOR_LEGAL_REASONS = 451;
|
||||
|
||||
const INTERNAL_SERVER_ERROR = 500;
|
||||
const NOT_IMPLEMENTED = 501;
|
||||
const BAD_GATEWAY = 502;
|
||||
const SERVICE_UNAVAILABLE = 503;
|
||||
const GATEWAY_TIMEOUT = 504;
|
||||
const HTTP_VERSION_NOT_SUPPORTED = 505;
|
||||
const VARIANT_ALSO_NEGOTIATES = 506;
|
||||
const INSUFFICIENT_STORAGE = 507;
|
||||
const NOT_EXTENDED = 510;
|
||||
const NETWORK_AUTHENTICATION_REQUIRED = 511;
|
||||
|
||||
/**
|
||||
* Send an HTTP request to a URI.
|
||||
*
|
||||
* Please note: The only URI that are supported in the HTTP Transport implementation
|
||||
* are the HTTP and HTTPS protocols.
|
||||
*
|
||||
* @access public
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @global string $wp_version
|
||||
*
|
||||
* @param string $url The request URL.
|
||||
* @param string|array $args {
|
||||
* Optional. Array or string of HTTP request arguments.
|
||||
*
|
||||
* @type string $method Request method. Accepts 'GET', 'POST', 'HEAD', or 'PUT'.
|
||||
* Some transports technically allow others, but should not be
|
||||
* assumed. Default 'GET'.
|
||||
* @type int $timeout How long the connection should stay open in seconds. Default 5.
|
||||
* @type int $redirection Number of allowed redirects. Not supported by all transports
|
||||
* Default 5.
|
||||
* @type string $httpversion Version of the HTTP protocol to use. Accepts '1.0' and '1.1'.
|
||||
* Default '1.0'.
|
||||
* @type string $user-agent User-agent value sent.
|
||||
* Default WordPress/' . $wp_version . '; ' . get_bloginfo( 'url' ).
|
||||
* @type bool $reject_unsafe_urls Whether to pass URLs through {@see wp_http_validate_url()}.
|
||||
* Default false.
|
||||
* @type bool $blocking Whether the calling code requires the result of the request.
|
||||
* If set to false, the request will be sent to the remote server,
|
||||
* and processing returned to the calling code immediately, the caller
|
||||
* will know if the request succeeded or failed, but will not receive
|
||||
* any response from the remote server. Default true.
|
||||
* @type string|array $headers Array or string of headers to send with the request.
|
||||
* Default empty array.
|
||||
* @type array $cookies List of cookies to send with the request. Default empty array.
|
||||
* @type string|array $body Body to send with the request. Default null.
|
||||
* @type bool $compress Whether to compress the $body when sending the request.
|
||||
* Default false.
|
||||
* @type bool $decompress Whether to decompress a compressed response. If set to false and
|
||||
* compressed content is returned in the response anyway, it will
|
||||
* need to be separately decompressed. Default true.
|
||||
* @type bool $sslverify Whether to verify SSL for the request. Default true.
|
||||
* @type string sslcertificates Absolute path to an SSL certificate .crt file.
|
||||
* Default ABSPATH . WPINC . '/certificates/ca-bundle.crt'.
|
||||
* @type bool $stream Whether to stream to a file. If set to true and no filename was
|
||||
* given, it will be droped it in the WP temp dir and its name will
|
||||
* be set using the basename of the URL. Default false.
|
||||
* @type string $filename Filename of the file to write to when streaming. $stream must be
|
||||
* set to true. Default null.
|
||||
* @type int $limit_response_size Size in bytes to limit the response to. Default null.
|
||||
*
|
||||
* }
|
||||
* @return array|WP_Error Array containing 'headers', 'body', 'response', 'cookies', 'filename'.
|
||||
* A WP_Error instance upon error.
|
||||
*/
|
||||
public function request( $url, $args = array() ) {
|
||||
global $wp_version;
|
||||
|
||||
$defaults = array(
|
||||
'method' => 'GET',
|
||||
/**
|
||||
* Filter the timeout value for an HTTP request.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @param int $timeout_value Time in seconds until a request times out.
|
||||
* Default 5.
|
||||
*/
|
||||
'timeout' => apply_filters( 'http_request_timeout', 5 ),
|
||||
/**
|
||||
* Filter the number of redirects allowed during an HTTP request.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @param int $redirect_count Number of redirects allowed. Default 5.
|
||||
*/
|
||||
'redirection' => apply_filters( 'http_request_redirection_count', 5 ),
|
||||
/**
|
||||
* Filter the version of the HTTP protocol used in a request.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @param string $version Version of HTTP used. Accepts '1.0' and '1.1'.
|
||||
* Default '1.0'.
|
||||
*/
|
||||
'httpversion' => apply_filters( 'http_request_version', '1.0' ),
|
||||
/**
|
||||
* Filter the user agent value sent with an HTTP request.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @param string $user_agent WordPress user agent string.
|
||||
*/
|
||||
'user-agent' => apply_filters( 'http_headers_useragent', 'WordPress/' . $wp_version . '; ' . get_bloginfo( 'url' ) ),
|
||||
/**
|
||||
* Filter whether to pass URLs through wp_http_validate_url() in an HTTP request.
|
||||
*
|
||||
* @since 3.6.0
|
||||
*
|
||||
* @param bool $pass_url Whether to pass URLs through wp_http_validate_url().
|
||||
* Default false.
|
||||
*/
|
||||
'reject_unsafe_urls' => apply_filters( 'http_request_reject_unsafe_urls', false ),
|
||||
'blocking' => true,
|
||||
'headers' => array(),
|
||||
'cookies' => array(),
|
||||
'body' => null,
|
||||
'compress' => false,
|
||||
'decompress' => true,
|
||||
'sslverify' => true,
|
||||
'sslcertificates' => ABSPATH . WPINC . '/certificates/ca-bundle.crt',
|
||||
'stream' => false,
|
||||
'filename' => null,
|
||||
'limit_response_size' => null,
|
||||
);
|
||||
|
||||
// Pre-parse for the HEAD checks.
|
||||
$args = wp_parse_args( $args );
|
||||
|
||||
// By default, Head requests do not cause redirections.
|
||||
if ( isset($args['method']) && 'HEAD' == $args['method'] )
|
||||
$defaults['redirection'] = 0;
|
||||
|
||||
$r = wp_parse_args( $args, $defaults );
|
||||
/**
|
||||
* Filter the arguments used in an HTTP request.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @param array $r An array of HTTP request arguments.
|
||||
* @param string $url The request URL.
|
||||
*/
|
||||
$r = apply_filters( 'http_request_args', $r, $url );
|
||||
|
||||
// The transports decrement this, store a copy of the original value for loop purposes.
|
||||
if ( ! isset( $r['_redirection'] ) )
|
||||
$r['_redirection'] = $r['redirection'];
|
||||
|
||||
/**
|
||||
* Filter whether to preempt an HTTP request's return value.
|
||||
*
|
||||
* Returning a non-false value from the filter will short-circuit the HTTP request and return
|
||||
* early with that value. A filter should return either:
|
||||
*
|
||||
* - An array containing 'headers', 'body', 'response', 'cookies', and 'filename' elements
|
||||
* - A WP_Error instance
|
||||
* - boolean false (to avoid short-circuiting the response)
|
||||
*
|
||||
* Returning any other value may result in unexpected behaviour.
|
||||
*
|
||||
* @since 2.9.0
|
||||
*
|
||||
* @param false|array|WP_Error $preempt Whether to preempt an HTTP request's return value. Default false.
|
||||
* @param array $r HTTP request arguments.
|
||||
* @param string $url The request URL.
|
||||
*/
|
||||
$pre = apply_filters( 'pre_http_request', false, $r, $url );
|
||||
|
||||
if ( false !== $pre )
|
||||
return $pre;
|
||||
|
||||
if ( function_exists( 'wp_kses_bad_protocol' ) ) {
|
||||
if ( $r['reject_unsafe_urls'] )
|
||||
$url = wp_http_validate_url( $url );
|
||||
if ( $url ) {
|
||||
$url = wp_kses_bad_protocol( $url, array( 'http', 'https', 'ssl' ) );
|
||||
}
|
||||
}
|
||||
|
||||
$arrURL = @parse_url( $url );
|
||||
|
||||
if ( empty( $url ) || empty( $arrURL['scheme'] ) )
|
||||
return new WP_Error('http_request_failed', __('A valid URL was not provided.'));
|
||||
|
||||
if ( $this->block_request( $url ) )
|
||||
return new WP_Error( 'http_request_failed', __( 'User has blocked requests through HTTP.' ) );
|
||||
|
||||
/*
|
||||
* Determine if this is a https call and pass that on to the transport functions
|
||||
* so that we can blacklist the transports that do not support ssl verification
|
||||
*/
|
||||
$r['ssl'] = $arrURL['scheme'] == 'https' || $arrURL['scheme'] == 'ssl';
|
||||
|
||||
// Determine if this request is to OUR install of WordPress.
|
||||
$homeURL = parse_url( get_bloginfo( 'url' ) );
|
||||
$r['local'] = 'localhost' == $arrURL['host'] || ( isset( $homeURL['host'] ) && $homeURL['host'] == $arrURL['host'] );
|
||||
unset( $homeURL );
|
||||
|
||||
/*
|
||||
* If we are streaming to a file but no filename was given drop it in the WP temp dir
|
||||
* and pick its name using the basename of the $url.
|
||||
*/
|
||||
if ( $r['stream'] && empty( $r['filename'] ) ) {
|
||||
$r['filename'] = get_temp_dir() . wp_unique_filename( get_temp_dir(), basename( $url ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* Force some settings if we are streaming to a file and check for existence and perms
|
||||
* of destination directory.
|
||||
*/
|
||||
if ( $r['stream'] ) {
|
||||
$r['blocking'] = true;
|
||||
if ( ! wp_is_writable( dirname( $r['filename'] ) ) )
|
||||
return new WP_Error( 'http_request_failed', __( 'Destination directory for file streaming does not exist or is not writable.' ) );
|
||||
}
|
||||
|
||||
if ( is_null( $r['headers'] ) )
|
||||
$r['headers'] = array();
|
||||
|
||||
if ( ! is_array( $r['headers'] ) ) {
|
||||
$processedHeaders = self::processHeaders( $r['headers'], $url );
|
||||
$r['headers'] = $processedHeaders['headers'];
|
||||
}
|
||||
|
||||
if ( isset( $r['headers']['User-Agent'] ) ) {
|
||||
$r['user-agent'] = $r['headers']['User-Agent'];
|
||||
unset( $r['headers']['User-Agent'] );
|
||||
}
|
||||
|
||||
if ( isset( $r['headers']['user-agent'] ) ) {
|
||||
$r['user-agent'] = $r['headers']['user-agent'];
|
||||
unset( $r['headers']['user-agent'] );
|
||||
}
|
||||
|
||||
if ( '1.1' == $r['httpversion'] && !isset( $r['headers']['connection'] ) ) {
|
||||
$r['headers']['connection'] = 'close';
|
||||
}
|
||||
|
||||
// Construct Cookie: header if any cookies are set.
|
||||
self::buildCookieHeader( $r );
|
||||
|
||||
// Avoid issues where mbstring.func_overload is enabled.
|
||||
mbstring_binary_safe_encoding();
|
||||
|
||||
if ( ! isset( $r['headers']['Accept-Encoding'] ) ) {
|
||||
if ( $encoding = WP_Http_Encoding::accept_encoding( $url, $r ) )
|
||||
$r['headers']['Accept-Encoding'] = $encoding;
|
||||
}
|
||||
|
||||
if ( ( ! is_null( $r['body'] ) && '' != $r['body'] ) || 'POST' == $r['method'] || 'PUT' == $r['method'] ) {
|
||||
if ( is_array( $r['body'] ) || is_object( $r['body'] ) ) {
|
||||
$r['body'] = http_build_query( $r['body'], null, '&' );
|
||||
|
||||
if ( ! isset( $r['headers']['Content-Type'] ) )
|
||||
$r['headers']['Content-Type'] = 'application/x-www-form-urlencoded; charset=' . get_option( 'blog_charset' );
|
||||
}
|
||||
|
||||
if ( '' === $r['body'] )
|
||||
$r['body'] = null;
|
||||
|
||||
if ( ! isset( $r['headers']['Content-Length'] ) && ! isset( $r['headers']['content-length'] ) )
|
||||
$r['headers']['Content-Length'] = strlen( $r['body'] );
|
||||
}
|
||||
|
||||
$response = $this->_dispatch_request( $url, $r );
|
||||
|
||||
reset_mbstring_encoding();
|
||||
|
||||
if ( is_wp_error( $response ) )
|
||||
return $response;
|
||||
|
||||
// Append cookies that were used in this request to the response
|
||||
if ( ! empty( $r['cookies'] ) ) {
|
||||
$cookies_set = wp_list_pluck( $response['cookies'], 'name' );
|
||||
foreach ( $r['cookies'] as $cookie ) {
|
||||
if ( ! in_array( $cookie->name, $cookies_set ) && $cookie->test( $url ) ) {
|
||||
$response['cookies'][] = $cookie;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests which transports are capable of supporting the request.
|
||||
*
|
||||
* @since 3.2.0
|
||||
* @access public
|
||||
*
|
||||
* @param array $args Request arguments
|
||||
* @param string $url URL to Request
|
||||
*
|
||||
* @return string|false Class name for the first transport that claims to support the request. False if no transport claims to support the request.
|
||||
*/
|
||||
public function _get_first_available_transport( $args, $url = null ) {
|
||||
$transports = array( 'curl', 'streams' );
|
||||
|
||||
/**
|
||||
* Filter which HTTP transports are available and in what order.
|
||||
*
|
||||
* @since 3.7.0
|
||||
*
|
||||
* @param array $transports Array of HTTP transports to check. Default array contains
|
||||
* 'curl', and 'streams', in that order.
|
||||
* @param array $args HTTP request arguments.
|
||||
* @param string $url The URL to request.
|
||||
*/
|
||||
$request_order = apply_filters( 'http_api_transports', $transports, $args, $url );
|
||||
|
||||
// Loop over each transport on each HTTP request looking for one which will serve this request's needs.
|
||||
foreach ( $request_order as $transport ) {
|
||||
if ( in_array( $transport, $transports ) ) {
|
||||
$transport = ucfirst( $transport );
|
||||
}
|
||||
$class = 'WP_Http_' . $transport;
|
||||
|
||||
// Check to see if this transport is a possibility, calls the transport statically.
|
||||
if ( !call_user_func( array( $class, 'test' ), $args, $url ) )
|
||||
continue;
|
||||
|
||||
return $class;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatches a HTTP request to a supporting transport.
|
||||
*
|
||||
* Tests each transport in order to find a transport which matches the request arguments.
|
||||
* Also caches the transport instance to be used later.
|
||||
*
|
||||
* The order for requests is cURL, and then PHP Streams.
|
||||
*
|
||||
* @since 3.2.0
|
||||
*
|
||||
* @static
|
||||
* @access private
|
||||
*
|
||||
* @param string $url URL to Request
|
||||
* @param array $args Request arguments
|
||||
* @return array|WP_Error Array containing 'headers', 'body', 'response', 'cookies', 'filename'. A WP_Error instance upon error
|
||||
*/
|
||||
private function _dispatch_request( $url, $args ) {
|
||||
static $transports = array();
|
||||
|
||||
$class = $this->_get_first_available_transport( $args, $url );
|
||||
if ( !$class )
|
||||
return new WP_Error( 'http_failure', __( 'There are no HTTP transports available which can complete the requested request.' ) );
|
||||
|
||||
// Transport claims to support request, instantiate it and give it a whirl.
|
||||
if ( empty( $transports[$class] ) )
|
||||
$transports[$class] = new $class;
|
||||
|
||||
$response = $transports[$class]->request( $url, $args );
|
||||
|
||||
/**
|
||||
* Fires after an HTTP API response is received and before the response is returned.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @param array|WP_Error $response HTTP response or WP_Error object.
|
||||
* @param string $context Context under which the hook is fired.
|
||||
* @param string $class HTTP transport used.
|
||||
* @param array $args HTTP request arguments.
|
||||
* @param string $url The request URL.
|
||||
*/
|
||||
do_action( 'http_api_debug', $response, 'response', $class, $args, $url );
|
||||
|
||||
if ( is_wp_error( $response ) )
|
||||
return $response;
|
||||
|
||||
/**
|
||||
* Filter the HTTP API response immediately before the response is returned.
|
||||
*
|
||||
* @since 2.9.0
|
||||
*
|
||||
* @param array $response HTTP response.
|
||||
* @param array $args HTTP request arguments.
|
||||
* @param string $url The request URL.
|
||||
*/
|
||||
return apply_filters( 'http_response', $response, $args, $url );
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses the POST HTTP method.
|
||||
*
|
||||
* Used for sending data that is expected to be in the body.
|
||||
*
|
||||
* @access public
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @param string $url The request URL.
|
||||
* @param string|array $args Optional. Override the defaults.
|
||||
* @return array|WP_Error Array containing 'headers', 'body', 'response', 'cookies', 'filename'. A WP_Error instance upon error
|
||||
*/
|
||||
public function post($url, $args = array()) {
|
||||
$defaults = array('method' => 'POST');
|
||||
$r = wp_parse_args( $args, $defaults );
|
||||
return $this->request($url, $r);
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses the GET HTTP method.
|
||||
*
|
||||
* Used for sending data that is expected to be in the body.
|
||||
*
|
||||
* @access public
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @param string $url The request URL.
|
||||
* @param string|array $args Optional. Override the defaults.
|
||||
* @return array|WP_Error Array containing 'headers', 'body', 'response', 'cookies', 'filename'. A WP_Error instance upon error
|
||||
*/
|
||||
public function get($url, $args = array()) {
|
||||
$defaults = array('method' => 'GET');
|
||||
$r = wp_parse_args( $args, $defaults );
|
||||
return $this->request($url, $r);
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses the HEAD HTTP method.
|
||||
*
|
||||
* Used for sending data that is expected to be in the body.
|
||||
*
|
||||
* @access public
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @param string $url The request URL.
|
||||
* @param string|array $args Optional. Override the defaults.
|
||||
* @return array|WP_Error Array containing 'headers', 'body', 'response', 'cookies', 'filename'. A WP_Error instance upon error
|
||||
*/
|
||||
public function head($url, $args = array()) {
|
||||
$defaults = array('method' => 'HEAD');
|
||||
$r = wp_parse_args( $args, $defaults );
|
||||
return $this->request($url, $r);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the responses and splits the parts into headers and body.
|
||||
*
|
||||
* @access public
|
||||
* @static
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @param string $strResponse The full response string
|
||||
* @return array Array with 'headers' and 'body' keys.
|
||||
*/
|
||||
public static function processResponse($strResponse) {
|
||||
$res = explode("\r\n\r\n", $strResponse, 2);
|
||||
|
||||
return array('headers' => $res[0], 'body' => isset($res[1]) ? $res[1] : '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform header string into an array.
|
||||
*
|
||||
* If an array is given then it is assumed to be raw header data with numeric keys with the
|
||||
* headers as the values. No headers must be passed that were already processed.
|
||||
*
|
||||
* @access public
|
||||
* @static
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @param string|array $headers
|
||||
* @param string $url The URL that was requested
|
||||
* @return array Processed string headers. If duplicate headers are encountered,
|
||||
* Then a numbered array is returned as the value of that header-key.
|
||||
*/
|
||||
public static function processHeaders( $headers, $url = '' ) {
|
||||
// Split headers, one per array element.
|
||||
if ( is_string($headers) ) {
|
||||
// Tolerate line terminator: CRLF = LF (RFC 2616 19.3).
|
||||
$headers = str_replace("\r\n", "\n", $headers);
|
||||
/*
|
||||
* Unfold folded header fields. LWS = [CRLF] 1*( SP | HT ) <US-ASCII SP, space (32)>,
|
||||
* <US-ASCII HT, horizontal-tab (9)> (RFC 2616 2.2).
|
||||
*/
|
||||
$headers = preg_replace('/\n[ \t]/', ' ', $headers);
|
||||
// Create the headers array.
|
||||
$headers = explode("\n", $headers);
|
||||
}
|
||||
|
||||
$response = array('code' => 0, 'message' => '');
|
||||
|
||||
/*
|
||||
* If a redirection has taken place, The headers for each page request may have been passed.
|
||||
* In this case, determine the final HTTP header and parse from there.
|
||||
*/
|
||||
for ( $i = count($headers)-1; $i >= 0; $i-- ) {
|
||||
if ( !empty($headers[$i]) && false === strpos($headers[$i], ':') ) {
|
||||
$headers = array_splice($headers, $i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$cookies = array();
|
||||
$newheaders = array();
|
||||
foreach ( (array) $headers as $tempheader ) {
|
||||
if ( empty($tempheader) )
|
||||
continue;
|
||||
|
||||
if ( false === strpos($tempheader, ':') ) {
|
||||
$stack = explode(' ', $tempheader, 3);
|
||||
$stack[] = '';
|
||||
list( , $response['code'], $response['message']) = $stack;
|
||||
continue;
|
||||
}
|
||||
|
||||
list($key, $value) = explode(':', $tempheader, 2);
|
||||
|
||||
$key = strtolower( $key );
|
||||
$value = trim( $value );
|
||||
|
||||
if ( isset( $newheaders[ $key ] ) ) {
|
||||
if ( ! is_array( $newheaders[ $key ] ) )
|
||||
$newheaders[$key] = array( $newheaders[ $key ] );
|
||||
$newheaders[ $key ][] = $value;
|
||||
} else {
|
||||
$newheaders[ $key ] = $value;
|
||||
}
|
||||
if ( 'set-cookie' == $key )
|
||||
$cookies[] = new WP_Http_Cookie( $value, $url );
|
||||
}
|
||||
|
||||
// Cast the Response Code to an int
|
||||
$response['code'] = intval( $response['code'] );
|
||||
|
||||
return array('response' => $response, 'headers' => $newheaders, 'cookies' => $cookies);
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes the arguments for a ::request() and checks for the cookie array.
|
||||
*
|
||||
* If it's found, then it upgrades any basic name => value pairs to WP_Http_Cookie instances,
|
||||
* which are each parsed into strings and added to the Cookie: header (within the arguments array).
|
||||
* Edits the array by reference.
|
||||
*
|
||||
* @access public
|
||||
* @version 2.8.0
|
||||
* @static
|
||||
*
|
||||
* @param array $r Full array of args passed into ::request()
|
||||
*/
|
||||
public static function buildCookieHeader( &$r ) {
|
||||
if ( ! empty($r['cookies']) ) {
|
||||
// Upgrade any name => value cookie pairs to WP_HTTP_Cookie instances.
|
||||
foreach ( $r['cookies'] as $name => $value ) {
|
||||
if ( ! is_object( $value ) )
|
||||
$r['cookies'][ $name ] = new WP_Http_Cookie( array( 'name' => $name, 'value' => $value ) );
|
||||
}
|
||||
|
||||
$cookies_header = '';
|
||||
foreach ( (array) $r['cookies'] as $cookie ) {
|
||||
$cookies_header .= $cookie->getHeaderValue() . '; ';
|
||||
}
|
||||
|
||||
$cookies_header = substr( $cookies_header, 0, -2 );
|
||||
$r['headers']['cookie'] = $cookies_header;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes chunk transfer-encoding, based off the HTTP 1.1 specification.
|
||||
*
|
||||
* Based off the HTTP http_encoding_dechunk function.
|
||||
*
|
||||
* @link http://tools.ietf.org/html/rfc2616#section-19.4.6 Process for chunked decoding.
|
||||
*
|
||||
* @access public
|
||||
* @since 2.7.0
|
||||
* @static
|
||||
*
|
||||
* @param string $body Body content
|
||||
* @return string Chunked decoded body on success or raw body on failure.
|
||||
*/
|
||||
public static function chunkTransferDecode( $body ) {
|
||||
// The body is not chunked encoded or is malformed.
|
||||
if ( ! preg_match( '/^([0-9a-f]+)[^\r\n]*\r\n/i', trim( $body ) ) )
|
||||
return $body;
|
||||
|
||||
$parsed_body = '';
|
||||
|
||||
// We'll be altering $body, so need a backup in case of error.
|
||||
$body_original = $body;
|
||||
|
||||
while ( true ) {
|
||||
$has_chunk = (bool) preg_match( '/^([0-9a-f]+)[^\r\n]*\r\n/i', $body, $match );
|
||||
if ( ! $has_chunk || empty( $match[1] ) )
|
||||
return $body_original;
|
||||
|
||||
$length = hexdec( $match[1] );
|
||||
$chunk_length = strlen( $match[0] );
|
||||
|
||||
// Parse out the chunk of data.
|
||||
$parsed_body .= substr( $body, $chunk_length, $length );
|
||||
|
||||
// Remove the chunk from the raw data.
|
||||
$body = substr( $body, $length + $chunk_length );
|
||||
|
||||
// End of the document.
|
||||
if ( '0' === trim( $body ) )
|
||||
return $parsed_body;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Block requests through the proxy.
|
||||
*
|
||||
* Those who are behind a proxy and want to prevent access to certain hosts may do so. This will
|
||||
* prevent plugins from working and core functionality, if you don't include api.wordpress.org.
|
||||
*
|
||||
* You block external URL requests by defining WP_HTTP_BLOCK_EXTERNAL as true in your wp-config.php
|
||||
* file and this will only allow localhost and your site to make requests. The constant
|
||||
* WP_ACCESSIBLE_HOSTS will allow additional hosts to go through for requests. The format of the
|
||||
* WP_ACCESSIBLE_HOSTS constant is a comma separated list of hostnames to allow, wildcard domains
|
||||
* are supported, eg *.wordpress.org will allow for all subdomains of wordpress.org to be contacted.
|
||||
*
|
||||
* @since 2.8.0
|
||||
* @link https://core.trac.wordpress.org/ticket/8927 Allow preventing external requests.
|
||||
* @link https://core.trac.wordpress.org/ticket/14636 Allow wildcard domains in WP_ACCESSIBLE_HOSTS
|
||||
*
|
||||
* @staticvar array|null $accessible_hosts
|
||||
* @staticvar array $wildcard_regex
|
||||
*
|
||||
* @param string $uri URI of url.
|
||||
* @return bool True to block, false to allow.
|
||||
*/
|
||||
public function block_request($uri) {
|
||||
// We don't need to block requests, because nothing is blocked.
|
||||
if ( ! defined( 'WP_HTTP_BLOCK_EXTERNAL' ) || ! WP_HTTP_BLOCK_EXTERNAL )
|
||||
return false;
|
||||
|
||||
$check = parse_url($uri);
|
||||
if ( ! $check )
|
||||
return true;
|
||||
|
||||
$home = parse_url( get_option('siteurl') );
|
||||
|
||||
// Don't block requests back to ourselves by default.
|
||||
if ( 'localhost' == $check['host'] || ( isset( $home['host'] ) && $home['host'] == $check['host'] ) ) {
|
||||
/**
|
||||
* Filter whether to block local requests through the proxy.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @param bool $block Whether to block local requests through proxy.
|
||||
* Default false.
|
||||
*/
|
||||
return apply_filters( 'block_local_requests', false );
|
||||
}
|
||||
|
||||
if ( !defined('WP_ACCESSIBLE_HOSTS') )
|
||||
return true;
|
||||
|
||||
static $accessible_hosts = null;
|
||||
static $wildcard_regex = array();
|
||||
if ( null === $accessible_hosts ) {
|
||||
$accessible_hosts = preg_split('|,\s*|', WP_ACCESSIBLE_HOSTS);
|
||||
|
||||
if ( false !== strpos(WP_ACCESSIBLE_HOSTS, '*') ) {
|
||||
$wildcard_regex = array();
|
||||
foreach ( $accessible_hosts as $host )
|
||||
$wildcard_regex[] = str_replace( '\*', '.+', preg_quote( $host, '/' ) );
|
||||
$wildcard_regex = '/^(' . implode('|', $wildcard_regex) . ')$/i';
|
||||
}
|
||||
}
|
||||
|
||||
if ( !empty($wildcard_regex) )
|
||||
return !preg_match($wildcard_regex, $check['host']);
|
||||
else
|
||||
return !in_array( $check['host'], $accessible_hosts ); //Inverse logic, If it's in the array, then we can't access it.
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Used as a wrapper for PHP's parse_url() function that handles edgecases in < PHP 5.4.7.
|
||||
*
|
||||
* @access protected
|
||||
* @deprecated 4.4.0 Use wp_parse_url()
|
||||
* @see wp_parse_url()
|
||||
*
|
||||
* @param string $url The URL to parse.
|
||||
* @return bool|array False on failure; Array of URL components on success;
|
||||
* See parse_url()'s return values.
|
||||
*/
|
||||
protected static function parse_url( $url ) {
|
||||
_deprecated_function( __METHOD__, '4.4.0', 'wp_parse_url()' );
|
||||
return wp_parse_url( $url );
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a relative URL to an absolute URL relative to a given URL.
|
||||
*
|
||||
* If an Absolute URL is provided, no processing of that URL is done.
|
||||
*
|
||||
* @since 3.4.0
|
||||
*
|
||||
* @static
|
||||
* @access public
|
||||
*
|
||||
* @param string $maybe_relative_path The URL which might be relative
|
||||
* @param string $url The URL which $maybe_relative_path is relative to
|
||||
* @return string An Absolute URL, in a failure condition where the URL cannot be parsed, the relative URL will be returned.
|
||||
*/
|
||||
public static function make_absolute_url( $maybe_relative_path, $url ) {
|
||||
if ( empty( $url ) )
|
||||
return $maybe_relative_path;
|
||||
|
||||
if ( ! $url_parts = wp_parse_url( $url ) ) {
|
||||
return $maybe_relative_path;
|
||||
}
|
||||
|
||||
if ( ! $relative_url_parts = wp_parse_url( $maybe_relative_path ) ) {
|
||||
return $maybe_relative_path;
|
||||
}
|
||||
|
||||
// Check for a scheme on the 'relative' url
|
||||
if ( ! empty( $relative_url_parts['scheme'] ) ) {
|
||||
return $maybe_relative_path;
|
||||
}
|
||||
|
||||
$absolute_path = $url_parts['scheme'] . '://';
|
||||
|
||||
// Schemeless URL's will make it this far, so we check for a host in the relative url and convert it to a protocol-url
|
||||
if ( isset( $relative_url_parts['host'] ) ) {
|
||||
$absolute_path .= $relative_url_parts['host'];
|
||||
if ( isset( $relative_url_parts['port'] ) )
|
||||
$absolute_path .= ':' . $relative_url_parts['port'];
|
||||
} else {
|
||||
$absolute_path .= $url_parts['host'];
|
||||
if ( isset( $url_parts['port'] ) )
|
||||
$absolute_path .= ':' . $url_parts['port'];
|
||||
}
|
||||
|
||||
// Start off with the Absolute URL path.
|
||||
$path = ! empty( $url_parts['path'] ) ? $url_parts['path'] : '/';
|
||||
|
||||
// If it's a root-relative path, then great.
|
||||
if ( ! empty( $relative_url_parts['path'] ) && '/' == $relative_url_parts['path'][0] ) {
|
||||
$path = $relative_url_parts['path'];
|
||||
|
||||
// Else it's a relative path.
|
||||
} elseif ( ! empty( $relative_url_parts['path'] ) ) {
|
||||
// Strip off any file components from the absolute path.
|
||||
$path = substr( $path, 0, strrpos( $path, '/' ) + 1 );
|
||||
|
||||
// Build the new path.
|
||||
$path .= $relative_url_parts['path'];
|
||||
|
||||
// Strip all /path/../ out of the path.
|
||||
while ( strpos( $path, '../' ) > 1 ) {
|
||||
$path = preg_replace( '![^/]+/\.\./!', '', $path );
|
||||
}
|
||||
|
||||
// Strip any final leading ../ from the path.
|
||||
$path = preg_replace( '!^/(\.\./)+!', '', $path );
|
||||
}
|
||||
|
||||
// Add the Query string.
|
||||
if ( ! empty( $relative_url_parts['query'] ) )
|
||||
$path .= '?' . $relative_url_parts['query'];
|
||||
|
||||
return $absolute_path . '/' . ltrim( $path, '/' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles HTTP Redirects and follows them if appropriate.
|
||||
*
|
||||
* @since 3.7.0
|
||||
*
|
||||
* @static
|
||||
*
|
||||
* @param string $url The URL which was requested.
|
||||
* @param array $args The Arguments which were used to make the request.
|
||||
* @param array $response The Response of the HTTP request.
|
||||
* @return false|object False if no redirect is present, a WP_HTTP or WP_Error result otherwise.
|
||||
*/
|
||||
public static function handle_redirects( $url, $args, $response ) {
|
||||
// If no redirects are present, or, redirects were not requested, perform no action.
|
||||
if ( ! isset( $response['headers']['location'] ) || 0 === $args['_redirection'] )
|
||||
return false;
|
||||
|
||||
// Only perform redirections on redirection http codes.
|
||||
if ( $response['response']['code'] > 399 || $response['response']['code'] < 300 )
|
||||
return false;
|
||||
|
||||
// Don't redirect if we've run out of redirects.
|
||||
if ( $args['redirection']-- <= 0 )
|
||||
return new WP_Error( 'http_request_failed', __('Too many redirects.') );
|
||||
|
||||
$redirect_location = $response['headers']['location'];
|
||||
|
||||
// If there were multiple Location headers, use the last header specified.
|
||||
if ( is_array( $redirect_location ) )
|
||||
$redirect_location = array_pop( $redirect_location );
|
||||
|
||||
$redirect_location = WP_Http::make_absolute_url( $redirect_location, $url );
|
||||
|
||||
// POST requests should not POST to a redirected location.
|
||||
if ( 'POST' == $args['method'] ) {
|
||||
if ( in_array( $response['response']['code'], array( 302, 303 ) ) )
|
||||
$args['method'] = 'GET';
|
||||
}
|
||||
|
||||
// Include valid cookies in the redirect process.
|
||||
if ( ! empty( $response['cookies'] ) ) {
|
||||
foreach ( $response['cookies'] as $cookie ) {
|
||||
if ( $cookie->test( $redirect_location ) )
|
||||
$args['cookies'][] = $cookie;
|
||||
}
|
||||
}
|
||||
|
||||
return wp_remote_request( $redirect_location, $args );
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if a specified string represents an IP address or not.
|
||||
*
|
||||
* This function also detects the type of the IP address, returning either
|
||||
* '4' or '6' to represent a IPv4 and IPv6 address respectively.
|
||||
* This does not verify if the IP is a valid IP, only that it appears to be
|
||||
* an IP address.
|
||||
*
|
||||
* @link http://home.deds.nl/~aeron/regex/ for IPv6 regex
|
||||
*
|
||||
* @since 3.7.0
|
||||
* @static
|
||||
*
|
||||
* @param string $maybe_ip A suspected IP address
|
||||
* @return integer|bool Upon success, '4' or '6' to represent a IPv4 or IPv6 address, false upon failure
|
||||
*/
|
||||
public static function is_ip_address( $maybe_ip ) {
|
||||
if ( preg_match( '/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/', $maybe_ip ) )
|
||||
return 4;
|
||||
|
||||
if ( false !== strpos( $maybe_ip, ':' ) && preg_match( '/^(((?=.*(::))(?!.*\3.+\3))\3?|([\dA-F]{1,4}(\3|:\b|$)|\2))(?4){5}((?4){2}|(((2[0-4]|1\d|[1-9])?\d|25[0-5])\.?\b){4})$/i', trim( $maybe_ip, ' []' ) ) )
|
||||
return 6;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
960
Kapitel_7/Lektion_4/wordpress/wp-includes/class-json.php
Executable file
960
Kapitel_7/Lektion_4/wordpress/wp-includes/class-json.php
Executable file
@@ -0,0 +1,960 @@
|
||||
<?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 305040 2010-11-02 23:19:03Z 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);
|
||||
|
||||
/**
|
||||
* Behavior switch for Services_JSON::decode()
|
||||
*/
|
||||
define('SERVICES_JSON_USE_TO_JSON', 64);
|
||||
|
||||
/**
|
||||
* 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()
|
||||
* - SERVICES_JSON_USE_TO_JSON: call toJSON when serializing objects
|
||||
* It serializes the return value from the toJSON call rather
|
||||
* than the object itself, toJSON can return associative arrays,
|
||||
* strings or numbers, if you return an object, make sure it does
|
||||
* not have a toJSON method, otherwise an error will occur.
|
||||
*/
|
||||
function __construct( $use = 0 )
|
||||
{
|
||||
$this->use = $use;
|
||||
$this->_mb_strlen = function_exists('mb_strlen');
|
||||
$this->_mb_convert_encoding = function_exists('mb_convert_encoding');
|
||||
$this->_mb_substr = function_exists('mb_substr');
|
||||
}
|
||||
|
||||
/**
|
||||
* PHP4 constructor.
|
||||
*/
|
||||
public function Services_JSON( $use = 0 ) {
|
||||
self::__construct( $use );
|
||||
}
|
||||
// private - cache the mbstring lookup results..
|
||||
var $_mb_strlen = false;
|
||||
var $_mb_substr = false;
|
||||
var $_mb_convert_encoding = false;
|
||||
|
||||
/**
|
||||
* 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($this->_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($this->_mb_convert_encoding) {
|
||||
return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8');
|
||||
}
|
||||
|
||||
switch($this->strlen8($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->encodeUnsafe($var);
|
||||
}
|
||||
/**
|
||||
* encodes an arbitrary variable into JSON format without JSON Header - warning - may allow XSS!!!!)
|
||||
*
|
||||
* @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)
|
||||
{
|
||||
// see bug #16908 - regarding numeric locale printing
|
||||
$lc = setlocale(LC_NUMERIC, 0);
|
||||
setlocale(LC_NUMERIC, 'C');
|
||||
$ret = $this->_encode($var);
|
||||
setlocale(LC_NUMERIC, $lc);
|
||||
return $ret;
|
||||
|
||||
}
|
||||
/**
|
||||
* 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 = $this->strlen8($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 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':
|
||||
|
||||
// support toJSON methods.
|
||||
if (($this->use & SERVICES_JSON_USE_TO_JSON) && method_exists($var, 'toJSON')) {
|
||||
// this may end up allowing unlimited recursion
|
||||
// so we check the return value to make sure it's not got the same method.
|
||||
$recode = $var->toJSON();
|
||||
|
||||
if (method_exists($recode, 'toJSON')) {
|
||||
|
||||
return ($this->use & SERVICES_JSON_SUPPRESS_ERRORS)
|
||||
? 'null'
|
||||
: new Services_JSON_Error(get_class($var).
|
||||
" toJSON returned an object with a toJSON method.");
|
||||
|
||||
}
|
||||
|
||||
return $this->_encode( $recode );
|
||||
}
|
||||
|
||||
$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 = $this->substr8($str, 0, 1);
|
||||
$chrs = $this->substr8($str, 1, -1);
|
||||
$utf8 = '';
|
||||
$strlen_chrs = $this->strlen8($chrs);
|
||||
|
||||
for ($c = 0; $c < $strlen_chrs; ++$c) {
|
||||
|
||||
$substr_chrs_c_2 = $this->substr8($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', $this->substr8($chrs, $c, 6)):
|
||||
// single, escaped unicode character
|
||||
$utf16 = chr(hexdec($this->substr8($chrs, ($c + 2), 2)))
|
||||
. chr(hexdec($this->substr8($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 .= $this->substr8($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 .= $this->substr8($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 .= $this->substr8($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 .= $this->substr8($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 .= $this->substr8($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 = $this->substr8($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 = $this->strlen8($chrs);
|
||||
|
||||
for ($c = 0; $c <= $strlen_chrs; ++$c) {
|
||||
|
||||
$top = end($stk);
|
||||
$substr_chrs_c_2 = $this->substr8($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 = $this->substr8($chrs, $top['where'], ($c - $top['where']));
|
||||
array_push($stk, array('what' => SERVICES_JSON_SLICE, 'where' => ($c + 1), 'delim' => false));
|
||||
//print("Found split at {$c}: ".$this->substr8($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*:/Uis', $slice, $parts)) {
|
||||
// "name":value pair
|
||||
$key = $this->decode($parts[1]);
|
||||
$val = $this->decode(trim(substr($slice, strlen($parts[0])), ", \t\n\r\0\x0B"));
|
||||
if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
|
||||
$obj[$key] = $val;
|
||||
} else {
|
||||
$obj->$key = $val;
|
||||
}
|
||||
} elseif (preg_match('/^\s*(\w+)\s*:/Uis', $slice, $parts)) {
|
||||
// name:value pair, where name is unquoted
|
||||
$key = $parts[1];
|
||||
$val = $this->decode(trim(substr($slice, strlen($parts[0])), ", \t\n\r\0\x0B"));
|
||||
|
||||
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) &&
|
||||
(($this->strlen8($this->substr8($chrs, 0, $c)) - $this->strlen8(rtrim($this->substr8($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}: ".$this->substr8($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}: ".$this->substr8($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}: ".$this->substr8($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}: ".$this->substr8($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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates length of string in bytes
|
||||
* @param string
|
||||
* @return integer length
|
||||
*/
|
||||
function strlen8( $str )
|
||||
{
|
||||
if ( $this->_mb_strlen ) {
|
||||
return mb_strlen( $str, "8bit" );
|
||||
}
|
||||
return strlen( $str );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns part of a string, interpreting $start and $length as number of bytes.
|
||||
* @param string
|
||||
* @param integer start
|
||||
* @param integer length
|
||||
* @return integer length
|
||||
*/
|
||||
function substr8( $string, $start, $length=false )
|
||||
{
|
||||
if ( $length === false ) {
|
||||
$length = $this->strlen8( $string ) - $start;
|
||||
}
|
||||
if ( $this->_mb_substr ) {
|
||||
return mb_substr( $string, $start, $length, "8bit" );
|
||||
}
|
||||
return substr( $string, $start, $length );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (class_exists('PEAR_Error')) {
|
||||
|
||||
class Services_JSON_Error extends PEAR_Error
|
||||
{
|
||||
function __construct($message = 'unknown error', $code = null,
|
||||
$mode = null, $options = null, $userinfo = null)
|
||||
{
|
||||
parent::PEAR_Error($message, $code, $mode, $options, $userinfo);
|
||||
}
|
||||
|
||||
public function Services_JSON_Error($message = 'unknown error', $code = null,
|
||||
$mode = null, $options = null, $userinfo = null) {
|
||||
self::__construct($message = 'unknown error', $code = null,
|
||||
$mode = null, $options = null, $userinfo = null);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
/**
|
||||
* @todo Ultimately, this class shall be descended from PEAR_Error
|
||||
*/
|
||||
class Services_JSON_Error
|
||||
{
|
||||
/**
|
||||
* PHP5 constructor.
|
||||
*/
|
||||
function __construct( $message = 'unknown error', $code = null,
|
||||
$mode = null, $options = null, $userinfo = null )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* PHP4 constructor.
|
||||
*/
|
||||
public function Services_JSON_Error( $message = 'unknown error', $code = null,
|
||||
$mode = null, $options = null, $userinfo = null ) {
|
||||
self::__construct( $message, $code, $mode, $options, $userinfo );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endif;
|
||||
695
Kapitel_7/Lektion_4/wordpress/wp-includes/class-oembed.php
Executable file
695
Kapitel_7/Lektion_4/wordpress/wp-includes/class-oembed.php
Executable file
@@ -0,0 +1,695 @@
|
||||
<?php
|
||||
/**
|
||||
* API for fetching the HTML to embed remote content based on a provided URL
|
||||
*
|
||||
* Used internally by the WP_Embed class, but is designed to be generic.
|
||||
*
|
||||
* @link https://codex.wordpress.org/oEmbed oEmbed Codex Article
|
||||
* @link http://oembed.com/ oEmbed Homepage
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage oEmbed
|
||||
*/
|
||||
|
||||
/**
|
||||
* Core class used to implement oEmbed functionality.
|
||||
*
|
||||
* @since 2.9.0
|
||||
*/
|
||||
class WP_oEmbed {
|
||||
|
||||
/**
|
||||
* A list of oEmbed providers.
|
||||
*
|
||||
* @since 2.9.0
|
||||
* @access public
|
||||
* @var array
|
||||
*/
|
||||
public $providers = array();
|
||||
|
||||
/**
|
||||
* A list of an early oEmbed providers.
|
||||
*
|
||||
* @since 4.0.0
|
||||
* @access public
|
||||
* @static
|
||||
* @var array
|
||||
*/
|
||||
public static $early_providers = array();
|
||||
|
||||
/**
|
||||
* A list of private/protected methods, used for backwards compatibility.
|
||||
*
|
||||
* @since 4.2.0
|
||||
* @access private
|
||||
* @var array
|
||||
*/
|
||||
private $compat_methods = array( '_fetch_with_format', '_parse_json', '_parse_xml', '_parse_body' );
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @since 2.9.0
|
||||
* @access public
|
||||
*/
|
||||
public function __construct() {
|
||||
$host = urlencode( home_url() );
|
||||
$providers = array(
|
||||
'#http://((m|www)\.)?youtube\.com/watch.*#i' => array( 'http://www.youtube.com/oembed', true ),
|
||||
'#https://((m|www)\.)?youtube\.com/watch.*#i' => array( 'http://www.youtube.com/oembed?scheme=https', true ),
|
||||
'#http://((m|www)\.)?youtube\.com/playlist.*#i' => array( 'http://www.youtube.com/oembed', true ),
|
||||
'#https://((m|www)\.)?youtube\.com/playlist.*#i' => array( 'http://www.youtube.com/oembed?scheme=https', true ),
|
||||
'#http://youtu\.be/.*#i' => array( 'http://www.youtube.com/oembed', true ),
|
||||
'#https://youtu\.be/.*#i' => array( 'http://www.youtube.com/oembed?scheme=https', true ),
|
||||
'#https?://(.+\.)?vimeo\.com/.*#i' => array( 'http://vimeo.com/api/oembed.{format}', true ),
|
||||
'#https?://(www\.)?dailymotion\.com/.*#i' => array( 'https://www.dailymotion.com/services/oembed', true ),
|
||||
'#https?://dai.ly/.*#i' => array( 'https://www.dailymotion.com/services/oembed', true ),
|
||||
'#https?://(www\.)?flickr\.com/.*#i' => array( 'https://www.flickr.com/services/oembed/', true ),
|
||||
'#https?://flic\.kr/.*#i' => array( 'https://www.flickr.com/services/oembed/', true ),
|
||||
'#https?://(.+\.)?smugmug\.com/.*#i' => array( 'http://api.smugmug.com/services/oembed/', true ),
|
||||
'#https?://(www\.)?hulu\.com/watch/.*#i' => array( 'http://www.hulu.com/api/oembed.{format}', true ),
|
||||
'http://i*.photobucket.com/albums/*' => array( 'http://api.photobucket.com/oembed', false ),
|
||||
'http://gi*.photobucket.com/groups/*' => array( 'http://api.photobucket.com/oembed', false ),
|
||||
'#https?://(www\.)?scribd\.com/doc/.*#i' => array( 'http://www.scribd.com/services/oembed', true ),
|
||||
'#https?://wordpress.tv/.*#i' => array( 'http://wordpress.tv/oembed/', true ),
|
||||
'#https?://(.+\.)?polldaddy\.com/.*#i' => array( 'https://polldaddy.com/oembed/', true ),
|
||||
'#https?://poll\.fm/.*#i' => array( 'https://polldaddy.com/oembed/', true ),
|
||||
'#https?://(www\.)?funnyordie\.com/videos/.*#i' => array( 'http://www.funnyordie.com/oembed', true ),
|
||||
'#https?://(www\.)?twitter\.com/.+?/status(es)?/.*#i' => array( 'https://publish.twitter.com/oembed', true ),
|
||||
'#https?://(www\.)?twitter\.com/.+?/timelines/.*#i' => array( 'https://publish.twitter.com/oembed', true ),
|
||||
'#https?://(www\.)?twitter\.com/i/moments/.*#i' => array( 'https://publish.twitter.com/oembed', true ),
|
||||
'#https?://vine.co/v/.*#i' => array( 'https://vine.co/oembed.{format}', true ),
|
||||
'#https?://(www\.)?soundcloud\.com/.*#i' => array( 'http://soundcloud.com/oembed', true ),
|
||||
'#https?://(.+?\.)?slideshare\.net/.*#i' => array( 'https://www.slideshare.net/api/oembed/2', true ),
|
||||
'#https?://(www\.)?instagr(\.am|am\.com)/p/.*#i' => array( 'https://api.instagram.com/oembed', true ),
|
||||
'#https?://(open|play)\.spotify\.com/.*#i' => array( 'https://embed.spotify.com/oembed/', true ),
|
||||
'#https?://(.+\.)?imgur\.com/.*#i' => array( 'http://api.imgur.com/oembed', true ),
|
||||
'#https?://(www\.)?meetu(\.ps|p\.com)/.*#i' => array( 'http://api.meetup.com/oembed', true ),
|
||||
'#https?://(www\.)?issuu\.com/.+/docs/.+#i' => array( 'http://issuu.com/oembed_wp', true ),
|
||||
'#https?://(www\.)?collegehumor\.com/video/.*#i' => array( 'http://www.collegehumor.com/oembed.{format}', true ),
|
||||
'#https?://(www\.)?mixcloud\.com/.*#i' => array( 'http://www.mixcloud.com/oembed', true ),
|
||||
'#https?://(www\.|embed\.)?ted\.com/talks/.*#i' => array( 'http://www.ted.com/talks/oembed.{format}', true ),
|
||||
'#https?://(www\.)?(animoto|video214)\.com/play/.*#i' => array( 'https://animoto.com/oembeds/create', true ),
|
||||
'#https?://(.+)\.tumblr\.com/post/.*#i' => array( 'https://www.tumblr.com/oembed/1.0', true ),
|
||||
'#https?://(www\.)?kickstarter\.com/projects/.*#i' => array( 'https://www.kickstarter.com/services/oembed', true ),
|
||||
'#https?://kck\.st/.*#i' => array( 'https://www.kickstarter.com/services/oembed', true ),
|
||||
'#https?://cloudup\.com/.*#i' => array( 'https://cloudup.com/oembed', true ),
|
||||
'#https?://(www\.)?reverbnation\.com/.*#i' => array( 'https://www.reverbnation.com/oembed', true ),
|
||||
'#https?://videopress.com/v/.*#' => array( 'https://public-api.wordpress.com/oembed/1.0/?for=' . $host, true ),
|
||||
'#https?://(www\.)?reddit\.com/r/[^/]+/comments/.*#i' => array( 'https://www.reddit.com/oembed', true ),
|
||||
'#https?://(www\.)?speakerdeck\.com/.*#i' => array( 'https://speakerdeck.com/oembed.{format}', true ),
|
||||
);
|
||||
|
||||
if ( ! empty( self::$early_providers['add'] ) ) {
|
||||
foreach ( self::$early_providers['add'] as $format => $data ) {
|
||||
$providers[ $format ] = $data;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! empty( self::$early_providers['remove'] ) ) {
|
||||
foreach ( self::$early_providers['remove'] as $format ) {
|
||||
unset( $providers[ $format ] );
|
||||
}
|
||||
}
|
||||
|
||||
self::$early_providers = array();
|
||||
|
||||
/**
|
||||
* Filter the list of whitelisted oEmbed providers.
|
||||
*
|
||||
* Since WordPress 4.4, oEmbed discovery is enabled for all users and allows embedding of sanitized
|
||||
* iframes. The providers in this list are whitelisted, meaning they are trusted and allowed to
|
||||
* embed any content, such as iframes, videos, JavaScript, and arbitrary HTML.
|
||||
*
|
||||
* Supported providers:
|
||||
*
|
||||
* | Provider | Flavor | Supports HTTPS | Since |
|
||||
* | ------------ | --------------------- | :------------: | --------- |
|
||||
* | Dailymotion | dailymotion.com | Yes | 2.9.0 |
|
||||
* | Flickr | flickr.com | Yes | 2.9.0 |
|
||||
* | Hulu | hulu.com | Yes | 2.9.0 |
|
||||
* | Photobucket | photobucket.com | No | 2.9.0 |
|
||||
* | Scribd | scribd.com | Yes | 2.9.0 |
|
||||
* | Vimeo | vimeo.com | Yes | 2.9.0 |
|
||||
* | WordPress.tv | wordpress.tv | Yes | 2.9.0 |
|
||||
* | YouTube | youtube.com/watch | Yes | 2.9.0 |
|
||||
* | Funny or Die | funnyordie.com | Yes | 3.0.0 |
|
||||
* | Polldaddy | polldaddy.com | Yes | 3.0.0 |
|
||||
* | SmugMug | smugmug.com | Yes | 3.0.0 |
|
||||
* | YouTube | youtu.be | Yes | 3.0.0 |
|
||||
* | Twitter | twitter.com | Yes | 3.4.0 |
|
||||
* | Instagram | instagram.com | Yes | 3.5.0 |
|
||||
* | Instagram | instagr.am | Yes | 3.5.0 |
|
||||
* | Slideshare | slideshare.net | Yes | 3.5.0 |
|
||||
* | SoundCloud | soundcloud.com | Yes | 3.5.0 |
|
||||
* | Dailymotion | dai.ly | Yes | 3.6.0 |
|
||||
* | Flickr | flic.kr | Yes | 3.6.0 |
|
||||
* | Spotify | spotify.com | Yes | 3.6.0 |
|
||||
* | Imgur | imgur.com | Yes | 3.9.0 |
|
||||
* | Meetup.com | meetup.com | Yes | 3.9.0 |
|
||||
* | Meetup.com | meetu.ps | Yes | 3.9.0 |
|
||||
* | Animoto | animoto.com | Yes | 4.0.0 |
|
||||
* | Animoto | video214.com | Yes | 4.0.0 |
|
||||
* | CollegeHumor | collegehumor.com | Yes | 4.0.0 |
|
||||
* | Issuu | issuu.com | Yes | 4.0.0 |
|
||||
* | Mixcloud | mixcloud.com | Yes | 4.0.0 |
|
||||
* | Polldaddy | poll.fm | Yes | 4.0.0 |
|
||||
* | TED | ted.com | Yes | 4.0.0 |
|
||||
* | YouTube | youtube.com/playlist | Yes | 4.0.0 |
|
||||
* | Vine | vine.co | Yes | 4.1.0 |
|
||||
* | Tumblr | tumblr.com | Yes | 4.2.0 |
|
||||
* | Kickstarter | kickstarter.com | Yes | 4.2.0 |
|
||||
* | Kickstarter | kck.st | Yes | 4.2.0 |
|
||||
* | Cloudup | cloudup.com | Yes | 4.4.0 |
|
||||
* | ReverbNation | reverbnation.com | Yes | 4.4.0 |
|
||||
* | VideoPress | videopress.com | Yes | 4.4.0 |
|
||||
* | Reddit | reddit.com | Yes | 4.4.0 |
|
||||
* | Speaker Deck | speakerdeck.com | Yes | 4.4.0 |
|
||||
* | Twitter | twitter.com/timelines | Yes | 4.5.0 |
|
||||
* | Twitter | twitter.com/moments | Yes | 4.5.0 |
|
||||
*
|
||||
* No longer supported providers:
|
||||
*
|
||||
* | Provider | Flavor | Supports HTTPS | Since | Removed |
|
||||
* | ------------ | -------------------- | :------------: | --------- | --------- |
|
||||
* | Qik | qik.com | Yes | 2.9.0 | 3.9.0 |
|
||||
* | Viddler | viddler.com | Yes | 2.9.0 | 4.0.0 |
|
||||
* | Revision3 | revision3.com | No | 2.9.0 | 4.2.0 |
|
||||
* | Blip | blip.tv | No | 2.9.0 | 4.4.0 |
|
||||
* | Rdio | rdio.com | Yes | 3.6.0 | 4.4.1 |
|
||||
* | Rdio | rd.io | Yes | 3.6.0 | 4.4.1 |
|
||||
*
|
||||
* @see wp_oembed_add_provider()
|
||||
*
|
||||
* @since 2.9.0
|
||||
*
|
||||
* @param array $providers An array of popular oEmbed providers.
|
||||
*/
|
||||
$this->providers = apply_filters( 'oembed_providers', $providers );
|
||||
|
||||
// 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 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Exposes private/protected methods for backwards compatibility.
|
||||
*
|
||||
* @since 4.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param callable $name Method to call.
|
||||
* @param array $arguments Arguments to pass when calling.
|
||||
* @return mixed|bool Return value of the callback, false otherwise.
|
||||
*/
|
||||
public function __call( $name, $arguments ) {
|
||||
if ( in_array( $name, $this->compat_methods ) ) {
|
||||
return call_user_func_array( array( $this, $name ), $arguments );
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes a URL and returns the corresponding oEmbed provider's URL, if there is one.
|
||||
*
|
||||
* @since 4.0.0
|
||||
* @access public
|
||||
*
|
||||
* @see WP_oEmbed::discover()
|
||||
*
|
||||
* @param string $url The URL to the content.
|
||||
* @param string|array $args Optional provider arguments.
|
||||
* @return false|string False on failure, otherwise the oEmbed provider URL.
|
||||
*/
|
||||
public function get_provider( $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';
|
||||
$matchmask = preg_replace( '|^#http\\\://|', '#https?\://', $matchmask );
|
||||
}
|
||||
|
||||
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 );
|
||||
|
||||
return $provider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an oEmbed provider.
|
||||
*
|
||||
* The provider is removed just-in-time when wp_oembed_add_provider() is called before
|
||||
* the {@see 'plugins_loaded'} hook.
|
||||
*
|
||||
* The just-in-time addition is for the benefit of the {@see 'oembed_providers'} filter.
|
||||
*
|
||||
* @static
|
||||
* @since 4.0.0
|
||||
* @access public
|
||||
*
|
||||
* @see wp_oembed_add_provider()
|
||||
*
|
||||
* @param string $format Format of URL that this provider can handle. You can use
|
||||
* asterisks as wildcards.
|
||||
* @param string $provider The URL to the oEmbed provider..
|
||||
* @param bool $regex Optional. Whether the $format parameter is in a regex format.
|
||||
* Default false.
|
||||
*/
|
||||
public static function _add_provider_early( $format, $provider, $regex = false ) {
|
||||
if ( empty( self::$early_providers['add'] ) ) {
|
||||
self::$early_providers['add'] = array();
|
||||
}
|
||||
|
||||
self::$early_providers['add'][ $format ] = array( $provider, $regex );
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an oEmbed provider.
|
||||
*
|
||||
* The provider is removed just-in-time when wp_oembed_remove_provider() is called before
|
||||
* the {@see 'plugins_loaded'} hook.
|
||||
*
|
||||
* The just-in-time removal is for the benefit of the {@see 'oembed_providers'} filter.
|
||||
*
|
||||
* @since 4.0.0
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @see wp_oembed_remove_provider()
|
||||
*
|
||||
* @param string $format The format of URL that this provider can handle. You can use
|
||||
* asterisks as wildcards.
|
||||
*/
|
||||
public static function _remove_provider_early( $format ) {
|
||||
if ( empty( self::$early_providers['remove'] ) ) {
|
||||
self::$early_providers['remove'] = array();
|
||||
}
|
||||
|
||||
self::$early_providers['remove'][] = $format;
|
||||
}
|
||||
|
||||
/**
|
||||
* The do-it-all function that takes a URL and attempts to return the HTML.
|
||||
*
|
||||
* @see WP_oEmbed::fetch()
|
||||
* @see WP_oEmbed::data2html()
|
||||
*
|
||||
* @since 2.9.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $url The URL to the content that should be attempted to be embedded.
|
||||
* @param array|string $args Optional. Arguments, usually passed from a shortcode. Default empty.
|
||||
* @return false|string False on failure, otherwise the UNSANITIZED (and potentially unsafe) HTML that should be used to embed.
|
||||
*/
|
||||
public function get_html( $url, $args = '' ) {
|
||||
/**
|
||||
* Filters the oEmbed result before any HTTP requests are made.
|
||||
*
|
||||
* This allows one to short-circuit the default logic, perhaps by
|
||||
* replacing it with a routine that is more optimal for your setup.
|
||||
*
|
||||
* Passing a non-null value to the filter will effectively short-circuit retrieval,
|
||||
* returning the passed value instead.
|
||||
*
|
||||
* @since 4.5.3
|
||||
*
|
||||
* @param null|string $result The UNSANITIZED (and potentially unsafe) HTML that should be used to embed. Default null.
|
||||
* @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. Default empty.
|
||||
*/
|
||||
$pre = apply_filters( 'pre_oembed_result', null, $url, $args );
|
||||
|
||||
if ( null !== $pre ) {
|
||||
return $pre;
|
||||
}
|
||||
|
||||
$provider = $this->get_provider( $url, $args );
|
||||
|
||||
if ( ! $provider || false === $data = $this->fetch( $provider, $url, $args ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter the HTML returned by the oEmbed provider.
|
||||
*
|
||||
* @since 2.9.0
|
||||
*
|
||||
* @param string $data The returned oEmbed HTML.
|
||||
* @param string $url URL of the content to be embedded.
|
||||
* @param array $args Optional arguments, usually passed from a shortcode.
|
||||
*/
|
||||
return apply_filters( 'oembed_result', $this->data2html( $data, $url ), $url, $args );
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to discover link tags at the given URL for an oEmbed provider.
|
||||
*
|
||||
* @since 2.9.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $url The URL that should be inspected for discovery `<link>` tags.
|
||||
* @return false|string False on failure, otherwise the oEmbed provider URL.
|
||||
*/
|
||||
public function discover( $url ) {
|
||||
$providers = array();
|
||||
$args = array(
|
||||
'limit_response_size' => 153600, // 150 KB
|
||||
);
|
||||
|
||||
/**
|
||||
* Filter oEmbed remote get arguments.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @see WP_Http::request()
|
||||
*
|
||||
* @param array $args oEmbed remote get arguments.
|
||||
* @param string $url URL to be inspected.
|
||||
*/
|
||||
$args = apply_filters( 'oembed_remote_get_args', $args, $url );
|
||||
|
||||
// Fetch URL content
|
||||
$request = wp_safe_remote_get( $url, $args );
|
||||
if ( $html = wp_remote_retrieve_body( $request ) ) {
|
||||
|
||||
/**
|
||||
* Filter the link types that contain oEmbed provider URLs.
|
||||
*
|
||||
* @since 2.9.0
|
||||
*
|
||||
* @param array $format Array of oEmbed link types. Accepts 'application/json+oembed',
|
||||
* 'text/xml+oembed', and 'application/xml+oembed' (incorrect,
|
||||
* used by at least Vimeo).
|
||||
*/
|
||||
$linktypes = apply_filters( 'oembed_linktypes', array(
|
||||
'application/json+oembed' => 'json',
|
||||
'text/xml+oembed' => 'xml',
|
||||
'application/xml+oembed' => 'xml',
|
||||
) );
|
||||
|
||||
// Strip <body>
|
||||
if ( $html_head_end = stripos( $html, '</head>' ) ) {
|
||||
$html = substr( $html, 0, $html_head_end );
|
||||
}
|
||||
|
||||
// Do a quick check
|
||||
$tagfound = false;
|
||||
foreach ( $linktypes as $linktype => $format ) {
|
||||
if ( stripos($html, $linktype) ) {
|
||||
$tagfound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $tagfound && preg_match_all( '#<link([^<>]+)/?>#iU', $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']]] = htmlspecialchars_decode( $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.
|
||||
*
|
||||
* @since 2.9.0
|
||||
* @access public
|
||||
*
|
||||
* @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|string $args Optional. Arguments, usually passed from a shortcode. Default empty.
|
||||
* @return false|object False on failure, otherwise the result in the form of an object.
|
||||
*/
|
||||
public function fetch( $provider, $url, $args = '' ) {
|
||||
$args = wp_parse_args( $args, wp_embed_defaults( $url ) );
|
||||
|
||||
$provider = add_query_arg( 'maxwidth', (int) $args['width'], $provider );
|
||||
$provider = add_query_arg( 'maxheight', (int) $args['height'], $provider );
|
||||
$provider = add_query_arg( 'url', urlencode($url), $provider );
|
||||
|
||||
/**
|
||||
* Filter the oEmbed URL to be fetched.
|
||||
*
|
||||
* @since 2.9.0
|
||||
*
|
||||
* @param string $provider URL of the oEmbed provider.
|
||||
* @param string $url URL of the content to be embedded.
|
||||
* @param array $args Optional arguments, usually passed from a shortcode.
|
||||
*/
|
||||
$provider = apply_filters( 'oembed_fetch_url', $provider, $url, $args );
|
||||
|
||||
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 false|object|WP_Error False on failure, otherwise the result in the form of an object.
|
||||
*/
|
||||
private function _fetch_with_format( $provider_url_with_args, $format ) {
|
||||
$provider_url_with_args = add_query_arg( 'format', $format, $provider_url_with_args );
|
||||
|
||||
/** This filter is documented in wp-includes/class-oembed.php */
|
||||
$args = apply_filters( 'oembed_remote_get_args', array(), $provider_url_with_args );
|
||||
|
||||
$response = wp_safe_remote_get( $provider_url_with_args, $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
|
||||
*
|
||||
* @param string $response_body
|
||||
* @return object|false
|
||||
*/
|
||||
private function _parse_json( $response_body ) {
|
||||
$data = json_decode( trim( $response_body ) );
|
||||
return ( $data && is_object( $data ) ) ? $data : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses an XML response body.
|
||||
*
|
||||
* @since 3.0.0
|
||||
* @access private
|
||||
*
|
||||
* @param string $response_body
|
||||
* @return object|false
|
||||
*/
|
||||
private function _parse_xml( $response_body ) {
|
||||
if ( ! function_exists( 'libxml_disable_entity_loader' ) )
|
||||
return false;
|
||||
|
||||
$loader = libxml_disable_entity_loader( true );
|
||||
$errors = libxml_use_internal_errors( true );
|
||||
|
||||
$return = $this->_parse_xml_body( $response_body );
|
||||
|
||||
libxml_use_internal_errors( $errors );
|
||||
libxml_disable_entity_loader( $loader );
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Serves as a helper function for parsing an XML response body.
|
||||
*
|
||||
* @since 3.6.0
|
||||
* @access private
|
||||
*
|
||||
* @param string $response_body
|
||||
* @return object|false
|
||||
*/
|
||||
private function _parse_xml_body( $response_body ) {
|
||||
if ( ! function_exists( 'simplexml_import_dom' ) || ! class_exists( 'DOMDocument', false ) )
|
||||
return false;
|
||||
|
||||
$dom = new DOMDocument;
|
||||
$success = $dom->loadXML( $response_body );
|
||||
if ( ! $success )
|
||||
return false;
|
||||
|
||||
if ( isset( $dom->doctype ) )
|
||||
return false;
|
||||
|
||||
foreach ( $dom->childNodes as $child ) {
|
||||
if ( XML_DOCUMENT_TYPE_NODE === $child->nodeType )
|
||||
return false;
|
||||
}
|
||||
|
||||
$xml = simplexml_import_dom( $dom );
|
||||
if ( ! $xml )
|
||||
return false;
|
||||
|
||||
$return = new stdClass;
|
||||
foreach ( $xml as $key => $value ) {
|
||||
$return->$key = (string) $value;
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a data object from WP_oEmbed::fetch() and returns the HTML.
|
||||
*
|
||||
* @since 2.9.0
|
||||
* @access public
|
||||
*
|
||||
* @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 false|string False on error, otherwise the HTML needed to embed.
|
||||
*/
|
||||
public function data2html( $data, $url ) {
|
||||
if ( ! is_object( $data ) || empty( $data->type ) )
|
||||
return false;
|
||||
|
||||
$return = false;
|
||||
|
||||
switch ( $data->type ) {
|
||||
case 'photo':
|
||||
if ( empty( $data->url ) || empty( $data->width ) || empty( $data->height ) )
|
||||
break;
|
||||
if ( ! is_string( $data->url ) || ! is_numeric( $data->width ) || ! is_numeric( $data->height ) )
|
||||
break;
|
||||
|
||||
$title = ! empty( $data->title ) && is_string( $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':
|
||||
if ( ! empty( $data->html ) && is_string( $data->html ) )
|
||||
$return = $data->html;
|
||||
break;
|
||||
|
||||
case 'link':
|
||||
if ( ! empty( $data->title ) && is_string( $data->title ) )
|
||||
$return = '<a href="' . esc_url( $url ) . '">' . esc_html( $data->title ) . '</a>';
|
||||
break;
|
||||
|
||||
default:
|
||||
$return = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter the returned oEmbed HTML.
|
||||
*
|
||||
* Use this filter to add support for custom data types, or to filter the result.
|
||||
*
|
||||
* @since 2.9.0
|
||||
*
|
||||
* @param string $return The returned oEmbed HTML.
|
||||
* @param object $data A data object result from an oEmbed provider.
|
||||
* @param string $url The URL of the content to be embedded.
|
||||
*/
|
||||
return apply_filters( 'oembed_dataparse', $return, $data, $url );
|
||||
}
|
||||
|
||||
/**
|
||||
* Strips any new lines from the HTML.
|
||||
*
|
||||
* @since 2.9.0 as strip_scribd_newlines()
|
||||
* @since 3.0.0
|
||||
* @access public
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
public function _strip_newlines( $html, $data, $url ) {
|
||||
if ( false === strpos( $html, "\n" ) ) {
|
||||
return $html;
|
||||
}
|
||||
|
||||
$count = 1;
|
||||
$found = array();
|
||||
$token = '__PRE__';
|
||||
$search = array( "\t", "\n", "\r", ' ' );
|
||||
$replace = array( '__TAB__', '__NL__', '__CR__', '__SPACE__' );
|
||||
$tokenized = str_replace( $search, $replace, $html );
|
||||
|
||||
preg_match_all( '#(<pre[^>]*>.+?</pre>)#i', $tokenized, $matches, PREG_SET_ORDER );
|
||||
foreach ( $matches as $i => $match ) {
|
||||
$tag_html = str_replace( $replace, $search, $match[0] );
|
||||
$tag_token = $token . $i;
|
||||
|
||||
$found[ $tag_token ] = $tag_html;
|
||||
$html = str_replace( $tag_html, $tag_token, $html, $count );
|
||||
}
|
||||
|
||||
$replaced = str_replace( $replace, $search, $html );
|
||||
$stripped = str_replace( array( "\r\n", "\n" ), '', $replaced );
|
||||
$pre = array_values( $found );
|
||||
$tokens = array_keys( $found );
|
||||
|
||||
return str_replace( $tokens, $pre, $stripped );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the initialized WP_oEmbed object.
|
||||
*
|
||||
* @since 2.9.0
|
||||
* @access private
|
||||
*
|
||||
* @staticvar WP_oEmbed $wp_oembed
|
||||
*
|
||||
* @return WP_oEmbed object.
|
||||
*/
|
||||
function _wp_oembed_get_object() {
|
||||
static $wp_oembed = null;
|
||||
|
||||
if ( is_null( $wp_oembed ) ) {
|
||||
$wp_oembed = new WP_oEmbed();
|
||||
}
|
||||
return $wp_oembed;
|
||||
}
|
||||
276
Kapitel_7/Lektion_4/wordpress/wp-includes/class-phpass.php
Executable file
276
Kapitel_7/Lektion_4/wordpress/wp-includes/class-phpass.php
Executable file
@@ -0,0 +1,276 @@
|
||||
<?php
|
||||
/**
|
||||
* Portable PHP password hashing framework.
|
||||
* @package phpass
|
||||
* @since 2.5.0
|
||||
* @version 0.3 / WordPress
|
||||
* @link http://www.openwall.com/phpass/
|
||||
*/
|
||||
|
||||
#
|
||||
# Written by Solar Designer <solar at openwall.com> in 2004-2006 and placed in
|
||||
# the public domain. Revised in subsequent years, still 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.3 / WordPress
|
||||
* @link http://www.openwall.com/phpass/
|
||||
* @since 2.5.0
|
||||
*/
|
||||
class PasswordHash {
|
||||
var $itoa64;
|
||||
var $iteration_count_log2;
|
||||
var $portable_hashes;
|
||||
var $random_state;
|
||||
|
||||
/**
|
||||
* PHP5 constructor.
|
||||
*/
|
||||
function __construct( $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 compatibility reasons
|
||||
}
|
||||
|
||||
/**
|
||||
* PHP4 constructor.
|
||||
*/
|
||||
public function PasswordHash( $iteration_count_log2, $portable_hashes ) {
|
||||
self::__construct( $iteration_count_log2, $portable_hashes );
|
||||
}
|
||||
|
||||
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';
|
||||
|
||||
$id = substr($setting, 0, 3);
|
||||
# We use "$P$", phpBB3 uses "$H$" for the same thing
|
||||
if ($id != '$P$' && $id != '$H$')
|
||||
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)
|
||||
{
|
||||
if ( strlen( $password ) > 4096 ) {
|
||||
return '*';
|
||||
}
|
||||
|
||||
$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)
|
||||
{
|
||||
if ( strlen( $password ) > 4096 ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$hash = $this->crypt_private($password, $stored_hash);
|
||||
if ($hash[0] == '*')
|
||||
$hash = crypt($password, $stored_hash);
|
||||
|
||||
return $hash === $stored_hash;
|
||||
}
|
||||
}
|
||||
3828
Kapitel_7/Lektion_4/wordpress/wp-includes/class-phpmailer.php
Executable file
3828
Kapitel_7/Lektion_4/wordpress/wp-includes/class-phpmailer.php
Executable file
File diff suppressed because it is too large
Load Diff
662
Kapitel_7/Lektion_4/wordpress/wp-includes/class-pop3.php
Executable file
662
Kapitel_7/Lektion_4/wordpress/wp-includes/class-pop3.php
Executable file
@@ -0,0 +1,662 @@
|
||||
<?php
|
||||
/**
|
||||
* mail_fetch/setup.php
|
||||
*
|
||||
* Copyright (c) 1999-2011 CDI (cdi@thewebmasters.net) All Rights Reserved
|
||||
* Modified by Philippe Mingo 2001-2009 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.
|
||||
*
|
||||
* POP3 class
|
||||
*
|
||||
* @copyright 1999-2011 The SquirrelMail Project Team
|
||||
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
|
||||
* @package plugins
|
||||
* @subpackage mail_fetch
|
||||
*/
|
||||
|
||||
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
|
||||
|
||||
/**
|
||||
* PHP5 constructor.
|
||||
*/
|
||||
function __construct ( $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;
|
||||
}
|
||||
|
||||
/**
|
||||
* PHP4 constructor.
|
||||
*/
|
||||
public function POP3( $server = '', $timeout = '' ) {
|
||||
self::__construct( $server, $timeout );
|
||||
}
|
||||
|
||||
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 its 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 ( !preg_match('/^\.\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(strpos($line, '.') === 0)
|
||||
{
|
||||
$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 ( !preg_match('/^\.\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 ( !preg_match('/^\.\r\n/',$line)) {
|
||||
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( stripos($cmd, '+OK') !== false );
|
||||
}
|
||||
|
||||
function strip_clf ($text = "") {
|
||||
// Strips \r\n from server responses
|
||||
|
||||
if(empty($text))
|
||||
return $text;
|
||||
else {
|
||||
$stripped = str_replace(array("\r","\n"),'',$text);
|
||||
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
|
||||
|
||||
// For php4 compatibility
|
||||
if (!function_exists("stripos")) {
|
||||
function stripos($haystack, $needle){
|
||||
return strpos($haystack, stristr( $haystack, $needle ));
|
||||
}
|
||||
}
|
||||
3119
Kapitel_7/Lektion_4/wordpress/wp-includes/class-simplepie.php
Executable file
3119
Kapitel_7/Lektion_4/wordpress/wp-includes/class-simplepie.php
Executable file
File diff suppressed because it is too large
Load Diff
1118
Kapitel_7/Lektion_4/wordpress/wp-includes/class-smtp.php
Executable file
1118
Kapitel_7/Lektion_4/wordpress/wp-includes/class-smtp.php
Executable file
File diff suppressed because it is too large
Load Diff
1259
Kapitel_7/Lektion_4/wordpress/wp-includes/class-snoopy.php
Executable file
1259
Kapitel_7/Lektion_4/wordpress/wp-includes/class-snoopy.php
Executable file
File diff suppressed because it is too large
Load Diff
80
Kapitel_7/Lektion_4/wordpress/wp-includes/class-walker-category-dropdown.php
Executable file
80
Kapitel_7/Lektion_4/wordpress/wp-includes/class-walker-category-dropdown.php
Executable file
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
/**
|
||||
* Taxonomy API: Walker_CategoryDropdown class
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Template
|
||||
* @since 4.4.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Core class used to create an HTML dropdown list of Categories.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @see Walker
|
||||
*/
|
||||
class Walker_CategoryDropdown extends Walker {
|
||||
|
||||
/**
|
||||
* What the class handles.
|
||||
*
|
||||
* @since 2.1.0
|
||||
* @access private
|
||||
* @var string
|
||||
*
|
||||
* @see Walker::$tree_type
|
||||
*/
|
||||
public $tree_type = 'category';
|
||||
|
||||
/**
|
||||
* Database fields to use.
|
||||
*
|
||||
* @since 2.1.0
|
||||
* @access public
|
||||
* @todo Decouple this
|
||||
* @var array
|
||||
*
|
||||
* @see Walker::$db_fields
|
||||
*/
|
||||
public $db_fields = array ('parent' => 'parent', 'id' => 'term_id');
|
||||
|
||||
/**
|
||||
* Starts the element output.
|
||||
*
|
||||
* @since 2.1.0
|
||||
* @access public
|
||||
*
|
||||
* @see Walker::start_el()
|
||||
*
|
||||
* @param string $output Passed by reference. Used to append additional content.
|
||||
* @param object $category Category data object.
|
||||
* @param int $depth Depth of category. Used for padding.
|
||||
* @param array $args Uses 'selected', 'show_count', and 'value_field' keys, if they exist.
|
||||
* See wp_dropdown_categories().
|
||||
* @param int $id Optional. ID of the current category. Default 0 (unused).
|
||||
*/
|
||||
public function start_el( &$output, $category, $depth = 0, $args = array(), $id = 0 ) {
|
||||
$pad = str_repeat(' ', $depth * 3);
|
||||
|
||||
/** This filter is documented in wp-includes/category-template.php */
|
||||
$cat_name = apply_filters( 'list_cats', $category->name, $category );
|
||||
|
||||
if ( isset( $args['value_field'] ) && isset( $category->{$args['value_field']} ) ) {
|
||||
$value_field = $args['value_field'];
|
||||
} else {
|
||||
$value_field = 'term_id';
|
||||
}
|
||||
|
||||
$output .= "\t<option class=\"level-$depth\" value=\"" . esc_attr( $category->{$value_field} ) . "\"";
|
||||
|
||||
// Type-juggling causes false matches, so we force everything to a string.
|
||||
if ( (string) $category->{$value_field} === (string) $args['selected'] )
|
||||
$output .= ' selected="selected"';
|
||||
$output .= '>';
|
||||
$output .= $pad.$cat_name;
|
||||
if ( $args['show_count'] )
|
||||
$output .= ' ('. number_format_i18n( $category->count ) .')';
|
||||
$output .= "</option>\n";
|
||||
}
|
||||
}
|
||||
235
Kapitel_7/Lektion_4/wordpress/wp-includes/class-walker-category.php
Executable file
235
Kapitel_7/Lektion_4/wordpress/wp-includes/class-walker-category.php
Executable file
@@ -0,0 +1,235 @@
|
||||
<?php
|
||||
/**
|
||||
* Taxonomy API: Walker_Category class
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Template
|
||||
* @since 4.4.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Core class used to create an HTML list of categories.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @see Walker
|
||||
*/
|
||||
class Walker_Category extends Walker {
|
||||
|
||||
/**
|
||||
* What the class handles.
|
||||
*
|
||||
* @since 2.1.0
|
||||
* @access public
|
||||
* @var string
|
||||
*
|
||||
* @see Walker::$tree_type
|
||||
*/
|
||||
public $tree_type = 'category';
|
||||
|
||||
/**
|
||||
* Database fields to use.
|
||||
*
|
||||
* @since 2.1.0
|
||||
* @access public
|
||||
* @var array
|
||||
*
|
||||
* @see Walker::$db_fields
|
||||
* @todo Decouple this
|
||||
*/
|
||||
public $db_fields = array ('parent' => 'parent', 'id' => 'term_id');
|
||||
|
||||
/**
|
||||
* Starts the list before the elements are added.
|
||||
*
|
||||
* @since 2.1.0
|
||||
* @access public
|
||||
*
|
||||
* @see Walker::start_lvl()
|
||||
*
|
||||
* @param string $output Used to append additional content. Passed by reference.
|
||||
* @param int $depth Optional. Depth of category. Used for tab indentation. Default 0.
|
||||
* @param array $args Optional. An array of arguments. Will only append content if style argument
|
||||
* value is 'list'. See wp_list_categories(). Default empty array.
|
||||
*/
|
||||
public function start_lvl( &$output, $depth = 0, $args = array() ) {
|
||||
if ( 'list' != $args['style'] )
|
||||
return;
|
||||
|
||||
$indent = str_repeat("\t", $depth);
|
||||
$output .= "$indent<ul class='children'>\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Ends the list of after the elements are added.
|
||||
*
|
||||
* @since 2.1.0
|
||||
* @access public
|
||||
*
|
||||
* @see Walker::end_lvl()
|
||||
*
|
||||
* @param string $output Used to append additional content. Passed by reference.
|
||||
* @param int $depth Optional. Depth of category. Used for tab indentation. Default 0.
|
||||
* @param array $args Optional. An array of arguments. Will only append content if style argument
|
||||
* value is 'list'. See wp_list_categories(). Default empty array.
|
||||
*/
|
||||
public function end_lvl( &$output, $depth = 0, $args = array() ) {
|
||||
if ( 'list' != $args['style'] )
|
||||
return;
|
||||
|
||||
$indent = str_repeat("\t", $depth);
|
||||
$output .= "$indent</ul>\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the element output.
|
||||
*
|
||||
* @since 2.1.0
|
||||
* @access public
|
||||
*
|
||||
* @see Walker::start_el()
|
||||
*
|
||||
* @param string $output Passed by reference. Used to append additional content.
|
||||
* @param object $category Category data object.
|
||||
* @param int $depth Optional. Depth of category in reference to parents. Default 0.
|
||||
* @param array $args Optional. An array of arguments. See wp_list_categories(). Default empty array.
|
||||
* @param int $id Optional. ID of the current category. Default 0.
|
||||
*/
|
||||
public function start_el( &$output, $category, $depth = 0, $args = array(), $id = 0 ) {
|
||||
/** This filter is documented in wp-includes/category-template.php */
|
||||
$cat_name = apply_filters(
|
||||
'list_cats',
|
||||
esc_attr( $category->name ),
|
||||
$category
|
||||
);
|
||||
|
||||
// Don't generate an element if the category name is empty.
|
||||
if ( ! $cat_name ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$link = '<a href="' . esc_url( get_term_link( $category ) ) . '" ';
|
||||
if ( $args['use_desc_for_title'] && ! empty( $category->description ) ) {
|
||||
/**
|
||||
* Filter the category description for display.
|
||||
*
|
||||
* @since 1.2.0
|
||||
*
|
||||
* @param string $description Category description.
|
||||
* @param object $category Category object.
|
||||
*/
|
||||
$link .= 'title="' . esc_attr( strip_tags( apply_filters( 'category_description', $category->description, $category ) ) ) . '"';
|
||||
}
|
||||
|
||||
$link .= '>';
|
||||
$link .= $cat_name . '</a>';
|
||||
|
||||
if ( ! empty( $args['feed_image'] ) || ! empty( $args['feed'] ) ) {
|
||||
$link .= ' ';
|
||||
|
||||
if ( empty( $args['feed_image'] ) ) {
|
||||
$link .= '(';
|
||||
}
|
||||
|
||||
$link .= '<a href="' . esc_url( get_term_feed_link( $category->term_id, $category->taxonomy, $args['feed_type'] ) ) . '"';
|
||||
|
||||
if ( empty( $args['feed'] ) ) {
|
||||
$alt = ' alt="' . sprintf(__( 'Feed for all posts filed under %s' ), $cat_name ) . '"';
|
||||
} else {
|
||||
$alt = ' alt="' . $args['feed'] . '"';
|
||||
$name = $args['feed'];
|
||||
$link .= empty( $args['title'] ) ? '' : $args['title'];
|
||||
}
|
||||
|
||||
$link .= '>';
|
||||
|
||||
if ( empty( $args['feed_image'] ) ) {
|
||||
$link .= $name;
|
||||
} else {
|
||||
$link .= "<img src='" . $args['feed_image'] . "'$alt" . ' />';
|
||||
}
|
||||
$link .= '</a>';
|
||||
|
||||
if ( empty( $args['feed_image'] ) ) {
|
||||
$link .= ')';
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! empty( $args['show_count'] ) ) {
|
||||
$link .= ' (' . number_format_i18n( $category->count ) . ')';
|
||||
}
|
||||
if ( 'list' == $args['style'] ) {
|
||||
$output .= "\t<li";
|
||||
$css_classes = array(
|
||||
'cat-item',
|
||||
'cat-item-' . $category->term_id,
|
||||
);
|
||||
|
||||
if ( ! empty( $args['current_category'] ) ) {
|
||||
// 'current_category' can be an array, so we use `get_terms()`.
|
||||
$_current_terms = get_terms( $category->taxonomy, array(
|
||||
'include' => $args['current_category'],
|
||||
'hide_empty' => false,
|
||||
) );
|
||||
|
||||
foreach ( $_current_terms as $_current_term ) {
|
||||
if ( $category->term_id == $_current_term->term_id ) {
|
||||
$css_classes[] = 'current-cat';
|
||||
} elseif ( $category->term_id == $_current_term->parent ) {
|
||||
$css_classes[] = 'current-cat-parent';
|
||||
}
|
||||
while ( $_current_term->parent ) {
|
||||
if ( $category->term_id == $_current_term->parent ) {
|
||||
$css_classes[] = 'current-cat-ancestor';
|
||||
break;
|
||||
}
|
||||
$_current_term = get_term( $_current_term->parent, $category->taxonomy );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter the list of CSS classes to include with each category in the list.
|
||||
*
|
||||
* @since 4.2.0
|
||||
*
|
||||
* @see wp_list_categories()
|
||||
*
|
||||
* @param array $css_classes An array of CSS classes to be applied to each list item.
|
||||
* @param object $category Category data object.
|
||||
* @param int $depth Depth of page, used for padding.
|
||||
* @param array $args An array of wp_list_categories() arguments.
|
||||
*/
|
||||
$css_classes = implode( ' ', apply_filters( 'category_css_class', $css_classes, $category, $depth, $args ) );
|
||||
|
||||
$output .= ' class="' . $css_classes . '"';
|
||||
$output .= ">$link\n";
|
||||
} elseif ( isset( $args['separator'] ) ) {
|
||||
$output .= "\t$link" . $args['separator'] . "\n";
|
||||
} else {
|
||||
$output .= "\t$link<br />\n";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ends the element output, if needed.
|
||||
*
|
||||
* @since 2.1.0
|
||||
* @access public
|
||||
*
|
||||
* @see Walker::end_el()
|
||||
*
|
||||
* @param string $output Passed by reference. Used to append additional content.
|
||||
* @param object $page Not used.
|
||||
* @param int $depth Optional. Depth of category. Not used.
|
||||
* @param array $args Optional. An array of arguments. Only uses 'list' for whether should append
|
||||
* to output. See wp_list_categories(). Default empty array.
|
||||
*/
|
||||
public function end_el( &$output, $page, $depth = 0, $args = array() ) {
|
||||
if ( 'list' != $args['style'] )
|
||||
return;
|
||||
|
||||
$output .= "</li>\n";
|
||||
}
|
||||
|
||||
}
|
||||
364
Kapitel_7/Lektion_4/wordpress/wp-includes/class-walker-comment.php
Executable file
364
Kapitel_7/Lektion_4/wordpress/wp-includes/class-walker-comment.php
Executable file
@@ -0,0 +1,364 @@
|
||||
<?php
|
||||
/**
|
||||
* Comment API: Walker_Comment class
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Comments
|
||||
* @since 4.4.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Core walker class used to create an HTML list of comments.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*
|
||||
* @see Walker
|
||||
*/
|
||||
class Walker_Comment extends Walker {
|
||||
|
||||
/**
|
||||
* What the class handles.
|
||||
*
|
||||
* @since 2.7.0
|
||||
* @access public
|
||||
* @var string
|
||||
*
|
||||
* @see Walker::$tree_type
|
||||
*/
|
||||
public $tree_type = 'comment';
|
||||
|
||||
/**
|
||||
* Database fields to use.
|
||||
*
|
||||
* @since 2.7.0
|
||||
* @access public
|
||||
* @var array
|
||||
*
|
||||
* @see Walker::$db_fields
|
||||
* @todo Decouple this
|
||||
*/
|
||||
public $db_fields = array ('parent' => 'comment_parent', 'id' => 'comment_ID');
|
||||
|
||||
/**
|
||||
* Starts the list before the elements are added.
|
||||
*
|
||||
* @since 2.7.0
|
||||
* @access public
|
||||
*
|
||||
* @see Walker::start_lvl()
|
||||
* @global int $comment_depth
|
||||
*
|
||||
* @param string $output Passed by reference. Used to append additional content.
|
||||
* @param int $depth Optional. Depth of the current comment. Default 0.
|
||||
* @param array $args Optional. Uses 'style' argument for type of HTML list. Default empty array.
|
||||
*/
|
||||
public function start_lvl( &$output, $depth = 0, $args = array() ) {
|
||||
$GLOBALS['comment_depth'] = $depth + 1;
|
||||
|
||||
switch ( $args['style'] ) {
|
||||
case 'div':
|
||||
break;
|
||||
case 'ol':
|
||||
$output .= '<ol class="children">' . "\n";
|
||||
break;
|
||||
case 'ul':
|
||||
default:
|
||||
$output .= '<ul class="children">' . "\n";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ends the list of items after the elements are added.
|
||||
*
|
||||
* @since 2.7.0
|
||||
* @access public
|
||||
*
|
||||
* @see Walker::end_lvl()
|
||||
* @global int $comment_depth
|
||||
*
|
||||
* @param string $output Passed by reference. Used to append additional content.
|
||||
* @param int $depth Optional. Depth of the current comment. Default 0.
|
||||
* @param array $args Optional. Will only append content if style argument value is 'ol' or 'ul'.
|
||||
* Default empty array.
|
||||
*/
|
||||
public function end_lvl( &$output, $depth = 0, $args = array() ) {
|
||||
$GLOBALS['comment_depth'] = $depth + 1;
|
||||
|
||||
switch ( $args['style'] ) {
|
||||
case 'div':
|
||||
break;
|
||||
case 'ol':
|
||||
$output .= "</ol><!-- .children -->\n";
|
||||
break;
|
||||
case 'ul':
|
||||
default:
|
||||
$output .= "</ul><!-- .children -->\n";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Traverses elements to create list from elements.
|
||||
*
|
||||
* This function is designed to enhance Walker::display_element() to
|
||||
* display children of higher nesting levels than selected inline on
|
||||
* the highest depth level displayed. This prevents them being orphaned
|
||||
* at the end of the comment list.
|
||||
*
|
||||
* Example: max_depth = 2, with 5 levels of nested content.
|
||||
* 1
|
||||
* 1.1
|
||||
* 1.1.1
|
||||
* 1.1.1.1
|
||||
* 1.1.1.1.1
|
||||
* 1.1.2
|
||||
* 1.1.2.1
|
||||
* 2
|
||||
* 2.2
|
||||
*
|
||||
* @since 2.7.0
|
||||
* @access public
|
||||
*
|
||||
* @see Walker::display_element()
|
||||
* @see wp_list_comments()
|
||||
*
|
||||
* @param WP_Comment $element Comment data object.
|
||||
* @param array $children_elements List of elements to continue traversing. Passed by reference.
|
||||
* @param int $max_depth Max depth to traverse.
|
||||
* @param int $depth Depth of the current element.
|
||||
* @param array $args An array of arguments.
|
||||
* @param string $output Used to append additional content. Passed by reference.
|
||||
*/
|
||||
public function display_element( $element, &$children_elements, $max_depth, $depth, $args, &$output ) {
|
||||
if ( !$element )
|
||||
return;
|
||||
|
||||
$id_field = $this->db_fields['id'];
|
||||
$id = $element->$id_field;
|
||||
|
||||
parent::display_element( $element, $children_elements, $max_depth, $depth, $args, $output );
|
||||
|
||||
/*
|
||||
* If at the max depth, and the current element still has children, loop over those
|
||||
* and display them at this level. This is to prevent them being orphaned to the end
|
||||
* of the list.
|
||||
*/
|
||||
if ( $max_depth <= $depth + 1 && isset( $children_elements[$id]) ) {
|
||||
foreach ( $children_elements[ $id ] as $child )
|
||||
$this->display_element( $child, $children_elements, $max_depth, $depth, $args, $output );
|
||||
|
||||
unset( $children_elements[ $id ] );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the element output.
|
||||
*
|
||||
* @since 2.7.0
|
||||
* @access public
|
||||
*
|
||||
* @see Walker::start_el()
|
||||
* @see wp_list_comments()
|
||||
* @global int $comment_depth
|
||||
* @global WP_Comment $comment
|
||||
*
|
||||
* @param string $output Used to append additional content. Passed by reference.
|
||||
* @param WP_Comment $comment Comment data object.
|
||||
* @param int $depth Optional. Depth of the current comment in reference to parents. Default 0.
|
||||
* @param array $args Optional. An array of arguments. Default empty array.
|
||||
* @param int $id Optional. ID of the current comment. Default 0 (unused).
|
||||
*/
|
||||
public function start_el( &$output, $comment, $depth = 0, $args = array(), $id = 0 ) {
|
||||
$depth++;
|
||||
$GLOBALS['comment_depth'] = $depth;
|
||||
$GLOBALS['comment'] = $comment;
|
||||
|
||||
if ( !empty( $args['callback'] ) ) {
|
||||
ob_start();
|
||||
call_user_func( $args['callback'], $comment, $args, $depth );
|
||||
$output .= ob_get_clean();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ( 'pingback' == $comment->comment_type || 'trackback' == $comment->comment_type ) && $args['short_ping'] ) {
|
||||
ob_start();
|
||||
$this->ping( $comment, $depth, $args );
|
||||
$output .= ob_get_clean();
|
||||
} elseif ( 'html5' === $args['format'] ) {
|
||||
ob_start();
|
||||
$this->html5_comment( $comment, $depth, $args );
|
||||
$output .= ob_get_clean();
|
||||
} else {
|
||||
ob_start();
|
||||
$this->comment( $comment, $depth, $args );
|
||||
$output .= ob_get_clean();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ends the element output, if needed.
|
||||
*
|
||||
* @since 2.7.0
|
||||
* @access public
|
||||
*
|
||||
* @see Walker::end_el()
|
||||
* @see wp_list_comments()
|
||||
*
|
||||
* @param string $output Used to append additional content. Passed by reference.
|
||||
* @param WP_Comment $comment The current comment object. Default current comment.
|
||||
* @param int $depth Optional. Depth of the current comment. Default 0.
|
||||
* @param array $args Optional. An array of arguments. Default empty array.
|
||||
*/
|
||||
public function end_el( &$output, $comment, $depth = 0, $args = array() ) {
|
||||
if ( !empty( $args['end-callback'] ) ) {
|
||||
ob_start();
|
||||
call_user_func( $args['end-callback'], $comment, $args, $depth );
|
||||
$output .= ob_get_clean();
|
||||
return;
|
||||
}
|
||||
if ( 'div' == $args['style'] )
|
||||
$output .= "</div><!-- #comment-## -->\n";
|
||||
else
|
||||
$output .= "</li><!-- #comment-## -->\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs a pingback comment.
|
||||
*
|
||||
* @since 3.6.0
|
||||
* @access protected
|
||||
*
|
||||
* @see wp_list_comments()
|
||||
*
|
||||
* @param WP_Comment $comment The comment object.
|
||||
* @param int $depth Depth of the current comment.
|
||||
* @param array $args An array of arguments.
|
||||
*/
|
||||
protected function ping( $comment, $depth, $args ) {
|
||||
$tag = ( 'div' == $args['style'] ) ? 'div' : 'li';
|
||||
?>
|
||||
<<?php echo $tag; ?> id="comment-<?php comment_ID(); ?>" <?php comment_class( '', $comment ); ?>>
|
||||
<div class="comment-body">
|
||||
<?php _e( 'Pingback:' ); ?> <?php comment_author_link( $comment ); ?> <?php edit_comment_link( __( 'Edit' ), '<span class="edit-link">', '</span>' ); ?>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs a single comment.
|
||||
*
|
||||
* @since 3.6.0
|
||||
* @access protected
|
||||
*
|
||||
* @see wp_list_comments()
|
||||
*
|
||||
* @param WP_Comment $comment Comment to display.
|
||||
* @param int $depth Depth of the current comment.
|
||||
* @param array $args An array of arguments.
|
||||
*/
|
||||
protected function comment( $comment, $depth, $args ) {
|
||||
if ( 'div' == $args['style'] ) {
|
||||
$tag = 'div';
|
||||
$add_below = 'comment';
|
||||
} else {
|
||||
$tag = 'li';
|
||||
$add_below = 'div-comment';
|
||||
}
|
||||
?>
|
||||
<<?php echo $tag; ?> <?php comment_class( $this->has_children ? 'parent' : '', $comment ); ?> id="comment-<?php comment_ID(); ?>">
|
||||
<?php if ( 'div' != $args['style'] ) : ?>
|
||||
<div id="div-comment-<?php comment_ID(); ?>" class="comment-body">
|
||||
<?php endif; ?>
|
||||
<div class="comment-author vcard">
|
||||
<?php if ( 0 != $args['avatar_size'] ) echo get_avatar( $comment, $args['avatar_size'] ); ?>
|
||||
<?php printf( __( '<cite class="fn">%s</cite> <span class="says">says:</span>' ), get_comment_author_link( $comment ) ); ?>
|
||||
</div>
|
||||
<?php if ( '0' == $comment->comment_approved ) : ?>
|
||||
<em class="comment-awaiting-moderation"><?php _e( 'Your comment is awaiting moderation.' ) ?></em>
|
||||
<br />
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="comment-meta commentmetadata"><a href="<?php echo esc_url( get_comment_link( $comment, $args ) ); ?>">
|
||||
<?php
|
||||
/* translators: 1: comment date, 2: comment time */
|
||||
printf( __( '%1$s at %2$s' ), get_comment_date( '', $comment ), get_comment_time() ); ?></a><?php edit_comment_link( __( '(Edit)' ), ' ', '' );
|
||||
?>
|
||||
</div>
|
||||
|
||||
<?php comment_text( get_comment_id(), array_merge( $args, array( 'add_below' => $add_below, 'depth' => $depth, 'max_depth' => $args['max_depth'] ) ) ); ?>
|
||||
|
||||
<?php
|
||||
comment_reply_link( array_merge( $args, array(
|
||||
'add_below' => $add_below,
|
||||
'depth' => $depth,
|
||||
'max_depth' => $args['max_depth'],
|
||||
'before' => '<div class="reply">',
|
||||
'after' => '</div>'
|
||||
) ) );
|
||||
?>
|
||||
|
||||
<?php if ( 'div' != $args['style'] ) : ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs a comment in the HTML5 format.
|
||||
*
|
||||
* @since 3.6.0
|
||||
* @access protected
|
||||
*
|
||||
* @see wp_list_comments()
|
||||
*
|
||||
* @param WP_Comment $comment Comment to display.
|
||||
* @param int $depth Depth of the current comment.
|
||||
* @param array $args An array of arguments.
|
||||
*/
|
||||
protected function html5_comment( $comment, $depth, $args ) {
|
||||
$tag = ( 'div' === $args['style'] ) ? 'div' : 'li';
|
||||
?>
|
||||
<<?php echo $tag; ?> id="comment-<?php comment_ID(); ?>" <?php comment_class( $this->has_children ? 'parent' : '', $comment ); ?>>
|
||||
<article id="div-comment-<?php comment_ID(); ?>" class="comment-body">
|
||||
<footer class="comment-meta">
|
||||
<div class="comment-author vcard">
|
||||
<?php if ( 0 != $args['avatar_size'] ) echo get_avatar( $comment, $args['avatar_size'] ); ?>
|
||||
<?php printf( __( '%s <span class="says">says:</span>' ), sprintf( '<b class="fn">%s</b>', get_comment_author_link( $comment ) ) ); ?>
|
||||
</div><!-- .comment-author -->
|
||||
|
||||
<div class="comment-metadata">
|
||||
<a href="<?php echo esc_url( get_comment_link( $comment, $args ) ); ?>">
|
||||
<time datetime="<?php comment_time( 'c' ); ?>">
|
||||
<?php
|
||||
/* translators: 1: comment date, 2: comment time */
|
||||
printf( __( '%1$s at %2$s' ), get_comment_date( '', $comment ), get_comment_time() );
|
||||
?>
|
||||
</time>
|
||||
</a>
|
||||
<?php edit_comment_link( __( 'Edit' ), '<span class="edit-link">', '</span>' ); ?>
|
||||
</div><!-- .comment-metadata -->
|
||||
|
||||
<?php if ( '0' == $comment->comment_approved ) : ?>
|
||||
<p class="comment-awaiting-moderation"><?php _e( 'Your comment is awaiting moderation.' ); ?></p>
|
||||
<?php endif; ?>
|
||||
</footer><!-- .comment-meta -->
|
||||
|
||||
<div class="comment-content">
|
||||
<?php comment_text(); ?>
|
||||
</div><!-- .comment-content -->
|
||||
|
||||
<?php
|
||||
comment_reply_link( array_merge( $args, array(
|
||||
'add_below' => 'div-comment',
|
||||
'depth' => $depth,
|
||||
'max_depth' => $args['max_depth'],
|
||||
'before' => '<div class="reply">',
|
||||
'after' => '</div>'
|
||||
) ) );
|
||||
?>
|
||||
</article><!-- .comment-body -->
|
||||
<?php
|
||||
}
|
||||
}
|
||||
90
Kapitel_7/Lektion_4/wordpress/wp-includes/class-walker-page-dropdown.php
Executable file
90
Kapitel_7/Lektion_4/wordpress/wp-includes/class-walker-page-dropdown.php
Executable file
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
/**
|
||||
* Post API: Walker_PageDropdown class
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Post
|
||||
* @since 4.4.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Core class used to create an HTML drop-down list of pages.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @see Walker
|
||||
*/
|
||||
class Walker_PageDropdown extends Walker {
|
||||
|
||||
/**
|
||||
* What the class handles.
|
||||
*
|
||||
* @since 2.1.0
|
||||
* @access public
|
||||
* @var string
|
||||
*
|
||||
* @see Walker::$tree_type
|
||||
*/
|
||||
public $tree_type = 'page';
|
||||
|
||||
/**
|
||||
* Database fields to use.
|
||||
*
|
||||
* @since 2.1.0
|
||||
* @access public
|
||||
* @var array
|
||||
*
|
||||
* @see Walker::$db_fields
|
||||
* @todo Decouple this
|
||||
*/
|
||||
public $db_fields = array( 'parent' => 'post_parent', 'id' => 'ID' );
|
||||
|
||||
/**
|
||||
* Starts the element output.
|
||||
*
|
||||
* @since 2.1.0
|
||||
* @access public
|
||||
*
|
||||
* @see Walker::start_el()
|
||||
*
|
||||
* @param string $output Used to append additional content. Passed by reference.
|
||||
* @param WP_Post $page Page data object.
|
||||
* @param int $depth Optional. Depth of page in reference to parent pages. Used for padding.
|
||||
* Default 0.
|
||||
* @param array $args Optional. Uses 'selected' argument for selected page to set selected HTML
|
||||
* attribute for option element. Uses 'value_field' argument to fill "value"
|
||||
* attribute. See wp_dropdown_pages(). Default empty array.
|
||||
* @param int $id Optional. ID of the current page. Default 0 (unused).
|
||||
*/
|
||||
public function start_el( &$output, $page, $depth = 0, $args = array(), $id = 0 ) {
|
||||
$pad = str_repeat(' ', $depth * 3);
|
||||
|
||||
if ( ! isset( $args['value_field'] ) || ! isset( $page->{$args['value_field']} ) ) {
|
||||
$args['value_field'] = 'ID';
|
||||
}
|
||||
|
||||
$output .= "\t<option class=\"level-$depth\" value=\"" . esc_attr( $page->{$args['value_field']} ) . "\"";
|
||||
if ( $page->ID == $args['selected'] )
|
||||
$output .= ' selected="selected"';
|
||||
$output .= '>';
|
||||
|
||||
$title = $page->post_title;
|
||||
if ( '' === $title ) {
|
||||
/* translators: %d: ID of a post */
|
||||
$title = sprintf( __( '#%d (no title)' ), $page->ID );
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter the page title when creating an HTML drop-down list of pages.
|
||||
*
|
||||
* @since 3.1.0
|
||||
*
|
||||
* @param string $title Page title.
|
||||
* @param object $page Page data object.
|
||||
*/
|
||||
$title = apply_filters( 'list_pages', $title, $page );
|
||||
|
||||
$output .= $pad . esc_html( $title );
|
||||
$output .= "</option>\n";
|
||||
}
|
||||
}
|
||||
181
Kapitel_7/Lektion_4/wordpress/wp-includes/class-walker-page.php
Executable file
181
Kapitel_7/Lektion_4/wordpress/wp-includes/class-walker-page.php
Executable file
@@ -0,0 +1,181 @@
|
||||
<?php
|
||||
/**
|
||||
* Post API: Walker_Page class
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Template
|
||||
* @since 4.4.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Core walker class used to create an HTML list of pages.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @see Walker
|
||||
*/
|
||||
class Walker_Page extends Walker {
|
||||
|
||||
/**
|
||||
* What the class handles.
|
||||
*
|
||||
* @since 2.1.0
|
||||
* @access public
|
||||
* @var string
|
||||
*
|
||||
* @see Walker::$tree_type
|
||||
*/
|
||||
public $tree_type = 'page';
|
||||
|
||||
/**
|
||||
* Database fields to use.
|
||||
*
|
||||
* @since 2.1.0
|
||||
* @access private
|
||||
* @var array
|
||||
*
|
||||
* @see Walker::$db_fields
|
||||
* @todo Decouple this.
|
||||
*/
|
||||
public $db_fields = array( 'parent' => 'post_parent', 'id' => 'ID' );
|
||||
|
||||
/**
|
||||
* Outputs the beginning of the current level in the tree before elements are output.
|
||||
*
|
||||
* @since 2.1.0
|
||||
* @access public
|
||||
*
|
||||
* @see Walker::start_lvl()
|
||||
*
|
||||
* @param string $output Passed by reference. Used to append additional content.
|
||||
* @param int $depth Optional. Depth of page. Used for padding. Default 0.
|
||||
* @param array $args Optional. Arguments for outputing the next level.
|
||||
* Default empty array.
|
||||
*/
|
||||
public function start_lvl( &$output, $depth = 0, $args = array() ) {
|
||||
$indent = str_repeat("\t", $depth);
|
||||
$output .= "\n$indent<ul class='children'>\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs the end of the current level in the tree after elements are output.
|
||||
*
|
||||
* @since 2.1.0
|
||||
* @access public
|
||||
*
|
||||
* @see Walker::end_lvl()
|
||||
*
|
||||
* @param string $output Passed by reference. Used to append additional content.
|
||||
* @param int $depth Optional. Depth of page. Used for padding. Default 0.
|
||||
* @param array $args Optional. Arguments for outputting the end of the current level.
|
||||
* Default empty array.
|
||||
*/
|
||||
public function end_lvl( &$output, $depth = 0, $args = array() ) {
|
||||
$indent = str_repeat("\t", $depth);
|
||||
$output .= "$indent</ul>\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs the beginning of the current element in the tree.
|
||||
*
|
||||
* @see Walker::start_el()
|
||||
* @since 2.1.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $output Used to append additional content. Passed by reference.
|
||||
* @param WP_Post $page Page data object.
|
||||
* @param int $depth Optional. Depth of page. Used for padding. Default 0.
|
||||
* @param array $args Optional. Array of arguments. Default empty array.
|
||||
* @param int $current_page Optional. Page ID. Default 0.
|
||||
*/
|
||||
public function start_el( &$output, $page, $depth = 0, $args = array(), $current_page = 0 ) {
|
||||
if ( $depth ) {
|
||||
$indent = str_repeat( "\t", $depth );
|
||||
} else {
|
||||
$indent = '';
|
||||
}
|
||||
|
||||
$css_class = array( 'page_item', 'page-item-' . $page->ID );
|
||||
|
||||
if ( isset( $args['pages_with_children'][ $page->ID ] ) ) {
|
||||
$css_class[] = 'page_item_has_children';
|
||||
}
|
||||
|
||||
if ( ! empty( $current_page ) ) {
|
||||
$_current_page = get_post( $current_page );
|
||||
if ( $_current_page && in_array( $page->ID, $_current_page->ancestors ) ) {
|
||||
$css_class[] = 'current_page_ancestor';
|
||||
}
|
||||
if ( $page->ID == $current_page ) {
|
||||
$css_class[] = 'current_page_item';
|
||||
} elseif ( $_current_page && $page->ID == $_current_page->post_parent ) {
|
||||
$css_class[] = 'current_page_parent';
|
||||
}
|
||||
} elseif ( $page->ID == get_option('page_for_posts') ) {
|
||||
$css_class[] = 'current_page_parent';
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter the list of CSS classes to include with each page item in the list.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @see wp_list_pages()
|
||||
*
|
||||
* @param array $css_class An array of CSS classes to be applied
|
||||
* to each list item.
|
||||
* @param WP_Post $page Page data object.
|
||||
* @param int $depth Depth of page, used for padding.
|
||||
* @param array $args An array of arguments.
|
||||
* @param int $current_page ID of the current page.
|
||||
*/
|
||||
$css_classes = implode( ' ', apply_filters( 'page_css_class', $css_class, $page, $depth, $args, $current_page ) );
|
||||
|
||||
if ( '' === $page->post_title ) {
|
||||
/* translators: %d: ID of a post */
|
||||
$page->post_title = sprintf( __( '#%d (no title)' ), $page->ID );
|
||||
}
|
||||
|
||||
$args['link_before'] = empty( $args['link_before'] ) ? '' : $args['link_before'];
|
||||
$args['link_after'] = empty( $args['link_after'] ) ? '' : $args['link_after'];
|
||||
|
||||
$output .= $indent . sprintf(
|
||||
'<li class="%s"><a href="%s">%s%s%s</a>',
|
||||
$css_classes,
|
||||
get_permalink( $page->ID ),
|
||||
$args['link_before'],
|
||||
/** This filter is documented in wp-includes/post-template.php */
|
||||
apply_filters( 'the_title', $page->post_title, $page->ID ),
|
||||
$args['link_after']
|
||||
);
|
||||
|
||||
if ( ! empty( $args['show_date'] ) ) {
|
||||
if ( 'modified' == $args['show_date'] ) {
|
||||
$time = $page->post_modified;
|
||||
} else {
|
||||
$time = $page->post_date;
|
||||
}
|
||||
|
||||
$date_format = empty( $args['date_format'] ) ? '' : $args['date_format'];
|
||||
$output .= " " . mysql2date( $date_format, $time );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs the end of the current element in the tree.
|
||||
*
|
||||
* @since 2.1.0
|
||||
* @access public
|
||||
*
|
||||
* @see Walker::end_el()
|
||||
*
|
||||
* @param string $output Used to append additional content. Passed by reference.
|
||||
* @param WP_Post $page Page data object. Not used.
|
||||
* @param int $depth Optional. Depth of page. Default 0 (unused).
|
||||
* @param array $args Optional. Array of arguments. Default empty array.
|
||||
*/
|
||||
public function end_el( &$output, $page, $depth = 0, $args = array() ) {
|
||||
$output .= "</li>\n";
|
||||
}
|
||||
|
||||
}
|
||||
599
Kapitel_7/Lektion_4/wordpress/wp-includes/class-wp-admin-bar.php
Executable file
599
Kapitel_7/Lektion_4/wordpress/wp-includes/class-wp-admin-bar.php
Executable file
@@ -0,0 +1,599 @@
|
||||
<?php
|
||||
/**
|
||||
* Toolbar API: WP_Admin_Bar class
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Toolbar
|
||||
* @since 3.1.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Core class used to implement the Toolbar API.
|
||||
*
|
||||
* @since 3.1.0
|
||||
*/
|
||||
class WP_Admin_Bar {
|
||||
private $nodes = array();
|
||||
private $bound = false;
|
||||
public $user;
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @return string|array|void
|
||||
*/
|
||||
public function __get( $name ) {
|
||||
switch ( $name ) {
|
||||
case 'proto' :
|
||||
return is_ssl() ? 'https://' : 'http://';
|
||||
|
||||
case 'menu' :
|
||||
_deprecated_argument( 'WP_Admin_Bar', '3.3', 'Modify admin bar nodes with WP_Admin_Bar::get_node(), WP_Admin_Bar::add_node(), and WP_Admin_Bar::remove_node(), not the <code>menu</code> property.' );
|
||||
return array(); // Sorry, folks.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @access public
|
||||
*/
|
||||
public function initialize() {
|
||||
$this->user = new stdClass;
|
||||
|
||||
if ( is_user_logged_in() ) {
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
|
||||
add_action( 'wp_head', 'wp_admin_bar_header' );
|
||||
|
||||
add_action( 'admin_head', 'wp_admin_bar_header' );
|
||||
|
||||
if ( current_theme_supports( 'admin-bar' ) ) {
|
||||
/**
|
||||
* To remove the default padding styles from WordPress for the Toolbar, use the following code:
|
||||
* add_theme_support( 'admin-bar', array( 'callback' => '__return_false' ) );
|
||||
*/
|
||||
$admin_bar_args = get_theme_support( 'admin-bar' );
|
||||
$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' );
|
||||
|
||||
/**
|
||||
* Fires after WP_Admin_Bar is initialized.
|
||||
*
|
||||
* @since 3.1.0
|
||||
*/
|
||||
do_action( 'admin_bar_init' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $node
|
||||
*/
|
||||
public function add_menu( $node ) {
|
||||
$this->add_node( $node );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $id
|
||||
*/
|
||||
public function remove_menu( $id ) {
|
||||
$this->remove_node( $id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a node to the menu.
|
||||
*
|
||||
* @since 3.1.0
|
||||
* @since 4.5.0 Added the ability to pass 'lang' and 'dir' meta data.
|
||||
* @access public
|
||||
*
|
||||
* @param array $args {
|
||||
* Arguments for adding a node.
|
||||
*
|
||||
* @type string $id ID of the item.
|
||||
* @type string $title Title of the node.
|
||||
* @type string $parent Optional. ID of the parent node.
|
||||
* @type string $href Optional. Link for the item.
|
||||
* @type bool $group Optional. Whether or not the node is a group. Default false.
|
||||
* @type array $meta Meta data including the following keys: 'html', 'class', 'rel', 'lang', 'dir',
|
||||
* 'onclick', 'target', 'title', 'tabindex'. Default empty.
|
||||
* }
|
||||
*/
|
||||
public function add_node( $args ) {
|
||||
// Shim for old method signature: add_node( $parent_id, $menu_obj, $args )
|
||||
if ( func_num_args() >= 3 && is_string( func_get_arg(0) ) )
|
||||
$args = array_merge( array( 'parent' => func_get_arg(0) ), func_get_arg(2) );
|
||||
|
||||
if ( is_object( $args ) )
|
||||
$args = get_object_vars( $args );
|
||||
|
||||
// Ensure we have a valid title.
|
||||
if ( empty( $args['id'] ) ) {
|
||||
if ( empty( $args['title'] ) )
|
||||
return;
|
||||
|
||||
_doing_it_wrong( __METHOD__, __( 'The menu ID should not be empty.' ), '3.3' );
|
||||
// Deprecated: Generate an ID from the title.
|
||||
$args['id'] = esc_attr( sanitize_title( trim( $args['title'] ) ) );
|
||||
}
|
||||
|
||||
$defaults = array(
|
||||
'id' => false,
|
||||
'title' => false,
|
||||
'parent' => false,
|
||||
'href' => false,
|
||||
'group' => false,
|
||||
'meta' => array(),
|
||||
);
|
||||
|
||||
// If the node already exists, keep any data that isn't provided.
|
||||
if ( $maybe_defaults = $this->get_node( $args['id'] ) )
|
||||
$defaults = get_object_vars( $maybe_defaults );
|
||||
|
||||
// Do the same for 'meta' items.
|
||||
if ( ! empty( $defaults['meta'] ) && ! empty( $args['meta'] ) )
|
||||
$args['meta'] = wp_parse_args( $args['meta'], $defaults['meta'] );
|
||||
|
||||
$args = wp_parse_args( $args, $defaults );
|
||||
|
||||
$back_compat_parents = array(
|
||||
'my-account-with-avatar' => array( 'my-account', '3.3' ),
|
||||
'my-blogs' => array( 'my-sites', '3.3' ),
|
||||
);
|
||||
|
||||
if ( isset( $back_compat_parents[ $args['parent'] ] ) ) {
|
||||
list( $new_parent, $version ) = $back_compat_parents[ $args['parent'] ];
|
||||
_deprecated_argument( __METHOD__, $version, sprintf( 'Use <code>%s</code> as the parent for the <code>%s</code> admin bar node instead of <code>%s</code>.', $new_parent, $args['id'], $args['parent'] ) );
|
||||
$args['parent'] = $new_parent;
|
||||
}
|
||||
|
||||
$this->_set_node( $args );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
final protected function _set_node( $args ) {
|
||||
$this->nodes[ $args['id'] ] = (object) $args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a node.
|
||||
*
|
||||
* @param string $id
|
||||
* @return object Node.
|
||||
*/
|
||||
final public function get_node( $id ) {
|
||||
if ( $node = $this->_get_node( $id ) )
|
||||
return clone $node;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $id
|
||||
* @return object|void
|
||||
*/
|
||||
final protected function _get_node( $id ) {
|
||||
if ( $this->bound )
|
||||
return;
|
||||
|
||||
if ( empty( $id ) )
|
||||
$id = 'root';
|
||||
|
||||
if ( isset( $this->nodes[ $id ] ) )
|
||||
return $this->nodes[ $id ];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array|void
|
||||
*/
|
||||
final public function get_nodes() {
|
||||
if ( ! $nodes = $this->_get_nodes() )
|
||||
return;
|
||||
|
||||
foreach ( $nodes as &$node ) {
|
||||
$node = clone $node;
|
||||
}
|
||||
return $nodes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array|void
|
||||
*/
|
||||
final protected function _get_nodes() {
|
||||
if ( $this->bound )
|
||||
return;
|
||||
|
||||
return $this->nodes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a group to a menu node.
|
||||
*
|
||||
* @since 3.3.0
|
||||
*
|
||||
* @param array $args {
|
||||
* Array of arguments for adding a group.
|
||||
*
|
||||
* @type string $id ID of the item.
|
||||
* @type string $parent Optional. ID of the parent node. Default 'root'.
|
||||
* @type array $meta Meta data for the group including the following keys:
|
||||
* 'class', 'onclick', 'target', and 'title'.
|
||||
* }
|
||||
*/
|
||||
final public function add_group( $args ) {
|
||||
$args['group'] = true;
|
||||
|
||||
$this->add_node( $args );
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a node.
|
||||
*
|
||||
* @param string $id The ID of the item.
|
||||
*/
|
||||
public function remove_node( $id ) {
|
||||
$this->_unset_node( $id );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $id
|
||||
*/
|
||||
final protected function _unset_node( $id ) {
|
||||
unset( $this->nodes[ $id ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* @access public
|
||||
*/
|
||||
public function render() {
|
||||
$root = $this->_bind();
|
||||
if ( $root )
|
||||
$this->_render( $root );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return object|void
|
||||
*/
|
||||
final protected function _bind() {
|
||||
if ( $this->bound )
|
||||
return;
|
||||
|
||||
// Add the root node.
|
||||
// Clear it first, just in case. Don't mess with The Root.
|
||||
$this->remove_node( 'root' );
|
||||
$this->add_node( array(
|
||||
'id' => 'root',
|
||||
'group' => false,
|
||||
) );
|
||||
|
||||
// Normalize nodes: define internal 'children' and 'type' properties.
|
||||
foreach ( $this->_get_nodes() as $node ) {
|
||||
$node->children = array();
|
||||
$node->type = ( $node->group ) ? 'group' : 'item';
|
||||
unset( $node->group );
|
||||
|
||||
// The Root wants your orphans. No lonely items allowed.
|
||||
if ( ! $node->parent )
|
||||
$node->parent = 'root';
|
||||
}
|
||||
|
||||
foreach ( $this->_get_nodes() as $node ) {
|
||||
if ( 'root' == $node->id )
|
||||
continue;
|
||||
|
||||
// Fetch the parent node. If it isn't registered, ignore the node.
|
||||
if ( ! $parent = $this->_get_node( $node->parent ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Generate the group class (we distinguish between top level and other level groups).
|
||||
$group_class = ( $node->parent == 'root' ) ? 'ab-top-menu' : 'ab-submenu';
|
||||
|
||||
if ( $node->type == 'group' ) {
|
||||
if ( empty( $node->meta['class'] ) )
|
||||
$node->meta['class'] = $group_class;
|
||||
else
|
||||
$node->meta['class'] .= ' ' . $group_class;
|
||||
}
|
||||
|
||||
// Items in items aren't allowed. Wrap nested items in 'default' groups.
|
||||
if ( $parent->type == 'item' && $node->type == 'item' ) {
|
||||
$default_id = $parent->id . '-default';
|
||||
$default = $this->_get_node( $default_id );
|
||||
|
||||
// The default group is added here to allow groups that are
|
||||
// added before standard menu items to render first.
|
||||
if ( ! $default ) {
|
||||
// Use _set_node because add_node can be overloaded.
|
||||
// Make sure to specify default settings for all properties.
|
||||
$this->_set_node( array(
|
||||
'id' => $default_id,
|
||||
'parent' => $parent->id,
|
||||
'type' => 'group',
|
||||
'children' => array(),
|
||||
'meta' => array(
|
||||
'class' => $group_class,
|
||||
),
|
||||
'title' => false,
|
||||
'href' => false,
|
||||
) );
|
||||
$default = $this->_get_node( $default_id );
|
||||
$parent->children[] = $default;
|
||||
}
|
||||
$parent = $default;
|
||||
|
||||
// Groups in groups aren't allowed. Add a special 'container' node.
|
||||
// The container will invisibly wrap both groups.
|
||||
} elseif ( $parent->type == 'group' && $node->type == 'group' ) {
|
||||
$container_id = $parent->id . '-container';
|
||||
$container = $this->_get_node( $container_id );
|
||||
|
||||
// We need to create a container for this group, life is sad.
|
||||
if ( ! $container ) {
|
||||
// Use _set_node because add_node can be overloaded.
|
||||
// Make sure to specify default settings for all properties.
|
||||
$this->_set_node( array(
|
||||
'id' => $container_id,
|
||||
'type' => 'container',
|
||||
'children' => array( $parent ),
|
||||
'parent' => false,
|
||||
'title' => false,
|
||||
'href' => false,
|
||||
'meta' => array(),
|
||||
) );
|
||||
|
||||
$container = $this->_get_node( $container_id );
|
||||
|
||||
// Link the container node if a grandparent node exists.
|
||||
$grandparent = $this->_get_node( $parent->parent );
|
||||
|
||||
if ( $grandparent ) {
|
||||
$container->parent = $grandparent->id;
|
||||
|
||||
$index = array_search( $parent, $grandparent->children, true );
|
||||
if ( $index === false )
|
||||
$grandparent->children[] = $container;
|
||||
else
|
||||
array_splice( $grandparent->children, $index, 1, array( $container ) );
|
||||
}
|
||||
|
||||
$parent->parent = $container->id;
|
||||
}
|
||||
|
||||
$parent = $container;
|
||||
}
|
||||
|
||||
// Update the parent ID (it might have changed).
|
||||
$node->parent = $parent->id;
|
||||
|
||||
// Add the node to the tree.
|
||||
$parent->children[] = $node;
|
||||
}
|
||||
|
||||
$root = $this->_get_node( 'root' );
|
||||
$this->bound = true;
|
||||
return $root;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @global bool $is_IE
|
||||
* @param object $root
|
||||
*/
|
||||
final protected function _render( $root ) {
|
||||
global $is_IE;
|
||||
|
||||
// Add browser classes.
|
||||
// We have to do this here since admin bar shows on the front end.
|
||||
$class = 'nojq nojs';
|
||||
if ( $is_IE ) {
|
||||
if ( strpos( $_SERVER['HTTP_USER_AGENT'], 'MSIE 7' ) )
|
||||
$class .= ' ie7';
|
||||
elseif ( strpos( $_SERVER['HTTP_USER_AGENT'], 'MSIE 8' ) )
|
||||
$class .= ' ie8';
|
||||
elseif ( strpos( $_SERVER['HTTP_USER_AGENT'], 'MSIE 9' ) )
|
||||
$class .= ' ie9';
|
||||
} elseif ( wp_is_mobile() ) {
|
||||
$class .= ' mobile';
|
||||
}
|
||||
|
||||
?>
|
||||
<div id="wpadminbar" class="<?php echo $class; ?>">
|
||||
<?php if ( ! is_admin() ) { ?>
|
||||
<a class="screen-reader-shortcut" href="#wp-toolbar" tabindex="1"><?php _e( 'Skip to toolbar' ); ?></a>
|
||||
<?php } ?>
|
||||
<div class="quicklinks" id="wp-toolbar" role="navigation" aria-label="<?php esc_attr_e( 'Toolbar' ); ?>" tabindex="0">
|
||||
<?php foreach ( $root->children as $group ) {
|
||||
$this->_render_group( $group );
|
||||
} ?>
|
||||
</div>
|
||||
<?php if ( is_user_logged_in() ) : ?>
|
||||
<a class="screen-reader-shortcut" href="<?php echo esc_url( wp_logout_url() ); ?>"><?php _e('Log Out'); ?></a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* @param object $node
|
||||
*/
|
||||
final protected function _render_container( $node ) {
|
||||
if ( $node->type != 'container' || empty( $node->children ) )
|
||||
return;
|
||||
|
||||
?><div id="<?php echo esc_attr( 'wp-admin-bar-' . $node->id ); ?>" class="ab-group-container"><?php
|
||||
foreach ( $node->children as $group ) {
|
||||
$this->_render_group( $group );
|
||||
}
|
||||
?></div><?php
|
||||
}
|
||||
|
||||
/**
|
||||
* @param object $node
|
||||
*/
|
||||
final protected function _render_group( $node ) {
|
||||
if ( $node->type == 'container' ) {
|
||||
$this->_render_container( $node );
|
||||
return;
|
||||
}
|
||||
if ( $node->type != 'group' || empty( $node->children ) )
|
||||
return;
|
||||
|
||||
if ( ! empty( $node->meta['class'] ) )
|
||||
$class = ' class="' . esc_attr( trim( $node->meta['class'] ) ) . '"';
|
||||
else
|
||||
$class = '';
|
||||
|
||||
?><ul id="<?php echo esc_attr( 'wp-admin-bar-' . $node->id ); ?>"<?php echo $class; ?>><?php
|
||||
foreach ( $node->children as $item ) {
|
||||
$this->_render_item( $item );
|
||||
}
|
||||
?></ul><?php
|
||||
}
|
||||
|
||||
/**
|
||||
* @param object $node
|
||||
*/
|
||||
final protected function _render_item( $node ) {
|
||||
if ( $node->type != 'item' )
|
||||
return;
|
||||
|
||||
$is_parent = ! empty( $node->children );
|
||||
$has_link = ! empty( $node->href );
|
||||
|
||||
$tabindex = isset( $node->meta['tabindex'] ) ? (int) $node->meta['tabindex'] : '';
|
||||
$aria_attributes = $tabindex ? 'tabindex="' . $tabindex . '"' : '';
|
||||
|
||||
$menuclass = '';
|
||||
|
||||
if ( $is_parent ) {
|
||||
$menuclass = 'menupop ';
|
||||
$aria_attributes .= ' aria-haspopup="true"';
|
||||
}
|
||||
|
||||
if ( ! empty( $node->meta['class'] ) )
|
||||
$menuclass .= $node->meta['class'];
|
||||
|
||||
if ( $menuclass )
|
||||
$menuclass = ' class="' . esc_attr( trim( $menuclass ) ) . '"';
|
||||
|
||||
?>
|
||||
|
||||
<li id="<?php echo esc_attr( 'wp-admin-bar-' . $node->id ); ?>"<?php echo $menuclass; ?>><?php
|
||||
if ( $has_link ):
|
||||
?><a class="ab-item" <?php echo $aria_attributes; ?> href="<?php echo esc_url( $node->href ) ?>"<?php
|
||||
if ( ! empty( $node->meta['onclick'] ) ) :
|
||||
?> onclick="<?php echo esc_js( $node->meta['onclick'] ); ?>"<?php
|
||||
endif;
|
||||
if ( ! empty( $node->meta['target'] ) ) :
|
||||
?> target="<?php echo esc_attr( $node->meta['target'] ); ?>"<?php
|
||||
endif;
|
||||
if ( ! empty( $node->meta['title'] ) ) :
|
||||
?> title="<?php echo esc_attr( $node->meta['title'] ); ?>"<?php
|
||||
endif;
|
||||
if ( ! empty( $node->meta['rel'] ) ) :
|
||||
?> rel="<?php echo esc_attr( $node->meta['rel'] ); ?>"<?php
|
||||
endif;
|
||||
if ( ! empty( $node->meta['lang'] ) ) :
|
||||
?> lang="<?php echo esc_attr( $node->meta['lang'] ); ?>"<?php
|
||||
endif;
|
||||
if ( ! empty( $node->meta['dir'] ) ) :
|
||||
?> dir="<?php echo esc_attr( $node->meta['dir'] ); ?>"<?php
|
||||
endif;
|
||||
?>><?php
|
||||
else:
|
||||
?><div class="ab-item ab-empty-item" <?php echo $aria_attributes;
|
||||
if ( ! empty( $node->meta['title'] ) ) :
|
||||
?> title="<?php echo esc_attr( $node->meta['title'] ); ?>"<?php
|
||||
endif;
|
||||
if ( ! empty( $node->meta['lang'] ) ) :
|
||||
?> lang="<?php echo esc_attr( $node->meta['lang'] ); ?>"<?php
|
||||
endif;
|
||||
if ( ! empty( $node->meta['dir'] ) ) :
|
||||
?> dir="<?php echo esc_attr( $node->meta['dir'] ); ?>"<?php
|
||||
endif;
|
||||
?>><?php
|
||||
endif;
|
||||
|
||||
echo $node->title;
|
||||
|
||||
if ( $has_link ) :
|
||||
?></a><?php
|
||||
else:
|
||||
?></div><?php
|
||||
endif;
|
||||
|
||||
if ( $is_parent ) :
|
||||
?><div class="ab-sub-wrapper"><?php
|
||||
foreach ( $node->children as $group ) {
|
||||
$this->_render_group( $group );
|
||||
}
|
||||
?></div><?php
|
||||
endif;
|
||||
|
||||
if ( ! empty( $node->meta['html'] ) )
|
||||
echo $node->meta['html'];
|
||||
|
||||
?>
|
||||
</li><?php
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $id Unused.
|
||||
* @param object $node
|
||||
*/
|
||||
public function recursive_render( $id, $node ) {
|
||||
_deprecated_function( __METHOD__, '3.3', 'WP_Admin_bar::render(), WP_Admin_Bar::_render_item()' );
|
||||
$this->_render_item( $node );
|
||||
}
|
||||
|
||||
/**
|
||||
* @access public
|
||||
*/
|
||||
public function add_menus() {
|
||||
// User related, aligned right.
|
||||
add_action( 'admin_bar_menu', 'wp_admin_bar_my_account_menu', 0 );
|
||||
add_action( 'admin_bar_menu', 'wp_admin_bar_search_menu', 4 );
|
||||
add_action( 'admin_bar_menu', 'wp_admin_bar_my_account_item', 7 );
|
||||
|
||||
// Site related.
|
||||
add_action( 'admin_bar_menu', 'wp_admin_bar_sidebar_toggle', 0 );
|
||||
add_action( 'admin_bar_menu', 'wp_admin_bar_wp_menu', 10 );
|
||||
add_action( 'admin_bar_menu', 'wp_admin_bar_my_sites_menu', 20 );
|
||||
add_action( 'admin_bar_menu', 'wp_admin_bar_site_menu', 30 );
|
||||
add_action( 'admin_bar_menu', 'wp_admin_bar_customize_menu', 40 );
|
||||
add_action( 'admin_bar_menu', 'wp_admin_bar_updates_menu', 50 );
|
||||
|
||||
// Content related.
|
||||
if ( ! is_network_admin() && ! is_user_admin() ) {
|
||||
add_action( 'admin_bar_menu', 'wp_admin_bar_comments_menu', 60 );
|
||||
add_action( 'admin_bar_menu', 'wp_admin_bar_new_content_menu', 70 );
|
||||
}
|
||||
add_action( 'admin_bar_menu', 'wp_admin_bar_edit_menu', 80 );
|
||||
|
||||
add_action( 'admin_bar_menu', 'wp_admin_bar_add_secondary_groups', 200 );
|
||||
|
||||
/**
|
||||
* Fires after menus are added to the menu bar.
|
||||
*
|
||||
* @since 3.1.0
|
||||
*/
|
||||
do_action( 'add_admin_bar_menus' );
|
||||
}
|
||||
}
|
||||
157
Kapitel_7/Lektion_4/wordpress/wp-includes/class-wp-ajax-response.php
Executable file
157
Kapitel_7/Lektion_4/wordpress/wp-includes/class-wp-ajax-response.php
Executable file
@@ -0,0 +1,157 @@
|
||||
<?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
|
||||
*/
|
||||
public $responses = array();
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
public function __construct( $args = '' ) {
|
||||
if ( !empty($args) )
|
||||
$this->add($args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends data to an XML response based on given arguments.
|
||||
*
|
||||
* With `$args` defaults, extra data output would be:
|
||||
*
|
||||
* <response action='{$action}_$id'>
|
||||
* <$what id='$id' position='$position'>
|
||||
* <response_data><![CDATA[$data]]></response_data>
|
||||
* </$what>
|
||||
* </response>
|
||||
*
|
||||
* @since 2.1.0
|
||||
* @access public
|
||||
*
|
||||
* @param string|array $args {
|
||||
* Optional. An array or string of XML response arguments.
|
||||
*
|
||||
* @type string $what XML-RPC response type. Used as a child element of `<response>`.
|
||||
* Default 'object' (`<object>`).
|
||||
* @type string|false $action Value to use for the `action` attribute in `<response>`. Will be
|
||||
* appended with `_$id` on output. If false, `$action` will default to
|
||||
* the value of `$_POST['action']`. Default false.
|
||||
* @type int|WP_Error $id The response ID, used as the response type `id` attribute. Also
|
||||
* accepts a `WP_Error` object if the ID does not exist. Default 0.
|
||||
* @type int|false $old_id The previous response ID. Used as the value for the response type
|
||||
* `old_id` attribute. False hides the attribute. Default false.
|
||||
* @type string $position Value of the response type `position` attribute. Accepts 1 (bottom),
|
||||
* -1 (top), html ID (after), or -html ID (before). Default 1 (bottom).
|
||||
* @type string|WP_Error $data The response content/message. Also accepts a WP_Error object if the
|
||||
* ID does not exist. Default empty.
|
||||
* @type array $supplemental An array of extra strings that will be output within a `<supplemental>`
|
||||
* element as CDATA. Default empty array.
|
||||
* }
|
||||
* @return string XML response.
|
||||
*/
|
||||
public 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 );
|
||||
|
||||
$position = preg_replace( '/[^a-z0-9:_-]/i', '', $r['position'] );
|
||||
$id = $r['id'];
|
||||
$what = $r['what'];
|
||||
$action = $r['action'];
|
||||
$old_id = $r['old_id'];
|
||||
$data = $r['data'];
|
||||
|
||||
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( $r['supplemental'] ) ) {
|
||||
foreach ( $r['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
|
||||
*/
|
||||
public function send() {
|
||||
header( 'Content-Type: text/xml; charset=' . get_option( 'blog_charset' ) );
|
||||
echo "<?xml version='1.0' encoding='" . get_option( 'blog_charset' ) . "' standalone='yes'?><wp_ajax>";
|
||||
foreach ( (array) $this->responses as $response )
|
||||
echo $response;
|
||||
echo '</wp_ajax>';
|
||||
if ( defined( 'DOING_AJAX' ) && DOING_AJAX )
|
||||
wp_die();
|
||||
else
|
||||
die();
|
||||
}
|
||||
}
|
||||
1107
Kapitel_7/Lektion_4/wordpress/wp-includes/class-wp-comment-query.php
Executable file
1107
Kapitel_7/Lektion_4/wordpress/wp-includes/class-wp-comment-query.php
Executable file
File diff suppressed because it is too large
Load Diff
395
Kapitel_7/Lektion_4/wordpress/wp-includes/class-wp-comment.php
Executable file
395
Kapitel_7/Lektion_4/wordpress/wp-includes/class-wp-comment.php
Executable file
@@ -0,0 +1,395 @@
|
||||
<?php
|
||||
/**
|
||||
* Comment API: WP_Comment class
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Comments
|
||||
* @since 4.4.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Core class used to organize comments as instantiated objects with defined members.
|
||||
*
|
||||
* @since 4.4.0
|
||||
*/
|
||||
final class WP_Comment {
|
||||
|
||||
/**
|
||||
* Comment ID.
|
||||
*
|
||||
* @since 4.4.0
|
||||
* @access public
|
||||
* @var int
|
||||
*/
|
||||
public $comment_ID;
|
||||
|
||||
/**
|
||||
* ID of the post the comment is associated with.
|
||||
*
|
||||
* @since 4.4.0
|
||||
* @access public
|
||||
* @var int
|
||||
*/
|
||||
public $comment_post_ID = 0;
|
||||
|
||||
/**
|
||||
* Comment author name.
|
||||
*
|
||||
* @since 4.4.0
|
||||
* @access public
|
||||
* @var string
|
||||
*/
|
||||
public $comment_author = '';
|
||||
|
||||
/**
|
||||
* Comment author email address.
|
||||
*
|
||||
* @since 4.4.0
|
||||
* @access public
|
||||
* @var string
|
||||
*/
|
||||
public $comment_author_email = '';
|
||||
|
||||
/**
|
||||
* Comment author URL.
|
||||
*
|
||||
* @since 4.4.0
|
||||
* @access public
|
||||
* @var string
|
||||
*/
|
||||
public $comment_author_url = '';
|
||||
|
||||
/**
|
||||
* Comment author IP address (IPv4 format).
|
||||
*
|
||||
* @since 4.4.0
|
||||
* @access public
|
||||
* @var string
|
||||
*/
|
||||
public $comment_author_IP = '';
|
||||
|
||||
/**
|
||||
* Comment date in YYYY-MM-DD HH:MM:SS format.
|
||||
*
|
||||
* @since 4.4.0
|
||||
* @access public
|
||||
* @var string
|
||||
*/
|
||||
public $comment_date = '0000-00-00 00:00:00';
|
||||
|
||||
/**
|
||||
* Comment GMT date in YYYY-MM-DD HH::MM:SS format.
|
||||
*
|
||||
* @since 4.4.0
|
||||
* @access public
|
||||
* @var string
|
||||
*/
|
||||
public $comment_date_gmt = '0000-00-00 00:00:00';
|
||||
|
||||
/**
|
||||
* Comment content.
|
||||
*
|
||||
* @since 4.4.0
|
||||
* @access public
|
||||
* @var string
|
||||
*/
|
||||
public $comment_content;
|
||||
|
||||
/**
|
||||
* Comment karma count.
|
||||
*
|
||||
* @since 4.4.0
|
||||
* @access public
|
||||
* @var int
|
||||
*/
|
||||
public $comment_karma = 0;
|
||||
|
||||
/**
|
||||
* Comment approval status.
|
||||
*
|
||||
* @since 4.4.0
|
||||
* @access public
|
||||
* @var string
|
||||
*/
|
||||
public $comment_approved = '1';
|
||||
|
||||
/**
|
||||
* Comment author HTTP user agent.
|
||||
*
|
||||
* @since 4.4.0
|
||||
* @access public
|
||||
* @var string
|
||||
*/
|
||||
public $comment_agent = '';
|
||||
|
||||
/**
|
||||
* Comment type.
|
||||
*
|
||||
* @since 4.4.0
|
||||
* @access public
|
||||
* @var string
|
||||
*/
|
||||
public $comment_type = '';
|
||||
|
||||
/**
|
||||
* Parent comment ID.
|
||||
*
|
||||
* @since 4.4.0
|
||||
* @access public
|
||||
* @var int
|
||||
*/
|
||||
public $comment_parent = 0;
|
||||
|
||||
/**
|
||||
* Comment author ID.
|
||||
*
|
||||
* @since 4.4.0
|
||||
* @access public
|
||||
* @var int
|
||||
*/
|
||||
public $user_id = 0;
|
||||
|
||||
/**
|
||||
* Comment children.
|
||||
*
|
||||
* @since 4.4.0
|
||||
* @access protected
|
||||
* @var array
|
||||
*/
|
||||
protected $children;
|
||||
|
||||
/**
|
||||
* Whether children have been populated for this comment object.
|
||||
*
|
||||
* @since 4.4.0
|
||||
* @access protected
|
||||
* @var bool
|
||||
*/
|
||||
protected $populated_children = false;
|
||||
|
||||
/**
|
||||
* Post fields.
|
||||
*
|
||||
* @since 4.4.0
|
||||
* @access protected
|
||||
* @var array
|
||||
*/
|
||||
protected $post_fields = array( 'post_author', 'post_date', 'post_date_gmt', 'post_content', 'post_title', 'post_excerpt', 'post_status', 'comment_status', 'ping_status', 'post_name', 'to_ping', 'pinged', 'post_modified', 'post_modified_gmt', 'post_content_filtered', 'post_parent', 'guid', 'menu_order', 'post_type', 'post_mime_type', 'comment_count' );
|
||||
|
||||
/**
|
||||
* Retrieves a WP_Comment instance.
|
||||
*
|
||||
* @since 4.4.0
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @global wpdb $wpdb WordPress database abstraction object.
|
||||
*
|
||||
* @param int $id Comment ID.
|
||||
* @return WP_Comment|false Comment object, otherwise false.
|
||||
*/
|
||||
public static function get_instance( $id ) {
|
||||
global $wpdb;
|
||||
|
||||
$comment_id = (int) $id;
|
||||
if ( ! $comment_id ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$_comment = wp_cache_get( $comment_id, 'comment' );
|
||||
|
||||
if ( ! $_comment ) {
|
||||
$_comment = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->comments WHERE comment_ID = %d LIMIT 1", $comment_id ) );
|
||||
|
||||
if ( ! $_comment ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
wp_cache_add( $_comment->comment_ID, $_comment, 'comment' );
|
||||
}
|
||||
|
||||
return new WP_Comment( $_comment );
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* Populates properties with object vars.
|
||||
*
|
||||
* @since 4.4.0
|
||||
* @access public
|
||||
*
|
||||
* @param WP_Comment $comment Comment object.
|
||||
*/
|
||||
public function __construct( $comment ) {
|
||||
foreach ( get_object_vars( $comment ) as $key => $value ) {
|
||||
$this->$key = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert object to array.
|
||||
*
|
||||
* @since 4.4.0
|
||||
* @access public
|
||||
*
|
||||
* @return array Object as array.
|
||||
*/
|
||||
public function to_array() {
|
||||
return get_object_vars( $this );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the children of a comment.
|
||||
*
|
||||
* @since 4.4.0
|
||||
* @access public
|
||||
*
|
||||
* @param array $args {
|
||||
* Array of arguments used to pass to get_comments() and determine format.
|
||||
*
|
||||
* @type string $format Return value format. 'tree' for a hierarchical tree, 'flat' for a flattened array.
|
||||
* Default 'tree'.
|
||||
* @type string $status Comment status to limit results by. Accepts 'hold' (`comment_status=0`),
|
||||
* 'approve' (`comment_status=1`), 'all', or a custom comment status.
|
||||
* Default 'all'.
|
||||
* @type string $hierarchical Whether to include comment descendants in the results.
|
||||
* 'threaded' returns a tree, with each comment's children
|
||||
* stored in a `children` property on the `WP_Comment` object.
|
||||
* 'flat' returns a flat array of found comments plus their children.
|
||||
* Pass `false` to leave out descendants.
|
||||
* The parameter is ignored (forced to `false`) when `$fields` is 'ids' or 'counts'.
|
||||
* Accepts 'threaded', 'flat', or false. Default: 'threaded'.
|
||||
* @type string|array $orderby Comment status or array of statuses. To use 'meta_value'
|
||||
* or 'meta_value_num', `$meta_key` must also be defined.
|
||||
* To sort by a specific `$meta_query` clause, use that
|
||||
* clause's array key. Accepts 'comment_agent',
|
||||
* 'comment_approved', 'comment_author',
|
||||
* 'comment_author_email', 'comment_author_IP',
|
||||
* 'comment_author_url', 'comment_content', 'comment_date',
|
||||
* 'comment_date_gmt', 'comment_ID', 'comment_karma',
|
||||
* 'comment_parent', 'comment_post_ID', 'comment_type',
|
||||
* 'user_id', 'comment__in', 'meta_value', 'meta_value_num',
|
||||
* the value of $meta_key, and the array keys of
|
||||
* `$meta_query`. Also accepts false, an empty array, or
|
||||
* 'none' to disable `ORDER BY` clause.
|
||||
* }
|
||||
* @return array Array of `WP_Comment` objects.
|
||||
*/
|
||||
public function get_children( $args = array() ) {
|
||||
$defaults = array(
|
||||
'format' => 'tree',
|
||||
'status' => 'all',
|
||||
'hierarchical' => 'threaded',
|
||||
'orderby' => '',
|
||||
);
|
||||
|
||||
$_args = wp_parse_args( $args, $defaults );
|
||||
$_args['parent'] = $this->comment_ID;
|
||||
|
||||
if ( is_null( $this->children ) ) {
|
||||
if ( $this->populated_children ) {
|
||||
$this->children = array();
|
||||
} else {
|
||||
$this->children = get_comments( $_args );
|
||||
}
|
||||
}
|
||||
|
||||
if ( 'flat' === $_args['format'] ) {
|
||||
$children = array();
|
||||
foreach ( $this->children as $child ) {
|
||||
$child_args = $_args;
|
||||
$child_args['format'] = 'flat';
|
||||
// get_children() resets this value automatically.
|
||||
unset( $child_args['parent'] );
|
||||
|
||||
$children = array_merge( $children, array( $child ), $child->get_children( $child_args ) );
|
||||
}
|
||||
} else {
|
||||
$children = $this->children;
|
||||
}
|
||||
|
||||
return $children;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a child to the comment.
|
||||
*
|
||||
* Used by `WP_Comment_Query` when bulk-filling descendants.
|
||||
*
|
||||
* @since 4.4.0
|
||||
* @access public
|
||||
*
|
||||
* @param WP_Comment $child Child comment.
|
||||
*/
|
||||
public function add_child( WP_Comment $child ) {
|
||||
$this->children[ $child->comment_ID ] = $child;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a child comment by ID.
|
||||
*
|
||||
* @since 4.4.0
|
||||
* @access public
|
||||
*
|
||||
* @param int $child_id ID of the child.
|
||||
* @return WP_Comment|bool Returns the comment object if found, otherwise false.
|
||||
*/
|
||||
public function get_child( $child_id ) {
|
||||
if ( isset( $this->children[ $child_id ] ) ) {
|
||||
return $this->children[ $child_id ];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the 'populated_children' flag.
|
||||
*
|
||||
* This flag is important for ensuring that calling `get_children()` on a childless comment will not trigger
|
||||
* unneeded database queries.
|
||||
*
|
||||
* @since 4.4.0
|
||||
*
|
||||
* @param bool $set Whether the comment's children have already been populated.
|
||||
*/
|
||||
public function populated_children( $set ) {
|
||||
$this->populated_children = (bool) $set;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether a non-public property is set.
|
||||
*
|
||||
* If `$name` matches a post field, the comment post will be loaded and the post's value checked.
|
||||
*
|
||||
* @since 4.4.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $name Property name.
|
||||
* @return bool
|
||||
*/
|
||||
public function __isset( $name ) {
|
||||
if ( in_array( $name, $this->post_fields ) && 0 !== (int) $this->comment_post_ID ) {
|
||||
$post = get_post( $this->comment_post_ID );
|
||||
return property_exists( $post, $name );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic getter.
|
||||
*
|
||||
* If `$name` matches a post field, the comment post will be loaded and the post's value returned.
|
||||
*
|
||||
* @since 4.4.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $name
|
||||
* @return mixed
|
||||
*/
|
||||
public function __get( $name ) {
|
||||
if ( in_array( $name, $this->post_fields ) ) {
|
||||
$post = get_post( $this->comment_post_ID );
|
||||
return $post->$name;
|
||||
}
|
||||
}
|
||||
}
|
||||
651
Kapitel_7/Lektion_4/wordpress/wp-includes/class-wp-customize-control.php
Executable file
651
Kapitel_7/Lektion_4/wordpress/wp-includes/class-wp-customize-control.php
Executable file
@@ -0,0 +1,651 @@
|
||||
<?php
|
||||
/**
|
||||
* WordPress Customize Control classes
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Customize
|
||||
* @since 3.4.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Customize Control class.
|
||||
*
|
||||
* @since 3.4.0
|
||||
*/
|
||||
class WP_Customize_Control {
|
||||
|
||||
/**
|
||||
* Incremented with each new class instantiation, then stored in $instance_number.
|
||||
*
|
||||
* Used when sorting two instances whose priorities are equal.
|
||||
*
|
||||
* @since 4.1.0
|
||||
*
|
||||
* @static
|
||||
* @access protected
|
||||
* @var int
|
||||
*/
|
||||
protected static $instance_count = 0;
|
||||
|
||||
/**
|
||||
* Order in which this instance was created in relation to other instances.
|
||||
*
|
||||
* @since 4.1.0
|
||||
* @access public
|
||||
* @var int
|
||||
*/
|
||||
public $instance_number;
|
||||
|
||||
/**
|
||||
* @access public
|
||||
* @var WP_Customize_Manager
|
||||
*/
|
||||
public $manager;
|
||||
|
||||
/**
|
||||
* @access public
|
||||
* @var string
|
||||
*/
|
||||
public $id;
|
||||
|
||||
/**
|
||||
* All settings tied to the control.
|
||||
*
|
||||
* @access public
|
||||
* @var array
|
||||
*/
|
||||
public $settings;
|
||||
|
||||
/**
|
||||
* The primary setting for the control (if there is one).
|
||||
*
|
||||
* @access public
|
||||
* @var string
|
||||
*/
|
||||
public $setting = 'default';
|
||||
|
||||
/**
|
||||
* Capability required to use this control.
|
||||
*
|
||||
* Normally this is empty and the capability is derived from the capabilities
|
||||
* of the associated `$settings`.
|
||||
*
|
||||
* @since 4.5.0
|
||||
* @access public
|
||||
* @var string
|
||||
*/
|
||||
public $capability;
|
||||
|
||||
/**
|
||||
* @access public
|
||||
* @var int
|
||||
*/
|
||||
public $priority = 10;
|
||||
|
||||
/**
|
||||
* @access public
|
||||
* @var string
|
||||
*/
|
||||
public $section = '';
|
||||
|
||||
/**
|
||||
* @access public
|
||||
* @var string
|
||||
*/
|
||||
public $label = '';
|
||||
|
||||
/**
|
||||
* @access public
|
||||
* @var string
|
||||
*/
|
||||
public $description = '';
|
||||
|
||||
/**
|
||||
* @todo: Remove choices
|
||||
*
|
||||
* @access public
|
||||
* @var array
|
||||
*/
|
||||
public $choices = array();
|
||||
|
||||
/**
|
||||
* @access public
|
||||
* @var array
|
||||
*/
|
||||
public $input_attrs = array();
|
||||
|
||||
/**
|
||||
* @deprecated It is better to just call the json() method
|
||||
* @access public
|
||||
* @var array
|
||||
*/
|
||||
public $json = array();
|
||||
|
||||
/**
|
||||
* @access public
|
||||
* @var string
|
||||
*/
|
||||
public $type = 'text';
|
||||
|
||||
/**
|
||||
* Callback.
|
||||
*
|
||||
* @since 4.0.0
|
||||
* @access public
|
||||
*
|
||||
* @see WP_Customize_Control::active()
|
||||
*
|
||||
* @var callable Callback is called with one argument, the instance of
|
||||
* WP_Customize_Control, and returns bool to indicate whether
|
||||
* the control is active (such as it relates to the URL
|
||||
* currently being previewed).
|
||||
*/
|
||||
public $active_callback = '';
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* Supplied `$args` override class property defaults.
|
||||
*
|
||||
* If `$args['settings']` is not defined, use the $id as the setting ID.
|
||||
*
|
||||
* @since 3.4.0
|
||||
*
|
||||
* @param WP_Customize_Manager $manager Customizer bootstrap instance.
|
||||
* @param string $id Control ID.
|
||||
* @param array $args {
|
||||
* Optional. Arguments to override class property defaults.
|
||||
*
|
||||
* @type int $instance_number Order in which this instance was created in relation
|
||||
* to other instances.
|
||||
* @type WP_Customize_Manager $manager Customizer bootstrap instance.
|
||||
* @type string $id Control ID.
|
||||
* @type array $settings All settings tied to the control. If undefined, `$id` will
|
||||
* be used.
|
||||
* @type string $setting The primary setting for the control (if there is one).
|
||||
* Default 'default'.
|
||||
* @type int $priority Order priority to load the control. Default 10.
|
||||
* @type string $section Section the control belongs to. Default empty.
|
||||
* @type string $label Label for the control. Default empty.
|
||||
* @type string $description Description for the control. Default empty.
|
||||
* @type array $choices List of choices for 'radio' or 'select' type controls, where
|
||||
* values are the keys, and labels are the values.
|
||||
* Default empty array.
|
||||
* @type array $input_attrs List of custom input attributes for control output, where
|
||||
* attribute names are the keys and values are the values. Not
|
||||
* used for 'checkbox', 'radio', 'select', 'textarea', or
|
||||
* 'dropdown-pages' control types. Default empty array.
|
||||
* @type array $json Deprecated. Use {@see WP_Customize_Control->json()} instead.
|
||||
* @type string $type Control type. Core controls include 'text', 'checkbox',
|
||||
* 'textarea', 'radio', 'select', and 'dropdown-pages'. Additional
|
||||
* input types such as 'email', 'url', 'number', 'hidden', and
|
||||
* 'date' are supported implicitly. Default 'text'.
|
||||
* }
|
||||
*/
|
||||
public function __construct( $manager, $id, $args = array() ) {
|
||||
$keys = array_keys( get_object_vars( $this ) );
|
||||
foreach ( $keys as $key ) {
|
||||
if ( isset( $args[ $key ] ) ) {
|
||||
$this->$key = $args[ $key ];
|
||||
}
|
||||
}
|
||||
|
||||
$this->manager = $manager;
|
||||
$this->id = $id;
|
||||
if ( empty( $this->active_callback ) ) {
|
||||
$this->active_callback = array( $this, 'active_callback' );
|
||||
}
|
||||
self::$instance_count += 1;
|
||||
$this->instance_number = self::$instance_count;
|
||||
|
||||
// Process settings.
|
||||
if ( ! isset( $this->settings ) ) {
|
||||
$this->settings = $id;
|
||||
}
|
||||
|
||||
$settings = array();
|
||||
if ( is_array( $this->settings ) ) {
|
||||
foreach ( $this->settings as $key => $setting ) {
|
||||
$settings[ $key ] = $this->manager->get_setting( $setting );
|
||||
}
|
||||
} else if ( is_string( $this->settings ) ) {
|
||||
$this->setting = $this->manager->get_setting( $this->settings );
|
||||
$settings['default'] = $this->setting;
|
||||
}
|
||||
$this->settings = $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue control related scripts/styles.
|
||||
*
|
||||
* @since 3.4.0
|
||||
*/
|
||||
public function enqueue() {}
|
||||
|
||||
/**
|
||||
* Check whether control is active to current Customizer preview.
|
||||
*
|
||||
* @since 4.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return bool Whether the control is active to the current preview.
|
||||
*/
|
||||
final public function active() {
|
||||
$control = $this;
|
||||
$active = call_user_func( $this->active_callback, $this );
|
||||
|
||||
/**
|
||||
* Filter response of WP_Customize_Control::active().
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @param bool $active Whether the Customizer control is active.
|
||||
* @param WP_Customize_Control $control WP_Customize_Control instance.
|
||||
*/
|
||||
$active = apply_filters( 'customize_control_active', $active, $control );
|
||||
|
||||
return $active;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default callback used when invoking WP_Customize_Control::active().
|
||||
*
|
||||
* Subclasses can override this with their specific logic, or they may
|
||||
* provide an 'active_callback' argument to the constructor.
|
||||
*
|
||||
* @since 4.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return true Always true.
|
||||
*/
|
||||
public function active_callback() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch a setting's value.
|
||||
* Grabs the main setting by default.
|
||||
*
|
||||
* @since 3.4.0
|
||||
*
|
||||
* @param string $setting_key
|
||||
* @return mixed The requested setting's value, if the setting exists.
|
||||
*/
|
||||
final public function value( $setting_key = 'default' ) {
|
||||
if ( isset( $this->settings[ $setting_key ] ) ) {
|
||||
return $this->settings[ $setting_key ]->value();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh the parameters passed to the JavaScript via JSON.
|
||||
*
|
||||
* @since 3.4.0
|
||||
*/
|
||||
public function to_json() {
|
||||
$this->json['settings'] = array();
|
||||
foreach ( $this->settings as $key => $setting ) {
|
||||
$this->json['settings'][ $key ] = $setting->id;
|
||||
}
|
||||
|
||||
$this->json['type'] = $this->type;
|
||||
$this->json['priority'] = $this->priority;
|
||||
$this->json['active'] = $this->active();
|
||||
$this->json['section'] = $this->section;
|
||||
$this->json['content'] = $this->get_content();
|
||||
$this->json['label'] = $this->label;
|
||||
$this->json['description'] = $this->description;
|
||||
$this->json['instanceNumber'] = $this->instance_number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the data to export to the client via JSON.
|
||||
*
|
||||
* @since 4.1.0
|
||||
*
|
||||
* @return array Array of parameters passed to the JavaScript.
|
||||
*/
|
||||
public function json() {
|
||||
$this->to_json();
|
||||
return $this->json;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the user can use this control.
|
||||
*
|
||||
* Returns false if the user cannot manipulate one of the associated settings,
|
||||
* or if one of the associated settings does not exist. Also returns false if
|
||||
* the associated section does not exist or if its capability check returns
|
||||
* false.
|
||||
*
|
||||
* @since 3.4.0
|
||||
*
|
||||
* @return bool False if theme doesn't support the control or user doesn't have the required permissions, otherwise true.
|
||||
*/
|
||||
final public function check_capabilities() {
|
||||
if ( ! empty( $this->capability ) && ! current_user_can( $this->capability ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ( $this->settings as $setting ) {
|
||||
if ( ! $setting || ! $setting->check_capabilities() ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
$section = $this->manager->get_section( $this->section );
|
||||
if ( isset( $section ) && ! $section->check_capabilities() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the control's content for insertion into the Customizer pane.
|
||||
*
|
||||
* @since 4.1.0
|
||||
*
|
||||
* @return string Contents of the control.
|
||||
*/
|
||||
final public function get_content() {
|
||||
ob_start();
|
||||
$this->maybe_render();
|
||||
return trim( ob_get_clean() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check capabilities and render the control.
|
||||
*
|
||||
* @since 3.4.0
|
||||
* @uses WP_Customize_Control::render()
|
||||
*/
|
||||
final public function maybe_render() {
|
||||
if ( ! $this->check_capabilities() )
|
||||
return;
|
||||
|
||||
/**
|
||||
* Fires just before the current Customizer control is rendered.
|
||||
*
|
||||
* @since 3.4.0
|
||||
*
|
||||
* @param WP_Customize_Control $this WP_Customize_Control instance.
|
||||
*/
|
||||
do_action( 'customize_render_control', $this );
|
||||
|
||||
/**
|
||||
* Fires just before a specific Customizer control is rendered.
|
||||
*
|
||||
* The dynamic portion of the hook name, `$this->id`, refers to
|
||||
* the control ID.
|
||||
*
|
||||
* @since 3.4.0
|
||||
*
|
||||
* @param WP_Customize_Control $this {@see WP_Customize_Control} instance.
|
||||
*/
|
||||
do_action( 'customize_render_control_' . $this->id, $this );
|
||||
|
||||
$this->render();
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the control wrapper and calls $this->render_content() for the internals.
|
||||
*
|
||||
* @since 3.4.0
|
||||
*/
|
||||
protected function render() {
|
||||
$id = 'customize-control-' . str_replace( array( '[', ']' ), array( '-', '' ), $this->id );
|
||||
$class = 'customize-control customize-control-' . $this->type;
|
||||
|
||||
?><li id="<?php echo esc_attr( $id ); ?>" class="<?php echo esc_attr( $class ); ?>">
|
||||
<?php $this->render_content(); ?>
|
||||
</li><?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the data link attribute for a setting.
|
||||
*
|
||||
* @since 3.4.0
|
||||
*
|
||||
* @param string $setting_key
|
||||
* @return string Data link parameter, if $setting_key is a valid setting, empty string otherwise.
|
||||
*/
|
||||
public function get_link( $setting_key = 'default' ) {
|
||||
if ( ! isset( $this->settings[ $setting_key ] ) )
|
||||
return '';
|
||||
|
||||
return 'data-customize-setting-link="' . esc_attr( $this->settings[ $setting_key ]->id ) . '"';
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the data link attribute for the control's input element.
|
||||
*
|
||||
* @since 3.4.0
|
||||
* @uses WP_Customize_Control::get_link()
|
||||
*
|
||||
* @param string $setting_key
|
||||
*/
|
||||
public function link( $setting_key = 'default' ) {
|
||||
echo $this->get_link( $setting_key );
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the custom attributes for the control's input element.
|
||||
*
|
||||
* @since 4.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function input_attrs() {
|
||||
foreach ( $this->input_attrs as $attr => $value ) {
|
||||
echo $attr . '="' . esc_attr( $value ) . '" ';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the control's content.
|
||||
*
|
||||
* Allows the content to be overriden without having to rewrite the wrapper in $this->render().
|
||||
*
|
||||
* Supports basic input types `text`, `checkbox`, `textarea`, `radio`, `select` and `dropdown-pages`.
|
||||
* Additional input types such as `email`, `url`, `number`, `hidden` and `date` are supported implicitly.
|
||||
*
|
||||
* Control content can alternately be rendered in JS. See {@see WP_Customize_Control::print_template()}.
|
||||
*
|
||||
* @since 3.4.0
|
||||
*/
|
||||
protected function render_content() {
|
||||
switch( $this->type ) {
|
||||
case 'checkbox':
|
||||
?>
|
||||
<label>
|
||||
<input type="checkbox" value="<?php echo esc_attr( $this->value() ); ?>" <?php $this->link(); checked( $this->value() ); ?> />
|
||||
<?php echo esc_html( $this->label ); ?>
|
||||
<?php if ( ! empty( $this->description ) ) : ?>
|
||||
<span class="description customize-control-description"><?php echo $this->description; ?></span>
|
||||
<?php endif; ?>
|
||||
</label>
|
||||
<?php
|
||||
break;
|
||||
case 'radio':
|
||||
if ( empty( $this->choices ) )
|
||||
return;
|
||||
|
||||
$name = '_customize-radio-' . $this->id;
|
||||
|
||||
if ( ! empty( $this->label ) ) : ?>
|
||||
<span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
|
||||
<?php endif;
|
||||
if ( ! empty( $this->description ) ) : ?>
|
||||
<span class="description customize-control-description"><?php echo $this->description ; ?></span>
|
||||
<?php endif;
|
||||
|
||||
foreach ( $this->choices as $value => $label ) :
|
||||
?>
|
||||
<label>
|
||||
<input type="radio" value="<?php echo esc_attr( $value ); ?>" name="<?php echo esc_attr( $name ); ?>" <?php $this->link(); checked( $this->value(), $value ); ?> />
|
||||
<?php echo esc_html( $label ); ?><br/>
|
||||
</label>
|
||||
<?php
|
||||
endforeach;
|
||||
break;
|
||||
case 'select':
|
||||
if ( empty( $this->choices ) )
|
||||
return;
|
||||
|
||||
?>
|
||||
<label>
|
||||
<?php if ( ! empty( $this->label ) ) : ?>
|
||||
<span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
|
||||
<?php endif;
|
||||
if ( ! empty( $this->description ) ) : ?>
|
||||
<span class="description customize-control-description"><?php echo $this->description; ?></span>
|
||||
<?php endif; ?>
|
||||
|
||||
<select <?php $this->link(); ?>>
|
||||
<?php
|
||||
foreach ( $this->choices as $value => $label )
|
||||
echo '<option value="' . esc_attr( $value ) . '"' . selected( $this->value(), $value, false ) . '>' . $label . '</option>';
|
||||
?>
|
||||
</select>
|
||||
</label>
|
||||
<?php
|
||||
break;
|
||||
case 'textarea':
|
||||
?>
|
||||
<label>
|
||||
<?php if ( ! empty( $this->label ) ) : ?>
|
||||
<span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
|
||||
<?php endif;
|
||||
if ( ! empty( $this->description ) ) : ?>
|
||||
<span class="description customize-control-description"><?php echo $this->description; ?></span>
|
||||
<?php endif; ?>
|
||||
<textarea rows="5" <?php $this->link(); ?>><?php echo esc_textarea( $this->value() ); ?></textarea>
|
||||
</label>
|
||||
<?php
|
||||
break;
|
||||
case 'dropdown-pages':
|
||||
?>
|
||||
<label>
|
||||
<?php if ( ! empty( $this->label ) ) : ?>
|
||||
<span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
|
||||
<?php endif;
|
||||
if ( ! empty( $this->description ) ) : ?>
|
||||
<span class="description customize-control-description"><?php echo $this->description; ?></span>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php $dropdown = wp_dropdown_pages(
|
||||
array(
|
||||
'name' => '_customize-dropdown-pages-' . $this->id,
|
||||
'echo' => 0,
|
||||
'show_option_none' => __( '— Select —' ),
|
||||
'option_none_value' => '0',
|
||||
'selected' => $this->value(),
|
||||
)
|
||||
);
|
||||
|
||||
// Hackily add in the data link parameter.
|
||||
$dropdown = str_replace( '<select', '<select ' . $this->get_link(), $dropdown );
|
||||
echo $dropdown;
|
||||
?>
|
||||
</label>
|
||||
<?php
|
||||
break;
|
||||
default:
|
||||
?>
|
||||
<label>
|
||||
<?php if ( ! empty( $this->label ) ) : ?>
|
||||
<span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
|
||||
<?php endif;
|
||||
if ( ! empty( $this->description ) ) : ?>
|
||||
<span class="description customize-control-description"><?php echo $this->description; ?></span>
|
||||
<?php endif; ?>
|
||||
<input type="<?php echo esc_attr( $this->type ); ?>" <?php $this->input_attrs(); ?> value="<?php echo esc_attr( $this->value() ); ?>" <?php $this->link(); ?> />
|
||||
</label>
|
||||
<?php
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the control's JS template.
|
||||
*
|
||||
* This function is only run for control types that have been registered with
|
||||
* {@see WP_Customize_Manager::register_control_type()}.
|
||||
*
|
||||
* In the future, this will also print the template for the control's container
|
||||
* element and be override-able.
|
||||
*
|
||||
* @since 4.1.0
|
||||
*/
|
||||
final public function print_template() {
|
||||
?>
|
||||
<script type="text/html" id="tmpl-customize-control-<?php echo $this->type; ?>-content">
|
||||
<?php $this->content_template(); ?>
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* An Underscore (JS) template for this control's content (but not its container).
|
||||
*
|
||||
* Class variables for this control class are available in the `data` JS object;
|
||||
* export custom variables by overriding {@see WP_Customize_Control::to_json()}.
|
||||
*
|
||||
* @see WP_Customize_Control::print_template()
|
||||
*
|
||||
* @since 4.1.0
|
||||
*/
|
||||
protected function content_template() {}
|
||||
|
||||
}
|
||||
|
||||
/** WP_Customize_Color_Control class */
|
||||
require_once( ABSPATH . WPINC . '/customize/class-wp-customize-color-control.php' );
|
||||
|
||||
/** WP_Customize_Media_Control class */
|
||||
require_once( ABSPATH . WPINC . '/customize/class-wp-customize-media-control.php' );
|
||||
|
||||
/** WP_Customize_Upload_Control class */
|
||||
require_once( ABSPATH . WPINC . '/customize/class-wp-customize-upload-control.php' );
|
||||
|
||||
/** WP_Customize_Image_Control class */
|
||||
require_once( ABSPATH . WPINC . '/customize/class-wp-customize-image-control.php' );
|
||||
|
||||
/** WP_Customize_Background_Image_Control class */
|
||||
require_once( ABSPATH . WPINC . '/customize/class-wp-customize-background-image-control.php' );
|
||||
|
||||
/** WP_Customize_Cropped_Image_Control class */
|
||||
require_once( ABSPATH . WPINC . '/customize/class-wp-customize-cropped-image-control.php' );
|
||||
|
||||
/** WP_Customize_Site_Icon_Control class */
|
||||
require_once( ABSPATH . WPINC . '/customize/class-wp-customize-site-icon-control.php' );
|
||||
|
||||
/** WP_Customize_Header_Image_Control class */
|
||||
require_once( ABSPATH . WPINC . '/customize/class-wp-customize-header-image-control.php' );
|
||||
|
||||
/** WP_Customize_Theme_Control class */
|
||||
require_once( ABSPATH . WPINC . '/customize/class-wp-customize-theme-control.php' );
|
||||
|
||||
/** WP_Widget_Area_Customize_Control class */
|
||||
require_once( ABSPATH . WPINC . '/customize/class-wp-widget-area-customize-control.php' );
|
||||
|
||||
/** WP_Widget_Form_Customize_Control class */
|
||||
require_once( ABSPATH . WPINC . '/customize/class-wp-widget-form-customize-control.php' );
|
||||
|
||||
/** WP_Customize_Nav_Menu_Control class */
|
||||
require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-control.php' );
|
||||
|
||||
/** WP_Customize_Nav_Menu_Item_Control class */
|
||||
require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-item-control.php' );
|
||||
|
||||
/** WP_Customize_Nav_Menu_Location_Control class */
|
||||
require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-location-control.php' );
|
||||
|
||||
/** WP_Customize_Nav_Menu_Name_Control class */
|
||||
require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-name-control.php' );
|
||||
|
||||
/** WP_Customize_Nav_Menu_Auto_Add_Control class */
|
||||
require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-auto-add-control.php' );
|
||||
|
||||
/** WP_Customize_New_Menu_Control class */
|
||||
require_once( ABSPATH . WPINC . '/customize/class-wp-customize-new-menu-control.php' );
|
||||
2301
Kapitel_7/Lektion_4/wordpress/wp-includes/class-wp-customize-manager.php
Executable file
2301
Kapitel_7/Lektion_4/wordpress/wp-includes/class-wp-customize-manager.php
Executable file
File diff suppressed because it is too large
Load Diff
1059
Kapitel_7/Lektion_4/wordpress/wp-includes/class-wp-customize-nav-menus.php
Executable file
1059
Kapitel_7/Lektion_4/wordpress/wp-includes/class-wp-customize-nav-menus.php
Executable file
File diff suppressed because it is too large
Load Diff
389
Kapitel_7/Lektion_4/wordpress/wp-includes/class-wp-customize-panel.php
Executable file
389
Kapitel_7/Lektion_4/wordpress/wp-includes/class-wp-customize-panel.php
Executable file
@@ -0,0 +1,389 @@
|
||||
<?php
|
||||
/**
|
||||
* WordPress Customize Panel classes
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Customize
|
||||
* @since 4.0.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Customize Panel class.
|
||||
*
|
||||
* A UI container for sections, managed by the WP_Customize_Manager.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @see WP_Customize_Manager
|
||||
*/
|
||||
class WP_Customize_Panel {
|
||||
|
||||
/**
|
||||
* Incremented with each new class instantiation, then stored in $instance_number.
|
||||
*
|
||||
* Used when sorting two instances whose priorities are equal.
|
||||
*
|
||||
* @since 4.1.0
|
||||
*
|
||||
* @static
|
||||
* @access protected
|
||||
* @var int
|
||||
*/
|
||||
protected static $instance_count = 0;
|
||||
|
||||
/**
|
||||
* Order in which this instance was created in relation to other instances.
|
||||
*
|
||||
* @since 4.1.0
|
||||
* @access public
|
||||
* @var int
|
||||
*/
|
||||
public $instance_number;
|
||||
|
||||
/**
|
||||
* WP_Customize_Manager instance.
|
||||
*
|
||||
* @since 4.0.0
|
||||
* @access public
|
||||
* @var WP_Customize_Manager
|
||||
*/
|
||||
public $manager;
|
||||
|
||||
/**
|
||||
* Unique identifier.
|
||||
*
|
||||
* @since 4.0.0
|
||||
* @access public
|
||||
* @var string
|
||||
*/
|
||||
public $id;
|
||||
|
||||
/**
|
||||
* Priority of the panel, defining the display order of panels and sections.
|
||||
*
|
||||
* @since 4.0.0
|
||||
* @access public
|
||||
* @var integer
|
||||
*/
|
||||
public $priority = 160;
|
||||
|
||||
/**
|
||||
* Capability required for the panel.
|
||||
*
|
||||
* @since 4.0.0
|
||||
* @access public
|
||||
* @var string
|
||||
*/
|
||||
public $capability = 'edit_theme_options';
|
||||
|
||||
/**
|
||||
* Theme feature support for the panel.
|
||||
*
|
||||
* @since 4.0.0
|
||||
* @access public
|
||||
* @var string|array
|
||||
*/
|
||||
public $theme_supports = '';
|
||||
|
||||
/**
|
||||
* Title of the panel to show in UI.
|
||||
*
|
||||
* @since 4.0.0
|
||||
* @access public
|
||||
* @var string
|
||||
*/
|
||||
public $title = '';
|
||||
|
||||
/**
|
||||
* Description to show in the UI.
|
||||
*
|
||||
* @since 4.0.0
|
||||
* @access public
|
||||
* @var string
|
||||
*/
|
||||
public $description = '';
|
||||
|
||||
/**
|
||||
* Customizer sections for this panel.
|
||||
*
|
||||
* @since 4.0.0
|
||||
* @access public
|
||||
* @var array
|
||||
*/
|
||||
public $sections;
|
||||
|
||||
/**
|
||||
* Type of this panel.
|
||||
*
|
||||
* @since 4.1.0
|
||||
* @access public
|
||||
* @var string
|
||||
*/
|
||||
public $type = 'default';
|
||||
|
||||
/**
|
||||
* Active callback.
|
||||
*
|
||||
* @since 4.1.0
|
||||
* @access public
|
||||
*
|
||||
* @see WP_Customize_Section::active()
|
||||
*
|
||||
* @var callable Callback is called with one argument, the instance of
|
||||
* {@see WP_Customize_Section}, and returns bool to indicate
|
||||
* whether the section is active (such as it relates to the URL
|
||||
* currently being previewed).
|
||||
*/
|
||||
public $active_callback = '';
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* Any supplied $args override class property defaults.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @param WP_Customize_Manager $manager Customizer bootstrap instance.
|
||||
* @param string $id An specific ID for the panel.
|
||||
* @param array $args Panel arguments.
|
||||
*/
|
||||
public function __construct( $manager, $id, $args = array() ) {
|
||||
$keys = array_keys( get_object_vars( $this ) );
|
||||
foreach ( $keys as $key ) {
|
||||
if ( isset( $args[ $key ] ) ) {
|
||||
$this->$key = $args[ $key ];
|
||||
}
|
||||
}
|
||||
|
||||
$this->manager = $manager;
|
||||
$this->id = $id;
|
||||
if ( empty( $this->active_callback ) ) {
|
||||
$this->active_callback = array( $this, 'active_callback' );
|
||||
}
|
||||
self::$instance_count += 1;
|
||||
$this->instance_number = self::$instance_count;
|
||||
|
||||
$this->sections = array(); // Users cannot customize the $sections array.
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether panel is active to current Customizer preview.
|
||||
*
|
||||
* @since 4.1.0
|
||||
* @access public
|
||||
*
|
||||
* @return bool Whether the panel is active to the current preview.
|
||||
*/
|
||||
final public function active() {
|
||||
$panel = $this;
|
||||
$active = call_user_func( $this->active_callback, $this );
|
||||
|
||||
/**
|
||||
* Filter response of WP_Customize_Panel::active().
|
||||
*
|
||||
* @since 4.1.0
|
||||
*
|
||||
* @param bool $active Whether the Customizer panel is active.
|
||||
* @param WP_Customize_Panel $panel {@see WP_Customize_Panel} instance.
|
||||
*/
|
||||
$active = apply_filters( 'customize_panel_active', $active, $panel );
|
||||
|
||||
return $active;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default callback used when invoking {@see WP_Customize_Panel::active()}.
|
||||
*
|
||||
* Subclasses can override this with their specific logic, or they may
|
||||
* provide an 'active_callback' argument to the constructor.
|
||||
*
|
||||
* @since 4.1.0
|
||||
* @access public
|
||||
*
|
||||
* @return bool Always true.
|
||||
*/
|
||||
public function active_callback() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gather the parameters passed to client JavaScript via JSON.
|
||||
*
|
||||
* @since 4.1.0
|
||||
*
|
||||
* @return array The array to be exported to the client as JSON.
|
||||
*/
|
||||
public function json() {
|
||||
$array = wp_array_slice_assoc( (array) $this, array( 'id', 'description', 'priority', 'type' ) );
|
||||
$array['title'] = html_entity_decode( $this->title, ENT_QUOTES, get_bloginfo( 'charset' ) );
|
||||
$array['content'] = $this->get_content();
|
||||
$array['active'] = $this->active();
|
||||
$array['instanceNumber'] = $this->instance_number;
|
||||
return $array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks required user capabilities and whether the theme has the
|
||||
* feature support required by the panel.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @return bool False if theme doesn't support the panel or the user doesn't have the capability.
|
||||
*/
|
||||
final public function check_capabilities() {
|
||||
if ( $this->capability && ! call_user_func_array( 'current_user_can', (array) $this->capability ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( $this->theme_supports && ! call_user_func_array( 'current_theme_supports', (array) $this->theme_supports ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the panel's content template for insertion into the Customizer pane.
|
||||
*
|
||||
* @since 4.1.0
|
||||
*
|
||||
* @return string Content for the panel.
|
||||
*/
|
||||
final public function get_content() {
|
||||
ob_start();
|
||||
$this->maybe_render();
|
||||
return trim( ob_get_clean() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check capabilities and render the panel.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
final public function maybe_render() {
|
||||
if ( ! $this->check_capabilities() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires before rendering a Customizer panel.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @param WP_Customize_Panel $this WP_Customize_Panel instance.
|
||||
*/
|
||||
do_action( 'customize_render_panel', $this );
|
||||
|
||||
/**
|
||||
* Fires before rendering a specific Customizer panel.
|
||||
*
|
||||
* The dynamic portion of the hook name, `$this->id`, refers to
|
||||
* the ID of the specific Customizer panel to be rendered.
|
||||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
do_action( "customize_render_panel_{$this->id}" );
|
||||
|
||||
$this->render();
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the panel container, and then its contents (via `this->render_content()`) in a subclass.
|
||||
*
|
||||
* Panel containers are now rendered in JS by default, see {@see WP_Customize_Panel::print_template()}.
|
||||
*
|
||||
* @since 4.0.0
|
||||
* @access protected
|
||||
*/
|
||||
protected function render() {}
|
||||
|
||||
/**
|
||||
* Render the panel UI in a subclass.
|
||||
*
|
||||
* Panel contents are now rendered in JS by default, see {@see WP_Customize_Panel::print_template()}.
|
||||
*
|
||||
* @since 4.1.0
|
||||
* @access protected
|
||||
*/
|
||||
protected function render_content() {}
|
||||
|
||||
/**
|
||||
* Render the panel's JS templates.
|
||||
*
|
||||
* This function is only run for panel types that have been registered with
|
||||
* WP_Customize_Manager::register_panel_type().
|
||||
*
|
||||
* @since 4.3.0
|
||||
*
|
||||
* @see WP_Customize_Manager::register_panel_type()
|
||||
*/
|
||||
public function print_template() {
|
||||
?>
|
||||
<script type="text/html" id="tmpl-customize-panel-<?php echo esc_attr( $this->type ); ?>-content">
|
||||
<?php $this->content_template(); ?>
|
||||
</script>
|
||||
<script type="text/html" id="tmpl-customize-panel-<?php echo esc_attr( $this->type ); ?>">
|
||||
<?php $this->render_template(); ?>
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* An Underscore (JS) template for rendering this panel's container.
|
||||
*
|
||||
* Class variables for this panel class are available in the `data` JS object;
|
||||
* export custom variables by overriding WP_Customize_Panel::json().
|
||||
*
|
||||
* @see WP_Customize_Panel::print_template()
|
||||
*
|
||||
* @since 4.3.0
|
||||
* @access protected
|
||||
*/
|
||||
protected function render_template() {
|
||||
?>
|
||||
<li id="accordion-panel-{{ data.id }}" class="accordion-section control-section control-panel control-panel-{{ data.type }}">
|
||||
<h3 class="accordion-section-title" tabindex="0">
|
||||
{{ data.title }}
|
||||
<span class="screen-reader-text"><?php _e( 'Press return or enter to open this panel' ); ?></span>
|
||||
</h3>
|
||||
<ul class="accordion-sub-container control-panel-content"></ul>
|
||||
</li>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* An Underscore (JS) template for this panel's content (but not its container).
|
||||
*
|
||||
* Class variables for this panel class are available in the `data` JS object;
|
||||
* export custom variables by overriding WP_Customize_Panel::json().
|
||||
*
|
||||
* @see WP_Customize_Panel::print_template()
|
||||
*
|
||||
* @since 4.3.0
|
||||
* @access protected
|
||||
*/
|
||||
protected function content_template() {
|
||||
?>
|
||||
<li class="panel-meta customize-info accordion-section <# if ( ! data.description ) { #> cannot-expand<# } #>">
|
||||
<button class="customize-panel-back" tabindex="-1"><span class="screen-reader-text"><?php _e( 'Back' ); ?></span></button>
|
||||
<div class="accordion-section-title">
|
||||
<span class="preview-notice"><?php
|
||||
/* translators: %s: the site/panel title in the Customizer */
|
||||
echo sprintf( __( 'You are customizing %s' ), '<strong class="panel-title">{{ data.title }}</strong>' );
|
||||
?></span>
|
||||
<# if ( data.description ) { #>
|
||||
<button class="customize-help-toggle dashicons dashicons-editor-help" tabindex="0" aria-expanded="false"><span class="screen-reader-text"><?php _e( 'Help' ); ?></span></button>
|
||||
<# } #>
|
||||
</div>
|
||||
<# if ( data.description ) { #>
|
||||
<div class="description customize-panel-description">
|
||||
{{{ data.description }}}
|
||||
</div>
|
||||
<# } #>
|
||||
</li>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
|
||||
/** WP_Customize_Nav_Menus_Panel class */
|
||||
require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menus-panel.php' );
|
||||
387
Kapitel_7/Lektion_4/wordpress/wp-includes/class-wp-customize-section.php
Executable file
387
Kapitel_7/Lektion_4/wordpress/wp-includes/class-wp-customize-section.php
Executable file
@@ -0,0 +1,387 @@
|
||||
<?php
|
||||
/**
|
||||
* WordPress Customize Section classes
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Customize
|
||||
* @since 3.4.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Customize Section class.
|
||||
*
|
||||
* A UI container for controls, managed by the WP_Customize_Manager class.
|
||||
*
|
||||
* @since 3.4.0
|
||||
*
|
||||
* @see WP_Customize_Manager
|
||||
*/
|
||||
class WP_Customize_Section {
|
||||
|
||||
/**
|
||||
* Incremented with each new class instantiation, then stored in $instance_number.
|
||||
*
|
||||
* Used when sorting two instances whose priorities are equal.
|
||||
*
|
||||
* @since 4.1.0
|
||||
*
|
||||
* @static
|
||||
* @access protected
|
||||
* @var int
|
||||
*/
|
||||
protected static $instance_count = 0;
|
||||
|
||||
/**
|
||||
* Order in which this instance was created in relation to other instances.
|
||||
*
|
||||
* @since 4.1.0
|
||||
* @access public
|
||||
* @var int
|
||||
*/
|
||||
public $instance_number;
|
||||
|
||||
/**
|
||||
* WP_Customize_Manager instance.
|
||||
*
|
||||
* @since 3.4.0
|
||||
* @access public
|
||||
* @var WP_Customize_Manager
|
||||
*/
|
||||
public $manager;
|
||||
|
||||
/**
|
||||
* Unique identifier.
|
||||
*
|
||||
* @since 3.4.0
|
||||
* @access public
|
||||
* @var string
|
||||
*/
|
||||
public $id;
|
||||
|
||||
/**
|
||||
* Priority of the section which informs load order of sections.
|
||||
*
|
||||
* @since 3.4.0
|
||||
* @access public
|
||||
* @var integer
|
||||
*/
|
||||
public $priority = 160;
|
||||
|
||||
/**
|
||||
* Panel in which to show the section, making it a sub-section.
|
||||
*
|
||||
* @since 4.0.0
|
||||
* @access public
|
||||
* @var string
|
||||
*/
|
||||
public $panel = '';
|
||||
|
||||
/**
|
||||
* Capability required for the section.
|
||||
*
|
||||
* @since 3.4.0
|
||||
* @access public
|
||||
* @var string
|
||||
*/
|
||||
public $capability = 'edit_theme_options';
|
||||
|
||||
/**
|
||||
* Theme feature support for the section.
|
||||
*
|
||||
* @since 3.4.0
|
||||
* @access public
|
||||
* @var string|array
|
||||
*/
|
||||
public $theme_supports = '';
|
||||
|
||||
/**
|
||||
* Title of the section to show in UI.
|
||||
*
|
||||
* @since 3.4.0
|
||||
* @access public
|
||||
* @var string
|
||||
*/
|
||||
public $title = '';
|
||||
|
||||
/**
|
||||
* Description to show in the UI.
|
||||
*
|
||||
* @since 3.4.0
|
||||
* @access public
|
||||
* @var string
|
||||
*/
|
||||
public $description = '';
|
||||
|
||||
/**
|
||||
* Customizer controls for this section.
|
||||
*
|
||||
* @since 3.4.0
|
||||
* @access public
|
||||
* @var array
|
||||
*/
|
||||
public $controls;
|
||||
|
||||
/**
|
||||
* Type of this section.
|
||||
*
|
||||
* @since 4.1.0
|
||||
* @access public
|
||||
* @var string
|
||||
*/
|
||||
public $type = 'default';
|
||||
|
||||
/**
|
||||
* Active callback.
|
||||
*
|
||||
* @since 4.1.0
|
||||
* @access public
|
||||
*
|
||||
* @see WP_Customize_Section::active()
|
||||
*
|
||||
* @var callable Callback is called with one argument, the instance of
|
||||
* {@see WP_Customize_Section}, and returns bool to indicate
|
||||
* whether the section is active (such as it relates to the URL
|
||||
* currently being previewed).
|
||||
*/
|
||||
public $active_callback = '';
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* Any supplied $args override class property defaults.
|
||||
*
|
||||
* @since 3.4.0
|
||||
*
|
||||
* @param WP_Customize_Manager $manager Customizer bootstrap instance.
|
||||
* @param string $id An specific ID of the section.
|
||||
* @param array $args Section arguments.
|
||||
*/
|
||||
public function __construct( $manager, $id, $args = array() ) {
|
||||
$keys = array_keys( get_object_vars( $this ) );
|
||||
foreach ( $keys as $key ) {
|
||||
if ( isset( $args[ $key ] ) ) {
|
||||
$this->$key = $args[ $key ];
|
||||
}
|
||||
}
|
||||
|
||||
$this->manager = $manager;
|
||||
$this->id = $id;
|
||||
if ( empty( $this->active_callback ) ) {
|
||||
$this->active_callback = array( $this, 'active_callback' );
|
||||
}
|
||||
self::$instance_count += 1;
|
||||
$this->instance_number = self::$instance_count;
|
||||
|
||||
$this->controls = array(); // Users cannot customize the $controls array.
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether section is active to current Customizer preview.
|
||||
*
|
||||
* @since 4.1.0
|
||||
* @access public
|
||||
*
|
||||
* @return bool Whether the section is active to the current preview.
|
||||
*/
|
||||
final public function active() {
|
||||
$section = $this;
|
||||
$active = call_user_func( $this->active_callback, $this );
|
||||
|
||||
/**
|
||||
* Filter response of {@see WP_Customize_Section::active()}.
|
||||
*
|
||||
* @since 4.1.0
|
||||
*
|
||||
* @param bool $active Whether the Customizer section is active.
|
||||
* @param WP_Customize_Section $section {@see WP_Customize_Section} instance.
|
||||
*/
|
||||
$active = apply_filters( 'customize_section_active', $active, $section );
|
||||
|
||||
return $active;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default callback used when invoking {@see WP_Customize_Section::active()}.
|
||||
*
|
||||
* Subclasses can override this with their specific logic, or they may provide
|
||||
* an 'active_callback' argument to the constructor.
|
||||
*
|
||||
* @since 4.1.0
|
||||
* @access public
|
||||
*
|
||||
* @return true Always true.
|
||||
*/
|
||||
public function active_callback() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gather the parameters passed to client JavaScript via JSON.
|
||||
*
|
||||
* @since 4.1.0
|
||||
*
|
||||
* @return array The array to be exported to the client as JSON.
|
||||
*/
|
||||
public function json() {
|
||||
$array = wp_array_slice_assoc( (array) $this, array( 'id', 'description', 'priority', 'panel', 'type' ) );
|
||||
$array['title'] = html_entity_decode( $this->title, ENT_QUOTES, get_bloginfo( 'charset' ) );
|
||||
$array['content'] = $this->get_content();
|
||||
$array['active'] = $this->active();
|
||||
$array['instanceNumber'] = $this->instance_number;
|
||||
|
||||
if ( $this->panel ) {
|
||||
/* translators: ▸ is the unicode right-pointing triangle, and %s is the section title in the Customizer */
|
||||
$array['customizeAction'] = sprintf( __( 'Customizing ▸ %s' ), esc_html( $this->manager->get_panel( $this->panel )->title ) );
|
||||
} else {
|
||||
$array['customizeAction'] = __( 'Customizing' );
|
||||
}
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks required user capabilities and whether the theme has the
|
||||
* feature support required by the section.
|
||||
*
|
||||
* @since 3.4.0
|
||||
*
|
||||
* @return bool False if theme doesn't support the section or user doesn't have the capability.
|
||||
*/
|
||||
final public function check_capabilities() {
|
||||
if ( $this->capability && ! call_user_func_array( 'current_user_can', (array) $this->capability ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( $this->theme_supports && ! call_user_func_array( 'current_theme_supports', (array) $this->theme_supports ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the section's content for insertion into the Customizer pane.
|
||||
*
|
||||
* @since 4.1.0
|
||||
*
|
||||
* @return string Contents of the section.
|
||||
*/
|
||||
final public function get_content() {
|
||||
ob_start();
|
||||
$this->maybe_render();
|
||||
return trim( ob_get_clean() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check capabilities and render the section.
|
||||
*
|
||||
* @since 3.4.0
|
||||
*/
|
||||
final public function maybe_render() {
|
||||
if ( ! $this->check_capabilities() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires before rendering a Customizer section.
|
||||
*
|
||||
* @since 3.4.0
|
||||
*
|
||||
* @param WP_Customize_Section $this WP_Customize_Section instance.
|
||||
*/
|
||||
do_action( 'customize_render_section', $this );
|
||||
/**
|
||||
* Fires before rendering a specific Customizer section.
|
||||
*
|
||||
* The dynamic portion of the hook name, `$this->id`, refers to the ID
|
||||
* of the specific Customizer section to be rendered.
|
||||
*
|
||||
* @since 3.4.0
|
||||
*/
|
||||
do_action( "customize_render_section_{$this->id}" );
|
||||
|
||||
$this->render();
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the section UI in a subclass.
|
||||
*
|
||||
* Sections are now rendered in JS by default, see {@see WP_Customize_Section::print_template()}.
|
||||
*
|
||||
* @since 3.4.0
|
||||
*/
|
||||
protected function render() {}
|
||||
|
||||
/**
|
||||
* Render the section's JS template.
|
||||
*
|
||||
* This function is only run for section types that have been registered with
|
||||
* WP_Customize_Manager::register_section_type().
|
||||
*
|
||||
* @since 4.3.0
|
||||
* @access public
|
||||
*
|
||||
* @see WP_Customize_Manager::render_template()
|
||||
*/
|
||||
public function print_template() {
|
||||
?>
|
||||
<script type="text/html" id="tmpl-customize-section-<?php echo $this->type; ?>">
|
||||
<?php $this->render_template(); ?>
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* An Underscore (JS) template for rendering this section.
|
||||
*
|
||||
* Class variables for this section class are available in the `data` JS object;
|
||||
* export custom variables by overriding WP_Customize_Section::json().
|
||||
*
|
||||
* @since 4.3.0
|
||||
* @access protected
|
||||
*
|
||||
* @see WP_Customize_Section::print_template()
|
||||
*/
|
||||
protected function render_template() {
|
||||
?>
|
||||
<li id="accordion-section-{{ data.id }}" class="accordion-section control-section control-section-{{ data.type }}">
|
||||
<h3 class="accordion-section-title" tabindex="0">
|
||||
{{ data.title }}
|
||||
<span class="screen-reader-text"><?php _e( 'Press return or enter to open this section' ); ?></span>
|
||||
</h3>
|
||||
<ul class="accordion-section-content">
|
||||
<li class="customize-section-description-container">
|
||||
<div class="customize-section-title">
|
||||
<button class="customize-section-back" tabindex="-1">
|
||||
<span class="screen-reader-text"><?php _e( 'Back' ); ?></span>
|
||||
</button>
|
||||
<h3>
|
||||
<span class="customize-action">
|
||||
{{{ data.customizeAction }}}
|
||||
</span>
|
||||
{{ data.title }}
|
||||
</h3>
|
||||
</div>
|
||||
<# if ( data.description ) { #>
|
||||
<div class="description customize-section-description">
|
||||
{{{ data.description }}}
|
||||
</div>
|
||||
<# } #>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
|
||||
/** WP_Customize_Themes_Section class */
|
||||
require_once( ABSPATH . WPINC . '/customize/class-wp-customize-themes-section.php' );
|
||||
|
||||
/** WP_Customize_Sidebar_Section class */
|
||||
require_once( ABSPATH . WPINC . '/customize/class-wp-customize-sidebar-section.php' );
|
||||
|
||||
/** WP_Customize_Nav_Menu_Section class */
|
||||
require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-section.php' );
|
||||
|
||||
/** WP_Customize_New_Menu_Section class */
|
||||
require_once( ABSPATH . WPINC . '/customize/class-wp-customize-new-menu-section.php' );
|
||||
837
Kapitel_7/Lektion_4/wordpress/wp-includes/class-wp-customize-setting.php
Executable file
837
Kapitel_7/Lektion_4/wordpress/wp-includes/class-wp-customize-setting.php
Executable file
@@ -0,0 +1,837 @@
|
||||
<?php
|
||||
/**
|
||||
* WordPress Customize Setting classes
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Customize
|
||||
* @since 3.4.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Customize Setting class.
|
||||
*
|
||||
* Handles saving and sanitizing of settings.
|
||||
*
|
||||
* @since 3.4.0
|
||||
*
|
||||
* @see WP_Customize_Manager
|
||||
*/
|
||||
class WP_Customize_Setting {
|
||||
/**
|
||||
* @access public
|
||||
* @var WP_Customize_Manager
|
||||
*/
|
||||
public $manager;
|
||||
|
||||
/**
|
||||
* Unique string identifier for the setting.
|
||||
*
|
||||
* @access public
|
||||
* @var string
|
||||
*/
|
||||
public $id;
|
||||
|
||||
/**
|
||||
* @access public
|
||||
* @var string
|
||||
*/
|
||||
public $type = 'theme_mod';
|
||||
|
||||
/**
|
||||
* Capability required to edit this setting.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $capability = 'edit_theme_options';
|
||||
|
||||
/**
|
||||
* Feature a theme is required to support to enable this setting.
|
||||
*
|
||||
* @access public
|
||||
* @var string
|
||||
*/
|
||||
public $theme_supports = '';
|
||||
public $default = '';
|
||||
public $transport = 'refresh';
|
||||
|
||||
/**
|
||||
* Server-side sanitization callback for the setting's value.
|
||||
*
|
||||
* @var callback
|
||||
*/
|
||||
public $sanitize_callback = '';
|
||||
public $sanitize_js_callback = '';
|
||||
|
||||
/**
|
||||
* Whether or not the setting is initially dirty when created.
|
||||
*
|
||||
* This is used to ensure that a setting will be sent from the pane to the
|
||||
* preview when loading the Customizer. Normally a setting only is synced to
|
||||
* the preview if it has been changed. This allows the setting to be sent
|
||||
* from the start.
|
||||
*
|
||||
* @since 4.2.0
|
||||
* @access public
|
||||
* @var bool
|
||||
*/
|
||||
public $dirty = false;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $id_data = array();
|
||||
|
||||
/**
|
||||
* Whether or not preview() was called.
|
||||
*
|
||||
* @since 4.4.0
|
||||
* @access protected
|
||||
* @var bool
|
||||
*/
|
||||
protected $is_previewed = false;
|
||||
|
||||
/**
|
||||
* Cache of multidimensional values to improve performance.
|
||||
*
|
||||
* @since 4.4.0
|
||||
* @access protected
|
||||
* @var array
|
||||
* @static
|
||||
*/
|
||||
protected static $aggregated_multidimensionals = array();
|
||||
|
||||
/**
|
||||
* Whether the multidimensional setting is aggregated.
|
||||
*
|
||||
* @since 4.4.0
|
||||
* @access protected
|
||||
* @var bool
|
||||
*/
|
||||
protected $is_multidimensional_aggregated = false;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* Any supplied $args override class property defaults.
|
||||
*
|
||||
* @since 3.4.0
|
||||
*
|
||||
* @param WP_Customize_Manager $manager
|
||||
* @param string $id An specific ID of the setting. Can be a
|
||||
* theme mod or option name.
|
||||
* @param array $args Setting arguments.
|
||||
*/
|
||||
public function __construct( $manager, $id, $args = array() ) {
|
||||
$keys = array_keys( get_object_vars( $this ) );
|
||||
foreach ( $keys as $key ) {
|
||||
if ( isset( $args[ $key ] ) ) {
|
||||
$this->$key = $args[ $key ];
|
||||
}
|
||||
}
|
||||
|
||||
$this->manager = $manager;
|
||||
$this->id = $id;
|
||||
|
||||
// Parse the ID for array keys.
|
||||
$this->id_data['keys'] = preg_split( '/\[/', str_replace( ']', '', $this->id ) );
|
||||
$this->id_data['base'] = array_shift( $this->id_data['keys'] );
|
||||
|
||||
// Rebuild the ID.
|
||||
$this->id = $this->id_data[ 'base' ];
|
||||
if ( ! empty( $this->id_data[ 'keys' ] ) ) {
|
||||
$this->id .= '[' . implode( '][', $this->id_data['keys'] ) . ']';
|
||||
}
|
||||
|
||||
if ( $this->sanitize_callback ) {
|
||||
add_filter( "customize_sanitize_{$this->id}", $this->sanitize_callback, 10, 2 );
|
||||
}
|
||||
if ( $this->sanitize_js_callback ) {
|
||||
add_filter( "customize_sanitize_js_{$this->id}", $this->sanitize_js_callback, 10, 2 );
|
||||
}
|
||||
|
||||
if ( 'option' === $this->type || 'theme_mod' === $this->type ) {
|
||||
// Other setting types can opt-in to aggregate multidimensional explicitly.
|
||||
$this->aggregate_multidimensional();
|
||||
|
||||
// Allow option settings to indicate whether they should be autoloaded.
|
||||
if ( 'option' === $this->type && isset( $args['autoload'] ) ) {
|
||||
self::$aggregated_multidimensionals[ $this->type ][ $this->id_data['base'] ]['autoload'] = $args['autoload'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get parsed ID data for multidimensional setting.
|
||||
*
|
||||
* @since 4.4.0
|
||||
* @access public
|
||||
*
|
||||
* @return array {
|
||||
* ID data for multidimensional setting.
|
||||
*
|
||||
* @type string $base ID base
|
||||
* @type array $keys Keys for multidimensional array.
|
||||
* }
|
||||
*/
|
||||
final public function id_data() {
|
||||
return $this->id_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up the setting for aggregated multidimensional values.
|
||||
*
|
||||
* When a multidimensional setting gets aggregated, all of its preview and update
|
||||
* calls get combined into one call, greatly improving performance.
|
||||
*
|
||||
* @since 4.4.0
|
||||
* @access protected
|
||||
*/
|
||||
protected function aggregate_multidimensional() {
|
||||
$id_base = $this->id_data['base'];
|
||||
if ( ! isset( self::$aggregated_multidimensionals[ $this->type ] ) ) {
|
||||
self::$aggregated_multidimensionals[ $this->type ] = array();
|
||||
}
|
||||
if ( ! isset( self::$aggregated_multidimensionals[ $this->type ][ $id_base ] ) ) {
|
||||
self::$aggregated_multidimensionals[ $this->type ][ $id_base ] = array(
|
||||
'previewed_instances' => array(), // Calling preview() will add the $setting to the array.
|
||||
'preview_applied_instances' => array(), // Flags for which settings have had their values applied.
|
||||
'root_value' => $this->get_root_value( array() ), // Root value for initial state, manipulated by preview and update calls.
|
||||
);
|
||||
}
|
||||
|
||||
if ( ! empty( $this->id_data['keys'] ) ) {
|
||||
// Note the preview-applied flag is cleared at priority 9 to ensure it is cleared before a deferred-preview runs.
|
||||
add_action( "customize_post_value_set_{$this->id}", array( $this, '_clear_aggregated_multidimensional_preview_applied_flag' ), 9 );
|
||||
$this->is_multidimensional_aggregated = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset `$aggregated_multidimensionals` static variable.
|
||||
*
|
||||
* This is intended only for use by unit tests.
|
||||
*
|
||||
* @since 4.5.0
|
||||
* @access public
|
||||
* @ignore
|
||||
*/
|
||||
static public function reset_aggregated_multidimensionals() {
|
||||
self::$aggregated_multidimensionals = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* The ID for the current site when the preview() method was called.
|
||||
*
|
||||
* @since 4.2.0
|
||||
* @access protected
|
||||
* @var int
|
||||
*/
|
||||
protected $_previewed_blog_id;
|
||||
|
||||
/**
|
||||
* Return true if the current site is not the same as the previewed site.
|
||||
*
|
||||
* @since 4.2.0
|
||||
* @access public
|
||||
*
|
||||
* @return bool If preview() has been called.
|
||||
*/
|
||||
public function is_current_blog_previewed() {
|
||||
if ( ! isset( $this->_previewed_blog_id ) ) {
|
||||
return false;
|
||||
}
|
||||
return ( get_current_blog_id() === $this->_previewed_blog_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Original non-previewed value stored by the preview method.
|
||||
*
|
||||
* @see WP_Customize_Setting::preview()
|
||||
* @since 4.1.1
|
||||
* @var mixed
|
||||
*/
|
||||
protected $_original_value;
|
||||
|
||||
/**
|
||||
* Add filters to supply the setting's value when accessed.
|
||||
*
|
||||
* If the setting already has a pre-existing value and there is no incoming
|
||||
* post value for the setting, then this method will short-circuit since
|
||||
* there is no change to preview.
|
||||
*
|
||||
* @since 3.4.0
|
||||
* @since 4.4.0 Added boolean return value.
|
||||
* @access public
|
||||
*
|
||||
* @return bool False when preview short-circuits due no change needing to be previewed.
|
||||
*/
|
||||
public function preview() {
|
||||
if ( ! isset( $this->_previewed_blog_id ) ) {
|
||||
$this->_previewed_blog_id = get_current_blog_id();
|
||||
}
|
||||
|
||||
// Prevent re-previewing an already-previewed setting.
|
||||
if ( $this->is_previewed ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$id_base = $this->id_data['base'];
|
||||
$is_multidimensional = ! empty( $this->id_data['keys'] );
|
||||
$multidimensional_filter = array( $this, '_multidimensional_preview_filter' );
|
||||
|
||||
/*
|
||||
* Check if the setting has a pre-existing value (an isset check),
|
||||
* and if doesn't have any incoming post value. If both checks are true,
|
||||
* then the preview short-circuits because there is nothing that needs
|
||||
* to be previewed.
|
||||
*/
|
||||
$undefined = new stdClass();
|
||||
$needs_preview = ( $undefined !== $this->post_value( $undefined ) );
|
||||
$value = null;
|
||||
|
||||
// Since no post value was defined, check if we have an initial value set.
|
||||
if ( ! $needs_preview ) {
|
||||
if ( $this->is_multidimensional_aggregated ) {
|
||||
$root = self::$aggregated_multidimensionals[ $this->type ][ $id_base ]['root_value'];
|
||||
$value = $this->multidimensional_get( $root, $this->id_data['keys'], $undefined );
|
||||
} else {
|
||||
$default = $this->default;
|
||||
$this->default = $undefined; // Temporarily set default to undefined so we can detect if existing value is set.
|
||||
$value = $this->value();
|
||||
$this->default = $default;
|
||||
}
|
||||
$needs_preview = ( $undefined === $value ); // Because the default needs to be supplied.
|
||||
}
|
||||
|
||||
// If the setting does not need previewing now, defer to when it has a value to preview.
|
||||
if ( ! $needs_preview ) {
|
||||
if ( ! has_action( "customize_post_value_set_{$this->id}", array( $this, 'preview' ) ) ) {
|
||||
add_action( "customize_post_value_set_{$this->id}", array( $this, 'preview' ) );
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
switch ( $this->type ) {
|
||||
case 'theme_mod' :
|
||||
if ( ! $is_multidimensional ) {
|
||||
add_filter( "theme_mod_{$id_base}", array( $this, '_preview_filter' ) );
|
||||
} else {
|
||||
if ( empty( self::$aggregated_multidimensionals[ $this->type ][ $id_base ]['previewed_instances'] ) ) {
|
||||
// Only add this filter once for this ID base.
|
||||
add_filter( "theme_mod_{$id_base}", $multidimensional_filter );
|
||||
}
|
||||
self::$aggregated_multidimensionals[ $this->type ][ $id_base ]['previewed_instances'][ $this->id ] = $this;
|
||||
}
|
||||
break;
|
||||
case 'option' :
|
||||
if ( ! $is_multidimensional ) {
|
||||
add_filter( "pre_option_{$id_base}", array( $this, '_preview_filter' ) );
|
||||
} else {
|
||||
if ( empty( self::$aggregated_multidimensionals[ $this->type ][ $id_base ]['previewed_instances'] ) ) {
|
||||
// Only add these filters once for this ID base.
|
||||
add_filter( "option_{$id_base}", $multidimensional_filter );
|
||||
add_filter( "default_option_{$id_base}", $multidimensional_filter );
|
||||
}
|
||||
self::$aggregated_multidimensionals[ $this->type ][ $id_base ]['previewed_instances'][ $this->id ] = $this;
|
||||
}
|
||||
break;
|
||||
default :
|
||||
|
||||
/**
|
||||
* Fires when the {@see WP_Customize_Setting::preview()} method is called for settings
|
||||
* not handled as theme_mods or options.
|
||||
*
|
||||
* The dynamic portion of the hook name, `$this->id`, refers to the setting ID.
|
||||
*
|
||||
* @since 3.4.0
|
||||
*
|
||||
* @param WP_Customize_Setting $this {@see WP_Customize_Setting} instance.
|
||||
*/
|
||||
do_action( "customize_preview_{$this->id}", $this );
|
||||
|
||||
/**
|
||||
* Fires when the {@see WP_Customize_Setting::preview()} method is called for settings
|
||||
* not handled as theme_mods or options.
|
||||
*
|
||||
* The dynamic portion of the hook name, `$this->type`, refers to the setting type.
|
||||
*
|
||||
* @since 4.1.0
|
||||
*
|
||||
* @param WP_Customize_Setting $this {@see WP_Customize_Setting} instance.
|
||||
*/
|
||||
do_action( "customize_preview_{$this->type}", $this );
|
||||
}
|
||||
|
||||
$this->is_previewed = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear out the previewed-applied flag for a multidimensional-aggregated value whenever its post value is updated.
|
||||
*
|
||||
* This ensures that the new value will get sanitized and used the next time
|
||||
* that `WP_Customize_Setting::_multidimensional_preview_filter()`
|
||||
* is called for this setting.
|
||||
*
|
||||
* @since 4.4.0
|
||||
* @access private
|
||||
* @see WP_Customize_Manager::set_post_value()
|
||||
* @see WP_Customize_Setting::_multidimensional_preview_filter()
|
||||
*/
|
||||
final public function _clear_aggregated_multidimensional_preview_applied_flag() {
|
||||
unset( self::$aggregated_multidimensionals[ $this->type ][ $this->id_data['base'] ]['preview_applied_instances'][ $this->id ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback function to filter non-multidimensional theme mods and options.
|
||||
*
|
||||
* If switch_to_blog() was called after the preview() method, and the current
|
||||
* site is now not the same site, then this method does a no-op and returns
|
||||
* the original value.
|
||||
*
|
||||
* @since 3.4.0
|
||||
*
|
||||
* @param mixed $original Old value.
|
||||
* @return mixed New or old value.
|
||||
*/
|
||||
public function _preview_filter( $original ) {
|
||||
if ( ! $this->is_current_blog_previewed() ) {
|
||||
return $original;
|
||||
}
|
||||
|
||||
$undefined = new stdClass(); // Symbol hack.
|
||||
$post_value = $this->post_value( $undefined );
|
||||
if ( $undefined !== $post_value ) {
|
||||
$value = $post_value;
|
||||
} else {
|
||||
/*
|
||||
* Note that we don't use $original here because preview() will
|
||||
* not add the filter in the first place if it has an initial value
|
||||
* and there is no post value.
|
||||
*/
|
||||
$value = $this->default;
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback function to filter multidimensional theme mods and options.
|
||||
*
|
||||
* For all multidimensional settings of a given type, the preview filter for
|
||||
* the first setting previewed will be used to apply the values for the others.
|
||||
*
|
||||
* @since 4.4.0
|
||||
* @access private
|
||||
*
|
||||
* @see WP_Customize_Setting::$aggregated_multidimensionals
|
||||
* @param mixed $original Original root value.
|
||||
* @return mixed New or old value.
|
||||
*/
|
||||
final public function _multidimensional_preview_filter( $original ) {
|
||||
if ( ! $this->is_current_blog_previewed() ) {
|
||||
return $original;
|
||||
}
|
||||
|
||||
$id_base = $this->id_data['base'];
|
||||
|
||||
// If no settings have been previewed yet (which should not be the case, since $this is), just pass through the original value.
|
||||
if ( empty( self::$aggregated_multidimensionals[ $this->type ][ $id_base ]['previewed_instances'] ) ) {
|
||||
return $original;
|
||||
}
|
||||
|
||||
foreach ( self::$aggregated_multidimensionals[ $this->type ][ $id_base ]['previewed_instances'] as $previewed_setting ) {
|
||||
// Skip applying previewed value for any settings that have already been applied.
|
||||
if ( ! empty( self::$aggregated_multidimensionals[ $this->type ][ $id_base ]['preview_applied_instances'][ $previewed_setting->id ] ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Do the replacements of the posted/default sub value into the root value.
|
||||
$value = $previewed_setting->post_value( $previewed_setting->default );
|
||||
$root = self::$aggregated_multidimensionals[ $previewed_setting->type ][ $id_base ]['root_value'];
|
||||
$root = $previewed_setting->multidimensional_replace( $root, $previewed_setting->id_data['keys'], $value );
|
||||
self::$aggregated_multidimensionals[ $previewed_setting->type ][ $id_base ]['root_value'] = $root;
|
||||
|
||||
// Mark this setting having been applied so that it will be skipped when the filter is called again.
|
||||
self::$aggregated_multidimensionals[ $previewed_setting->type ][ $id_base ]['preview_applied_instances'][ $previewed_setting->id ] = true;
|
||||
}
|
||||
|
||||
return self::$aggregated_multidimensionals[ $this->type ][ $id_base ]['root_value'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Check user capabilities and theme supports, and then save
|
||||
* the value of the setting.
|
||||
*
|
||||
* @since 3.4.0
|
||||
*
|
||||
* @return false|void False if cap check fails or value isn't set.
|
||||
*/
|
||||
final public function save() {
|
||||
$value = $this->post_value();
|
||||
|
||||
if ( ! $this->check_capabilities() || ! isset( $value ) )
|
||||
return false;
|
||||
|
||||
/**
|
||||
* Fires when the WP_Customize_Setting::save() method is called.
|
||||
*
|
||||
* The dynamic portion of the hook name, `$this->id_data['base']` refers to
|
||||
* the base slug of the setting name.
|
||||
*
|
||||
* @since 3.4.0
|
||||
*
|
||||
* @param WP_Customize_Setting $this {@see WP_Customize_Setting} instance.
|
||||
*/
|
||||
do_action( 'customize_save_' . $this->id_data[ 'base' ], $this );
|
||||
|
||||
$this->update( $value );
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch and sanitize the $_POST value for the setting.
|
||||
*
|
||||
* @since 3.4.0
|
||||
*
|
||||
* @param mixed $default A default value which is used as a fallback. Default is null.
|
||||
* @return mixed The default value on failure, otherwise the sanitized value.
|
||||
*/
|
||||
final public function post_value( $default = null ) {
|
||||
return $this->manager->post_value( $this, $default );
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitize an input.
|
||||
*
|
||||
* @since 3.4.0
|
||||
*
|
||||
* @param string|array $value The value to sanitize.
|
||||
* @return string|array|null Null if an input isn't valid, otherwise the sanitized value.
|
||||
*/
|
||||
public function sanitize( $value ) {
|
||||
|
||||
/**
|
||||
* Filter a Customize setting value in un-slashed form.
|
||||
*
|
||||
* @since 3.4.0
|
||||
*
|
||||
* @param mixed $value Value of the setting.
|
||||
* @param WP_Customize_Setting $this WP_Customize_Setting instance.
|
||||
*/
|
||||
return apply_filters( "customize_sanitize_{$this->id}", $value, $this );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the root value for a setting, especially for multidimensional ones.
|
||||
*
|
||||
* @since 4.4.0
|
||||
* @access protected
|
||||
*
|
||||
* @param mixed $default Value to return if root does not exist.
|
||||
* @return mixed
|
||||
*/
|
||||
protected function get_root_value( $default = null ) {
|
||||
$id_base = $this->id_data['base'];
|
||||
if ( 'option' === $this->type ) {
|
||||
return get_option( $id_base, $default );
|
||||
} else if ( 'theme_mod' ) {
|
||||
return get_theme_mod( $id_base, $default );
|
||||
} else {
|
||||
/*
|
||||
* Any WP_Customize_Setting subclass implementing aggregate multidimensional
|
||||
* will need to override this method to obtain the data from the appropriate
|
||||
* location.
|
||||
*/
|
||||
return $default;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the root value for a setting, especially for multidimensional ones.
|
||||
*
|
||||
* @since 4.4.0
|
||||
* @access protected
|
||||
*
|
||||
* @param mixed $value Value to set as root of multidimensional setting.
|
||||
* @return bool Whether the multidimensional root was updated successfully.
|
||||
*/
|
||||
protected function set_root_value( $value ) {
|
||||
$id_base = $this->id_data['base'];
|
||||
if ( 'option' === $this->type ) {
|
||||
$autoload = true;
|
||||
if ( isset( self::$aggregated_multidimensionals[ $this->type ][ $this->id_data['base'] ]['autoload'] ) ) {
|
||||
$autoload = self::$aggregated_multidimensionals[ $this->type ][ $this->id_data['base'] ]['autoload'];
|
||||
}
|
||||
return update_option( $id_base, $value, $autoload );
|
||||
} else if ( 'theme_mod' ) {
|
||||
set_theme_mod( $id_base, $value );
|
||||
return true;
|
||||
} else {
|
||||
/*
|
||||
* Any WP_Customize_Setting subclass implementing aggregate multidimensional
|
||||
* will need to override this method to obtain the data from the appropriate
|
||||
* location.
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the value of the setting, using the related API.
|
||||
*
|
||||
* @since 3.4.0
|
||||
*
|
||||
* @param mixed $value The value to update.
|
||||
* @return bool The result of saving the value.
|
||||
*/
|
||||
protected function update( $value ) {
|
||||
$id_base = $this->id_data['base'];
|
||||
if ( 'option' === $this->type || 'theme_mod' === $this->type ) {
|
||||
if ( ! $this->is_multidimensional_aggregated ) {
|
||||
return $this->set_root_value( $value );
|
||||
} else {
|
||||
$root = self::$aggregated_multidimensionals[ $this->type ][ $id_base ]['root_value'];
|
||||
$root = $this->multidimensional_replace( $root, $this->id_data['keys'], $value );
|
||||
self::$aggregated_multidimensionals[ $this->type ][ $id_base ]['root_value'] = $root;
|
||||
return $this->set_root_value( $root );
|
||||
}
|
||||
} else {
|
||||
/**
|
||||
* Fires when the {@see WP_Customize_Setting::update()} method is called for settings
|
||||
* not handled as theme_mods or options.
|
||||
*
|
||||
* The dynamic portion of the hook name, `$this->type`, refers to the type of setting.
|
||||
*
|
||||
* @since 3.4.0
|
||||
*
|
||||
* @param mixed $value Value of the setting.
|
||||
* @param WP_Customize_Setting $this WP_Customize_Setting instance.
|
||||
*/
|
||||
do_action( "customize_update_{$this->type}", $value, $this );
|
||||
|
||||
return has_action( "customize_update_{$this->type}" );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated method.
|
||||
*
|
||||
* @since 3.4.0
|
||||
* @deprecated 4.4.0 Deprecated in favor of update() method.
|
||||
*/
|
||||
protected function _update_theme_mod() {
|
||||
_deprecated_function( __METHOD__, '4.4.0', __CLASS__ . '::update()' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated method.
|
||||
*
|
||||
* @since 3.4.0
|
||||
* @deprecated 4.4.0 Deprecated in favor of update() method.
|
||||
*/
|
||||
protected function _update_option() {
|
||||
_deprecated_function( __METHOD__, '4.4.0', __CLASS__ . '::update()' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the value of the setting.
|
||||
*
|
||||
* @since 3.4.0
|
||||
*
|
||||
* @return mixed The value.
|
||||
*/
|
||||
public function value() {
|
||||
$id_base = $this->id_data['base'];
|
||||
$is_core_type = ( 'option' === $this->type || 'theme_mod' === $this->type );
|
||||
|
||||
if ( ! $is_core_type && ! $this->is_multidimensional_aggregated ) {
|
||||
$value = $this->get_root_value( $this->default );
|
||||
|
||||
/**
|
||||
* Filter a Customize setting value not handled as a theme_mod or option.
|
||||
*
|
||||
* The dynamic portion of the hook name, `$this->id_date['base']`, refers to
|
||||
* the base slug of the setting name.
|
||||
*
|
||||
* For settings handled as theme_mods or options, see those corresponding
|
||||
* functions for available hooks.
|
||||
*
|
||||
* @since 3.4.0
|
||||
*
|
||||
* @param mixed $default The setting default value. Default empty.
|
||||
*/
|
||||
$value = apply_filters( "customize_value_{$id_base}", $value );
|
||||
} else if ( $this->is_multidimensional_aggregated ) {
|
||||
$root_value = self::$aggregated_multidimensionals[ $this->type ][ $id_base ]['root_value'];
|
||||
$value = $this->multidimensional_get( $root_value, $this->id_data['keys'], $this->default );
|
||||
} else {
|
||||
$value = $this->get_root_value( $this->default );
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitize the setting's value for use in JavaScript.
|
||||
*
|
||||
* @since 3.4.0
|
||||
*
|
||||
* @return mixed The requested escaped value.
|
||||
*/
|
||||
public function js_value() {
|
||||
|
||||
/**
|
||||
* Filter a Customize setting value for use in JavaScript.
|
||||
*
|
||||
* The dynamic portion of the hook name, `$this->id`, refers to the setting ID.
|
||||
*
|
||||
* @since 3.4.0
|
||||
*
|
||||
* @param mixed $value The setting value.
|
||||
* @param WP_Customize_Setting $this {@see WP_Customize_Setting} instance.
|
||||
*/
|
||||
$value = apply_filters( "customize_sanitize_js_{$this->id}", $this->value(), $this );
|
||||
|
||||
if ( is_string( $value ) )
|
||||
return html_entity_decode( $value, ENT_QUOTES, 'UTF-8');
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate user capabilities whether the theme supports the setting.
|
||||
*
|
||||
* @since 3.4.0
|
||||
*
|
||||
* @return bool False if theme doesn't support the setting or user can't change setting, otherwise true.
|
||||
*/
|
||||
final public function check_capabilities() {
|
||||
if ( $this->capability && ! call_user_func_array( 'current_user_can', (array) $this->capability ) )
|
||||
return false;
|
||||
|
||||
if ( $this->theme_supports && ! call_user_func_array( 'current_theme_supports', (array) $this->theme_supports ) )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Multidimensional helper function.
|
||||
*
|
||||
* @since 3.4.0
|
||||
*
|
||||
* @param $root
|
||||
* @param $keys
|
||||
* @param bool $create Default is false.
|
||||
* @return array|void Keys are 'root', 'node', and 'key'.
|
||||
*/
|
||||
final protected function multidimensional( &$root, $keys, $create = false ) {
|
||||
if ( $create && empty( $root ) )
|
||||
$root = array();
|
||||
|
||||
if ( ! isset( $root ) || empty( $keys ) )
|
||||
return;
|
||||
|
||||
$last = array_pop( $keys );
|
||||
$node = &$root;
|
||||
|
||||
foreach ( $keys as $key ) {
|
||||
if ( $create && ! isset( $node[ $key ] ) )
|
||||
$node[ $key ] = array();
|
||||
|
||||
if ( ! is_array( $node ) || ! isset( $node[ $key ] ) )
|
||||
return;
|
||||
|
||||
$node = &$node[ $key ];
|
||||
}
|
||||
|
||||
if ( $create ) {
|
||||
if ( ! is_array( $node ) ) {
|
||||
// account for an array overriding a string or object value
|
||||
$node = array();
|
||||
}
|
||||
if ( ! isset( $node[ $last ] ) ) {
|
||||
$node[ $last ] = array();
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! isset( $node[ $last ] ) )
|
||||
return;
|
||||
|
||||
return array(
|
||||
'root' => &$root,
|
||||
'node' => &$node,
|
||||
'key' => $last,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will attempt to replace a specific value in a multidimensional array.
|
||||
*
|
||||
* @since 3.4.0
|
||||
*
|
||||
* @param $root
|
||||
* @param $keys
|
||||
* @param mixed $value The value to update.
|
||||
* @return mixed
|
||||
*/
|
||||
final protected function multidimensional_replace( $root, $keys, $value ) {
|
||||
if ( ! isset( $value ) )
|
||||
return $root;
|
||||
elseif ( empty( $keys ) ) // If there are no keys, we're replacing the root.
|
||||
return $value;
|
||||
|
||||
$result = $this->multidimensional( $root, $keys, true );
|
||||
|
||||
if ( isset( $result ) )
|
||||
$result['node'][ $result['key'] ] = $value;
|
||||
|
||||
return $root;
|
||||
}
|
||||
|
||||
/**
|
||||
* Will attempt to fetch a specific value from a multidimensional array.
|
||||
*
|
||||
* @since 3.4.0
|
||||
*
|
||||
* @param $root
|
||||
* @param $keys
|
||||
* @param mixed $default A default value which is used as a fallback. Default is null.
|
||||
* @return mixed The requested value or the default value.
|
||||
*/
|
||||
final protected function multidimensional_get( $root, $keys, $default = null ) {
|
||||
if ( empty( $keys ) ) // If there are no keys, test the root.
|
||||
return isset( $root ) ? $root : $default;
|
||||
|
||||
$result = $this->multidimensional( $root, $keys );
|
||||
return isset( $result ) ? $result['node'][ $result['key'] ] : $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Will attempt to check if a specific value in a multidimensional array is set.
|
||||
*
|
||||
* @since 3.4.0
|
||||
*
|
||||
* @param $root
|
||||
* @param $keys
|
||||
* @return bool True if value is set, false if not.
|
||||
*/
|
||||
final protected function multidimensional_isset( $root, $keys ) {
|
||||
$result = $this->multidimensional_get( $root, $keys );
|
||||
return isset( $result );
|
||||
}
|
||||
}
|
||||
|
||||
/** WP_Customize_Filter_Setting class */
|
||||
require_once( ABSPATH . WPINC . '/customize/class-wp-customize-filter-setting.php' );
|
||||
|
||||
/** WP_Customize_Header_Image_Setting class */
|
||||
require_once( ABSPATH . WPINC . '/customize/class-wp-customize-header-image-setting.php' );
|
||||
|
||||
/** WP_Customize_Background_Image_Setting class */
|
||||
require_once( ABSPATH . WPINC . '/customize/class-wp-customize-background-image-setting.php' );
|
||||
|
||||
/** WP_Customize_Nav_Menu_Item_Setting class */
|
||||
require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-item-setting.php' );
|
||||
|
||||
/** WP_Customize_Nav_Menu_Setting class */
|
||||
require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-setting.php' );
|
||||
2019
Kapitel_7/Lektion_4/wordpress/wp-includes/class-wp-customize-widgets.php
Executable file
2019
Kapitel_7/Lektion_4/wordpress/wp-includes/class-wp-customize-widgets.php
Executable file
File diff suppressed because it is too large
Load Diff
1468
Kapitel_7/Lektion_4/wordpress/wp-includes/class-wp-editor.php
Executable file
1468
Kapitel_7/Lektion_4/wordpress/wp-includes/class-wp-editor.php
Executable file
File diff suppressed because it is too large
Load Diff
372
Kapitel_7/Lektion_4/wordpress/wp-includes/class-wp-embed.php
Executable file
372
Kapitel_7/Lektion_4/wordpress/wp-includes/class-wp-embed.php
Executable file
@@ -0,0 +1,372 @@
|
||||
<?php
|
||||
/**
|
||||
* API for easily embedding rich media such as videos and images into content.
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Embed
|
||||
* @since 2.9.0
|
||||
*/
|
||||
class WP_Embed {
|
||||
public $handlers = array();
|
||||
public $post_ID;
|
||||
public $usecache = true;
|
||||
public $linkifunknown = true;
|
||||
public $last_attr = array();
|
||||
public $last_url = '';
|
||||
|
||||
/**
|
||||
* When a URL cannot be embedded, return false instead of returning a link
|
||||
* or the URL. Bypasses the 'embed_maybe_make_link' filter.
|
||||
*/
|
||||
public $return_false_on_fail = false;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct() {
|
||||
// Hack to get the [embed] shortcode to run before wpautop()
|
||||
add_filter( 'the_content', array( $this, 'run_shortcode' ), 8 );
|
||||
|
||||
// Shortcode placeholder for strip_shortcodes()
|
||||
add_shortcode( 'embed', '__return_false' );
|
||||
|
||||
// Attempts to embed all URLs in a post
|
||||
add_filter( 'the_content', array( $this, 'autoembed' ), 8 );
|
||||
|
||||
// After a post is saved, cache oEmbed items via AJAX
|
||||
add_action( 'edit_form_advanced', array( $this, 'maybe_run_ajax_cache' ) );
|
||||
add_action( 'edit_page_form', array( $this, 'maybe_run_ajax_cache' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the [embed] shortcode.
|
||||
*
|
||||
* Since the [embed] shortcode needs to be run earlier than other shortcodes,
|
||||
* this function removes all existing shortcodes, registers the [embed] shortcode,
|
||||
* calls {@link do_shortcode()}, and then re-registers the old shortcodes.
|
||||
*
|
||||
* @global array $shortcode_tags
|
||||
*
|
||||
* @param string $content Content to parse
|
||||
* @return string Content with shortcode parsed
|
||||
*/
|
||||
public function run_shortcode( $content ) {
|
||||
global $shortcode_tags;
|
||||
|
||||
// Back up current registered shortcodes and clear them all out
|
||||
$orig_shortcode_tags = $shortcode_tags;
|
||||
remove_all_shortcodes();
|
||||
|
||||
add_shortcode( 'embed', array( $this, 'shortcode' ) );
|
||||
|
||||
// Do the shortcode (only the [embed] one is registered)
|
||||
$content = do_shortcode( $content, true );
|
||||
|
||||
// Put the original shortcodes back
|
||||
$shortcode_tags = $orig_shortcode_tags;
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* If a post/page was saved, then output JavaScript to make
|
||||
* an AJAX request that will call WP_Embed::cache_oembed().
|
||||
*/
|
||||
public function maybe_run_ajax_cache() {
|
||||
$post = get_post();
|
||||
|
||||
if ( ! $post || empty( $_GET['message'] ) )
|
||||
return;
|
||||
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
jQuery(document).ready(function($){
|
||||
$.get("<?php echo admin_url( 'admin-ajax.php?action=oembed-cache&post=' . $post->ID, 'relative' ); ?>");
|
||||
});
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Register an embed handler. Do not use this function directly, use {@link wp_embed_register_handler()} instead.
|
||||
* This function should probably also only be used for sites that do not support oEmbed.
|
||||
*
|
||||
* @param string $id An internal ID/name for the handler. Needs to be unique.
|
||||
* @param string $regex The regex that will be used to see if this handler should be used for a URL.
|
||||
* @param callable $callback The callback function that will be called if the regex is matched.
|
||||
* @param int $priority Optional. Used to specify the order in which the registered handlers will be tested (default: 10). Lower numbers correspond with earlier testing, and handlers with the same priority are tested in the order in which they were added to the action.
|
||||
*/
|
||||
public function register_handler( $id, $regex, $callback, $priority = 10 ) {
|
||||
$this->handlers[$priority][$id] = array(
|
||||
'regex' => $regex,
|
||||
'callback' => $callback,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister a previously registered embed handler. Do not use this function directly, use {@link wp_embed_unregister_handler()} instead.
|
||||
*
|
||||
* @param string $id The handler ID that should be removed.
|
||||
* @param int $priority Optional. The priority of the handler to be removed (default: 10).
|
||||
*/
|
||||
public function unregister_handler( $id, $priority = 10 ) {
|
||||
unset( $this->handlers[ $priority ][ $id ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* The {@link do_shortcode()} callback function.
|
||||
*
|
||||
* Attempts to convert a URL into embed HTML. Starts by checking the URL against the regex of the registered embed handlers.
|
||||
* If none of the regex matches and it's enabled, then the URL will be given to the {@link WP_oEmbed} class.
|
||||
*
|
||||
* @param array $attr {
|
||||
* Shortcode attributes. Optional.
|
||||
*
|
||||
* @type int $width Width of the embed in pixels.
|
||||
* @type int $height Height of the embed in pixels.
|
||||
* }
|
||||
* @param string $url The URL attempting to be embedded.
|
||||
* @return string|false The embed HTML on success, otherwise the original URL.
|
||||
* `->maybe_make_link()` can return false on failure.
|
||||
*/
|
||||
public function shortcode( $attr, $url = '' ) {
|
||||
$post = get_post();
|
||||
|
||||
if ( empty( $url ) && ! empty( $attr['src'] ) ) {
|
||||
$url = $attr['src'];
|
||||
}
|
||||
|
||||
$this->last_url = $url;
|
||||
|
||||
if ( empty( $url ) ) {
|
||||
$this->last_attr = $attr;
|
||||
return '';
|
||||
}
|
||||
|
||||
$rawattr = $attr;
|
||||
$attr = wp_parse_args( $attr, wp_embed_defaults( $url ) );
|
||||
|
||||
$this->last_attr = $attr;
|
||||
|
||||
// kses converts & into & and we need to undo this
|
||||
// See https://core.trac.wordpress.org/ticket/11311
|
||||
$url = str_replace( '&', '&', $url );
|
||||
|
||||
// Look for known internal handlers
|
||||
ksort( $this->handlers );
|
||||
foreach ( $this->handlers as $priority => $handlers ) {
|
||||
foreach ( $handlers as $id => $handler ) {
|
||||
if ( preg_match( $handler['regex'], $url, $matches ) && is_callable( $handler['callback'] ) ) {
|
||||
if ( false !== $return = call_user_func( $handler['callback'], $matches, $attr, $url, $rawattr ) )
|
||||
/**
|
||||
* Filter the returned embed handler.
|
||||
*
|
||||
* @since 2.9.0
|
||||
*
|
||||
* @see WP_Embed::shortcode()
|
||||
*
|
||||
* @param mixed $return The shortcode callback function to call.
|
||||
* @param string $url The attempted embed URL.
|
||||
* @param array $attr An array of shortcode attributes.
|
||||
*/
|
||||
return apply_filters( 'embed_handler_html', $return, $url, $attr );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$post_ID = ( ! empty( $post->ID ) ) ? $post->ID : null;
|
||||
if ( ! empty( $this->post_ID ) ) // Potentially set by WP_Embed::cache_oembed()
|
||||
$post_ID = $this->post_ID;
|
||||
|
||||
// Unknown URL format. Let oEmbed have a go.
|
||||
if ( $post_ID ) {
|
||||
|
||||
// Check for a cached result (stored in the post meta)
|
||||
$key_suffix = md5( $url . serialize( $attr ) );
|
||||
$cachekey = '_oembed_' . $key_suffix;
|
||||
$cachekey_time = '_oembed_time_' . $key_suffix;
|
||||
|
||||
/**
|
||||
* Filter the oEmbed TTL value (time to live).
|
||||
*
|
||||
* @since 4.0.0
|
||||
*
|
||||
* @param int $time Time to live (in seconds).
|
||||
* @param string $url The attempted embed URL.
|
||||
* @param array $attr An array of shortcode attributes.
|
||||
* @param int $post_ID Post ID.
|
||||
*/
|
||||
$ttl = apply_filters( 'oembed_ttl', DAY_IN_SECONDS, $url, $attr, $post_ID );
|
||||
|
||||
$cache = get_post_meta( $post_ID, $cachekey, true );
|
||||
$cache_time = get_post_meta( $post_ID, $cachekey_time, true );
|
||||
|
||||
if ( ! $cache_time ) {
|
||||
$cache_time = 0;
|
||||
}
|
||||
|
||||
$cached_recently = ( time() - $cache_time ) < $ttl;
|
||||
|
||||
if ( $this->usecache || $cached_recently ) {
|
||||
// Failures are cached. Serve one if we're using the cache.
|
||||
if ( '{{unknown}}' === $cache )
|
||||
return $this->maybe_make_link( $url );
|
||||
|
||||
if ( ! empty( $cache ) ) {
|
||||
/**
|
||||
* Filter the cached oEmbed HTML.
|
||||
*
|
||||
* @since 2.9.0
|
||||
*
|
||||
* @see WP_Embed::shortcode()
|
||||
*
|
||||
* @param mixed $cache The cached HTML result, stored in post meta.
|
||||
* @param string $url The attempted embed URL.
|
||||
* @param array $attr An array of shortcode attributes.
|
||||
* @param int $post_ID Post ID.
|
||||
*/
|
||||
return apply_filters( 'embed_oembed_html', $cache, $url, $attr, $post_ID );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter whether to inspect the given URL for discoverable link tags.
|
||||
*
|
||||
* @since 2.9.0
|
||||
* @since 4.4.0 The default value changed to true.
|
||||
*
|
||||
* @see WP_oEmbed::discover()
|
||||
*
|
||||
* @param bool $enable Whether to enable `<link>` tag discovery. Default true.
|
||||
*/
|
||||
$attr['discover'] = ( apply_filters( 'embed_oembed_discover', true ) );
|
||||
|
||||
// Use oEmbed to get the HTML
|
||||
$html = wp_oembed_get( $url, $attr );
|
||||
|
||||
// Maybe cache the result
|
||||
if ( $html ) {
|
||||
update_post_meta( $post_ID, $cachekey, $html );
|
||||
update_post_meta( $post_ID, $cachekey_time, time() );
|
||||
} elseif ( ! $cache ) {
|
||||
update_post_meta( $post_ID, $cachekey, '{{unknown}}' );
|
||||
}
|
||||
|
||||
// If there was a result, return it
|
||||
if ( $html ) {
|
||||
/** This filter is documented in wp-includes/class-wp-embed.php */
|
||||
return apply_filters( 'embed_oembed_html', $html, $url, $attr, $post_ID );
|
||||
}
|
||||
}
|
||||
|
||||
// Still unknown
|
||||
return $this->maybe_make_link( $url );
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all oEmbed caches. Unused by core as of 4.0.0.
|
||||
*
|
||||
* @param int $post_ID Post ID to delete the caches for.
|
||||
*/
|
||||
public function delete_oembed_caches( $post_ID ) {
|
||||
$post_metas = get_post_custom_keys( $post_ID );
|
||||
if ( empty($post_metas) )
|
||||
return;
|
||||
|
||||
foreach ( $post_metas as $post_meta_key ) {
|
||||
if ( '_oembed_' == substr( $post_meta_key, 0, 8 ) )
|
||||
delete_post_meta( $post_ID, $post_meta_key );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggers a caching of all oEmbed results.
|
||||
*
|
||||
* @param int $post_ID Post ID to do the caching for.
|
||||
*/
|
||||
public function cache_oembed( $post_ID ) {
|
||||
$post = get_post( $post_ID );
|
||||
|
||||
$post_types = get_post_types( array( 'show_ui' => true ) );
|
||||
/**
|
||||
* Filter the array of post types to cache oEmbed results for.
|
||||
*
|
||||
* @since 2.9.0
|
||||
*
|
||||
* @param array $post_types Array of post types to cache oEmbed results for. Defaults to post types with `show_ui` set to true.
|
||||
*/
|
||||
if ( empty( $post->ID ) || ! in_array( $post->post_type, apply_filters( 'embed_cache_oembed_types', $post_types ) ) ){
|
||||
return;
|
||||
}
|
||||
|
||||
// Trigger a caching
|
||||
if ( ! empty( $post->post_content ) ) {
|
||||
$this->post_ID = $post->ID;
|
||||
$this->usecache = false;
|
||||
|
||||
$content = $this->run_shortcode( $post->post_content );
|
||||
$this->autoembed( $content );
|
||||
|
||||
$this->usecache = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Passes any unlinked URLs that are on their own line to {@link WP_Embed::shortcode()} for potential embedding.
|
||||
*
|
||||
* @uses WP_Embed::autoembed_callback()
|
||||
*
|
||||
* @param string $content The content to be searched.
|
||||
* @return string Potentially modified $content.
|
||||
*/
|
||||
public function autoembed( $content ) {
|
||||
// Replace line breaks from all HTML elements with placeholders.
|
||||
$content = wp_replace_in_html_tags( $content, array( "\n" => '<!-- wp-line-break -->' ) );
|
||||
|
||||
// Find URLs that are on their own line.
|
||||
$content = preg_replace_callback( '|^(\s*)(https?://[^\s"]+)(\s*)$|im', array( $this, 'autoembed_callback' ), $content );
|
||||
|
||||
// Put the line breaks back.
|
||||
return str_replace( '<!-- wp-line-break -->', "\n", $content );
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback function for {@link WP_Embed::autoembed()}.
|
||||
*
|
||||
* @param array $match A regex match array.
|
||||
* @return string The embed HTML on success, otherwise the original URL.
|
||||
*/
|
||||
public function autoembed_callback( $match ) {
|
||||
$oldval = $this->linkifunknown;
|
||||
$this->linkifunknown = false;
|
||||
$return = $this->shortcode( array(), $match[2] );
|
||||
$this->linkifunknown = $oldval;
|
||||
|
||||
return $match[1] . $return . $match[3];
|
||||
}
|
||||
|
||||
/**
|
||||
* Conditionally makes a hyperlink based on an internal class variable.
|
||||
*
|
||||
* @param string $url URL to potentially be linked.
|
||||
* @return false|string Linked URL or the original URL. False if 'return_false_on_fail' is true.
|
||||
*/
|
||||
public function maybe_make_link( $url ) {
|
||||
if ( $this->return_false_on_fail ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$output = ( $this->linkifunknown ) ? '<a href="' . esc_url($url) . '">' . esc_html($url) . '</a>' : $url;
|
||||
|
||||
/**
|
||||
* Filter the returned, maybe-linked embed URL.
|
||||
*
|
||||
* @since 2.9.0
|
||||
*
|
||||
* @param string $output The linked or original URL.
|
||||
* @param string $url The original URL.
|
||||
*/
|
||||
return apply_filters( 'embed_maybe_make_link', $output, $url );
|
||||
}
|
||||
}
|
||||
$GLOBALS['wp_embed'] = new WP_Embed();
|
||||
218
Kapitel_7/Lektion_4/wordpress/wp-includes/class-wp-error.php
Executable file
218
Kapitel_7/Lektion_4/wordpress/wp-includes/class-wp-error.php
Executable file
@@ -0,0 +1,218 @@
|
||||
<?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
|
||||
*/
|
||||
public $errors = array();
|
||||
|
||||
/**
|
||||
* Stores the list of data for error codes.
|
||||
*
|
||||
* @since 2.1.0
|
||||
* @var array
|
||||
*/
|
||||
public $error_data = array();
|
||||
|
||||
/**
|
||||
* Initialize the error.
|
||||
*
|
||||
* If `$code` is empty, the other parameters will be ignored.
|
||||
* When `$code` is not empty, `$message` will be used even if
|
||||
* it is empty. The `$data` parameter will be used only if it
|
||||
* is not empty.
|
||||
*
|
||||
* Though the class is constructed with a single error code and
|
||||
* message, multiple codes can be added using the `add()` method.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @param string|int $code Error code
|
||||
* @param string $message Error message
|
||||
* @param mixed $data Optional. Error data.
|
||||
*/
|
||||
public function __construct( $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 available.
|
||||
*/
|
||||
public 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.
|
||||
*/
|
||||
public 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 code parameter).
|
||||
*/
|
||||
public 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
|
||||
*/
|
||||
public 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 Error data, if it exists.
|
||||
*/
|
||||
public function get_error_data($code = '') {
|
||||
if ( empty($code) )
|
||||
$code = $this->get_error_code();
|
||||
|
||||
if ( isset($this->error_data[$code]) )
|
||||
return $this->error_data[$code];
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an error or append additional message to an existing error.
|
||||
*
|
||||
* @since 2.1.0
|
||||
* @access public
|
||||
*
|
||||
* @param string|int $code Error code.
|
||||
* @param string $message Error message.
|
||||
* @param mixed $data Optional. Error data.
|
||||
*/
|
||||
public 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.
|
||||
*/
|
||||
public function add_data($data, $code = '') {
|
||||
if ( empty($code) )
|
||||
$code = $this->get_error_code();
|
||||
|
||||
$this->error_data[$code] = $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the specified error.
|
||||
*
|
||||
* This function removes all error messages associated with the specified
|
||||
* error code, along with any error data for that code.
|
||||
*
|
||||
* @since 4.1.0
|
||||
*
|
||||
* @param string|int $code Error code.
|
||||
*/
|
||||
public function remove( $code ) {
|
||||
unset( $this->errors[ $code ] );
|
||||
unset( $this->error_data[ $code ] );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether variable is a WordPress Error.
|
||||
*
|
||||
* Returns true if $thing is an object of the WP_Error class.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*
|
||||
* @param mixed $thing Check if unknown variable is a WP_Error object.
|
||||
* @return bool True, if WP_Error. False, if not WP_Error.
|
||||
*/
|
||||
function is_wp_error( $thing ) {
|
||||
return ( $thing instanceof WP_Error );
|
||||
}
|
||||
219
Kapitel_7/Lektion_4/wordpress/wp-includes/class-wp-http-cookie.php
Executable file
219
Kapitel_7/Lektion_4/wordpress/wp-includes/class-wp-http-cookie.php
Executable file
@@ -0,0 +1,219 @@
|
||||
<?php
|
||||
/**
|
||||
* HTTP API: WP_Http_Cookie class
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage HTTP
|
||||
* @since 4.4.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Core class used to encapsulate a single cookie object for internal use.
|
||||
*
|
||||
* Returned cookies are represented using this class, and when cookies are set, if they are not
|
||||
* already a WP_Http_Cookie() object, then they are turned into one.
|
||||
*
|
||||
* @todo The WordPress convention is to use underscores instead of camelCase for function and method
|
||||
* names. Need to switch to use underscores instead for the methods.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*/
|
||||
class WP_Http_Cookie {
|
||||
|
||||
/**
|
||||
* Cookie name.
|
||||
*
|
||||
* @since 2.8.0
|
||||
* @var string
|
||||
*/
|
||||
public $name;
|
||||
|
||||
/**
|
||||
* Cookie value.
|
||||
*
|
||||
* @since 2.8.0
|
||||
* @var string
|
||||
*/
|
||||
public $value;
|
||||
|
||||
/**
|
||||
* When the cookie expires.
|
||||
*
|
||||
* @since 2.8.0
|
||||
* @var string
|
||||
*/
|
||||
public $expires;
|
||||
|
||||
/**
|
||||
* Cookie URL path.
|
||||
*
|
||||
* @since 2.8.0
|
||||
* @var string
|
||||
*/
|
||||
public $path;
|
||||
|
||||
/**
|
||||
* Cookie Domain.
|
||||
*
|
||||
* @since 2.8.0
|
||||
* @var string
|
||||
*/
|
||||
public $domain;
|
||||
|
||||
/**
|
||||
* Sets up this cookie object.
|
||||
*
|
||||
* The parameter $data should be either an associative array containing the indices names below
|
||||
* or a header string detailing it.
|
||||
*
|
||||
* @since 2.8.0
|
||||
* @access public
|
||||
*
|
||||
* @param string|array $data {
|
||||
* Raw cookie data as header string or data array.
|
||||
*
|
||||
* @type string $name Cookie name.
|
||||
* @type mixed $value Value. Should NOT already be urlencoded.
|
||||
* @type string|int $expires Optional. Unix timestamp or formatted date. Default null.
|
||||
* @type string $path Optional. Path. Default '/'.
|
||||
* @type string $domain Optional. Domain. Default host of parsed $requested_url.
|
||||
* @type int $port Optional. Port. Default null.
|
||||
* }
|
||||
* @param string $requested_url The URL which the cookie was set on, used for default $domain
|
||||
* and $port values.
|
||||
*/
|
||||
public function __construct( $data, $requested_url = '' ) {
|
||||
if ( $requested_url )
|
||||
$arrURL = @parse_url( $requested_url );
|
||||
if ( isset( $arrURL['host'] ) )
|
||||
$this->domain = $arrURL['host'];
|
||||
$this->path = isset( $arrURL['path'] ) ? $arrURL['path'] : '/';
|
||||
if ( '/' != substr( $this->path, -1 ) )
|
||||
$this->path = dirname( $this->path ) . '/';
|
||||
|
||||
if ( is_string( $data ) ) {
|
||||
// Assume it's a header string direct from a previous request.
|
||||
$pairs = explode( ';', $data );
|
||||
|
||||
// Special handling for first pair; name=value. Also be careful of "=" in value.
|
||||
$name = trim( substr( $pairs[0], 0, strpos( $pairs[0], '=' ) ) );
|
||||
$value = substr( $pairs[0], strpos( $pairs[0], '=' ) + 1 );
|
||||
$this->name = $name;
|
||||
$this->value = urldecode( $value );
|
||||
|
||||
// Removes name=value from items.
|
||||
array_shift( $pairs );
|
||||
|
||||
// Set everything else as a property.
|
||||
foreach ( $pairs as $pair ) {
|
||||
$pair = rtrim($pair);
|
||||
|
||||
// Handle the cookie ending in ; which results in a empty final pair.
|
||||
if ( empty($pair) )
|
||||
continue;
|
||||
|
||||
list( $key, $val ) = strpos( $pair, '=' ) ? explode( '=', $pair ) : array( $pair, '' );
|
||||
$key = strtolower( trim( $key ) );
|
||||
if ( 'expires' == $key )
|
||||
$val = strtotime( $val );
|
||||
$this->$key = $val;
|
||||
}
|
||||
} else {
|
||||
if ( !isset( $data['name'] ) )
|
||||
return;
|
||||
|
||||
// Set properties based directly on parameters.
|
||||
foreach ( array( 'name', 'value', 'path', 'domain', 'port' ) as $field ) {
|
||||
if ( isset( $data[ $field ] ) )
|
||||
$this->$field = $data[ $field ];
|
||||
}
|
||||
|
||||
if ( isset( $data['expires'] ) )
|
||||
$this->expires = is_int( $data['expires'] ) ? $data['expires'] : strtotime( $data['expires'] );
|
||||
else
|
||||
$this->expires = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirms that it's OK to send this cookie to the URL checked against.
|
||||
*
|
||||
* Decision is based on RFC 2109/2965, so look there for details on validity.
|
||||
*
|
||||
* @access public
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @param string $url URL you intend to send this cookie to
|
||||
* @return bool true if allowed, false otherwise.
|
||||
*/
|
||||
public function test( $url ) {
|
||||
if ( is_null( $this->name ) )
|
||||
return false;
|
||||
|
||||
// Expires - if expired then nothing else matters.
|
||||
if ( isset( $this->expires ) && time() > $this->expires )
|
||||
return false;
|
||||
|
||||
// Get details on the URL we're thinking about sending to.
|
||||
$url = parse_url( $url );
|
||||
$url['port'] = isset( $url['port'] ) ? $url['port'] : ( 'https' == $url['scheme'] ? 443 : 80 );
|
||||
$url['path'] = isset( $url['path'] ) ? $url['path'] : '/';
|
||||
|
||||
// Values to use for comparison against the URL.
|
||||
$path = isset( $this->path ) ? $this->path : '/';
|
||||
$port = isset( $this->port ) ? $this->port : null;
|
||||
$domain = isset( $this->domain ) ? strtolower( $this->domain ) : strtolower( $url['host'] );
|
||||
if ( false === stripos( $domain, '.' ) )
|
||||
$domain .= '.local';
|
||||
|
||||
// Host - very basic check that the request URL ends with the domain restriction (minus leading dot).
|
||||
$domain = substr( $domain, 0, 1 ) == '.' ? substr( $domain, 1 ) : $domain;
|
||||
if ( substr( $url['host'], -strlen( $domain ) ) != $domain )
|
||||
return false;
|
||||
|
||||
// Port - supports "port-lists" in the format: "80,8000,8080".
|
||||
if ( !empty( $port ) && !in_array( $url['port'], explode( ',', $port) ) )
|
||||
return false;
|
||||
|
||||
// Path - request path must start with path restriction.
|
||||
if ( substr( $url['path'], 0, strlen( $path ) ) != $path )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert cookie name and value back to header string.
|
||||
*
|
||||
* @access public
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @return string Header encoded cookie name and value.
|
||||
*/
|
||||
public function getHeaderValue() {
|
||||
if ( ! isset( $this->name ) || ! isset( $this->value ) )
|
||||
return '';
|
||||
|
||||
/**
|
||||
* Filter the header-encoded cookie value.
|
||||
*
|
||||
* @since 3.4.0
|
||||
*
|
||||
* @param string $value The cookie value.
|
||||
* @param string $name The cookie name.
|
||||
*/
|
||||
return $this->name . '=' . apply_filters( 'wp_http_cookie_value', $this->value, $this->name );
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve cookie header for usage in the rest of the WordPress HTTP API.
|
||||
*
|
||||
* @access public
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getFullHeader() {
|
||||
return 'Cookie: ' . $this->getHeaderValue();
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user