Passed
Push — master ( 57b2d8...55b64c )
by Raffael
22:23 queued 13s
created

Factory   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 167
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 7

Test Coverage

Coverage 78.43%

Importance

Changes 0
Metric Value
wmc 12
lcom 1
cbo 7
dl 0
loc 167
ccs 40
cts 51
cp 0.7843
rs 10
c 0
b 0
f 0

9 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 8 1
A has() 0 7 1
A getAll() 0 18 2
A getOne() 0 15 2
A deleteOne() 0 6 1
A add() 0 13 2
A update() 0 8 1
A watch() 0 8 1
A build() 0 6 1
1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * tubee
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\Collection;
13
14
use Generator;
15
use MongoDB\BSON\ObjectIdInterface;
16
use MongoDB\Database;
17
use Psr\Log\LoggerInterface;
18
use Tubee\Collection;
19
use Tubee\DataObject\Factory as DataObjectFactory;
20
use Tubee\Endpoint\Factory as EndpointFactory;
21
use Tubee\Resource\Factory as ResourceFactory;
22
use Tubee\ResourceNamespace\ResourceNamespaceInterface;
23
use Tubee\Schema;
24
25
class Factory
26
{
27
    /**
28
     * Collection name.
29
     */
30
    public const COLLECTION_NAME = 'collections';
31
32
    /**
33
     * Database.
34
     *
35
     * @var Database
36
     */
37
    protected $db;
38
39
    /**
40
     * Resource factory.
41
     *
42
     * @var ResourceFactory
43
     */
44
    protected $resource_factory;
45
46
    /**
47
     * Object factory.
48
     *
49
     * @var DataObjectFactory
50
     */
51
    protected $object_factory;
52
53
    /**
54
     * Endpoint.
55
     *
56
     * @var EndpointFactory
57
     */
58
    protected $endpoint_factory;
59
60
    /**
61
     * Logger.
62
     *
63
     * @var LoggerInterface
64
     */
65
    protected $logger;
66
67
    /**
68
     * Initialize.
69
     */
70 10
    public function __construct(Database $db, ResourceFactory $resource_factory, EndpointFactory $endpoint_factory, DataObjectFactory $object_factory, LoggerInterface $logger)
71
    {
72 10
        $this->db = $db;
73 10
        $this->resource_factory = $resource_factory;
74 10
        $this->endpoint_factory = $endpoint_factory;
75 10
        $this->object_factory = $object_factory;
76 10
        $this->logger = $logger;
77 10
    }
78
79
    /**
80
     * Has namespace.
81
     */
82 8
    public function has(ResourceNamespaceInterface $namespace, string $name): bool
83
    {
84 8
        return $this->db->{self::COLLECTION_NAME}->count([
85 8
            'name' => $name,
86 8
            'namespace' => $namespace->getName(),
87 8
        ]) > 0;
88
    }
89
90
    /**
91
     * Get all.
92
     */
93 3
    public function getAll(ResourceNamespaceInterface $namespace, ?array $query = null, ?int $offset = null, ?int $limit = null, ?array $sort = null): Generator
94
    {
95
        $filter = [
96 3
            'namespace' => $namespace->getName(),
97
        ];
98
99 3
        if (!empty($query)) {
100
            $filter = [
101 1
                '$and' => [$filter, $query],
102
            ];
103
        }
104
105 3
        $that = $this;
106
107 3
        return $this->resource_factory->getAllFrom($this->db->{self::COLLECTION_NAME}, $filter, $offset, $limit, $sort, function (array $resource) use ($namespace, $that) {
108 3
            return $that->build($resource, $namespace);
109 3
        });
110
    }
111
112
    /**
113
     * Get one.
114
     */
115 3
    public function getOne(ResourceNamespaceInterface $namespace, string $name): CollectionInterface
116
    {
117 3
        $result = $this->db->{self::COLLECTION_NAME}->findOne([
118 3
            'name' => $name,
119 3
            'namespace' => $namespace->getName(),
120
        ], [
121 3
            'projection' => ['history' => 0],
122
        ]);
123
124 3
        if ($result === null) {
125 2
            throw new Exception\NotFound('collection '.$name.' is not registered');
126
        }
127
128 1
        return $this->build($result, $namespace);
129
    }
130
131
    /**
132
     * Delete by name.
133
     */
134 1
    public function deleteOne(ResourceNamespaceInterface $namespace, string $name): bool
135
    {
136 1
        $resource = $this->getOne($namespace, $name);
137
138
        return $this->resource_factory->deleteFrom($this->db->{self::COLLECTION_NAME}, $resource->getId());
139
    }
140
141
    /**
142
     * Add namespace.
143
     */
144 7
    public function add(ResourceNamespaceInterface $namespace, array $resource): ObjectIdInterface
145
    {
146 7
        $resource['kind'] = 'Collection';
147 7
        $resource = $this->resource_factory->validate($resource);
148
149 7
        if ($this->has($namespace, $resource['name'])) {
150 1
            throw new Exception\NotUnique('collection '.$resource['name'].' does already exists');
151
        }
152
153 7
        $resource['namespace'] = $namespace->getName();
154
155 7
        return $this->resource_factory->addTo($this->db->{self::COLLECTION_NAME}, $resource);
156
    }
157
158
    /**
159
     * Update.
160
     */
161
    public function update(CollectionInterface $resource, array $data): bool
162
    {
163
        $data['name'] = $resource->getName();
164
        $data['kind'] = 'Collection';
165
        $data = $this->resource_factory->validate($data);
166
167
        return $this->resource_factory->updateIn($this->db->{self::COLLECTION_NAME}, $resource, $data);
168
    }
169
170
    /**
171
     * Change stream.
172
     */
173
    public function watch(ResourceNamespaceInterface $namespace, ?ObjectIdInterface $after = null, bool $existing = true, ?array $query = null, ?int $offset = null, ?int $limit = null, ?array $sort = null): Generator
174
    {
175
        $that = $this;
176
177
        return $this->resource_factory->watchFrom($this->db->{self::COLLECTION_NAME}, $after, $existing, $query, function (array $resource) use ($namespace, $that) {
178
            return $that->build($resource, $namespace);
179
        }, $offset, $limit, $sort);
180
    }
181
182
    /**
183
     * Build instance.
184
     */
185 4
    public function build(array $resource, ResourceNamespaceInterface $namespace): CollectionInterface
186
    {
187 4
        $schema = new Schema($resource['data']['schema'], $this->logger);
188
189 4
        return $this->resource_factory->initResource(new Collection($resource['name'], $namespace, $this->endpoint_factory, $this->object_factory, $schema, $this->logger, $resource));
190
    }
191
}
192