Files
Umbraco-CMS/src/Umbraco.Web.BackOffice/Controllers/ImagesController.cs

134 lines
5.1 KiB
C#
Raw Normal View History

using System;
2018-06-29 19:52:40 +02:00
using System.IO;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.IO;
using Umbraco.Cms.Core.Media;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Web.Common.Attributes;
using Umbraco.Extensions;
using Constants = Umbraco.Cms.Core.Constants;
2018-06-29 19:52:40 +02:00
namespace Umbraco.Cms.Web.BackOffice.Controllers
2018-06-29 19:52:40 +02:00
{
/// <summary>
/// A controller used to return images for media
/// </summary>
[PluginController(Constants.Web.Mvc.BackOfficeApiArea)]
2018-06-29 19:52:40 +02:00
public class ImagesController : UmbracoAuthorizedApiController
{
Netcore: File systems rework (#10181) * Allow IMediaFileSystem to be replace in the DI, or registered with inner filesystem * Remove GetFileSystem from Filesystems It was only used by tests. * Make MediaFileSystem inherit from PhysicalFileSystem directly * Remove FileSystemWrapper * Remove inner filesystem from MediaFileSystem * Add MediaFileManager and bare minimum to make it testable * Remove MediaFileSystem * Fix unit tests using MediaFileManager * Remove IFileSystem and rely only on FileSystem * Hide dangerous methods in FileSystems and do some cleaning * Apply stylecop warnings to MediaFileManager * Add FilesystemsCreator to Tests.Common This allows you to create an instance if FileSystems with your own specified IFileSystem for testing purposes outside our own test suite. * Allow the stylesheet filesystem to be replaced. * Fix tests * Don't save stylesheetWrapper in a temporary var * refactor(FileSystems): change how stylesheet filesystem is registered * fix(FileSystems): unable to overwrite media filesystem SetMediaFileSystem added the MediaManager as a Singleton instead of replacing the existing instance. * fix(FileSystems): calling AddFileSystems replaces MediaManager When calling AddFileSystems after SetMediaFileSystem the MediaManager gets replaced by the default PhysicalFileSystem, so instead of calling SetMediaFileSystem in AddFileSystems we now call TrySetMediaFileSystem instead. This method will not replace any existing instance of the MediaManager if there's already a MediaManager registered. * Use SetMediaFileSystem instead of TrySet, and rename AddFilesystems to ConfigureFileSystems Also don't call AddFileSystems again in ConfigureFilesystems * Don't wrap CSS filesystem twice * Add CreateShadowWrapperInternal to avoid casting * Throw UnauthorizedAccessException isntead of InvalidOperationException * Remove ResetShadowId Co-authored-by: Rasmus John Pedersen <mail@rjp.dk>
2021-04-27 09:52:17 +02:00
private readonly MediaFileManager _mediaFileManager;
private readonly IImageUrlGenerator _imageUrlGenerator;
2018-06-29 19:52:40 +02:00
public ImagesController(
Netcore: File systems rework (#10181) * Allow IMediaFileSystem to be replace in the DI, or registered with inner filesystem * Remove GetFileSystem from Filesystems It was only used by tests. * Make MediaFileSystem inherit from PhysicalFileSystem directly * Remove FileSystemWrapper * Remove inner filesystem from MediaFileSystem * Add MediaFileManager and bare minimum to make it testable * Remove MediaFileSystem * Fix unit tests using MediaFileManager * Remove IFileSystem and rely only on FileSystem * Hide dangerous methods in FileSystems and do some cleaning * Apply stylecop warnings to MediaFileManager * Add FilesystemsCreator to Tests.Common This allows you to create an instance if FileSystems with your own specified IFileSystem for testing purposes outside our own test suite. * Allow the stylesheet filesystem to be replaced. * Fix tests * Don't save stylesheetWrapper in a temporary var * refactor(FileSystems): change how stylesheet filesystem is registered * fix(FileSystems): unable to overwrite media filesystem SetMediaFileSystem added the MediaManager as a Singleton instead of replacing the existing instance. * fix(FileSystems): calling AddFileSystems replaces MediaManager When calling AddFileSystems after SetMediaFileSystem the MediaManager gets replaced by the default PhysicalFileSystem, so instead of calling SetMediaFileSystem in AddFileSystems we now call TrySetMediaFileSystem instead. This method will not replace any existing instance of the MediaManager if there's already a MediaManager registered. * Use SetMediaFileSystem instead of TrySet, and rename AddFilesystems to ConfigureFileSystems Also don't call AddFileSystems again in ConfigureFilesystems * Don't wrap CSS filesystem twice * Add CreateShadowWrapperInternal to avoid casting * Throw UnauthorizedAccessException isntead of InvalidOperationException * Remove ResetShadowId Co-authored-by: Rasmus John Pedersen <mail@rjp.dk>
2021-04-27 09:52:17 +02:00
MediaFileManager mediaFileManager,
IImageUrlGenerator imageUrlGenerator)
2018-06-29 19:52:40 +02:00
{
Netcore: File systems rework (#10181) * Allow IMediaFileSystem to be replace in the DI, or registered with inner filesystem * Remove GetFileSystem from Filesystems It was only used by tests. * Make MediaFileSystem inherit from PhysicalFileSystem directly * Remove FileSystemWrapper * Remove inner filesystem from MediaFileSystem * Add MediaFileManager and bare minimum to make it testable * Remove MediaFileSystem * Fix unit tests using MediaFileManager * Remove IFileSystem and rely only on FileSystem * Hide dangerous methods in FileSystems and do some cleaning * Apply stylecop warnings to MediaFileManager * Add FilesystemsCreator to Tests.Common This allows you to create an instance if FileSystems with your own specified IFileSystem for testing purposes outside our own test suite. * Allow the stylesheet filesystem to be replaced. * Fix tests * Don't save stylesheetWrapper in a temporary var * refactor(FileSystems): change how stylesheet filesystem is registered * fix(FileSystems): unable to overwrite media filesystem SetMediaFileSystem added the MediaManager as a Singleton instead of replacing the existing instance. * fix(FileSystems): calling AddFileSystems replaces MediaManager When calling AddFileSystems after SetMediaFileSystem the MediaManager gets replaced by the default PhysicalFileSystem, so instead of calling SetMediaFileSystem in AddFileSystems we now call TrySetMediaFileSystem instead. This method will not replace any existing instance of the MediaManager if there's already a MediaManager registered. * Use SetMediaFileSystem instead of TrySet, and rename AddFilesystems to ConfigureFileSystems Also don't call AddFileSystems again in ConfigureFilesystems * Don't wrap CSS filesystem twice * Add CreateShadowWrapperInternal to avoid casting * Throw UnauthorizedAccessException isntead of InvalidOperationException * Remove ResetShadowId Co-authored-by: Rasmus John Pedersen <mail@rjp.dk>
2021-04-27 09:52:17 +02:00
_mediaFileManager = mediaFileManager;
_imageUrlGenerator = imageUrlGenerator;
2018-06-29 19:52:40 +02:00
}
/// <summary>
/// Gets the big thumbnail image for the original image path
/// </summary>
/// <param name="originalImagePath"></param>
/// <returns></returns>
/// <remarks>
/// If there is no original image is found then this will return not found.
/// </remarks>
public IActionResult GetBigThumbnail(string originalImagePath)
2018-06-29 19:52:40 +02:00
{
return string.IsNullOrWhiteSpace(originalImagePath)
? Ok()
: GetResized(originalImagePath, 500);
2018-06-29 19:52:40 +02:00
}
/// <summary>
/// Gets a resized image for the image at the given path
/// </summary>
/// <param name="imagePath"></param>
/// <param name="width"></param>
/// <returns></returns>
/// <remarks>
/// If there is no media, image property or image file is found then this will return not found.
/// </remarks>
public IActionResult GetResized(string imagePath, int width)
2018-06-29 19:52:40 +02:00
{
var ext = Path.GetExtension(imagePath);
// we need to check if it is an image by extension
if (_imageUrlGenerator.IsSupportedImageFormat(ext) == false)
return NotFound();
2018-06-29 19:52:40 +02:00
//redirect to ImageProcessor thumbnail with rnd generated from last modified time of original media file
DateTimeOffset? imageLastModified = null;
try
{
Netcore: File systems rework (#10181) * Allow IMediaFileSystem to be replace in the DI, or registered with inner filesystem * Remove GetFileSystem from Filesystems It was only used by tests. * Make MediaFileSystem inherit from PhysicalFileSystem directly * Remove FileSystemWrapper * Remove inner filesystem from MediaFileSystem * Add MediaFileManager and bare minimum to make it testable * Remove MediaFileSystem * Fix unit tests using MediaFileManager * Remove IFileSystem and rely only on FileSystem * Hide dangerous methods in FileSystems and do some cleaning * Apply stylecop warnings to MediaFileManager * Add FilesystemsCreator to Tests.Common This allows you to create an instance if FileSystems with your own specified IFileSystem for testing purposes outside our own test suite. * Allow the stylesheet filesystem to be replaced. * Fix tests * Don't save stylesheetWrapper in a temporary var * refactor(FileSystems): change how stylesheet filesystem is registered * fix(FileSystems): unable to overwrite media filesystem SetMediaFileSystem added the MediaManager as a Singleton instead of replacing the existing instance. * fix(FileSystems): calling AddFileSystems replaces MediaManager When calling AddFileSystems after SetMediaFileSystem the MediaManager gets replaced by the default PhysicalFileSystem, so instead of calling SetMediaFileSystem in AddFileSystems we now call TrySetMediaFileSystem instead. This method will not replace any existing instance of the MediaManager if there's already a MediaManager registered. * Use SetMediaFileSystem instead of TrySet, and rename AddFilesystems to ConfigureFileSystems Also don't call AddFileSystems again in ConfigureFilesystems * Don't wrap CSS filesystem twice * Add CreateShadowWrapperInternal to avoid casting * Throw UnauthorizedAccessException isntead of InvalidOperationException * Remove ResetShadowId Co-authored-by: Rasmus John Pedersen <mail@rjp.dk>
2021-04-27 09:52:17 +02:00
imageLastModified = _mediaFileManager.FileSystem.GetLastModified(imagePath);
}
catch (Exception)
{
// if we get an exception here it's probably because the image path being requested is an image that doesn't exist
// in the local media file system. This can happen if someone is storing an absolute path to an image online, which
// is perfectly legal but in that case the media file system isn't going to resolve it.
// so ignore and we won't set a last modified date.
}
var rnd = imageLastModified.HasValue ? $"&rnd={imageLastModified:yyyyMMddHHmmss}" : null;
var imageUrl = _imageUrlGenerator.GetImageUrl(new ImageUrlGenerationOptions(imagePath)
{
Width = width,
ImageCropMode = ImageCropMode.Max,
CacheBusterValue = rnd
});
return new RedirectResult(imageUrl, false);
2018-06-29 19:52:40 +02:00
}
2019-11-05 13:45:42 +01:00
/// <summary>
/// Gets a processed image for the image at the given path
/// </summary>
/// <param name="imagePath"></param>
/// <param name="width"></param>
/// <param name="height"></param>
/// <param name="focalPointLeft"></param>
/// <param name="focalPointTop"></param>
/// <param name="mode"></param>
/// <returns></returns>
/// <remarks>
/// If there is no media, image property or image file is found then this will return not found.
/// </remarks>
public string GetProcessedImageUrl(string imagePath,
int? width = null,
int? height = null,
decimal? focalPointLeft = null,
decimal? focalPointTop = null,
Merge remote-tracking branch 'origin/netcore/dev' into netcore/netcore # Conflicts: # build/NuSpecs/UmbracoCms.Web.nuspec # src/SolutionInfo.cs # src/Umbraco.Infrastructure/Logging/Serilog/LoggerConfigExtensions.cs # src/Umbraco.Infrastructure/PropertyEditors/NestedContentPropertyEditor.cs # src/Umbraco.Tests.AcceptanceTest/cypress/integration/Tour/backofficeTour.ts # src/Umbraco.Tests.AcceptanceTest/package.json # src/Umbraco.Tests/TestHelpers/TestObjects.cs # src/Umbraco.Web.BackOffice/Controllers/ContentTypeController.cs # src/Umbraco.Web.BackOffice/Controllers/ImageUrlGeneratorController.cs # src/Umbraco.Web.BackOffice/Controllers/ImagesController.cs # src/Umbraco.Web.BackOffice/Controllers/MediaController.cs # src/Umbraco.Web.BackOffice/Controllers/MemberTypeController.cs # src/Umbraco.Web.BackOffice/Controllers/RelationTypeController.cs # src/Umbraco.Web.BackOffice/Controllers/TemplateController.cs # src/Umbraco.Web.UI.Client/src/common/services/formhelper.service.js # src/Umbraco.Web.UI.Client/src/installer/steps/database.html # src/Umbraco.Web.UI.Client/src/less/components/tree/umb-tree.less # src/Umbraco.Web.UI.Client/src/less/components/umb-property-actions.less # src/Umbraco.Web.UI.Client/src/less/forms.less # src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/querybuilder/querybuilder.html # src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/treepicker/treepicker.html # src/Umbraco.Web.UI.Client/src/views/components/application/umb-navigation.html # src/Umbraco.Web.UI.Client/src/views/components/property/umb-property-actions.html # src/Umbraco.Web.UI.Client/src/views/content/overlays/publish.controller.js # src/Umbraco.Web.UI.Client/src/views/content/overlays/publishdescendants.html # src/Umbraco.Web.UI.Client/src/views/dictionary/edit.html # src/Umbraco.Web.UI.Client/src/views/dictionary/list.html # src/Umbraco.Web.UI.Client/src/views/logViewer/search.html # src/Umbraco.Web.UI.Client/src/views/media/media.edit.controller.js # src/Umbraco.Web.UI.Client/src/views/mediaTypes/edit.controller.js # src/Umbraco.Web.UI.Client/src/views/member/member.edit.controller.js # src/Umbraco.Web.UI.Client/src/views/memberTypes/edit.controller.js # src/Umbraco.Web.UI.Client/src/views/packages/views/repo.html # src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/dialogs/layoutconfig.html # src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/dialogs/rowconfig.html # src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/layouts.prevalues.html # src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/layouts/list/list.listviewlayout.controller.js # src/Umbraco.Web.UI.Client/src/views/propertyeditors/nestedcontent/nestedcontent.controller.js # src/Umbraco.Web.UI.Client/src/views/propertyeditors/userpicker/userpicker.controller.js # src/Umbraco.Web.UI.NetCore/umbraco/UmbracoBackOffice/Default.cshtml # src/Umbraco.Web.UI.NetCore/umbraco/config/lang/da.xml # src/Umbraco.Web.UI.NetCore/umbraco/config/lang/en.xml # src/Umbraco.Web.UI.NetCore/umbraco/config/lang/en_us.xml # src/Umbraco.Web.UI/Umbraco/config/lang/cs.xml # src/Umbraco.Web.UI/Views/Partials/Grid/Editors/Media.cshtml # src/Umbraco.Web.UI/config/umbracoSettings.config # src/Umbraco.Web/Editors/BackOfficeServerVariables.cs # src/Umbraco.Web/Editors/DictionaryController.cs # src/Umbraco.Web/Editors/LogController.cs # src/Umbraco.Web/Editors/MediaTypeController.cs # src/Umbraco.Web/Editors/MemberGroupController.cs
2020-09-09 19:13:37 +02:00
ImageCropMode mode = ImageCropMode.Max,
string cacheBusterValue = "",
decimal? cropX1 = null,
decimal? cropX2 = null,
decimal? cropY1 = null,
decimal? cropY2 = null
)
{
var options = new ImageUrlGenerationOptions(imagePath)
{
Width = width,
Height = height,
ImageCropMode = mode,
CacheBusterValue = cacheBusterValue
};
if (focalPointLeft.HasValue && focalPointTop.HasValue)
{
options.FocalPoint = new ImageUrlGenerationOptions.FocalPointPosition(focalPointTop.Value, focalPointLeft.Value);
}
else if (cropX1.HasValue && cropX2.HasValue && cropY1.HasValue && cropY2.HasValue)
{
options.Crop = new ImageUrlGenerationOptions.CropCoordinates(cropX1.Value, cropY1.Value, cropX2.Value, cropY2.Value);
}
return _imageUrlGenerator.GetImageUrl(options);
}
2018-06-29 19:52:40 +02:00
}
}