Current File : /home/k/a/r/karenpetzb/www/items/category/Parse.tar |
Date.php 0000644 00000064345 15071175241 0006151 0 ustar 00 <?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-2022, Ryan Parman, Sam 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
* @copyright 2004-2016 Ryan Parman, Sam Sneddon, Ryan McCue
* @author Ryan Parman
* @author Sam Sneddon
* @author Ryan McCue
* @link http://simplepie.org/ SimplePie
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
namespace SimplePie\Parse;
/**
* Date Parser
*
* @package SimplePie
* @subpackage Parsing
*/
class Date
{
/**
* Input data
*
* @access protected
* @var string
*/
public $date;
/**
* List of days, calendar day name => ordinal day number in the week
*
* @access protected
* @var array
*/
public $day = [
// 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,
'mo' => 1,
'dienstag' => 2,
'di' => 2,
'mittwoch' => 3,
'mi' => 3,
'donnerstag' => 4,
'do' => 4,
'freitag' => 5,
'fr' => 5,
'samstag' => 6,
'sa' => 6,
'sonnabend' => 6,
// AFAIK no short form for sonnabend
'so' => 7,
'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,
// Russian
'Пн.' => 1,
'Вт.' => 2,
'Ср.' => 3,
'Чт.' => 4,
'Пт.' => 5,
'Сб.' => 6,
'Вс.' => 7,
];
/**
* List of months, calendar month name => calendar month number
*
* @access protected
* @var array
*/
public $month = [
// 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' => 9,
'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,
'jan' => 1,
'februar' => 2,
'feb' => 2,
'märz' => 3,
'mär' => 3,
'april' => 4,
'apr' => 4,
'mai' => 5, // no short form for may
'juni' => 6,
'jun' => 6,
'juli' => 7,
'jul' => 7,
'august' => 8,
'aug' => 8,
'september' => 9,
'sep' => 9,
'oktober' => 10,
'okt' => 10,
'november' => 11,
'nov' => 11,
'dezember' => 12,
'dez' => 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,
// Russian
'Янв' => 1,
'января' => 1,
'Фев' => 2,
'февраля' => 2,
'Мар' => 3,
'марта' => 3,
'Апр' => 4,
'апреля' => 4,
'Май' => 5,
'мая' => 5,
'Июн' => 6,
'июня' => 6,
'Июл' => 7,
'июля' => 7,
'Авг' => 8,
'августа' => 8,
'Сен' => 9,
'сентября' => 9,
'Окт' => 10,
'октября' => 10,
'Ноя' => 11,
'ноября' => 11,
'Дек' => 12,
'декабря' => 12,
];
/**
* List of timezones, abbreviation => offset from UTC
*
* @access protected
* @var array
*/
public $timezone = [
'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 Date::$day
*
* @access protected
* @var string
*/
public $day_pcre;
/**
* Cached PCRE for Date::$month
*
* @access protected
* @var string
*/
public $month_pcre;
/**
* Array of user-added callback methods
*
* @access private
* @var array
*/
public $built_in = [];
/**
* Array of user-added callback methods
*
* @access private
* @var array
*/
public $user = [];
/**
* Create new 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 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([$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 separator (including more than one))
*
* @access protected
* @return int Timestamp
*/
public function date_w3cdtf($date)
{
$pcre = <<<'PCRE'
/
^
(?P<year>[0-9]{4})
(?:
-?
(?P<month>[0-9]{2})
(?:
-?
(?P<day>[0-9]{2})
(?:
[Tt\x09\x20]+
(?P<hour>[0-9]{2})
(?:
:?
(?P<minute>[0-9]{2})
(?:
:?
(?P<second>[0-9]{2})
(?:
.
(?P<second_fraction>[0-9]*)
)?
)?
)?
(?:
(?P<zulu>Z)
| (?P<tz_sign>[+\-])
(?P<tz_hour>[0-9]{1,2})
:?
(?P<tz_minute>[0-9]{1,2})
)
)?
)?
)?
$
/x
PCRE;
if (preg_match($pcre, $date, $match)) {
// Fill in empty matches and convert to proper types.
$year = (int) $match['year'];
$month = isset($match['month']) ? (int) $match['month'] : 1;
$day = isset($match['day']) ? (int) $match['day'] : 1;
$hour = isset($match['hour']) ? (int) $match['hour'] : 0;
$minute = isset($match['minute']) ? (int) $match['minute'] : 0;
$second = isset($match['second']) ? (int) $match['second'] : 0;
$second_fraction = isset($match['second_fraction']) ? ((int) $match['second_fraction']) / (10 ** strlen($match['second_fraction'])) : 0;
$tz_sign = ($match['tz_sign'] ?? '') === '-' ? -1 : 1;
$tz_hour = isset($match['tz_hour']) ? (int) $match['tz_hour'] : 0;
$tz_minute = isset($match['tz_minute']) ? (int) $match['tz_minute'] : 0;
// Numeric timezone
$timezone = $tz_hour * 3600;
$timezone += $tz_minute * 60;
$timezone *= $tz_sign;
// Convert the number of seconds to an integer, taking decimals into account
$second = (int) round($second + $second_fraction);
return gmmktime($hour, $minute, $second, $month, $day, $year) - $timezone;
}
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 ($pos === 0 || $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(intval($match[5]), intval($match[6]), intval($second), intval($month), intval($match[2]), intval($match[4])) - $timezone;
}
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;
}
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((int) $match[4], (int) $match[5], (int) $match[6], $month, (int) $match[3], (int) $match[7]);
}
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;
}
return $strtotime;
}
}
class_alias('SimplePie\Parse\Date', 'SimplePie_Parse_Date');
OutputStream.php 0000604 00000002676 15071530550 0007741 0 ustar 00 <?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Amf
* @subpackage Parse
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
/** Zend_Amf_Util_BinaryStream */
require_once 'Zend/Amf/Util/BinaryStream.php';
/**
* Iterate at a binary level through the AMF response
*
* OutputStream extends BinaryStream as eventually BinaryStream could be placed
* outside of Zend_Amf in order to allow other packages to use the class.
*
* @uses Zend_Amf_Util_BinaryStream
* @package Zend_Amf
* @subpackage Parse
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Amf_Parse_OutputStream extends Zend_Amf_Util_BinaryStream
{
/**
* Constructor
*
* @return void
*/
public function __construct()
{
parent::__construct('');
}
}
TypeLoader.php 0000604 00000010570 15071530550 0007325 0 ustar 00 <?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Amf
* @subpackage Parse
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
require_once 'Zend/Amf/Value/Messaging/AcknowledgeMessage.php';
require_once 'Zend/Amf/Value/Messaging/AsyncMessage.php';
require_once 'Zend/Amf/Value/Messaging/CommandMessage.php';
require_once 'Zend/Amf/Value/Messaging/ErrorMessage.php';
require_once 'Zend/Amf/Value/Messaging/RemotingMessage.php';
/**
* Loads a local class and executes the instantiation of that class.
*
* @todo PHP 5.3 can drastically change this class w/ namespace and the new call_user_func w/ namespace
* @package Zend_Amf
* @subpackage Parse
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
final class Zend_Amf_Parse_TypeLoader
{
/**
* @var string callback class
*/
public static $callbackClass;
/**
* @var array AMF class map
*/
public static $classMap = array (
'flex.messaging.messages.AcknowledgeMessage' => 'Zend_Amf_Value_Messaging_AcknowledgeMessage',
'flex.messaging.messages.ErrorMessage' => 'Zend_Amf_Value_Messaging_AsyncMessage',
'flex.messaging.messages.CommandMessage' => 'Zend_Amf_Value_Messaging_CommandMessage',
'flex.messaging.messages.ErrorMessage' => 'Zend_Amf_Value_Messaging_ErrorMessage',
'flex.messaging.messages.RemotingMessage' => 'Zend_Amf_Value_Messaging_RemotingMessage',
);
/**
* @var array Default class map
*/
protected static $_defaultClassMap = array(
'flex.messaging.messages.AcknowledgeMessage' => 'Zend_Amf_Value_Messaging_AcknowledgeMessage',
'flex.messaging.messages.ErrorMessage' => 'Zend_Amf_Value_Messaging_AsyncMessage',
'flex.messaging.messages.CommandMessage' => 'Zend_Amf_Value_Messaging_CommandMessage',
'flex.messaging.messages.ErrorMessage' => 'Zend_Amf_Value_Messaging_ErrorMessage',
'flex.messaging.messages.RemotingMessage' => 'Zend_Amf_Value_Messaging_RemotingMessage',
);
/**
* Load the mapped class type into a callback.
*
* @param string $className
* @return object|false
*/
public static function loadType($className)
{
$class = false;
$callBack = false;
$class = self::getMappedClassName($className);
if (!class_exists($class)) {
require_once 'Zend/Amf/Exception.php';
throw new Zend_Amf_Exception($className .' mapped class '. $class . ' is not defined');
}
return $class;
}
/**
* Looks up the supplied call name to its mapped class name
*
* @param string $className
* @return string
*/
public static function getMappedClassName($className)
{
$mappedName = array_search($className, self::$classMap);
if ($mappedName) {
return $mappedName;
}
$mappedName = array_search($className, array_flip(self::$classMap));
if ($mappedName) {
return $mappedName;
}
return false;
}
/**
* Map PHP class names to ActionScript class names
*
* Allows users to map the class names of there action script classes
* to the equivelent php class name. Used in deserialization to load a class
* and serialiation to set the class name of the returned object.
*
* @param string $asClassName
* @param string $phpClassName
* @return void
*/
public static function setMapping($asClassName, $phpClassName)
{
self::$classMap[$asClassName] = $phpClassName;
}
/**
* Reset type map
*
* @return void
*/
public static function resetMap()
{
self::$classMap = self::$_defaultClassMap;
}
}
InputStream.php 0000604 00000002433 15071530550 0007527 0 ustar 00 <?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Amf
* @subpackage Parse
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
/** Zend_Amf_Util_BinaryStream */
require_once 'Zend/Amf/Util/BinaryStream.php';
/**
* InputStream is used to iterate at a binary level through the AMF request.
*
* InputStream extends BinaryStream as eventually BinaryStream could be placed
* outside of Zend_Amf in order to allow other packages to use the class.
*
* @package Zend_Amf
* @subpackage Parse
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Amf_Parse_InputStream extends Zend_Amf_Util_BinaryStream
{
}
Amf3/Deserializer.php 0000604 00000035703 15071530550 0010472 0 ustar 00 <?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Amf
* @subpackage Parse_Amf3
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
/** Zend_Amf_Parse_Deserializer */
require_once 'Zend/Amf/Parse/Deserializer.php';
/** Zend_Amf_Parse_TypeLoader */
require_once 'Zend/Amf/Parse/TypeLoader.php';
/**
* Read an AMF3 input stream and convert it into PHP data types.
*
* @todo readObject to handle Typed Objects
* @todo readXMLStrimg to be implemented.
* @todo Class could be implmented as Factory Class with each data type it's own class.
* @package Zend_Amf
* @subpackage Parse_Amf3
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Amf_Parse_Amf3_Deserializer extends Zend_Amf_Parse_Deserializer
{
/**
* Total number of objects in the referenceObject array
* @var int
*/
protected $_objectCount;
/**
* An array of reference objects per amf body
* @var array
*/
protected $_referenceObjects = array();
/**
* An array of reference strings per amf body
* @var array
*/
protected $_referenceStrings = array();
/**
* An array of reference class definitions per body
* @var array
*/
protected $_referenceDefinitions = array();
/**
* Read AMF markers and dispatch for deserialization
*
* Checks for AMF marker types and calls the appropriate methods
* for deserializing those marker types. markers are the data type of
* the following value.
*
* @param integer $typeMarker
* @return mixed Whatever the corresponding PHP data type is
* @throws Zend_Amf_Exception for unidentified marker type
*/
public function readTypeMarker($typeMarker = null)
{
if(null === $typeMarker) {
$typeMarker = $this->_stream->readByte();
}
switch($typeMarker) {
case Zend_Amf_Constants::AMF3_UNDEFINED:
return null;
case Zend_Amf_Constants::AMF3_NULL:
return null;
case Zend_Amf_Constants::AMF3_BOOLEAN_FALSE:
return false;
case Zend_Amf_Constants::AMF3_BOOLEAN_TRUE:
return true;
case Zend_Amf_Constants::AMF3_INTEGER:
return $this->readInteger();
case Zend_Amf_Constants::AMF3_NUMBER:
return $this->_stream->readDouble();
case Zend_Amf_Constants::AMF3_STRING:
return $this->readString();
case Zend_Amf_Constants::AMF3_DATE:
return $this->readDate();
case Zend_Amf_Constants::AMF3_ARRAY:
return $this->readArray();
case Zend_Amf_Constants::AMF3_OBJECT:
return $this->readObject();
case Zend_Amf_Constants::AMF3_XML:
case Zend_Amf_Constants::AMF3_XMLSTRING:
return $this->readXmlString();
case Zend_Amf_Constants::AMF3_BYTEARRAY:
return $this->readString();
default:
require_once 'Zend/Amf/Exception.php';
throw new Zend_Amf_Exception('Unsupported type marker: ' . $typeMarker);
}
}
/**
* Read and deserialize an integer
*
* AMF 3 represents smaller integers with fewer bytes using the most
* significant bit of each byte. The worst case uses 32-bits
* to represent a 29-bit number, which is what we would have
* done with no compression.
* - 0x00000000 - 0x0000007F : 0xxxxxxx
* - 0x00000080 - 0x00003FFF : 1xxxxxxx 0xxxxxxx
* - 0x00004000 - 0x001FFFFF : 1xxxxxxx 1xxxxxxx 0xxxxxxx
* - 0x00200000 - 0x3FFFFFFF : 1xxxxxxx 1xxxxxxx 1xxxxxxx xxxxxxxx
* - 0x40000000 - 0xFFFFFFFF : throw range exception
*
*
* 0x04 -> integer type code, followed by up to 4 bytes of data.
*
* @see: Parsing integers on OSFlash {http://osflash.org/amf3/parsing_integers>} for the AMF3 integer data format.
* @return int|float
*/
public function readInteger()
{
$count = 1;
$intReference = $this->_stream->readByte();
$result = 0;
while ((($intReference & 0x80) != 0) && $count < 4) {
$result <<= 7;
$result |= ($intReference & 0x7f);
$intReference = $this->_stream->readByte();
$count++;
}
if ($count < 4) {
$result <<= 7;
$result |= $intReference;
} else {
// Use all 8 bits from the 4th byte
$result <<= 8;
$result |= $intReference;
// Check if the integer should be negative
if (($result & 0x10000000) != 0) {
//and extend the sign bit
$result |= 0xe0000000;
}
}
return $result;
}
/**
* Read and deserialize a string
*
* Strings can be sent as a reference to a previously
* occurring String by using an index to the implicit string reference table.
* Strings are encoding using UTF-8 - however the header may either
* describe a string literal or a string reference.
*
* - string = 0x06 string-data
* - string-data = integer-data [ modified-utf-8 ]
* - modified-utf-8 = *OCTET
*
* @return String
*/
public function readString()
{
$stringReference = $this->readInteger();
//Check if this is a reference string
if (($stringReference & 0x01) == 0) {
// reference string
$stringReference = $stringReference >> 1;
if ($stringReference >= count($this->_referenceStrings)) {
require_once 'Zend/Amf/Exception.php';
throw new Zend_Amf_Exception('Undefined string reference: ' . $stringReference);
}
// reference string found
return $this->_referenceStrings[$stringReference];
}
$length = $stringReference >> 1;
if ($length) {
$string = $this->_stream->readBytes($length);
$this->_referenceStrings[] = $string;
} else {
$string = "";
}
return $string;
}
/**
* Read and deserialize a date
*
* Data is the number of milliseconds elapsed since the epoch
* of midnight, 1st Jan 1970 in the UTC time zone.
* Local time zone information is not sent to flash.
*
* - date = 0x08 integer-data [ number-data ]
*
* @return Zend_Date
*/
public function readDate()
{
$dateReference = $this->readInteger();
if (($dateReference & 0x01) == 0) {
$dateReference = $dateReference >> 1;
if ($dateReference>=count($this->_referenceObjects)) {
require_once 'Zend/Amf/Exception.php';
throw new Zend_Amf_Exception('Undefined date reference: ' . $dateReference);
}
return $this->_referenceObjects[$dateReference];
}
$timestamp = floor($this->_stream->readDouble() / 1000);
require_once 'Zend/Date.php';
$dateTime = new Zend_Date((int) $timestamp);
$this->_referenceObjects[] = $dateTime;
return $dateTime;
}
/**
* Read amf array to PHP array
*
* - array = 0x09 integer-data ( [ 1OCTET *amf3-data ] | [OCTET *amf3-data 1] | [ OCTET *amf-data ] )
*
* @return array
*/
public function readArray()
{
$arrayReference = $this->readInteger();
if (($arrayReference & 0x01)==0){
$arrayReference = $arrayReference >> 1;
if ($arrayReference>=count($this->_referenceObjects)) {
require_once 'Zend/Amf/Exception.php';
throw new Zend_Amf_Exception('Unknow array reference: ' . $arrayReference);
}
return $this->_referenceObjects[$arrayReference];
}
// Create a holder for the array in the reference list
$data = array();
$this->_referenceObjects[] &= $data;
$key = $this->readString();
// Iterating for string based keys.
while ($key != '') {
$data[$key] = $this->readTypeMarker();
$key = $this->readString();
}
$arrayReference = $arrayReference >>1;
//We have a dense array
for ($i=0; $i < $arrayReference; $i++) {
$data[] = $this->readTypeMarker();
}
return $data;
}
/**
* Read an object from the AMF stream and convert it into a PHP object
*
* @todo Rather than using an array of traitsInfo create Zend_Amf_Value_TraitsInfo
* @return object
*/
public function readObject()
{
$traitsInfo = $this->readInteger();
$storedObject = ($traitsInfo & 0x01)==0;
$traitsInfo = $traitsInfo >> 1;
// Check if the Object is in the stored Objects reference table
if ($storedObject) {
$ref = $traitsInfo;
if (!isset($this->_referenceObjects[$ref])) {
require_once 'Zend/Amf/Exception.php';
throw new Zend_Amf_Exception('Unknown Object reference: ' . $ref);
}
$returnObject = $this->_referenceObjects[$ref];
} else {
// Check if the Object is in the stored Definistions reference table
$storedClass = ($traitsInfo & 0x01) == 0;
$traitsInfo = $traitsInfo >> 1;
if ($storedClass) {
$ref = $traitsInfo;
if (!isset($this->_referenceDefinitions[$ref])) {
require_once 'Zend/Amf/Exception.php';
throw new Zend_Amf_Exception('Unknows Definition reference: '. $ref);
}
// Populate the reference attributes
$className = $this->_referenceDefinitions[$ref]['className'];
$encoding = $this->_referenceDefinitions[$ref]['encoding'];
$propertyNames = $this->_referenceDefinitions[$ref]['propertyNames'];
} else {
// The class was not in the reference tables. Start reading rawdata to build traits.
// Create a traits table. Zend_Amf_Value_TraitsInfo would be ideal
$className = $this->readString();
$encoding = $traitsInfo & 0x03;
$propertyNames = array();
$traitsInfo = $traitsInfo >> 2;
}
// We now have the object traits defined in variables. Time to go to work:
if (!$className) {
// No class name generic object
$returnObject = new stdClass();
} else {
// Defined object
// Typed object lookup agsinst registered classname maps
if ($loader = Zend_Amf_Parse_TypeLoader::loadType($className)) {
$returnObject = new $loader();
} else {
//user defined typed object
require_once 'Zend/Amf/Exception.php';
throw new Zend_Amf_Exception('Typed object not found: '. $className . ' ');
}
}
// Add the Object ot the reference table
$this->_referenceObjects[] = $returnObject;
// Check encoding types for additional processing.
switch ($encoding) {
case (Zend_Amf_Constants::ET_EXTERNAL):
// Externalizable object such as {ArrayCollection} and {ObjectProxy}
if (!$storedClass) {
$this->_referenceDefinitions[] = array(
'className' => $className,
'encoding' => $encoding,
'propertyNames' => $propertyNames,
);
}
$returnObject->externalizedData = $this->readTypeMarker();
break;
case (Zend_Amf_Constants::ET_DYNAMIC):
// used for Name-value encoding
if (!$storedClass) {
$this->_referenceDefinitions[] = array(
'className' => $className,
'encoding' => $encoding,
'propertyNames' => $propertyNames,
);
}
// not a refrence object read name value properties from byte stream
$properties = array(); // clear value
do {
$property = $this->readString();
if ($property != "") {
$propertyNames[] = $property;
$properties[$property] = $this->readTypeMarker();
}
} while ($property !="");
break;
default:
// basic property list object.
if (!$storedClass) {
$count = $traitsInfo; // Number of properties in the list
for($i=0; $i< $count; $i++) {
$propertyNames[] = $this->readString();
}
// Add a refrence to the class.
$this->_referenceDefinitions[] = array(
'className' => $className,
'encoding' => $encoding,
'propertyNames' => $propertyNames,
);
}
$properties = array(); // clear value
foreach ($propertyNames as $property) {
$properties[$property] = $this->readTypeMarker();
}
break;
}
// Add properties back to the return object.
foreach($properties as $key=>$value) {
if($key) {
$returnObject->$key = $value;
}
}
}
return $returnObject;
}
/**
* Convert XML to SimpleXml
* If user wants DomDocument they can use dom_import_simplexml
*
* @return SimpleXml Object
*/
public function readXmlString()
{
$xmlReference = $this->readInteger();
$length = $xmlReference >> 1;
$string = $this->_stream->readBytes($length);
return simplexml_load_string($string);
}
}
Amf3/Serializer.php 0000604 00000025754 15071530550 0010166 0 ustar 00 <?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Amf
* @subpackage Parse_Amf3
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
/** Zend_Amf_Parse_Serializer */
require_once 'Zend/Amf/Parse/Serializer.php';
/** Zend_Amf_Parse_TypeLoader */
require_once 'Zend/Amf/Parse/TypeLoader.php';
/**
* Detect PHP object type and convert it to a corresponding AMF3 object type
*
* @package Zend_Amf
* @subpackage Parse_Amf3
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Amf_Parse_Amf3_Serializer extends Zend_Amf_Parse_Serializer
{
/**
* Serialize PHP types to AMF3 and write to stream
*
* Checks to see if the type was declared and then either
* auto negotiates the type or use the user defined markerType to
* serialize the data from php back to AMF3
*
* @param mixed $content
* @param int $markerType
* @return void
*/
public function writeTypeMarker($data, $markerType=null)
{
if (null !== $markerType) {
// Write the Type Marker to denote the following action script data type
$this->_stream->writeByte($markerType);
switch ($markerType) {
case Zend_Amf_Constants::AMF3_NULL:
break;
case Zend_Amf_Constants::AMF3_BOOLEAN_FALSE:
break;
case Zend_Amf_Constants::AMF3_BOOLEAN_TRUE:
break;
case Zend_Amf_Constants::AMF3_INTEGER:
$this->writeInteger($data);
break;
case Zend_Amf_Constants::AMF3_NUMBER:
$this->_stream->writeDouble($data);
break;
case Zend_Amf_Constants::AMF3_STRING:
$this->writeString($data);
break;
case Zend_Amf_Constants::AMF3_DATE:
$this->writeDate($data);
break;
case Zend_Amf_Constants::AMF3_ARRAY:
$this->writeArray($data);
break;
case Zend_Amf_Constants::AMF3_OBJECT:
$this->writeObject($data);
break;
case Zend_Amf_Constants::AMF3_BYTEARRAY:
$this->writeString($data);
break;
default:
require_once 'Zend/Amf/Exception.php';
throw new Zend_Amf_Exception('Unknown Type Marker: ' . $markerType);
}
} else {
// Detect Type Marker
switch (true) {
case (null === $data):
$markerType = Zend_Amf_Constants::AMF3_NULL;
break;
case (is_bool($data)):
if ($data){
$markerType = Zend_Amf_Constants::AMF3_BOOLEAN_TRUE;
} else {
$markerType = Zend_Amf_Constants::AMF3_BOOLEAN_FALSE;
}
break;
case (is_int($data)):
if (($data > 0xFFFFFFF) || ($data < -268435456)) {
$markerType = Zend_Amf_Constants::AMF3_NUMBER;
} else {
$markerType = Zend_Amf_Constants::AMF3_INTEGER;
}
break;
case (is_float($data)):
$markerType = Zend_Amf_Constants::AMF3_NUMBER;
break;
case (is_string($data)):
$markerType = Zend_Amf_Constants::AMF3_STRING;
break;
case (is_array($data)):
$markerType = Zend_Amf_Constants::AMF3_ARRAY;
break;
case (is_object($data)):
// Handle object types.
if (($data instanceof DateTime) || ($data instanceof Zend_Date)) {
$markerType = Zend_Amf_Constants::AMF3_DATE;
} else if ($data instanceof Zend_Amf_Value_ByteArray) {
$markerType = Zend_Amf_Constants::AMF3_BYTEARRAY;
} else {
$markerType = Zend_Amf_Constants::AMF3_OBJECT;
}
break;
default:
require_once 'Zend/Amf/Exception.php';
throw new Zend_Amf_Exception('Unsupported data type: ' . gettype($data));
}
$this->writeTypeMarker($data, $markerType);
}
}
/**
* Write an AMF3 integer
*
* @param int|float $data
* @return Zend_Amf_Parse_Amf3_Serializer
*/
public function writeInteger($int)
{
if (($int & 0xffffff80) == 0) {
$this->_stream->writeByte($int & 0x7f);
return $this;
}
if (($int & 0xffffc000) == 0 ) {
$this->_stream->writeByte(($int >> 7 ) | 0x80);
$this->_stream->writeByte($int & 0x7f);
return $this;
}
if (($int & 0xffe00000) == 0) {
$this->_stream->writeByte(($int >> 14 ) | 0x80);
$this->_stream->writeByte(($int >> 7 ) | 0x80);
$this->_stream->writeByte($int & 0x7f);
return $this;
}
$this->_stream->writeByte(($int >> 22 ) | 0x80);
$this->_stream->writeByte(($int >> 15 ) | 0x80);
$this->_stream->writeByte(($int >> 8 ) | 0x80);
$this->_stream->writeByte($int & 0xff);
return $this;
}
/**
* Send string to output stream
*
* @param string $string
* @return Zend_Amf_Parse_Amf3_Serializer
*/
public function writeString($string)
{
$ref = strlen($string) << 1 | 0x01;
$this->writeInteger($ref);
$this->_stream->writeBytes($string);
return $this;
}
/**
* Convert DateTime/Zend_Date to AMF date
*
* @param DateTime|Zend_Date $date
* @return Zend_Amf_Parse_Amf3_Serializer
*/
public function writeDate($date)
{
if ($date instanceof DateTime) {
$dateString = $date->format('U') * 1000;
} elseif ($date instanceof Zend_Date) {
$dateString = $date->toString('U') * 1000;
} else {
require_once 'Zend/Amf/Exception.php';
throw new Zend_Amf_Exception('Invalid date specified; must be a string DateTime or Zend_Date object');
}
$this->writeInteger(0x01);
// write time to stream minus milliseconds
$this->_stream->writeDouble($dateString);
return $this;
}
/**
* Write a PHP array back to the amf output stream
*
* @param array $array
* @return Zend_Amf_Parse_Amf3_Serializer
*/
public function writeArray(array $array)
{
// have to seperate mixed from numberic keys.
$numeric = array();
$string = array();
foreach ($array as $key => $value) {
if (is_int($key)) {
$numeric[] = $value;
} else {
$string[$key] = $value;
}
}
// write the preamble id of the array
$length = count($numeric);
$id = ($length << 1) | 0x01;
$this->writeInteger($id);
//Write the mixed type array to the output stream
foreach($string as $key => $value) {
$this->writeString($key)
->writeTypeMarker($value);
}
$this->writeString('');
// Write the numeric array to ouput stream
foreach($numeric as $value) {
$this->writeTypeMarker($value);
}
return $this;
}
/**
* Write object to ouput stream
*
* @param mixed $data
* @return Zend_Amf_Parse_Amf3_Serializer
*/
public function writeObject($object)
{
$encoding = Zend_Amf_Constants::ET_PROPLIST;
$className = '';
//Check to see if the object is a typed object and we need to change
switch (true) {
// the return class mapped name back to actionscript class name.
case ($className = Zend_Amf_Parse_TypeLoader::getMappedClassName(get_class($object))):
break;
// Check to see if the user has defined an explicit Action Script type.
case isset($object->_explicitType):
$className = $object->_explicitType;
unset($object->_explicitType);
break;
// Check if user has defined a method for accessing the Action Script type
case method_exists($object, 'getASClassName'):
$className = $object->getASClassName();
break;
// No return class name is set make it a generic object
default:
break;
}
$traitsInfo = Zend_Amf_Constants::AMF3_OBJECT_ENCODING;
$traitsInfo |= $encoding << 2;
try {
switch($encoding) {
case Zend_Amf_Constants::ET_PROPLIST:
$count = 0;
foreach($object as $key => $value) {
$count++;
}
$traitsInfo |= ($count << 4);
// Write the object ID
$this->writeInteger($traitsInfo);
// Write the classname
$this->writeString($className);
// Write the object Key's to the output stream
foreach ($object as $key => $value) {
$this->writeString($key);
}
//Write the object values to the output stream.
foreach ($object as $key => $value) {
$this->writeTypeMarker($value);
}
break;
case Zend_Amf_Constants::ET_EXTERNAL:
require_once 'Zend/Amf/Exception.php';
throw new Zend_Amf_Exception('External Object Encoding not implemented');
break;
default:
require_once 'Zend/Amf/Exception.php';
throw new Zend_Amf_Exception('Unknown Object Encoding type: ' . $encoding);
}
} catch (Exception $e) {
require_once 'Zend/Amf/Exception.php';
throw new Zend_Amf_Exception('Unable to writeObject output: ' . $e->getMessage());
}
return $this;
}
}
Serializer.php 0000604 00000003126 15071530550 0007365 0 ustar 00 <?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Amf
* @subpackage Parse
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
/**
* Base abstract class for all AMF serializers.
*
* @package Zend_Amf
* @subpackage Parse
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
abstract class Zend_Amf_Parse_Serializer
{
/**
* Refrence to the current output stream being constructed
*
* @var string
*/
protected $_stream;
/**
* Constructor
*
* @param Zend_Amf_Parse_OutputStream $stream
* @return void
*/
public function __construct(Zend_Amf_Parse_OutputStream $stream)
{
$this->_stream = $stream;
}
/**
* Find the PHP object type and convert it into an AMF object type
*
* @param mixed $content
* @param int $markerType
* @return void
*/
public abstract function writeTypeMarker($content, $markerType=null);
}
Deserializer.php 0000604 00000004000 15071530550 0007666 0 ustar 00 <?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Amf
* @subpackage Parse
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
/**
* Abstract cass that all deserializer must implement.
*
* Logic for deserialization of the AMF envelop is based on resources supplied
* by Adobe Blaze DS. For and example of deserialization please review the BlazeDS
* source tree.
*
* @see http://opensource.adobe.com/svn/opensource/blazeds/trunk/modules/core/src/java/flex/messaging/io/amf/
* @package Zend_Amf
* @subpackage Parse
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
abstract class Zend_Amf_Parse_Deserializer
{
/**
* The raw string that represents the AMF request.
*
* @var Zend_Amf_Parse_InputStream
*/
protected $_stream;
/**
* Constructor
*
* @param Zend_Amf_Parse_InputStream $stream
* @return void
*/
public function __construct(Zend_Amf_Parse_InputStream $stream)
{
$this->_stream = $stream;
}
/**
* Checks for AMF marker types and calls the appropriate methods
* for deserializing those marker types. Markers are the data type of
* the following value.
*
* @param int $typeMarker
* @return mixed Whatever the data type is of the marker in php
*/
public abstract function readTypeMarker($markerType = null);
}
Amf0/Serializer.php 0000604 00000024475 15071530550 0010162 0 ustar 00 <?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Amf
* @subpackage Parse_Amf0
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
/** Zend_Amf_Parse_Serializer */
require_once 'Zend/Amf/Parse/Serializer.php';
/**
* Serializer php misc types back to there corresponding AMF0 Type Marker.
*
* @uses Zend_Amf_Parse_Serializer
* @package Zend_Amf
* @subpackage Parse_Amf0
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Amf_Parse_Amf0_Serializer extends Zend_Amf_Parse_Serializer
{
/**
* @var string Name of the class to be returned
*/
protected $_className = '';
/**
* Determine type and serialize accordingly
*
* Checks to see if the type was declared and then either
* auto negotiates the type or relies on the user defined markerType to
* serialize the data into amf
*
* @param misc $data
* @param misc $markerType
* @return Zend_Amf_Parse_Amf0_Serializer
* @throws Zend_Amf_Exception for unrecognized types or data
*/
public function writeTypeMarker($data, $markerType = null)
{
if (null !== $markerType) {
// Write the Type Marker to denote the following action script data type
$this->_stream->writeByte($markerType);
switch($markerType) {
case Zend_Amf_Constants::AMF0_NUMBER:
$this->_stream->writeDouble($data);
break;
case Zend_Amf_Constants::AMF0_BOOLEAN:
$this->_stream->writeByte($data);
break;
case Zend_Amf_Constants::AMF0_STRING:
$this->_stream->writeUTF($data);
break;
case Zend_Amf_Constants::AMF0_OBJECT:
$this->writeObject($data);
break;
case Zend_Amf_Constants::AMF0_NULL:
break;
case Zend_Amf_Constants::AMF0_MIXEDARRAY:
// Write length of numeric keys as zero.
$this->_stream->writeLong(0);
$this->writeObject($data);
break;
case Zend_Amf_Constants::AMF0_ARRAY:
$this->writeArray($data);
break;
case Zend_Amf_Constants::AMF0_DATE:
$this->writeDate($data);
break;
case Zend_Amf_Constants::AMF0_LONGSTRING:
$this->_stream->writeLongUTF($data);
break;
case Zend_Amf_Constants::AMF0_TYPEDOBJECT:
$this->writeTypedObject($data);
break;
case Zend_Amf_Constants::AMF0_AMF3:
$this->writeAmf3TypeMarker($data);
break;
default:
require_once 'Zend/Amf/Exception.php';
throw new Zend_Amf_Exception("Unknown Type Marker: " . $markerType);
}
} else {
switch (true) {
case (is_int($data) || is_float($data)):
$markerType = Zend_Amf_Constants::AMF0_NUMBER;
break;
case (is_bool($data)):
$markerType = Zend_Amf_Constants::AMF0_BOOLEAN;
break;
case (is_string($data) && (strlen($data) > 65536)):
$markerType = Zend_Amf_Constants::AMF0_LONGSTRING;
break;
case (is_string($data)):
$markerType = Zend_Amf_Constants::AMF0_STRING;
break;
case (is_object($data)):
if (($data instanceof DateTime) || ($data instanceof Zend_Date)) {
$markerType = Zend_Amf_Constants::AMF0_DATE;
} else {
if($className = $this->getClassName($data)){
//Object is a Typed object set classname
$markerType = Zend_Amf_Constants::AMF0_TYPEDOBJECT;
$this->_className = $className;
} else {
// Object is a generic classname
$markerType = Zend_Amf_Constants::AMF0_OBJECT;
}
break;
}
break;
case (null === $data):
$markerType = Zend_Amf_Constants::AMF0_NULL;
break;
case (is_array($data)):
// check if it is a mixed typed array
foreach (array_keys($data) as $key) {
if (!is_numeric($key)) {
$markerType = Zend_Amf_Constants::AMF0_MIXEDARRAY;
break;
}
}
// Dealing with a standard numeric array
if(!$markerType){
$markerType = Zend_Amf_Constants::AMF0_ARRAY;
break;
}
break;
default:
require_once 'Zend/Amf/Exception.php';
throw new Zend_Amf_Exception('Unsupported data type: ' . gettype($data));
}
$this->writeTypeMarker($data, $markerType);
}
return $this;
}
/**
* Write a php array with string or mixed keys.
*
* @param object $data
* @return Zend_Amf_Parse_Amf0_Serializer
*/
public function writeObject($object)
{
// Loop each element and write the name of the property.
foreach ($object as $key => $value) {
$this->_stream->writeUTF($key);
$this->writeTypeMarker($value);
}
// Write the end object flag
$this->_stream->writeInt(0);
$this->_stream->writeByte(Zend_Amf_Constants::AMF0_OBJECTTERM);
return $this;
}
/**
* Write a standard numeric array to the output stream. If a mixed array
* is encountered call writeTypeMarker with mixed array.
*
* @param array $array
* @return Zend_Amf_Parse_Amf0_Serializer
*/
public function writeArray($array)
{
$length = count($array);
if (!$length < 0) {
// write the length of the array
$this->_stream->writeLong(0);
} else {
// Write the length of the numberic array
$this->_stream->writeLong($length);
for ($i=0; $i<$length; $i++) {
$value = isset($array[$i]) ? $array[$i] : null;
$this->writeTypeMarker($value);
}
}
return $this;
}
/**
* Convert the DateTime into an AMF Date
*
* @param DateTime|Zend_Date $data
* @return Zend_Amf_Parse_Amf0_Serializer
*/
public function writeDate($data)
{
if ($data instanceof DateTime) {
$dateString = $data->format('U');
} elseif ($data instanceof Zend_Date) {
$dateString = $data->toString('U');
} else {
require_once 'Zend/Amf/Exception.php';
throw new Zend_Amf_Exception('Invalid date specified; must be a DateTime or Zend_Date object');
}
$dateString *= 1000;
// Make the conversion and remove milliseconds.
$this->_stream->writeDouble($dateString);
// Flash does not respect timezone but requires it.
$this->_stream->writeInt(0);
return $this;
}
/**
* Write a class mapped object to the output stream.
*
* @param object $data
* @return Zend_Amf_Parse_Amf0_Serializer
*/
public function writeTypedObject($data)
{
$this->_stream->writeUTF($this->_className);
$this->writeObject($data);
return $this;
}
/**
* Encountered and AMF3 Type Marker use AMF3 serializer. Once AMF3 is
* enountered it will not return to AMf0.
*
* @param string $data
* @return Zend_Amf_Parse_Amf0_Serializer
*/
public function writeAmf3TypeMarker($data)
{
require_once 'Zend/Amf/Parse/Amf3/Serializer.php';
$serializer = new Zend_Amf_Parse_Amf3_Serializer($this->_stream);
$serializer->writeTypeMarker($data);
return $this;
}
/**
* Find if the class name is a class mapped name and return the
* respective classname if it is.
*
* @param object $object
* @return false|string $className
*/
protected function getClassName($object)
{
require_once 'Zend/Amf/Parse/TypeLoader.php';
//Check to see if the object is a typed object and we need to change
$className = '';
switch (true) {
// the return class mapped name back to actionscript class name.
case Zend_Amf_Parse_TypeLoader::getMappedClassName(get_class($object)):
$className = Zend_Amf_Parse_TypeLoader::getMappedClassName(get_class($object));
break;
// Check to see if the user has defined an explicit Action Script type.
case isset($object->_explicitType):
$className = $object->_explicitType;
unset($object->_explicitType);
break;
// Check if user has defined a method for accessing the Action Script type
case method_exists($object, 'getASClassName'):
$className = $object->getASClassName();
break;
// No return class name is set make it a generic object
default:
break;
}
if(!$className == '') {
return $className;
} else {
return false;
}
}
}
Amf0/Deserializer.php 0000604 00000022535 15071530550 0010466 0 ustar 00 <?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Amf
* @subpackage Parse_Amf0
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
/** Zend_Amf_Parse_Deserializer */
require_once 'Zend/Amf/Parse/Deserializer.php';
/**
* Read an AMF0 input stream and convert it into PHP data types
*
* @todo Implement Typed Object Class Mapping
* @todo Class could be implmented as Factory Class with each data type it's own class
* @package Zend_Amf
* @subpackage Parse_Amf0
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Amf_Parse_Amf0_Deserializer extends Zend_Amf_Parse_Deserializer
{
/**
* An array of objects used for recursivly deserializing an object.
* @var array
*/
protected $_reference = array();
/**
* If AMF3 serialization occurs, update to AMF0 0x03
*
* @var int
*/
protected $_objectEncoding = Zend_Amf_Constants::AMF0_OBJECT_ENCODING;
/**
* refrence to AMF3 deserializer
*
* @var Zend_Amf_Parse_Amf3_Deserializer
*/
protected $_deserializer = null;
/**
* Read AMF markers and dispatch for deserialization
*
* Checks for AMF marker types and calls the appropriate methods
* for deserializing those marker types. Markers are the data type of
* the following value.
*
* @param integer $typeMarker
* @return mixed whatever the data type is of the marker in php
* @return mixed
* @throws Zend_Amf_Exception for invalid type
*/
public function readTypeMarker($typeMarker = null)
{
if (is_null($typeMarker)) {
$typeMarker = $this->_stream->readByte();
}
switch($typeMarker) {
// number
case Zend_Amf_Constants::AMF0_NUMBER:
return $this->_stream->readDouble();
// boolean
case Zend_Amf_Constants::AMF0_BOOLEAN:
return (boolean) $this->_stream->readByte();
// string
case Zend_Amf_Constants::AMF0_STRING:
return $this->_stream->readUTF();
// object
case Zend_Amf_Constants::AMF0_OBJECT:
return $this->readObject();
// null
case Zend_Amf_Constants::AMF0_NULL:
return null;
// undefined
case Zend_Amf_Constants::AMF0_UNDEFINED:
return null;
// Circular references are returned here
case Zend_Amf_Constants::AMF0_REFERENCE:
return $this->readReference();
// mixed array with numeric and string keys
case Zend_Amf_Constants::AMF0_MIXEDARRAY:
return $this->readMixedArray();
// array
case Zend_Amf_Constants::AMF0_ARRAY:
return $this->readArray();
// date
case Zend_Amf_Constants::AMF0_DATE:
return $this->readDate();
// longString strlen(string) > 2^16
case Zend_Amf_Constants::AMF0_LONGSTRING:
return $this->_stream->readLongUTF();
//internal AS object, not supported
case Zend_Amf_Constants::AMF0_UNSUPPORTED:
return null;
// XML
case Zend_Amf_Constants::AMF0_XML:
return $this->readXmlString();
// typed object ie Custom Class
case Zend_Amf_Constants::AMF0_TYPEDOBJECT:
return $this->readTypedObject();
//AMF3-specific
case Zend_Amf_Constants::AMF0_AMF3:
return $this->readAmf3TypeMarker();
default:
require_once 'Zend/Amf/Exception.php';
throw new Zend_Amf_Exception('Unsupported marker type: ' . $typeMarker);
}
}
/**
* Read AMF objects and convert to PHP objects
*
* Read the name value pair objects form the php message and convert them to
* a php object class.
*
* Called when the marker type is 3.
*
* @param array|null $object
* @return object
*/
public function readObject($object = null)
{
if (is_null($object)) {
$object = array();
}
while (true) {
$key = $this->_stream->readUTF();
$typeMarker = $this->_stream->readByte();
if ($typeMarker != Zend_Amf_Constants::AMF0_OBJECTTERM ){
//Recursivly call readTypeMarker to get the types of properties in the object
$object[$key] = $this->readTypeMarker($typeMarker);
} else {
//encountered AMF object terminator
break;
}
}
$this->_reference[] = $object;
return (object) $object;
}
/**
* Read reference objects
*
* Used to gain access to the private array of refrence objects.
* Called when marker type is 7.
*
* @return object
* @throws Zend_Amf_Exception for invalid reference keys
*/
public function readReference()
{
$key = $this->_stream->readInt();
if (!array_key_exists($key, $this->_reference)) {
require_once 'Zend/Amf/Exception.php';
throw new Zend_Amf_Exception('Invalid reference key: '. $key);
}
return $this->_reference[$key];
}
/**
* Reads an array with numeric and string indexes.
*
* Called when marker type is 8
*
* @todo As of Flash Player 9 there is not support for mixed typed arrays
* so we handle this as an object. With the introduction of vectors
* in Flash Player 10 this may need to be reconsidered.
* @return array
*/
public function readMixedArray()
{
$length = $this->_stream->readLong();
return $this->readObject();
}
/**
* Converts numberically indexed actiosncript arrays into php arrays.
*
* Called when marker type is 10
*
* @return array
*/
public function readArray()
{
$length = $this->_stream->readLong();
$array = array();
while ($length--) {
$array[] = $this->readTypeMarker();
}
return $array;
}
/**
* Convert AS Date to Zend_Date
*
* @return Zend_Date
*/
public function readDate()
{
// get the unix time stamp. Not sure why ActionScript does not use
// milliseconds
$timestamp = floor($this->_stream->readDouble() / 1000);
// The timezone offset is never returned to the server; it is always 0,
// so read and ignore.
$offset = $this->_stream->readInt();
require_once 'Zend/Date.php';
$date = new Zend_Date($timestamp);
return $date;
}
/**
* Convert XML to SimpleXml
* If user wants DomDocument they can use dom_import_simplexml
*
* @return SimpleXml Object
*/
public function readXmlString()
{
$string = $this->_stream->readLongUTF();
return simplexml_load_string($string);
}
/**
* Read Class that is to be mapped to a server class.
*
* Commonly used for Value Objects on the server
*
* @todo implement Typed Class mapping
* @return object
* @throws Zend_Amf_Exception if unable to load type
*/
public function readTypedObject()
{
require_once 'Zend/Amf/Parse/TypeLoader.php';
// get the remote class name
$className = $this->_stream->readUTF();
$loader = Zend_Amf_Parse_TypeLoader::loadType($className);
$returnObject = new $loader();
$properties = get_object_vars($this->readObject());
foreach($properties as $key=>$value) {
if($key) {
$returnObject->$key = $value;
}
}
return $returnObject;
}
/**
* AMF3 data type encountered load AMF3 Deserializer to handle
* type markers.
*
* @return string
*/
public function readAmf3TypeMarker()
{
$deserializer = $this->getDeserializer();
$this->_objectEncoding = Zend_Amf_Constants::AMF3_OBJECT_ENCODING;
return $deserializer->readTypeMarker();
}
/**
* Return the object encoding to check if an AMF3 object
* is going to be return.
*
* @return int
*/
public function getObjectEncoding()
{
return $this->_objectEncoding;
}
/**
* Get deserializer
*
* @return Zend_Amf_Parse_Amf3_Deserializer
*/
public function getDeserializer()
{
if (null === $this->_deserializer) {
require_once 'Zend/Amf/Parse/Amf3/Deserializer.php';
$this->_deserializer = new Zend_Amf_Parse_Amf3_Deserializer($this->_stream);
}
return $this->_deserializer;
}
}