PluginProbe
FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration / 2.0.4
FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration v2.0.4
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.4, at app/Services/Libs/FileSystem.php

242 lines 7.4 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 $currentTimeStamp = (new \DateTimeImmutable())->getTimestamp();
187 $prefix = $currentTimeStamp . '-';
188 $prefix = apply_filters('fluent_boards/uploaded_file_name_prefix', $prefix);
189 $file['name'] = $prefix . $file['name'];
190
191 return $file;
192 }
193
194 public function _deleteDir($dir)
195 {
196 $dir = $this->getDir() . DIRECTORY_SEPARATOR . $dir;
197 if (is_dir($dir)) {
198 $this->deleteContents($dir);
199 }
200 }
201
202 /**
203 * Delete a directory and its content
204 * Lead Note: this method should be called via scheduler or queue
205 * @param string $dir
206 * @return bool
207 */
208 private function deleteContents($dir)
209 {
210 $files = array_diff(scandir($dir), ['.', '..']);
211 foreach ($files as $file) {
212 if(is_dir("$dir/$file")) {
213 // Recursively delete subdirectory
214 $this->deleteContents("$dir/$file");
215 } else {
216 // Delete file
217 // phpcs:ignore WordPress.WP.AlternativeFunctions.unlink_unlink -- Recursive directory cleanup, direct file operations required
218 unlink("$dir/$file");
219 }
220 }
221 // Delete the directory itself. If the directory is not empty, it will not be deleted.
222 // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_rmdir -- Recursive directory removal, WP_Filesystem not suitable for this operation
223 return rmdir($dir);
224 }
225
226 public static function __callStatic($method, $params)
227 {
228 $instance = new static;
229
230 return call_user_func_array([$instance, $method], $params);
231 }
232
233 public function __call($method, $params)
234 {
235 $hiddenMethod = "_" . $method;
236
237 $method = method_exists($this, $hiddenMethod) ? $hiddenMethod : $method;
238
239 return call_user_func_array([$this, $method], $params);
240 }
241 }
242