Test Failed
Push — master ( 39fcfb...91c09e )
by Bjørn
02:56
created

ServeFile::serve()   C

Complexity

Conditions 11
Paths 225

Size

Total Lines 42
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 11.4402

Importance

Changes 0
Metric Value
cc 11
eloc 22
nc 225
nop 3
dl 0
loc 42
ccs 11
cts 13
cp 0.8462
crap 11.4402
rs 6.1708
c 0
b 0
f 0

How to fix   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\Report;
5
use WebPConvert\Options\ArrayOption;
6
use WebPConvert\Options\BooleanOption;
7
use WebPConvert\Options\Options;
8
use WebPConvert\Options\StringOption;
9
use WebPConvert\Serve\Header;
10
use WebPConvert\Serve\Exceptions\ServeFailedException;
11
12
/**
13
 * Serve a file (send to standard output)
14
 *
15
 * @package    WebPConvert
16
 * @author     Bjørn Rosell <[email protected]>
17
 * @since      Class available since Release 2.0.0
18
 */
19
class ServeFile
20
{
21
22
    /**
23
     * Process options.
24
     *
25
     * @throws \WebPConvert\Options\Exceptions\InvalidOptionTypeException   If the type of an option is invalid
26
     * @throws \WebPConvert\Options\Exceptions\InvalidOptionValueException  If the value of an option is invalid
27
     * @param array $options
28
     */
29
    private static function processOptions($options)
30
    {
31
        $options2 = new Options();
32
        $options2->addOptions(
33
            new ArrayOption('headers', []),
34
            new StringOption('cache-control-header', 'public, max-age=31536000'),
35
        );
36
        foreach ($options as $optionId => $optionValue) {
37
            $options2->setOrCreateOption($optionId, $optionValue);
38
        }
39
        $options2->check();
40
        $options = $options2->getOptions();
41
42
        // headers option
43
        // --------------
44
45
        $headerOptions = new Options();
46
        $headerOptions->addOptions(
47
            new BooleanOption('cache-control', false),
48
            new BooleanOption('content-length', true),
49
            new BooleanOption('content-type', true),
50
            new BooleanOption('expires', false),
51
            new BooleanOption('last-modified', true),
52
            new BooleanOption('vary-accept', false)
53
        );
54
        foreach ($options['headers'] as $optionId => $optionValue) {
55
            $headerOptions->setOrCreateOption($optionId, $optionValue);
56
        }
57
        $options['headers'] = $headerOptions->getOptions();
58
        return $options;
59
    }
60 5
61
    /**
62 5
     * Serve existing file.
63
     *
64
     * @param  string  $filename     File to serve (absolute path)
65
     * @param  string  $contentType  Content-type (used to set header).
66
     *                                    Only used when the "set-content-type-header" option is set.
67 5
     *                                    Set to ie "image/jpeg" for serving jpeg file.
68
     * @param  array   $options      Array of named options (optional).
69 5
     *       Supported options:
70 4
     *       'add-vary-accept-header'  => (boolean)   Whether to add *Vary: Accept* header or not. Default: true.
71
     *       'set-content-type-header' => (boolean)   Whether to set *Content-Type* header or not. Default: true.
72
     *       'set-last-modified-header' => (boolean)  Whether to set *Last-Modified* header or not. Default: true.
73 5
     *       'set-cache-control-header' => (boolean)  Whether to set *Cache-Control* header or not. Default: true.
74 4
     *       'cache-control-header' => string         Cache control header. Default: "public, max-age=86400"
75
     *
76
     * @throws ServeFailedException  if serving failed
77 5
     * @return  void
78 1
     */
79
    public static function serve($filename, $contentType, $options = [])
80
    {
81 5
        if (!file_exists($filename)) {
82 5
            Header::addHeader('X-WebP-Convert-Error: Could not read file');
83 2
            throw new ServeFailedException('Could not read file');
84
        }
85 5
86
        $options = self::processOptions($options);
87
88 1
        if ($options['headers']['last-modified']) {
89 1
            Header::setHeader("Last-Modified: " . gmdate("D, d M Y H:i:s", @filemtime($filename)) ." GMT");
90 1
        }
91
92
        if ($options['headers']['content-type']) {
93
            Header::setHeader('Content-Type: ' . $contentType);
94
        }
95 5
96 4
        if ($options['headers']['vary-accept']) {
97
            Header::addHeader('Vary: Accept');
98
        }
99 5
100
        if (!empty($options['cache-control-header'])) {
101
            if ($options['headers']['cache-control']) {
102
                Header::setHeader('Cache-Control: ' . $options['cache-control-header']);
103 5
            }
104
            if ($options['headers']['expires']) {
105
                // Add exprires header too (#126)
106
                // Check string for something like this: max-age:86400
107
                if (preg_match('#max-age\\s*=\\s*(\\d*)#', $options['cache-control-header'], $matches)) {
108
                    $seconds = $matches[1];
109
                    Header::setHeader('Expires: '. gmdate('D, d M Y H:i:s \G\M\T', time() + intval($seconds)));
110
                }
111
            }
112
        }
113
114
        if ($options['headers']['content-length']) {
115
            Header::setHeader('Content-Length: ' . filesize($filename));
116
        }
117
118
        if (@readfile($filename) === false) {
119
            Header::addHeader('X-WebP-Convert-Error: Could not read file');
120
            throw new ServeFailedException('Could not read file');
121
        }
122
    }
123
}
124