Completed
Push — master ( 2eecd4...fa815d )
by Bjørn
03:05
created

OptionsTrait::getUnsupportedDefaultOptions()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 0
cts 2
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace WebPConvert\Convert\Converters\BaseTraits;
4
5
use WebPConvert\Convert\Exceptions\ConversionFailed\ConversionSkippedException;
6
use WebPConvert\Options\Exceptions\InvalidOptionValueException;
7
8
use WebPConvert\Options\ArrayOption;
9
use WebPConvert\Options\BooleanOption;
10
use WebPConvert\Options\GhostOption;
11
use WebPConvert\Options\IntegerOption;
12
use WebPConvert\Options\IntegerOrNullOption;
13
use WebPConvert\Options\MetadataOption;
14
use WebPConvert\Options\Options;
15
use WebPConvert\Options\StringOption;
16
use WebPConvert\Options\QualityOption;
17
18
/**
19
 * Trait for handling options
20
 *
21
 * This trait is currently only used in the AbstractConverter class. It has been extracted into a
22
 * trait in order to bundle the methods concerning options.
23
 *
24
 * @package    WebPConvert
25
 * @author     Bjørn Rosell <[email protected]>
26
 * @since      Class available since Release 2.0.0
27
 */
28
trait OptionsTrait
29
{
30
31
    /** @var array  Provided conversion options */
32
    public $providedOptions;
33
34
    /** @var array  Calculated conversion options (merge of default options and provided options)*/
35
    protected $options;
36
37
    /** @var Options  */
38
    protected $options2;
39
40
    abstract protected function getMimeTypeOfSource();
41
    abstract protected static function getConverterId();
42
    abstract public function log($msg, $style = '');
43
    abstract public function logLn($msg, $style = '');
44
45
    /**
46
     *  Create options.
47
     *
48
     *  The options created here will be available to all converters.
49
     *  Individual converters may add options by overriding this method.
50
     *
51
     *  @return void
52
     */
53 31
    protected function createOptions()
54
    {
55 31
        $isPng = ($this->getMimeTypeOfSource() == 'image/png');
56
57 31
        $this->options2 = new Options();
58 31
        $this->options2->addOptions(
59 31
            new IntegerOption('alpha-quality', 85, 0, 100),
60 31
            new BooleanOption('auto-filter', false),
61 31
            new IntegerOption('default-quality', ($isPng ? 85 : 75), 0, 100),
62 31
            new StringOption('encoding', 'auto', ['lossy', 'lossless', 'auto']),
63 31
            new BooleanOption('low-memory', false),
64 31
            new BooleanOption('log-call-arguments', false),
65 31
            new IntegerOption('max-quality', 85, 0, 100),
66 31
            new MetadataOption('metadata', 'none'),
67 31
            new IntegerOption('method', 6, 0, 6),
68 31
            new IntegerOption('near-lossless', 60, 0, 100),
69 31
            new StringOption('preset', 'none', ['none', 'default', 'photo', 'picture', 'drawing', 'icon', 'text']),
70 31
            new QualityOption('quality', ($isPng ? 85 : 'auto')),
71 31
            new IntegerOrNullOption('size-in-percentage', null, 0, 100),
72 31
            new BooleanOption('skip', false),
73 31
            new BooleanOption('use-nice', false),
74 31
            new ArrayOption('jpeg', []),
75 31
            new ArrayOption('png', [])
76
        );
77 31
    }
78
79
    /**
80
     * Set "provided options" (options provided by the user when calling convert().
81
     *
82
     * This also calculates the protected options array, by merging in the default options, merging
83
     * jpeg and png options and merging prefixed options (such as 'vips-quality').
84
     * The resulting options array are set in the protected property $this->options and can be
85
     * retrieved using the public ::getOptions() function.
86
     *
87
     * @param   array $providedOptions (optional)
88
     * @return  void
89
     */
90 31
    public function setProvidedOptions($providedOptions = [])
91
    {
92 31
        $this->createOptions();
93
94 31
        $this->providedOptions = $providedOptions;
95
96 31
        if (isset($this->providedOptions['png'])) {
97 1
            if ($this->getMimeTypeOfSource() == 'image/png') {
98
                $this->providedOptions = array_merge($this->providedOptions, $this->providedOptions['png']);
99
//                $this->logLn(print_r($this->providedOptions, true));
100
                unset($this->providedOptions['png']);
101
            }
102
        }
103
104 31
        if (isset($this->providedOptions['jpeg'])) {
105 1
            if ($this->getMimeTypeOfSource() == 'image/jpeg') {
106 1
                $this->providedOptions = array_merge($this->providedOptions, $this->providedOptions['jpeg']);
107 1
                unset($this->providedOptions['jpeg']);
108
            }
109
        }
110
111
        // merge down converter-prefixed options
112 31
        $converterId = self::getConverterId();
113 31
        $strLen = strlen($converterId);
114 31
        foreach ($this->providedOptions as $optionKey => $optionValue) {
115 17
            if (substr($optionKey, 0, $strLen + 1) == ($converterId . '-')) {
116 17
                $this->providedOptions[substr($optionKey, $strLen + 1)] = $optionValue;
117
            }
118
        }
119
120
        // Create options (Option objects)
121 31
        foreach ($this->providedOptions as $optionId => $optionValue) {
122 17
            $this->options2->setOrCreateOption($optionId, $optionValue);
123
        }
124
        //$this->logLn(print_r($this->options2->getOptions(), true));
125
//$this->logLn($this->options2->getOption('hello'));
126
127
        // Create flat associative array of options
128 31
        $this->options = $this->options2->getOptions();
129
130
        // -  Merge $defaultOptions into provided options
131
        //$this->options = array_merge($this->getDefaultOptions(), $this->providedOptions);
132
133
        //$this->logOptions();
134 31
    }
135
136
    /**
137
     * Get the resulting options after merging provided options with default options.
138
     *
139
     * Note that the defaults depends on the mime type of the source. For example, the default value for quality
140
     * is "auto" for jpegs, and 85 for pngs.
141
     *
142
     * @return array  An associative array of options: ['metadata' => 'none', ...]
143
     */
144 2
    public function getOptions()
145
    {
146 2
        return $this->options;
147
    }
148
149
    /**
150
     * Change an option specifically.
151
     *
152
     * This method is probably rarely neeeded. We are using it to change the "encoding" option temporarily
153
     * in the EncodingAutoTrait.
154
     *
155
     * @param  string  $id      Id of option (ie "metadata")
156
     * @param  mixed   $value   The new value.
157
     * @return void
158
     */
159 1
    protected function setOption($id, $value)
160
    {
161 1
        $this->options[$id] = $value;
162 1
        $this->options2->setOrCreateOption($id, $value);
163 1
    }
164
165
    /**
166
     *  Check options.
167
     *
168
     *  @throws InvalidOptionValueException  if an option value have wrong type or is out of range
169
     *  @throws ConversionSkippedException  if 'skip' option is set to true
170
     *  @return void
171
     */
172 12
    protected function checkOptions()
173
    {
174 12
        $this->options2->check();
175
176 12
        if ($this->options['skip']) {
177
            if (($this->getMimeTypeOfSource() == 'image/png') && isset($this->options['png']['skip'])) {
178
                throw new ConversionSkippedException(
179
                    'skipped conversion (configured to do so for PNG)'
180
                );
181
            } else {
182
                throw new ConversionSkippedException(
183
                    'skipped conversion (configured to do so)'
184
                );
185
            }
186
        }
187 12
    }
188
189
    public function logOptions()
190
    {
191
        $this->logLn('');
192
        $this->logLn('Options:');
193
        $this->logLn('------------');
194
        $this->logLn(
195
            'The following options have been set explicitly. ' .
196
            'Note: it is the resulting options after merging down the "jpeg" and "png" options and any ' .
197
            'converter-prefixed options.'
198
        );
199
        $this->logLn('- source: ' . $this->source, 'italic');
200
        $this->logLn('- destination: ' . $this->destination, 'italic');
201
202
        $unsupported = $this->getUnsupportedDefaultOptions();
203
        //$this->logLn('Unsupported:' . print_r($this->getUnsupportedDefaultOptions(), true));
204
        $ignored = [];
205
        $implicit = [];
206
        foreach ($this->options2->getOptionsMap() as $id => $option) {
207
            if (($id == 'png') || ($id == 'jpeg')) {
208
                continue;
209
            }
210
            if ($option->isValueExplicitlySet()) {
211
                if (($option instanceof GhostOption) || in_array($id, $unsupported)) {
212
                    //$this->log(' (note: this option is ignored by this converter)', 'italic');
213
                    $ignored[] = $option;
214
                } else {
215
                    $this->log('- ' . $id . ': ', 'italic');
216
                    $this->log($option->getValueForPrint());
217
                    $this->logLn('');
218
                }
219
            } else {
220
                if (($option instanceof GhostOption) || in_array($id, $unsupported)) {
221
                } else {
222
                    $implicit[] = $option;
223
                }
224
            }
225
        }
226
227
        if (count($implicit) > 0) {
228
            $this->logLn('');
229
            $this->logLn(
230
                'The following options have not been explicitly set, so using the following defaults:'
231
            );
232
            foreach ($implicit as $option) {
233
                $this->log('- ' . $option->getId() . ': ', 'italic');
234
                $this->log($option->getValueForPrint());
235
                $this->logLn('');
236
            }
237
        }
238
        if (count($ignored) > 0) {
239
            $this->logLn('');
240
            $this->logLn(
241
                'The following options were supplied but are ignored because they are not supported by this converter:'
242
            );
243
            foreach ($ignored as $option) {
244
                $this->logLn('- ' . $option->getId(), 'italic');
245
            }
246
        }
247
        $this->logLn('------------');
248
    }
249
250
    // to be overridden by converters
251
    protected function getUnsupportedDefaultOptions()
252
    {
253
        return [];
254
    }
255
}
256