Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 43
0.00% covered (danger)
0.00%
0 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
ServeConvertedWebPWithErrorHandling
0.00% covered (danger)
0.00%
0 / 43
0.00% covered (danger)
0.00%
0 / 4
210
0.00% covered (danger)
0.00%
0 / 1
 processOptions
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
6
 addHeadersPreventingCaching
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 performFailAction
0.00% covered (danger)
0.00%
0 / 21
0.00% covered (danger)
0.00%
0 / 1
72
 serve
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
12
1<?php
2namespace WebPConvert\Serve;
3
4use WebPConvert\Helpers\InputValidator;
5use WebPConvert\Options\Options;
6use WebPConvert\Options\StringOption;
7use WebPConvert\Serve\Header;
8use WebPConvert\Serve\Report;
9use WebPConvert\Serve\ServeConvertedWeb;
10use WebPConvert\Serve\Exceptions\ServeFailedException;
11use WebPConvert\Exceptions\WebPConvertException;
12
13/**
14 * Serve a converted webp image and handle errors.
15 *
16 * @package    WebPConvert
17 * @author     Bjørn Rosell <it@rosell.dk>
18 * @since      Class available since Release 2.0.0
19 */
20class ServeConvertedWebPWithErrorHandling
21{
22
23    /**
24     * Process options.
25     *
26     * @throws \WebPConvert\Options\Exceptions\InvalidOptionTypeException   If the type of an option is invalid
27     * @throws \WebPConvert\Options\Exceptions\InvalidOptionValueException  If the value of an option is invalid
28     * @param array $options
29     */
30    private static function processOptions($options)
31    {
32        $options2 = new Options();
33        $options2->addOptions(
34            new StringOption('fail', 'original', ['original', '404', 'throw', 'report']),
35            new StringOption('fail-when-fail-fails', 'throw', ['original', '404', 'throw', 'report'])
36        );
37        foreach ($options as $optionId => $optionValue) {
38            $options2->setOrCreateOption($optionId, $optionValue);
39        }
40        $options2->check();
41        return $options2->getOptions();
42    }
43
44    /**
45     *  Add headers for preventing caching.
46     *
47     *  @return  void
48     */
49    private static function addHeadersPreventingCaching()
50    {
51        Header::setHeader("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
52        Header::addHeader("Cache-Control: post-check=0, pre-check=0");
53        Header::setHeader("Pragma: no-cache");
54    }
55
56    /**
57     * Perform fail action.
58     *
59     * @param  string  $fail                Action to perform (original | 404 | report)
60     * @param  string  $failIfFailFails     Action to perform if $fail action fails
61     * @param  string  $source              path to source file
62     * @param  string  $destination         path to destination
63     * @param  array   $options (optional)  options for serving/converting
64     * @param  \Exception  $e               exception that was thrown when trying to serve
65     * @param   string  $serveClass         (optional) Full class name to a class that has a serveOriginal() method
66     * @return void
67     */
68    public static function performFailAction($fail, $failIfFailFails, $source, $destination, $options, $e, $serveClass)
69    {
70        self::addHeadersPreventingCaching();
71
72        Header::addLogHeader('Performing fail action: ' . $fail);
73
74        switch ($fail) {
75            case 'original':
76                try {
77                    //ServeConvertedWebP::serveOriginal($source, $options);
78                    call_user_func($serveClass . '::serveOriginal', $source, $options);
79                } catch (\Exception $e) {
80                    self::performFailAction($failIfFailFails, '404', $source, $destination, $options, $e, $serveClass);
81                }
82                break;
83
84            case '404':
85                $protocol = isset($_SERVER["SERVER_PROTOCOL"]) ? $_SERVER["SERVER_PROTOCOL"] : 'HTTP/1.0';
86                Header::setHeader($protocol . " 404 Not Found");
87                break;
88
89            case 'report':
90                $options['show-report'] = true;
91                Report::convertAndReport($source, $destination, $options);
92                break;
93
94            case 'throw':
95                throw $e;
96                //break;  commented out as phpstan complains. But do something else complain now?
97
98            case 'report-as-image':
99                // TODO: Implement or discard ?
100                break;
101        }
102    }
103
104    /**
105     * Serve webp image and handle errors as specified in the 'fail' option.
106     *
107     * This method basically wraps ServeConvertedWebP:serve in order to provide exception handling.
108     * The error handling is set with the 'fail' option and can be either '404', 'original' or 'report'.
109     * If set to '404', errors results in 404 Not Found headers being issued. If set to 'original', an
110     * error results in the original being served.
111     * Look up the ServeConvertedWebP:serve method to learn more.
112     *
113     * @param   string  $source              path to source file
114     * @param   string  $destination         path to destination
115     * @param   array   $options (optional)  options for serving/converting
116     *       Supported options:
117     *       - 'fail' => (string)    Action to take on failure (404 | original | report | throw).
118     *               "404" or "throw" is recommended for development and "original" is recommended for production.
119     *               Default: 'original'.
120     *       - 'fail-when-fail-fails'  => (string) Action to take if fail action also fails. Default: '404'.
121     *       - All options supported by WebPConvert::convert()
122     *       - All options supported by ServeFile::serve()
123     *       - All options supported by DecideWhatToServe::decide)
124     * @param  \WebPConvert\Loggers\BaseLogger $serveLogger (optional)
125     * @param  \WebPConvert\Loggers\BaseLogger $convertLogger (optional)
126     * @param   string  $serveClass     (optional) Full class name to a class that has a serve() method and a
127     *                                  serveOriginal() method
128     * @return  void
129     */
130    public static function serve(
131        $source,
132        $destination,
133        $options = [],
134        $serveLogger = null,
135        $convertLogger = null,
136        $serveClass = '\\WebPConvert\\Serve\\ServeConvertedWebP'
137    ) {
138
139        $options = self::processOptions($options);
140        try {
141            InputValidator::checkSourceAndDestination($source, $destination);
142            //ServeConvertedWebP::serve($source, $destination, $options, $serveLogger);
143            call_user_func($serveClass . '::serve', $source, $destination, $options, $serveLogger, $convertLogger);
144        } catch (\Exception $e) {
145            if ($e instanceof \WebPConvert\Exceptions\WebPConvertException) {
146                Header::addLogHeader($e->getShortMessage(), $serveLogger);
147            }
148
149            self::performFailAction(
150                $options['fail'],
151                $options['fail-when-fail-fails'],
152                $source,
153                $destination,
154                $options,
155                $e,
156                $serveClass
157            );
158        }
159    }
160}