Completed
Push — master ( abe227...316baf )
by Raffael
13:55 queued 08:01
created

Json::__construct()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
dl 0
loc 8
ccs 0
cts 5
cp 0
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 8
crap 6

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * tubee.io
7
 *
8
 * @copyright   Copryright (c) 2017-2019 gyselroth GmbH (https://gyselroth.com)
9
 * @license     GPL-3.0 https://opensource.org/licenses/GPL-3.0
10
 */
11
12
namespace Tubee\Endpoint;
13
14
use Generator;
15
use Psr\Log\LoggerInterface;
16
use Tubee\AttributeMap\AttributeMapInterface;
17
use Tubee\Collection\CollectionInterface;
18
use Tubee\Endpoint\Json\Exception as JsonException;
19
use Tubee\EndpointObject\EndpointObjectInterface;
20
use Tubee\Storage\StorageInterface;
21
use Tubee\Workflow\Factory as WorkflowFactory;
22
23
class Json extends AbstractFile
24
{
25
    /**
26
     * Kind.
27
     */
28
    public const KIND = 'JsonEndpoint';
29
30
    /**
31
     * Init endpoint.
32
     */
33
    public function __construct(string $name, string $type, string $file, StorageInterface $storage, CollectionInterface $collection, WorkflowFactory $workflow, LoggerInterface $logger, array $resource = [])
34
    {
35
        if ($type === EndpointInterface::TYPE_DESTINATION) {
36
            $this->flush = true;
37
        }
38
39
        parent::__construct($name, $type, $file, $storage, $collection, $workflow, $logger, $resource);
40
    }
41
42
    /**
43
     * {@inheritdoc}
44
     */
45
    public function setup(bool $simulate = false): EndpointInterface
46
    {
47
        if ($this->type === EndpointInterface::TYPE_DESTINATION) {
48
            $streams = [$this->file => $this->storage->openWriteStream($this->file)];
49
        } else {
50
            $streams = $this->storage->openReadStreams($this->file);
51
        }
52
53
        foreach ($streams as $path => $stream) {
54
            $content = [];
55
            if ($this->type === EndpointInterface::TYPE_SOURCE) {
56
                $content = json_decode(stream_get_contents($stream), true);
57
58
                if ($err = json_last_error() !== JSON_ERROR_NONE) {
59
                    throw new JsonException\InvalidJson('failed decode json '.$this->file.', json error '.$err);
60
                }
61
62
                if (!is_array($content)) {
63
                    throw new JsonException\ArrayExpected('json file contents must be an array');
64
                }
65
            }
66
67
            $this->files[] = [
68
                'stream' => $stream,
69
                'content' => $content,
70
                'path' => $path,
71
            ];
72
        }
73
74
        return $this;
75
    }
76
77
    /**
78
     * {@inheritdoc}
79
     */
80
    public function shutdown(bool $simulate = false): EndpointInterface
81
    {
82
        foreach ($this->files as $resource) {
83
            if ($simulate === false && $this->type === EndpointInterface::TYPE_DESTINATION) {
84
                $json = json_encode($resource['content'], JSON_PRETTY_PRINT);
85
86
                if (fwrite($resource['stream'], $json) === false) {
87
                    throw new Exception\WriteOperationFailed('failed create json file '.$resource['path']);
88
                }
89
90
                $this->storage->syncWriteStream($resource['stream'], $resource['path']);
91
            }
92
93
            fclose($resource['stream']);
94
        }
95
96
        $this->files = [];
97
98
        return $this;
99
    }
100
101
    /**
102
     * {@inheritdoc}
103
     */
104
    public function transformQuery(?array $query = null)
105
    {
106
        $result = null;
107
        if ($this->filter_all !== null) {
108
            $result = json_decode(stripslashes($this->filter_all), true);
109
        }
110
111
        if (!empty($query)) {
112
            if ($this->filter_all === null) {
113
                $result = json_decode($query, true);
114
            } else {
115
                $result = array_merge($result, $query);
116
            }
117
        }
118
119
        return $result;
120
    }
121
122
    /**
123
     * {@inheritdoc}
124
     */
125
    public function getAll(?array $query = null): Generator
126
    {
127
        $filter = $this->transformQuery($query);
128
        $i = 0;
129
130
        foreach ($this->files as $resource_key => $json) {
131
            foreach ($json['content'] as $object) {
132
                if (!is_array($object)) {
133
                    throw new JsonException\ArrayExpected('json must contain an array of objects');
134
                }
135
136
                if (count(array_intersect_assoc($object, $filter)) !== count($filter)) {
137
                    $this->logger->debug('json object does not match filter [{filter}], skip it', [
138
                        'category' => get_class($this),
139
                        'filter' => $filter,
140
                    ]);
141
142
                    continue;
143
                }
144
145
                yield $this->build($object);
146
                ++$i;
147
            }
148
        }
149
150
        return $i;
151
    }
152
153
    /**
154
     * {@inheritdoc}
155
     */
156
    public function create(AttributeMapInterface $map, array $object, bool $simulate = false): ?string
157
    {
158
        foreach ($this->files as $resource_key => $xml) {
159
            $this->files[$resource_key]['content'][] = $object;
160
161
            $this->logger->debug('create new json object on endpoint ['.$this->name.'] with values [{values}]', [
162
                'category' => get_class($this),
163
                'values' => $object,
164
            ]);
165
        }
166
167
        return null;
168
    }
169
170
    /**
171
     * {@inheritdoc}
172
     */
173
    public function getDiff(AttributeMapInterface $map, array $diff): array
174
    {
175
        throw new Exception\UnsupportedEndpointOperation('endpoint '.get_class($this).' does not support getDiff(), use flush=true');
176
    }
177
178
    /**
179
     * {@inheritdoc}
180
     */
181
    public function change(AttributeMapInterface $map, array $diff, array $object, array $endpoint_object, bool $simulate = false): ?string
182
    {
183
        throw new Exception\UnsupportedEndpointOperation('endpoint '.get_class($this).' does not support change(), use flush=true');
184
    }
185
186
    /**
187
     * {@inheritdoc}
188
     */
189
    public function delete(AttributeMapInterface $map, array $object, array $endpoint_object, bool $simulate = false): bool
190
    {
191
        throw new Exception\UnsupportedEndpointOperation('endpoint '.get_class($this).' does not support delete(), use flush=true');
192
    }
193
194
    /**
195
     * {@inheritdoc}
196
     */
197
    public function getOne(array $object, array $attributes = []): EndpointObjectInterface
198
    {
199
        $elements = [];
200
        $filter = json_decode($this->getFilterOne($object), true);
201
202
        foreach ($this->files as $json) {
203
            if (isset($json['content'])) {
204
                foreach ($json['content'] as $object) {
205
                    if (!is_array($object)) {
206
                        throw new JsonException\ArrayExpected('json must contain an array of objects');
207
                    }
208
209
                    if (count(array_intersect_assoc($object, $filter)) !== count($filter)) {
210
                        continue;
211
                    }
212
                    $elements[] = $object;
213
                }
214
            }
215
216
            if (count($elements) > 1) {
217
                throw new Exception\ObjectMultipleFound('found more than one object with filter '.json_encode($filter));
218
            }
219
            if (count($elements) === 0) {
220
                throw new Exception\ObjectNotFound('no object found with filter '.json_encode($filter));
221
            }
222
223
            return $this->build(array_shift($elements));
224
        }
225
    }
226
}
227