1 | <?php |
||||
2 | |||||
3 | /** |
||||
4 | * Copyright 2019 Amin Yazdanpanah<http://www.aminyazdanpanah.com>. |
||||
5 | * |
||||
6 | * Licensed under the MIT License; |
||||
7 | * you may not use this file except in compliance with the License. |
||||
8 | * You may obtain a copy of the License at |
||||
9 | * |
||||
10 | * https://opensource.org/licenses/MIT |
||||
11 | * |
||||
12 | * Unless required by applicable law or agreed to in writing, software |
||||
13 | * distributed under the License is distributed on an "AS IS" BASIS, |
||||
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
15 | * See the License for the specific language governing permissions and |
||||
16 | * limitations under the License. |
||||
17 | */ |
||||
18 | |||||
19 | |||||
20 | //before require auto load, you should install package via composer: |
||||
21 | //composer install |
||||
22 | //or |
||||
23 | //composer require aminyazdanpanah/handling-file-uploads |
||||
24 | //Note: To find out how to install composer, just google "install or download composer" |
||||
25 | |||||
26 | require_once '../vendor/autoload.php'; |
||||
27 | |||||
28 | use Gumlet\ImageResize; |
||||
0 ignored issues
–
show
|
|||||
29 | use wapmorgan\UnifiedArchive\UnifiedArchive; |
||||
0 ignored issues
–
show
The type
wapmorgan\UnifiedArchive\UnifiedArchive was not found. Maybe you did not declare it correctly or list all dependencies?
The issue could also be caused by a filter entry in the build configuration.
If the path has been excluded in your configuration, e.g. filter:
dependency_paths: ["lib/*"]
For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths ![]() |
|||||
30 | use AYazdanpanah\SaveUploadedFiles\Exception\Exception; |
||||
0 ignored issues
–
show
This use statement conflicts with another class in this namespace,
Exception . Consider defining an alias.
Let?s assume that you have a directory layout like this: .
|-- OtherDir
| |-- Bar.php
| `-- Foo.php
`-- SomeDir
`-- Foo.php
and let?s assume the following content of // Bar.php
namespace OtherDir;
use SomeDir\Foo; // This now conflicts the class OtherDir\Foo
If both files PHP Fatal error: Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php
However, as // Bar.php
namespace OtherDir;
use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
![]() |
|||||
31 | |||||
32 | if(isset($_POST['submit'])) { |
||||
33 | |||||
34 | $user_id = rand(10000, 1000000); |
||||
35 | |||||
36 | //So, to export your uploaded file, create a callback method and use its callback to validate, update, modify, convert, copy and etc after your file was uploaded. |
||||
37 | /** |
||||
38 | * Add additional validators and handle image after your file was uploaded. |
||||
39 | * |
||||
40 | * @param $filename |
||||
41 | * @return ImageResize |
||||
42 | */ |
||||
43 | $image_path = __DIR__ . "/images/user/$user_id"; |
||||
44 | $export_image = function ($filename) use ($image_path) { |
||||
45 | //Add a Validator: check if the file is image |
||||
46 | if (!is_type("image", $filename)) { |
||||
47 | throw new Exception("Your file is not an image!"); |
||||
48 | } |
||||
49 | |||||
50 | $image_metadata = exif_read_data($filename); |
||||
51 | |||||
52 | //Add a Validator: check whether the image is square or not |
||||
53 | if ($image_metadata['COMPUTED']['Width'] / $image_metadata['COMPUTED']['Height'] != 1) { |
||||
54 | throw new Exception("Your image must be square!"); |
||||
55 | } |
||||
56 | |||||
57 | if (!is_dir($image_path . "/thumbnail")) { |
||||
58 | mkdir($image_path . "/thumbnail", 0777, true); |
||||
59 | } |
||||
60 | |||||
61 | // Resize and crop your image |
||||
62 | $image = new ImageResize($filename); |
||||
63 | $image->resizeToWidth(50)->save($image_path . "/thumbnail/thumb_50.jpg"); |
||||
64 | $image->resizeToWidth(100)->save($image_path . "/thumbnail/thumb_100.jpg"); |
||||
65 | $image->resizeToWidth(240)->save($image_path . "/thumbnail/thumb_240.jpg"); |
||||
66 | $image->resizeToBestFit(500, 300)->save($image_path . "/thumbnail/thumb_500_300.jpg"); |
||||
67 | $image->crop(200, 200)->save($image_path . "/thumbnail/thumb_crop_200_200.jpg"); |
||||
68 | |||||
69 | return $image_metadata; |
||||
70 | }; |
||||
71 | |||||
72 | /** |
||||
73 | * Add additional validators and handle video after your file was uploaded. |
||||
74 | * |
||||
75 | * @param $filename |
||||
76 | * @return array |
||||
77 | */ |
||||
78 | $video_path = __DIR__ . "/videos/$user_id"; |
||||
79 | $video_name = str_random(); |
||||
80 | $export_video = function ($filename) use ($video_path, $video_name) { |
||||
81 | |||||
82 | $video = AYazdanpanah\FFMpegStreaming\FFMpeg::create() |
||||
0 ignored issues
–
show
The type
AYazdanpanah\FFMpegStreaming\FFMpeg was not found. Maybe you did not declare it correctly or list all dependencies?
The issue could also be caused by a filter entry in the build configuration.
If the path has been excluded in your configuration, e.g. filter:
dependency_paths: ["lib/*"]
For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths ![]() |
|||||
83 | ->open($filename); |
||||
84 | |||||
85 | //Extracting video meta data |
||||
86 | $video_metadata = $video->getFirstStream(); |
||||
87 | |||||
88 | //Add a Validator: check if the file is video and video duration is not longer than 1 minute |
||||
89 | if (!$video_metadata->isVideo() && null === ($duration = $video_metadata->get('duration')) && $duration >= 60) { |
||||
90 | throw new Exception("Your file is not a video or your video duration is longer than 1 minute!"); |
||||
91 | } |
||||
92 | |||||
93 | //Add a Validator: check if the video is HD or higher resolution |
||||
94 | if ($video_metadata->get('width',1) * $video_metadata->get('height', 1) < 1280 * 720) { |
||||
95 | throw new Exception("Sorry, your video must be at least HD or higher resolution"); |
||||
96 | } |
||||
97 | |||||
98 | //Add a Validator: check if the video ratio is 16 / 9 |
||||
99 | if ($video_metadata->getDimensions()->getRatio()->getValue() == 16 / 9) { |
||||
100 | throw new Exception("Sorry, the video ratio must be 16 / 9"); |
||||
101 | } |
||||
102 | |||||
103 | //Extracting image and resize it |
||||
104 | $video->frame(FFMpeg\Coordinate\TimeCode::fromSeconds(intval($duration / 4)))->save("$video_path/screenshots.jpg"); |
||||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||||
105 | $image = new ImageResize("$video_path/screenshots.jpg"); |
||||
106 | $image->resizeToWidth(240)->save("$video_path/{$video_name}_screenshots_small.jpg"); |
||||
107 | |||||
108 | //Extracting gif |
||||
109 | $video->gif(FFMpeg\Coordinate\TimeCode::fromSeconds(3), new FFMpeg\Coordinate\Dimension(240, 95), 3) |
||||
110 | ->save("$video_path/{$video_name}_animation.gif"); |
||||
111 | |||||
112 | //Create the dash files(it is better to create a job and dispatch it-do it in the background) |
||||
113 | mkdir("$video_path/dash/$video_name", 0777, true); |
||||
114 | dash($filename, "$video_path/dash/$video_name/output.mpd", function ($audio, $format, $percentage) { |
||||
0 ignored issues
–
show
The function
dash() has been deprecated: this method is deprecated
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This function has been deprecated. The supplier of the function has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead. ![]() |
|||||
115 | echo "$percentage % transcoded\n"; |
||||
116 | }); |
||||
117 | |||||
118 | //Delete the original file |
||||
119 | @unlink($filename); |
||||
0 ignored issues
–
show
It seems like you do not handle an error condition for
unlink() . This can introduce security issues, and is generally not recommended.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
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.');
}
![]() |
|||||
120 | |||||
121 | return $video_metadata->all(); |
||||
122 | }; |
||||
123 | |||||
124 | /** |
||||
125 | * Add additional validators and handle archive after your file was uploaded. |
||||
126 | * |
||||
127 | * @param $filename |
||||
128 | * @return array |
||||
129 | */ |
||||
130 | $archive_path = __DIR__ . "/archive/$user_id"; |
||||
131 | $archive_name = str_random(); |
||||
132 | $archive_export = function ($filename) use ($archive_path, $archive_name) { |
||||
133 | mkdir("$archive_path/$archive_name"); |
||||
134 | $archive = UnifiedArchive::open($filename); |
||||
135 | |||||
136 | //Add a Validator: check whether the file is able to open or not |
||||
137 | if (null === $archive) { |
||||
138 | unlink($filename); |
||||
139 | throw new Exception("Sorry!we could not open the archive. |
||||
140 | Please check whether your extension has been installed or not. |
||||
141 | Your file may be corrupted or is encrypted"); |
||||
142 | } |
||||
143 | |||||
144 | //Add a Validator: check whether the profile.jpg is in archive or not |
||||
145 | if (!$archive->isFileExists('profile.jpg')) { |
||||
146 | unlink($filename); |
||||
147 | throw new Exception("Sorry!we could not find 'profile.jpg' in the archive"); |
||||
148 | } |
||||
149 | |||||
150 | //Extracting files |
||||
151 | $archive->extractFiles("$archive_path/$archive_name"); |
||||
152 | |||||
153 | return $archive->getFileNames(); |
||||
154 | }; |
||||
155 | |||||
156 | /** |
||||
157 | * Add additional validators and handle document after your file was uploaded. |
||||
158 | * |
||||
159 | * @param $filename |
||||
160 | * @return array |
||||
161 | */ |
||||
162 | $doc_path = __DIR__ . "/docs/$user_id"; |
||||
163 | $doc_name = str_random(); |
||||
164 | $doc_export = function ($filename) use ($doc_path, $doc_name) { |
||||
165 | mkdir($doc_path . '/backup'); |
||||
166 | copy($filename, "$doc_path/backup/$doc_name.backup"); |
||||
167 | return ['backup_to' => $doc_path . '/backup']; |
||||
168 | }; |
||||
169 | |||||
170 | /** |
||||
171 | * Add additional validators and handle audio after your file was uploaded. |
||||
172 | * |
||||
173 | * @param $filename |
||||
174 | * @return array |
||||
175 | */ |
||||
176 | $audio_path = __DIR__ . "/audios/$user_id"; |
||||
177 | $audio_name = str_random(); |
||||
178 | $audio_export = function ($filename) use ($audio_path, $audio_name) { |
||||
179 | mkdir($audio_path . '/flac'); |
||||
180 | $audio = AYazdanpanah\FFMpegStreaming\FFMpeg::create() |
||||
181 | ->open($filename); |
||||
182 | $audio_metadata = $audio->getFirstStream(); |
||||
183 | |||||
184 | //Add a Validator: check if the file is audio |
||||
185 | if (!$audio_metadata->isAudio() && null === ($duration = $audio_metadata->get('duration')) && $duration <= 60) { |
||||
186 | throw new Exception("Sorry, your file is not an audio or your audio duration must be longer than 1 minute!"); |
||||
187 | } |
||||
188 | |||||
189 | //Add a Validator: check if the file is mp3 |
||||
190 | if (!strstr($audio_metadata->get('codec_name'), 'mp3')) { |
||||
191 | throw new Exception("Sorry, your audio format must be mp3!"); |
||||
192 | } |
||||
193 | |||||
194 | //Convert the file into flac format |
||||
195 | $format = new FFMpeg\Format\Audio\Flac(); |
||||
196 | |||||
197 | $format->on('progress', function ($audio, $format, $percentage) { |
||||
198 | echo "$percentage % transcoded\n"; |
||||
199 | }); |
||||
200 | |||||
201 | $format |
||||
202 | ->setAudioChannels(2) |
||||
203 | ->setAudioKiloBitrate(256); |
||||
204 | |||||
205 | $audio->save($format, "$audio_path/flac/$audio_name.flac"); |
||||
206 | |||||
207 | return $audio_metadata->all(); |
||||
208 | }; |
||||
209 | |||||
210 | $config_files = [ |
||||
211 | [ |
||||
212 | 'name' => 'upload_image', //The key name that you send your file to the server |
||||
213 | 'save_to' => $image_path, //The path you'd like to save your file(auto make new directory) |
||||
214 | 'validator' => [ |
||||
215 | 'min_size' => 100, //Minimum size is 100KB |
||||
216 | 'max_size' => 1024 * 2, //Maximum size is 2MB |
||||
217 | 'allowed_extensions' => ['jpg', 'jpeg', 'png'] //Just images are allowed |
||||
218 | ], |
||||
219 | 'export' => $export_image //Get a callback method(what happen to file after uploading!) |
||||
220 | ], |
||||
221 | [ |
||||
222 | 'name' => 'upload_archive', //The key name that you send to the server |
||||
223 | 'save_to' => $archive_path, //The path you'd like to save your file |
||||
224 | 'save_as' => $archive_name, //The name you'd like to save in your server |
||||
225 | 'validator' => [ |
||||
226 | 'min_size' => 10, //Minimum size is 10KB |
||||
227 | 'max_size' => 1024, //Maximum size is 1MB |
||||
228 | 'allowed_extensions' => ['zip', '7z', 'rar', 'gz', 'bz2', 'xz', 'cab', 'tar', 'tar.gz', 'tar.bz2', 'tar.x', 'tar.Z', 'iso'] //Just archive files are allowed |
||||
229 | ], |
||||
230 | 'export' => $archive_export //Get a callback method(what happen to file after uploading!) |
||||
231 | ], |
||||
232 | [ |
||||
233 | 'name' => 'upload_doc', //The key name that you send to the server |
||||
234 | 'save_to' => $doc_path, //The path you'd like to save your file |
||||
235 | 'save_as' => $doc_name, //The name you'd like to save in your server |
||||
236 | 'override' => true, //Replace the file in the destination |
||||
237 | 'validator' => [ |
||||
238 | 'min_size' => 10, //Minimum size is 10KB |
||||
239 | 'max_size' => 1024, //Maximum size is 1MB |
||||
240 | 'allowed_extensions' => ['doc', 'docx'] //Just doc and docx are allowed |
||||
241 | ], |
||||
242 | 'export' => $doc_export |
||||
243 | ], |
||||
244 | [ |
||||
245 | 'name' => 'upload_audio', //The key name that you send to the server |
||||
246 | 'save_to' => $audio_path, //The path you'd like to save your file |
||||
247 | 'save_as' => $audio_name, //The name you'd like to save in your server |
||||
248 | 'override' => true, //Replace the file in the destination |
||||
249 | 'validator' => [ |
||||
250 | 'min_size' => 100, //Minimum size is 100KB |
||||
251 | 'max_size' => 1024 * 10, //Maximum size is 10MB |
||||
252 | 'allowed_extensions' => ['mp3', 'aac', 'ogg'] //Just audio files are allowed |
||||
253 | ], |
||||
254 | 'export' => $audio_export |
||||
255 | ], |
||||
256 | [ |
||||
257 | 'name' => 'upload_video', //The key name that you send to the server |
||||
258 | 'save_to' => $video_path, //The path you'd like to save your file |
||||
259 | 'save_as' => $video_name, //The name you'd like to save in your server(generate random name) |
||||
260 | 'validator' => [ |
||||
261 | 'min_size' => 512, //Minimum size is 512KB |
||||
262 | 'max_size' => 1024 * 170, //Maximum size is 170MB |
||||
263 | 'allowed_extensions' => video_types() //Just video files are allowed |
||||
264 | ], |
||||
265 | 'export' => $export_video |
||||
266 | ], |
||||
267 | [ |
||||
268 | 'name' => 'upload_raw', //The key name that you send to the server |
||||
269 | 'save_to' => __DIR__ . '/raw' //The path you'd like to save your file |
||||
270 | ] |
||||
271 | ]; |
||||
272 | |||||
273 | $uploads = uploads($config_files); |
||||
274 | |||||
275 | echo "<pre>"; |
||||
276 | |||||
277 | echo " |
||||
278 | |------------------------------------------------------All uploads--------------------------------------------------------------| |
||||
279 | "; |
||||
280 | print_r($uploads->all()); //Returns all uploads and their details. |
||||
281 | echo " |
||||
282 | |-------------------------------------------------------Get some uploads-------------------------------------------------------------| |
||||
283 | "; |
||||
284 | print_r($uploads->get(['upload_video', 'upload_raw'])); //Returns specified uploads and their details. |
||||
285 | echo " |
||||
286 | |--------------------------------------------------------Except some uploads------------------------------------------------------------| |
||||
287 | "; |
||||
288 | print_r($uploads->except(['upload_raw', 'upload_image'])); //Returns all uploads and their details except those ones specified. |
||||
289 | echo " |
||||
290 | |--------------------------------------------------------First upload------------------------------------------------------------| |
||||
291 | "; |
||||
292 | print_r($uploads->first()); //Returns first upload and it's detail. |
||||
293 | echo " |
||||
294 | |--------------------------------------------------------All succeeded uploads------------------------------------------------------------| |
||||
295 | "; |
||||
296 | print_r($uploads->succeeded()); //Returns all succeeded uploads and their details. |
||||
297 | echo " |
||||
298 | |--------------------------------------------------------All failed uploads------------------------------------------------------------| |
||||
299 | "; |
||||
300 | print_r($uploads->failed()); //Returns all failed uploads and their details. |
||||
301 | echo " |
||||
302 | |--------------------------------------------------------All names of uploads------------------------------------------------------------| |
||||
303 | "; |
||||
304 | print_r($uploads->names()); //Returns all upload names. |
||||
305 | echo " |
||||
306 | |--------------------------------------------------------The number of uploads------------------------------------------------------------| |
||||
307 | "; |
||||
308 | print_r($uploads->count()); //Returns the number of uploads |
||||
309 | |||||
310 | echo "</pre>"; |
||||
311 | } |
||||
312 | ?> |
||||
313 | <!DOCTYPE html> |
||||
314 | <html> |
||||
315 | <body> |
||||
316 | ************************************************************************************************************************ |
||||
317 | <form action="" method="post" enctype="multipart/form-data"> |
||||
318 | Select files to upload: <br><br><br> |
||||
319 | Select an image: <input type="file" name="upload_image" id="upload_image"><br><br> |
||||
320 | Select a video: <input type="file" name="upload_video" id="upload_video"><br><br> |
||||
321 | Select an audio: <input type="file" name="upload_audio" id="upload_audio"><br><br> |
||||
322 | Select an archive: <input type="file" name="upload_archive" id="upload_archive"><br><br> |
||||
323 | Select a document(word): <input type="file" name="upload_doc" id="upload_doc"><br><br> |
||||
324 | Select a raw file: <input type="file" name="upload_raw" id="upload_raw"><br><br> |
||||
325 | <input type="submit" value="Upload" name="submit"><br><br> |
||||
326 | </form> |
||||
327 | ************************************************************************************************************************ |
||||
328 | |||||
329 | </body> |
||||
330 | </html> |
The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g.
excluded_paths: ["lib/*"]
, you can move it to the dependency path list as follows:For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths