Completed
Branch dev (d5d70c)
by Raffael
11:00
created

Converter::getSupportedFormats()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * balloon
7
 *
8
 * @copyright   Copryright (c) 2012-2018 gyselroth GmbH (https://gyselroth.com)
9
 * @license     GPL-3.0 https://opensource.org/licenses/GPL-3.0
10
 */
11
12
namespace Balloon\App\Convert;
13
14
use Balloon\Converter as FileConverter;
15
use Balloon\Exception\NotFound;
16
use Balloon\Filesystem\Node\File;
17
use Balloon\Filesystem\Node\NodeInterface;
18
use Balloon\Server;
19
use MongoDB\BSON\ObjectId;
20
use MongoDB\Database;
21
use Psr\Log\LoggerInterface;
22
use TaskScheduler\Async;
23
24
class Converter
25
{
26
    /**
27
     * Converter.
28
     *
29
     * @var FileConverter
30
     */
31
    protected $converter;
32
33
    /**
34
     * Async.
35
     *
36
     * @var Async
37
     */
38
    protected $async;
39
40
    /**
41
     * Server.
42
     *
43
     * @var Server
44
     */
45
    protected $server;
46
47
    /**
48
     * Collection name.
49
     *
50
     * @var string
51
     */
52
    protected $collection_name = 'convert';
53
54
    /**
55
     * Database.
56
     *
57
     * @var Database
58
     */
59
    protected $db;
60
61
    /**
62
     * Logger.
63
     *
64
     * @var LoggerInterface
65
     */
66
    protected $logger;
67
68
    /**
69
     * Constructor.
70
     *
71
     * @param Database      $db
72
     * @param Server        $server
73
     * @param FileConverter $converter
74
     * @param Async         $async
75
     * @param LoggerInterface   logger
76
     */
77
    public function __construct(Database $db, Server $server, FileConverter $converter, Async $async, LoggerInterface $logger)
78
    {
79
        $this->server = $server;
80
        $this->db = $db;
81
        $this->converter = $converter;
82
        $this->async = $async;
83
        $this->logger = $logger;
84
    }
85
86
    /**
87
     * Get Supported formats.
88
     *
89
     * @param File $node
90
     *
91
     * @return array
92
     */
93
    public function getSupportedFormats(File $node): array
94
    {
95
        return $this->converter->getSupportedFormats($node);
96
    }
97
98
    /**
99
     * Get slaves.
100
     *
101
     * @param File $node
102
     *
103
     * @return iterable
104
     */
105
    public function getSlaves(File $node): Iterable
106
    {
107
        return $this->db->{$this->collection_name}->find([
108
            'master' => $node->getId(),
109
        ]);
110
    }
111
112
    /**
113
     * Get slave.
114
     *
115
     * @param ObjectId $id
116
     *
117
     * @return array
118
     */
119
    public function getSlave(ObjectId $id): array
120
    {
121
        $result = $this->db->{$this->collection_name}->findOne([
122
            '_id' => $id,
123
        ]);
124
125
        if ($result === null) {
126
            throw new Exception('slave not found', Exception::SLAVE_NOT_FOUND);
127
        }
128
129
        return $result;
130
    }
131
132
    /**
133
     * Add slave.
134
     *
135
     * @param File   $node
136
     * @param string $format
137
     *
138
     * @return ObjectId
139
     */
140
    public function addSlave(File $node, string $format): ObjectId
141
    {
142
        $supported = $this->converter->getSupportedFormats($node);
143
        if (!in_array($format, $supported)) {
144
            throw new Exception('format '.$format.' is not available for file');
145
        }
146
147
        $result = $this->db->{$this->collection_name}->insertOne([
148
            'master' => $node->getId(),
149
            'format' => $format,
150
        ]);
151
152
        return $result->getInsertedId();
153
    }
154
155
    /**
156
     * Delete slave.
157
     *
158
     * @param ObjectId $slave
159
     * @param bool     $node
160
     *
161
     * @return bool
162
     */
163
    public function deleteSlave(ObjectId $slave, bool $node = false): bool
164
    {
165
        $slave = $this->getSlave($slave);
166
167
        $result = $this->db->{$this->collection_name}->deleteOne([
168
            '_id' => $slave,
169
        ]);
170
171
        if (true === $node && isset($slave['slave'])) {
172
            $this->server->getFilesystem()->getNodeById($slave['slave'], File::class)->delete();
0 ignored issues
show
Bug introduced by
The method getNodeById() does not exist on Balloon\Filesystem. Did you maybe mean getNode()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
173
        }
174
175
        return $result->isAcknowledged();
176
    }
177
178
    /**
179
     * Convert master to slaves.
180
     *
181
     * @param ObjectId $slave
182
     * @param File     $master
183
     *
184
     * @return bool
185
     */
186
    public function convert(ObjectId $slave, File $master): bool
187
    {
188
        $this->logger->info('create slave for master node ['.$master->getId().']', [
189
            'category' => get_class($this),
190
        ]);
191
192
        $slave = $this->getSlave($slave);
193
        $result = $this->converter->convert($master, $slave['format']);
194
        $master->setFilesystem($this->server->getUserById($master->getOwner())->getFilesystem());
195
196
        try {
197
            if (isset($slave['slave'])) {
198
                $slave = $master->getFilesystem()->findNodeById($slave['slave']);
199
200
                $slave->setReadonly(false);
201
                $slave->put($result->getPath());
202
                $slave->setReadonly();
203
204
                return true;
205
            }
206
        } catch (NotFound $e) {
207
            $this->logger->debug('referenced slave node ['.$slave['slave'].'] does not exists or is not accessible', [
208
                'category' => get_class($this),
209
                'exception' => $e,
210
            ]);
211
        }
212
213
        $this->logger->debug('create non existing slave ['.$slave['_id'].'] node for master ['.$master->getId().']', [
214
            'category' => get_class($this),
215
        ]);
216
217
        try {
218
            $name = substr($master->getName(), 0, (strlen($master->getExtension()) + 1) * -1);
219
            $name .= '.'.$slave['format'];
220
        } catch (\Exception $e) {
221
            $name = $master->getName().'.'.$slave['format'];
222
        }
223
224
        $node = $master->getParent()->addFile($name, $result->getPath(), [
225
            'owner' => $master->getOwner(),
226
            'app' => [
227
                __NAMESPACE__ => [
228
                    'master' => $master->getId(),
229
                ],
230
            ],
231
        ], NodeInterface::CONFLICT_RENAME);
232
233
        $node->setReadonly();
234
235
        $result = $this->db->{$this->collection_name}->updateOne(['_id' => $slave['_id']], [
236
            '$set' => [
237
                'slave' => $node->getId(),
238
            ],
239
        ]);
240
241
        return $result->isAcknowledged();
242
    }
243
}
244