* 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>
154 lines
4.9 KiB
C#
154 lines
4.9 KiB
C#
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using Umbraco.Cms.Core.IO;
|
|
using Umbraco.Cms.Core.Models;
|
|
using Umbraco.Cms.Core.Persistence.Repositories;
|
|
using Umbraco.Extensions;
|
|
|
|
namespace Umbraco.Cms.Infrastructure.Persistence.Repositories.Implement
|
|
{
|
|
internal class PartialViewRepository : FileRepository<string, IPartialView>, IPartialViewRepository
|
|
{
|
|
private readonly IIOHelper _ioHelper;
|
|
|
|
public PartialViewRepository(FileSystems fileSystems, IIOHelper ioHelper)
|
|
: base(fileSystems.PartialViewsFileSystem)
|
|
{
|
|
_ioHelper = ioHelper;
|
|
}
|
|
|
|
protected PartialViewRepository(IFileSystem fileSystem, IIOHelper ioHelper)
|
|
: base(fileSystem)
|
|
{
|
|
_ioHelper = ioHelper;
|
|
}
|
|
|
|
protected virtual PartialViewType ViewType => PartialViewType.PartialView;
|
|
|
|
public override IPartialView Get(string id)
|
|
{
|
|
// get the relative path within the filesystem
|
|
// (though... id should be relative already)
|
|
var path = FileSystem.GetRelativePath(id);
|
|
|
|
if (FileSystem.FileExists(path) == false)
|
|
return null;
|
|
|
|
// content will be lazy-loaded when required
|
|
var created = FileSystem.GetCreated(path).UtcDateTime;
|
|
var updated = FileSystem.GetLastModified(path).UtcDateTime;
|
|
//var content = GetFileContent(path);
|
|
|
|
var view = new PartialView(ViewType, path, file => GetFileContent(file.OriginalPath))
|
|
{
|
|
//id can be the hash
|
|
Id = path.GetHashCode(),
|
|
Key = path.EncodeAsGuid(),
|
|
//Content = content,
|
|
CreateDate = created,
|
|
UpdateDate = updated,
|
|
VirtualPath = FileSystem.GetUrl(id)
|
|
};
|
|
|
|
// reset dirty initial properties (U4-1946)
|
|
view.ResetDirtyProperties(false);
|
|
|
|
return view;
|
|
}
|
|
|
|
public override void Save(IPartialView entity)
|
|
{
|
|
var partialView = entity as PartialView;
|
|
if (partialView != null)
|
|
partialView.ViewType = ViewType;
|
|
|
|
base.Save(entity);
|
|
|
|
// ensure that from now on, content is lazy-loaded
|
|
if (partialView != null && partialView.GetFileContent == null)
|
|
partialView.GetFileContent = file => GetFileContent(file.OriginalPath);
|
|
}
|
|
|
|
public override IEnumerable<IPartialView> GetMany(params string[] ids)
|
|
{
|
|
//ensure they are de-duplicated, easy win if people don't do this as this can cause many excess queries
|
|
ids = ids.Distinct().ToArray();
|
|
|
|
if (ids.Any())
|
|
{
|
|
foreach (var id in ids)
|
|
{
|
|
yield return Get(id);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
var files = FindAllFiles("", "*.*");
|
|
foreach (var file in files)
|
|
{
|
|
yield return Get(file);
|
|
}
|
|
}
|
|
}
|
|
|
|
private static readonly List<string> ValidExtensions = new List<string> { "cshtml" };
|
|
|
|
public virtual bool ValidatePartialView(IPartialView partialView)
|
|
{
|
|
// get full path
|
|
string fullPath;
|
|
try
|
|
{
|
|
// may throw for security reasons
|
|
fullPath = FileSystem.GetFullPath(partialView.Path);
|
|
}
|
|
catch
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// validate path & extension
|
|
var validDir = Cms.Core.Constants.SystemDirectories.MvcViews;
|
|
var isValidPath = _ioHelper.VerifyEditPath(fullPath, validDir);
|
|
var isValidExtension = _ioHelper.VerifyFileExtension(fullPath, ValidExtensions);
|
|
return isValidPath && isValidExtension;
|
|
}
|
|
|
|
public Stream GetFileContentStream(string filepath)
|
|
{
|
|
if (FileSystem.FileExists(filepath) == false) return null;
|
|
|
|
try
|
|
{
|
|
return FileSystem.OpenFile(filepath);
|
|
}
|
|
catch
|
|
{
|
|
return null; // deal with race conds
|
|
}
|
|
}
|
|
|
|
public void SetFileContent(string filepath, Stream content)
|
|
{
|
|
FileSystem.AddFile(filepath, content, true);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets a stream that is used to write to the file
|
|
/// </summary>
|
|
/// <param name="content"></param>
|
|
/// <returns></returns>
|
|
/// <remarks>
|
|
/// This ensures the stream includes a utf8 BOM
|
|
/// </remarks>
|
|
protected override Stream GetContentStream(string content)
|
|
{
|
|
var data = Encoding.UTF8.GetBytes(content);
|
|
var withBom = Encoding.UTF8.GetPreamble().Concat(data).ToArray();
|
|
return new MemoryStream(withBom);
|
|
}
|
|
}
|
|
}
|