Completed
Push — master ( 24f6ce...c3efa2 )
by Guilherme
05:36
created

SystemsRegistryService::getSystemOwners()   C

Complexity

Conditions 7
Paths 16

Size

Total Lines 28
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 18
c 0
b 0
f 0
nc 16
nop 1
dl 0
loc 28
rs 6.7272
1
<?php
2
/**
3
 * This file is part of the login-cidadao project or it's bundles.
4
 *
5
 * (c) Guilherme Donato <guilhermednt on github>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace PROCERGS\LoginCidadao\AccountingBundle\Service;
12
13
use GuzzleHttp\ClientInterface as HttpClientInterface;
14
use GuzzleHttp\Exception\ClientException;
15
use LoginCidadao\OAuthBundle\Model\ClientInterface;
16
use PROCERGS\Generic\Traits\OptionalLoggerAwareTrait;
17
use PROCERGS\LoginCidadao\AccountingBundle\Entity\ProcergsLink;
18
use PROCERGS\LoginCidadao\AccountingBundle\Entity\ProcergsLinkRepository;
19
use Psr\Log\LoggerAwareInterface;
20
21
class SystemsRegistryService implements LoggerAwareInterface
22
{
23
    use OptionalLoggerAwareTrait;
24
25
    /** @var HttpClientInterface */
26
    private $client;
27
28
    /** @var string */
29
    private $apiUri;
30
31
    /** @var array */
32
    private $headers;
33
34
    /** @var array */
35
    private $cache = [];
36
37
    /**
38
     * SystemsRegistryService constructor.
39
     * @param HttpClientInterface $client
40
     * @param array $options
41
     */
42
    public function __construct(HttpClientInterface $client, array $options)
43
    {
44
        $this->client = $client;
45
        $this->apiUri = $options['apiUri'];
46
        $this->headers = [
47
            'organizacao' => $options['organization'],
48
            'matricula' => $options['registration_number'],
49
            'senha' => $options['password'],
50
        ];
51
    }
52
53
    public function getSystemInitials(ClientInterface $client)
54
    {
55
        $this->log('info', "Fetching PROCERGS's system initials for client_id: {$client->getPublicId()}");
56
        $hosts = $this->getHosts($client);
57
58
        $identifiedSystems = [];
59
        $systems = [];
60
        foreach ($hosts as $host) {
61
            foreach (array_column($this->fetchInfo($host), 'sistema') as $system) {
62
                if (array_key_exists($system, $systems)) {
63
                    $systems[$system] += 1;
64
                } else {
65
                    $systems[$system] = 1;
66
                }
67
            }
68
        }
69
        if (count($systems) <= 0) {
70
            return [];
71
        }
72
        asort($systems);
73
        $max = max($systems);
74
        foreach ($systems as $key => $value) {
75
            if ($value === $max) {
76
                $identifiedSystems[] = $key;
77
            }
78
        }
79
80
        return $identifiedSystems;
81
    }
82
83
    public function getSystemOwners(ClientInterface $client)
84
    {
85
        $hosts = $this->getHosts($client);
86
87
        $identifiedOwners = [];
88
        $owners = [];
89
        foreach ($hosts as $host) {
90
            foreach (array_column($this->fetchInfo($host), 'clienteDono') as $owner) {
91
                if (array_key_exists($owner, $owners)) {
92
                    $owners[$owner] += 1;
93
                } else {
94
                    $owners[$owner] = 1;
95
                }
96
            }
97
        }
98
        if (count($owners) <= 0) {
99
            return [];
100
        }
101
        asort($owners);
102
        $max = max($owners);
103
        foreach ($owners as $key => $value) {
104
            if ($value === $max) {
105
                $identifiedOwners[] = $key;
106
            }
107
        }
108
109
        return $identifiedOwners;
110
    }
111
112
    private function fetchInfo($query)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
113
    {
114
        $this->log('info', "Searching for '{$query}'");
115
        $hashKey = hash('sha256', $query);
116
        if (false === array_key_exists($hashKey, $this->cache)) {
117
            $requestUrl = str_replace('{host}', $query, $this->apiUri);
118
119
            $response = null;
120
            try {
121
                $response = $this->client->get($requestUrl, ['headers' => $this->headers]);
122
            } catch (ClientException $e) {
123
                if ($e->getResponse()->getStatusCode() === 404) {
124
                    $response = $e->getResponse();
125
                } else {
126
                    $this->log('info',
127
                        "An exception occurred when trying to fetch PROCERGS's system initials for '{$query}'",
128
                        ['exception' => $e]
129
                    );
130
                    throw $e;
131
                }
132
            }
133
            $this->cache[$hashKey] = $response->json();
134
        }
135
136
        $this->log('info', "Returning cached result for '{$query}'");
137
138
        return $this->cache[$hashKey];
139
    }
140
141
    /**
142
     * @param ClientInterface[] $clients OIDC Clients mapped by ID
143
     * @param ProcergsLinkRepository $repo
144
     * @return ProcergsLink[]
145
     */
146
    public function fetchLinked(array $clients, ProcergsLinkRepository $repo)
147
    {
148
        $result = [];
149
        $linked = $repo->findBy(['client' => $clients]);
150
        foreach ($linked as $link) {
151
            if ($link instanceof ProcergsLink && $link->getSystemType() !== null) {
152
                $result[$link->getClient()->getId()] = $link;
153
            }
154
        }
155
156
        return $result;
157
    }
158
159
    private function getHosts(ClientInterface $client)
160
    {
161
        $urls = array_filter($client->getRedirectUris());
162
        if ($client->getSiteUrl()) {
163
            $urls[] = $client->getSiteUrl();
164
        }
165
        $hosts = array_unique(
166
            array_map(
167
                function ($url) {
168
                    return parse_url($url)['host'];
169
                },
170
                $urls
171
            )
172
        );
173
        if ($client->getSiteUrl()) {
174
            $hosts[] = $client->getSiteUrl();
175
        }
176
177
        return $hosts;
178
    }
179
}
180