/** * 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|array */ public function readTypedObject() { // get the remote class name $className = $this->_stream->readUTF(); $loader = TypeLoader::loadType($className); $returnObject = new $loader(); $properties = get_object_vars($this->readObject()); foreach ($properties as $key => $value) { if ($key) { $returnObject->{$key} = $value; } } if ($returnObject instanceof \ZendAmf\Value\Messaging\ArrayCollection) { $returnObject = get_object_vars($returnObject); } return $returnObject; }
public function testUnknownClassMap() { $class = Parser\TypeLoader::loadType('com.example.vo.Bogus'); $this->assertEquals('stdClass', $class); }
/** * 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|array * @throws \ZendAmf\Parser\Exception\OutOfBoundsException */ public function readObject() { $traitsInfo = $this->readInteger(); $storedObject = ($traitsInfo & 0x1) == 0; $traitsInfo = $traitsInfo >> 1; // Check if the Object is in the stored Objects reference table if ($storedObject) { $ref = $traitsInfo; if (!isset($this->_referenceObjects[$ref])) { throw new OutOfBoundsException('Unknown Object reference: ' . $ref); } $returnObject = $this->_referenceObjects[$ref]; } else { // Check if the Object is in the stored Definitions reference table $storedClass = ($traitsInfo & 0x1) == 0; $traitsInfo = $traitsInfo >> 1; if ($storedClass) { $ref = $traitsInfo; if (!isset($this->_referenceDefinitions[$ref])) { throw new OutOfBoundsException('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 & 0x3; $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 against registered classname maps if ($loader = TypeLoader::loadType($className)) { $returnObject = new $loader(); } else { //user defined typed object throw new OutOfBoundsException('Typed object not found: ' . $className . ' '); } } // Add the Object to the reference table $this->_referenceObjects[] = $returnObject; $properties = array(); // clear value // Check encoding types for additional processing. switch ($encoding) { case 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 Constants::ET_DYNAMIC: // used for Name-value encoding if (!$storedClass) { $this->_referenceDefinitions[] = array('className' => $className, 'encoding' => $encoding, 'propertyNames' => $propertyNames); } // not a reference object read name value properties from byte stream 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 reference to the class. $this->_referenceDefinitions[] = array('className' => $className, 'encoding' => $encoding, 'propertyNames' => $propertyNames); } foreach ($propertyNames as $property) { $properties[$property] = $this->readTypeMarker(); } break; } // Add properties back to the return object. if (!is_array($properties)) { $properties = array(); } foreach ($properties as $key => $value) { if ($key) { $returnObject->{$key} = $value; } } } if ($returnObject instanceof ArrayCollection) { if (isset($returnObject->externalizedData)) { $returnObject = $returnObject->externalizedData; } else { $returnObject = get_object_vars($returnObject); } } return $returnObject; }