Completed
Branch master (fd4772)
by Pierre-Henry
37:10
created

File::getModifTime()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 2
nc 2
nop 1
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 23 and the first side effect is on line 14.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
2
/**
3
 * @title            File Class
4
 * @desc             Useful methods for handling files.
5
 *
6
 * @author           Pierre-Henry Soria <[email protected]>
7
 * @copyright        (c) 2012-2017, Pierre-Henry Soria. All Rights Reserved.
8
 * @license          GNU General Public License; See PH7.LICENSE.txt and PH7.COPYRIGHT.txt in the root directory.
9
 * @package          PH7 / Framework / File
10
 */
11
12
namespace PH7\Framework\File;
13
14
defined('PH7') or exit('Restricted access');
15
16
use PH7\Framework\Server\Server;
17
use PH7\Framework\Url\Url;
18
use PH7\Framework\Parse\Url as ParseUrl;
19
use PH7\Framework\Navigation\Browser;
20
use PH7\Framework\Registry\Registry;
21
use PH7\Framework\Error\CException\PH7InvalidArgumentException;
22
23
class File
24
{
25
    // End Of Line relative to the operating system
26
    const EOL = PHP_EOL;
27
28
    /**
29
     * Mime Types list.
30
     *
31
     * @staticvar array $_aMimeTypes
32
     */
33
    private static $_aMimeTypes = [
34
        'pdf' => 'application/pdf',
35
        'txt' => 'text/plain',
36
        'html' => 'text/html',
37
        'htm' => 'text/html',
38
        'exe' => 'application/octet-stream',
39
        'zip' => 'application/zip',
40
        'doc' => 'application/msword',
41
        'xls' => 'application/vnd.ms-excel',
42
        'ppt' => 'application/vnd.ms-powerpoint',
43
        'gif' => 'image/gif',
44
        'png' => 'image/png',
45
        'jpeg' => 'image/jpg',
46
        'jpg' => 'image/jpg',
47
        'ico' => 'image/x-icon',
48
        'eot' => 'application/vnd.ms-fontobject',
49
        'otf' => 'application/octet-stream',
50
        'ttf' => 'application/octet-stream',
51
        'woff' => 'application/octet-stream',
52
        'svg' => 'application/octet-stream',
53
        'swf' => 'application/x-shockwave-flash',
54
        'mp3' => 'audio/mpeg',
55
        'mp4' => 'video/mp4',
56
        'mov' => 'video/quicktime',
57
        'avi' => 'video/x-msvideo',
58
        'php' => 'text/plain',
59
    ];
60
61
    /**
62
     * @param string $sExt Extension File.
63
     * @return string (string | null) Returns the "mime type" if it is found, otherwise "null"
64
     */
65
    public function getMimeType($sExt)
66
    {
67
        return (array_key_exists($sExt, static::$_aMimeTypes)) ? static::$_aMimeTypes[$sExt] : null;
0 ignored issues
show
Bug introduced by
Since $_aMimeTypes is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $_aMimeTypes to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return static::$someVariable;
    }
}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass { }

YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class SomeClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return self::$someVariable; // self works fine with private.
    }
}
Loading history...
68
    }
69
70
    /**
71
     * Get Extension file without the dot.
72
     *
73
     * @param string $sFile The File Name.
74
     * @return string
75
     */
76
    public function getFileExt($sFile)
77
    {
78
        return strtolower(substr(strrchr($sFile, PH7_DOT), 1));
79
    }
80
81
    /**
82
     * Get File without Extension and dot.
83
     * This function is smarter than just a code like this, substr($sFile,0,strpos($sFile,'.'))
84
     * Just look at the example below for you to realize that the function removes only the extension and nothing else!
85
     * Example 1 "my_file.pl" The return value is "my_file"
86
     * Example 2 "my_file.inc.pl" The return value is "my_file.inc"
87
     * Example 3 "my_file.class.html.php" The return value is "my_file.class.html"
88
     *
89
     * @see File::getFileExt() To see the method that retrieves the file extension.
90
     * @param string $sFile
91
     * @return string
92
     */
93
    public function getFileWithoutExt($sFile)
94
    {
95
        $sExt = $this->getFileExt($sFile);
96
        return str_replace(PH7_DOT . $sExt, '', $sFile);
97
    }
98
99
    /**
100
     * Get File Contents.
101
     *
102
     * @param string $sFile File name.
103
     * @param boolean $bIncPath Default FALSE
104
     * @return mixed (string | boolean) Returns the read data or FALSE on failure.
105
     */
106
    public function getFile($sFile, $bIncPath = false)
107
    {
108
        return @file_get_contents($sFile, $bIncPath);
109
    }
110
111
    /**
112
     * Put File Contents.
113
     *
114
     * @param string $sFile File name.
115
     * @param string $sContents Contents file.
116
     * @param integer $iFlag Constant (see http://php.net/manual/function.file-put-contents.php). Default 0
117
     * @return mixed (integer | boolean) Returns the number of bytes that were written to the file, or FALSE on failure.
118
     */
119
    public function putFile($sFile, $sContents, $iFlag = 0)
120
    {
121
        return @file_put_contents($sFile, $sContents, $iFlag);
122
    }
123
124
    /**
125
     * Check if file exists.
126
     *
127
     * @param mixed (array | string) $mFile
128
     * @return boolean TRUE if file exists, FALSE otherwise.
129
     */
130
    public function existFile($mFile)
131
    {
132
        $bExists = false; // Default value
133
134
        if (is_array($mFile))
135
        {
136
            foreach ($mFile as $sFile) {
137
                if (!$bExists = $this->existFile($sFile)) {
138
                    return false;
139
                }
140
            }
141
        }
142
        else
143
        {
144
            $bExists = is_file($mFile);
145
        }
146
147
        return $bExists;
148
    }
149
150
    /**
151
     * Check if directory exists.
152
     *
153
     * @param mixed (array | string) $mDir
154
     * @return boolean TRUE if file exists, FALSE otherwise.
155
     */
156
    public function existDir($mDir)
157
    {
158
        $bExists = false; // Default value
159
160
        if (is_array($mDir))
161
        {
162
            foreach ($mDir as $sDir) {
163
                if (!$bExists = $this->existDir($sDir)) {
164
                    return false;
165
                }
166
            }
167
        }
168
        else
169
        {
170
            $bExists = is_dir($mDir);
171
        }
172
173
        return $bExists;
174
    }
175
176
    /**
177
     * @param string $sDir The directory.
178
     * @return array The list of the folder that is in the directory.
179
     */
180
    public function getDirList($sDir)
181
    {
182
        $aDirList = array();
183
184
        if ($rHandle = opendir($sDir))
185
        {
186
            while (false !== ($sFile = readdir($rHandle)))
187
            {
188
                if ($sFile != '.' && $sFile != '..' && is_dir($sDir . PH7_DS . $sFile))
189
                    $aDirList[] = $sFile;
190
            }
191
            asort($aDirList);
192
            reset($aDirList);
193
        }
194
        closedir($rHandle);
195
        return $aDirList;
196
    }
197
198
    /**
199
     * Get file size.
200
     *
201
     * @param string $sFile
202
     * @return integer The size of the file in bytes.
203
     */
204
    public function size($sFile)
205
    {
206
        return (int) @filesize($sFile);
207
    }
208
209
    /**
210
     * @param string $sDir
211
     * @param mixed (string | array) $mExt Optional, retrieves only files with specific extensions. Default value is NULL.
212
     * @return array List of files sorted alphabetically.
213
     */
214
    public function getFileList($sDir, $mExt = null)
215
    {
216
        $aTree = array();
217
        $sDir = $this->checkExtDir($sDir);
218
219
        if (is_dir($sDir) && $rHandle = opendir($sDir))
220
        {
221
            while (false !== ($sF = readdir($rHandle)))
222
            {
223
                if ($sF !== '.' && $sF !== '..')
224
                {
225
                    if (is_dir($sDir . $sF))
226
                    {
227
                        $aTree = array_merge($aTree, $this->getFileList($sDir . $sF, $mExt));
228
                    }
229
                    else
230
                    {
231
                        if (!empty($mExt))
232
                        {
233
                            $aExt = (array) $mExt;
234
235
                            foreach ($aExt as $sExt)
236
                            {
237
                                if (substr($sF, -strlen($sExt)) === $sExt)
238
                                    $aTree[] = $sDir . $sF;
239
                            }
240
                        }
241
                        else
242
                        {
243
                            $aTree[] = $sDir . $sF;
244
                        }
245
                    }
246
                }
247
            }
248
            sort($aTree);
249
        }
250
        closedir($rHandle);
0 ignored issues
show
Bug introduced by
The variable $rHandle does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
251
        return $aTree;
252
    }
253
254
    /**
255
     * Make sure that folder names have a trailing.
256
     *
257
     * @param string $sDir The directory.
258
     * @param bool $bStart for check extension directory start. Default FALSE
259
     * @param bool $bEnd for check extension end. Default TRUE
260
     * @return string $sDir Directory
261
     */
262
    public function checkExtDir($sDir, $bStart = false, $bEnd = true)
263
    {
264
        $bIsWindows = Server::isWindows();
265
266
        if (!$bIsWindows && $bStart === true && substr($sDir, 0, 1) !== PH7_DS)
267
            $sDir = PH7_DS . $sDir;
268
269
        if ($bEnd === true && substr($sDir, -1) !== PH7_DS)
270
            $sDir .= PH7_DS;
271
272
        return $sDir;
273
    }
274
275
    /**
276
     * Creates a directory if they are in an array. If it does not exist and
277
     * allows the creation of nested directories specified in the pathname.
278
     *
279
     * @param mixed (string | array) $mDir
280
     * @param integer (octal) $iMode Default: 0777
281
     * @return void
282
     * @throws Exception If the file cannot be created.
283
     */
284
    public function createDir($mDir, $iMode = 0777)
285
    {
286
        if (is_array($mDir))
287
        {
288
            foreach ($mDir as $sD) $this->createDir($sD);
289
        }
290
        else
291
        {
292
            if (!is_dir($mDir))
293
                if (!@mkdir($mDir, $iMode, true))
294
                    throw new Exception('Error to create file: \'' . $mDir . '\'<br /> Please verify that the directory permission is in writing mode.');
295
        }
296
    }
297
298
    /**
299
     * Copy files and checks if the "from file" exists.
300
     *
301
     * @param string $sFrom File.
302
     * @param string $sTo File.
303
     * @return boolean
304
     */
305
    public function copy($sFrom, $sTo)
306
    {
307
        if (!is_file($sFrom)) return false;
308
309
        return @copy($sFrom, $sTo);
310
    }
311
312
    /**
313
     * Copy the contents of a directory into another.
314
     *
315
     * @param string $sFrom Old directory.
316
     * @param string $sTo New directory.
317
     * @return boolean TRUE if everything went well, otherwise FALSE if the "from directory" couldn't be found or if it couldn't be copied.
318
     */
319
    public function copyDir($sFrom, $sTo)
320
    {
321
        return $this->_recursiveDirIterator($sFrom, $sTo, 'copy');
322
    }
323
324
    /**
325
     * Copy a file or directory with the Unix cp command.
326
     *
327
     * @param string $sFrom File or directory.
328
     * @param string $sTo File or directory.
329
     * @return mixed (integer | boolean) Returns the last line on success, and FALSE on failure.
330
     */
331
    public function systemCopy($sFrom, $sTo)
332
    {
333
        if (file_exists($sFrom))
334
            return system("cp -r $sFrom $sTo");
335
336
        return false;
337
    }
338
339
    /**
340
     * Rename a file or directory and checks if the "from file" or directory exists with file_exists() function
341
     * since it checks the existance of a file or directory (because, as in the Unix OS, a directory is a file).
342
     *
343
     * @param string $sFrom File or directory.
344
     * @param string $sTo File or directory.
345
     * @return boolean
346
     */
347
    public function rename($sFrom, $sTo)
348
    {
349
        if (!file_exists($sFrom)) return false;
350
351
        return @rename($sFrom, $sTo);
352
    }
353
354
    /**
355
     * Rename the contents of a directory into another.
356
     *
357
     * @param string $sFrom Old directory.
358
     * @param string $sTo New directory.
359
     * @return boolean TRUE if everything went well, otherwise FALSE if the "from directory" couldn't be found or if it couldn't be renamed.
360
     */
361
    public function renameDir($sFrom, $sTo)
362
    {
363
        return $this->_recursiveDirIterator($sFrom, $sTo, 'rename');
364
    }
365
366
    /**
367
     * Rename a file or directory with the Unix mv command.
368
     *
369
     * @param string $sFrom File or directory.
370
     * @param string $sTo File or directory.
371
     * @return mixed (integer | boolean) Returns the last line on success, and FALSE on failure.
372
     */
373
    public function systemRename($sFrom, $sTo)
374
    {
375
        if (file_exists($sFrom))
376
            return system("mv $sFrom $sTo");
377
378
        return false;
379
    }
380
381
    /**
382
     * Deletes a file or files if they are in an array.
383
     * If the file does not exist, the function does nothing.
384
     *
385
     * @param mixed (string | array) $mFile
386
     * @return void
387
     */
388
    public function deleteFile($mFile)
389
    {
390
        if (is_array($mFile))
391
            foreach ($mFile as $sF) $this->deleteFile($sF);
392
        else
393
            if (is_file($mFile)) @unlink($mFile);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

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...
394
    }
395
396
    /**
397
     * For deleting Directory and files!
398
     * A "rmdir" function improved PHP which also delete files in a directory.
399
     *
400
     * @param string $sPath The path
401
     * @return boolean
402
     */
403
    public function deleteDir($sPath)
404
    {
405
        return (is_file($sPath) ? unlink($sPath) : (is_dir($sPath) ? array_map(array($this, 'deleteDir'), glob($sPath . '/*')) === @rmdir($sPath) : false));
406
    }
407
408
    /**
409
     * Remove the contents of a directory.
410
     *
411
     * @param string $sDir
412
     * @return void
413
     */
414
    public function remove($sDir)
415
    {
416
        $oIterator = new \RecursiveIteratorIterator($this->getDirIterator($sDir), \RecursiveIteratorIterator::CHILD_FIRST);
417
        foreach ($oIterator as $sPath) ($sPath->isFile()) ? unlink($sPath) : @rmdir($sPath);
418
        @rmdir($sDir);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

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...
419
    }
420
421
    /**
422
     * Get the creation/modification time of a file in the Unix timestamp.
423
     *
424
     * @param string Full path of the file.
425
     * @return mixed (integer | boolean) Returns the time the file was last modified, or FALSE if it not found.
426
     */
427
    public function getModifTime($sFile)
428
    {
429
        return (is_file($sFile)) ? filemtime($sFile) : false;
430
    }
431
432
    /**
433
     * Get the version of a file based on the its latest modification.
434
     * Shortened form of self::getModifTime()
435
     *
436
     * @param string Full path of the file.
437
     * @return integer Returns the latest modification time of the file in Unix timestamp.
438
     */
439
    public static function version($sFile)
440
    {
441
        return @filemtime($sFile);
442
    }
443
444
    /**
445
     * Delay script execution.
446
     *
447
     * @param integer $iSleep Halt time in seconds. Optional parameter, default value is 5.
448
     * @return mixed (integer | boolean) Returns "0" on success, or "false" on error.
449
     */
450
    public function sleep($iSleep = null)
451
    {
452
        $iSleep = (!empty($iSleep)) ? $iSleep : 5;
453
        return sleep($iSleep);
454
    }
455
456
    /**
457
     * Changes permission on a file or directory.
458
     *
459
     * @param string $sFile
460
     * @param integer $iMode Octal Permission for the file.
461
     * @return boolean
462
     */
463
    public function chmod($sFile, $iMode)
464
    {
465
        // file_exists function verify the existence of a "file" or "folder"!
466
        if (file_exists($sFile) && $this->getOctalAccess($sFile) !== $iMode)
0 ignored issues
show
Unused Code Bug introduced by
The strict comparison !== seems to always evaluate to true as the types of $this->getOctalAccess($sFile) (string) and $iMode (integer) can never be identical. Maybe you want to use a loose comparison != instead?
Loading history...
467
            return @chmod($sFile, $iMode);
468
469
        return false;
470
    }
471
472
    /**
473
     * @param string $sFile
474
     * @return string Octal Permissions.
475
     */
476
    public function getOctalAccess($sFile)
477
    {
478
        clearstatcache();
479
        return substr(sprintf('%o', fileperms($sFile)), -4);
480
    }
481
482
    /**
483
     * @param string $sData
484
     * @return string
485
     */
486
    public function pack($sData)
487
    {
488
        return urlencode(serialize($sData));
489
    }
490
491
    /**
492
     * Get the size of a directory.
493
     *
494
     * @param string $sPath
495
     * @return integer The size of the file in bytes.
496
     */
497
    public function getDirSize($sPath)
498
    {
499
        if (!is_dir($sPath)) return 0;
500
        if (!($rHandle = opendir($sPath))) return 0;
501
502
        $iSize = 0;
503
        while (false !== ($sFile = readdir($rHandle)))
504
        {
505
            if ($sFile != '.' && $sFile != '..')
506
            {
507
                $sFullPath = $sPath . PH7_DS . $sFile;
508
509
                if (is_dir($sFullPath))
510
                    $iSize = $this->getDirSize($sFullPath);
511
                else
512
                    $iSize += $this->size($sFullPath);
513
            }
514
        }
515
        closedir($rHandle);
516
517
        return $iSize;
518
    }
519
520
    /**
521
     * Get free space of a directory.
522
     *
523
     * @param string $sPath
524
     * @return float The number of available bytes as a float.
525
     */
526
    public function getDirFreeSpace($sPath)
527
    {
528
        return disk_free_space($sPath);
529
    }
530
531
    /**
532
     * @param string $sData
533
     * @return mixed (boolean, integer, float, string, array or object)
534
     */
535
    public function unpack($sData)
536
    {
537
        return unserialize(urldecode($sData));
538
    }
539
540
    /**
541
     * For download file.
542
     *
543
     * @param string $sFile File to download.
544
     * @param string $sName A name for the file to download.
545
     * @param string $sMimeType Optional, default value is NULL.
546
     * @return void
547
     */
548
    public function download($sFile, $sName, $sMimeType = null)
549
    {
550
        /*
551
          This function takes a path to a file to output ($sFile),
552
          the filename that the browser will see ($sName) and
553
          the MIME type of the file ($sMimeType, optional).
554
555
          If you want to do something on download abort/finish,
556
          register_shutdown_function('function_name');
557
         */
558
559
        //if (!is_readable($sFile)) exit('File not found or inaccessible!');
0 ignored issues
show
Unused Code Comprehensibility introduced by
80% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
560
561
        $sName = Url::decode($sName); // Clean the name file
562
563
        /* Figure out the MIME type (if not specified) */
564
565
566
        if (empty($sMimeType))
567
        {
568
            $sFileExtension = $this->getFileExt($sFile);
569
570
            $mGetMimeType = $this->getMimeType($sFileExtension);
571
572
            if (!empty($mGetMimeType))
573
                $sMimeType = $mGetMimeType;
574
            else
575
                $sMimeType = 'application/force-download';
576
        }
577
578
        @ob_end_clean(); // Turn off output buffering to decrease CPU usage
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

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...
579
580
        (new Browser)->nocache(); // No cache
581
582
        $sPrefix = Registry::getInstance()->site_name . '_'; // the prefix
583
        header('Content-Type: ' . $sMimeType);
584
        header('Content-Disposition: attachment; filename=' . ParseUrl::clean($sPrefix) . $sName);
585
        header('Content-Transfer-Encoding: binary');
586
        header('Accept-Ranges: bytes');
587
        header('Content-Length: ' . $this->size($sFile));
588
        readfile($sFile);
589
    }
590
591
    /**
592
     * Write Header Contents.
593
     *
594
     * @param string $sHeader Text to be shown in the headers
595
     * @param array $aFile
596
     * @return void
597
     */
598
    public function writeHeader($sHeader, $aFile = array())
599
    {
600
        for ($i = 0, $iCountFiles = count($aFile); $i < $iCountFiles; $i++)
601
        {
602
            $rHandle = fopen($aFile[$i], 'wb+');
603
            $sData = '';
604
            if ($this->size($aFile[$i]) > 0)
605
            {
606
                $aData = fread($rHandle, $this->size($aFile[$i]));
0 ignored issues
show
Unused Code introduced by
$aData is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
607
                fwrite($rHandle, $sHeader . static::EOL . $sData);
608
            }
609
            fclose($rHandle);
610
        }
611
    }
612
613
    /**
614
     * Writes and saves the contents to a file.
615
     * It also creates a temporary file to not delete the original file if something goes wrong during the recording file.
616
     *
617
     * @param string $sFile
618
     * @param string $sData
619
     * @return integer Returns the number of bytes written, or NULL on error.
620
     */
621
    public function save($sFile, $sData)
622
    {
623
        $sTmpFile = $this->getFileWithoutExt($sFile) . '.tmp.' . $this->getFileExt($sFile);
624
        $iWritten = (new \SplFileObject($sTmpFile, 'wb'))->fwrite($sData);
625
626
        if ($iWritten !== null) {
627
            // Copy of the temporary file to the original file if no problem occurred.
628
            copy($sTmpFile, $sFile);
629
        }
630
631
        // Deletes the temporary file.
632
        $this->deleteFile($sTmpFile);
633
634
        return $iWritten;
635
    }
636
637
    /**
638
     * Reading Files.
639
     *
640
     * @param string $sPath
641
     * @param mixed (array | string) $mFiles
642
     * @return mixed (array | string) The Files.
643
     */
644
    public function readFiles($sPath = './', &$mFiles)
645
    {
646
        if (!($rHandle = opendir($sPath)))
647
            return false;
648
649
        while (false !== ($sFile = readdir($rHandle)))
650
        {
651
            if ($sFile != '.' && $sFile != '..')
652
            {
653
                if (strpos($sFile, '.') === false)
654
                    $this->readFiles($sPath . PH7_DS . $sFile, $mFiles);
655
                else
656
                    $mFiles[] = $sPath . PH7_DS . $sFile;
657
            }
658
        }
659
        closedir($rHandle);
660
661
        return $mFiles;
662
    }
663
664
    /**
665
     * Reading Directories.
666
     *
667
     * @param string $sPath
668
     * @return mixed (array | boolean) Returns an ARRAY with the folders or FALSE if the folder could not be opened.
669
     */
670
    public function readDirs($sPath = './')
671
    {
672
        if (!($rHandle = opendir($sPath))) return false; // Return when yield is used will be OK with PHP 7
673
        $aRet = array();//remove it for yield
674
675
        while (false !== ($sFolder = readdir($rHandle)))
676
        {
677
            if ('.' == $sFolder || '..' == $sFolder || !is_dir($sPath . $sFolder))
678
                continue;
679
680
            //yield $sFolder; // PHP 7
681
            $aRet[] = $sFolder;//remove it for yield
682
        }
683
        closedir($rHandle);
684
685
        return $aRet;//remove it for yield
686
    }
687
688
    /**
689
     * Get the URL contents (For URLs, it is better to use CURL because it is faster than file_get_contents function).
690
     *
691
     * @param string $sUrl URL to be read contents.
692
     * @return mixed (string | boolean) Return the result content on success, FALSE on failure.
693
     */
694
    public function getUrlContents($sUrl)
695
    {
696
        $rCh = curl_init();
697
        curl_setopt($rCh, CURLOPT_URL, $sUrl);
698
        curl_setopt($rCh, CURLOPT_HEADER, 0);
699
        curl_setopt($rCh, CURLOPT_RETURNTRANSFER, 1);
700
        curl_setopt($rCh, CURLOPT_FOLLOWLOCATION, 1);
701
        $mRes = curl_exec($rCh);
702
        curl_close($rCh);
703
        unset($rCh);
704
705
        return $mRes;
706
    }
707
708
    /**
709
     * Extract Zip archive.
710
     *
711
     * @param string $sFile Zip file.
712
     * @param string $sDir Destination to extract the file.
713
     * @return boolean
714
     */
715
    public function zipExtract($sFile, $sDir)
716
    {
717
        $oZip = new \ZipArchive;
718
        $mRes = $oZip->open($sFile);
719
720
        if ($mRes === true) {
721
            $oZip->extractTo($sDir);
722
            $oZip->close();
723
            return true;
724
        }
725
726
        return false; // Return error value
727
    }
728
729
    /**
730
     * Check if the file is binary.
731
     *
732
     * @param string $sFile
733
     * @return boolean
734
     */
735
    public function isBinary($sFile)
736
    {
737
        if (file_exists($sFile))
738
        {
739
            if (!is_file($sFile))
740
                return false;
741
742
            if (preg_match('/^(.*?)\.(gif|jpg|jpeg|png|ico|mp3|mp4|mov|avi|flv|mpg|mpeg|wmv|ogg|ogv|webm|pdf|ttf|eot|woff|svg|swf)$/i', $sFile))
743
                return true;
744
745
            $rHandle  = fopen($sFile, 'r');
746
            $sContents = fread($rHandle, 512); // Get 512 bytes of the file.
747
            fclose($rHandle);
748
            clearstatcache();
749
750
            if (!function_exists('is_binary')) // PHP 6
751
                return is_binary($sContents);
752
753
            return (
754
                0 or substr_count($sContents, "^ -~", "^\r\n")/512 > 0.3
755
                or substr_count($sContents, "\x00") > 0
756
            );
757
        }
758
759
        return false;
760
    }
761
762
    /**
763
     * Create a recurive directory iterator for a given directory.
764
     *
765
     * @param string $sPath
766
     * @return string The directory.
767
     */
768
    public function getDirIterator($sPath)
769
    {
770
        return (new \RecursiveDirectoryIterator($sPath));
771
    }
772
773
    /**
774
     * Recursive Directory Iterator.
775
     *
776
     * @param string $sFuncName The function name. Choose between 'copy' and 'rename'.
777
     * @param string $sFrom Directory.
778
     * @param string $sTo Directory.
779
     *
780
     * @return boolean
781
     *
782
     * @throws PH7InvalidArgumentException If the type is bad.
783
     */
784
    private function _recursiveDirIterator($sFrom, $sTo, $sFuncName)
785
    {
786
        if ($sFuncName !== 'copy' && $sFuncName !== 'rename') {
787
            throw new PH7InvalidArgumentException('Bad function name: \'' . $sFuncName . '\'');
788
        }
789
790
        if (!is_dir($sFrom)) {
791
            return false;
792
        }
793
794
        $bRet = false; // Default value
795
        $oIterator = new \RecursiveIteratorIterator($this->getDirIterator($sFrom), \RecursiveIteratorIterator::SELF_FIRST);
796
797
        foreach ($oIterator as $sFromFile) {
798
            $sDest = $sTo . PH7_DS . $oIterator->getSubPathName();
799
800
            if ($sFromFile->isDir()) {
801
                $this->createDir($sDest);
802
            } else {
803
                if (!$bRet = $this->$sFuncName($sFromFile, $sDest)) {
804
                    return false;
805
                }
806
            }
807
        }
808
809
        return $bRet;
810
    }
811
}
812