Token::addServiceCatalog()   B
last analyzed

Complexity

Conditions 6
Paths 8

Size

Total Lines 23
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 6

Importance

Changes 0
Metric Value
dl 0
loc 23
ccs 15
cts 15
cp 1
rs 8.5906
c 0
b 0
f 0
cc 6
eloc 11
nc 8
nop 3
crap 6
1
<?php
2
3
namespace TreeHouse\Keystone\Client\Model;
4
5
use TreeHouse\Keystone\Client\Exception\TokenException;
6
7
class Token implements \JsonSerializable
8
{
9
    /**
10
     * @var string
11
     */
12
    protected $id;
13
14
    /**
15
     * @var \DateTime
16
     */
17
    protected $expires;
18
19
    /**
20
     * @var array
21
     */
22
    protected $catalogs;
23
24
    /**
25
     * @param string    $id
26
     * @param \DateTime $expires
27
     */
28 30
    public function __construct($id, \DateTime $expires)
29
    {
30 30
        $this->id = $id;
31 30
        $this->expires = $expires;
32 30
        $this->catalogs = [];
33 30
    }
34
35
    /**
36
     * @return string
37
     */
38 12
    public function getId()
39
    {
40 12
        return $this->id;
41
    }
42
43
    /**
44
     * Adds a service catalog, using the array output of a token-call.
45
     *
46
     * @param string $type      The service type
47
     * @param string $name      The service name
48
     * @param array  $endpoints Array of endpoints
49
     */
50 22
    public function addServiceCatalog($type, $name, array $endpoints)
51
    {
52 22
        if (!array_key_exists($type, $this->catalogs)) {
53 22
            $this->catalogs[$type] = [];
54 22
        }
55
56
        // check if endpoints config is correct
57 22
        foreach ($endpoints as $index => $endpoint) {
58 22
            if (!is_array($endpoint)) {
59 1
                throw new TokenException('Expecting an array for an endpoint');
60
            }
61
62 21
            $endpoints[$index] = array_change_key_case($endpoint, CASE_LOWER);
63
64 21
            if (!isset($endpoints[$index]['publicurl']) && !isset($endpoints[$index]['adminurl'])) {
65 1
                throw new TokenException(
66 1
                    sprintf('An endpoint must have either a "publicurl" or "adminurl" key, got %s', json_encode($endpoint))
67 1
                );
68
            }
69 20
        }
70
71 20
        $this->catalogs[$type][$name] = $endpoints;
72 20
    }
73
74
    /**
75
     * @param string $type
76
     * @param string $name
77
     *
78
     * @throws TokenException
79
     *
80
     * @return array
81
     */
82 14
    public function getServiceCatalog($type, $name = null)
83
    {
84 14
        if (!array_key_exists($type, $this->catalogs) || empty($this->catalogs[$type])) {
85 1
            throw new TokenException(sprintf('There is no catalog for "%s"', $type));
86
        }
87
88 13
        $catalogs = $this->catalogs[$type];
89
90 13
        if (is_null($name)) {
91 11
            return reset($catalogs);
92
        }
93
94 3
        if (!array_key_exists($name, $catalogs)) {
95 1
            throw new TokenException(sprintf('There is no service named "%s" for catalog "%s"', $name, $type));
96
        }
97
98 2
        return $catalogs[$name];
99
    }
100
101
    /**
102
     * @return \DateTime
103
     */
104 13
    public function getExpirationDate()
105
    {
106 13
        return $this->expires;
107
    }
108
109
    /**
110
     * @return bool
111
     */
112 7
    public function isExpired()
113
    {
114 7
        return new \DateTime() >= $this->getExpirationDate();
115
    }
116
117
    /**
118
     * Factory method to use with Keystone token responses, or a json_encoded Token instance.
119
     *
120
     * @param array $content
121
     *
122
     * @throws TokenException
123
     *
124
     * @return static
125
     */
126 21
    public static function create(array $content)
127
    {
128 21
        $access = static::arrayGet($content, 'access');
129 20
        $token = static::arrayGet($access, 'token');
130 19
        $tokenid = static::arrayGet($token, 'id');
131 19
        $expires = static::arrayGet($token, 'expires');
132
133
        try {
134 18
            $expireDate = new \DateTime($expires);
135 18
        } catch (\Exception $e) {
136 1
            throw new TokenException(sprintf('Invalid expiration date: %s', $e->getMessage()), null, $e);
137
        }
138
139 17
        $token = new static($tokenid, $expireDate);
140
141 17
        $catalogs = static::arrayGet($access, 'serviceCatalog');
142 16
        if (is_array($catalogs)) {
143 16
            foreach ($catalogs as $catalog) {
144 15
                $type = static::arrayGet($catalog, 'type');
145 13
                $name = static::arrayGet($catalog, 'name');
146 12
                $endpoints = static::arrayGet($catalog, 'endpoints');
147
148 12
                if (!is_array($endpoints)) {
149 2
                    throw new TokenException(sprintf('Invalid endpoints: %s', json_encode($endpoints)));
150
                }
151
152 10
                $token->addServiceCatalog($type, $name, $endpoints);
153 9
            }
154 9
        }
155
156 9
        return $token;
157
    }
158
159
    /**
160
     * @inheritdoc
161
     */
162 8
    public function jsonSerialize()
163
    {
164
        $response = [
165
            'access' => [
166
                'token' => [
167 8
                    'id' => $this->id,
168 8
                    'expires' => $this->expires->format(DATE_ISO8601),
169 8
                ],
170 8
                'serviceCatalog' => [],
171 8
            ],
172 8
        ];
173
174 8
        foreach ($this->catalogs as $type => $catalogs) {
175 8
            foreach ($catalogs as $name => $endpoints) {
176 8
                $response['access']['serviceCatalog'][] = [
177 8
                    'name' => $name,
178 8
                    'type' => $type,
179 8
                    'endpoints' => $endpoints,
180
                ];
181 8
            }
182 8
        }
183
184 8
        return $response;
185
    }
186
187
    /**
188
     * @param array  $array
189
     * @param string $key
190
     *
191
     * @return mixed
192
     */
193 21
    protected static function arrayGet(array $array, $key)
194
    {
195 21
        $key = strtolower($key);
196 21
        $array = array_change_key_case($array, CASE_LOWER);
197
198 21
        if (!array_key_exists($key, $array)) {
199 7
            throw new TokenException(
200 7
                sprintf('Did not find key %s in array: %s', json_encode($key), json_encode($array))
201 7
            );
202
        }
203
204 20
        return $array[$key];
205
    }
206
}
207