Completed
Push — master ( 41c0c2...358625 )
by Bjørn
04:46 queued 11s
created

ServeConvertedWebP::serve()   C

Complexity

Conditions 12
Paths 34

Size

Total Lines 62
Code Lines 36

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 34
CRAP Score 12.0247

Importance

Changes 4
Bugs 0 Features 0
Metric Value
cc 12
eloc 36
c 4
b 0
f 0
nc 34
nop 5
dl 0
loc 62
ccs 34
cts 36
cp 0.9444
crap 12.0247
rs 6.9666

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
namespace WebPConvert\Serve;
3
4
use WebPConvert\Convert\Exceptions\ConversionFailedException;
5
use WebPConvert\Helpers\InputValidator;
6
use WebPConvert\Helpers\MimeType;
7
use WebPConvert\Serve\Exceptions\ServeFailedException;
8
use WebPConvert\Serve\Header;
9
use WebPConvert\Serve\Report;
10
use WebPConvert\Serve\ServeFile;
11
use WebPConvert\Options\ArrayOption;
12
use WebPConvert\Options\BooleanOption;
13
use WebPConvert\Options\Options;
14
use WebPConvert\Options\SensitiveArrayOption;
15
use WebPConvert\Options\Exceptions\InvalidOptionTypeException;
16
use WebPConvert\Options\Exceptions\InvalidOptionValueException;
17
use WebPConvert\WebPConvert;
18
19
/**
20
 * Serve a converted webp image.
21
 *
22
 * The webp that is served might end up being one of these:
23
 * - a fresh convertion
24
 * - the destionation
25
 * - the original
26
 *
27
 * Exactly which is a decision based upon options, file sizes and file modification dates
28
 * (see the serve method of this class for details)
29
 *
30
 * @package    WebPConvert
31
 * @author     Bjørn Rosell <[email protected]>
32
 * @since      Class available since Release 2.0.0
33
 */
34
class ServeConvertedWebP
35
{
36
37
    /**
38
     * Process options.
39
     *
40
     * @throws \WebPConvert\Options\Exceptions\InvalidOptionTypeException   If the type of an option is invalid
41
     * @throws \WebPConvert\Options\Exceptions\InvalidOptionValueException  If the value of an option is invalid
42
     * @param array $options
43
     */
44 7
    private static function processOptions($options)
45
    {
46 7
        $options2 = new Options();
47 7
        $options2->addOptions(
48 7
            new BooleanOption('reconvert', false),
49 7
            new BooleanOption('serve-original', false),
50 7
            new BooleanOption('show-report', false),
51 7
            new BooleanOption('suppress-warnings', true),
52 7
            new ArrayOption('serve-image', []),
53 7
            new SensitiveArrayOption('convert', [])
54
        );
55 7
        foreach ($options as $optionId => $optionValue) {
56 7
            $options2->setOrCreateOption($optionId, $optionValue);
57
        }
58 7
        $options2->check();
59 7
        return $options2->getOptions();
60
    }
61
62
    /**
63
     * Serve original file (source).
64
     *
65
     * @param   string  $source                        path to source file
66
     * @param   array   $serveImageOptions (optional)  options for serving an image
67
     *                  Supported options:
68
     *                  - All options supported by ServeFile::serve()
69
     * @throws  ServeFailedException  if source is not an image or mime type cannot be determined
70
     * @return  void
71
     */
72 3
    public static function serveOriginal($source, $serveImageOptions = [])
73
    {
74 3
        InputValidator::checkSource($source);
75 3
        $contentType = MimeType::getMimeTypeDetectionResult($source);
76 3
        if (is_null($contentType)) {
77
            throw new ServeFailedException('Rejecting to serve original (mime type cannot be determined)');
78 3
        } elseif ($contentType === false) {
79
            throw new ServeFailedException('Rejecting to serve original (it is not an image)');
80
        } else {
81 3
            ServeFile::serve($source, $contentType, $serveImageOptions);
82
        }
83 3
    }
84
85
    /**
86
     * Serve destination file.
87
     *
88
     * TODO: SHould this really be public?
89
     *
90
     * @param   string  $destination                   path to destination file
91
     * @param   array   $serveImageOptions (optional)  options for serving (such as which headers to add)
92
     *       Supported options:
93
     *       - All options supported by ServeFile::serve()
94
     * @return  void
95
     */
96 6
    public static function serveDestination($destination, $serveImageOptions = [])
97
    {
98 6
        InputValidator::checkDestination($destination);
99 6
        ServeFile::serve($destination, 'image/webp', $serveImageOptions);
100 6
    }
101
102
103 9
    public static function warningHandler()
104
    {
105
        // do nothing! - as we do not return anything, the warning is suppressed
106 9
    }
107
108
    /**
109
     * Serve converted webp.
110
     *
111
     * Serve a converted webp. If a file already exists at the destination, that is served (unless it is
112
     * older than the source - in that case a fresh conversion will be made, or the file at the destination
113
     * is larger than the source - in that case the source is served). Some options may alter this logic.
114
     * In case no file exists at the destination, a fresh conversion is made and served.
115
     *
116
     * @param   string  $source              path to source file
117
     * @param   string  $destination         path to destination
118
     * @param   array   $options (optional)  options for serving/converting
119
     *       Supported options:
120
     *       'show-report'     => (boolean)   If true, the decision will always be 'report'
121
     *       'serve-original'  => (boolean)   If true, the decision will be 'source' (unless above option is set)
122
     *       'reconvert     '  => (boolean)   If true, the decision will be 'fresh-conversion' (unless one of the
123
     *                                        above options is set)
124
     *       - All options supported by WebPConvert::convert()
125
     *       - All options supported by ServeFile::serve()
126
     * @param  \WebPConvert\Loggers\BaseLogger $serveLogger (optional)
127
     * @param  \WebPConvert\Loggers\BaseLogger $convertLogger (optional)
128
     *
129
     * @throws  \WebPConvert\Exceptions\WebPConvertException  If something went wrong.
130
     * @return  void
131
     */
132 7
    public static function serve($source, $destination, $options = [], $serveLogger = null, $convertLogger = null)
133
    {
134 7
        InputValidator::checkSourceAndDestination($source, $destination);
135
136 7
        $options = self::processOptions($options);
137
138 7
        if ($options['suppress-warnings']) {
139 7
            set_error_handler(
140 7
                array('\\WebPConvert\\Serve\\ServeConvertedWebP', "warningHandler"),
141 7
                E_WARNING | E_USER_WARNING | E_NOTICE | E_USER_NOTICE
142
            );
143
        }
144
145
146
        //$options = array_merge(self::$defaultOptions, $options);
147
148
        // Step 1: Is there a file at the destination? If not, trigger conversion
149
        // However 1: if "show-report" option is set, serve the report instead
150
        // However 2: "reconvert" option should also trigger conversion
151 7
        if ($options['show-report']) {
152 1
            Header::addLogHeader('Showing report', $serveLogger);
153 1
            Report::convertAndReport($source, $destination, $options);
154 1
            return;
155
        }
156
157 6
        if (!@file_exists($destination)) {
158 2
            Header::addLogHeader('Converting (there were no file at destination)', $serveLogger);
159 2
            WebPConvert::convert($source, $destination, $options['convert'], $convertLogger);
160 4
        } elseif ($options['reconvert']) {
161
            Header::addLogHeader('Converting (told to reconvert)', $serveLogger);
162
            WebPConvert::convert($source, $destination, $options['convert'], $convertLogger);
163
        } else {
164
            // Step 2: Is the destination older than the source?
165
            //         If yes, trigger conversion (deleting destination is implicit)
166 4
            $timestampSource = @filemtime($source);
167 4
            $timestampDestination = @filemtime($destination);
168 4
            if (($timestampSource !== false) &&
169 4
                ($timestampDestination !== false) &&
170 4
                ($timestampSource > $timestampDestination)) {
171 1
                    Header::addLogHeader('Converting (destination was older than the source)', $serveLogger);
172 1
                    WebPConvert::convert($source, $destination, $options['convert'], $convertLogger);
173
            }
174
        }
175
176
        // Step 3: Serve the smallest file (destination or source)
177
        // However, first check if 'serve-original' is set
178 6
        if ($options['serve-original']) {
179 1
            Header::addLogHeader('Serving original (told to)', $serveLogger);
180 1
            self::serveOriginal($source, $options['serve-image']);
181
        }
182
183 6
        $filesizeDestination = @filesize($destination);
184 6
        $filesizeSource = @filesize($source);
185 6
        if (($filesizeSource !== false) &&
186 6
            ($filesizeDestination !== false) &&
187 6
            ($filesizeDestination > $filesizeSource)) {
188 1
                Header::addLogHeader('Serving original (it is smaller)', $serveLogger);
189 1
                self::serveOriginal($source, $options['serve-image']);
190
        }
191
192 6
        Header::addLogHeader('Serving converted file', $serveLogger);
193 6
        self::serveDestination($destination, $options['serve-image']);
194 6
    }
195
}
196