PageRenderTime 69ms CodeModel.GetById 37ms RepoModel.GetById 0ms app.codeStats 0ms

/library/Zend/Amf/Parse/Amf0/Serializer.php

https://bitbucket.org/brunoMaurice/youfood
PHP | 346 lines | 206 code | 21 blank | 119 comment | 36 complexity | f9f4c0b15f8d154187d11bd628f77231 MD5 | raw file
  1. <?php
  2. /**
  3. * Zend Framework
  4. *
  5. * LICENSE
  6. *
  7. * This source file is subject to the new BSD license that is bundled
  8. * with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://framework.zend.com/license/new-bsd
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@zend.com so we can send you a copy immediately.
  14. *
  15. * @category Zend
  16. * @package Zend_Amf
  17. * @subpackage Parse_Amf0
  18. * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
  19. * @license http://framework.zend.com/license/new-bsd New BSD License
  20. * @version $Id: Serializer.php 16971 2009-07-22 18:05:45Z mikaelkael $
  21. */
  22. /** Zend_Amf_Parse_Serializer */
  23. require_once 'Zend/Amf/Parse/Serializer.php';
  24. /**
  25. * Serializer php misc types back to there corresponding AMF0 Type Marker.
  26. *
  27. * @uses Zend_Amf_Parse_Serializer
  28. * @package Zend_Amf
  29. * @subpackage Parse_Amf0
  30. * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
  31. * @license http://framework.zend.com/license/new-bsd New BSD License
  32. */
  33. class Zend_Amf_Parse_Amf0_Serializer extends Zend_Amf_Parse_Serializer
  34. {
  35. /**
  36. * @var string Name of the class to be returned
  37. */
  38. protected $_className = '';
  39. /**
  40. * An array of reference objects
  41. * @var array
  42. */
  43. protected $_referenceObjects = array();
  44. /**
  45. * Determine type and serialize accordingly
  46. *
  47. * Checks to see if the type was declared and then either
  48. * auto negotiates the type or relies on the user defined markerType to
  49. * serialize the data into amf
  50. *
  51. * @param misc $data
  52. * @param misc $markerType
  53. * @return Zend_Amf_Parse_Amf0_Serializer
  54. * @throws Zend_Amf_Exception for unrecognized types or data
  55. */
  56. public function writeTypeMarker($data, $markerType = null)
  57. {
  58. if (null !== $markerType) {
  59. //try to refrence the given object
  60. if( !$this->writeObjectReference($data, $markerType) ) {
  61. // Write the Type Marker to denote the following action script data type
  62. $this->_stream->writeByte($markerType);
  63. switch($markerType) {
  64. case Zend_Amf_Constants::AMF0_NUMBER:
  65. $this->_stream->writeDouble($data);
  66. break;
  67. case Zend_Amf_Constants::AMF0_BOOLEAN:
  68. $this->_stream->writeByte($data);
  69. break;
  70. case Zend_Amf_Constants::AMF0_STRING:
  71. $this->_stream->writeUTF($data);
  72. break;
  73. case Zend_Amf_Constants::AMF0_OBJECT:
  74. $this->writeObject($data);
  75. break;
  76. case Zend_Amf_Constants::AMF0_NULL:
  77. break;
  78. case Zend_Amf_Constants::AMF0_REFERENCE:
  79. $this->_stream->writeInt($data);
  80. break;
  81. case Zend_Amf_Constants::AMF0_MIXEDARRAY:
  82. // Write length of numeric keys as zero.
  83. $this->_stream->writeLong(0);
  84. $this->writeObject($data);
  85. break;
  86. case Zend_Amf_Constants::AMF0_ARRAY:
  87. $this->writeArray($data);
  88. break;
  89. case Zend_Amf_Constants::AMF0_DATE:
  90. $this->writeDate($data);
  91. break;
  92. case Zend_Amf_Constants::AMF0_LONGSTRING:
  93. $this->_stream->writeLongUTF($data);
  94. break;
  95. case Zend_Amf_Constants::AMF0_TYPEDOBJECT:
  96. $this->writeTypedObject($data);
  97. break;
  98. case Zend_Amf_Constants::AMF0_AMF3:
  99. $this->writeAmf3TypeMarker($data);
  100. break;
  101. default:
  102. require_once 'Zend/Amf/Exception.php';
  103. throw new Zend_Amf_Exception("Unknown Type Marker: " . $markerType);
  104. }
  105. }
  106. } else {
  107. if(is_resource($data)) {
  108. $data = Zend_Amf_Parse_TypeLoader::handleResource($data);
  109. }
  110. switch (true) {
  111. case (is_int($data) || is_float($data)):
  112. $markerType = Zend_Amf_Constants::AMF0_NUMBER;
  113. break;
  114. case (is_bool($data)):
  115. $markerType = Zend_Amf_Constants::AMF0_BOOLEAN;
  116. break;
  117. case (is_string($data) && (strlen($data) > 65536)):
  118. $markerType = Zend_Amf_Constants::AMF0_LONGSTRING;
  119. break;
  120. case (is_string($data)):
  121. $markerType = Zend_Amf_Constants::AMF0_STRING;
  122. break;
  123. case (is_object($data)):
  124. if (($data instanceof DateTime) || ($data instanceof Zend_Date)) {
  125. $markerType = Zend_Amf_Constants::AMF0_DATE;
  126. } else {
  127. if($className = $this->getClassName($data)){
  128. //Object is a Typed object set classname
  129. $markerType = Zend_Amf_Constants::AMF0_TYPEDOBJECT;
  130. $this->_className = $className;
  131. } else {
  132. // Object is a generic classname
  133. $markerType = Zend_Amf_Constants::AMF0_OBJECT;
  134. }
  135. break;
  136. }
  137. break;
  138. case (null === $data):
  139. $markerType = Zend_Amf_Constants::AMF0_NULL;
  140. break;
  141. case (is_array($data)):
  142. // check if it is an associative array
  143. $i = 0;
  144. foreach (array_keys($data) as $key) {
  145. // check if it contains non-integer keys
  146. if (!is_numeric($key) || intval($key) != $key) {
  147. $markerType = Zend_Amf_Constants::AMF0_OBJECT;
  148. break;
  149. // check if it is a sparse indexed array
  150. } else if ($key != $i) {
  151. $markerType = Zend_Amf_Constants::AMF0_MIXEDARRAY;
  152. break;
  153. }
  154. $i++;
  155. }
  156. // Dealing with a standard numeric array
  157. if(!$markerType){
  158. $markerType = Zend_Amf_Constants::AMF0_ARRAY;
  159. break;
  160. }
  161. break;
  162. default:
  163. require_once 'Zend/Amf/Exception.php';
  164. throw new Zend_Amf_Exception('Unsupported data type: ' . gettype($data));
  165. }
  166. $this->writeTypeMarker($data, $markerType);
  167. }
  168. return $this;
  169. }
  170. /**
  171. * Check if the given object is in the reference table, write the reference if it exists,
  172. * otherwise add the object to the reference table
  173. *
  174. * @param mixed $object object to check for reference
  175. * @param $markerType AMF type of the object to write
  176. * @return Boolean true, if the reference was written, false otherwise
  177. */
  178. protected function writeObjectReference($object, $markerType){
  179. if( $markerType == Zend_Amf_Constants::AMF0_OBJECT ||
  180. $markerType == Zend_Amf_Constants::AMF0_MIXEDARRAY ||
  181. $markerType == Zend_Amf_Constants::AMF0_ARRAY ||
  182. $markerType == Zend_Amf_Constants::AMF0_TYPEDOBJECT ) {
  183. $ref = array_search($object, $this->_referenceObjects,true);
  184. //handle object reference
  185. if($ref !== false){
  186. $this->writeTypeMarker($ref,Zend_Amf_Constants::AMF0_REFERENCE);
  187. return true;
  188. }
  189. $this->_referenceObjects[] = $object;
  190. }
  191. return false;
  192. }
  193. /**
  194. * Write a php array with string or mixed keys.
  195. *
  196. * @param object $data
  197. * @return Zend_Amf_Parse_Amf0_Serializer
  198. */
  199. public function writeObject($object)
  200. {
  201. // Loop each element and write the name of the property.
  202. foreach ($object as $key => $value) {
  203. // skip variables starting with an _ provate transient
  204. if( $key[0] == "_") continue;
  205. $this->_stream->writeUTF($key);
  206. $this->writeTypeMarker($value);
  207. }
  208. // Write the end object flag
  209. $this->_stream->writeInt(0);
  210. $this->_stream->writeByte(Zend_Amf_Constants::AMF0_OBJECTTERM);
  211. return $this;
  212. }
  213. /**
  214. * Write a standard numeric array to the output stream. If a mixed array
  215. * is encountered call writeTypeMarker with mixed array.
  216. *
  217. * @param array $array
  218. * @return Zend_Amf_Parse_Amf0_Serializer
  219. */
  220. public function writeArray($array)
  221. {
  222. $length = count($array);
  223. if (!$length < 0) {
  224. // write the length of the array
  225. $this->_stream->writeLong(0);
  226. } else {
  227. // Write the length of the numberic array
  228. $this->_stream->writeLong($length);
  229. for ($i=0; $i<$length; $i++) {
  230. $value = isset($array[$i]) ? $array[$i] : null;
  231. $this->writeTypeMarker($value);
  232. }
  233. }
  234. return $this;
  235. }
  236. /**
  237. * Convert the DateTime into an AMF Date
  238. *
  239. * @param DateTime|Zend_Date $data
  240. * @return Zend_Amf_Parse_Amf0_Serializer
  241. */
  242. public function writeDate($data)
  243. {
  244. if ($data instanceof DateTime) {
  245. $dateString = $data->format('U');
  246. } elseif ($data instanceof Zend_Date) {
  247. $dateString = $data->toString('U');
  248. } else {
  249. require_once 'Zend/Amf/Exception.php';
  250. throw new Zend_Amf_Exception('Invalid date specified; must be a DateTime or Zend_Date object');
  251. }
  252. $dateString *= 1000;
  253. // Make the conversion and remove milliseconds.
  254. $this->_stream->writeDouble($dateString);
  255. // Flash does not respect timezone but requires it.
  256. $this->_stream->writeInt(0);
  257. return $this;
  258. }
  259. /**
  260. * Write a class mapped object to the output stream.
  261. *
  262. * @param object $data
  263. * @return Zend_Amf_Parse_Amf0_Serializer
  264. */
  265. public function writeTypedObject($data)
  266. {
  267. $this->_stream->writeUTF($this->_className);
  268. $this->writeObject($data);
  269. return $this;
  270. }
  271. /**
  272. * Encountered and AMF3 Type Marker use AMF3 serializer. Once AMF3 is
  273. * enountered it will not return to AMf0.
  274. *
  275. * @param string $data
  276. * @return Zend_Amf_Parse_Amf0_Serializer
  277. */
  278. public function writeAmf3TypeMarker($data)
  279. {
  280. require_once 'Zend/Amf/Parse/Amf3/Serializer.php';
  281. $serializer = new Zend_Amf_Parse_Amf3_Serializer($this->_stream);
  282. $serializer->writeTypeMarker($data);
  283. return $this;
  284. }
  285. /**
  286. * Find if the class name is a class mapped name and return the
  287. * respective classname if it is.
  288. *
  289. * @param object $object
  290. * @return false|string $className
  291. */
  292. protected function getClassName($object)
  293. {
  294. require_once 'Zend/Amf/Parse/TypeLoader.php';
  295. //Check to see if the object is a typed object and we need to change
  296. $className = '';
  297. switch (true) {
  298. // the return class mapped name back to actionscript class name.
  299. case Zend_Amf_Parse_TypeLoader::getMappedClassName(get_class($object)):
  300. $className = Zend_Amf_Parse_TypeLoader::getMappedClassName(get_class($object));
  301. break;
  302. // Check to see if the user has defined an explicit Action Script type.
  303. case isset($object->_explicitType):
  304. $className = $object->_explicitType;
  305. break;
  306. // Check if user has defined a method for accessing the Action Script type
  307. case method_exists($object, 'getASClassName'):
  308. $className = $object->getASClassName();
  309. break;
  310. // No return class name is set make it a generic object
  311. case ($object instanceof stdClass):
  312. $className = '';
  313. break;
  314. // By default, use object's class name
  315. default:
  316. $className = get_class($object);
  317. break;
  318. }
  319. if(!$className == '') {
  320. return $className;
  321. } else {
  322. return false;
  323. }
  324. }
  325. }