using System.Text.RegularExpressions; using Microsoft.AspNetCore.Http; using Nop.Core; using Nop.Core.Infrastructure; namespace Nop.Services.Media.RoxyFileman; public partial class RoxyFilemanService : IRoxyFilemanService { #region Fields protected readonly IRoxyFilemanFileProvider _fileProvider; protected readonly IWorkContext _workContext; #endregion #region Ctor public RoxyFilemanService( IRoxyFilemanFileProvider fileProvider, IWorkContext workContext) { _fileProvider = fileProvider; _workContext = workContext; } #endregion #region Utilities /// /// Check whether there are any restrictions on handling the file /// /// Path to the file /// /// The result contains true if the file can be handled; otherwise false /// protected virtual bool CanHandleFile(string path) { var result = false; var fileExtension = Path.GetExtension(path).Replace(".", string.Empty).ToLowerInvariant(); var roxyConfig = Singleton.Instance; var forbiddenUploads = roxyConfig.FORBIDDEN_UPLOADS.Trim().ToLowerInvariant(); if (!string.IsNullOrEmpty(forbiddenUploads)) result = !WhiteSpaceRegex().Split(forbiddenUploads).Contains(fileExtension); var allowedUploads = roxyConfig.ALLOWED_UPLOADS.Trim().ToLowerInvariant(); if (string.IsNullOrEmpty(allowedUploads)) return result; return WhiteSpaceRegex().Split(allowedUploads).Contains(fileExtension); } [GeneratedRegex("\\s+")] private static partial Regex WhiteSpaceRegex(); #endregion #region Configuration /// /// Initial service configuration /// /// The base path for the current request /// A task that represents the asynchronous operation public async Task ConfigureAsync(string pathBase) { var currentLanguage = await _workContext.GetWorkingLanguageAsync(); await _fileProvider.GetOrCreateConfigurationAsync(pathBase, currentLanguage.UniqueSeoCode); } #endregion #region Directories /// /// Delete the directory /// /// Path to the directory public void DeleteDirectory(string path) { _fileProvider.DeleteDirectory(path); } /// /// Download the directory from the server as a zip archive /// /// Path to the directory public byte[] DownloadDirectory(string path) { return _fileProvider.CreateZipArchiveFromDirectory(path); } /// /// Copy the directory /// /// Path to the source directory /// Path to the destination directory public void CopyDirectory(string sourcePath, string destinationPath) { _fileProvider.CopyDirectory(sourcePath, destinationPath); } /// /// Create the new directory /// /// Path to the parent directory /// Name of the new directory public virtual void CreateDirectory(string parentDirectoryPath, string name) { _fileProvider.CreateDirectory(parentDirectoryPath, name); } /// /// Get all available directories as a directory tree /// /// Type of the file /// List of directories public IEnumerable GetDirectoryList(string type) { var contents = _fileProvider.GetDirectories(type); var result = new List() { new { p = "/", f = _fileProvider.GetFiles("/", type).Count(), d = 0 } }; foreach (var (path, countFiles, countDirectories) in contents) { result.Add(new { p = path.Replace("\\", "/"), f = countFiles, d = countDirectories }); } return result; } /// /// Move the directory /// /// Path to the source directory /// Path to the destination directory public void MoveDirectory(string sourcePath, string destinationPath) { if (destinationPath.IndexOf(sourcePath, StringComparison.InvariantCulture) == 0) throw new RoxyFilemanException("E_CannotMoveDirToChild"); _fileProvider.DirectoryMove(sourcePath, destinationPath); } /// /// Get files in the passed directory /// /// Path to the files directory /// Type of the files public IEnumerable GetFiles(string directoryPath, string type) { return _fileProvider.GetFiles(directoryPath, type?.Trim('#')) .Select(f => new { p = f.RelativePath.Replace("\\", "/"), t = f.LastWriteTime.ToUnixTimeSeconds(), s = f.FileLength, w = f.Width, h = f.Height }); } /// /// Rename the directory /// /// Path to the source directory /// New name of the directory public void RenameDirectory(string sourcePath, string newName) { _fileProvider.RenameDirectory(sourcePath, newName); } /// /// Upload files to a directory on passed path /// /// Path to directory to upload files /// Files sent with the HttpRequest /// A task that represents the asynchronous operation public async Task UploadFilesAsync(string directoryPath, IEnumerable files) { foreach (var formFile in files) { await _fileProvider.SaveFileAsync(directoryPath, formFile.FileName, formFile.ContentType, formFile.OpenReadStream()); } } #endregion #region Files /// /// Copy the file /// /// Path to the source file /// Path to the destination file public void CopyFile(string sourcePath, string destinationPath) { _fileProvider.CopyFile(sourcePath, destinationPath); } /// /// Get binary image thumbnail data /// /// Path to the image /// The resulting MIME type public virtual byte[] CreateImageThumbnail(string path, string contentType) { return _fileProvider.CreateImageThumbnail(path, contentType); } /// /// Delete the directory /// /// Path to the directory public void DeleteFile(string path) { _fileProvider.DeleteFile(path); } /// /// Get filename and read-only content stream /// /// Path to the file public (Stream stream, string name) GetFileStream(string path) { var file = _fileProvider.GetFileInfo(path); if (!file.Exists) throw new FileNotFoundException(); return (file.CreateReadStream(), file.Name); } /// /// Move the file /// /// Path to the source file /// Path to the destination file public void MoveFile(string sourcePath, string destinationPath) { if (!CanHandleFile(sourcePath) && !CanHandleFile(destinationPath)) throw new RoxyFilemanException("E_FileExtensionForbidden"); _fileProvider.FileMove(sourcePath, destinationPath); } /// /// Rename the file /// /// Path to the source file /// New name of the file public void RenameFile(string sourcePath, string newName) { if (!CanHandleFile(sourcePath) && !CanHandleFile(newName)) throw new RoxyFilemanException("E_FileExtensionForbidden"); _fileProvider.RenameFile(sourcePath, newName); } #endregion }