* @license http://www.apache.org/licenses/LICENSE-2.0 * @link http://phpsx.org */ class Dumper { /** @var \Doctrine\Common\Annotations\Reader */ protected $reader; /** @var ResolverInterface */ protected $resolver; /** * @param \Doctrine\Common\Annotations\Reader $reader */ public function __construct(Reader $reader = null) { if ($reader === null) { $reader = new SimpleAnnotationReader(); $reader->addNamespace('PSX\\Schema\\Annotation'); } $this->reader = $reader; $this->resolver = Popo::createDefaultResolver(); } /** * @param object $object * @return mixed */ public function dump($data) { if (is_iterable($data)) { return $this->dumpIterable($data); } elseif ($data instanceof \DateTime) { return DateTime::fromDateTime($data)->toString(); } elseif ($data instanceof \DateInterval) { return Duration::fromDateInterval($data)->toString(); } elseif (is_object($data)) { return $this->dumpObject($data, get_class($data)); } elseif (is_resource($data)) { return stream_get_contents($data, -1, 0); } else { return $data; } } private function dumpObject($data, string $class) { $type = $this->resolver->resolveClass(new \ReflectionClass($class)); if ($type instanceof StructType) { return $this->dumpStruct($data); } elseif ($type instanceof MapType) { return $this->dumpMap($data, $type); } else { throw new ParserException('Could not determine object type'); } } private function dumpStruct($data): RecordInterface { if (!is_object($data)) { throw new ParserException('Struct must be an object'); } $reflection = new \ReflectionClass(get_class($data)); $result = new Record($reflection->getShortName()); $properties = ObjectReader::getProperties($this->reader, $reflection); foreach ($properties as $name => $property) { $getters = [ 'get' . ucfirst($property->getName()), 'is' . ucfirst($property->getName()) ]; foreach ($getters as $getter) { if ($reflection->hasMethod($getter)) { $value = $reflection->getMethod($getter)->invoke($data); $type = $this->resolver->resolveProperty($property); if ($type instanceof TypeInterface) { $value = $this->dumpValue($value, $type); } if ($value !== null) { $result->setProperty($name, $value); } break; } } } return $result; } private function dumpMap($data, MapType $type): RecordInterface { if (!$data instanceof \Traversable) { throw new ParserException('Map must be traversable'); } $reflection = new \ReflectionClass(get_class($data)); $result = new Record($reflection->getShortName()); foreach ($data as $key => $value) { $result->setProperty($key, $this->dumpValue($value, $type->getAdditionalProperties())); } return $result; } private function dumpArray($data, ArrayType $type): array { if (!is_iterable($data)) { throw new ParserException('Array must be iterable'); } $result = []; foreach ($data as $index => $value) { $result[] = $this->dumpValue($value, $type->getItems()); } return $result; } private function dumpValue($value, TypeInterface $type) { if ($value === null) { return null; } if ($type instanceof StructType) { return $this->dumpStruct($value); } elseif ($type instanceof MapType) { return $this->dumpMap($value, $type); } elseif ($type instanceof ArrayType) { return $this->dumpArray($value, $type); } elseif ($type instanceof BooleanType) { return (bool) $value; } elseif ($type instanceof IntegerType) { return (int) $value; } elseif ($type instanceof NumberType) { return (float) $value; } elseif ($type instanceof StringType) { $format = $type->getFormat(); if ($format === TypeAbstract::FORMAT_BINARY && is_resource($value)) { return base64_encode(stream_get_contents($value, -1, 0)); } elseif ($format === TypeAbstract::FORMAT_DATETIME && $value instanceof \DateTime) { return DateTime::fromDateTime($value)->toString(); } elseif ($format === TypeAbstract::FORMAT_DATE && $value instanceof \DateTime) { return Date::fromDateTime($value)->toString(); } elseif ($format === TypeAbstract::FORMAT_TIME && $value instanceof \DateTime) { return Time::fromDateTime($value)->toString(); } elseif ($format === TypeAbstract::FORMAT_DURATION && $value instanceof \DateInterval) { return Duration::fromDateInterval($value)->toString(); } else { return (string) $value; } } elseif ($type instanceof IntersectionType) { return $this->dump($value); } elseif ($type instanceof UnionType) { return $this->dump($value); } elseif ($type instanceof ReferenceType) { return $this->dumpReference($value, $type); } elseif ($type instanceof AnyType) { return $value; } return null; } private function dumpReference($data, ReferenceType $type) { return $this->dumpObject($data, $type->getRef()); } private function dumpIterable(iterable $data) { $values = []; foreach ($data as $key => $value) { $values[$key] = $this->dump($value); } if (isset($values[0])) { return array_values($values); } else { return Record::fromArray($values); } } } __halt_compiler();----SIGNATURE:----Z07yHZtrtEQPBuzpYFSUSsbk5gTs/Xux3W2GE2BXQdMYKs2d5uXL1E7IT4gYYVcMlu26s4wBp7Mxi450dh76po7yfqAQNw2FzVpzv1VzArCPAEAex7pA9xqk3cs2092BN3LpPWshENPOUU8hgcXmOPvdK1pzyi4z9wVWh0s33ocmPviF+cdFt/lBRIorTIh8BZkH+rMM7SOAFyVpPn3uEYBtKfQbiojpTGMOYmiN2hyh4qQuVbpyjTW+iwc/KCXf7Ddo2axOs28HFnjHtcwGd0YNEpEnLLFy+fkss4HToaaCAwZKOVQfbMqYisQbckV2KWGtxTX7uL9sPO8oL1nA4fWp2mwuER7UAdZRbyqUAjdu7GGZnrYYiYwOF2VtnqRG6b+F14eoWOLBmPAuiCkTAM3bEKnfnewfVeZbdjhMllYshil+HrIzyrvAQ79QkT3VVWni6xxStzLyhNQ9bmGYVm/qMYj7UVbXmkgLGg5rP8ddyu9mmKRw8kA8n5sAHPdo+RM/zFLxZ83URlzIM2zq6qbMKAmvb3+uPe+OXUOtRXYvh876fxQlT5nL5G6NWlGTWjjlOCwqIMGiXjfUDp26ZRjtHwOwzNa/5KFR5AomPMHGn5UmX+Yqa36SaMZzU0SzyhN8107pCdIN6vMiPkOxuR1ZbevQ4rmVcScqxq2vUR8=----ATTACHMENT:----Mzg3MDc5Mzk3MzI5MTQ4MiA3MTU4NTY2NDQ4NzQyMjU2IDc5MTI5NzgyOTI3NjU1NjI=