Passed
Push — master ( 9447ae...806fc4 )
by Pol
05:53
created

WopiDiscovery::getPublicKey()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 3
ccs 0
cts 2
cp 0
crap 2
rs 10
1
<?php
2
3
/**
4
 * For the full copyright and license information, please view
5
 * the LICENSE file that was distributed with this source code.
6
 */
7
8
declare(strict_types=1);
9
10
namespace ChampsLibres\WopiLib\Discovery;
11
12
use ChampsLibres\WopiLib\Configuration\WopiConfigurationInterface;
13
use Exception;
14
use loophp\psr17\Psr17Interface;
15
use Psr\Http\Client\ClientInterface;
16
use Psr\Http\Message\ResponseInterface;
17
use SimpleXMLElement;
18
19
use const JSON_THROW_ON_ERROR;
20
21
final class WopiDiscovery implements WopiDiscoveryInterface
22
{
23
    private ClientInterface $client;
24
25
    private WopiConfigurationInterface $configuration;
26
27
    private Psr17Interface $psr17;
28
29 5
    public function __construct(
30
        WopiConfigurationInterface $configuration,
31
        ClientInterface $client,
32
        Psr17Interface $psr17
33
    ) {
34 5
        $this->configuration = $configuration;
35 5
        $this->client = $client;
36 5
        $this->psr17 = $psr17;
37 5
    }
38
39 1
    public function discoverExtension(string $extension): array
40
    {
41 1
        $extensions = [];
42
43
        /** @var false|SimpleXMLElement[]|null $apps */
44 1
        $apps = $this->discover()->xpath('//net-zone/app');
45
46 1
        if (false === $apps || null === $apps) {
47
            throw new Exception();
48
        }
49
50 1
        foreach ($apps as $app) {
51
            /** @var false|SimpleXMLElement[]|null $actions */
52 1
            $actions = $app->xpath(sprintf("action[@ext='%s']", $extension));
53
54 1
            if (false === $actions || null === $actions) {
55
                continue;
56
            }
57
58 1
            foreach ($actions as $action) {
59 1
                $actionAttributes = $action->attributes() ?: [];
60
61 1
                $extensions[] = array_merge(
62 1
                    (array) reset($actionAttributes),
63 1
                    ['name' => (string) $app['name']],
64 1
                    ['favIconUrl' => (string) $app['favIconUrl']]
65
                );
66
            }
67
        }
68
69 1
        return $extensions;
70
    }
71
72 1
    public function discoverMimeType(string $mimeType): array
73
    {
74 1
        $mimeTypes = [];
75
76
        /** @var false|SimpleXMLElement[]|null $apps */
77 1
        $apps = $this->discover()->xpath(sprintf("//net-zone/app[@name='%s']", $mimeType));
78
79 1
        if (false === $apps || null === $apps) {
80
            throw new Exception();
81
        }
82
83 1
        foreach ($apps as $app) {
84
            /** @var false|SimpleXMLElement[]|null $actions */
85 1
            $actions = $app->xpath('action');
86
87 1
            if (false === $actions || null === $actions) {
88
                continue;
89
            }
90
91 1
            foreach ($actions as $action) {
92 1
                $actionAttributes = $action->attributes() ?: [];
93
94 1
                $mimeTypes[] = array_merge(
95 1
                    (array) reset($actionAttributes),
96 1
                    ['name' => (string) $app['name']],
97
                );
98
            }
99
        }
100
101 1
        return $mimeTypes;
102
    }
103
104 2
    public function getCapabilities(): array
105
    {
106 2
        $capabilities = $this->discover()->xpath("//net-zone/app[@name='Capabilities']");
107
108 2
        return json_decode(
109 2
            (string) $this->request((string) $capabilities[0]->action['urlsrc'])->getBody(),
110 2
            true,
111 2
            512,
112 2
            JSON_THROW_ON_ERROR
113
        );
114
    }
115
116
    public function getPublicKey(): array
117
    {
118
        return current(current($this->discover()->xpath('//proof-key')));
119
    }
120
121 4
    private function discover(): SimpleXMLElement
122
    {
123 4
        $simpleXmlElement = simplexml_load_string(
124
            (string) $this
125 4
                ->request(
126 4
                    sprintf('%s/%s', $this->configuration['server'], 'hosting/discovery')
127
                )
128 4
                ->getBody()
129
        );
130
131 4
        if (false === $simpleXmlElement) {
132
            // TODO
133
            throw new Exception('Unable to parse XML.');
134
        }
135
136 4
        return $simpleXmlElement;
137
    }
138
139 4
    private function request(string $url): ResponseInterface
140
    {
141
        $response = $this
142 4
            ->client
143 4
            ->sendRequest($this->psr17->createRequest('GET', $url));
144
145 4
        if (200 !== $response->getStatusCode()) {
146
            // TODO
147
            throw new Exception('Invalid status code');
148
        }
149
150 4
        return $response;
151
    }
152
}
153