Completed
Push — master ( 37faaa...541bbf )
by Raffael
10:18 queued 06:30
created

Converter::convert()   A

Complexity

Conditions 5
Paths 4

Size

Total Lines 22

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 0
Metric Value
dl 0
loc 22
ccs 0
cts 15
cp 0
rs 9.2568
c 0
b 0
f 0
cc 5
crap 30
nc 4
nop 2
1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * balloon
7
 *
8
 * @copyright   Copryright (c) 2012-2019 gyselroth GmbH (https://gyselroth.com)
9
 * @license     GPL-3.0 https://opensource.org/licenses/GPL-3.0
10
 */
11
12
namespace Balloon;
13
14
use Balloon\Converter\Adapter\AdapterInterface;
15
use Balloon\Converter\Exception;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, Balloon\Exception.

Let’s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let’s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
16
use Balloon\Filesystem\Node\File;
17
use Psr\Log\LoggerInterface;
18
19
class Converter
20
{
21
    /**
22
     * LoggerInterface.
23
     *
24
     * @var LoggerInterface
25
     */
26
    protected $logger;
27
28
    /**
29
     * Adapter.
30
     *
31
     * @var array
32
     */
33
    protected $adapter = [];
34
35
    /**
36
     * Initialize.
37
     */
38
    public function __construct(LoggerInterface $logger)
39
    {
40
        $this->logger = $logger;
41
    }
42
43
    /**
44
     * Has adapter.
45
     */
46
    public function hasAdapter(string $name): bool
47
    {
48
        return isset($this->adapter[$name]);
49
    }
50
51
    /**
52
     * Inject adapter.
53
     */
54
    public function injectAdapter(AdapterInterface $adapter, ?string $name = null): self
55
    {
56
        if (null === $name) {
57
            $name = get_class($adapter);
58
        }
59
60
        $this->logger->debug('inject converter adapter ['.$name.'] of type ['.get_class($adapter).']', [
61
            'category' => get_class($this),
62
        ]);
63
64
        if ($this->hasAdapter($name)) {
65
            throw new Exception('adapter '.$name.' is already registered');
66
        }
67
68
        $this->adapter[$name] = $adapter;
69
70
        return $this;
71
    }
72
73
    /**
74
     * Get adapter.
75
     */
76
    public function getAdapter(string $name): AdapterInterface
77
    {
78
        if (!$this->hasAdapter($name)) {
79
            throw new Exception('adapter '.$name.' is not registered');
80
        }
81
82
        return $this->adapter[$name];
83
    }
84
85
    /**
86
     * Get adapters.
87
     */
88
    public function getAdapters(array $adapters = []): array
0 ignored issues
show
Unused Code introduced by
The parameter $adapters is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
89
    {
90
        if (empty($adapter)) {
0 ignored issues
show
Bug introduced by
The variable $adapter does not exist. Did you mean $adapters?

This check looks for variables that are accessed but have not been defined. It raises an issue if it finds another variable that has a similar name.

The variable may have been renamed without also renaming all references.

Loading history...
91
            return $this->adapter;
92
        }
93
        $list = [];
94
        foreach ($adapter as $name) {
95
            if (!$this->hasAdapter($name)) {
96
                throw new Exception('adapter '.$name.' is not registered');
97
            }
98
            $list[$name] = $this->adapter[$name];
99
        }
100
101
        return $list;
102
    }
103
104
    /**
105
     * Get supported formats.
106
     */
107
    public function getSupportedFormats(File $file): array
108
    {
109
        foreach ($this->adapter as $adapter) {
110
            if ($adapter->match($file)) {
111
                return $adapter->getSupportedFormats($file);
112
            }
113
        }
114
115
        return [];
116
    }
117
118
    /**
119
     * Create preview.
120
     */
121
    public function createPreview(File $file)
122
    {
123
        $this->logger->debug('create preview from file ['.$file->getId().']', [
124
            'category' => get_class($this),
125
        ]);
126
127
        if (0 === $file->getSize()) {
128
            throw new Exception('can not create preview from empty file');
129
        }
130
131
        foreach ($this->adapter as $name => $adapter) {
132
            if ($adapter->matchPreview($file)) {
133
                return $adapter->createPreview($file);
134
            }
135
136
            $this->logger->debug('skip convert adapter ['.$name.'], adapter can not handle file', [
137
                'category' => get_class($this),
138
            ]);
139
        }
140
141
        throw new Exception('no converter adapter available to create preview for node '.$file->getId());
142
    }
143
144
    /**
145
     * Convert document.
146
     */
147
    public function convert(File $file, string $format)
148
    {
149
        $this->logger->debug('convert file ['.$file->getId().'] to format ['.$format.']', [
150
            'category' => get_class($this),
151
        ]);
152
153
        if (0 === $file->getSize()) {
154
            throw new Exception('can not convert empty file');
155
        }
156
157
        foreach ($this->adapter as $name => $adapter) {
158
            if ($adapter->match($file) && in_array($format, $adapter->getSupportedFormats($file), true)) {
159
                return $adapter->convert($file, $format);
160
            }
161
162
            $this->logger->debug('skip convert adapter ['.$name.'], adapter can not handle file', [
163
                'category' => get_class($this),
164
            ]);
165
        }
166
167
        throw new Exception('no converter adapter available for node '.$file->getId());
168
    }
169
}
170