#20453: Adding Clone Button to Media Library

#20453: Fixing Formatting Issues

#20453: Adding Clone Button to Media Library

Work Item: 20453

Conflicts:
	src/Orchard.Web/Modules/Orchard.MediaLibrary/Controllers/AdminController.cs
	src/Orchard.Web/Modules/Orchard.MediaLibrary/Scripts/media-library.js
This commit is contained in:
Stanley Goldman
2014-01-26 12:17:22 -05:00
committed by Stanley Goldman
parent b50ae151bd
commit e90001605d
9 changed files with 132 additions and 5 deletions

View File

@@ -257,6 +257,9 @@ namespace Orchard.Tests.Modules.Media.Services {
public void RenameFile(string path, string newPath) {
}
public void CopyFile(string originalPath, string duplicatePath) {
}
public IStorageFile CreateFile(string path) {
throw new NotImplementedException();
}

View File

@@ -261,6 +261,18 @@ namespace Orchard.Azure.Services.FileSystems {
blob.Delete();
}
public void CopyFile(string path, string newPath) {
path = ConvertToRelativeUriPath(path);
newPath = ConvertToRelativeUriPath(newPath);
Container.EnsureBlobExists(String.Concat(_root, path));
Container.EnsureBlobDoesNotExist(String.Concat(_root, newPath));
var blob = Container.GetBlockBlobReference(String.Concat(_root, path));
var newBlob = Container.GetBlockBlobReference(String.Concat(_root, newPath));
newBlob.StartCopyFromBlob(blob);
}
public IStorageFile CreateFile(string path) {
path = ConvertToRelativeUriPath(path);

View File

@@ -1,7 +1,9 @@
using System;
using System.IO;
using System.Linq;
using System.Web.Mvc;
using Orchard.ContentManagement;
using Orchard.Core.Title.Models;
using Orchard.Localization;
using Orchard.Logging;
using Orchard.MediaLibrary.Models;
@@ -180,6 +182,35 @@ namespace Orchard.MediaLibrary.Controllers {
}
}
[HttpPost]
public ActionResult Clone(int mediaItemId) {
if (!Services.Authorizer.Authorize(Permissions.ManageMediaContent, T("Couldn't clone media items")))
return new HttpUnauthorizedResult();
try {
var media = Services.ContentManager.Get(mediaItemId).As<MediaPart>();
var newFileName = Path.GetFileNameWithoutExtension(media.FileName) + " Copy" + Path.GetExtension(media.FileName);
_mediaLibraryService.CopyFile(media.FolderPath, media.FileName, media.FolderPath, newFileName);
var clonedContentItem = Services.ContentManager.Clone(media.ContentItem);
var clonedMediaPart = clonedContentItem.As<MediaPart>();
var clonedTitlePart = clonedContentItem.As<TitlePart>();
clonedMediaPart.FileName = newFileName;
clonedTitlePart.Title = clonedTitlePart.Title + " Copy";
Services.ContentManager.Publish(clonedContentItem);
return Json(true);
}
catch (Exception e) {
Logger.Error(e, "Could not clone media item.");
return Json(false);
}
}
private FolderHierarchy GetFolderHierarchy(IMediaFolder root) {
Argument.ThrowIfNull(root, "root");
return new FolderHierarchy(root) {Children = _mediaLibraryService.GetMediaFolders(root.MediaPath).Select(GetFolderHierarchy)};

View File

@@ -485,16 +485,16 @@ $(function () {
var pickAndClose = function () {
if (parent.$.colorbox) {
var selectedData = [];
var selectedData = [];
for (var i = 0; i < viewModel.selection().length; i++) {
var selection = viewModel.selection()[i];
var selection = viewModel.selection()[i];
selectedData.push(selection.data);
}
parent.$.colorbox.selectedData = selectedData;
}
parent.$.colorbox.selectedData = selectedData;
parent.$.colorbox.close();
};
}
$("#media-library-main-selection-select > .button-select").on('click', function () {
pickAndClose();
});
@@ -571,5 +571,39 @@ $(function () {
});
return false;
});
$('#clone-selection-button').click(function () {
if (!confirm(settings.cloneConfirmationMessage)) {
return false;
}
var ids = [];
viewModel.selection().forEach(function (item) { ids.push(item.data.id); });
if (ids.length != 1) {
return false;
}
var url = settings.cloneActionUrl;
$.ajax({
type: "POST",
url: url,
dataType: "json",
traditional: true,
data: {
mediaItemId: ids[0],
__RequestVerificationToken: settings.antiForgeryToken
}
}).done(function (result) {
if (result) {
viewModel.getMediaItems(viewModel.pageCount);
} else {
console.log('failed to clone media items');
}
return false;
});
return false;
});
})(window.mediaLibrarySettings);
})

View File

@@ -96,6 +96,15 @@ namespace Orchard.MediaLibrary.Services {
/// <param name="newFilename">The new file name.</param>
void MoveFile(string currentPath, string filename, string newPath, string newFilename);
/// <summary>
/// Moves a media file.
/// </summary>
/// <param name="currentPath">The path to the file's parent folder.</param>
/// <param name="filename">The file name.</param>
/// <param name="duplicatePath">The path where the file will be copied to.</param>
/// <param name="duplicateFilename">The new file name.</param>
void CopyFile(string currentPath, string filename, string duplicatePath, string duplicateFilename);
/// <summary>
/// Uploads a media file based on a posted file.
/// </summary>

View File

@@ -355,6 +355,20 @@ namespace Orchard.MediaLibrary.Services {
_storageProvider.RenameFile(_storageProvider.Combine(currentPath, filename), _storageProvider.Combine(newPath, newFilename));
}
/// <summary>
/// Copies a file in the storage provider.
/// </summary>
/// <param name="originalPath">The relative path to the file to be copied.</param>
/// <param name="duplicatePath">The relative path to the new file.</param>
public void CopyFile(string currentPath, string filename, string duplicatePath, string duplicateFilename) {
Argument.ThrowIfNullOrEmpty(currentPath, "currentPath");
Argument.ThrowIfNullOrEmpty(duplicatePath, "duplicatePath");
Argument.ThrowIfNullOrEmpty(filename, "filename");
Argument.ThrowIfNullOrEmpty(duplicateFilename, "duplicateFilename");
_storageProvider.CopyFile(_storageProvider.Combine(currentPath, filename), _storageProvider.Combine(duplicatePath, duplicateFilename));
}
/// <summary>
/// Uploads a media file based on a posted file.
/// </summary>

View File

@@ -68,6 +68,7 @@
</ul>
<div id="media-library-main-selection-actions">
<button id="delete-selection-button">@T("Delete")</button>
<button id="clone-selection-button" data-bind="visible: selection().length == 1">@T("Clone")</button>
</div>
</div>
</header>
@@ -94,9 +95,11 @@ var mediaLibrarySettings = {
importActionUrl: '@HttpUtility.JavaScriptStringEncode(Url.Action("Import", "Admin"))',
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"})',
hasFolderPath: @(viewModel.FolderPath != null ? "true" : "false"),
folderPath: '@HttpUtility.JavaScriptStringEncode(viewModel.FolderPath)',
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)',
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

@@ -268,6 +268,20 @@ namespace Orchard.FileSystems.Media {
File.Move(sourceFileInfo.FullName, targetFileInfo.FullName);
}
public void CopyFile(string originalPath, string duplicatePath) {
FileInfo sourceFileInfo = new FileInfo(MapStorage(originalPath));
if (!sourceFileInfo.Exists) {
throw new ArgumentException(T("File {0} does not exist", originalPath).ToString());
}
FileInfo targetFileInfo = new FileInfo(MapStorage(duplicatePath));
if (targetFileInfo.Exists) {
throw new ArgumentException(T("File {0} already exists", duplicatePath).ToString());
}
File.Copy(sourceFileInfo.FullName, targetFileInfo.FullName);
}
/// <summary>
/// Creates a file in the storage provider.
/// </summary>

View File

@@ -96,6 +96,13 @@ namespace Orchard.FileSystems.Media {
/// <param name="newPath">The relative path to the new file.</param>
void RenameFile(string oldPath, string newPath);
/// <summary>
/// Copies a file in the storage provider.
/// </summary>
/// <param name="originalPath">The relative path to the file to be copied.</param>
/// <param name="duplicatePath">The relative path to the new file.</param>
void CopyFile(string originalPath, string duplicatePath);
/// <summary>
/// Creates a file in the storage provider.
/// </summary>