|
21 | 21 | use App\Services\Model\AbstractService; |
22 | 22 | use App\Services\Model\FileInfoDTO; |
23 | 23 | use App\Services\Model\ICompanyService; |
24 | | -use App\Services\Model\IFilePostProcessorForChildEntity; |
25 | 24 | use Illuminate\Http\UploadedFile; |
26 | 25 | use Illuminate\Support\Facades\Log; |
27 | 26 | use libs\utils\FileUtils; |
|
39 | 38 | */ |
40 | 39 | final class CompanyService |
41 | 40 | extends AbstractService |
42 | | - implements ICompanyService, IFilePostProcessorForChildEntity |
| 41 | + implements ICompanyService |
43 | 42 | { |
44 | 43 | use FileUtils; |
45 | 44 |
|
@@ -89,49 +88,8 @@ public function addCompany(array $payload): Company |
89 | 88 | return $company; |
90 | 89 | }); |
91 | 90 |
|
92 | | - if(isset($payload['logo'])){ |
93 | | - $file_upload_info = FileUploadInfo::buildFromPayload($payload['logo']); |
94 | | - if(!is_null($file_upload_info)){ |
95 | | - if(!in_array($file_upload_info->getFileExt(),Company::LogoAllowedExtensions )) |
96 | | - throw new ValidationException(sprintf("Logo file does not has a valid extension (%s).", implode(',', Company::LogoAllowedExtensions))); |
97 | | - $job = new FileProcessingJob(new FileInfoDTO( |
98 | | - owner_entity_id : $company->getId(), |
99 | | - owner_entity_class: Company::class, |
100 | | - owner_member_name: "logo", |
101 | | - filepath: $file_upload_info->getFilePath(), |
102 | | - filename: $file_upload_info->getFileName(), |
103 | | - size: $file_upload_info->getSize(), |
104 | | - md5: $file_upload_info->getMd5(), |
105 | | - mime_type: $file_upload_info->getMimeType(), |
106 | | - source_bucket: $file_upload_info->getSourceBucket() |
107 | | - )); |
108 | | - JobDispatcher::withDbFallback( |
109 | | - job: $job, |
110 | | - ); |
111 | | - } |
112 | | - } |
113 | | - |
114 | | - if(isset($payload['big_logo'])){ |
115 | | - $file_upload_info = FileUploadInfo::buildFromPayload($payload['big_logo']); |
116 | | - if(!is_null($file_upload_info)){ |
117 | | - if(!in_array($file_upload_info->getFileExt(),Company::LogoAllowedExtensions )) |
118 | | - throw new ValidationException(sprintf("Big Logo file does not has a valid extension (%s).", implode(',', Company::LogoAllowedExtensions))); |
119 | | - $job = new FileProcessingJob(new FileInfoDTO( |
120 | | - owner_entity_id : $company->getId(), |
121 | | - owner_entity_class: Company::class, |
122 | | - owner_member_name: "big_logo", |
123 | | - filepath: $file_upload_info->getFilePath(), |
124 | | - filename: $file_upload_info->getFileName(), |
125 | | - size: $file_upload_info->getSize(), |
126 | | - md5: $file_upload_info->getMd5(), |
127 | | - mime_type: $file_upload_info->getMimeType(), |
128 | | - source_bucket: $file_upload_info->getSourceBucket() |
129 | | - )); |
130 | | - JobDispatcher::withDbFallback( |
131 | | - job: $job, |
132 | | - ); |
133 | | - } |
134 | | - } |
| 91 | + if (isset($payload['logo'])) $this->dispatchLogoJob($company, 'logo', $payload['logo']); |
| 92 | + if (isset($payload['big_logo'])) $this->dispatchLogoJob($company, 'big_logo', $payload['big_logo']); |
135 | 93 |
|
136 | 94 | return $company; |
137 | 95 | } |
@@ -278,77 +236,80 @@ public function deleteCompanyBigLogo(int $company_id): void |
278 | 236 | * @throws EntityNotFoundException |
279 | 237 | * @throws ValidationException |
280 | 238 | */ |
281 | | - public function processFileForChildEntity(FileInfoDTO $file_info_dto): IEntity{ |
282 | | - Log::debug(sprintf("CompanyService::processFileForChildEntity file_info_dto %s", $file_info_dto )); |
283 | | - $logo = null; |
284 | | - switch($file_info_dto->owner_member_name){ |
| 239 | + public function processFileForChildEntity(FileInfoDTO $file_info_dto): IEntity { |
| 240 | + Log::debug(sprintf("CompanyService::processFileForChildEntity file_info_dto %s", $file_info_dto)); |
| 241 | + switch ($file_info_dto->owner_member_name) { |
285 | 242 | case 'big_logo': |
286 | | - $localPath = self::getFileFromRemoteStorageOnTempStorage( |
287 | | - $file_info_dto->filename, |
288 | | - $file_info_dto->filepath |
289 | | - ); |
290 | | - $succeeded = false; |
291 | | - try { |
292 | | - if (!is_null($file_info_dto->md5)) { |
293 | | - $localHash = md5_file($localPath); |
294 | | - if ($localHash === false) |
295 | | - throw new ValidationException("File integrity check failed: unable to read local temp file."); |
296 | | - if ($localHash !== strtolower($file_info_dto->md5)) |
297 | | - throw new ValidationException("File integrity check failed: MD5 mismatch."); |
298 | | - } |
299 | | - $file = new UploadedFile( |
300 | | - path: $localPath, |
301 | | - originalName: $file_info_dto->filename, |
302 | | - mimeType: $file_info_dto->mime_type, |
303 | | - error: null, |
304 | | - test: true, |
305 | | - ); |
306 | | - $logo = $this->addCompanyBigLogo($file_info_dto->owner_entity_id, $file); |
307 | | - $succeeded = true; |
308 | | - } finally { |
309 | | - // Remote file preserved on failure so queue retries can re-download it. |
310 | | - if ($succeeded) { |
311 | | - self::cleanLocalAndRemoteFile($localPath, $file_info_dto->filepath); |
312 | | - } else { |
313 | | - self::cleanLocalFile($localPath); |
314 | | - } |
315 | | - } |
316 | | - return $logo; |
| 243 | + return $this->processLogoFile($file_info_dto, [$this, 'addCompanyBigLogo']); |
317 | 244 | case 'logo': |
318 | | - $localPath = self::getFileFromRemoteStorageOnTempStorage( |
319 | | - $file_info_dto->filename, |
320 | | - $file_info_dto->filepath |
321 | | - ); |
322 | | - $succeeded = false; |
323 | | - try { |
324 | | - if (!is_null($file_info_dto->md5)) { |
325 | | - $localHash = md5_file($localPath); |
326 | | - if ($localHash === false) |
327 | | - throw new ValidationException("File integrity check failed: unable to read local temp file."); |
328 | | - if ($localHash !== strtolower($file_info_dto->md5)) |
329 | | - throw new ValidationException("File integrity check failed: MD5 mismatch."); |
330 | | - } |
331 | | - $file = new UploadedFile( |
332 | | - path: $localPath, |
333 | | - originalName: $file_info_dto->filename, |
334 | | - mimeType: $file_info_dto->mime_type, |
335 | | - error: null, |
336 | | - test: true, |
337 | | - ); |
338 | | - $logo = $this->addCompanyLogo($file_info_dto->owner_entity_id, $file); |
339 | | - $succeeded = true; |
340 | | - } finally { |
341 | | - // Remote file preserved on failure so queue retries can re-download it. |
342 | | - if ($succeeded) { |
343 | | - self::cleanLocalAndRemoteFile($localPath, $file_info_dto->filepath); |
344 | | - } else { |
345 | | - self::cleanLocalFile($localPath); |
346 | | - } |
347 | | - } |
348 | | - return $logo; |
| 245 | + return $this->processLogoFile($file_info_dto, [$this, 'addCompanyLogo']); |
349 | 246 | default: |
350 | 247 | Log::warning(sprintf("CompanyService::processFileForChildEntity unknown member name '%s'", $file_info_dto->owner_member_name)); |
351 | 248 | throw new \InvalidArgumentException(sprintf("Unknown owner_member_name '%s' for entity class '%s'.", $file_info_dto->owner_member_name, $file_info_dto->owner_entity_class)); |
352 | 249 | } |
353 | 250 | } |
| 251 | + |
| 252 | + /** |
| 253 | + * Downloads a file from remote storage to a local temp path, verifies its MD5 (when provided), |
| 254 | + * invokes $uploader to persist it, then cleans up. On failure the remote file is preserved |
| 255 | + * so queue retries can re-download it. |
| 256 | + */ |
| 257 | + private function processLogoFile(FileInfoDTO $file_info_dto, callable $uploader): IEntity |
| 258 | + { |
| 259 | + $localPath = self::getFileFromRemoteStorageOnTempStorage( |
| 260 | + $file_info_dto->filename, |
| 261 | + $file_info_dto->filepath |
| 262 | + ); |
| 263 | + $succeeded = false; |
| 264 | + try { |
| 265 | + if (!is_null($file_info_dto->md5)) { |
| 266 | + $localHash = md5_file($localPath); |
| 267 | + if ($localHash === false) |
| 268 | + throw new ValidationException("File integrity check failed: unable to read local temp file."); |
| 269 | + if ($localHash !== strtolower($file_info_dto->md5)) |
| 270 | + throw new ValidationException("File integrity check failed: MD5 mismatch."); |
| 271 | + } |
| 272 | + $file = new UploadedFile( |
| 273 | + path: $localPath, |
| 274 | + originalName: $file_info_dto->filename, |
| 275 | + mimeType: $file_info_dto->mime_type, |
| 276 | + error: null, |
| 277 | + test: true, |
| 278 | + ); |
| 279 | + $logo = $uploader($file_info_dto->owner_entity_id, $file); |
| 280 | + $succeeded = true; |
| 281 | + } finally { |
| 282 | + if ($succeeded) { |
| 283 | + self::cleanLocalAndRemoteFile($localPath, $file_info_dto->filepath); |
| 284 | + } else { |
| 285 | + self::cleanLocalFile($localPath); |
| 286 | + } |
| 287 | + } |
| 288 | + return $logo; |
| 289 | + } |
| 290 | + |
| 291 | + private function dispatchLogoJob(Company $company, string $memberName, array $payload): void |
| 292 | + { |
| 293 | + $file_upload_info = FileUploadInfo::buildFromPayload($payload); |
| 294 | + if (is_null($file_upload_info)) return; |
| 295 | + |
| 296 | + if (!in_array($file_upload_info->getFileExt(), Company::LogoAllowedExtensions)) |
| 297 | + throw new ValidationException(sprintf( |
| 298 | + "%s file does not have a valid extension (%s).", |
| 299 | + ucwords(str_replace('_', ' ', $memberName)), |
| 300 | + implode(',', Company::LogoAllowedExtensions) |
| 301 | + )); |
| 302 | + |
| 303 | + JobDispatcher::withDbFallback(job: new FileProcessingJob(new FileInfoDTO( |
| 304 | + owner_entity_id: $company->getId(), |
| 305 | + owner_entity_class: Company::class, |
| 306 | + owner_member_name: $memberName, |
| 307 | + filepath: $file_upload_info->getFilePath(), |
| 308 | + filename: $file_upload_info->getFileName(), |
| 309 | + size: $file_upload_info->getSize(), |
| 310 | + md5: $file_upload_info->getMd5(), |
| 311 | + mime_type: $file_upload_info->getMimeType(), |
| 312 | + source_bucket: $file_upload_info->getSourceBucket() |
| 313 | + ))); |
| 314 | + } |
354 | 315 | } |
0 commit comments