diff --git a/src/Asset/Controller/Document/PreviewStreamController.php b/src/Asset/Controller/Document/PreviewStreamController.php
index 84dcec946..e694fcb85 100644
--- a/src/Asset/Controller/Document/PreviewStreamController.php
+++ b/src/Asset/Controller/Document/PreviewStreamController.php
@@ -33,6 +33,7 @@
use Pimcore\Bundle\StudioBackendBundle\OpenApi\Attribute\Response\SuccessResponse;
use Pimcore\Bundle\StudioBackendBundle\OpenApi\Config\Tags;
use Pimcore\Bundle\StudioBackendBundle\Security\Service\SecurityServiceInterface;
+use Pimcore\Bundle\StudioBackendBundle\Util\Constant\ElementTypes;
use Pimcore\Bundle\StudioBackendBundle\Util\Constant\HttpResponseCodes;
use Pimcore\Bundle\StudioBackendBundle\Util\Constant\UserPermissions;
use Pimcore\Model\Asset\Document;
@@ -97,7 +98,7 @@ public function streamDocumentPreview(int $id): StreamedResponse
);
if (!$asset instanceof Document) {
- throw new InvalidElementTypeException($asset->getType());
+ throw new InvalidElementTypeException($asset->getType(), ElementTypes::TYPE_ASSET);
}
return $this->documentService->getPreviewStream($asset);
diff --git a/src/Asset/Controller/Image/StreamController.php b/src/Asset/Controller/Image/StreamController.php
new file mode 100644
index 000000000..8d5433056
--- /dev/null
+++ b/src/Asset/Controller/Image/StreamController.php
@@ -0,0 +1,98 @@
+value)]
+ #[Get(
+ path: self::PREFIX . '/assets/{id}/image/stream',
+ operationId: 'asset_image_stream',
+ description: 'asset_image_stream_description',
+ summary: 'asset_image_stream_summary',
+ tags: [Tags::Assets->name]
+ )]
+ #[IdParameter(type: 'image')]
+ #[SuccessResponse(
+ description: 'asset_image_stream_success_response',
+ content: [new MediaType('image/*')],
+ headers: [new ContentDisposition(HttpResponseHeaders::INLINE_TYPE->value)]
+ )]
+ #[DefaultResponses([
+ HttpResponseCodes::BAD_REQUEST,
+ HttpResponseCodes::UNAUTHORIZED,
+ HttpResponseCodes::NOT_FOUND,
+ ])]
+ public function streamOriginalImage(
+ int $id,
+ ): StreamedResponse {
+ $asset = $this->assetService->getAssetElement(
+ $this->securityService->getCurrentUser(),
+ $id
+ );
+
+ return $this->binaryService->streamImage($asset);
+ }
+}
diff --git a/src/Asset/Encoder/TextEncoder.php b/src/Asset/Encoder/TextEncoder.php
index dfb8289dc..d6207a9cc 100644
--- a/src/Asset/Encoder/TextEncoder.php
+++ b/src/Asset/Encoder/TextEncoder.php
@@ -21,6 +21,7 @@
use Pimcore\Bundle\StudioBackendBundle\Exception\Api\MaxFileSizeExceededException;
use Pimcore\Model\Asset\Text;
use Pimcore\Model\Element\ElementInterface;
+use function sprintf;
final class TextEncoder implements TextEncoderInterface
{
@@ -32,7 +33,14 @@ final class TextEncoder implements TextEncoderInterface
public function encodeUTF8(ElementInterface $element): string
{
if (!$element instanceof Text) {
- throw new InvalidElementTypeException('Element must be an instance of Text');
+ throw new InvalidElementTypeException(
+ sprintf(
+ 'should have been (%s) but was (%s)',
+ Text::class,
+ $element->getType(),
+ ),
+ 'Asset'
+ );
}
if ($element->getFileSize() > self::MAX_FILE_SIZE) {
diff --git a/src/Asset/Service/BinaryService.php b/src/Asset/Service/BinaryService.php
index 333bc55d2..a6502847d 100644
--- a/src/Asset/Service/BinaryService.php
+++ b/src/Asset/Service/BinaryService.php
@@ -25,6 +25,7 @@
use Pimcore\Bundle\StudioBackendBundle\Exception\Api\InvalidElementTypeException;
use Pimcore\Bundle\StudioBackendBundle\Exception\Api\InvalidThumbnailConfigurationException;
use Pimcore\Bundle\StudioBackendBundle\Exception\Api\InvalidThumbnailException;
+use Pimcore\Bundle\StudioBackendBundle\Util\Constant\ElementTypes;
use Pimcore\Bundle\StudioBackendBundle\Util\Constant\HttpResponseHeaders;
use Pimcore\Bundle\StudioBackendBundle\Util\Trait\StreamedResponseTrait;
use Pimcore\Messenger\AssetPreviewImageMessage;
@@ -59,19 +60,32 @@ public function downloadVideoByThumbnail(
string $thumbnailName
): StreamedResponse {
if (!$video instanceof Video) {
- throw new InvalidElementTypeException($video->getType());
+ throw new InvalidElementTypeException($video->getType(), ElementTypes::TYPE_ASSET);
}
return $this->getVideoByThumbnail($video, $thumbnailName, HttpResponseHeaders::ATTACHMENT_TYPE->value);
}
+ /**
+ * @throws ElementStreamResourceNotFoundException|InvalidElementTypeException
+ */
+ public function streamImage(
+ Asset $image
+ ): StreamedResponse {
+ if (!$image instanceof Image) {
+ throw new InvalidElementTypeException($image->getType(), ElementTypes::TYPE_ASSET);
+ }
+
+ return $this->getStreamedResponse($image, HttpResponseHeaders::INLINE_TYPE->value);
+ }
+
/**
* @throws InvalidElementTypeException|InvalidThumbnailException
*/
public function streamPreviewImageThumbnail(Asset $image): StreamedResponse
{
if (!$image instanceof Image) {
- throw new InvalidElementTypeException($image->getType());
+ throw new InvalidElementTypeException($image->getType(), ElementTypes::TYPE_ASSET);
}
return $this->getStreamedResponse(
@@ -85,7 +99,7 @@ public function streamImageThumbnailFromConfig(
ImageDownloadConfigParameter $configParameter
): StreamedResponse {
if (!$image instanceof Image) {
- throw new InvalidElementTypeException($image->getType());
+ throw new InvalidElementTypeException($image->getType(), ElementTypes::TYPE_ASSET);
}
return $this->getStreamedResponse(
@@ -105,7 +119,7 @@ public function streamVideoByThumbnail(
string $thumbnailName
): StreamedResponse {
if (!$video instanceof Video) {
- throw new InvalidElementTypeException($video->getType());
+ throw new InvalidElementTypeException($video->getType(), ElementTypes::TYPE_ASSET);
}
return $this->getVideoByThumbnail($video, $thumbnailName, HttpResponseHeaders::INLINE_TYPE->value);
@@ -122,7 +136,7 @@ public function streamVideoImageThumbnail(
VideoImageStreamConfigParameter $imageConfig
): StreamedResponse {
if (!$video instanceof Video) {
- throw new InvalidElementTypeException($video->getType());
+ throw new InvalidElementTypeException($video->getType(), ElementTypes::TYPE_ASSET);
}
$this->thumbnailService->validateCustomVideoThumbnailConfig($imageConfig);
diff --git a/src/Asset/Service/BinaryServiceInterface.php b/src/Asset/Service/BinaryServiceInterface.php
index c3143f88b..0e613a0e0 100644
--- a/src/Asset/Service/BinaryServiceInterface.php
+++ b/src/Asset/Service/BinaryServiceInterface.php
@@ -43,6 +43,13 @@ public function downloadVideoByThumbnail(
string $thumbnailName
): StreamedResponse;
+ /**
+ * @throws ElementStreamResourceNotFoundException|InvalidElementTypeException
+ */
+ public function streamImage(
+ Asset $image
+ ): StreamedResponse;
+
/**
* @throws InvalidElementTypeException|InvalidThumbnailException
*/
diff --git a/src/Dependency/Controller/Element/CollectionController.php b/src/Dependency/Controller/Element/CollectionController.php
index 3dc663377..923bce800 100644
--- a/src/Dependency/Controller/Element/CollectionController.php
+++ b/src/Dependency/Controller/Element/CollectionController.php
@@ -68,7 +68,7 @@ public function __construct(
tags: [Tags::Dependencies->name]
)]
#[ElementTypeParameter]
- #[IdParameter('element')]
+ #[IdParameter]
#[PageParameter]
#[PageSizeParameter]
#[DependencyModeParameter]
diff --git a/src/Exception/Api/ElementProcessingNotCompletedException.php b/src/Exception/Api/ElementProcessingNotCompletedException.php
index 661db7551..d558a0a96 100644
--- a/src/Exception/Api/ElementProcessingNotCompletedException.php
+++ b/src/Exception/Api/ElementProcessingNotCompletedException.php
@@ -16,6 +16,7 @@
namespace Pimcore\Bundle\StudioBackendBundle\Exception\Api;
+use Pimcore\Bundle\StudioBackendBundle\Util\Constant\ElementTypes;
use Pimcore\Bundle\StudioBackendBundle\Util\Constant\HttpResponseCodes;
use function sprintf;
@@ -24,7 +25,7 @@
*/
final class ElementProcessingNotCompletedException extends AbstractApiException
{
- public function __construct(int $id, string $type = 'Element')
+ public function __construct(int $id, string $type = ElementTypes::TYPE_ELEMENT)
{
parent::__construct(
HttpResponseCodes::NOT_COMPLETED->value,
diff --git a/src/Exception/Api/ElementStreamResourceNotFoundException.php b/src/Exception/Api/ElementStreamResourceNotFoundException.php
index 7597939bb..df20976ab 100644
--- a/src/Exception/Api/ElementStreamResourceNotFoundException.php
+++ b/src/Exception/Api/ElementStreamResourceNotFoundException.php
@@ -16,6 +16,7 @@
namespace Pimcore\Bundle\StudioBackendBundle\Exception\Api;
+use Pimcore\Bundle\StudioBackendBundle\Util\Constant\ElementTypes;
use Pimcore\Bundle\StudioBackendBundle\Util\Constant\HttpResponseCodes;
use function sprintf;
@@ -24,7 +25,7 @@
*/
final class ElementStreamResourceNotFoundException extends AbstractApiException
{
- public function __construct(int $id, string $type = 'Element')
+ public function __construct(int $id, string $type = ElementTypes::TYPE_ELEMENT)
{
parent::__construct(
HttpResponseCodes::NOT_FOUND->value,
diff --git a/src/Exception/Api/InvalidElementTypeException.php b/src/Exception/Api/InvalidElementTypeException.php
index 0e400b34d..3b5d4caeb 100644
--- a/src/Exception/Api/InvalidElementTypeException.php
+++ b/src/Exception/Api/InvalidElementTypeException.php
@@ -16,6 +16,7 @@
namespace Pimcore\Bundle\StudioBackendBundle\Exception\Api;
+use Pimcore\Bundle\StudioBackendBundle\Util\Constant\ElementTypes;
use Pimcore\Bundle\StudioBackendBundle\Util\Constant\HttpResponseCodes;
use function sprintf;
@@ -24,13 +25,14 @@
*/
final class InvalidElementTypeException extends AbstractApiException
{
- public function __construct(string $type)
+ public function __construct(string $subType, string $elementType = ElementTypes::TYPE_ELEMENT)
{
parent::__construct(
HttpResponseCodes::BAD_REQUEST->value,
sprintf(
- 'Invalid element type: %s',
- $type
+ 'Invalid %s type: %s',
+ $elementType,
+ $subType
)
);
}
diff --git a/src/Note/Controller/Element/CollectionController.php b/src/Note/Controller/Element/CollectionController.php
index e8d23bc37..d6fe2f534 100644
--- a/src/Note/Controller/Element/CollectionController.php
+++ b/src/Note/Controller/Element/CollectionController.php
@@ -36,6 +36,7 @@
use Pimcore\Bundle\StudioBackendBundle\OpenApi\Attribute\Response\DefaultResponses;
use Pimcore\Bundle\StudioBackendBundle\OpenApi\Attribute\Response\SuccessResponse;
use Pimcore\Bundle\StudioBackendBundle\OpenApi\Config\Tags;
+use Pimcore\Bundle\StudioBackendBundle\Util\Constant\ElementTypes;
use Pimcore\Bundle\StudioBackendBundle\Util\Constant\HttpResponseCodes;
use Pimcore\Bundle\StudioBackendBundle\Util\Constant\UserPermissions;
use Pimcore\Bundle\StudioBackendBundle\Util\Trait\PaginatedResponseTrait;
@@ -78,7 +79,7 @@ public function __construct(
tags: [Tags::Notes->name]
)]
#[ElementTypeParameter]
- #[IdParameter(type: 'element')]
+ #[IdParameter(type: ElementTypes::TYPE_ELEMENT)]
#[PageParameter]
#[PageSizeParameter(50)]
#[NoteSortByParameter]
diff --git a/src/Note/Controller/Element/CreateController.php b/src/Note/Controller/Element/CreateController.php
index 6bf8fdd77..08abc5dda 100644
--- a/src/Note/Controller/Element/CreateController.php
+++ b/src/Note/Controller/Element/CreateController.php
@@ -32,6 +32,7 @@
use Pimcore\Bundle\StudioBackendBundle\OpenApi\Attribute\Response\DefaultResponses;
use Pimcore\Bundle\StudioBackendBundle\OpenApi\Attribute\Response\SuccessResponse;
use Pimcore\Bundle\StudioBackendBundle\OpenApi\Config\Tags;
+use Pimcore\Bundle\StudioBackendBundle\Util\Constant\ElementTypes;
use Pimcore\Bundle\StudioBackendBundle\Util\Constant\HttpResponseCodes;
use Pimcore\Bundle\StudioBackendBundle\Util\Constant\UserPermissions;
use Symfony\Component\HttpFoundation\JsonResponse;
@@ -66,7 +67,7 @@ public function __construct(
tags: [Tags::Notes->name]
)]
#[ElementTypeParameter]
- #[IdParameter(type: 'element')]
+ #[IdParameter(type: ElementTypes::TYPE_ELEMENT)]
#[CreateNoteRequestBody]
#[SuccessResponse(
description: 'note_element_create_success_response',
diff --git a/src/Property/Controller/Element/CollectionController.php b/src/Property/Controller/Element/CollectionController.php
index fe6348950..a3646bbe7 100644
--- a/src/Property/Controller/Element/CollectionController.php
+++ b/src/Property/Controller/Element/CollectionController.php
@@ -61,7 +61,7 @@ public function __construct(
tags: [Tags::Properties->value]
)]
#[ElementTypeParameter]
- #[IdParameter(type: 'element')]
+ #[IdParameter]
#[SuccessResponse(
description: 'property_get_collection_for_element_by_type_and_id_success_response',
content: new ItemsJson(ElementProperty::class)
diff --git a/src/Schedule/Controller/Element/CollectionController.php b/src/Schedule/Controller/Element/CollectionController.php
index 245ccbd80..3b6787446 100644
--- a/src/Schedule/Controller/Element/CollectionController.php
+++ b/src/Schedule/Controller/Element/CollectionController.php
@@ -59,7 +59,7 @@ public function __construct(
tags: [Tags::Schedule->name]
)]
#[ElementTypeParameter]
- #[IdParameter(type: 'element')]
+ #[IdParameter]
#[SuccessResponse(
description: 'schedule_get_collection_for_element_by_type_and_id_success_response',
content: new ItemsJson(Schedule::class)
diff --git a/src/Schedule/Controller/Element/CreateController.php b/src/Schedule/Controller/Element/CreateController.php
index 683966860..e1c79c1fd 100644
--- a/src/Schedule/Controller/Element/CreateController.php
+++ b/src/Schedule/Controller/Element/CreateController.php
@@ -61,7 +61,7 @@ public function __construct(
tags: [Tags::Schedule->name]
)]
#[ElementTypeParameter]
- #[IdParameter(type: 'element')]
+ #[IdParameter]
#[SuccessResponse(
description: 'schedule_create_for_element_by_type_and_id_success_response',
content: new JsonContent(ref: Schedule::class)
diff --git a/src/Schedule/Controller/Element/UpdateController.php b/src/Schedule/Controller/Element/UpdateController.php
index 0747ae215..b3a1e660c 100644
--- a/src/Schedule/Controller/Element/UpdateController.php
+++ b/src/Schedule/Controller/Element/UpdateController.php
@@ -66,7 +66,7 @@ public function __construct(
tags: [Tags::Schedule->name]
)]
#[ElementTypeParameter]
- #[IdParameter(type: 'element')]
+ #[IdParameter]
#[ElementScheduleRequestBody]
#[SuccessResponse(
description: 'schedule_update_for_element_by_type_and_id_success_response',
diff --git a/src/Tag/Controller/Element/AssignController.php b/src/Tag/Controller/Element/AssignController.php
index 53b3d9d2f..8ad250ae4 100644
--- a/src/Tag/Controller/Element/AssignController.php
+++ b/src/Tag/Controller/Element/AssignController.php
@@ -62,7 +62,7 @@ public function __construct(
tags: [Tags::TagsForElement->value]
)]
#[ElementTypeParameter]
- #[IdParameter(type: 'element')]
+ #[IdParameter]
#[IdParameter(type: 'tag', name: 'tagId')]
#[DefaultResponses([
HttpResponseCodes::UNAUTHORIZED,
diff --git a/src/Tag/Controller/Element/CollectionController.php b/src/Tag/Controller/Element/CollectionController.php
index a2bd6d665..c6c6f788b 100644
--- a/src/Tag/Controller/Element/CollectionController.php
+++ b/src/Tag/Controller/Element/CollectionController.php
@@ -60,7 +60,7 @@ public function __construct(
tags: [Tags::TagsForElement->value]
)]
#[ElementTypeParameter]
- #[IdParameter(type: 'element')]
+ #[IdParameter]
#[SuccessResponse(
description: 'tag_get_collection_for_element_by_type_and_id_success_response',
content: new CollectionJson(new TagCollection())
diff --git a/src/Tag/Controller/Element/UnassignController.php b/src/Tag/Controller/Element/UnassignController.php
index 71a235fd6..9316ba75e 100644
--- a/src/Tag/Controller/Element/UnassignController.php
+++ b/src/Tag/Controller/Element/UnassignController.php
@@ -58,7 +58,7 @@ public function __construct(
tags: [Tags::TagsForElement->value]
)]
#[ElementTypeParameter]
- #[IdParameter(type: 'element')]
+ #[IdParameter]
#[IdParameter(type: 'tag', name: 'tagId')]
#[DefaultResponses([
HttpResponseCodes::UNAUTHORIZED,
diff --git a/src/Util/Constant/ElementTypes.php b/src/Util/Constant/ElementTypes.php
index 037cec8b9..39824abd3 100644
--- a/src/Util/Constant/ElementTypes.php
+++ b/src/Util/Constant/ElementTypes.php
@@ -27,6 +27,8 @@
public const TYPE_DATA_OBJECT = 'data-object';
+ public const TYPE_ELEMENT = 'element';
+
public const TYPE_OBJECT = 'object';
public const TYPE_VARIANT = 'variant';
diff --git a/src/Version/Controller/Element/CollectionController.php b/src/Version/Controller/Element/CollectionController.php
index e7b610b55..9fa37ec37 100644
--- a/src/Version/Controller/Element/CollectionController.php
+++ b/src/Version/Controller/Element/CollectionController.php
@@ -71,7 +71,7 @@ public function __construct(
tags: [Tags::Versions->name]
)]
#[ElementTypeParameter]
- #[IdParameter('element')]
+ #[IdParameter]
#[PageParameter]
#[PageSizeParameter]
#[SuccessResponse(
diff --git a/translations/studio_api_docs.en.yaml b/translations/studio_api_docs.en.yaml
index d5b3379f7..c51202cfe 100644
--- a/translations/studio_api_docs.en.yaml
+++ b/translations/studio_api_docs.en.yaml
@@ -120,11 +120,16 @@ asset_image_download_custom_description: |
The {id} must be an ID of existing asset image
asset_image_download_custom_success_response: Custom image binary file
asset_image_download_custom_summary: Download custom image by ID and configuration
-asset_image_stream_custom_summary: Stream custom image thumbnail by ID and configuration
+asset_image_stream_description: |
+ Stream original image asset based on the provided {id}.
+ The {id} must be an ID of existing asset image
+asset_image_stream_success_response: Stream of an original image asset
+asset_image_stream_summary: Stream original image asset by ID
asset_image_stream_custom_description: |
Stream image asset thumbnail based on the provided {id} and configuration parameters.
The {id} must be an ID of existing asset image
asset_image_stream_custom_success_response: Image asset stream based on custom thumbnail configuration
+asset_image_stream_custom_summary: Stream custom image thumbnail by ID and configuration
asset_image_stream_preview_description: |
Stream image asset preview based on the provided {id}.
The {id} must be an ID of existing asset image