Passed
Push — master ( 9a9435...d1ff45 )
by Pol
04:12 queued 02:46
created

MockSoapClient::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 6
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 6
b 0
f 0
nc 1
nop 1
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace loophp\MockSoapClient;
6
7
use ArrayIterator;
8
use InfiniteIterator;
9
use SoapClient;
10
use SoapFault;
11
use SoapHeader;
12
13
use function array_key_exists;
14
use function func_get_args;
15
use function is_callable;
16
17
use const ARRAY_FILTER_USE_KEY;
18
19
class MockSoapClient extends SoapClient
20
{
21
    /**
22
     * @var array<int|string, InfiniteIterator>
23
     */
24
    private $iterators;
25
26
    /**
27
     * MockSoapClient constructor.
28
     *
29
     * @param mixed $responses
30
     */
31 7
    public function __construct($responses)
32
    {
33 7
        $this->iterators = $this->buildIterators((array) $responses);
34 7
    }
35
36
    /**
37
     * @param string $function_name
38
     * @param array<mixed> $arguments
39
     *
40
     * @throws SoapFault
41
     *
42
     * @return mixed
43
     */
44 3
    public function __call($function_name, $arguments = [])
45
    {
46
        try {
47 3
            $response = $this->__soapCall($function_name, $arguments);
48 1
        } catch (SoapFault $exception) {
49 1
            throw $exception;
50
        }
51
52 2
        return $response;
53
    }
54
55
    /**
56
     * @param string $function_name
57
     * @param array<mixed> $arguments
58
     * @param array<mixed>|null $options
59
     * @param array<mixed>|SoapHeader|null $input_headers
60
     * @param array<mixed>|null $output_headers
61
     *
62
     * @throws SoapFault
63
     *
64
     * @return mixed
65
     */
66 6
    public function __soapCall(
67
        $function_name,
68
        $arguments,
69
        $options = null,
70
        $input_headers = null,
71
        &$output_headers = null
72
    ) {
73 6
        $iterator = true === array_key_exists($function_name, $this->iterators) ?
74 1
            $this->iterators[$function_name] :
75 6
            $this->iterators['*'];
76
77 6
        $response = $iterator->current();
78 6
        $iterator->next();
79
80 6
        if ($response instanceof SoapFault) {
81 1
            throw $response;
82
        }
83
84 5
        return true === is_callable($response) ?
85 4
            ($response)(...func_get_args()) :
86 5
            $response;
87
    }
88
89
    /**
90
     * Build a simple Infinite iterator.
91
     *
92
     * @param array<mixed> $data
93
     */
94 7
    private function buildIterator(array $data): InfiniteIterator
95
    {
96 7
        $iterator = new InfiniteIterator(new ArrayIterator($data));
97 7
        $iterator->rewind();
98
99 7
        return $iterator;
100
    }
101
102
    /**
103
     * Build the structure of iterators.
104
     *
105
     * @param array<callable|mixed> $data
106
     *
107
     * @return array<int|string, InfiniteIterator>
108
     */
109 7
    private function buildIterators(array $data): array
110
    {
111 7
        return array_reduce(
112 7
            array_keys($data),
113
            /**
114
             * @param int|string $key
115
             *
116
             * @return array<int|string, InfiniteIterator>
117
             */
118
            function (array $iterators, $key) use ($data): array {
119 7
                if (false === is_numeric($key)) {
120 1
                    $iterators[$key] = $this->buildIterator((array) $data[$key]);
121
                }
122
123 7
                return $iterators;
124 7
            },
125
            [
126 7
                '*' => $this->buildIterator(array_filter($data, 'is_numeric', ARRAY_FILTER_USE_KEY)),
127
            ]
128
        );
129
    }
130
}
131