Test Failed
Push — master ( 88c612...2def1a )
by Bjørn
03:10
created

ServeConvertedWebP::serve()   C

Complexity

Conditions 14
Paths 28

Size

Total Lines 60
Code Lines 36

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 17
CRAP Score 14.6615

Importance

Changes 0
Metric Value
cc 14
eloc 36
nc 28
nop 4
dl 0
loc 60
ccs 17
cts 20
cp 0.85
crap 14.6615
rs 6.2666
c 0
b 0
f 0

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\Serve\Header;
5
use WebPConvert\Serve\Report;
6
use WebPConvert\Serve\ServeFile;
7
8
use WebPConvert\WebPConvert;
9
use WebPConvert\Serve\Exceptions\ServeFailedException;
10
use WebPConvert\Convert\Exceptions\ConversionFailedException;
11
12
use ImageMimeTypeGuesser\ImageMimeTypeGuesser;
13
14
/**
15
 * Serve a converted webp image.
16
 *
17
 * The webp that is served might end up being one of these:
18
 * - a fresh convertion
19
 * - the destionation
20
 * - the original
21
 *
22
 * Exactly which is a decision based upon options, file sizes and file modification dates
23
 * (see the serve method of this class for details)
24
 *
25
 * @package    WebPConvert
26
 * @author     Bjørn Rosell <[email protected]>
27
 * @since      Class available since Release 2.0.0
28
 */
29
class ServeConvertedWebP
30
{
31
32
    public static $defaultOptions = [
33
        'reconvert' => false,
34
        'serve-original' => false,
35
        'show-report' => false,
36
    ];
37
38
    /**
39
     * Serve original file (source).
40
     *
41
     * @param   string  $source              path to source file
42
     * @param   array   $options (optional)  options for serving
43
     *                  Supported options:
44
     *                  - All options supported by ServeFile::serve()
45
     * @throws  ServeFailedException  if source is not an image or mime type cannot be determined
46
     * @return  void
47
     */
48
    public static function serveOriginal($source, $options = [])
49
    {
50
        $contentType = ImageMimeTypeGuesser::lenientGuess($source);
51
        if (is_null($contentType)) {
52
            throw new ServeFailedException('Rejecting to serve original (mime type cannot be determined)');
53
        } elseif ($contentType === false) {
54
            throw new ServeFailedException('Rejecting to serve original (it is not an image)');
55
        } else {
56
            ServeFile::serve($source, $contentType, $options);
57
        }
58
    }
59
60
    /**
61 3
     * Serve destination file.
62
     *
63 3
     * @param   string  $destination         path to destination file
64 3
     * @param   array   $options (optional)  options for serving (such as which headers to add)
65
     *       Supported options:
66 3
     *       - All options supported by ServeFile::serve()
67
     * @return  void
68
     */
69 3
    public static function serveDestination($destination, $options = [])
70
    {
71 3
        ServeFile::serve($destination, 'image/webp', $options);
72
    }
73
74
    /**
75
     * @param  string  $msg  Message to add to "X-WebP-Convert-Log" header
76
     * @param  \WebPConvert\Loggers\BaseLogger $logger (optional)
77
     * @return void
78
     */
79
    private static function headerLog($msg, $logger = null)
80
    {
81
        Header::addHeader('X-WebP-Convert-Log: ' . $msg);
82 2
        if (!is_null($logger)) {
83
            $logger->logLn($msg);
84 2
        }
85 2
    }
86
87
    /**
88
     * Serve converted webp.
89
     *
90
     * Serve a converted webp. If a file already exists at the destination, that is served (unless it is
91
     * older than the source - in that case a fresh conversion will be made, or the file at the destination
92
     * is larger than the source - in that case the source is served). Some options may alter this logic.
93
     * In case no file exists at the destination, a fresh conversion is made and served.
94
     *
95
     * @param   string  $source              path to source file
96
     * @param   string  $destination         path to destination
97
     * @param   array   $options (optional)  options for serving/converting
98
     *       Supported options:
99
     *       'show-report'     => (boolean)   If true, the decision will always be 'report'
100
     *       'serve-original'  => (boolean)   If true, the decision will be 'source' (unless above option is set)
101
     *       'reconvert     '  => (boolean)   If true, the decision will be 'fresh-conversion' (unless one of the
102
     *                                        above options is set)
103
     *       - All options supported by WebPConvert::convert()
104
     *       - All options supported by ServeFile::serve()
105
     * @param  \WebPConvert\Loggers\BaseLogger $logger (optional)
106
     *
107
     * @throws  \WebPConvert\Convert\Exceptions\ConversionFailedException  If conversion failed
108 4
     * @throws  ServeFailedException       If an argument is invalid or source file does not exists
109
     * @return  void
110 4
     */
111
    public static function serve($source, $destination, $options = [], $logger = null)
112
    {
113 4
        if (empty($source)) {
114
            throw new ServeFailedException('Source argument missing');
115
        }
116 4
        if (empty($destination)) {
117
            throw new ServeFailedException('Destination argument missing');
118
        }
119
        if (@!file_exists($source)) {
120 4
            throw new ServeFailedException('Source file was not found');
121
        }
122 4
123
        $options = array_merge(self::$defaultOptions, $options);
124
125 4
        // Step 1: Is there a file at the destination? If not, trigger conversion
126 1
        // However, if show-report option is set, serve the report instead
127 1
        if ($options['show-report']) {
128
            self::headerLog('Showing report', $logger);
129 3
            Report::convertAndReport($source, $destination, $options);
130 1
            return;
131 1
        }
132
133 2
        if (!@file_exists($destination)) {
134 1
            self::headerLog('Converting (there were no file at destination)', $logger);
135 1
            WebPConvert::convert($source, $destination, $options, $logger);
136
        } elseif ($options['reconvert']) {
137 1
            self::headerLog('Converting (told to reconvert)', $logger);
138 1
            WebPConvert::convert($source, $destination, $options, $logger);
139 1
        }
140
141 4
        // Step 2: Is the destination older than the source?
142
        //         If yes, trigger conversion (deleting destination is implicit)
143
        $timestampSource = @filemtime($source);
144
        $timestampDestination = @filemtime($destination);
145
        if (($timestampSource !== false) &&
146
            ($timestampDestination !== false) &&
147
            ($timestampSource > $timestampDestination)) {
148
                self::headerLog('Converting (destination was older than the source)', $logger);
149
                WebPConvert::convert($source, $destination, $options, $logger);
150
        }
151
152
153
        // Step 3: Serve the smallest file (destination or source)
154
        // However, first check if 'serve-original' is set
155
        if ($options['serve-original']) {
156
            self::headerLog('Serving original (told to)', $logger);
157
            self::serveOriginal($source, $options);
158
        }
159
160
        $filesizeDestination = @filesize($destination);
161
        $filesizeSource = @filesize($source);
162
        if (($filesizeSource !== false) &&
163
            ($filesizeDestination !== false) &&
164
            ($filesizeDestination > $filesizeSource)) {
165
                self::headerLog('Serving original (it is smaller)', $logger);
166
                self::serveOriginal($source, $options);
167
        }
168
169
        self::headerLog('Serving converted file', $logger);
170
        self::serveDestination($destination, $options);
171
    }
172
}
173