PluginProbe ʕ •ᴥ•ʔ
Backup Migration / 2.1.2
Backup Migration v2.1.2
2.1.6 2.1.5.2 trunk 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.6.1 1.4.7 1.4.8 1.4.9 1.4.9.1 2.0.0 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.5.1
backup-backup / includes / file-explorer.php
backup-backup / includes Last commit date
banner 3 months ago bodies 3 months ago check 3 months ago cli 3 months ago cron 3 months ago dashboard 3 months ago database 3 months ago external 3 months ago extracter 3 months ago htaccess 3 months ago notices 3 months ago progress 3 months ago scanner 3 months ago staging 3 months ago traits 3 months ago uploader 3 months ago vendor 3 months ago zipper 3 months ago .htaccess 3 months ago activation.php 3 months ago ajax.php 3 months ago ajax_offline.php 3 months ago analyst.php 3 months ago backup-process.php 3 months ago class-backup-method-mananger.php 3 months ago cli-handler.php 3 months ago compatibility.php 3 months ago config.php 3 months ago constants.php 3 months ago file-explorer.php 3 months ago initializer.php 3 months ago logger.php 3 months ago offline.php 3 months ago
file-explorer.php
192 lines
1 <?php
2
3
4 namespace BMI\Plugin;
5
6
7
8 if (!defined('ABSPATH')) exit;
9
10 use BMI\Plugin\Backup_Migration_Plugin as BMP;
11 use BMI\Plugin\BMI_Logger as Logger;
12
13
14 /**
15 * File_Queue is an interface that define the methods that should be implemented by the file container
16 */
17 interface File_Queue{
18
19 /**
20 * Insert the file in the container
21 * @param string $path
22 * @return void
23 */
24 public function insert_file($path);
25
26 /**
27 * Get the largest n files and directories
28 * @param int $n
29 * @return array of largest n files and directories [['path', 'type', 'size'], ...]
30 */
31 public function getLargest($n); // Get the largest n files and directories
32 }
33
34
35 /**
36 * BMI_File_Queue is a priority queue that store the files and directories and sort them based on the size
37 */
38 class BMI_File_Queue extends \SplPriorityQueue implements File_Queue{
39
40 const DIR_TYPE = 0;
41 const FILE_TYPE = 1;
42
43 const PATH_INDEX = 0;
44 const TYPE_INDEX = 1;
45 const SIZE_INDEX = 2;
46
47
48 const UNABLE_TO_READ = -1;
49
50 public function __construct(){
51 $this->setExtractFlags(\SplPriorityQueue::EXTR_DATA);
52 }
53
54
55 /**
56 * Insert the file in the container determine the type of the file and size and insert it in array ['path', 'type', 'size']
57 * @param string $path
58 * @return void
59 */
60 public function insert_file($path){
61 if (strpos($path, '..') !== false || strpos($path, '/.') !== false){
62 return;
63 }
64 $path = BMP::fixSlashes($path);
65 if (is_dir($path)){
66 $size = $this->getDirSize($path);
67 if ($size == self::UNABLE_TO_READ){
68 Logger::debug('Unable to read the directory: ' . $path);
69 return;
70 }
71 $this->insert([$path, self::DIR_TYPE, $size], $size);
72 }else{
73 $this->insert([$path, self::FILE_TYPE, filesize($path)], filesize($path));
74 }
75 }
76
77 /**
78 * Get the largest n files and directories
79 * @param int $n
80 * @return array of largest n files and directories [['path', 'type', 'size'], ...]
81 */
82 public function getLargest($n){
83 $largest = [];
84 for ($i = 0; $i < $n; $i++){
85 if ($this->isEmpty()){
86 break;
87 }
88 $largest[] = $this->extract();
89 }
90 return $largest;
91 }
92
93
94
95 /**
96 * Get the size of the directory recursively using DirectoryIterator
97 * @param string $path
98 * @return int size of the directory
99 */
100 function getDirSize($path){
101 $bytestotal = 0;
102 $path = realpath($path);
103 if($path!==false && $path!='' && file_exists($path)){
104 try{
105 new \DirectoryIterator($path);
106 }catch(\Exception $e){
107 return self::UNABLE_TO_READ;
108 }
109 foreach(new \DirectoryIterator($path) as $file){
110 if($file->isFile()){
111 $bytestotal += $file->getSize();
112 }
113 else if(!$file->isDot() && $file->isDir()){
114 $bytestotal += $this->getDirSize($file->getPathname());
115 }
116 }
117 }
118 return $bytestotal;
119 }
120
121 }
122
123
124 /**
125 * BMI_File_Explorer is a class that provide the methods to scan the directory and get the list of largest files and directories
126 *
127 * @package BMI\Plugin
128 * @since 1.4.5
129 * @version 1.0
130 * @category Class
131 * @see BMI_File_Queue
132 * @method BMI_File_Queue scanDir($path) Get the list of largest 100 files and directories in the path
133 * @method int isSub($dir, $path) Recursivly get if the directory is sub directory of given path or not and return the depth of the sub directory return -1 if not sub directory
134 *
135 */
136 class BMI_File_Explorer {
137
138 /**
139 * Get the list of largest 100 files and directories in the path
140 * don't include the ignored files and directories
141 * @param string $path
142 * @param array $ignored
143 * @param File_Queue $queue
144 * @return BMI_File_Queue of directories and files each element is an path and type and size [['html/wp-content/plugins', 'dir', 658745], ['html/wp-content/index.php', 'file', 0]], ...]
145 *
146 */
147 public static function scanDir($path, $ignored = [], $queue = null) {
148 if ($queue == null){
149 $queue = new BMI_File_Queue();
150 }
151 $handle = opendir($path);
152 while (false !== ($entry = readdir($handle))) {
153
154 $full_path = BMP::fixSlashes($path . '\\' . $entry);
155 if (in_array($entry, $ignored) || in_array($full_path, $ignored) || $entry == '.' || $entry == '..') {
156 continue;
157 }
158 $queue->insert_file($full_path);
159
160 }
161 return $queue;
162 }
163
164 /**
165 * Recursivly get if the directory is sub directory of given path or not and return true or false
166 * @param string $dir directory path
167 * @param string $path path to check if the directory is sub directory of this path
168 * @return int -1 if not sub directory, 0 is the same directory, depth of the sub directory
169 */
170 public static function isSub($dir, $path , $depth = 0){
171 $path = str_replace('***ABSPATH***', ABSPATH, $path);
172 $dir = str_replace('***ABSPATH***', ABSPATH, $dir);
173 if (strpos($dir, $path) === false || strpos($dir, '..') !== false) {
174 return -1;
175 }
176
177 if ($dir == $path) {
178 return $depth;
179 }
180
181 return self::isSub(dirname($dir), $path, $depth + 1);
182 }
183
184 /**
185 * Get the size of the directory recursively using DirectoryIterator
186 * @param string $path
187 * @return int size of the directory
188 */
189 public static function getDirSize($path){
190 return (new BMI_File_Queue())->getDirSize($path);
191 }
192 }