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

AbstractEndpoint::getKind()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 0
cts 2
cp 0
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
crap 2
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 InvalidArgumentException;
16
use Psr\Http\Message\ServerRequestInterface;
17
use Psr\Log\LoggerInterface;
18
use Tubee\Collection\CollectionInterface;
19
use Tubee\EndpointObject;
20
use Tubee\EndpointObject\EndpointObjectInterface;
21
use Tubee\Helper;
22
use Tubee\Resource\AbstractResource;
23
use Tubee\Resource\AttributeResolver;
24
use Tubee\Workflow\Factory as WorkflowFactory;
25
use Tubee\Workflow\WorkflowInterface;
26
27
abstract class AbstractEndpoint extends AbstractResource implements EndpointInterface
28
{
29
    /**
30
     * Kind.
31
     */
32
    public const KIND = 'Endpoint';
33
34
    /**
35
     * Endpoint name.
36
     *
37
     * @var string
38
     */
39
    protected $name;
40
41
    /**
42
     * CollectionInterface.
43
     *
44
     * @var CollectionInterface
45
     */
46
    protected $collection;
47
48
    /**
49
     * Logger.
50
     *
51
     * @var LoggerInterface
52
     */
53
    protected $logger;
54
55
    /**
56
     * Filter All.
57
     *
58
     * @var string
59
     */
60
    protected $filter_all;
61
62
    /**
63
     * Filter One.
64
     *
65
     * @var string
66
     */
67
    protected $filter_one;
68
69
    /**
70
     * Import.
71
     *
72
     * @var array
73
     */
74
    protected $import = [];
75
76
    /**
77
     * Type.
78
     *
79
     * @var string
80
     */
81
    protected $type;
82
83
    /**
84
     * Flush.
85
     *
86
     * @var bool
87
     */
88
    protected $flush = false;
89
90
    /**
91
     * Workflow factory.
92
     *
93
     * @var WorkflowFactory
94
     */
95
    protected $workflow_factory;
96
97
    /**
98
     * Endpoint object identifiers.
99
     *
100
     * @var string
101
     */
102
    protected $identifier;
103
104
    /**
105
     * Init endpoint.
106
     */
107 58
    public function __construct(string $name, string $type, CollectionInterface $collection, WorkflowFactory $workflow_factory, LoggerInterface $logger, array $resource = [])
108
    {
109 58
        $this->name = $name;
110 58
        $this->type = $type;
111 58
        $this->resource = $resource;
112 58
        $this->collection = $collection;
113 58
        $this->logger = $logger;
114 58
        $this->workflow_factory = $workflow_factory;
115
116 58
        if (isset($resource['data']['options'])) {
117 9
            $this->setOptions($resource['data']['options']);
118
        }
119 58
    }
120
121
    /**
122
     * {@inheritdoc}
123
     */
124
    public function setup(bool $simulate = false): EndpointInterface
125
    {
126
        return $this;
127
    }
128
129
    /**
130
     * {@inheritdoc}
131
     */
132
    public function getKind(): string
133
    {
134
        return $this->resource['kind'];
135
    }
136
137
    /**
138
     * Set options.
139
     */
140 9
    public function setOptions(?array $config = null): EndpointInterface
141
    {
142 9
        if ($config === null) {
143
            return $this;
144
        }
145
146 9
        foreach ($config as $option => $value) {
147 9
            switch ($option) {
148 9
                case 'flush':
149 9
                case 'import':
150 9
                case 'identifier':
151 9
                case 'filter_one':
152 2
                case 'filter_all':
153 9
                    $this->{$option} = $value;
154
155 9
                break;
156
                default:
157 9
                    throw new InvalidArgumentException('unknown option '.$option.' given');
158
            }
159
        }
160
161 9
        return $this;
162
    }
163
164
    /**
165
     * {@inheritdoc}
166
     */
167
    public function decorate(ServerRequestInterface $request): array
168
    {
169
        $collection = $this->collection->getName();
170
        $namespace = $this->collection->getResourceNamespace()->getName();
171
172
        $resource = [
173
            '_links' => [
174
                'namespace' => ['href' => (string) $request->getUri()->withPath('/api/v1/namespaces/'.$namespace)],
175
                'collection' => ['href' => (string) $request->getUri()->withPath('/api/v1/namespaces/'.$namespace.'/collections/'.$collection)],
176
           ],
177
            'kind' => static::KIND,
178
            'namespace' => $namespace,
179
            'collection' => $collection,
180
            'data' => $this->getData(),
181
            'status' => function ($endpoint) {
182
                try {
183
                    $endpoint->setup();
184
185
                    return [
186
                        'available' => true,
187
                    ];
188
                } catch (\Exception $e) {
189
                    return [
190
                        'available' => false,
191
                        'exception' => get_class($e),
192
                        'error' => $e->getMessage(),
193
                        'code' => $e->getCode(),
194
                    ];
195
                }
196
            },
197
        ];
198
199
        return AttributeResolver::resolve($request, $this, $resource);
200
    }
201
202
    /**
203
     * {@inheritdoc}
204
     */
205
    public function shutdown(bool $simulate = false): EndpointInterface
206
    {
207
        return $this;
208
    }
209
210
    /**
211
     * {@inheritdoc}
212
     */
213
    public function flushRequired(): bool
214
    {
215
        return $this->flush;
216
    }
217
218
    /**
219
     * {@inheritdoc}
220
     */
221
    public function flush(bool $simulate = false): bool
222
    {
223
        return true;
224
    }
225
226
    /**
227
     * {@inheritdoc}
228
     */
229
    public function getCollection(): CollectionInterface
230
    {
231
        return $this->collection;
232
    }
233
234
    /**
235
     * {@inheritdoc}
236
     */
237
    public function getResourceIdentifier(): array
238
    {
239
        return $this->identifier;
240
    }
241
242
    /**
243
     * {@inheritdoc}
244
     */
245
    public function getImport(): array
246
    {
247
        return $this->import;
248
    }
249
250
    /**
251
     * {@inheritdoc}
252
     */
253 3
    public function exists(array $object): bool
254
    {
255
        try {
256 3
            $this->getOne($object, []);
257
258 1
            return true;
259 2
        } catch (Exception\ObjectMultipleFound $e) {
260 1
            return true;
261 1
        } catch (\Exception $e) {
262 1
            return false;
263
        }
264
    }
265
266
    /**
267
     * {@inheritdoc}
268
     */
269
    public function hasWorkflow(string $name): bool
270
    {
271
        return $this->workflow_factory->has($this, $name);
272
    }
273
274
    /**
275
     * {@inheritdoc}
276
     */
277
    public function getWorkflow(string $name): WorkflowInterface
278
    {
279
        return $this->workflow_factory->getOne($this, $name);
280
    }
281
282
    /**
283
     * {@inheritdoc}
284
     */
285
    public function getWorkflows(array $workflows = [], ?int $offset = null, ?int $limit = null): Generator
286
    {
287
        return $this->workflow_factory->getAll($this, $workflows, $offset, $limit, [
288
            'priority' => 1,
289
        ]);
290
    }
291
292
    /**
293
     * {@inheritdoc}
294
     */
295
    public function getType(): string
296
    {
297
        return $this->type;
298
    }
299
300
    /**
301
     * {@inheritdoc}
302
     */
303 22
    public function getIdentifier(): string
304
    {
305 22
        return $this->collection->getIdentifier().'::'.$this->name;
306
    }
307
308
    /**
309
     * {@inheritdoc}
310
     */
311 7
    public function getFilterOne(array $object)
312
    {
313 7
        return $this->parseAttribute($this->filter_one, $object);
314
    }
315
316
    /**
317
     * {@inheritdoc}
318
     */
319 2
    public function getFilterAll()
320
    {
321 2
        return $this->filter_all;
322
    }
323
324
    /**
325
     * Build endpoint object.
326
     */
327 2
    protected function build(array $object): EndpointObjectInterface
328
    {
329 2
        return new EndpointObject(['data' => $object], $this);
330
    }
331
332
    /**
333
     * Parse and replace string with attribute values.
334
     */
335
    private function parseAttribute(string $string, array $data): string
336
    {
337 7
        return preg_replace_callback('/(\{(([^\}\"]*)+)\})(\}?)/', function ($match) use ($string, $data) {
338
            if (substr($match[0], 0, 2) === '{{' && $match[4][0] === '}') {
339
                return $match[2].$match[4];
340
            }
341
342
            $attribute = $match[2];
343
344
            try {
345
                return Helper::getArrayValue($data, $attribute);
346
            } catch (\Exception $e) {
347
                throw new Exception\AttributeNotResolvable('could not resolve attribute '.$attribute.' in value '.$string);
348
            }
349 7
        }, $string);
350
    }
351
}
352