FileHelper::tail()   B
last analyzed

Complexity

Conditions 9
Paths 41

Size

Total Lines 48
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 9
eloc 22
c 1
b 0
f 0
nc 41
nop 3
dl 0
loc 48
rs 8.0555
1
<?php
2
3
namespace LeKoala\Admini\Helpers;
4
5
use RecursiveIteratorIterator;
6
use RecursiveDirectoryIterator;
7
8
class FileHelper
9
{
10
11
    /**
12
     * Slightly modified version of http://www.geekality.net/2011/05/28/php-tail-tackling-large-files/
13
     * @author Torleif Berger, Lorenzo Stanco
14
     * @link http://stackoverflow.com/a/15025877/995958
15
     * @license http://creativecommons.org/licenses/by/3.0/
16
     */
17
    public static function tail($filepath, $lines = 1, $adaptive = true)
18
    {
19
        // Open file
20
        $f = @fopen($filepath, "rb");
21
        if ($f === false) {
22
            return false;
23
        }
24
25
        // Sets buffer size, according to the number of lines to retrieve.
26
        // This gives a performance boost when reading a few lines from the file.
27
        if (!$adaptive) {
28
            $buffer = 4096;
29
        } else {
30
            $buffer = ($lines < 2 ? 64 : ($lines < 10 ? 512 : 4096));
31
        }
32
        // Jump to last character
33
        fseek($f, -1, SEEK_END);
34
        // Read it and adjust line number if necessary
35
        // (Otherwise the result would be wrong if file doesn't end with a blank line)
36
        if (fread($f, 1) != "\n") {
37
            $lines -= 1;
38
        }
39
40
        // Start reading
41
        $output = '';
42
        $chunk = '';
0 ignored issues
show
Unused Code introduced by
The assignment to $chunk is dead and can be removed.
Loading history...
43
        // While we would like more
44
        while (ftell($f) > 0 && $lines >= 0) {
45
            // Figure out how far back we should jump
46
            $seek = min(ftell($f), $buffer);
47
            // Do the jump (backwards, relative to where we are)
48
            fseek($f, -$seek, SEEK_CUR);
49
            // Read a chunk and prepend it to our output
50
            $output = ($chunk = fread($f, $seek)) . $output;
51
            // Jump back to where we started reading
52
            fseek($f, -mb_strlen($chunk, '8bit'), SEEK_CUR);
53
            // Decrease our line counter
54
            $lines -= substr_count($chunk, "\n");
55
        }
56
        // While we have too many lines
57
        // (Because of buffer size we might have read too many)
58
        while ($lines++ < 0) {
59
            // Find first newline and remove all text before that
60
            $output = substr($output, strpos($output, "\n") + 1);
61
        }
62
        // Close file and return
63
        fclose($f);
64
        return trim($output);
65
    }
66
67
    /**
68
     * Recursively remove a dir
69
     *
70
     * @param string $dir
71
     * @return bool
72
     */
73
    public static function rmDir($dir)
74
    {
75
        if (!is_dir($dir)) {
76
            return false;
77
        }
78
        $it = new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS);
79
        $files = new RecursiveIteratorIterator($it, RecursiveIteratorIterator::CHILD_FIRST);
80
        foreach ($files as $file) {
81
            if ($file->isDir()) {
82
                rmdir($file->getRealPath());
83
            } else {
84
                unlink($file->getRealPath());
85
            }
86
        }
87
        return rmdir($dir);
88
    }
89
90
    /**
91
     * Check if a directory contains children
92
     *
93
     * @link https://stackoverflow.com/questions/6786014/php-fastest-way-to-find-if-directory-has-children
94
     * @param string $dir
95
     * @return bool
96
     */
97
    public static function dirContainsChildren($dir)
98
    {
99
        $result = false;
100
        if ($dh = opendir($dir)) {
101
            while (!$result && ($file = readdir($dh)) !== false) {
102
                $result = $file !== "." && $file !== "..";
103
            }
104
            closedir($dh);
105
        }
106
        return $result;
107
    }
108
109
    /**
110
     * @link https://www.digitalocean.com/community/questions/proper-permissions-for-web-server-s-directory
111
     * @param string $dir
112
     * @return bool
113
     */
114
    public static function ensureDir($dir)
115
    {
116
        if (!is_dir($dir)) {
117
            return mkdir($dir, 0755, true);
118
        }
119
        return true;
120
    }
121
122
    /**
123
     * @param int $bytes
124
     * @param integer $decimals
125
     * @return string
126
     */
127
    public static function humanFilesize($bytes, $decimals = 2)
128
    {
129
        if ($bytes < 1024) {
130
            return $bytes . ' B';
131
        }
132
        $factor = floor(log($bytes, 1024));
133
        return sprintf("%.{$decimals}f ", $bytes / pow(1024, $factor)) . ['B', 'KB', 'MB', 'GB', 'TB', 'PB'][$factor];
134
    }
135
136
    public static function convertToByte($val)
137
    {
138
        $val  = trim($val);
139
140
        if (is_numeric($val)) {
141
            return $val;
142
        }
143
144
        $last = strtolower($val[strlen($val) - 1]);
145
        $val  = substr($val, 0, -1);
146
147
        switch ($last) {
148
            case 'g':
149
                $val *= 1024;
150
                // keep processing
151
            case 'm':
152
                $val *= 1024;
153
                // keep processing
154
            case 'k':
155
                $val *= 1024;
156
                // keep processing
157
        }
158
159
        return $val;
160
    }
161
162
    public static function memoryLimit()
163
    {
164
        return self::convertToByte(ini_get("memory_limit"));
165
    }
166
}
167