summaryrefslogtreecommitdiff
path: root/src/phorkie/Tools.php
blob: 2febb29a222907621137239122a2f83493254dfe (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
<?php
namespace phorkie;


class Tools
{
    /**
     * Delete an entire directory structure
     *
     * @param string $path Path to delete
     *
     * @return bool
     */
    public static function recursiveDelete($path)
    {
        if (!file_exists($path)) {
            return true;
        }
        if (!is_dir($path) || is_link($path)) {
            return unlink($path);
        }
        foreach (scandir($path) as $file) {
            if ($file == '.' || $file == '..') {
                continue;
            }
            $filepath = $path . DIRECTORY_SEPARATOR . $file;
            if (!static::recursiveDelete($filepath)) {
                return false;
            };
        }
        return rmdir($path);
    }

    /**
     * Create a full URL with protocol and host name
     *
     * @param string $path Path to the file, with leading /
     *
     * @return string Full URL
     */
    public static function fullUrl($path = '')
    {
        if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS']) {
            $prot = 'https';
        } else {
            $prot = 'http';
        }
        return $prot . '://' . $_SERVER['HTTP_HOST'] . $GLOBALS['phorkie']['cfg']['baseurl'] . $path;
    }

    /**
     * Get the full URL to a path, but remove the .phar file from
     * the base URL if necessary
     *
     * @param string $path Path to the file
     *
     * @return string Full URL without .phar/
     */
    public static function fullUrlNoPhar($path = '')
    {
        $base = static::fullUrl();
        if (substr($base, -6) == '.phar/') {
            $base = dirname($base) . '/';
        }
        return $base . $path;
    }

    /**
     * Removes malicious parts from a file name
     *
     * @param string $file File name from the user
     *
     * @return string Fixed and probably secure filename
     */
    public static function sanitizeFilename($file)
    {
        $file = trim($file);
        $file = str_replace(array('\\', '//'), '/', $file);
        $file = str_replace('/../', '/', $file);
        if (substr($file, 0, 3) == '../') {
            $file = substr($file, 3);
        }
        if (substr($file, 0, 1) == '../') {
            $file = substr($file, 1);
        }

        return $file;
    }


    public static function detectBaseUrl()
    {
        if (!isset($_SERVER['REQUEST_URI'])
            || !isset($_SERVER['SCRIPT_NAME'])
        ) {
            return '/';
        }

        $scriptName = $_SERVER['SCRIPT_NAME'];
        $requestUri = $_SERVER['REQUEST_URI'];
        if (substr($scriptName, -4) != '.php') {
            //a phar
            return $scriptName . '/';
        }

        if (isset($_GET['id'])) {
            $idp = strpos($requestUri, '/' . $_GET['id'] . '/');
            if ($idp !== false) {
                return substr($requestUri, 0, $idp) . '/';
            }
        }

        if (substr($requestUri, -4) != '.php') {
            $requestUri .= '.php';
        }
        $snl = strlen($scriptName);
        if (substr($requestUri, -$snl) == $scriptName) {
            return substr($requestUri, 0, -$snl) . '/';
        }

        return '/';
    }

    /**
     * Resolves "/../" and "/./" in file paths without validating them.
     */
    public static function foldPath($path)
    {
        $path = str_replace('/./', '/', $path);
        $path = str_replace('/./', '/', $path);
        $path = preg_replace('#/[^/]+/\.\./#', '/', $path);
        $path = preg_replace('#/[^/]+/\.\./#', '/', $path);
        return $path;
    }
}
?>