Completed
Push — master ( 283031...763f93 )
by Mihail
02:33
created

File::inc()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 14
rs 8.8571
cc 5
eloc 8
nc 5
nop 3
1
<?php
2
3
namespace Ffcms\Core\Helper\FileSystem;
4
5
use Ffcms\Core\Helper\Type\Arr;
6
use Ffcms\Core\Helper\Type\Str;
7
8
/**
9
 * Class File. Provide methods to work with files in current filesystem.
10
 * @package Ffcms\Core\Helper
11
 */
12
class File
13
{
14
15
    /**
16
     * Read file content from local storage
17
     * @param $path
18
     * @return bool|string
19
     */
20
    public static function read($path)
21
    {
22
        $path = Normalize::diskFullPath($path);
23
24
        if (!self::exist($path)) {
25
            return false;
26
        }
27
28
        return @file_get_contents($path);
29
    }
30
31
    /**
32
     * Check if $path is exist and readable in filesystem
33
     * @param string $path
34
     * @return bool
35
     */
36
    public static function exist($path)
37
    {
38
        $path = Normalize::diskFullPath($path);
39
        return (file_exists($path) && is_readable($path) && is_file($path));
40
    }
41
42
    /**
43
     * Alias for exist method
44
     * @param string $path
45
     * @return bool
46
     */
47
    public static function readable($path) {
48
        return self::exist($path);
49
    }
50
51
    /**
52
     * Check is file writable
53
     * @param string $path
54
     * @return bool
55
     */
56 View Code Duplication
    public static function writable($path)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
57
    {
58
        $path = Normalize::diskFullPath($path);
59
60
        if (!self::exist($path)) {
61
            return false;
62
        }
63
64
        return is_writable($path);
65
    }
66
67
    /**
68
     * Check is file executable
69
     * @param string $path
70
     * @return bool
71
     */
72
    public static function executable($path)
73
    {
74
        $path = Normalize::diskFullPath($path);
75
76
        if (!self::exist($path)) {
77
            return false;
78
        }
79
80
        return is_executable($path);
81
    }
82
83
    /**
84
     * @param string $path
85
     * @param null|string $content
86
     * @param null|int $flags
87
     * @return int
88
     */
89
    public static function write($path, $content = null, $flags = null)
90
    {
91
        $path = Normalize::diskFullPath($path);
92
93
        $pathArray = explode(DIRECTORY_SEPARATOR, $path);
94
        array_pop($pathArray);
95
        $pathName = implode(DIRECTORY_SEPARATOR, $pathArray);
96
97
        if (Directory::exist($pathName)) {
98
            Directory::create($pathName);
99
        }
100
        return @file_put_contents($path, $content, $flags);
101
    }
102
103
    /**
104
     * Remove file
105
     * @param string $path
106
     * @return bool
107
     */
108
    public static function remove($path)
109
    {
110
        $path = Normalize::diskFullPath($path);
111
112
        if (!self::exist($path)) {
113
            return false;
114
        }
115
        return unlink($path);
116
    }
117
118
119
    /**
120
     * Alternative of functions include, require, include_once and etc in 1 function
121
     * @param string $path
122
     * @param bool|false $return
123
     * @param bool|false $once
124
     * @return bool|mixed
125
     */
126
    public static function inc($path, $return = false, $once = false)
127
    {
128
        $path = Normalize::diskFullPath($path);
129
130
        if (!self::exist($path)) {
131
            return false;
132
        }
133
134
        if ($return === true) {
135
            return $once === true ? require_once($path) : require $path;
136
        } else {
137
            ($once == true) ? require_once($path) : require $path;
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
138
        }
139
    }
140
141
    /**
142
     * Get file make time in unix timestamp
143
     * @param string $path
144
     * @return int
145
     */
146
    public static function mTime($path)
147
    {
148
        $path = Normalize::diskFullPath($path);
149
        if (!self::exist($path)) {
150
            return 0;
151
        }
152
153
        return filemtime($path);
154
    }
155
156
    /**
157
     * Recursive scan directory, based on $path and allowed extensions $ext or without it
158
     * @param string $path
159
     * @param array $ext
160
     * @param bool $returnRelative
161
     * @param $files
162
     * @return array
163
     */
164
    public static function listFiles($path, array $ext = null, $returnRelative = false, &$files = [])
165
    {
166
        $path = Normalize::diskFullPath($path);
167
168
        if (!Directory::exist($path)) {
169
            return [];
170
        }
171
172
        $dir = opendir($path . '/.');
173
        while ($item = readdir($dir)) {
174
            if (is_file($sub = $path . '/' . $item)) {
175
                $item_ext = Str::lastIn($item, '.');
176
                if ($ext === null || Arr::in($item_ext, $ext)) {
0 ignored issues
show
Security Bug introduced by
It seems like $item_ext defined by \Ffcms\Core\Helper\Type\Str::lastIn($item, '.') on line 175 can also be of type false; however, Ffcms\Core\Helper\Type\Arr::in() does only seem to accept string, did you maybe forget to handle an error condition?

This check looks for type mismatches where the missing type is false. This is usually indicative of an error condtion.

Consider the follow example

<?php

function getDate($date)
{
    if ($date !== null) {
        return new DateTime($date);
    }

    return false;
}

This function either returns a new DateTime object or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returned false before passing on the value to another function or method that may not be able to handle a false.

Loading history...
177
                    if ($returnRelative) {
178
                        $files[] = $item;
179
                    } else {
180
                        $files[] = $path . DIRECTORY_SEPARATOR . $item;
181
                    }
182
                }
183
            } else {
184
                if ($item !== '.' && $item !== '..') {
185
                    self::listFiles($sub, $ext, $returnRelative, $files);
186
                }
187
            }
188
        }
189
190
        return $files;
191
    }
192
193
    /**
194
     * Get file size in bytes
195
     * @param string $path
196
     * @return int
197
     */
198
    public static function size($path)
199
    {
200
        $path = Normalize::diskFullPath($path);
201
202
        if (!self::exist($path)) {
203
            return 0;
204
        }
205
206
        return filesize($path);
207
    }
208
209
    /**
210
     * Get data from remote $url by curl library
211
     * @param string $url
212
     * @return mixed|null|false
213
     */
214
    public static function getFromUrl($url)
215
    {
216
        // check is valid url
217
        if (!filter_var($url, FILTER_VALIDATE_URL) || !function_exists('curl_init')) {
218
            return null;
219
        }
220
221
        // initialize curl & set required options and target url
222
        $curl = \curl_init();
223
        \curl_setopt($curl, CURLOPT_URL, $url);
224 View Code Duplication
        if (Str::startsWith('https', $url)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
225
            \curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
226
            \curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
227
        }
228
        \curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
229
        \curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 5);
230
        \curl_setopt($curl, CURLOPT_HEADER, 0);
231
        \curl_setopt($curl, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322)');
232
        \curl_setopt($curl, CURLOPT_FAILONERROR, true);
233
        \curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
234
        \curl_setopt($curl, CURLOPT_AUTOREFERER, true);
235
        \curl_setopt($curl, CURLOPT_TIMEOUT, 10);
236
        $content = \curl_exec($curl);
237
        \curl_close($curl);
238
239
        return $content;
240
    }
241
242
    /**
243
     * Download file from $url and save it into $path
244
     * @param string $url
245
     * @param string $path
246
     * @return bool
247
     */
248
    public static function saveFromUrl($url, $path)
249
    {
250
        if (!filter_var($url, FILTER_VALIDATE_URL) || !function_exists('curl_init')) {
251
            return false;
252
        }
253
254
        $path = Normalize::diskFullPath($path);
255
        // initialize stream resource
256
        $stream = @fopen($path, 'w');
257
        // initialize curl & set required options, target url, destination save stream
258
        $curl = \curl_init();
259
        \curl_setopt($curl, CURLOPT_URL, $url);
260 View Code Duplication
        if (Str::startsWith('https', $url)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
261
            \curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
262
            \curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
263
        }
264
        \curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
265
        \curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 5);
266
        \curl_setopt($curl, CURLOPT_HEADER, 0);
267
        \curl_setopt($curl, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322');
268
        \curl_setopt($curl, CURLOPT_FAILONERROR, true);
269
        \curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
270
        \curl_setopt($curl, CURLOPT_AUTOREFERER, true);
271
        \curl_setopt($curl, CURLOPT_TIMEOUT, 10);
272
        // set destination file path
273
        \curl_setopt($curl, CURLOPT_FILE, $stream);
274
        \curl_exec($curl);
275
        \curl_close($curl);
276
        fclose($stream);
277
278
        return true;
279
    }
280
281
}