GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — 3.x ( 550ea0...801b7b )
by Jindřich
24s queued 12s
created

WebService::parseOutput()   C

Complexity

Conditions 9
Paths 7

Size

Total Lines 104

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 9.5338

Importance

Changes 0
Metric Value
cc 9
nc 7
nop 2
dl 0
loc 104
ccs 13
cts 16
cp 0.8125
crap 9.5338
rs 6.4444
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
declare(strict_types = 1);
3
4
namespace Skaut\Skautis\Wsdl;
5
6
use Psr\EventDispatcher\EventDispatcherInterface;
7
use Skaut\Skautis\InvalidArgumentException;
8
use Skaut\Skautis\Wsdl\Event\RequestFailEvent;
9
use Skaut\Skautis\Wsdl\Event\RequestPostEvent;
10
use Skaut\Skautis\Wsdl\Event\RequestPreEvent;
11
use SoapClient;
12
use stdClass;
13
use Throwable;
14
15
/**
16
 * @author Hána František <[email protected]>
17
 */
18
class WebService implements WebServiceInterface
19
{
20
21
    /**
22
     * základní údaje volané při každém požadavku
23
     * ID_Application, ID_Login
24
     *
25
     * @var array<string, mixed>
26
     */
27
    protected $init;
28
29
    /**
30
     * @var SoapClient
31
     */
32
    protected $soapClient;
33
34
    /**
35
     * @var EventDispatcherInterface|null
36
     */
37
    private $eventDispatcher;
38
39
    /**
40
     * @param array<string, mixed> $soapOpts Nastaveni SOAP requestu
41
     * @throws InvalidArgumentException pokud je odkaz na WSDL soubor prázdný
42
     */
43 6
    public function __construct(
44
      SoapClient $soapClient,
45
      array $soapOpts,
46
      ?EventDispatcherInterface $eventDispatcher
47
    ) {
48 6
        $this->init = $soapOpts;
49 6
        $this->soapClient = $soapClient;
50 6
        $this->eventDispatcher = $eventDispatcher;
51 6
    }
52
53
    /**
54
     * @inheritdoc
55
     */
56 5
    public function call(string $functionName, array $arguments = [])
57
    {
58 5
        return $this->soapCall($functionName, $arguments);
59
    }
60
61
62
    /**
63
     * @inheritdoc
64
     */
65 5
    public function __call(string $functionName, array $arguments)
66
    {
67 5
        return $this->call($functionName, $arguments);
68
    }
69
70
    /**
71
     * Metoda provadejici SOAP pozadavek na servery Skautisu
72
     *
73
     * @see http://php.net/manual/en/soapclient.soapcall.php
74
     *
75
     * @param string $functionName Nazev akce k provedeni na WebService
76
     * @param array<int|string, mixed> $arguments ([0]=args [1]=cover)
77
     * @param array<string, mixed> $options Nastaveni
78
     * @param array<int, string> $inputHeaders Hlavicky pouzite pri odesilani
79
     * @param array<int, string> $outputHeaders Hlavicky ktere prijdou s odpovedi
80
     * @return array<int|string, mixed>|stdClass|null
0 ignored issues
show
Documentation introduced by
The doc-type array<int|string, could not be parsed: Expected ">" at position 7, but found "end of type". (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
81
     */
82 5
    protected function soapCall(
83
      string $functionName,
84
      array $arguments,
85
      array $options = [],
86
      array $inputHeaders = [],
87
      array &$outputHeaders = []
88
    ) {
89 5
        $fname = ucfirst($functionName);
90 5
        $args = $this->prepareArgs($fname, $arguments);
91
92 5
        if ($this->eventDispatcher !== null) {
93 1
            $event = new RequestPreEvent($fname, $args, $options, $inputHeaders, debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS));
94 1
            $this->eventDispatcher->dispatch($event);
0 ignored issues
show
Documentation introduced by
$event is of type object<Skaut\Skautis\Wsdl\Event\RequestPreEvent>, but the function expects a object<Psr\EventDispatcher\object>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
95
        }
96
97 5
        $requestStart = microtime(true);
98
        try {
99 5
            $soapResponse = $this->soapClient->__soapCall($fname, $args, $options, $inputHeaders, $outputHeaders);
100 4
            $soapResponse = $this->parseOutput($fname, $soapResponse);
101
102 4
            if ($this->eventDispatcher !== null) {
103
                $duration = microtime(true) - $requestStart;
104
                $event = new RequestPostEvent($fname, $args, $soapResponse, $duration);
105
                $this->eventDispatcher->dispatch($event);
0 ignored issues
show
Documentation introduced by
$event is of type object<Skaut\Skautis\Wsdl\Event\RequestPostEvent>, but the function expects a object<Psr\EventDispatcher\object>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
106
            }
107
108 4
            return $soapResponse;
109 1
        } catch (Throwable $t) {
110
111 1
            if ($this->eventDispatcher !== null) {
112 1
              $duration = microtime(true) - $requestStart;
113 1
              $event = new RequestFailEvent($fname, $args, $t, $duration);
114 1
              $this->eventDispatcher->dispatch($event);
0 ignored issues
show
Documentation introduced by
$event is of type object<Skaut\Skautis\Wsdl\Event\RequestFailEvent>, but the function expects a object<Psr\EventDispatcher\object>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
115
            }
116
117 1
            throw $this->convertToSkautisException($t);
118
        }
119
    }
120
121
    /**
122
     * Z defaultnich parametru a parametru callu vytvori argumenty pro SoapClient::__soapCall
123
     *
124
     * @param string $functionName Jmeno funkce volane pres SOAP
125
     * @param array<int|string, mixed> $arguments Argumenty k mergnuti s defaultnimy
126
     *
127
     * @return array<int, mixed> Argumenty pro SoapClient::__soapCall
0 ignored issues
show
Documentation introduced by
The doc-type array<int, could not be parsed: Expected ">" at position 5, but found "end of type". (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
128
     */
129 5
    protected function prepareArgs(string $functionName, array $arguments): array
130
    {
131 5
        if (!isset($arguments[0]) || !is_array($arguments[0])) {
132 1
            $arguments[0] = [];
133
        }
134
135
        //k argumentum připoji vlastni informace o aplikaci a uzivateli
136 5
        $args = array_merge($this->init, $arguments[0]);
137
138 5
        if (!isset($arguments[1])) {
139 5
            $functionName = lcfirst($functionName);
140 5
            $args = [[$functionName . 'Input' => $args]];
141 5
            return $args;
142
        }
143
144
        //pokud je zadan druhy parametr tak lze prejmenovat obal dat
145
        $matches = explode('/', $arguments[1]);
146
        //pole se budou vytvaret zevnitr ven
147
        $matches = array_reverse($matches);
148
149
        $matches[] = 0; //zakladni obal 0=>...
150
151
        foreach ($matches as $value) {
152
            $args = [$value => $args];
153
        }
154
155
        return $args;
156
    }
157
158
    /**
159
     * Parsuje output ze SoapClient do jednotného formátu
160
     *
161
     * @param string $fname Jméno funkce volané přes SOAP
162
     * @param mixed $ret    Odpoveď ze SoapClient::__soapCall
163
     *
164
     * @return array<int|string, mixed>|\stdClass|null
0 ignored issues
show
Documentation introduced by
The doc-type array<int|string, could not be parsed: Expected ">" at position 7, but found "end of type". (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
165
     */
166 4
    protected function parseOutput(string $fname, $ret)
167
    {
168
169
        /*
170
            Pokud se jedna o request ktery ma vracet jednu hodnotu a ta existuje, skautis vraci primo objekt odpovedi
171
                Napriklad:
172
                <UnitDetailResponse xmlns="https://is.skaut.cz/">
173
                    <UnitDetailResult>
174
                        data jednoho objektu
175
                    </UnitDetailResult>
176
                </UnitDetailResponse>
177
178
            To SoapClient naparsuje jako:
179
                class stdClass#25 (1) {
180
                    public $UnitDetailResult =>
181
                        class stdClass#26 (48) {
182
                            data objectu
183
                        }
184
                }
185
186
187
188
            Pokud se jedna o request ktery ma vracet jednu hodnotu a ta neexistuje, skautis vraci jeden self-closing tag
189
            Napriklad:
190
                <UnitDetailResponse xmlns="https://is.skaut.cz/" />
191
192
            To SoapClient naparsuje jako:
193
                class stdClass#25 (0) {
194
                }
195
196
            Pokud se jedna o request ktery ma vracet vice hodnot, vraci *Result/*Output
197
            Napriklad:
198
                <UnitAllResponse xmlns="https://is.skaut.cz/">
199
                    <UnitAllResult>
200
                        <UnitAllOutput>
201
                            data jednoho objektu
202
                        </UnitAllOutput>
203
                        <UnitAllOutput>
204
                            data dalsiho objektu
205
                        </UnitAllOutput>
206
                    </UnitAllResult>
207
                </UnitAllResponse>
208
209
            To SoapClient naparsuje jako:
210
                class stdClass#25 (1) {
211
                    public $UnitAllResult =>
212
                        class stdClass#26 (1) {
213
                            public $UnitAllOutput =>
214
                                array(2) {
215
                                    stdClass - data jednoho objektu,
216
                                    stdClass - data dalsiho objektu,
217
                                }
218
                        }
219
                    }
220
                }
221
222
            Pokud se jedna o request ktery ma vracet vice hodnot, vraci klasickou dvojici tagu
223
            Napriklad:
224
                <UnitAllResponse xmlns="https://is.skaut.cz/">
225
                    <UnitAllResult />
226
                </UnitAllResponse>
227
228
            To SoapClient naparsuje jako:
229
                class stdClass#25 (1) {
230
                    public $UnitAllResult =>
231
                        class stdClass#26 (0) {
232
                        }
233
                }
234
235
        */
236
237 4
        if (!$ret) {
238
            throw new ParsingFailedException('Unexpected output from Skautis');
239
        }
240
241
        // Pokud byl vracen prazdny objekt predstavujici neexistujici vec
242 4
        if ($ret instanceof stdClass && count((array) $ret) === 0) {
243 1
            return null;
244
        }
245
246
        // Pokud obsahuje *Result pak se  bud jedna o existujici jeden objekt, vice objektu nebo prazdny seznam objektu
247 3
        $result = $ret->{$fname . 'Result'} ?? null;
248 3
        if (!isset($result)) {
249
            throw new ParsingFailedException('Unexpected output from Skautis');
250
        }
251
252 3
        $output = $result->{$fname . 'Output'} ?? null;
253
        // Pokud obsahuje *Result, ale zadny *Output pak se jedna o jeden
254 3
        if (!isset($output)) {
255
            // Vraci prazdny object
256 2
            if ($result instanceof stdClass && count((array) $result) === 0) {
257 1
                return [];
258
            }
259
260 1
            return $result;
261
        }
262
263
        // Vraci pouze jednu hodnotu misto pole?
264 1
        if ($output instanceof stdClass) {
265
            return [$output];
266
        }
267
268 1
        return $output; //vraci pole se stdClass
269
    }
270
271 1
    private function convertToSkautisException(Throwable $e): WsdlException
272
    {
273 1
      if (preg_match('/Uživatel byl odhlášen/ui', $e->getMessage())) {
274
        return new AuthenticationException($e->getMessage(), $e->getCode(), $e);
275
      }
276
277 1
      if (preg_match('/Nemáte oprávnění/ui', $e->getMessage())) {
278
        return new PermissionException($e->getMessage(), $e->getCode(), $e);
279
      }
280
281 1
      return new WsdlException($e->getMessage(), $e->getCode(), $e);
282
    }
283
}
284