[Fixes 6759] Replace Media Item: Replacing an Image/OEmbed with new one (#7160)

Fixes #6759
This commit is contained in:
Hannan Azam Khan
2016-10-14 00:31:49 +05:00
committed by Sébastien Ros
parent 210aebcbe9
commit 794f30af39
28 changed files with 614 additions and 217 deletions

View File

@@ -79,10 +79,15 @@ namespace Orchard.MediaLibrary.Controllers {
return View(viewModel);
}
public ActionResult Import(string folderPath) {
public ActionResult Import(string folderPath, int? replaceId = null) {
if (!Services.Authorizer.Authorize(Permissions.ManageOwnMedia, T("Cannot import media")))
return new HttpUnauthorizedResult();
// Check permission
if (!Services.Authorizer.Authorize(Permissions.ManageMediaContent) && !_mediaLibraryService.CanManageMediaFolder(folderPath)) {
return new HttpUnauthorizedResult();
}
var mediaProviderMenu = _navigationManager.BuildMenu("mediaproviders");
var imageSets = _navigationManager.BuildImageSets("mediaproviders");
@@ -90,9 +95,17 @@ namespace Orchard.MediaLibrary.Controllers {
Menu = mediaProviderMenu,
ImageSets = imageSets,
FolderPath = folderPath,
MediaTypes = _mediaLibraryService.GetMediaTypes()
MediaTypes = _mediaLibraryService.GetMediaTypes(),
};
if (replaceId != null) {
var replaceMedia = Services.ContentManager.Get(replaceId.Value).As<MediaPart>();
if (replaceMedia == null)
return HttpNotFound();
viewModel.Replace = replaceMedia;
}
return View(viewModel);
}
@@ -101,7 +114,7 @@ namespace Orchard.MediaLibrary.Controllers {
if (!Services.Authorizer.Authorize(Permissions.ManageOwnMedia, T("Cannot view media")))
return new HttpUnauthorizedResult();
// Check permission.var rootMediaFolder = _mediaLibraryService.GetRootMediaFolder();
// Check permission
if (!Services.Authorizer.Authorize(Permissions.ManageMediaContent) && !_mediaLibraryService.CanManageMediaFolder(folderPath)) {
var model = new MediaManagerMediaItemsViewModel {
MediaItems = new List<MediaManagerMediaItemViewModel>(),
@@ -134,7 +147,7 @@ namespace Orchard.MediaLibrary.Controllers {
if (!Services.Authorizer.Authorize(Permissions.ManageOwnMedia, T("Cannot get child folder listing")))
return new HttpUnauthorizedResult();
// Check permission.
// Check permission
var rootMediaFolder = _mediaLibraryService.GetRootMediaFolder();
if (!Services.Authorizer.Authorize(Permissions.ManageMediaContent) && !_mediaLibraryService.CanManageMediaFolder(folderPath)) {
var model = new MediaManagerChildFoldersViewModel {
@@ -213,7 +226,8 @@ namespace Orchard.MediaLibrary.Controllers {
}
return Json(true);
} catch (Exception e) {
}
catch (Exception e) {
Logger.Error(e, "Could not delete media items.");
return Json(false);
}
@@ -247,7 +261,8 @@ namespace Orchard.MediaLibrary.Controllers {
Services.ContentManager.Publish(clonedContentItem);
return Json(true);
} catch (Exception e) {
}
catch (Exception e) {
Logger.Error(e, "Could not clone media item.");
return Json(false);
}

View File

@@ -10,18 +10,20 @@ using Orchard.UI.Admin;
using Orchard.MediaLibrary.Models;
using Orchard.Localization;
using System.Linq;
using Orchard.FileSystems.Media;
namespace Orchard.MediaLibrary.Controllers {
[Admin, Themed(false)]
public class ClientStorageController : Controller {
private readonly IMediaLibraryService _mediaLibraryService;
private readonly IMimeTypeProvider _mimeTypeProvider;
public ClientStorageController(
IMediaLibraryService mediaManagerService,
IContentManager contentManager,
IOrchardServices orchardServices) {
IMediaLibraryService mediaManagerService,
IOrchardServices orchardServices,
IMimeTypeProvider mimeTypeProvider) {
_mediaLibraryService = mediaManagerService;
Services = orchardServices;
_mimeTypeProvider = mimeTypeProvider;
Services = orchardServices;
T = NullLocalizer.Instance;
}
@@ -29,34 +31,39 @@ namespace Orchard.MediaLibrary.Controllers {
public IOrchardServices Services { get; set; }
public Localizer T { get; set; }
public ActionResult Index(string folderPath, string type) {
public ActionResult Index(string folderPath, string type, int? replaceId = null) {
if (!Services.Authorizer.Authorize(Permissions.ManageOwnMedia)) {
return new HttpUnauthorizedResult();
}
// Check permission.
var rootMediaFolder = _mediaLibraryService.GetRootMediaFolder();
// Check permission
if (!Services.Authorizer.Authorize(Permissions.ManageMediaContent) && !_mediaLibraryService.CanManageMediaFolder(folderPath)) {
return new HttpUnauthorizedResult();
}
var viewModel = new ImportMediaViewModel {
FolderPath = folderPath,
Type = type
Type = type,
};
if (replaceId != null) {
var replaceMedia = Services.ContentManager.Get<MediaPart>(replaceId.Value);
if (replaceMedia == null)
return HttpNotFound();
viewModel.Replace = replaceMedia;
}
return View(viewModel);
}
[HttpPost]
public ActionResult Upload(string folderPath, string type) {
if (!Services.Authorizer.Authorize(Permissions.ManageOwnMedia)) {
if (!Services.Authorizer.Authorize(Permissions.ManageOwnMedia)) {
return new HttpUnauthorizedResult();
}
// Check permission.
var rootMediaFolder = _mediaLibraryService.GetRootMediaFolder();
// Check permission
if (!Services.Authorizer.Authorize(Permissions.ManageMediaContent) && !_mediaLibraryService.CanManageMediaFolder(folderPath)) {
return new HttpUnauthorizedResult();
}
@@ -64,7 +71,7 @@ namespace Orchard.MediaLibrary.Controllers {
var statuses = new List<object>();
var settings = Services.WorkContext.CurrentSite.As<MediaLibrarySettingsPart>();
var allowedExtensions = (settings.UploadAllowedFileTypeWhitelist ?? "")
.Split(new [] { ',' }, StringSplitOptions.RemoveEmptyEntries)
.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
.Where(x => x.StartsWith("."));
// Loop through each file in the request
@@ -72,15 +79,15 @@ namespace Orchard.MediaLibrary.Controllers {
// Pointer to file
var file = HttpContext.Request.Files[i];
var filename = Path.GetFileName(file.FileName);
// if the file has been pasted, provide a default name
if (file.ContentType.Equals("image/png", StringComparison.InvariantCultureIgnoreCase) && !filename.EndsWith(".png", StringComparison.InvariantCultureIgnoreCase)) {
filename = "clipboard.png";
}
// skip file if the allowed extensions is defined and doesn't match
if(allowedExtensions.Any()) {
if(!allowedExtensions.Any(e => filename.EndsWith(e, StringComparison.OrdinalIgnoreCase))) {
if (allowedExtensions.Any()) {
if (!allowedExtensions.Any(e => filename.EndsWith(e, StringComparison.OrdinalIgnoreCase))) {
statuses.Add(new {
error = T("This file type is not allowed: {0}", Path.GetExtension(filename)).Text,
progress = 1.0,
@@ -89,21 +96,107 @@ namespace Orchard.MediaLibrary.Controllers {
}
}
var mediaPart = _mediaLibraryService.ImportMedia(file.InputStream, folderPath, filename, type);
Services.ContentManager.Create(mediaPart);
try {
var mediaPart = _mediaLibraryService.ImportMedia(file.InputStream, folderPath, filename, type);
Services.ContentManager.Create(mediaPart);
statuses.Add(new {
id = mediaPart.Id,
name = mediaPart.Title,
type = mediaPart.MimeType,
size = file.ContentLength,
progress = 1.0,
url= mediaPart.FileName,
});
statuses.Add(new {
id = mediaPart.Id,
name = mediaPart.Title,
type = mediaPart.MimeType,
size = file.ContentLength,
progress = 1.0,
url = mediaPart.FileName,
});
}
catch (Exception ex) {
statuses.Add(new {
error = T(ex.Message).Text,
progress = 1.0,
});
}
}
// Return JSON
return Json(statuses, JsonRequestBehavior.AllowGet);
}
[HttpPost]
public ActionResult Replace(int replaceId, string type) {
if (!Services.Authorizer.Authorize(Permissions.ManageOwnMedia))
return new HttpUnauthorizedResult();
var replaceMedia = Services.ContentManager.Get<MediaPart>(replaceId);
if (replaceMedia == null)
return HttpNotFound();
// Check permission
if (!Services.Authorizer.Authorize(Permissions.ManageMediaContent) && !_mediaLibraryService.CanManageMediaFolder(replaceMedia.FolderPath)) {
return new HttpUnauthorizedResult();
}
var statuses = new List<object>();
var settings = Services.WorkContext.CurrentSite.As<MediaLibrarySettingsPart>();
var allowedExtensions = (settings.UploadAllowedFileTypeWhitelist ?? "")
.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
.Where(x => x.StartsWith("."));
// Loop through each file in the request
for (int i = 0; i < HttpContext.Request.Files.Count; i++) {
// Pointer to file
var file = HttpContext.Request.Files[i];
var filename = Path.GetFileName(file.FileName);
// if the file has been pasted, provide a default name
if (file.ContentType.Equals("image/png", StringComparison.InvariantCultureIgnoreCase) && !filename.EndsWith(".png", StringComparison.InvariantCultureIgnoreCase)) {
filename = "clipboard.png";
}
// skip file if the allowed extensions is defined and doesn't match
if (allowedExtensions.Any()) {
if (!allowedExtensions.Any(e => filename.EndsWith(e, StringComparison.OrdinalIgnoreCase))) {
statuses.Add(new {
error = T("This file type is not allowed: {0}", Path.GetExtension(filename)).Text,
progress = 1.0,
});
continue;
}
}
try {
var mimeType = _mimeTypeProvider.GetMimeType(filename);
string replaceContentType = _mediaLibraryService.MimeTypeToContentType(file.InputStream, mimeType, type) ?? type;
if (!replaceContentType.Equals(replaceMedia.TypeDefinition.Name, StringComparison.OrdinalIgnoreCase))
throw new Exception(T("Cannot replace {0} with {1}", replaceMedia.TypeDefinition.Name, replaceContentType).Text);
_mediaLibraryService.DeleteFile(replaceMedia.FolderPath, replaceMedia.FileName);
_mediaLibraryService.UploadMediaFile(replaceMedia.FolderPath, replaceMedia.FileName, file.InputStream);
replaceMedia.MimeType = mimeType;
// Force a publish event which will update relevant Media properties
replaceMedia.ContentItem.VersionRecord.Published = false;
Services.ContentManager.Publish(replaceMedia.ContentItem);
statuses.Add(new {
id = replaceMedia.Id,
name = replaceMedia.Title,
type = replaceMedia.MimeType,
size = file.ContentLength,
progress = 1.0,
url = replaceMedia.FileName,
});
}
catch (Exception ex) {
statuses.Add(new {
error = T(ex.Message).Text,
progress = 1.0,
});
}
}
return Json(statuses, JsonRequestBehavior.AllowGet);
}
}
}

View File

@@ -17,7 +17,7 @@ namespace Orchard.MediaLibrary.Controllers {
private readonly IMediaLibraryService _mediaLibraryService;
public FolderController(
IOrchardServices services,
IOrchardServices services,
IMediaLibraryService mediaManagerService
) {
_mediaLibraryService = mediaManagerService;
@@ -111,7 +111,7 @@ namespace Orchard.MediaLibrary.Controllers {
}
// Shouldn't be able to rename the root folder
if(IsRootFolder(viewModel.FolderPath)) {
if (IsRootFolder(viewModel.FolderPath)) {
return new HttpUnauthorizedResult();
}
@@ -179,7 +179,7 @@ namespace Orchard.MediaLibrary.Controllers {
private bool IsRootFolder(string folderPath) {
var rootMediaFolder = _mediaLibraryService.GetRootMediaFolder();
return rootMediaFolder == null ?
string.IsNullOrEmpty(folderPath) :
string.Equals(rootMediaFolder.MediaPath, folderPath, StringComparison.OrdinalIgnoreCase);

View File

@@ -10,6 +10,8 @@ using Orchard.Themes;
using Orchard.UI.Admin;
using Orchard.ContentManagement;
using Orchard.MediaLibrary.Services;
using Orchard.Localization;
using Orchard.UI.Notify;
namespace Orchard.MediaLibrary.Controllers {
[Admin, Themed(false)]
@@ -19,40 +21,64 @@ namespace Orchard.MediaLibrary.Controllers {
public OEmbedController(
IOrchardServices services,
IMediaLibraryService mediaManagerService) {
Services = services;
_mediaLibraryService = mediaManagerService;
Services = services;
T = NullLocalizer.Instance;
}
public IOrchardServices Services { get; set; }
public Localizer T { get; set; }
public ActionResult Index(string folderPath, string type, int? replaceId) {
if (!Services.Authorizer.Authorize(Permissions.ManageOwnMedia))
return new HttpUnauthorizedResult();
// Check permission
if (!Services.Authorizer.Authorize(Permissions.ManageMediaContent) && !_mediaLibraryService.CanManageMediaFolder(folderPath)) {
return new HttpUnauthorizedResult();
}
public ActionResult Index(string folderPath, string type) {
var viewModel = new OEmbedViewModel {
FolderPath = folderPath,
Type = type
};
if (replaceId != null) {
var replaceMedia = Services.ContentManager.Get<MediaPart>(replaceId.Value);
if (replaceMedia == null)
return HttpNotFound();
viewModel.Replace = replaceMedia;
if (!replaceMedia.TypeDefinition.Name.Equals("OEmbed"))
Services.Notifier.Error(T("Cannot replace {0} with OEmbed", replaceMedia.ContentItem.TypeDefinition.Name));
}
return View(viewModel);
}
[HttpPost]
[ActionName("Index")]
[ValidateInput(false)]
public ActionResult IndexPOST(string folderPath, string url, string type, string title, string html, string thumbnail, string width, string height, string description) {
if (!Services.Authorizer.Authorize(Permissions.ManageOwnMedia))
return new HttpUnauthorizedResult();
// Check permission.
var rootMediaFolder = _mediaLibraryService.GetRootMediaFolder();
if (!Services.Authorizer.Authorize(Permissions.ManageMediaContent) && !_mediaLibraryService.CanManageMediaFolder(folderPath)) {
return new HttpUnauthorizedResult();
}
public ActionResult IndexPOST(string folderPath, string url, string type, string title, string html, string thumbnail, string width, string height, string description, int? replaceId) {
var viewModel = new OEmbedViewModel {
Url = url,
FolderPath = folderPath
FolderPath = folderPath,
};
var webClient = new WebClient {Encoding = Encoding.UTF8};
if (replaceId != null) {
var replaceMedia = Services.ContentManager.Get<MediaPart>(replaceId.Value);
if (replaceMedia == null)
return HttpNotFound();
viewModel.Replace = replaceMedia;
if (!replaceMedia.ContentItem.TypeDefinition.Name.Equals("OEmbed")) {
Services.Notifier.Error(T("Cannot replace {0} with OEmbed", replaceMedia.ContentItem.TypeDefinition.Name));
return View(viewModel);
}
}
var webClient = new WebClient { Encoding = Encoding.UTF8 };
try {
// <link rel="alternate" href="http://vimeo.com/api/oembed.xml?url=http%3A%2F%2Fvimeo.com%2F23608259" type="text/xml+oembed">
@@ -120,12 +146,21 @@ namespace Orchard.MediaLibrary.Controllers {
}
[HttpPost, ValidateInput(false)]
public ActionResult MediaPost(string folderPath, string url, string document) {
public ActionResult Import(string folderPath, string url, string document) {
if (!Services.Authorizer.Authorize(Permissions.ManageOwnMedia)) {
return new HttpUnauthorizedResult();
}
// Check permission
if (!Services.Authorizer.Authorize(Permissions.ManageMediaContent) && !_mediaLibraryService.CanManageMediaFolder(folderPath)) {
return new HttpUnauthorizedResult();
}
var content = XDocument.Parse(document);
var oembed = content.Root;
var part = Services.ContentManager.New<MediaPart>("OEmbed");
part.MimeType = "text/html";
part.FolderPath = folderPath;
part.LogicalType = "OEmbed";
@@ -151,13 +186,56 @@ namespace Orchard.MediaLibrary.Controllers {
}
Services.ContentManager.Create(oembedPart);
Services.Notifier.Information(T("Media imported successfully."));
}
var viewModel = new OEmbedViewModel {
FolderPath = folderPath
};
return RedirectToAction("Index", new { folderPath = folderPath });
}
return View("Index", viewModel);
[HttpPost, ValidateInput(false)]
public ActionResult Replace(int replaceId, string url, string document) {
if (!Services.Authorizer.Authorize(Permissions.ManageOwnMedia)) {
return new HttpUnauthorizedResult();
}
var replaceMedia = Services.ContentManager.Get<MediaPart>(replaceId);
if (replaceMedia == null)
return HttpNotFound();
// Check permission
if (!Services.Authorizer.Authorize(Permissions.ManageMediaContent) && !_mediaLibraryService.CanManageMediaFolder(replaceMedia.FolderPath)) {
return new HttpUnauthorizedResult();
}
var content = XDocument.Parse(document);
var oembed = content.Root;
if (oembed.Element("title") != null) {
replaceMedia.Title = oembed.Element("title").Value;
}
else {
replaceMedia.Title = oembed.Element("url").Value;
}
if (oembed.Element("description") != null) {
replaceMedia.Caption = oembed.Element("description").Value;
}
var oembedPart = replaceMedia.As<OEmbedPart>();
if (oembedPart != null) {
replaceMedia.ContentItem.Record.Infoset.Element.Element("OEmbedPart").Remove();
oembedPart.Source = url;
foreach (var element in oembed.Elements()) {
oembedPart[element.Name.LocalName] = element.Value;
}
Services.ContentManager.Publish(oembedPart.ContentItem);
Services.Notifier.Information(T("Media replaced successfully."));
}
return RedirectToAction("Index", new { folderPath = replaceMedia.FolderPath, replaceId = replaceMedia.Id });
}
}
}

View File

@@ -7,63 +7,149 @@ using Orchard.MediaLibrary.Services;
using Orchard.MediaLibrary.ViewModels;
using Orchard.Themes;
using Orchard.UI.Admin;
using Orchard.FileSystems.Media;
using Orchard.MediaLibrary.Models;
using System.Linq;
using Orchard.Localization;
namespace Orchard.MediaLibrary.Controllers {
[Admin, Themed(false)]
public class WebSearchController : Controller {
private readonly IMediaLibraryService _mediaLibraryService;
private readonly IContentManager _contentManager;
private readonly IMimeTypeProvider _mimeTypeProvider;
public WebSearchController(
IMediaLibraryService mediaManagerService,
IMediaLibraryService mediaManagerService,
IContentManager contentManager,
IOrchardServices orchardServices) {
IOrchardServices orchardServices,
IMimeTypeProvider mimeTypeProvider) {
_mediaLibraryService = mediaManagerService;
_contentManager = contentManager;
_mimeTypeProvider = mimeTypeProvider;
Services = orchardServices;
T = NullLocalizer.Instance;
}
public IOrchardServices Services { get; set; }
public Localizer T { get; set; }
public ActionResult Index(string folderPath, string type) {
var viewModel = new ImportMediaViewModel {
FolderPath = folderPath,
Type = type
};
return View(viewModel);
}
[HttpPost]
public ActionResult ImagePost(string folderPath, string type, string url) {
if (!Services.Authorizer.Authorize(Permissions.ManageOwnMedia))
public ActionResult Index(string folderPath, string type, int? replaceId = null) {
if (!Services.Authorizer.Authorize(Permissions.ManageOwnMedia)) {
return new HttpUnauthorizedResult();
}
// Check permission.
var rootMediaFolder = _mediaLibraryService.GetRootMediaFolder();
// Check permission
if (!Services.Authorizer.Authorize(Permissions.ManageMediaContent) && !_mediaLibraryService.CanManageMediaFolder(folderPath)) {
return new HttpUnauthorizedResult();
}
var viewModel = new ImportMediaViewModel {
FolderPath = folderPath,
Type = type,
};
if (replaceId != null) {
var replaceMedia = Services.ContentManager.Get<MediaPart>(replaceId.Value);
if (replaceMedia == null)
return HttpNotFound();
viewModel.Replace = replaceMedia;
}
return View(viewModel);
}
[HttpPost]
public ActionResult Import(string folderPath, string type, string url) {
if (!Services.Authorizer.Authorize(Permissions.ManageOwnMedia))
return new HttpUnauthorizedResult();
// Check permission
if (!Services.Authorizer.Authorize(Permissions.ManageMediaContent) && !_mediaLibraryService.CanManageMediaFolder(folderPath)) {
return new HttpUnauthorizedResult();
}
var settings = Services.WorkContext.CurrentSite.As<MediaLibrarySettingsPart>();
var allowedExtensions = (settings.UploadAllowedFileTypeWhitelist ?? "")
.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
.Where(x => x.StartsWith("."));
try {
var filename = Path.GetFileName(url);
// skip file if the allowed extensions is defined and doesn't match
if (allowedExtensions.Any()) {
if (!allowedExtensions.Any(e => filename.EndsWith(e, StringComparison.OrdinalIgnoreCase))) {
throw new Exception(T("This file type is not allowed: {0}", Path.GetExtension(filename)).Text);
}
}
var buffer = new WebClient().DownloadData(url);
var stream = new MemoryStream(buffer);
var mediaPart = _mediaLibraryService.ImportMedia(stream, folderPath, Path.GetFileName(url), type);
var mediaPart = _mediaLibraryService.ImportMedia(stream, folderPath, filename, type);
_contentManager.Create(mediaPart);
return new JsonResult {
Data = new {folderPath, MediaPath = mediaPart.FileName}
};
return new JsonResult { Data = new { folderPath, MediaPath = mediaPart.FileName } };
}
catch(Exception e) {
return new JsonResult {
Data = new { error= e.Message }
};
catch (Exception e) {
return new JsonResult { Data = new { error = e.Message } };
}
}
[HttpPost]
public ActionResult Replace(int replaceId, string type, string url) {
if (!Services.Authorizer.Authorize(Permissions.ManageOwnMedia))
return new HttpUnauthorizedResult();
var replaceMedia = Services.ContentManager.Get<MediaPart>(replaceId);
if (replaceMedia == null)
return HttpNotFound();
// Check permission
if (!Services.Authorizer.Authorize(Permissions.ManageMediaContent) && !_mediaLibraryService.CanManageMediaFolder(replaceMedia.FolderPath)) {
return new HttpUnauthorizedResult();
}
var settings = Services.WorkContext.CurrentSite.As<MediaLibrarySettingsPart>();
var allowedExtensions = (settings.UploadAllowedFileTypeWhitelist ?? "")
.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
.Where(x => x.StartsWith("."));
try {
var filename = Path.GetFileName(url);
// skip file if the allowed extensions is defined and doesn't match
if (allowedExtensions.Any()) {
if (!allowedExtensions.Any(e => filename.EndsWith(e, StringComparison.OrdinalIgnoreCase))) {
throw new Exception(T("This file type is not allowed: {0}", Path.GetExtension(filename)).Text);
}
}
var buffer = new WebClient().DownloadData(url);
var stream = new MemoryStream(buffer);
var mimeType = _mimeTypeProvider.GetMimeType(filename);
string replaceContentType = _mediaLibraryService.MimeTypeToContentType(stream, mimeType, type) ?? type;
if (!replaceContentType.Equals(replaceMedia.TypeDefinition.Name, StringComparison.OrdinalIgnoreCase))
throw new Exception(T("Cannot replace {0} with {1}", replaceMedia.TypeDefinition.Name, replaceContentType).Text);
_mediaLibraryService.DeleteFile(replaceMedia.FolderPath, replaceMedia.FileName);
_mediaLibraryService.UploadMediaFile(replaceMedia.FolderPath, replaceMedia.FileName, stream);
replaceMedia.MimeType = mimeType;
// Force a publish event which will update relevant Media properties
replaceMedia.ContentItem.VersionRecord.Published = false;
Services.ContentManager.Publish(replaceMedia.ContentItem);
return new JsonResult { Data = new { replaceMedia.FolderPath, MediaPath = replaceMedia.FileName } };
}
catch (Exception e) {
return new JsonResult { Data = new { Success = false, error = e.Message } };
}
}
}
}

View File

@@ -60,6 +60,10 @@ namespace Orchard.MediaLibrary.Drivers {
context.ImportAttribute(part.PartDefinition.Name, "FileName", fileName =>
part.FileName = fileName
);
context.ImportAttribute(part.PartDefinition.Name, "LogicalType", logicalType =>
part.LogicalType = logicalType
);
}
protected override void Exporting(MediaPart part, ContentManagement.Handlers.ExportContentContext context) {
@@ -68,6 +72,7 @@ namespace Orchard.MediaLibrary.Drivers {
context.Element(part.PartDefinition.Name).SetAttributeValue("AlternateText", part.AlternateText);
context.Element(part.PartDefinition.Name).SetAttributeValue("FolderPath", part.FolderPath);
context.Element(part.PartDefinition.Name).SetAttributeValue("FileName", part.FileName);
context.Element(part.PartDefinition.Name).SetAttributeValue("LogicalType", part.LogicalType);
}
}
}

View File

@@ -57,13 +57,10 @@ namespace Orchard.MediaLibrary.Factories {
part.Title = Path.GetFileNameWithoutExtension(path);
var audioPart = part.As<AudioPart>();
if (audioPart == null) {
return null;
}
audioPart.Length = 0;
return part;
}
}

View File

@@ -27,7 +27,7 @@ namespace Orchard.MediaLibrary.Factories {
return null;
}
}
return new MediaFactorySelectorResult {
Priority = -10,
MediaFactory = new DocumentFactory(_contentManager)
@@ -43,7 +43,6 @@ namespace Orchard.MediaLibrary.Factories {
}
public MediaPart CreateMedia(Stream stream, string path, string mimeType, string contentType) {
if (String.IsNullOrEmpty(contentType)) {
contentType = "Document";
}
@@ -55,12 +54,9 @@ namespace Orchard.MediaLibrary.Factories {
part.Title = Path.GetFileNameWithoutExtension(path);
var documentPart = part.As<DocumentPart>();
if (documentPart == null) {
return null;
}
documentPart.Length = stream.Length;
return part;
}

View File

@@ -5,7 +5,6 @@ using System.Linq;
using Orchard.ContentManagement;
using Orchard.ContentManagement.MetaData;
using Orchard.MediaLibrary.Models;
using Image = System.Drawing.Image;
namespace Orchard.MediaLibrary.Factories {
@@ -18,7 +17,6 @@ namespace Orchard.MediaLibrary.Factories {
_contentDefinitionManager = contentDefinitionManager;
}
public MediaFactorySelectorResult GetMediaFactory(Stream stream, string mimeType, string contentType) {
if (!mimeType.StartsWith("image/")) {
return null;
@@ -38,7 +36,6 @@ namespace Orchard.MediaLibrary.Factories {
Priority = -5,
MediaFactory = new ImageFactory(_contentManager)
};
}
}
@@ -65,36 +62,7 @@ namespace Orchard.MediaLibrary.Factories {
return null;
}
try {
using (var image = Image.FromStream(stream)) {
imagePart.Width = image.Width;
imagePart.Height = image.Height;
}
}
catch (ArgumentException) {
// Still trying to get .ico dimensions when it's blocked in System.Drawing, see: https://github.com/OrchardCMS/Orchard/issues/4473
if (mimeType != "image/x-icon" && mimeType != "image/vnd.microsoft.icon") {
throw;
}
TryFillDimensionsForIco(stream, imagePart);
}
return part;
}
private void TryFillDimensionsForIco(Stream stream, ImagePart imagePart) {
stream.Position = 0;
using (var binaryReader = new BinaryReader(stream)) {
// Reading out the necessary bytes that indicate the image dimensions. For the file format see:
// http://en.wikipedia.org/wiki/ICO_%28file_format%29
// Reading out leading bytes containing unneded information.
binaryReader.ReadBytes(6);
// Reading out dimensions. If there are multiple icons bundled in the same file then this is the first image.
imagePart.Width = binaryReader.ReadByte();
imagePart.Height = binaryReader.ReadByte();
}
}
}
}

View File

@@ -21,7 +21,7 @@ namespace Orchard.MediaLibrary.Factories {
if (!mimeType.StartsWith("image/svg")) {
return null;
}
if (!String.IsNullOrEmpty(contentType)) {
var contentDefinition = _contentDefinitionManager.GetTypeDefinition(contentType);
if (contentDefinition == null || contentDefinition.Parts.All(x => x.PartDefinition.Name != typeof(VectorImagePart).Name)) {

View File

@@ -55,13 +55,10 @@ namespace Orchard.MediaLibrary.Factories {
part.Title = Path.GetFileNameWithoutExtension(path);
var videoPart = part.As<VideoPart>();
if (videoPart == null) {
return null;
}
videoPart.Length = 0;
return part;
}
}

View File

@@ -3,14 +3,20 @@ using Orchard.ContentManagement.Handlers;
using Orchard.Data;
using Orchard.MediaLibrary.Services;
using Orchard.MediaLibrary.Models;
using System.IO;
using Orchard.FileSystems.Media;
using Orchard.ContentManagement;
namespace Orchard.MediaLibrary.Handlers {
public class MediaPartHandler : ContentHandler {
private readonly IMediaLibraryService _mediaLibraryService;
private readonly IStorageProvider _storageProvider;
public MediaPartHandler(
IStorageProvider storageProvider,
IMediaLibraryService mediaLibraryService,
IRepository<MediaPartRecord> repository) {
_storageProvider = storageProvider;
_mediaLibraryService = mediaLibraryService;
Filters.Add(StorageFilter.For(repository));
@@ -21,7 +27,7 @@ namespace Orchard.MediaLibrary.Handlers {
}
});
OnIndexing<MediaPart>((context, part) =>
OnIndexing<MediaPart>((context, part) =>
context.DocumentIndex
.Add("media-folderpath", Normalize(part.FolderPath)).Store()
.Add("media-filename", Normalize(part.FileName)).Store()
@@ -30,22 +36,55 @@ namespace Orchard.MediaLibrary.Handlers {
.Add("media-alternatetext", part.AlternateText).Analyze()
);
OnPublished<ImagePart>((context, part) => {
var mediaPart = part.As<MediaPart>();
var file = _storageProvider.GetFile(_storageProvider.Combine(mediaPart.FolderPath, mediaPart.FileName));
using (var stream = file.OpenRead()) {
try {
using (var image = System.Drawing.Image.FromStream(stream)) {
part.Width = image.Width;
part.Height = image.Height;
}
}
catch (ArgumentException) {
// Still trying to get .ico dimensions when it's blocked in System.Drawing, see: https://github.com/OrchardCMS/Orchard/issues/4473
if (mediaPart.MimeType != "image/x-icon" && mediaPart.MimeType != "image/vnd.microsoft.icon")
throw;
TryFillDimensionsForIco(stream, part);
}
}
});
OnIndexing<ImagePart>((context, part) =>
context.DocumentIndex
.Add("image-height", part.Height).Analyze().Store()
.Add("image-width", part.Width).Analyze().Store()
);
OnPublished<DocumentPart>((context, part) => {
var mediaPart = part.As<MediaPart>();
var file = _storageProvider.GetFile(_storageProvider.Combine(mediaPart.FolderPath, mediaPart.FileName));
using (var stream = file.OpenRead()) {
part.Length = stream.Length;
}
});
OnIndexing<DocumentPart>((context, part) =>
context.DocumentIndex
.Add("document-length", part.Length).Analyze().Store()
);
OnPublished<VideoPart>((context, part) => part.Length = 0);
OnIndexing<VideoPart>((context, part) =>
context.DocumentIndex
.Add("video-length", part.Length).Analyze().Store()
);
OnPublished<AudioPart>((context, part) => part.Length = 0);
OnIndexing<AudioPart>((context, part) =>
context.DocumentIndex
.Add("audio-length", part.Length).Analyze().Store()
@@ -67,5 +106,18 @@ namespace Orchard.MediaLibrary.Handlers {
// when not indexed with Analyze() searches are case sensitive
return text.Replace("\\", "/").ToLowerInvariant();
}
private void TryFillDimensionsForIco(Stream stream, ImagePart imagePart) {
stream.Position = 0;
using (var binaryReader = new BinaryReader(stream)) {
// Reading out the necessary bytes that indicate the image dimensions. For the file format see:
// http://en.wikipedia.org/wiki/ICO_%28file_format%29
// Reading out leading bytes containing unneded information.
binaryReader.ReadBytes(6);
// Reading out dimensions. If there are multiple icons bundled in the same file then this is the first image.
imagePart.Width = binaryReader.ReadByte();
imagePart.Height = binaryReader.ReadByte();
}
}
}
}

View File

@@ -327,6 +327,17 @@ $(function () {
window.location = url;
};
self.replaceMedia = function (item) {
var url = settings.replaceUrl;
var ids = [];
var folder = "";
if (self.displayed()) {
folder = self.displayed();
}
viewModel.selection().forEach(function (item) { ids.push(item.data.id); });
var actionurl = url + '?folderPath=' + encodeURIComponent(folder) + "&replaceId=" + encodeURIComponent(ids[0]);
window.location = actionurl;
}
var selectFolderOrRecent = function () {
if (self.displayed()) {
self.selectFolder(self.displayed());

View File

@@ -167,5 +167,26 @@ namespace Orchard.MediaLibrary.Services {
return folderPath;
}
public static string MimeTypeToContentType(this IMediaLibraryService service, Stream stream, string mimeType, string contentType) {
var mediaFactory = service.GetMediaFactory(stream, mimeType, contentType);
if (mediaFactory == null)
return null;
switch (mediaFactory.GetType().Name) {
case "ImageFactory":
return "Image";
case "AudioFactory":
return "Audio";
case "DocumentFactory":
return "Document";
case "VectorImageFactory":
return "VectorImage";
case "VideoFactory":
return "Video";
default:
return null;
}
}
}
}

View File

@@ -174,6 +174,8 @@ namespace Orchard.MediaLibrary.Services {
using (var stream = storageFile.OpenRead()) {
var mediaFactory = GetMediaFactory(stream, mimeType, contentType);
if (mediaFactory == null)
throw new Exception(T("No media factory available to handle this resource.").Text);
var mediaPart = mediaFactory.CreateMedia(stream, mediaFile.Name, mimeType, contentType);
if (mediaPart != null) {
mediaPart.FolderPath = relativePath;

View File

@@ -46,4 +46,23 @@
border-top-left-radius: 0;
border-bottom-left-radius: 0;
font-size: 18px;
}
/* Messages */
.message {
margin:10px 0 4px 0;
padding:4px;
clear:both;
}
.message-Information {
background:#e6f1c9; /* green */
border:1px solid #cfe493;
color:#062232;
}
.message-Error {
background:#e68585; /* red */
border:1px solid #990808;
color:#fff;
}

View File

@@ -1,6 +1,9 @@
namespace Orchard.MediaLibrary.ViewModels {
using Orchard.MediaLibrary.Models;
namespace Orchard.MediaLibrary.ViewModels {
public class ImportMediaViewModel {
public string FolderPath { get; set; }
public string Type { get; set; }
public MediaPart Replace { get; set; }
}
}

View File

@@ -1,6 +1,7 @@
using System.Collections.Generic;
using Orchard.ContentManagement.MetaData.Models;
using Orchard.UI.Navigation;
using Orchard.MediaLibrary.Models;
namespace Orchard.MediaLibrary.ViewModels {
public class MediaManagerImportViewModel {
@@ -8,5 +9,6 @@ namespace Orchard.MediaLibrary.ViewModels {
public IEnumerable<string> ImageSets { get; set; }
public string FolderPath { get; set; }
public IEnumerable<ContentTypeDefinition> MediaTypes { get; set; }
public MediaPart Replace { get; set; }
}
}

View File

@@ -12,5 +12,4 @@ namespace Orchard.MediaLibrary.ViewModels {
public MediaPart MediaPart { get; set; }
public dynamic Shape { get; set; }
}
}

View File

@@ -1,11 +1,11 @@
using System.Xml.Linq;
using Orchard.MediaLibrary.Models;
using System.Xml.Linq;
namespace Orchard.MediaLibrary.ViewModels {
public class OEmbedViewModel {
public string FolderPath { get; set; }
public string Url { get; set; }
public XDocument Content { get; set; }
public bool Success { get; set; }
public string Type { get; set; }
public MediaPart Replace { get; set; }
}
}

View File

@@ -18,16 +18,15 @@
<div id="media-library-toolbar">
<div id="media-library-toolbar-actions">
<label for="filterMediaType">@T("Create")</label>
<label for="filterMediaType">@if (Model.Replace == null) { <text>@T("Create")</text> } else { <text>@T("Replace")</text> }</label>
<select id="filterMediaType" name="FilteredMediaType">
@Html.SelectOption("", true, T("Any").ToString())
@foreach (var mediaType in Model.MediaTypes) {
@Html.SelectOption(mediaType.Name, false, mediaType.DisplayName)
}
</select>
<a href="@Url.Action("Index", "Admin", new { folderPath = Model.FolderPath})" class="button">@T("Close")</a>
<a href="@Url.Action("Index", "Admin", new { folderPath = Model.FolderPath})" class="button close">@T("Close")</a>
</div>
@Html.ActionLink(T("Media Library").ToString(), "Index", "Admin", new { area = "Orchard.MediaLibrary" }, null)
@@ -37,11 +36,15 @@
<div id="media-library-main">
<div id="media-library-main-navigation">
@foreach (var menuItem in Model.Menu) {
@foreach (var menuItem in Model.Menu)
{
string sectionHeaderTextHint = menuItem.Text.TextHint;
var itemClassName = "navicon-" + sectionHeaderTextHint.HtmlClassify();
<div class="import-provider"><a class="navicon @itemClassName" href="@menuItem.Href/Index?folderPath=@HttpUtility.UrlEncode(Model.FolderPath)">@menuItem.Text</a></div>
if (Model.Replace == null) {
<div class="import-provider"><a class="navicon @itemClassName" href="@menuItem.Href/Index?folderPath=@HttpUtility.UrlEncode(Model.FolderPath)">@menuItem.Text</a></div>
} else {
<div class="import-provider"><a class="navicon @itemClassName" href="@menuItem.Href/Index?folderPath=@HttpUtility.UrlEncode(Model.FolderPath)&replaceId=@HttpUtility.UrlEncode(Model.Replace.Id.ToString())">@menuItem.Text</a></div>
}
}
</div>
<div id="media-library-main-list-wrapper">

View File

@@ -68,6 +68,7 @@
</ul>
<div id="media-library-main-selection-actions">
<button id="delete-selection-button">@T("Delete")</button>
<button href="#" data-bind="click: replaceMedia, visible: selection().length == 1" class="button" id="replace-selection-button">@T("Replace")</button>
<button id="clone-selection-button" data-bind="visible: selection().length == 1">@T("Clone")</button>
</div>
</div>
@@ -96,11 +97,13 @@ var mediaLibrarySettings = {
moveActionUrl: '@Url.Action("Move", "Folder", new {area = "Orchard.MediaLibrary"})',
deleteActionUrl: '@Url.Action("Delete", "Admin", new {area = "Orchard.MediaLibrary"})',
cloneActionUrl: '@Url.Action("Clone", "Admin", new {area = "Orchard.MediaLibrary"})',
replaceUrl: '@Url.Action("Import", "Admin", new {area = "Orchard.MediaLibrary" })' ,
hasFolderPath: @(!string.IsNullOrEmpty(viewModel.FolderPath) ? "true" : "false"),
folderPath: '@HttpUtility.JavaScriptStringEncode(viewModel.FolderPath)',
rootFolderPath: '@HttpUtility.JavaScriptStringEncode(viewModel.RootFolderPath ?? "")',
deleteConfirmationMessage: '@HttpUtility.JavaScriptStringEncode(T("Are you sure you want to delete these media items ?").Text)',
cloneConfirmationMessage: '@HttpUtility.JavaScriptStringEncode(T("Are you sure you want to clone this media item ?").Text)',
replaceConfirmationMessage: '@HttpUtility.JavaScriptStringEncode(T("Are you sure you want to replace this media item ?").Text)',
errorMessage: '@HttpUtility.JavaScriptStringEncode(T("An unexpected error occured, please refresh the page and try again.").Text)',
antiForgeryToken: '@Html.AntiForgeryTokenValueOrchard()',
childFolders: (@Display.Partial(TemplateName: "ChildFolders", Model: viewModel.ChildFoldersViewModel))['childFolders']

View File

@@ -1,5 +1,4 @@
@model Orchard.MediaLibrary.ViewModels.ImportMediaViewModel
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
@@ -21,11 +20,10 @@
@Display.StyleSheetLinks()
</head>
<body>
<div id="clientstorage-main">
<div id="message">@T("Click here, Drop files or Paste images")</div>
<div id="fileupload">
<input type="file" name="files[]" multiple="multiple">
<input type="file" name="files[]" @if(Model.Replace == null) { <text>multiple="multiple"</text> } >
<ul id="fileupload-transfers" data-bind="foreach: transfers">
<li data-bind="css: status()" class="transfer">
<div class="media-thumbnail" data-bind="html: thumbnail(), visible: status() == 'success'"></div>
@@ -36,15 +34,12 @@
</div>
</li>
</ul>
</div>
</div>
@using(Script.Foot()) {
@using (Script.Foot()) {
<script type="text/javascript">
//<![CDATA[
//<![CDATA[
$(function () {
function transferViewModel(filename, size) {
@@ -63,7 +58,7 @@
self.transfers = ko.observableArray([]);
self.upload = function(file) {
self.upload = function (file) {
var transfer = new transferViewModel(file.name, file.size);
self.transfers.push(transfer);
return transfer;
@@ -73,24 +68,37 @@
var viewModel = new clientStorageViewModel();
ko.applyBindings(viewModel);
$('#fileupload').click(function() {
console.log('click');
$('#fileupload').click(function () {
//console.log('click');
$('#fileupload > input').trigger('click');
});
$('#fileupload > input').click(function(event) {
$('#fileupload > input').click(function (event) {
event.stopPropagation();
});
// Add drag-n-drop HTML5 support
$('#fileupload').fileupload({
url: '@Url.Action("Upload", "ClientStorage")',
autoUpload: true,
@if(Model.Replace == null) {
<text>
url: '@Url.Action("Upload")',
formData: {
folderPath: '@Html.Raw(HttpUtility.JavaScriptStringEncode(Model.FolderPath))',
type: '@HttpUtility.JavaScriptStringEncode(Model.Type)',
__RequestVerificationToken: '@Html.AntiForgeryTokenValueOrchard()'
},
</text>
} else {
<text>
url: '@Url.Action("Replace")',
formData: {
replaceId: '@HttpUtility.JavaScriptStringEncode(Model.Replace.Id.ToString())',
type: '@HttpUtility.JavaScriptStringEncode(Model.Type)',
__RequestVerificationToken: '@Html.AntiForgeryTokenValueOrchard()'
},
</text>
}
done: function (e, data) {
console.log(data.result);
},
@@ -114,7 +122,6 @@
data.context = viewModel.upload(file);
}
data.submit();
},
// Callback for upload progress events:
@@ -128,11 +135,11 @@
pasteZone: window.parent.document,
paste: function (e, data) {
$.each(data.files, function (index, file) {
//console.log('Pasted file type: ' + file.type);
console.log('Pasted file type: ' + file.type);
});
return true;
},
done: function(e, data) {
done: function (e, data) {
var result = data.result[0];
if (result.error) {
@@ -142,23 +149,27 @@
data.context.label('@HttpUtility.JavaScriptStringEncode(T("Loading thumbnail...").Text)');
var url = '@HttpUtility.JavaScriptStringEncode(Url.Action("MediaItem", "Admin"))/' + result.id + '?displayType=Thumbnail';
$.ajax({
type: "GET",
url: url,
}).done(function(html) {
}).done(function (html) {
data.context.thumbnail(html);
data.context.status('success');
@if(Model.Replace != null) {
<text>
window.parent.$("a.button.close")[0].click();
</text>
}
});
},
fail: function(e, data) {
fail: function (e, data) {
data.context.status('error');
}
});
})
//]]>
//]]>
</script>
}

View File

@@ -46,14 +46,18 @@
@Display.StyleSheetLinks()
</head>
<body>
<div id="oembed-main">
@if (Layout.Messages != null) {
<div id="messages">
@Display(Layout.Messages)
</div>
}
<div class="query-container">
@using (Html.BeginFormAntiForgeryPost()) {
<fieldset>
<legend>@T("Please enter the URL of the embeddable media you want to integrate (requires an oEmbed compatible media provider such as YouTube):")</legend>
<div id="icon">
<button type="submit" class="fa fa-download">@T("Preview")</button>
<button type="submit" class="fa fa-download"></button>
</div>
<div id="query">
<input name="url" type="text" autofocus placeholder="@T("media url")" value="@Model.Url" />
@@ -126,15 +130,24 @@
</div>
}
using (Html.BeginFormAntiForgeryPost(Url.Action("MediaPost"))) {
@Html.Hidden("url", Model.Url)
@Html.Hidden("folderPath", Model.FolderPath)
@Html.Hidden("document", Model.Content.ToString())
<br/>
<button type="submit">@T("Import")</button>
if (Model.Replace == null) {
using (Html.BeginFormAntiForgeryPost(Url.Action("Import"))) {
@Html.Hidden("folderPath", Model.FolderPath)
@Html.Hidden("url", Model.Url)
@Html.Hidden("document", Model.Content.ToString())
<br/>
<button type="submit">@T("Import")</button>
}
} else {
using (Html.BeginFormAntiForgeryPost(Url.Action("Replace"), FormMethod.Post, new { onsubmit = "window.parent.$('a.button.close')[0].click();" })) {
@Html.Hidden("replaceId", Model.Replace)
@Html.Hidden("url", Model.Url)
@Html.Hidden("document", Model.Content.ToString())
<br />
<button type="submit">@T("Replace")</button>
}
}
}
</div>
@Display.FootScripts()
</body>

View File

@@ -27,7 +27,9 @@
var self = $(this);
var href = self.attr('href');
var containsQueryString = href.indexOf("?") >= 0;
if (href.indexOf("returnUrl") == -1) {
var returnUrl = href + (containsQueryString ? "&" : "?") + "returnUrl=" + encodeURIComponent(window.location);
}
self.attr('href', returnUrl);
});
//]]>

View File

@@ -11,7 +11,7 @@
@if (HasText(mediaUrl)) {
<div class="file-name">
<em>@T("Filename:")</em>
<span><a href="@mediaUrl">@HttpUtility.UrlDecode(Path.GetFileName(mediaUrl))</a></span>
<span><a href="@mediaUrl" target="_blank">@HttpUtility.UrlDecode(Path.GetFileName(mediaUrl))</a></span>
</div>
}
<div class="mime-type">

View File

@@ -70,12 +70,12 @@
<div id="websearch-properties-selection" data-bind="visible: selection().length">
<h1>@T("SELECTION")</h1>
<button id="button-import">IMPORT</button>
<button id="button-import">@if (Model.Replace == null) { <text>@T("Import")</text> } else { <text>@T("Replace")</text> } </button>
<ul data-bind="foreach: selection">
<li>
<div class="selection" data-bind="click: $parent.focus, style: { backgroundImage: 'url(' + data.Thumbnail.MediaUrl + ')' }">
<div class="selection-overlay">
<div class="selection-progress" data-bind="css: status()"></div>
<div class="selection-progress" data-bind="css: status(), attr: { 'title': tooltip() == '' ? null : tooltip() }"></div>
</div>
</div>
</li>
@@ -83,42 +83,38 @@
</div>
</div>
@Html.Hidden("antiforgerytoken", Html.AntiForgeryTokenValueOrchard())
@Html.Hidden("action", Url.Action("ImagePost"))
@Html.Hidden("folderPath", Model.FolderPath)
@Html.Hidden("type", Model.Type)
@using(Script.Foot()) {
<script type="text/javascript">
//<![CDATA[
//<![CDATA[
$(function () {
function SearchResult(data) {
var self = this;
// values
self.data = data;
self.hasFocus = ko.observable();
self.selected = ko.observable();
self.status = ko.observable('');
self.tooltip = ko.observable('');
// operations
self.setData = function (value) {
self.data = value;
};
self.getFilename = function() {
self.getFilename = function () {
var value = self.data.MediaUrl;
return value.substr(value.lastIndexOf('/') + 1);
};
self.kilobytes = function() {
self.kilobytes = function () {
return Math.round(self.data.FileSize / 1024);
};
}
function WebSearchViewModel() {
var self = this;
// values
self.selection = ko.observableArray([]);
self.focus = ko.observable();
@@ -127,11 +123,11 @@
self.filename = function () {
return value.substr(value.lastIndexOf('/') + 1);
};
self.doSearch = function () {
var query = $('#query > input').val();
var url = 'https://api.datamarket.azure.com/Bing/Search/Image?$format=json&Query=%27' + encodeURIComponent(query) + '%27';
$.ajax({
type: "POST",
url: url,
@@ -154,7 +150,7 @@
self.selection([]);
};
self.focus.subscribe(function (oldValue) {
if (oldValue) {
oldValue.hasFocus(false);
@@ -166,7 +162,7 @@
newValue.hasFocus(true);
}
});
self.toggleSelect = function (searchResult) {
var index = $.inArray(searchResult, self.selection());
if (index == -1) {
@@ -176,10 +172,10 @@
self.selection.remove(searchResult);
searchResult.selected(false);
}
self.focus(searchResult);
};
self.select = function (searchResult) {
var index = $.inArray(searchResult, self.selection());
if (index == -1) {
@@ -187,7 +183,7 @@
self.selection([searchResult]);
searchResult.selected(true);
}
self.focus(searchResult);
};
@@ -198,52 +194,73 @@
$("#websearch-results").on("click", "li", function (e) {
var searchResult = ko.dataFor(this);
if (e.ctrlKey) {
viewModel.toggleSelect(searchResult);
@if(Model.Replace == null) {
<text>
if (e.ctrlKey) {
viewModel.toggleSelect(searchResult);
} else {
viewModel.select(searchResult);
}
</text>
} else {
<text>
viewModel.select(searchResult);
</text>
}
}).on("contextmenu", "li", function(e) {
}).on("contextmenu", "li", function (e) {
var searchResult = ko.dataFor(this);
viewModel.toggleSelect(searchResult);
return false;
});
$("#button-import").on("click", function (e) {
var antiForgeryToken = $('[name=antiforgerytoken]').val();
var folderPath = $('[name=folderPath]').val();
var type = $('[name=type]').val();
var action = $('[name=action]').val();
$("#button-import").on("click", function (e) {
viewModel.selection().forEach(function (item) {
var url = item.data.MediaUrl;
item.status('uploading');
$.post(action, {
folderPath: folderPath,
type: type,
url: url,
__RequestVerificationToken: antiForgeryToken,
})
item.tooltip('');
@if (Model.Replace == null) {
<text>
$.post('@Url.Action("Import")', {
folderPath: '@Html.Raw(HttpUtility.JavaScriptStringEncode(Model.FolderPath))',
type: '@HttpUtility.JavaScriptStringEncode(Model.Type)',
url: url,
__RequestVerificationToken: '@Html.AntiForgeryTokenValueOrchard()'
})
</text>
} else {
<text>
$.post('@Url.Action("Replace")', {
replaceId: '@HttpUtility.JavaScriptStringEncode(Model.Replace.Id.ToString())',
type: '@HttpUtility.JavaScriptStringEncode(Model.Type)',
url: url,
__RequestVerificationToken: '@Html.AntiForgeryTokenValueOrchard()'
})
</text>
}
.done(function (data) {
if (data.error) {
console.log(data);
item.status('failure');
item.tooltip(data.error);
} else {
item.status('success');
viewModel.selection.remove(item);
item.tooltip("Media imported successfully.");
@if(Model.Replace != null) {
<text>
window.parent.$("a.button.close")[0].click();
</text>
}
}
})
.fail(function (jqXhr, data) {
console.log('failed: ' + JSON.stringify(textStatus));
item.status('failure');
})
.always(function() {
.always(function () {
});
});
});
})
//]]>
//]]>
</script>
}

View File

@@ -933,7 +933,9 @@
<Compile Include="Mvc\Routes\UrlPrefix.cs" />
<Compile Include="Mvc\Routes\UrlPrefixAdjustedHttpContext.cs" />
<Compile Include="Mvc\Routes\ShellRoute.cs" />
<Compile Include="Mvc\ViewUserControl.cs" />
<Compile Include="Mvc\ViewUserControl.cs">
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="Mvc\Wrappers\HttpContextBaseWrapper.cs" />
<Compile Include="Mvc\Wrappers\HttpRequestBaseWrapper.cs" />
<Compile Include="Mvc\Wrappers\HttpResponseBaseWrapper.cs" />
@@ -1013,7 +1015,9 @@
<Compile Include="UI\Resources\LinkEntry.cs" />
<Compile Include="UI\Resources\ResourceFilter.cs" />
<Compile Include="UI\Resources\ResourceManager.cs" />
<Compile Include="Mvc\ViewPage.cs" />
<Compile Include="Mvc\ViewPage.cs">
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="Security\IAuthenticationService.cs" />
<Compile Include="Security\Authorizer.cs" />
<Compile Include="Security\Providers\FormsAuthenticationService.cs" />