Passed
Push — master ( 1ada49...6f88dc )
by Bjørn
02:29
created

ImagickBinary::checkOperationality()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 4
nc 3
nop 0
dl 0
loc 7
rs 10
c 0
b 0
f 0
1
<?php
2
// TODO: Quality option
3
namespace WebPConvert\Convert\Converters;
4
5
use WebPConvert\Convert\BaseConverters\AbstractExecConverter;
6
7
use WebPConvert\Convert\Exceptions\ConversionFailed\ConverterNotOperational\SystemRequirementsNotMetException;
8
use WebPConvert\Convert\Exceptions\ConversionFailedException;
9
10
//use WebPConvert\Convert\Exceptions\ConversionFailed\InvalidInput\TargetNotFoundException;
11
12
// To futher improve this converter, I could check out:
13
// https://github.com/Orbitale/ImageMagickPHP
14
class ImagickBinary extends AbstractExecConverter
15
{
16
    protected function getOptionDefinitionsExtra()
17
    {
18
        return [
19
            ['use-nice', 'boolean', false],
20
        ];
21
    }
22
23
    public static function imagickInstalled()
24
    {
25
        exec('convert -version', $output, $returnCode);
26
        return ($returnCode == 0);
27
    }
28
29
    // Check if webp delegate is installed
30
    public static function webPDelegateInstalled()
31
    {
32
        /* HM. We should not rely on grep being available
33
        $command = 'convert -list configure | grep -i "delegates" | grep -i webp';
34
        exec($command, $output, $returnCode);
35
        return (count($output) > 0);
36
        */
37
        $command = 'convert -version';
38
        exec($command, $output, $returnCode);
39
        foreach ($output as $line) {
40
            if (preg_match('/Delegate.*webp.*/i', $line)) {
41
                return true;
42
            }
43
        }
44
        return false;
45
    }
46
47
    /**
48
     * Check (general) operationality of imagack converter executable
49
     *
50
     * @throws SystemRequirementsNotMetException  if system requirements are not met
51
     */
52
    protected function checkOperationality()
53
    {
54
        if (!self::imagickInstalled()) {
55
            throw new SystemRequirementsNotMetException('imagick is not installed');
56
        }
57
        if (!self::webPDelegateInstalled()) {
58
            throw new SystemRequirementsNotMetException('webp delegate missing');
59
        }
60
    }
61
62
    protected function doActualConvert()
63
    {
64
        //$this->logLn('Using quality:' . $this->getCalculatedQuality());
65
        // Should we use "magick" or "convert" command?
66
        // It seems they do the same. But which is best supported? Which is mostly available (whitelisted)?
67
        // Should we perhaps try both?
68
        // For now, we just go with "convert"
69
70
71
        $commandArguments = [];
72
        if ($this->isQualityDetectionRequiredButFailing()) {
73
            // quality:auto was specified, but could not be determined.
74
            // we cannot apply the max-quality logic, but we can provide auto quality
75
            // simply by not specifying the quality option.
76
        } else {
77
            $commandArguments[] = '-quality ' . escapeshellarg($this->getCalculatedQuality());
78
        }
79
        $commandArguments[] = escapeshellarg($this->source);
80
        $commandArguments[] = escapeshellarg('webp:' . $this->destination);
81
82
        $command = 'convert ' . implode(' ', $commandArguments);
83
84
        $useNice = (($this->options['use-nice']) && self::hasNiceSupport()) ? true : false;
85
        if ($useNice) {
86
            $this->logLn('using nice');
87
            $command = 'nice ' . $command;
88
        }
89
        $this->logLn('command: ' . $command);
90
        exec($command, $output, $returnCode);
91
        if ($returnCode == 127) {
92
            throw new SystemRequirementsNotMetException('imagick is not installed');
93
        }
94
        if ($returnCode != 0) {
95
            $this->logLn('command:' . $command);
96
            $this->logLn('return code:' . $returnCode);
97
            $this->logLn('output:' . print_r(implode("\n", $output), true));
98
            throw new SystemRequirementsNotMetException('The exec call failed');
99
        }
100
    }
101
}
102