> */ protected array $sizes = []; public function initFileProperties(): void { parent::initFileProperties(); if ($this->file_key !== '' && $this->file_metadata !== null && array_key_exists( 'sizes', $this->file_metadata )) { $this->sizes = $this->file_metadata['sizes']; $this->initSizeProperties(); } } public function initSizeProperties(): bool { helper('filesystem'); $fileKeyWithoutExt = path_without_ext($this->file_key); foreach ($this->sizes as $name => $size) { $extension = array_key_exists('extension', $size) ? $size['extension'] : $this->file_extension; $mimetype = array_key_exists('mimetype', $size) ? $size['mimetype'] : $this->file_mimetype; $this->{$name . '_key'} = $fileKeyWithoutExt . '_' . $name . '.' . $extension; $this->{$name . '_url'} = $this->fileManager->getUrl($this->{$name . '_key'}); $this->{$name . '_mimetype'} = $mimetype; } return true; } /** * @param array $data */ public function setAttributes(array $data): self { parent::setAttributes($data); if ($this->attributes === []) { return $this; } if ($this->file_metadata !== [] && array_key_exists('sizes', $this->file_metadata)) { $this->sizes = $this->file_metadata['sizes']; $this->attributes['sizes'] = $this->file_metadata['sizes']; $this->initFileProperties(); $this->initSizeProperties(); } return $this; } public function setFile(File $file): self { parent::setFile($file); if ($this->file_mimetype === 'image/jpeg' && $metadata = @exif_read_data( $file->getRealPath(), null, true )) { $metadata['sizes'] = $this->attributes['sizes']; $this->attributes['file_size'] = $metadata['FILE']['FileSize']; } else { $metadata = [ 'sizes' => $this->attributes['sizes'], ]; } $this->attributes['file_metadata'] = json_encode($metadata, JSON_INVALID_UTF8_IGNORE); return $this; } public function saveFile(): bool { if ($this->attributes['sizes'] !== []) { $this->initFileProperties(); $this->saveSizes(); } return parent::saveFile(); } public function deleteFile(): bool { if (parent::deleteFile()) { return $this->deleteSizes(); } return false; } public function saveSizes(): void { $tempImagePath = ''; if (! array_key_exists('file', $this->attributes) && $this->file_key) { // no original file instance set to save sizes from // download image temporarily to generate sizes from $tempImagePath = (string) tempnam(WRITEPATH . 'temp', 'img_'); $imageContent = $this->fileManager->getFileContents($this->file_key); file_put_contents($tempImagePath, $imageContent); $this->attributes['file'] = new File($tempImagePath, true); } // save derived sizes $imageService = Services::image(); foreach ($this->sizes as $name => $size) { $tempFilePath = tempnam(WRITEPATH . 'temp', 'img_'); $imageService ->withFile($this->attributes['file']->getRealPath()) ->resize($size['width'], $size['height']) ->save($tempFilePath); $newImage = new File($tempFilePath, true); $this->fileManager ->save($newImage, $this->{$name . '_key'}); } if ($tempImagePath !== '') { unlink($tempImagePath); } } private function deleteSizes(): bool { // delete all derived sizes foreach (array_keys($this->sizes) as $name) { $pathProperty = $name . '_key'; if (! $this->fileManager->delete($this->{$pathProperty})) { return false; } } return true; } }