Completed
Push — master ( c79d57...cdca2b )
by Bjørn
02:46
created

src/Helpers/FileExists.php (1 issue)

Severity
1
<?php
2
3
namespace WebPConvert\Helpers;
4
5
/**
6
 * A fileExist function free of deception
7
 *
8
 * @package    WebPConvert
9
 * @author     Bjørn Rosell <[email protected]>
10
 * @since      Class available since Release 2.3.0
11
 */
12
class FileExists
13
{
14
15
    private static $lastWarning;
16
17
    /**
18
     * A warning handler that registers that a warning has occured and suppresses it.
19
     *
20
     * @return void
21
     */
22 1
    public static function warningHandler($errno, $errstr, $errfile, $errline)
23
    {
24 1
        self::$lastWarning = [$errstr, $errno];
25
26
        // Suppress the warning by returning void
27 1
        return;
28
    }
29
30
    /**
31
     * A well behaved replacement for file_exist that throws upon failure rather than emmitting a warning.
32
     *
33
     * @throws \Exception If file_exists threw a warning
34
     * @return boolean|null  True if file exists. False if it doesn't.
35
     */
36 1
    public static function honestFileExists($path)
37
    {
38
        // There is a challenges here:
39
        // We want to suppress warnings, but at the same time we want to know that it happened.
40
        // We achieve this by registering an error handler
41 1
        $previousErrorHandler = set_error_handler(
0 ignored issues
show
The assignment to $previousErrorHandler is dead and can be removed.
Loading history...
42 1
            array('WebPConvert\Helpers\FileExists', "warningHandler"),
43 1
            E_WARNING | E_USER_WARNING | E_NOTICE | E_USER_NOTICE
44
        );
45 1
        self::$lastWarning = null;
46 1
        $found = @file_exists($path);
47
48
        // restore previous error handler immediately
49 1
        restore_error_handler();
50
51
        // If file_exists returns true, we can rely on there being a file there
52 1
        if ($found) {
53 1
            return true;
54
        }
55
56
        // file_exists returned false.
57
        // this result is only trustworthy if no warning was emitted.
58 1
        if (is_null(self::$lastWarning)) {
59 1
            return false;
60
        }
61
62 1
        list($errstr, $errno) = self::$lastWarning;
63 1
        throw new \Exception($errstr, $errno);
64
    }
65
66
    /**
67
     * A fileExist based on an exec call.
68
     *
69
     * @throws \Exception  If exec cannot be called
70
     * @return boolean|null  True if file exists. False if it doesn't.
71
     */
72 1
    public static function fileExistsUsingExec($path)
73
    {
74 1
        if (!function_exists('exec')) {
75
            throw new \Exception(
76
                'cannot determine if file exists using exec() - the function is unavailable'
77
            );
78
        }
79
80
        // Lets try to find out by executing "ls path/to/cwebp"
81 1
        exec('ls ' . $path, $output, $returnCode);
82 1
        if (($returnCode == 0) && (isset($output[0]))) {
83 1
            return true;
84
        }
85
86
        // We assume that "ls" command is general available!
87
        // As that failed, we can conclude the file does not exist.
88 1
        return false;
89
    }
90
91
    /**
92
     * A fileExist doing the best it can.
93
     *
94
     * @throws \Exception  If it cannot be determined if the file exists
95
     * @return boolean|null  True if file exists. False if it doesn't.
96
     */
97
    public static function fileExistsTryHarder($path)
98
    {
99
        try {
100
            $result = self::honestFileExists($path);
101
        } catch (\Exception $e) {
102
            try {
103
                $result = self::fileExistsUsingExec($path);
104
            } catch (\Exception $e) {
105
                throw new \Exception('Cannot determine if file exists or not');
106
            }
107
        }
108
        return $result;
109
    }
110
}
111