From c531342006d41242cfcb6a1a298229311e495312 Mon Sep 17 00:00:00 2001 From: Ivan Herak Date: Wed, 4 Sep 2019 09:44:52 +0000 Subject: [PATCH 1/2] Keep extension of uploaded file --- .../Cloudinary/CloudinaryProvider.php | 76 +++++++++++++++ RemoteMedia/RemoteMediaProvider.php | 13 +++ RemoteMedia/UploadFile.php | 96 +++++++++++++++++++ .../modules/ngremotemedia/simple_upload.php | 8 +- .../modules/ngremotemedia/upload.php | 5 +- 5 files changed, 193 insertions(+), 5 deletions(-) create mode 100644 RemoteMedia/UploadFile.php diff --git a/RemoteMedia/Provider/Cloudinary/CloudinaryProvider.php b/RemoteMedia/Provider/Cloudinary/CloudinaryProvider.php index 7b579ab6..a012bf0d 100644 --- a/RemoteMedia/Provider/Cloudinary/CloudinaryProvider.php +++ b/RemoteMedia/Provider/Cloudinary/CloudinaryProvider.php @@ -4,6 +4,7 @@ use Netgen\Bundle\RemoteMediaBundle\Exception\MimeCategoryParseException; use Netgen\Bundle\RemoteMediaBundle\RemoteMedia\Transformation\Registry; +use Netgen\Bundle\RemoteMediaBundle\RemoteMedia\UploadFile; use Netgen\Bundle\RemoteMediaBundle\RemoteMedia\VariationResolver; use Netgen\Bundle\RemoteMediaBundle\Core\FieldType\RemoteMedia\Value; use Netgen\Bundle\RemoteMediaBundle\Exception\TransformationHandlerFailedException; @@ -78,6 +79,27 @@ private function appendExtension($publicId, $fileUri) return $publicId; } + /** + * @param $publicId + * @param UploadFile $uploadFile + * + * @return string + */ + private function appendExtensionFromUploadFile($publicId, UploadFile $uploadFile) + { + $extension = $uploadFile->originalExtension(); + if (empty($extension)) { + return $publicId; + } + $file = new File($uploadFile->uri()); + $mimeCategory = $this->parseMimeCategory($file); + // cloudinary handles pdf in a weird way - it is considered an "image" but it delivers it with proper extension on download + if ($extension !== 'pdf' && !in_array($mimeCategory, $this->noExtensionMimeTypes)) { + $publicId .= '.' . $extension; + } + return $publicId; + } + /** * Prepares upload options for Cloudinary. * Every image with the same name will be overwritten. @@ -121,6 +143,9 @@ protected function prepareUploadOptions($fileName, $fileUri, $options = array()) } /** + * @deprecated this method will have a different signature in 2.0 + * @see \Netgen\Bundle\RemoteMediaBundle\RemoteMedia\Provider\Cloudinary\CloudinaryProvider::uploadWithExtension + * * Uploads the local resource to remote storage and builds the Value from the response. * * @param string $fileUri @@ -138,6 +163,57 @@ public function upload($fileUri, $fileName, $options = array()) return Value::createFromCloudinaryResponse($response); } + /** + * Prepares upload options for Cloudinary. + * Every image with the same name will be overwritten. + * + * @param UploadFile $uploadFile + * @param array $options + * + * @return array + */ + protected function prepareUploadOptionsWithExtension(UploadFile $uploadFile, $options = array()) + { + $clean = preg_replace("/[^\p{L}|\p{N}]+/u", '_', $uploadFile->originalFilename()); + $cleanFileName = preg_replace("/[\p{Z}]{2,}/u", '_', $clean); + $fileName = rtrim($cleanFileName, '_'); + // check if overwrite is set, if it is, do not append random string + $overwrite = isset($options['overwrite']) ? $options['overwrite'] : false; + $invalidate = isset($options['invalidate']) ? $options['invalidate'] : $overwrite; + $publicId = $overwrite ? $fileName : $fileName . '_' . base_convert(uniqid(), 16, 36); + $publicId = $this->appendExtensionFromUploadFile($publicId, $uploadFile); + if (!empty($options['folder'])) { + $publicId = $options['folder'].'/'.$publicId; + } + return array( + 'public_id' => $publicId, + 'overwrite' => $overwrite, + 'invalidate' => $invalidate, + 'discard_original_filename' => + isset($options['discard_original_filename']) ? $options['discard_original_filename'] : true, + 'context' => array( + 'alt' => !empty($options['alt_text']) ? $options['alt_text'] : '', + 'caption' => !empty($options['caption']) ? $options['caption'] : '', + ), + 'resource_type' => !empty($options['resource_type']) ? $options['resource_type'] : 'auto' + ); + } + + /** + * Uploads the local resource to remote storage and builds the Value from the response. + * + * @param UploadFile $uploadFile + * @param array $options + * + * @return Value + */ + public function uploadWithExtension(UploadFile $uploadFile, $options = array()) + { + $options = $this->prepareUploadOptionsWithExtension($uploadFile, $options); + $response = $this->gateway->upload($uploadFile->uri(), $options); + return Value::createFromCloudinaryResponse($response); + } + /** * Builds transformation options for the provider to consume. * diff --git a/RemoteMedia/RemoteMediaProvider.php b/RemoteMedia/RemoteMediaProvider.php index 23e29ca3..01b68cd3 100644 --- a/RemoteMedia/RemoteMediaProvider.php +++ b/RemoteMedia/RemoteMediaProvider.php @@ -51,6 +51,9 @@ abstract public function supportsContentBrowser(); abstract public function supportsFolders(); /** + * @deprecated this method will have a different signature in 2.0 + * @see \Netgen\Bundle\RemoteMediaBundle\RemoteMedia\RemoteMediaProvider::uploadWithExtension + * * Uploads the local resource to remote storage and builds the Value from the response. * * @param string $fileUri @@ -61,6 +64,16 @@ abstract public function supportsFolders(); */ abstract public function upload($fileUri, $fileName, $options = array()); + /** + * Uploads the local resource to remote storage and builds the Value from the response. + * + * @param \Netgen\Bundle\RemoteMediaBundle\RemoteMedia\UploadFile $uploadFile + * @param array $options + * + * @return mixed + */ + abstract public function uploadWithExtension(UploadFile $uploadFile, $options = array()); + /** * Gets the remote media Variation. * If the remote media does not support variations, this method should return the Variation diff --git a/RemoteMedia/UploadFile.php b/RemoteMedia/UploadFile.php new file mode 100644 index 00000000..bc99b7e1 --- /dev/null +++ b/RemoteMedia/UploadFile.php @@ -0,0 +1,96 @@ +uri = $uri; + $uploadFile->originalFilename = pathinfo($uri, PATHINFO_FILENAME); + $uploadFile->originalExtension = pathinfo($uri, PATHINFO_EXTENSION); + + return $uploadFile; + } + + /** + * Constructs UploadFile from given eZHTTPFile (usually uploaded through the legacy admin). + * + * @param eZHTTPFile $file + * + * @return UploadFile + */ + public static function fromZHTTPFile(eZHTTPFile $file) + { + $uploadFile = new UploadFile; + + $uploadFile->uri = $file->Filename; + $uploadFile->originalFilename = pathinfo($file->OriginalFilename, PATHINFO_FILENAME); + $uploadFile->originalExtension = pathinfo($file->OriginalFilename, PATHINFO_EXTENSION); + + return $uploadFile; + } + + /** + * Constructs UploadFile from given eZImage field Value. + * + * @param Value $value + * @param $webRoot + * + * @return UploadFile + */ + public static function fromEzImageValue(Value $value, $webRoot) + { + $uploadFile = new UploadFile; + + $uploadFile->uri = $webRoot.$value->uri; + $uploadFile->originalFilename = pathinfo($value->fileName, PATHINFO_FILENAME); + $uploadFile->originalExtension = pathinfo($value->fileName, PATHINFO_EXTENSION); + + return $uploadFile; + } + + /** + * @return string + */ + public function uri() + { + return $this->uri; + } + + /** + * @return string + */ + public function originalFilename() + { + return $this->originalFilename; + } + + /** + * @return string + */ + public function originalExtension() + { + return $this->originalExtension; + } +} diff --git a/ezpublish_legacy/ngremotemedia/modules/ngremotemedia/simple_upload.php b/ezpublish_legacy/ngremotemedia/modules/ngremotemedia/simple_upload.php index c163697c..56b7fd1c 100644 --- a/ezpublish_legacy/ngremotemedia/modules/ngremotemedia/simple_upload.php +++ b/ezpublish_legacy/ngremotemedia/modules/ngremotemedia/simple_upload.php @@ -1,5 +1,7 @@ getServiceContainer(); $provider = $container->get( 'netgen_remote_media.provider' ); -$value = $provider->upload( - $file->Filename, - pathinfo($file->OriginalFilename, PATHINFO_FILENAME) -); +$uploadFile = UploadFile::fromZHTTPFile($file); +$value = $provider->uploadWithExtension($uploadFile); $responseData = array( 'media' => !empty($value->resourceId) ? $value : false, diff --git a/ezpublish_legacy/ngremotemedia/modules/ngremotemedia/upload.php b/ezpublish_legacy/ngremotemedia/modules/ngremotemedia/upload.php index 333838af..13b3640c 100644 --- a/ezpublish_legacy/ngremotemedia/modules/ngremotemedia/upload.php +++ b/ezpublish_legacy/ngremotemedia/modules/ngremotemedia/upload.php @@ -1,5 +1,7 @@ upload($file->Filename, pathinfo($file->OriginalFilename, PATHINFO_FILENAME), $options); +$uploadFile = UploadFile::fromZHTTPFile($file); +$value = $provider->uploadWithExtension($uploadFile, $options); $attribute = eZContentObjectAttribute::fetch($fieldId, $contentVersionId); $attribute->setAttribute('data_text', json_encode($value)); From 528725df5cc5ff1b83f2f848d029604b66ac0740 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edi=20Modri=C4=87?= Date: Wed, 16 Oct 2019 11:28:49 +0200 Subject: [PATCH 2/2] Fix deprecated package name in composer.json --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index bc34415b..11dcffcb 100644 --- a/composer.json +++ b/composer.json @@ -29,7 +29,7 @@ "netgen/admin-ui-bundle": "^2.0", "matthiasnoback/symfony-config-test": "^2.0", "matthiasnoback/symfony-dependency-injection-test": "^1.0", - "mikey179/vfsStream": "^1.0", + "mikey179/vfsstream": "^1.0", "phpunit/phpunit": "^5.7", "friendsofphp/php-cs-fixer": "^2.0" },