Passed
Push — master ( 47232b...207a99 )
by Bjørn
01:36 queued 12s
created

ServeConvertedWebP::serve()   C

Complexity

Conditions 13
Paths 34

Size

Total Lines 74
Code Lines 45

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 39
CRAP Score 13.2477

Importance

Changes 7
Bugs 1 Features 0
Metric Value
cc 13
eloc 45
c 7
b 1
f 0
nc 34
nop 5
dl 0
loc 74
ccs 39
cts 44
cp 0.8864
crap 13.2477
rs 6.6166

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 BooleanOption('redirect-to-self-instead-of-serving', false),
53 7
            new ArrayOption('serve-image', []),
54 7
            new SensitiveArrayOption('convert', [])
55
        );
56 7
        foreach ($options as $optionId => $optionValue) {
57 7
            $options2->setOrCreateOption($optionId, $optionValue);
58
        }
59 7
        $options2->check();
60 7
        return $options2->getOptions();
61
    }
62
63
    /**
64
     * Serve original file (source).
65
     *
66
     * @param   string  $source                        path to source file
67
     * @param   array   $serveImageOptions (optional)  options for serving an image
68
     *                  Supported options:
69
     *                  - All options supported by ServeFile::serve()
70
     * @throws  ServeFailedException  if source is not an image or mime type cannot be determined
71
     * @return  void
72
     */
73 3
    public static function serveOriginal($source, $serveImageOptions = [])
74
    {
75 3
        InputValidator::checkSource($source);
76 3
        $contentType = MimeType::getMimeTypeDetectionResult($source);
77 3
        if (is_null($contentType)) {
78
            throw new ServeFailedException('Rejecting to serve original (mime type cannot be determined)');
79 3
        } elseif ($contentType === false) {
80
            throw new ServeFailedException('Rejecting to serve original (it is not an image)');
81
        } else {
82 3
            ServeFile::serve($source, $contentType, $serveImageOptions);
83
        }
84 3
    }
85
86
    /**
87
     * Serve destination file.
88
     *
89
     * TODO: SHould this really be public?
90
     *
91
     * @param   string  $destination                   path to destination file
92
     * @param   array   $serveImageOptions (optional)  options for serving (such as which headers to add)
93
     *       Supported options:
94
     *       - All options supported by ServeFile::serve()
95
     * @return  void
96
     */
97 4
    public static function serveDestination($destination, $serveImageOptions = [])
98
    {
99 4
        InputValidator::checkDestination($destination);
100 4
        ServeFile::serve($destination, 'image/webp', $serveImageOptions);
101 4
    }
102
103
104 3
    public static function warningHandler()
105
    {
106
        // do nothing! - as we do not return anything, the warning is suppressed
107 3
    }
108
109
    /**
110
     * Serve converted webp.
111
     *
112
     * Serve a converted webp. If a file already exists at the destination, that is served (unless it is
113
     * older than the source - in that case a fresh conversion will be made, or the file at the destination
114
     * is larger than the source - in that case the source is served). Some options may alter this logic.
115
     * In case no file exists at the destination, a fresh conversion is made and served.
116
     *
117
     * @param   string  $source              path to source file
118
     * @param   string  $destination         path to destination
119
     * @param   array   $options (optional)  options for serving/converting
120
     *       Supported options:
121
     *       'show-report'     => (boolean)   If true, the decision will always be 'report'
122
     *       'serve-original'  => (boolean)   If true, the decision will be 'source' (unless above option is set)
123
     *       'reconvert     '  => (boolean)   If true, the decision will be 'fresh-conversion' (unless one of the
124
     *                                        above options is set)
125
     *       - All options supported by WebPConvert::convert()
126
     *       - All options supported by ServeFile::serve()
127
     * @param  \WebPConvert\Loggers\BaseLogger $serveLogger (optional)
128
     * @param  \WebPConvert\Loggers\BaseLogger $convertLogger (optional)
129
     *
130
     * @throws  \WebPConvert\Exceptions\WebPConvertException  If something went wrong.
131
     * @return  void
132
     */
133 7
    public static function serve($source, $destination, $options = [], $serveLogger = null, $convertLogger = null)
134
    {
135 7
        InputValidator::checkSourceAndDestination($source, $destination);
136
137 7
        $options = self::processOptions($options);
138
139 7
        if ($options['suppress-warnings']) {
140 7
            set_error_handler(
141 7
                array('\\WebPConvert\\Serve\\ServeConvertedWebP', "warningHandler"),
142 7
                E_WARNING | E_USER_WARNING | E_NOTICE | E_USER_NOTICE
143
            );
144
        }
145
146
147
        //$options = array_merge(self::$defaultOptions, $options);
148
149
        // Step 1: Is there a file at the destination? If not, trigger conversion
150
        // However 1: if "show-report" option is set, serve the report instead
151
        // However 2: "reconvert" option should also trigger conversion
152 7
        if ($options['show-report']) {
153 1
            Header::addLogHeader('Showing report', $serveLogger);
154 1
            Report::convertAndReport($source, $destination, $options);
155 1
            return;
156
        }
157
158 6
        if (!@file_exists($destination)) {
159 1
            Header::addLogHeader('Converting (there were no file at destination)', $serveLogger);
160 1
            WebPConvert::convert($source, $destination, $options['convert'], $convertLogger);
161 5
        } elseif ($options['reconvert']) {
162 1
            Header::addLogHeader('Converting (told to reconvert)', $serveLogger);
163 1
            WebPConvert::convert($source, $destination, $options['convert'], $convertLogger);
164
        } else {
165
            // Step 2: Is the destination older than the source?
166
            //         If yes, trigger conversion (deleting destination is implicit)
167 4
            $timestampSource = @filemtime($source);
168 4
            $timestampDestination = @filemtime($destination);
169 4
            if (($timestampSource !== false) &&
170 4
                ($timestampDestination !== false) &&
171 4
                ($timestampSource > $timestampDestination)) {
172 1
                    Header::addLogHeader('Converting (destination was older than the source)', $serveLogger);
173 1
                    WebPConvert::convert($source, $destination, $options['convert'], $convertLogger);
174
            }
175
        }
176
177
        // Step 3: Serve the smallest file (destination or source)
178
        // However, first check if 'serve-original' is set
179 6
        if ($options['serve-original']) {
180 1
            Header::addLogHeader('Serving original (told to)', $serveLogger);
181 1
            self::serveOriginal($source, $options['serve-image']);
182 1
            return;
183
        }
184
185 5
        if ($options['redirect-to-self-instead-of-serving']) {
186
            Header::addLogHeader(
187
                'Redirecting to self! ' .
188
                    '(hope you got redirection to existing webps set up, otherwise you will get a loop!)',
189
                $serveLogger
190
            );
191
            header('Location: ?fresh', 302);
192
            return;
193
        }
194
195 5
        $filesizeDestination = @filesize($destination);
196 5
        $filesizeSource = @filesize($source);
197 5
        if (($filesizeSource !== false) &&
198 5
            ($filesizeDestination !== false) &&
199 5
            ($filesizeDestination > $filesizeSource)) {
200 1
                Header::addLogHeader('Serving original (it is smaller)', $serveLogger);
201 1
                self::serveOriginal($source, $options['serve-image']);
202 1
                return;
203
        }
204
205 4
        Header::addLogHeader('Serving converted file', $serveLogger);
206 4
        self::serveDestination($destination, $options['serve-image']);
207 4
    }
208
}
209