Filesystem::fileWrite()   A
last analyzed

Complexity

Conditions 4
Paths 4

Size

Total Lines 17
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 8
nc 4
nop 3
dl 0
loc 17
rs 9.2
c 0
b 0
f 0
1
<?php
2
namespace Filesystem;
3
4
class Filesystem
5
{
6
7
    /**
8
     * Changes mode for files/directories.
9
     *
10
     * @param  string $path      path to the file or file
11
     * @param  int 	  $mode 	 mode
12
     * @param  bool   $recursive recursive file mode change
13
     * @return bool
14
     */
15
    final public static function chmod($path, $mode, $recursive = false)
16
    {
17
        $mode = self::fixFileModeFormat($mode);
18
        $recursive = ($recursive === false) ? '' : '-R';
19
        system("chmod {$recursive} {$mode} {$path} 2> /dev/null", $retval);
20
21
        if ($retval != 0)
22
        {
23
            throw new \RuntimeException(__METHOD__ . ": failed to change or update file permissions for {$path}");
24
        }
25
        return true;
26
    }
27
28
    /**
29
     * Changes group of file.
30
     *
31
     * @param  string $file      path to the file
32
     * @param  int 	  $group 	 file group
33
     * @param  bool   $recursive recursive file mode change
34
     * @return bool
35
     */
36
    final public static function chgrp($file, $group, $recursive = false)
37
    {
38
        $recursive = ($recursive === false) ? '' : '-R';
39
        system("chgrp {$recursive} {$group} {$file} 2> /dev/null", $retval);
40
41
        if ($retval != 0)
42
        {
43
            throw new \RuntimeException(__METHOD__ . ": failed to set file '{$file}' to {$group}");
44
        }
45
        return true;
46
    }
47
48
    /**
49
     * Copies file.
50
     *
51
     * @param  string $srcfile  path to the source file
52
     * @param  string $destfile path to the destination file
53
     * @return bool
54
     */
55
    final public static function copy($srcfile, $destfile)
56
    {
57
        self::fileExists($srcfile);
58
        if (@copy($srcfile, $destfile) === false)
59
        {
60
            throw new \RuntimeException(__METHOD__ . ": failed to create copy of '{$srcfile}' to '{$destfile}'");
61
        }
62
        return true;
63
    }
64
    
65
    /**
66
     * Removes file.
67
     *
68
     * @param  string $file   file name
69
     * @param  bool   $strict strict error checking
70
     * @return bool
71
     */
72
    final public static function delete($file, $strict = true)
73
    {
74
        self::fileExists($file);
75
        if (@unlink($file) === false)
76
        {
77
            if ($strict)
78
            {
79
                throw new \RuntimeException(__METHOD__ . ": failed to delete {$file}");
80
            }
81
            return false;
82
        }
83
        return true;
84
    }
85
86
    /**
87
     * Removes files.
88
     *
89
     * @param  array  $files   file names
90
     * @param  bool   $strict strict error checking
91
     * @return bool
92
     */
93
    final public static function deleteFiles($files, $strict = true)
94
    {
95
        foreach ($files as $file)
96
        {
97
            self::delete($file, $strict);
98
        }
99
        return true;
100
    }
101
    
102
    /**
103
     * Returns pathnames matching a pattern (for files only & hidden files).
104
     *
105
     * @param  string $directory directory
106
     * @param  mixed  $pattern   pattern (does not support tilde expansion)
107
     * @return mixed
108
     */
109
    final public static function glob($directory, $pattern = null)
110
    {
111
        self::dirExists($directory);
112
113
        $pattern = is_array(($pattern)) ? '{' . implode(',', $pattern) . '}' : $pattern;
114
        if ($pattern === null)
115
        {
116
            return array_diff(glob($directory . '/*'), ['.', '..']);
117
        }
118
        return glob($directory . '/{,.}*' . $pattern . '*', GLOB_BRACE);
119
    }
120
121
    /**
122
     * Create new directory.
123
     *
124
     * @param  mixed  $directory   path to the directory
125
     * @param  int    $mode        directory permission mode value (octal)
126
     * @param  bool   $recursive   create directories as needed
127
     * @param  bool   $strict      strict error checking
128
     * @return bool
129
     */
130
    final public static function mkdir($directory, $mode = 0777, $recursive = false, $strict = true)
131
    {
132
        if (self::dirExists($directory, false))
133
        {
134
            return false;
135
        }
136
137
        if (@mkdir($directory, self::fixFileModeFormat($mode), $recursive) === false)
138
        {
139
            if ($strict)
140
            {
141
                throw new \RuntimeException(__METHOD__ . ": failed to create new directory {$directory}");
142
            }
143
            return false;
144
        }
145
        return true;
146
    }
147
    
148
    /**
149
     * Create new directories.
150
     *
151
     * @param  mixed  $directories path to the directories
152
     * @param  int    $mode        directory permission mode value (octal)
153
     * @param  bool   $recursive   create directories as needed
154
     * @param  bool   $strict      strict error checking
155
     * @return bool
156
     */
157
    final public static function mkdirs($directories, $mode = 0777, $recursive = false, $strict = true)
158
    {
159
        foreach ($directories as $directory)
160
        {
161
            self::mkdir($directory, $mode, $recursive, $strict);
162
            self::chmod($directory, $mode);
163
        }
164
        return true;
165
    }
166
167
    /**
168
     * Removes a directory.
169
     *
170
     * @param  string   $directory  directory to remove
171
     * @param  bool     $strict     strict error checking
172
     * @return mixed
173
     */
174
    final public static function rmdir($directory, $strict = true)
175
    {
176
        self::dirExists($directory);
177
178
        // Remove any files, if found in directory
179
        if (count(($files = self::glob($directory))) > 0)
180
        {
181
            self::deleteFiles($files);
182
        }
183
        
184
        if (@rmdir($directory) === false)
185
        {
186
            if ($strict)
187
            {
188
                throw new \RuntimeException(__METHOD__ . ": failed to delete directory '{$directory}'");
189
            }
190
            return false;
191
        }
192
        return true;
193
    }
194
195
    /**
196
     * Removes a directories.
197
     *
198
     * @param  array    $directories  directories to remove
199
     * @param  bool     $strict       strict error checking
200
     * @return mixed
201
     */
202
    final public static function rmdirs($directories, $strict = true)
203
    {
204
        foreach ($directories as $directory)
205
        {
206
            self::rmdir($directory, $strict);
207
        }
208
        return true;
209
    }
210
211
    /**
212
     * Moves file to different path (rename).
213
     *
214
     * @param  string $old_file path to the old file
215
     * @param  string $new_file path to the new file
216
     * @return bool
217
     */
218
    final public static function rename($old_file, $new_file)
219
    {
220
        self::fileExists($old_file);
221
        if (!@rename($old_file, $new_file))
222
        {
223
            throw new \RuntimeException(__METHOD__ . ": failed to move '{$old_file}' to '{$new_file}'");
224
        }
225
        return true;
226
    }
227
    
228
    /*
229
     * Write content to file.
230
     *
231
     * @param  string $filename file name
232
     * @param  string $content  content
233
     * @param  bool   $append   append to file
234
     * @return void
235
     */
236
    final public static function fileWrite($filename, $content, $append = false)
237
    {
238
        if ($append !== false)
239
        {
240
            @file_put_contents($filename, $content, FILE_APPEND | LOCK_EX);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for file_put_contents(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

240
            /** @scrutinizer ignore-unhandled */ @file_put_contents($filename, $content, FILE_APPEND | LOCK_EX);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
241
        }
242
        else
243
        {
244
            @file_put_contents($filename, $content);
245
        }
246
        
247
        $filesize = @filesize($filename);
248
        if ($filesize === false || $filesize == 0)
249
        {
250
            throw new \RuntimeException(__METHOD__ . ": failed to write contents to file: {$filename}");
251
        }
252
        return;
253
    }
254
    
255
    /*
256
     * Return file content.
257
     *
258
     * @param  string $filename file name
259
     * @return string
260
     */
261
    final public static function fileContent($filename)
262
    {
263
        $content = @file_get_contents($filename);
264
265
        if (empty($content) || $content === false)
266
        {
267
            throw new \RuntimeException(__METHOD__ . ": failed to retrieve contents of file: {$filename}");
268
        }
269
        return $content;
270
    }
271
    
272
    /**
273
     * Create temporary file.
274
     *
275
     * @param  string $template temporary filename template (default=tmp-XXXXXXXXXXXXXX)
276
     * @param  bool   $resource request file pointer into temporary file
277
     * @return mixed
278
     */
279
    final public static function tmpfile($template = null, $resource = false)
280
    {
281
        $template = ($template === null) ? "tmp.XXXXXXXXXXXXXX" : "{$template}.XXXXXXXXXXXXXX";
282
        $tempfile = shell_exec("mktemp -p /tmp {$template}");
283
        return ($resource === false) ? rtrim($tempfile) : fopen($tempfile, "w+");
284
    }
285
286
    /**
287
     * Create temporary directory.
288
     *
289
     * @param  string $template temporary directory template (default=tmpXXXXXXXXXXXXXX)
290
     * @return mixed
291
     */
292
    final public static function tmpdir($template = null)
293
    {
294
        $template = ($template === null) ? "tmpXXXXXXXXXXXXXX" : "{$template}xxxxxxxxxxxxxx";
295
        $tempdir = shell_exec("mktemp -p /tmp -d {$template}");
296
        return rtrim($tempdir);
297
    }
298
299
    /**
300
     * Fix mode to proper formats.
301
     *
302
     * @param  int   $mode file mode
303
     * @return int
304
     */
305
    final private static function fixFileModeFormat($mode)
306
    {
307
        if (preg_match('/^[0-9]{3}$/', $mode))
308
        {
309
            return (int) str_pad(decoct($mode), 4, '0', STR_PAD_LEFT);
310
        }
311
        return $mode;
312
    }
313
    
314
    /**
315
     * Checks if directory exists;.
316
     *
317
     * @param  string $directory directory name
318
     * @param  bool   $strict    strict error checking
319
     * @return bool
320
     */
321
    final public static function dirExists($directory, $strict = true)
322
    {
323
        if (!file_exists($directory))
324
        {
325
            if ($strict)
326
            {
327
                throw new \RuntimeException(__METHOD__ . ": directory doesn't exist: {$directory}.");
328
            }
329
            return false;
330
        }
331
        return true;
332
    }
333
334
    /**
335
     * Checks if file exists;.
336
     *
337
     * @param  string $file     file name
338
     * @param  bool   $strict   strict error checking
339
     * @return bool
340
     */
341
    final public static function fileExists($file, $strict = true)
342
    {
343
        if (!file_exists($file))
344
        {
345
            if ($strict)
346
            {
347
                throw new \RuntimeException(__METHOD__ . ": file doesn't exist: {$file}.");
348
            }
349
            return false;
350
        }
351
        return true;
352
    }
353
354
}
355