• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

tylernathanreed / jira-client-php / 13634794100

03 Mar 2025 03:19PM UTC coverage: 2.067% (-0.1%) from 2.21%
13634794100

push

github

web-flow
~ Try coveralls action

140 of 6773 relevant lines covered (2.07%)

0.03 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

46.43
/src/Deserializer.php
1
<?php
2

3
namespace Jira\Client;
4

5
use DateTimeImmutable;
6
use InvalidArgumentException;
7
use ReflectionClass;
8
use ReflectionNamedType;
9
use ReflectionProperty;
10

11
class Deserializer
12
{
13
    /**
14
     * @phpstan-template TDto of Dto
15
     * @param ($array is true ? list<array<string,mixed>> : array<string,mixed>) $data
16
     * @param class-string<TDto> $class
17
     * @return ($array is true ? (TDto is PolymorphicDto ? list<Dto> : list<TDto>) : (TDto is PolymorphicDto ? Dto : TDto))
18
     */
19
    public function deserialize(array $data, string $class, bool $array = false)
1✔
20
    {
21
        if ($array) {
1✔
22
            $values = [];
×
23

24
            foreach ($data as $value) {
×
25
                $values[] = self::deserialize($value, $class);
×
26
            }
27

28
            return $values;
×
29
        }
30

31
        if (is_subclass_of($class, PolymorphicDto::class)) {
1✔
32
            $class = $class::discriminateFromData($data);
×
33
        }
34

35
        return $this->from($class, $data);
1✔
36
    }
37

38
    /**
39
     * @phpstan-template T of Dto
40
     * @param class-string<T> $class
41
     * @param array<string,mixed> $data
42
     * @return T
43
     */
44
    public function from(string $class, array $data): Dto
1✔
45
    {
46
        $reflector = new ReflectionClass($class);
1✔
47

48
        $parameters = $reflector->getConstructor()?->getParameters() ?? [];
1✔
49

50
        $args = [];
1✔
51

52
        foreach ($parameters as $parameter) {
1✔
53
            $name = $parameter->getName();
1✔
54
            $key = str_starts_with($name, '_')
1✔
55
                ? substr($name, 1)
×
56
                : $name;
1✔
57

58
            $property = $reflector->getProperty($name);
1✔
59

60
            $value = array_key_exists($key, $data)
1✔
61
                ? $data[$key]
1✔
62
                : (
1✔
63
                    $parameter->isDefaultValueAvailable()
×
64
                    ? $parameter->getDefaultValue()
×
65
                    : null
×
66
                );
1✔
67

68
            $type = $parameter->getType();
1✔
69

70
            if (is_null($value)) {
1✔
71
                $args[] = $value;
×
72
            } elseif (is_null($type)) {
1✔
73
                $args[] = $value;
×
74
            } elseif (! $type instanceof ReflectionNamedType) {
1✔
75
                $args[] = $value;
×
76
            } elseif ($type->getName() === 'array' && is_array($value)) {
1✔
77
                $args[] = $this->fromArray($property, $value);
×
78
            } elseif ($type->getName() === DateTimeImmutable::class && is_string($value)) {
1✔
79
                $args[] = new DateTimeImmutable($value);
×
80
            } elseif (! $type->isBuiltin() && is_subclass_of($type->getName(), Dto::class) && is_array($value)) {
1✔
81
                // @phpstan-ignore argument.type
82
                $args[] = $this->from($type->getName(), $value);
×
83
            } else {
84
                $args[] = $value;
1✔
85
            }
86
        }
87

88
        return $reflector->newInstanceArgs($args);
1✔
89
    }
90

91
    /**
92
     * @param array<mixed,mixed> $array
93
     * @return array<mixed,mixed>
94
     */
95
    protected function fromArray(ReflectionProperty $property, array $array): array
×
96
    {
97
        $doc = $property->getDocComment();
×
98

99
        if (! $doc || ! preg_match('/list<(?<list>[^>]+)>|array<(?<key>[^>]+), ?(?<type>[^>]+)/', $doc, $matches)) {
×
100
            return $array;
×
101
        }
102

103
        $type = $matches['type'] ?? $matches['list'];
×
104

105
        if ($type === 'mixed') {
×
106
            return $array;
×
107
        }
108

109
        if (in_array($type, ['int', 'float', 'string'])) {
×
110
            return array_map(function ($v) use ($type) {
×
111
                settype($v, $type);
×
112
                return $v;
×
113
            }, $array);
×
114
        }
115

116
        if (class_exists($subclass = 'Jira\\Client\\Schema\\' . $type) && is_subclass_of($subclass, Dto::class)) {
×
117
            // @phpstan-ignore argument.type
118
            return $this->deserialize($array, $subclass, array: true);
×
119
        }
120

121
        throw new InvalidArgumentException("Unknown class [{$subclass}].");
×
122
    }
123
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc