| 
									
										
										
										
											2015-07-18 09:49:29 +02:00
										 |  |  | <?php | 
					
						
							| 
									
										
										
										
											2022-12-29 19:41:57 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-20 12:27:31 +02:00
										 |  |  | /** | 
					
						
							|  |  |  |  * AttachmentHelper.php | 
					
						
							| 
									
										
										
										
											2020-01-28 08:46:01 +01:00
										 |  |  |  * Copyright (c) 2019 james@firefly-iii.org | 
					
						
							| 
									
										
										
										
											2016-05-20 12:27:31 +02:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2019-10-02 06:37:26 +02:00
										 |  |  |  * This file is part of Firefly III (https://github.com/firefly-iii). | 
					
						
							| 
									
										
										
										
											2016-10-05 06:52:15 +02:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2019-10-02 06:37:26 +02:00
										 |  |  |  * This program is free software: you can redistribute it and/or modify | 
					
						
							|  |  |  |  * it under the terms of the GNU Affero General Public License as | 
					
						
							|  |  |  |  * published by the Free Software Foundation, either version 3 of the | 
					
						
							|  |  |  |  * License, or (at your option) any later version. | 
					
						
							| 
									
										
										
										
											2017-10-21 08:40:00 +02:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2019-10-02 06:37:26 +02:00
										 |  |  |  * This program is distributed in the hope that it will be useful, | 
					
						
							| 
									
										
										
										
											2017-10-21 08:40:00 +02:00
										 |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							| 
									
										
										
										
											2019-10-02 06:37:26 +02:00
										 |  |  |  * GNU Affero General Public License for more details. | 
					
						
							| 
									
										
										
										
											2017-10-21 08:40:00 +02:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2019-10-02 06:37:26 +02:00
										 |  |  |  * You should have received a copy of the GNU Affero General Public License | 
					
						
							|  |  |  |  * along with this program.  If not, see <https://www.gnu.org/licenses/>. | 
					
						
							| 
									
										
										
										
											2016-05-20 12:27:31 +02:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2017-04-09 07:44:22 +02:00
										 |  |  | declare(strict_types=1); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-18 09:49:29 +02:00
										 |  |  | namespace FireflyIII\Helpers\Attachments; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-27 13:54:59 +02:00
										 |  |  | use FireflyIII\Exceptions\FireflyException; | 
					
						
							| 
									
										
										
										
											2015-07-18 09:49:29 +02:00
										 |  |  | use FireflyIII\Models\Attachment; | 
					
						
							| 
									
										
										
										
											2020-03-19 09:14:49 +01:00
										 |  |  | use FireflyIII\Models\PiggyBank; | 
					
						
							| 
									
										
										
										
											2018-05-06 16:19:29 +02:00
										 |  |  | use Illuminate\Contracts\Encryption\DecryptException; | 
					
						
							| 
									
										
										
										
											2020-03-17 15:01:00 +01:00
										 |  |  | use Illuminate\Contracts\Encryption\EncryptException; | 
					
						
							|  |  |  | use Illuminate\Contracts\Filesystem\Filesystem; | 
					
						
							| 
									
										
										
										
											2015-07-18 09:49:29 +02:00
										 |  |  | use Illuminate\Database\Eloquent\Model; | 
					
						
							| 
									
										
										
										
											2017-04-28 18:04:57 +02:00
										 |  |  | use Illuminate\Support\Collection; | 
					
						
							| 
									
										
										
										
											2023-11-01 18:53:36 +01:00
										 |  |  | use Illuminate\Support\Facades\Log; | 
					
						
							| 
									
										
										
										
											2019-02-13 17:38:41 +01:00
										 |  |  | use Illuminate\Support\Facades\Storage; | 
					
						
							| 
									
										
										
										
											2015-07-18 09:49:29 +02:00
										 |  |  | use Illuminate\Support\MessageBag; | 
					
						
							| 
									
										
										
										
											2016-02-16 18:39:03 +01:00
										 |  |  | use Symfony\Component\HttpFoundation\File\UploadedFile; | 
					
						
							| 
									
										
										
										
											2017-06-05 11:12:50 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-18 09:49:29 +02:00
										 |  |  | /** | 
					
						
							| 
									
										
										
										
											2017-11-15 12:25:49 +01:00
										 |  |  |  * Class AttachmentHelper. | 
					
						
							| 
									
										
										
										
											2015-07-18 09:49:29 +02:00
										 |  |  |  */ | 
					
						
							|  |  |  | class AttachmentHelper implements AttachmentHelperInterface | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2021-04-08 10:13:35 +02:00
										 |  |  |     public Collection $attachments; | 
					
						
							|  |  |  |     public MessageBag $errors; | 
					
						
							|  |  |  |     public MessageBag $messages; | 
					
						
							|  |  |  |     protected array   $allowedMimes  = []; | 
					
						
							|  |  |  |     protected int     $maxUploadSize = 0; | 
					
						
							| 
									
										
										
										
											2015-07-18 09:49:29 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-04 14:09:51 +01:00
										 |  |  |     protected Filesystem $uploadDisk; | 
					
						
							| 
									
										
										
										
											2021-03-28 11:46:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-18 09:49:29 +02:00
										 |  |  |     /** | 
					
						
							| 
									
										
										
										
											2018-02-28 21:32:59 +01:00
										 |  |  |      * AttachmentHelper constructor. | 
					
						
							| 
									
										
										
										
											2015-07-18 09:49:29 +02:00
										 |  |  |      */ | 
					
						
							|  |  |  |     public function __construct() | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2024-12-22 08:43:12 +01:00
										 |  |  |         $this->maxUploadSize = (int) config('firefly.maxUploadSize'); | 
					
						
							|  |  |  |         $this->allowedMimes  = (array) config('firefly.allowedMimes'); | 
					
						
							| 
									
										
										
										
											2022-10-30 14:24:19 +01:00
										 |  |  |         $this->errors        = new MessageBag(); | 
					
						
							|  |  |  |         $this->messages      = new MessageBag(); | 
					
						
							|  |  |  |         $this->attachments   = new Collection(); | 
					
						
							| 
									
										
										
										
											2016-02-23 09:12:21 +01:00
										 |  |  |         $this->uploadDisk    = Storage::disk('upload'); | 
					
						
							| 
									
										
										
										
											2015-07-18 09:49:29 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-03-28 11:46:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-06 16:19:29 +02:00
										 |  |  |     /** | 
					
						
							| 
									
										
										
										
											2018-07-07 21:17:46 +02:00
										 |  |  |      * Returns the content of an attachment. | 
					
						
							| 
									
										
										
										
											2018-05-06 16:19:29 +02:00
										 |  |  |      */ | 
					
						
							|  |  |  |     public function getAttachmentContent(Attachment $attachment): string | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2024-12-22 08:43:12 +01:00
										 |  |  |         $encryptedData = (string) $this->uploadDisk->get(sprintf('at-%d.data', $attachment->id)); | 
					
						
							| 
									
										
										
										
											2023-12-20 19:35:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-06 16:19:29 +02:00
										 |  |  |         try { | 
					
						
							| 
									
										
										
										
											2023-12-20 19:35:52 +01:00
										 |  |  |             $unencryptedData = \Crypt::decrypt($encryptedData); // verified
 | 
					
						
							| 
									
										
										
										
											2022-03-19 08:10:42 +01:00
										 |  |  |         } catch (DecryptException $e) { | 
					
						
							| 
									
										
										
										
											2023-11-01 18:53:36 +01:00
										 |  |  |             Log::error(sprintf('Could not decrypt data of attachment #%d: %s', $attachment->id, $e->getMessage())); | 
					
						
							| 
									
										
										
										
											2019-08-25 07:25:01 +02:00
										 |  |  |             $unencryptedData = $encryptedData; | 
					
						
							| 
									
										
										
										
											2018-05-06 16:19:29 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-25 07:25:01 +02:00
										 |  |  |         return $unencryptedData; | 
					
						
							| 
									
										
										
										
											2018-05-06 16:19:29 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-18 21:32:31 +02:00
										 |  |  |     /** | 
					
						
							| 
									
										
										
										
											2018-10-13 09:56:26 +03:00
										 |  |  |      * Returns the file path relative to upload disk for an attachment, | 
					
						
							| 
									
										
										
										
											2015-07-18 21:32:31 +02:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2016-02-18 07:21:48 +01:00
										 |  |  |     public function getAttachmentLocation(Attachment $attachment): string | 
					
						
							| 
									
										
										
										
											2015-07-18 21:32:31 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2023-12-20 19:35:52 +01:00
										 |  |  |         return sprintf('%sat-%d.data', \DIRECTORY_SEPARATOR, $attachment->id); | 
					
						
							| 
									
										
										
										
											2015-07-18 21:32:31 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-28 18:04:57 +02:00
										 |  |  |     /** | 
					
						
							| 
									
										
										
										
											2018-07-07 21:17:46 +02:00
										 |  |  |      * Get all attachments. | 
					
						
							| 
									
										
										
										
											2017-04-28 18:04:57 +02:00
										 |  |  |      */ | 
					
						
							|  |  |  |     public function getAttachments(): Collection | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return $this->attachments; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-19 13:59:54 +01:00
										 |  |  |     /** | 
					
						
							| 
									
										
										
										
											2018-07-07 21:17:46 +02:00
										 |  |  |      * Get all errors. | 
					
						
							| 
									
										
										
										
											2016-01-19 13:59:54 +01:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2016-02-18 07:21:48 +01:00
										 |  |  |     public function getErrors(): MessageBag | 
					
						
							| 
									
										
										
										
											2016-01-19 13:59:54 +01:00
										 |  |  |     { | 
					
						
							|  |  |  |         return $this->errors; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							| 
									
										
										
										
											2018-07-07 21:17:46 +02:00
										 |  |  |      * Get all messages. | 
					
						
							| 
									
										
										
										
											2016-01-19 13:59:54 +01:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2016-02-18 07:21:48 +01:00
										 |  |  |     public function getMessages(): MessageBag | 
					
						
							| 
									
										
										
										
											2016-01-19 13:59:54 +01:00
										 |  |  |     { | 
					
						
							|  |  |  |         return $this->messages; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-24 06:51:22 +02:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Uploads a file as a string. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function saveAttachmentFromApi(Attachment $attachment, string $content): bool | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2023-11-01 18:53:36 +01:00
										 |  |  |         Log::debug(sprintf('Now in %s', __METHOD__)); | 
					
						
							| 
									
										
										
										
											2024-01-01 14:43:56 +01:00
										 |  |  |         $resource             = tmpfile(); | 
					
						
							| 
									
										
										
										
											2018-06-24 06:51:22 +02:00
										 |  |  |         if (false === $resource) { | 
					
						
							| 
									
										
										
										
											2023-11-01 18:53:36 +01:00
										 |  |  |             Log::error('Cannot create temp-file for file upload.'); | 
					
						
							| 
									
										
										
										
											2018-06-24 06:51:22 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-10-20 16:17:43 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if ('' === $content) { | 
					
						
							| 
									
										
										
										
											2023-11-01 18:53:36 +01:00
										 |  |  |             Log::error('Cannot upload empty file.'); | 
					
						
							| 
									
										
										
										
											2019-10-20 16:17:43 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-01 14:43:56 +01:00
										 |  |  |         $path                 = stream_get_meta_data($resource)['uri']; | 
					
						
							| 
									
										
										
										
											2023-11-01 18:53:36 +01:00
										 |  |  |         Log::debug(sprintf('Path is %s', $path)); | 
					
						
							| 
									
										
										
										
											2024-01-01 14:43:56 +01:00
										 |  |  |         $result               = fwrite($resource, $content); | 
					
						
							| 
									
										
										
										
											2023-11-26 12:10:42 +01:00
										 |  |  |         if (false === $result) { | 
					
						
							| 
									
										
										
										
											2023-11-01 18:53:36 +01:00
										 |  |  |             Log::error('Could not write temp file.'); | 
					
						
							| 
									
										
										
										
											2023-12-20 19:35:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-01 18:53:36 +01:00
										 |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         Log::debug(sprintf('Wrote %d bytes to temp file.', $result)); | 
					
						
							| 
									
										
										
										
											2024-01-01 14:43:56 +01:00
										 |  |  |         $finfo                = finfo_open(FILEINFO_MIME_TYPE); | 
					
						
							| 
									
										
										
										
											2023-11-26 12:10:42 +01:00
										 |  |  |         if (false === $finfo) { | 
					
						
							|  |  |  |             Log::error('Could not open finfo.'); | 
					
						
							|  |  |  |             fclose($resource); | 
					
						
							| 
									
										
										
										
											2023-12-20 19:35:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-26 12:10:42 +01:00
										 |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2024-12-22 08:43:12 +01:00
										 |  |  |         $mime                 = (string) finfo_file($finfo, $path); | 
					
						
							| 
									
										
										
										
											2024-01-01 14:43:56 +01:00
										 |  |  |         $allowedMime          = config('firefly.allowedMimes'); | 
					
						
							| 
									
										
										
										
											2019-06-21 19:10:02 +02:00
										 |  |  |         if (!in_array($mime, $allowedMime, true)) { | 
					
						
							| 
									
										
										
										
											2023-11-01 18:53:36 +01:00
										 |  |  |             Log::error(sprintf('Mime type %s is not allowed for API file upload.', $mime)); | 
					
						
							| 
									
										
										
										
											2021-10-01 11:33:45 +02:00
										 |  |  |             fclose($resource); | 
					
						
							| 
									
										
										
										
											2018-06-24 06:51:22 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-11-01 18:53:36 +01:00
										 |  |  |         Log::debug(sprintf('Found mime "%s" in file "%s"', $mime, $path)); | 
					
						
							| 
									
										
										
										
											2019-08-25 07:25:01 +02:00
										 |  |  |         // is allowed? Save the file, without encryption.
 | 
					
						
							| 
									
										
										
										
											2024-01-01 14:43:56 +01:00
										 |  |  |         $parts                = explode('/', $attachment->fileName()); | 
					
						
							|  |  |  |         $file                 = $parts[count($parts) - 1]; | 
					
						
							| 
									
										
										
										
											2023-11-01 18:53:36 +01:00
										 |  |  |         Log::debug(sprintf('Write file to disk in file named "%s"', $file)); | 
					
						
							| 
									
										
										
										
											2021-12-17 17:27:01 +01:00
										 |  |  |         $this->uploadDisk->put($file, $content); | 
					
						
							| 
									
										
										
										
											2018-06-24 06:51:22 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         // update attachment.
 | 
					
						
							| 
									
										
										
										
											2024-12-22 08:43:12 +01:00
										 |  |  |         $attachment->md5      = (string) md5_file($path); | 
					
						
							| 
									
										
										
										
											2018-06-24 06:51:22 +02:00
										 |  |  |         $attachment->mime     = $mime; | 
					
						
							| 
									
										
										
										
											2019-06-07 17:58:11 +02:00
										 |  |  |         $attachment->size     = strlen($content); | 
					
						
							| 
									
										
										
										
											2018-07-14 23:04:05 +02:00
										 |  |  |         $attachment->uploaded = true; | 
					
						
							| 
									
										
										
										
											2018-06-24 06:51:22 +02:00
										 |  |  |         $attachment->save(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-01 18:53:36 +01:00
										 |  |  |         Log::debug('Done!'); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-24 06:51:22 +02:00
										 |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-18 09:49:29 +02:00
										 |  |  |     /** | 
					
						
							| 
									
										
										
										
											2018-07-07 21:17:46 +02:00
										 |  |  |      * Save attachments that get uploaded with models, through the app. | 
					
						
							|  |  |  |      * | 
					
						
							| 
									
										
										
										
											2021-03-21 09:15:40 +01:00
										 |  |  |      * @throws FireflyException | 
					
						
							| 
									
										
										
										
											2015-07-18 09:49:29 +02:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2018-09-23 06:57:37 +02:00
										 |  |  |     public function saveAttachmentsForModel(object $model, ?array $files): bool | 
					
						
							| 
									
										
										
										
											2015-07-18 09:49:29 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2023-12-20 19:35:52 +01:00
										 |  |  |         if (!$model instanceof Model) { | 
					
						
							| 
									
										
										
										
											2021-04-08 10:13:35 +02:00
										 |  |  |             return false; | 
					
						
							| 
									
										
										
										
											2018-09-23 06:57:37 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-10-20 16:17:43 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-01 18:53:36 +01:00
										 |  |  |         Log::debug(sprintf('Now in saveAttachmentsForModel for model %s', get_class($model))); | 
					
						
							| 
									
										
										
										
											2019-06-22 13:09:25 +02:00
										 |  |  |         if (is_array($files)) { | 
					
						
							| 
									
										
										
										
											2023-11-01 18:53:36 +01:00
										 |  |  |             Log::debug('$files is an array.'); | 
					
						
							| 
									
										
										
										
											2023-12-20 19:35:52 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |             /** @var null|UploadedFile $entry */ | 
					
						
							| 
									
										
										
										
											2016-12-28 13:02:56 +01:00
										 |  |  |             foreach ($files as $entry) { | 
					
						
							| 
									
										
										
										
											2017-11-15 12:25:49 +01:00
										 |  |  |                 if (null !== $entry) { | 
					
						
							| 
									
										
										
										
											2016-12-28 13:02:56 +01:00
										 |  |  |                     $this->processFile($entry, $model); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2023-11-01 18:53:36 +01:00
										 |  |  |             Log::debug('Done processing uploads.'); | 
					
						
							| 
									
										
										
										
											2015-07-18 09:49:29 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-04-07 07:28:43 +02:00
										 |  |  |         if (!is_array($files)) { | 
					
						
							| 
									
										
										
										
											2023-11-01 18:53:36 +01:00
										 |  |  |             Log::debug('Array of files is not an array. Probably nothing uploaded. Will not store attachments.'); | 
					
						
							| 
									
										
										
										
											2018-07-07 21:17:46 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2015-07-18 09:49:29 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-18 22:17:31 +02:00
										 |  |  |     /** | 
					
						
							| 
									
										
										
										
											2018-07-07 21:17:46 +02:00
										 |  |  |      * Process the upload of a file. | 
					
						
							|  |  |  |      * | 
					
						
							| 
									
										
										
										
											2021-03-21 09:15:40 +01:00
										 |  |  |      * @throws FireflyException | 
					
						
							|  |  |  |      * @throws EncryptException | 
					
						
							| 
									
										
										
										
											2015-07-18 22:17:31 +02:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2018-07-07 21:17:46 +02:00
										 |  |  |     protected function processFile(UploadedFile $file, Model $model): ?Attachment | 
					
						
							| 
									
										
										
										
											2015-07-18 22:17:31 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2023-11-01 18:53:36 +01:00
										 |  |  |         Log::debug('Now in processFile()'); | 
					
						
							| 
									
										
										
										
											2015-07-18 22:17:31 +02:00
										 |  |  |         $validation = $this->validateUpload($file, $model); | 
					
						
							| 
									
										
										
										
											2018-07-07 21:17:46 +02:00
										 |  |  |         $attachment = null; | 
					
						
							|  |  |  |         if (false !== $validation) { | 
					
						
							| 
									
										
										
										
											2024-01-01 14:43:56 +01:00
										 |  |  |             $user                 = $model->user; | 
					
						
							| 
									
										
										
										
											2022-12-31 06:57:05 +01:00
										 |  |  |             // ignore lines about polymorphic calls.
 | 
					
						
							|  |  |  |             if ($model instanceof PiggyBank) { | 
					
						
							| 
									
										
										
										
											2022-12-31 07:33:44 +01:00
										 |  |  |                 $user = $model->account->user; | 
					
						
							| 
									
										
										
										
											2020-03-19 09:14:49 +01:00
										 |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-01 14:43:56 +01:00
										 |  |  |             $attachment           = new Attachment(); // create Attachment object.
 | 
					
						
							| 
									
										
										
										
											2020-03-19 09:14:49 +01:00
										 |  |  |             $attachment->user()->associate($user); | 
					
						
							| 
									
										
										
										
											2018-07-07 21:17:46 +02:00
										 |  |  |             $attachment->attachable()->associate($model); | 
					
						
							| 
									
										
										
										
											2024-12-22 08:43:12 +01:00
										 |  |  |             $attachment->md5      = (string) md5_file($file->getRealPath()); | 
					
						
							| 
									
										
										
										
											2018-07-07 21:17:46 +02:00
										 |  |  |             $attachment->filename = $file->getClientOriginalName(); | 
					
						
							|  |  |  |             $attachment->mime     = $file->getMimeType(); | 
					
						
							|  |  |  |             $attachment->size     = $file->getSize(); | 
					
						
							| 
									
										
										
										
											2018-07-22 21:32:58 +02:00
										 |  |  |             $attachment->uploaded = false; | 
					
						
							| 
									
										
										
										
											2018-07-07 21:17:46 +02:00
										 |  |  |             $attachment->save(); | 
					
						
							| 
									
										
										
										
											2023-11-01 18:53:36 +01:00
										 |  |  |             Log::debug('Created attachment:', $attachment->toArray()); | 
					
						
							| 
									
										
										
										
											2018-07-07 21:17:46 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-01 14:43:56 +01:00
										 |  |  |             $fileObject           = $file->openFile(); | 
					
						
							| 
									
										
										
										
											2018-07-07 21:17:46 +02:00
										 |  |  |             $fileObject->rewind(); | 
					
						
							| 
									
										
										
										
											2018-09-27 13:54:59 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-13 17:38:41 +01:00
										 |  |  |             if (0 === $file->getSize()) { | 
					
						
							| 
									
										
										
										
											2024-03-16 06:25:56 +01:00
										 |  |  |                 $this->errors->add('attachments', trans('validation.file_zero_length')); | 
					
						
							| 
									
										
										
										
											2024-03-16 06:28:21 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-16 06:25:56 +01:00
										 |  |  |                 return null; | 
					
						
							| 
									
										
										
										
											2018-09-27 13:54:59 +02:00
										 |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-22 08:43:12 +01:00
										 |  |  |             $content              = (string) $fileObject->fread($file->getSize()); | 
					
						
							| 
									
										
										
										
											2023-11-01 18:53:36 +01:00
										 |  |  |             Log::debug(sprintf('Full file length is %d and upload size is %d.', strlen($content), $file->getSize())); | 
					
						
							| 
									
										
										
										
											2018-07-07 21:17:46 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-29 12:10:13 +02:00
										 |  |  |             // store it without encryption.
 | 
					
						
							| 
									
										
										
										
											2019-08-25 07:25:01 +02:00
										 |  |  |             $this->uploadDisk->put($attachment->fileName(), $content); | 
					
						
							| 
									
										
										
										
											2018-07-25 06:45:25 +02:00
										 |  |  |             $attachment->uploaded = true; // update attachment
 | 
					
						
							| 
									
										
										
										
											2018-07-07 21:17:46 +02:00
										 |  |  |             $attachment->save(); | 
					
						
							|  |  |  |             $this->attachments->push($attachment); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-01 14:43:56 +01:00
										 |  |  |             $name                 = e($file->getClientOriginalName()); // add message:
 | 
					
						
							| 
									
										
										
										
											2024-12-22 08:43:12 +01:00
										 |  |  |             $msg                  = (string) trans('validation.file_attached', ['name' => $name]); | 
					
						
							| 
									
										
										
										
											2018-07-07 21:17:46 +02:00
										 |  |  |             $this->messages->add('attachments', $msg); | 
					
						
							| 
									
										
										
										
											2015-07-18 22:17:31 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-18 09:49:29 +02:00
										 |  |  |         return $attachment; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Verify if the file was uploaded correctly. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     protected function validateUpload(UploadedFile $file, Model $model): bool | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2023-11-01 18:53:36 +01:00
										 |  |  |         Log::debug('Now in validateUpload()'); | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |         $result = true; | 
					
						
							|  |  |  |         if (!$this->validMime($file)) { | 
					
						
							|  |  |  |             $result = false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (0 === $file->getSize()) { | 
					
						
							| 
									
										
										
										
											2023-11-01 18:53:36 +01:00
										 |  |  |             Log::error('Cannot upload empty file.'); | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |             $result = false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // can't seem to reach this point.
 | 
					
						
							|  |  |  |         if (true === $result && !$this->validSize($file)) { | 
					
						
							|  |  |  |             $result = false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (true === $result && $this->hasFile($file, $model)) { | 
					
						
							|  |  |  |             $result = false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return $result; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-18 21:46:16 +02:00
										 |  |  |     /** | 
					
						
							| 
									
										
										
										
											2018-07-07 21:17:46 +02:00
										 |  |  |      * Verify if the mime of a file is valid. | 
					
						
							| 
									
										
										
										
											2015-07-18 21:46:16 +02:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2016-02-18 07:21:48 +01:00
										 |  |  |     protected function validMime(UploadedFile $file): bool | 
					
						
							| 
									
										
										
										
											2015-07-18 09:49:29 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2023-11-01 18:53:36 +01:00
										 |  |  |         Log::debug('Now in validMime()'); | 
					
						
							| 
									
										
										
										
											2024-01-01 14:43:56 +01:00
										 |  |  |         $mime   = e($file->getMimeType()); | 
					
						
							|  |  |  |         $name   = e($file->getClientOriginalName()); | 
					
						
							| 
									
										
										
										
											2023-11-01 18:53:36 +01:00
										 |  |  |         Log::debug(sprintf('Name is %s, and mime is %s', $name, $mime)); | 
					
						
							|  |  |  |         Log::debug('Valid mimes are', $this->allowedMimes); | 
					
						
							| 
									
										
										
										
											2018-07-07 21:17:46 +02:00
										 |  |  |         $result = true; | 
					
						
							| 
									
										
										
										
											2015-07-18 09:49:29 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-21 19:10:02 +02:00
										 |  |  |         if (!in_array($mime, $this->allowedMimes, true)) { | 
					
						
							| 
									
										
										
										
											2024-12-22 08:43:12 +01:00
										 |  |  |             $msg    = (string) trans('validation.file_invalid_mime', ['name' => $name, 'mime' => $mime]); | 
					
						
							| 
									
										
										
										
											2015-07-18 22:17:31 +02:00
										 |  |  |             $this->errors->add('attachments', $msg); | 
					
						
							| 
									
										
										
										
											2023-11-01 18:53:36 +01:00
										 |  |  |             Log::error($msg); | 
					
						
							| 
									
										
										
										
											2015-07-18 09:49:29 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-07 21:17:46 +02:00
										 |  |  |             $result = false; | 
					
						
							| 
									
										
										
										
											2015-07-18 09:49:29 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-07 21:17:46 +02:00
										 |  |  |         return $result; | 
					
						
							| 
									
										
										
										
											2015-07-18 09:49:29 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-18 21:46:16 +02:00
										 |  |  |     /** | 
					
						
							| 
									
										
										
										
											2018-07-07 21:17:46 +02:00
										 |  |  |      * Verify if the size of a file is valid. | 
					
						
							| 
									
										
										
										
											2015-07-18 21:46:16 +02:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2016-02-18 07:21:48 +01:00
										 |  |  |     protected function validSize(UploadedFile $file): bool | 
					
						
							| 
									
										
										
										
											2015-07-18 09:49:29 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2018-07-07 21:17:46 +02:00
										 |  |  |         $size   = $file->getSize(); | 
					
						
							|  |  |  |         $name   = e($file->getClientOriginalName()); | 
					
						
							|  |  |  |         $result = true; | 
					
						
							| 
									
										
										
										
											2015-07-18 09:49:29 +02:00
										 |  |  |         if ($size > $this->maxUploadSize) { | 
					
						
							| 
									
										
										
										
											2024-12-22 08:43:12 +01:00
										 |  |  |             $msg    = (string) trans('validation.file_too_large', ['name' => $name]); | 
					
						
							| 
									
										
										
										
											2015-07-18 22:17:31 +02:00
										 |  |  |             $this->errors->add('attachments', $msg); | 
					
						
							| 
									
										
										
										
											2023-11-01 18:53:36 +01:00
										 |  |  |             Log::error($msg); | 
					
						
							| 
									
										
										
										
											2015-07-18 09:49:29 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-07 21:17:46 +02:00
										 |  |  |             $result = false; | 
					
						
							| 
									
										
										
										
											2015-07-18 09:49:29 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-07 21:17:46 +02:00
										 |  |  |         return $result; | 
					
						
							| 
									
										
										
										
											2015-07-18 09:49:29 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |      * Check if a model already has this file attached. | 
					
						
							| 
									
										
										
										
											2015-07-18 09:49:29 +02:00
										 |  |  |      */ | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |     protected function hasFile(UploadedFile $file, Model $model): bool | 
					
						
							| 
									
										
										
										
											2015-07-18 09:49:29 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2024-01-01 14:43:56 +01:00
										 |  |  |         $md5    = md5_file($file->getRealPath()); | 
					
						
							|  |  |  |         $name   = $file->getClientOriginalName(); | 
					
						
							|  |  |  |         $class  = get_class($model); | 
					
						
							|  |  |  |         $count  = 0; | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |         // ignore lines about polymorphic calls.
 | 
					
						
							|  |  |  |         if ($model instanceof PiggyBank) { | 
					
						
							|  |  |  |             $count = $model->account->user->attachments()->where('md5', $md5)->where('attachable_id', $model->id)->where('attachable_type', $class)->count(); | 
					
						
							| 
									
										
										
										
											2016-01-19 13:59:54 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-12-20 19:35:52 +01:00
										 |  |  |         if (!$model instanceof PiggyBank) { | 
					
						
							| 
									
										
										
										
											2023-10-29 12:10:03 +01:00
										 |  |  |             $count = $model->user->attachments()->where('md5', $md5)->where('attachable_id', $model->id)->where('attachable_type', $class)->count(); | 
					
						
							| 
									
										
										
										
											2023-05-29 13:56:55 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |         $result = false; | 
					
						
							|  |  |  |         if ($count > 0) { | 
					
						
							| 
									
										
										
										
											2024-12-22 08:43:12 +01:00
										 |  |  |             $msg    = (string) trans('validation.file_already_attached', ['name' => $name]); | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |             $this->errors->add('attachments', $msg); | 
					
						
							| 
									
										
										
										
											2023-11-01 18:53:36 +01:00
										 |  |  |             Log::error($msg); | 
					
						
							| 
									
										
										
										
											2023-06-21 12:34:58 +02:00
										 |  |  |             $result = true; | 
					
						
							| 
									
										
										
										
											2016-01-19 13:59:54 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2015-07-18 09:49:29 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-07 21:17:46 +02:00
										 |  |  |         return $result; | 
					
						
							| 
									
										
										
										
											2015-07-18 09:49:29 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-07-19 09:38:44 +02:00
										 |  |  | } |