* @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:----qV8CTXeQ7vhrCa0Qw5qYQufE6DY32AS1r7enNZhwQsjy37bF8K2VZUAgBY599dqMHRvEn6ufCccne/6nKRcxw1Z1XQr9cBbtGA7EVeBtL3HX8TjOfg0ICzSaCEOedQJqeDBpTR+FomDFFu9aofWolY5R5olbXNQg0IFHijZCuauArbfXPPQGdhuLStm6ANXRmJGCKDt9oMDgqYhSQkCosH0asoB6D4vOYMSWbeCiOELEFkw0i4MrqhPkLH7XolX2a7D2TOF0dxFTmBnkvFAs6XXo1kXTevwxMz29exHCAGvF1JBV82FFQeNKXFxzMyB+TgF/BL6yTxXkkXYaLrqbQASdLgpvSApqfobZN0WAUUacNDa7pVP9BoE2Hp4fRZOU5sDIWs72eJCKiEMbcgUSgImhmRU5uRgm3SfBWAiP9xoXFD9WhpCWsMTkYPcv+MB1CZ3lLfuBDi5iv3MZ4zN/rnxK1+n/PZVf/CZxsAZgpmrm3gCzRygRvswvhlMDj4ZVWBU7xKAV264vAWAiZjRAHpTvXm40S773iKqw6EcYF2/jNdTU41MHzFNjw0xgiyCr94t1Lv272LNm9FFRw0OcTQGDyCfXhJY4vJwSlOodP2tRZu73pA8DcoQBOK29F6ecdNV9zlwJLYeh7TprwN251DUOqMG852fXgAfkq9i88Q4=----ATTACHMENT:----ODkxNjc5MDYwMzEzNTk3OCA1NzQyNzE4NzA1MjE5Mzc1IDgzNjkwMjM3MjIwMDgxNjA=