PluginProbe
FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration / 2.0.12
FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration v2.0.12
2.0.15 2.0.12 2.0.10 2.0.4 2.0.1 2.0.0 1.95.3 1.95.2 1.95 1.91.6 trunk 1.11 1.12 1.13 1.20 1.21 1.22 1.23 1.30 1.31 1.32 1.35 1.40 1.41 1.45 All 41 releases
fluent-boards / app / Services / Libs / FileSystem.php

FileSystem.php in FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration 2.0.12, at app/Services/Libs/FileSystem.php

241 lines 7.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentBoards\App\Services\Libs;
4
5 use FluentBoards\Framework\Support\Arr;
6
7 class FileSystem
8 {
9 protected $subDir = '';
10
11 public function _setSubDir($subDir)
12 {
13 $this->subDir = $subDir;
14 return $this;
15 }
16 /**
17 * Read file content from custom upload dir of this application
18 * @return string [path]
19 */
20 public function _get($file)
21 {
22 $arr = explode('/', $file);
23 $fileName = end($arr);
24 if ($this->subDir) {
25 $fileName = $this->subDir . DIRECTORY_SEPARATOR . $fileName;
26 }
27
28 $filePath = $this->getDir() . DIRECTORY_SEPARATOR . $fileName;
29
30 // Use WordPress Filesystem API
31 global $wp_filesystem;
32 if (!function_exists('WP_Filesystem')) {
33 require_once(ABSPATH . 'wp-admin/includes/file.php');
34 }
35 WP_Filesystem();
36
37 return $wp_filesystem->get_contents($filePath);
38 }
39
40 /**
41 * Get custom upload dir name of this application
42 * @return string [directory path]
43 */
44 public function _getDir()
45 {
46 $uploadDir = wp_upload_dir();
47
48 $fbsUploadDir = apply_filters('fluent_boards/upload_folder_name', FLUENT_BOARDS_UPLOAD_DIR);
49
50 if ($this->subDir) {
51 return $uploadDir['basedir'] . DIRECTORY_SEPARATOR . $fbsUploadDir. DIRECTORY_SEPARATOR. $this->subDir;
52 }
53
54 return $uploadDir['basedir'] . DIRECTORY_SEPARATOR . $fbsUploadDir;
55 }
56
57 /**
58 * Get absolute path of file using custom upload dir name of this application
59 * @return string [file path]
60 */
61 public function _getAbsolutePathOfFile($file)
62 {
63 return $this->_getDir() . DIRECTORY_SEPARATOR . $file;
64 }
65
66 /**
67 * Upload files into custom upload dir of this application
68 * @return array
69 */
70 public function _uploadFromRequest()
71 {
72 return $this->_put(FluentBoards('request')->files());
73 }
74
75 /**
76 * Upload files into custom upload dir of this application
77 * @param array $files
78 * @return array
79 */
80 public function _put($files)
81 {
82 if (!function_exists('wp_handle_upload')) {
83 require_once(ABSPATH . 'wp-admin/includes/file.php');
84 }
85
86 $this->overrideUploadDir();
87
88 $uploadOverrides = [
89 'test_form' => false,
90 // Accept the same allow-list FluentBoards validates against, so wp_handle_upload
91 // doesn't reject broader types (e.g. .json, .md) by extension.
92 'mimes' => \FluentBoards\App\Services\UploadService::getAllowedMimeMap(),
93 ];
94 $uploadedFiles = []; // Initialize the array
95
96 if(is_object($files)) {
97 $files = [$files];
98 }
99
100 foreach ((array)$files as $file) {
101
102 $filesArray = $file->toArray();
103
104 // tmp_name is the path to the uploaded file which is required for wp_handle_upload, new framework update
105 // changed the way to get the tmp_name Reference to line # 448 in File.php
106 $filesArray['tmp_name'] = $file->getRealPath();
107
108 $extraData = Arr::only($filesArray, ['name', 'size']);
109 $uploadsData = \wp_handle_upload($filesArray, $uploadOverrides);
110 // Add the full path to the file
111 $uploadsData['full_path'] = $this->_getAbsolutePathOfFile($uploadsData['file']);
112 $uploadedFiles[] = array_merge($extraData, $uploadsData);
113 }
114
115 return $uploadedFiles;
116 }
117
118 /**
119 * Delete a file from custom upload directory of this application
120 * @param array $files
121 * @return void
122 */
123 public function _delete($files)
124 {
125 $files = (array)$files;
126
127 foreach ($files as $file) {
128 $arr = explode('/', $file);
129 $fileName = end($arr);
130 $filePath = $this->getDir() . '/' . $fileName;
131 if (file_exists($filePath)) {
132 wp_delete_file($filePath);
133 }
134 }
135 }
136
137 /**
138 * Register filters for custom upload dir
139 */
140 public function _overrideUploadDir()
141 {
142 add_filter('wp_handle_upload_prefilter', function ($file) {
143 add_filter('upload_dir', [$this, '_setCustomUploadDir']);
144
145 add_filter('wp_handle_upload', function ($fileinfo) {
146 remove_filter('upload_dir', [$this, '_setCustomUploadDir']);
147 $fileinfo['file'] = basename($fileinfo['file']);
148 return $fileinfo;
149 });
150
151 return $this->_renameFileName($file);
152 });
153 }
154
155 /**
156 * Set plugin's custom upload dir
157 * @param array $param
158 * @return array $param
159 */
160 public function _setCustomUploadDir($param)
161 {
162 $fbsUploadDir = apply_filters('fluent_boards/upload_folder_name', FLUENT_BOARDS_UPLOAD_DIR);
163
164 if ($this->subDir) {
165 $fbsUploadDir .= DIRECTORY_SEPARATOR . $this->subDir;
166 if (!is_dir($param['basedir'] . $fbsUploadDir)) {
167 // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_mkdir -- Creating custom upload subdirectory during upload process, WP_Filesystem not initialized
168 @mkdir($param['basedir'] . $fbsUploadDir, 0755);
169 }
170 }
171
172 $param['url'] = $param['baseurl'] . DIRECTORY_SEPARATOR . $fbsUploadDir;
173
174 $param['path'] = $param['basedir'] . DIRECTORY_SEPARATOR . $fbsUploadDir;
175
176 return $param;
177 }
178
179 /**
180 * Rename the uploaded file name before saving
181 * @param array $file
182 * @return array $file
183 */
184 public function _renameFileName($file)
185 {
186 $prefix = wp_generate_uuid4() . '-';
187 $prefix = apply_filters('fluent_boards/uploaded_file_name_prefix', $prefix);
188 $file['name'] = $prefix . $file['name'];
189
190 return $file;
191 }
192
193 public function _deleteDir($dir)
194 {
195 $dir = $this->getDir() . DIRECTORY_SEPARATOR . $dir;
196 if (is_dir($dir)) {
197 $this->deleteContents($dir);
198 }
199 }
200
201 /**
202 * Delete a directory and its content
203 * Lead Note: this method should be called via scheduler or queue
204 * @param string $dir
205 * @return bool
206 */
207 private function deleteContents($dir)
208 {
209 $files = array_diff(scandir($dir), ['.', '..']);
210 foreach ($files as $file) {
211 if(is_dir("$dir/$file")) {
212 // Recursively delete subdirectory
213 $this->deleteContents("$dir/$file");
214 } else {
215 // Delete file
216 // phpcs:ignore WordPress.WP.AlternativeFunctions.unlink_unlink -- Recursive directory cleanup, direct file operations required
217 unlink("$dir/$file");
218 }
219 }
220 // Delete the directory itself. If the directory is not empty, it will not be deleted.
221 // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_rmdir -- Recursive directory removal, WP_Filesystem not suitable for this operation
222 return rmdir($dir);
223 }
224
225 public static function __callStatic($method, $params)
226 {
227 $instance = new static;
228
229 return call_user_func_array([$instance, $method], $params);
230 }
231
232 public function __call($method, $params)
233 {
234 $hiddenMethod = "_" . $method;
235
236 $method = method_exists($this, $hiddenMethod) ? $hiddenMethod : $method;
237
238 return call_user_func_array([$this, $method], $params);
239 }
240 }
241