mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-24 10:11:35 +08:00
Merge branch '1.10.x' into dev
This commit is contained in:
@@ -3,16 +3,19 @@ using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.MetaData;
|
||||
using Orchard.Core.Contents.Settings;
|
||||
using Orchard.Localization;
|
||||
using Orchard.Security;
|
||||
using Orchard.UI.Navigation;
|
||||
|
||||
namespace Orchard.Core.Contents {
|
||||
public class AdminMenu : INavigationProvider {
|
||||
private readonly IContentDefinitionManager _contentDefinitionManager;
|
||||
private readonly IContentManager _contentManager;
|
||||
private readonly IAuthorizer _authorizer;
|
||||
|
||||
public AdminMenu(IContentDefinitionManager contentDefinitionManager, IContentManager contentManager) {
|
||||
public AdminMenu(IContentDefinitionManager contentDefinitionManager, IContentManager contentManager, IAuthorizer authorizer) {
|
||||
_contentDefinitionManager = contentDefinitionManager;
|
||||
_contentManager = contentManager;
|
||||
_authorizer = authorizer;
|
||||
}
|
||||
|
||||
public Localizer T { get; set; }
|
||||
@@ -20,10 +23,17 @@ namespace Orchard.Core.Contents {
|
||||
|
||||
public void GetNavigation(NavigationBuilder builder) {
|
||||
var contentTypeDefinitions = _contentDefinitionManager.ListTypeDefinitions().OrderBy(d => d.Name);
|
||||
builder.AddImageSet("content")
|
||||
.Add(T("Content"), "1.4", menu => menu
|
||||
.Permission(Permissions.EditOwnContent)
|
||||
.Add(T("Content Items"), "1", item => item.Action("List", "Admin", new { area = "Contents", id = "" }).LocalNav()));
|
||||
var listableContentTypes = contentTypeDefinitions.Where(ctd => ctd.Settings.GetModel<ContentTypeSettings>().Listable);
|
||||
ContentItem listableCi = null;
|
||||
foreach(var contentTypeDefinition in listableContentTypes) {
|
||||
listableCi = _contentManager.New(contentTypeDefinition.Name);
|
||||
if(_authorizer.Authorize(Permissions.EditContent, listableCi)) {
|
||||
builder.AddImageSet("content")
|
||||
.Add(T("Content"), "1.4", menu => menu
|
||||
.Add(T("Content Items"), "1", item => item.Action("List", "Admin", new { area = "Contents", id = "" }).LocalNav()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
var contentTypes = contentTypeDefinitions.Where(ctd => ctd.Settings.GetModel<ContentTypeSettings>().Creatable).OrderBy(ctd => ctd.DisplayName);
|
||||
if (contentTypes.Any()) {
|
||||
builder.Add(T("New"), "-1", menu => {
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System.Web.UI.WebControls;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Aspects;
|
||||
using Orchard.Security;
|
||||
using Orchard.Security.Permissions;
|
||||
@@ -13,11 +12,13 @@ namespace Orchard.Blogs.Security {
|
||||
if (!context.Granted &&
|
||||
context.Content.Is<ICommonPart>()) {
|
||||
|
||||
if (context.Permission.Name == Orchard.Core.Contents.Permissions.PublishContent.Name && context.Content.ContentItem.ContentType == "BlogPost") {
|
||||
if (context.Content.ContentItem.ContentType == "BlogPost" &&
|
||||
BlogPostVariationExists(context.Permission)) {
|
||||
context.Adjusted = true;
|
||||
context.Permission = Permissions.PublishBlogPost;
|
||||
context.Permission = GetBlogPostVariation(context.Permission);
|
||||
}
|
||||
else if (OwnerVariationExists(context.Permission) &&
|
||||
|
||||
if (OwnerVariationExists(context.Permission) &&
|
||||
HasOwnership(context.User, context.Content)) {
|
||||
context.Adjusted = true;
|
||||
context.Permission = GetOwnerVariation(context.Permission);
|
||||
@@ -73,5 +74,28 @@ namespace Orchard.Blogs.Security {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static bool BlogPostVariationExists(Permission permission)
|
||||
{
|
||||
return GetBlogPostVariation(permission) != null;
|
||||
}
|
||||
|
||||
private static Permission GetBlogPostVariation(Permission permission)
|
||||
{
|
||||
if (permission.Name == Orchard.Core.Contents.Permissions.PublishContent.Name)
|
||||
return Permissions.PublishBlogPost;
|
||||
if (permission.Name == Orchard.Core.Contents.Permissions.PublishOwnContent.Name)
|
||||
return Permissions.PublishOwnBlogPost;
|
||||
if (permission.Name == Orchard.Core.Contents.Permissions.EditContent.Name)
|
||||
return Permissions.EditBlogPost;
|
||||
if (permission.Name == Orchard.Core.Contents.Permissions.EditOwnContent.Name)
|
||||
return Permissions.EditOwnBlogPost;
|
||||
if (permission.Name == Orchard.Core.Contents.Permissions.DeleteContent.Name)
|
||||
return Permissions.DeleteBlogPost;
|
||||
if (permission.Name == Orchard.Core.Contents.Permissions.DeleteOwnContent.Name)
|
||||
return Permissions.DeleteOwnBlogPost;
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -25,10 +25,12 @@
|
||||
@T(" | ")
|
||||
|
||||
if (contentItem.HasDraft()) {
|
||||
@Html.Link(T("Publish Draft").Text, Url.Action("Publish", "Admin", new { area = "Contents", id = contentItem.Id, returnUrl = Request.ToUrlString() }), new { itemprop = "UnsafeUrl" })
|
||||
@T(" | ")
|
||||
|
||||
if (Authorizer.Authorize(Orchard.Blogs.Permissions.PublishBlogPost, contentItem)) {
|
||||
@Html.Link(T("Publish Draft").Text, Url.Action("Publish", "Admin", new { area = "Contents", id = contentItem.Id, returnUrl = Request.ToUrlString() }), new { itemprop = "UnsafeUrl" })
|
||||
@T(" | ")
|
||||
}
|
||||
|
||||
if (Authorizer.Authorize(Permissions.PreviewContent, contentItem)) {
|
||||
@Html.ActionLink(T("Preview").Text, "Preview", "Item", new { area = "Contents", id = contentItem.Id }, new { })
|
||||
@T(" | ")
|
||||
}
|
||||
@@ -39,9 +41,11 @@
|
||||
@T(" | ")
|
||||
}
|
||||
} else {
|
||||
if (contentItem.HasDraft()) {
|
||||
@Html.ActionLink(T("Preview").Text, "Preview", "Item", new { area = "Contents", id = contentItem.Id }, new { })
|
||||
@T(" | ")
|
||||
if (contentItem.HasDraft()) {
|
||||
if (Authorizer.Authorize(Permissions.PreviewContent, contentItem)) {
|
||||
@Html.ActionLink(T("Preview").Text, "Preview", "Item", new { area = "Contents", id = contentItem.Id }, new { })
|
||||
@T(" | ")
|
||||
}
|
||||
}
|
||||
|
||||
if (Authorizer.Authorize(Orchard.Blogs.Permissions.PublishBlogPost, contentItem)) {
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace Orchard.DesignerTools.Controllers {
|
||||
|
||||
alternate = alternate.Replace("__", "-").Replace("_", ".");
|
||||
|
||||
var currentTheme = _themeManager.GetRequestTheme(Request.RequestContext);
|
||||
var currentTheme = Services.WorkContext.CurrentTheme;
|
||||
var alternateFilename = Server.MapPath(Path.Combine(currentTheme.Location, currentTheme.Id, "Views", alternate));
|
||||
var isCodeTemplate = template.Contains("::");
|
||||
|
||||
|
||||
@@ -19,7 +19,6 @@ namespace Orchard.DesignerTools.Services {
|
||||
public class ShapeTracingFactory : IShapeFactoryEvents, IShapeDisplayEvents {
|
||||
private readonly WorkContext _workContext;
|
||||
private readonly IShapeTableManager _shapeTableManager;
|
||||
private readonly IThemeManager _themeManager;
|
||||
private readonly IWebSiteFolder _webSiteFolder;
|
||||
private readonly IAuthorizer _authorizer;
|
||||
private bool _processing;
|
||||
@@ -28,14 +27,12 @@ namespace Orchard.DesignerTools.Services {
|
||||
|
||||
public ShapeTracingFactory(
|
||||
IWorkContextAccessor workContextAccessor,
|
||||
IShapeTableManager shapeTableManager,
|
||||
IThemeManager themeManager,
|
||||
IShapeTableManager shapeTableManager,
|
||||
IWebSiteFolder webSiteFolder,
|
||||
IAuthorizer authorizer
|
||||
) {
|
||||
_workContext = workContextAccessor.GetContext();
|
||||
_shapeTableManager = shapeTableManager;
|
||||
_themeManager = themeManager;
|
||||
_webSiteFolder = webSiteFolder;
|
||||
_authorizer = authorizer;
|
||||
}
|
||||
@@ -103,7 +100,7 @@ namespace Orchard.DesignerTools.Services {
|
||||
|
||||
var shape = context.Shape;
|
||||
var shapeMetadata = (ShapeMetadata) context.Shape.Metadata;
|
||||
var currentTheme = _themeManager.GetRequestTheme(_workContext.HttpContext.Request.RequestContext);
|
||||
var currentTheme = _workContext.CurrentTheme;
|
||||
var shapeTable = _shapeTableManager.GetShapeTable(currentTheme.Id);
|
||||
|
||||
if (!shapeMetadata.Wrappers.Contains("ShapeTracingWrapper")) {
|
||||
|
||||
@@ -163,8 +163,8 @@ namespace Orchard.DynamicForms.Drivers {
|
||||
|
||||
var projection = terms.Select(x => {
|
||||
var data = new {Content = x};
|
||||
var value = _tokenizer.Replace(valueExpression, data);
|
||||
var text = _tokenizer.Replace(textExpression, data);
|
||||
var value = _tokenizer.Replace(valueExpression, data, new ReplaceOptions { Encoding = ReplaceOptions.NoEncode });
|
||||
var text = _tokenizer.Replace(textExpression, data, new ReplaceOptions { Encoding = ReplaceOptions.NoEncode });
|
||||
|
||||
return new SelectListItem {
|
||||
Text = text,
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
using System.Linq;
|
||||
using System.Web.Mvc;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.DisplayManagement;
|
||||
using Orchard.Environment.Extensions;
|
||||
using Orchard.Localization;
|
||||
using Orchard.JobsQueue.Models;
|
||||
using System.Linq;
|
||||
using System.Web.Mvc;
|
||||
using Orchard.JobsQueue.Services;
|
||||
using Orchard.Localization;
|
||||
using Orchard.Mvc;
|
||||
using Orchard.UI.Admin;
|
||||
using Orchard.UI.Navigation;
|
||||
@@ -20,9 +20,9 @@ namespace Orchard.JobsQueue.Controllers {
|
||||
private readonly IJobsQueueProcessor _jobsQueueProcessor;
|
||||
|
||||
public AdminController(
|
||||
IJobsQueueManager jobsQueueManager,
|
||||
IJobsQueueManager jobsQueueManager,
|
||||
IShapeFactory shapeFactory,
|
||||
IOrchardServices services,
|
||||
IOrchardServices services,
|
||||
IJobsQueueProcessor jobsQueueProcessor) {
|
||||
_jobsQueueManager = jobsQueueManager;
|
||||
_services = services;
|
||||
@@ -43,7 +43,7 @@ namespace Orchard.JobsQueue.Controllers {
|
||||
return View(model);
|
||||
}
|
||||
|
||||
public ActionResult List(PagerParameters pagerParameters) {
|
||||
public ActionResult List(PagerParameters pagerParameters, bool processQueue = false) {
|
||||
var pager = new Pager(_services.WorkContext.CurrentSite, pagerParameters);
|
||||
|
||||
var jobsCount = _jobsQueueManager.GetJobsCount();
|
||||
@@ -52,6 +52,7 @@ namespace Orchard.JobsQueue.Controllers {
|
||||
.Pager(_services.New.Pager(pager).TotalItemCount(jobsCount))
|
||||
.JobsQueueStatus(_services.WorkContext.CurrentSite.As<JobsQueueSettingsPart>().Status)
|
||||
.Jobs(jobs)
|
||||
.ProcessQueue(processQueue)
|
||||
;
|
||||
|
||||
return View(model);
|
||||
@@ -82,10 +83,17 @@ namespace Orchard.JobsQueue.Controllers {
|
||||
[HttpPost, ActionName("List")]
|
||||
[FormValueRequired("submit.Process")]
|
||||
public ActionResult Process() {
|
||||
_jobsQueueProcessor.ProcessQueue();
|
||||
_services.Notifier.Information(T("Processing has started."));
|
||||
return RedirectToAction("List");
|
||||
}
|
||||
var processQueue = false;
|
||||
if (_jobsQueueManager.GetJobsCount() > 0) {
|
||||
_services.Notifier.Information(T("Processing is in progress."));
|
||||
processQueue = true;
|
||||
_jobsQueueProcessor.ProcessQueue(10, 1);
|
||||
}
|
||||
else {
|
||||
_services.Notifier.Information(T("Processing has been completed."));
|
||||
}
|
||||
|
||||
return RedirectToAction("List", new { processQueue });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
namespace Orchard.JobsQueue.Services {
|
||||
public interface IJobsQueueProcessor : ISingletonDependency {
|
||||
void ProcessQueue();
|
||||
void ProcessQueue(int batchSize, uint batchCount);
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,7 @@ namespace Orchard.JobsQueue.Services {
|
||||
}
|
||||
|
||||
public void Sweep() {
|
||||
_jobsQueueProcessor.ProcessQueue();
|
||||
_jobsQueueProcessor.ProcessQueue(10, uint.MaxValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,59 +7,66 @@ using Orchard.Events;
|
||||
using Orchard.JobsQueue.Models;
|
||||
using Orchard.Logging;
|
||||
using Orchard.Tasks.Locking.Services;
|
||||
using Orchard.Data;
|
||||
|
||||
namespace Orchard.JobsQueue.Services {
|
||||
public class JobsQueueProcessor : IJobsQueueProcessor {
|
||||
private readonly Work<IJobsQueueManager> _jobsQueueManager;
|
||||
private readonly Work<IEventBus> _eventBus;
|
||||
private readonly Work<IDistributedLockService> _distributedLockService;
|
||||
private readonly Work<ITransactionManager> _transactionManager;
|
||||
|
||||
public JobsQueueProcessor(
|
||||
Work<IJobsQueueManager> jobsQueueManager,
|
||||
Work<IEventBus> eventBus,
|
||||
Work<IDistributedLockService> distributedLockService) {
|
||||
Work<IDistributedLockService> distributedLockService,
|
||||
Work<ITransactionManager> transactionManager) {
|
||||
|
||||
_jobsQueueManager = jobsQueueManager;
|
||||
_eventBus = eventBus;
|
||||
_distributedLockService = distributedLockService;
|
||||
_transactionManager = transactionManager;
|
||||
Logger = NullLogger.Instance;
|
||||
}
|
||||
|
||||
public ILogger Logger { get; set; }
|
||||
|
||||
public void ProcessQueue() {
|
||||
public void ProcessQueue(int batchSize, uint batchCount) {
|
||||
IDistributedLock @lock;
|
||||
if (_distributedLockService.Value.TryAcquireLock(GetType().FullName, TimeSpan.FromMinutes(5), out @lock)) {
|
||||
using (@lock) {
|
||||
IEnumerable<QueuedJobRecord> messages;
|
||||
|
||||
while ((messages = _jobsQueueManager.Value.GetJobs(0, 10).ToArray()).Any()) {
|
||||
var currentBatch = 0;
|
||||
while (batchCount > currentBatch && (messages = _jobsQueueManager.Value.GetJobs(0, batchSize).ToArray()).Any()) {
|
||||
foreach (var message in messages) {
|
||||
ProcessMessage(message);
|
||||
}
|
||||
|
||||
currentBatch++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ProcessMessage(QueuedJobRecord job) {
|
||||
|
||||
Logger.Debug("Processing job {0}.", job.Id);
|
||||
|
||||
_transactionManager.Value.RequireNew();
|
||||
|
||||
try {
|
||||
var payload = JObject.Parse(job.Parameters);
|
||||
var parameters = payload.ToDictionary();
|
||||
|
||||
_eventBus.Value.Notify(job.Message, parameters);
|
||||
|
||||
_jobsQueueManager.Value.Delete(job);
|
||||
|
||||
Logger.Debug("Processed job Id {0}.", job.Id);
|
||||
}
|
||||
catch (Exception e) {
|
||||
_transactionManager.Value.Cancel();
|
||||
Logger.Error(e, "An unexpected error while processing job {0}. Error message: {1}.", job.Id, e);
|
||||
}
|
||||
finally {
|
||||
_jobsQueueManager.Value.Delete(job);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
Layout.Title = T("Jobs Queue");
|
||||
Style.Include("admin-jobsqueue.css");
|
||||
Script.Require("jQuery");
|
||||
}
|
||||
@using (Html.BeginFormAntiForgeryPost()) {
|
||||
<div class="manage">
|
||||
@@ -62,4 +63,14 @@ else {
|
||||
</table>
|
||||
}
|
||||
@Display(Model.Pager)
|
||||
}
|
||||
|
||||
@if (Model.ProcessQueue) {
|
||||
using (Script.Foot()) {
|
||||
<script type="text/javascript">
|
||||
$(function () {
|
||||
$("[name='submit.Process']").trigger("click");
|
||||
});
|
||||
</script>
|
||||
}
|
||||
}
|
||||
@@ -83,11 +83,6 @@ namespace Orchard.MediaLibrary.Controllers {
|
||||
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");
|
||||
|
||||
@@ -98,12 +93,23 @@ namespace Orchard.MediaLibrary.Controllers {
|
||||
MediaTypes = _mediaLibraryService.GetMediaTypes(),
|
||||
};
|
||||
|
||||
if (replaceId != null) {
|
||||
if (replaceId.HasValue) {
|
||||
var replaceMedia = Services.ContentManager.Get(replaceId.Value).As<MediaPart>();
|
||||
if (replaceMedia == null)
|
||||
return HttpNotFound();
|
||||
|
||||
// Check permission
|
||||
if (!Services.Authorizer.Authorize(Permissions.ManageMediaContent) && !_mediaLibraryService.CanManageMediaFolder(replaceMedia.FolderPath)) {
|
||||
return new HttpUnauthorizedResult();
|
||||
}
|
||||
|
||||
viewModel.Replace = replaceMedia;
|
||||
viewModel.FolderPath = replaceMedia.FolderPath;
|
||||
} else {
|
||||
// Check permission
|
||||
if (!Services.Authorizer.Authorize(Permissions.ManageMediaContent) && !_mediaLibraryService.CanManageMediaFolder(folderPath)) {
|
||||
return new HttpUnauthorizedResult();
|
||||
}
|
||||
}
|
||||
|
||||
return View(viewModel);
|
||||
|
||||
@@ -293,7 +293,7 @@ namespace Orchard.OutputCache.Filters {
|
||||
var action = filterContext.ActionDescriptor.ActionName;
|
||||
var culture = _workContext.CurrentCulture.ToLowerInvariant();
|
||||
var auth = filterContext.HttpContext.User.Identity.IsAuthenticated.ToString().ToLowerInvariant();
|
||||
var theme = _themeManager.GetRequestTheme(filterContext.RequestContext).Id.ToLowerInvariant();
|
||||
var theme = _workContext.CurrentTheme.Id.ToLowerInvariant();
|
||||
|
||||
itemDescriptor = string.Format("{0} (Area: {1}, Controller: {2}, Action: {3}, Culture: {4}, Theme: {5}, Auth: {6})", url, area, controller, action, culture, theme, auth);
|
||||
}
|
||||
@@ -383,7 +383,7 @@ namespace Orchard.OutputCache.Filters {
|
||||
result.Add("scheme", filterContext.RequestContext.HttpContext.Request.Url.Scheme);
|
||||
|
||||
// Vary by theme.
|
||||
result.Add("theme", _themeManager.GetRequestTheme(filterContext.RequestContext).Id.ToLowerInvariant());
|
||||
result.Add("theme", _workContext.CurrentTheme.Id.ToLowerInvariant());
|
||||
|
||||
// Vary by configured query string parameters.
|
||||
var queryString = filterContext.RequestContext.HttpContext.Request.QueryString;
|
||||
|
||||
@@ -17,11 +17,13 @@ namespace Orchard.OutputCache.Services {
|
||||
var key = shellSettings.Name + ":TagCache";
|
||||
var workContext = workContextAccessor.GetContext();
|
||||
|
||||
_dictionary = workContext.HttpContext.Cache.Get(key) as ConcurrentDictionary<string, HashSet<string>>;
|
||||
if ( workContext != null ) {
|
||||
_dictionary = workContext.HttpContext.Cache.Get(key) as ConcurrentDictionary<string, HashSet<string>>;
|
||||
|
||||
if (_dictionary == null) {
|
||||
_dictionary = new ConcurrentDictionary<string, HashSet<string>>(StringComparer.OrdinalIgnoreCase);
|
||||
workContext.HttpContext.Cache.Add(key, _dictionary, null, Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, CacheItemPriority.Normal, null);
|
||||
if ( _dictionary == null ) {
|
||||
_dictionary = new ConcurrentDictionary<string, HashSet<string>>(StringComparer.OrdinalIgnoreCase);
|
||||
workContext.HttpContext.Cache.Add(key, _dictionary, null, Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, CacheItemPriority.Normal, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -183,13 +183,15 @@ Aliquam vel sem nibh. Suspendisse vel condimentum tellus.</p>").Text;
|
||||
}
|
||||
else {
|
||||
if (!String.IsNullOrEmpty(Text)) {
|
||||
layout =
|
||||
"{\"elements\": [" +
|
||||
"{" +
|
||||
"\"typeName\": \"Orchard.Layouts.Elements.Html\"," +
|
||||
"\"data\": \"Content=" + Encode(Text) + "\"" +
|
||||
"}" +
|
||||
"]}";
|
||||
layout = @"{
|
||||
'elements': [{
|
||||
'typeName': 'Orchard.Layouts.Elements.Canvas',
|
||||
'elements': [{
|
||||
'typeName': 'Orchard.Layouts.Elements.Html',
|
||||
'data': 'Content=" + Encode(Text) + @"'
|
||||
}]
|
||||
}]
|
||||
}";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -216,4 +218,4 @@ Aliquam vel sem nibh. Suspendisse vel condimentum tellus.</p>").Text;
|
||||
return HttpUtility.UrlEncode(text);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace Orchard.Roles.Activities {
|
||||
}
|
||||
|
||||
public override LocalizedString Description {
|
||||
get { return T("Assign specific roles to the current content item if it's a user."); }
|
||||
get { return T("Assign specific roles to the current content item if it's a user."); }
|
||||
}
|
||||
|
||||
public override string Form {
|
||||
@@ -49,7 +49,7 @@ namespace Orchard.Roles.Activities {
|
||||
}
|
||||
|
||||
public override IEnumerable<LocalizedString> GetPossibleOutcomes(WorkflowContext workflowContext, ActivityContext activityContext) {
|
||||
return new[] {T("Done")};
|
||||
return new[] { T("Done") };
|
||||
}
|
||||
|
||||
public override IEnumerable<LocalizedString> Execute(WorkflowContext workflowContext, ActivityContext activityContext) {
|
||||
@@ -59,7 +59,7 @@ namespace Orchard.Roles.Activities {
|
||||
if (user == null) {
|
||||
user = _workContextAccessor.GetContext().CurrentUser.As<IUserRoles>();
|
||||
}
|
||||
|
||||
|
||||
var roles = GetRoles(activityContext);
|
||||
|
||||
if (user != null) {
|
||||
@@ -67,7 +67,7 @@ namespace Orchard.Roles.Activities {
|
||||
if (!user.Roles.Contains(role)) {
|
||||
var roleRecord = _roleService.GetRoleByName(role);
|
||||
if (roleRecord != null) {
|
||||
_repository.Create(new UserRolesPartRecord {UserId = user.Id, Role = roleRecord});
|
||||
_repository.Create(new UserRolesPartRecord { UserId = user.Id, Role = roleRecord });
|
||||
}
|
||||
else {
|
||||
Logger.Debug("Role not found: {0}", role);
|
||||
@@ -78,7 +78,7 @@ namespace Orchard.Roles.Activities {
|
||||
|
||||
yield return T("Done");
|
||||
}
|
||||
|
||||
|
||||
private IEnumerable<string> GetRoles(ActivityContext context) {
|
||||
var roles = context.GetState<string>("Roles");
|
||||
|
||||
@@ -86,7 +86,8 @@ namespace Orchard.Roles.Activities {
|
||||
return Enumerable.Empty<string>();
|
||||
}
|
||||
|
||||
return roles.Split(new [] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim()).ToList();
|
||||
return roles.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim()).ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.Data;
|
||||
using Orchard.Environment.Extensions;
|
||||
using Orchard.Localization;
|
||||
using Orchard.Logging;
|
||||
using Orchard.Roles.Models;
|
||||
using Orchard.Roles.Services;
|
||||
using Orchard.Workflows.Models;
|
||||
using Orchard.Workflows.Services;
|
||||
|
||||
namespace Orchard.Roles.Activities {
|
||||
[OrchardFeature("Orchard.Roles.Workflows")]
|
||||
public class UnssignRoleActivity : Task {
|
||||
private readonly IWorkContextAccessor _workContextAccessor;
|
||||
private readonly IRepository<UserRolesPartRecord> _repository;
|
||||
private readonly IRoleService _roleService;
|
||||
|
||||
public UnssignRoleActivity(
|
||||
IWorkContextAccessor workContextAccessor,
|
||||
IRepository<UserRolesPartRecord> repository,
|
||||
IRoleService roleService) {
|
||||
_workContextAccessor = workContextAccessor;
|
||||
_repository = repository;
|
||||
_roleService = roleService;
|
||||
T = NullLocalizer.Instance;
|
||||
Logger = NullLogger.Instance;
|
||||
}
|
||||
|
||||
public Localizer T { get; set; }
|
||||
public ILogger Logger { get; set; }
|
||||
|
||||
public override string Name {
|
||||
get { return "UnassignRole"; }
|
||||
}
|
||||
|
||||
public override LocalizedString Category {
|
||||
get { return T("User"); }
|
||||
}
|
||||
|
||||
public override LocalizedString Description {
|
||||
get { return T("Unassign specific roles from the current content item if it's a user."); }
|
||||
}
|
||||
|
||||
public override string Form {
|
||||
get { return "SelectRoles"; }
|
||||
}
|
||||
|
||||
public override IEnumerable<LocalizedString> GetPossibleOutcomes(WorkflowContext workflowContext, ActivityContext activityContext) {
|
||||
return new[] { T("Done") };
|
||||
}
|
||||
|
||||
public override IEnumerable<LocalizedString> Execute(WorkflowContext workflowContext, ActivityContext activityContext) {
|
||||
var user = workflowContext.Content.As<IUserRoles>();
|
||||
|
||||
// if the current workflow subject is not a user, use current user
|
||||
if (user == null) {
|
||||
user = _workContextAccessor.GetContext().CurrentUser.As<IUserRoles>();
|
||||
}
|
||||
|
||||
var roles = GetRoles(activityContext);
|
||||
|
||||
if (user != null) {
|
||||
foreach (var role in roles) {
|
||||
if (user.Roles.Contains(role)) {
|
||||
var roleRecord = _roleService.GetRoleByName(role);
|
||||
if (roleRecord != null) {
|
||||
var currentUserRoleRecord = _repository.Fetch(x => x.UserId == user.Id && x.Role.Id == roleRecord.Id).SingleOrDefault();
|
||||
if (currentUserRoleRecord != null) {
|
||||
_repository.Delete(currentUserRoleRecord);
|
||||
}
|
||||
}
|
||||
else {
|
||||
Logger.Debug("Role not found: {0}", role);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
yield return T("Done");
|
||||
}
|
||||
|
||||
private IEnumerable<string> GetRoles(ActivityContext context) {
|
||||
var roles = context.GetState<string>("Roles");
|
||||
|
||||
if (String.IsNullOrEmpty(roles)) {
|
||||
return Enumerable.Empty<string>();
|
||||
}
|
||||
|
||||
return roles.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim()).ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -90,6 +90,7 @@
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Activities\UnassignRoleActivity.cs" />
|
||||
<Compile Include="Activities\AssignRoleActivity.cs" />
|
||||
<Compile Include="Activities\IsInRoleActivity.cs" />
|
||||
<Compile Include="Activities\UserTaskActivity.cs" />
|
||||
@@ -137,6 +138,7 @@
|
||||
<ItemGroup>
|
||||
<Content Include="Module.txt" />
|
||||
<Content Include="Styles\admin-usertask.css" />
|
||||
<Content Include="Styles\workflows-activity-unassign-role.css" />
|
||||
<Content Include="Styles\workflows-activity-assign-role.css" />
|
||||
<Content Include="Styles\workflows-activity-isinrole.css" />
|
||||
<Content Include="Styles\workflows-activity-usertask.css" />
|
||||
@@ -195,6 +197,9 @@
|
||||
<ItemGroup>
|
||||
<Content Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Views\Activity-UnassignRole.cshtml" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup>
|
||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
|
||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
activity-unassign-role {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4AsSDQYi3LJqFgAAAaRJREFUWMPtl7tKA1EQhr9dNIhXVETEylthYyEknYWCYKeFzyNEwRQ+ggipBAkEawsL9REsbARBEnRjTGGhlbGZyHo4N+OJF/CHIZvzzz+ZzM6Zswv/0KMbKAA3YgVZC8U7UQCaiu0G5J2oagJUA/LviA0JRJq1jINPo8f3n5oSKGrWDhx80eBr0zibMAEawJ6hyRIxtckyomkY+N+JTeBO0zwTDl61CrAumkkH/wH3hoAuXme3KZ2VjxRH245ofrKikU/c+Kfv+48n0NXB2M0/UYHQCSRAHsgB42I5YAeo+ZTMtg1dW+8Q6LPE7weOUv4zuuxtCSSWHy9ZDqhIuS6L5tx3Err4GjDoMQ9aGAbqol32uRVjDn7LcyClkRftvk8CJWkmE7/QRgKLor0K0YwDnk2ajjMk10/xdw0cBa8tbYgEplOl1lmsfAeYk89KiAQ22tC0ngfOQvTAV7bhSqiJ2M4gOg09ksvAiKUSo8Cx+NaB2U6cCXUZMlmgVywLbAOP4vMALIU+VeeBC48ZcAJMdfJ4X5MXkEvgGXgBruVFZVUneAM9RhZRUdfKzwAAAABJRU5ErkJggg==');
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
}
|
||||
|
||||
.toolbox-task.toolbox-unassign-role {
|
||||
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4AsSDQYi3LJqFgAAAaRJREFUWMPtl7tKA1EQhr9dNIhXVETEylthYyEknYWCYKeFzyNEwRQ+ggipBAkEawsL9REsbARBEnRjTGGhlbGZyHo4N+OJF/CHIZvzzz+ZzM6Zswv/0KMbKAA3YgVZC8U7UQCaiu0G5J2oagJUA/LviA0JRJq1jINPo8f3n5oSKGrWDhx80eBr0zibMAEawJ6hyRIxtckyomkY+N+JTeBO0zwTDl61CrAumkkH/wH3hoAuXme3KZ2VjxRH245ofrKikU/c+Kfv+48n0NXB2M0/UYHQCSRAHsgB42I5YAeo+ZTMtg1dW+8Q6LPE7weOUv4zuuxtCSSWHy9ZDqhIuS6L5tx3Err4GjDoMQ9aGAbqol32uRVjDn7LcyClkRftvk8CJWkmE7/QRgKLor0K0YwDnk2ajjMk10/xdw0cBa8tbYgEplOl1lmsfAeYk89KiAQ22tC0ngfOQvTAV7bhSqiJ2M4gOg09ksvAiKUSo8Cx+NaB2U6cCXUZMlmgVywLbAOP4vMALIU+VeeBC48ZcAJMdfJ4X5MXkEvgGXgBruVFZVUneAM9RhZRUdfKzwAAAABJRU5ErkJggg==');
|
||||
background-repeat: no-repeat;
|
||||
background-position: 6px 10px;
|
||||
}
|
||||
|
||||
.toolbox-task.toolbox-unassign-role div {
|
||||
margin-left: 36px;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
@{
|
||||
var rolesData = (string)Model.State.Roles;
|
||||
var roles = !String.IsNullOrWhiteSpace(rolesData) ? rolesData.Split(',') : Enumerable.Empty<string>();
|
||||
var description = roles.Any() ? T("Unassign roles: {0}", String.Join(", ", roles)) : T("No roles specified");
|
||||
}
|
||||
|
||||
<div class="activity-unassign-role" title="@description">
|
||||
</div>
|
||||
@@ -1,17 +1,28 @@
|
||||
using Orchard.Localization;
|
||||
using Orchard.Security;
|
||||
using Orchard.UI.Navigation;
|
||||
|
||||
namespace Orchard.Taxonomies {
|
||||
public class AdminMenu : INavigationProvider {
|
||||
private readonly IOrchardServices _services;
|
||||
public AdminMenu(IOrchardServices services) {
|
||||
_services = services;
|
||||
}
|
||||
public Localizer T { get; set; }
|
||||
public string MenuName { get { return "admin"; } }
|
||||
|
||||
public void GetNavigation(NavigationBuilder builder) {
|
||||
builder
|
||||
.AddImageSet("taxonomies")
|
||||
.Add(T("Taxonomies"), "4", menu => menu
|
||||
.Add(T("Manage Taxonomies"), "1.0", item => item.Action("Index", "Admin", new { area = "Orchard.Taxonomies" }).Permission(Permissions.ManageTaxonomies))
|
||||
);
|
||||
.Add(T("Taxonomies"), "4", BuildMenu);
|
||||
}
|
||||
|
||||
private void BuildMenu(NavigationItemBuilder menu) {
|
||||
|
||||
if (_services.Authorizer.Authorize(Permissions.MergeTerms) || _services.Authorizer.Authorize(Permissions.EditTerm) || _services.Authorizer.Authorize(Permissions.CreateTerm) || _services.Authorizer.Authorize(Permissions.DeleteTerm)) {
|
||||
menu.Add(T("Manage Taxonomies"), "1.0", item => item.Action("Index", "Admin", new { area = "Orchard.Taxonomies" }));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -12,6 +12,14 @@ using Orchard.Taxonomies.Services;
|
||||
using Orchard.UI.Navigation;
|
||||
using Orchard.UI.Notify;
|
||||
using Orchard.DisplayManagement;
|
||||
using Orchard.ContentManagement.MetaData;
|
||||
using Orchard.Data;
|
||||
using Orchard.ContentManagement.Aspects;
|
||||
using Orchard.Core.Contents.Settings;
|
||||
using Orchard.Mvc.Html;
|
||||
using Orchard.Utility.Extensions;
|
||||
using Orchard.Mvc.Extensions;
|
||||
using System.Web.Routing;
|
||||
|
||||
namespace Orchard.Taxonomies.Controllers {
|
||||
|
||||
@@ -19,16 +27,24 @@ namespace Orchard.Taxonomies.Controllers {
|
||||
public class AdminController : Controller, IUpdateModel {
|
||||
private readonly ITaxonomyService _taxonomyService;
|
||||
private readonly ISiteService _siteService;
|
||||
|
||||
private readonly IContentDefinitionManager _contentDefinitionManager;
|
||||
private readonly ITransactionManager _transactionManager;
|
||||
private readonly IContentManager _contentManager;
|
||||
private string contentType = "Taxonomy";
|
||||
public AdminController(
|
||||
IOrchardServices services,
|
||||
IContentManager contentManager,
|
||||
IContentDefinitionManager contentDefinitionManager,
|
||||
ITransactionManager transactionManager,
|
||||
ITaxonomyService taxonomyService,
|
||||
ISiteService siteService,
|
||||
IShapeFactory shapeFactory) {
|
||||
Services = services;
|
||||
_siteService = siteService;
|
||||
_taxonomyService = taxonomyService;
|
||||
|
||||
_contentDefinitionManager = contentDefinitionManager;
|
||||
_transactionManager = transactionManager;
|
||||
_contentManager = contentManager;
|
||||
T = NullLocalizer.Instance;
|
||||
Shape = shapeFactory;
|
||||
}
|
||||
@@ -83,6 +99,142 @@ namespace Orchard.Taxonomies.Controllers {
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
|
||||
|
||||
public ActionResult Create() {
|
||||
var contentItem = _contentManager.New(contentType);
|
||||
|
||||
if (!Services.Authorizer.Authorize(Permissions.CreateTaxonomy, contentItem, T("Cannot create taxonomies")))
|
||||
return new HttpUnauthorizedResult();
|
||||
var model = _contentManager.BuildEditor(contentItem);
|
||||
return View(model);
|
||||
}
|
||||
|
||||
[HttpPost, ActionName("Create")]
|
||||
[Mvc.FormValueRequired("submit.Save")]
|
||||
public ActionResult CreatePOST(string returnUrl) {
|
||||
return CreatePOST(returnUrl, contentItem => {
|
||||
if (!contentItem.Has<IPublishingControlAspect>() && !contentItem.TypeDefinition.Settings.GetModel<ContentTypeSettings>().Draftable)
|
||||
_contentManager.Publish(contentItem);
|
||||
});
|
||||
}
|
||||
|
||||
[HttpPost, ActionName("Create")]
|
||||
[Mvc.FormValueRequired("submit.Publish")]
|
||||
public ActionResult CreateAndPublishPOST(string returnUrl) {
|
||||
|
||||
// pass a dummy content to the authorization check to check for "own" variations
|
||||
var dummyContent = _contentManager.New(contentType);
|
||||
|
||||
if (!Services.Authorizer.Authorize(Permissions.CreateTaxonomy, dummyContent, T("Couldn't create taxonomies")))
|
||||
return new HttpUnauthorizedResult();
|
||||
|
||||
return CreatePOST(returnUrl, contentItem => _contentManager.Publish(contentItem));
|
||||
}
|
||||
|
||||
private ActionResult CreatePOST(string returnUrl, Action<ContentItem> conditionallyPublish) {
|
||||
var contentItem = _contentManager.New(contentType);
|
||||
|
||||
if (!Services.Authorizer.Authorize(Permissions.CreateTaxonomy, contentItem, T("Couldn't create taxonomies")))
|
||||
return new HttpUnauthorizedResult();
|
||||
|
||||
_contentManager.Create(contentItem, VersionOptions.Draft);
|
||||
|
||||
var model = _contentManager.UpdateEditor(contentItem, this);
|
||||
|
||||
if (!ModelState.IsValid) {
|
||||
_transactionManager.Cancel();
|
||||
return View(model);
|
||||
}
|
||||
|
||||
conditionallyPublish(contentItem);
|
||||
|
||||
Services.Notifier.Information(string.IsNullOrWhiteSpace(contentItem.TypeDefinition.DisplayName)
|
||||
? T("Your content has been created.")
|
||||
: T("Your {0} has been created.", contentItem.TypeDefinition.DisplayName));
|
||||
if (!string.IsNullOrEmpty(returnUrl)) {
|
||||
return this.RedirectLocal(returnUrl);
|
||||
}
|
||||
var adminRouteValues = _contentManager.GetItemMetadata(contentItem).AdminRouteValues;
|
||||
return RedirectToRoute(adminRouteValues);
|
||||
}
|
||||
|
||||
public ActionResult Edit(int id) {
|
||||
var contentItem = _contentManager.Get(id, VersionOptions.Latest);
|
||||
|
||||
if (contentItem == null)
|
||||
return HttpNotFound();
|
||||
|
||||
if (!Services.Authorizer.Authorize(Permissions.CreateTaxonomy, contentItem, T("Cannot edit content")))
|
||||
return new HttpUnauthorizedResult();
|
||||
|
||||
var model = _contentManager.BuildEditor(contentItem);
|
||||
return View(model);
|
||||
}
|
||||
|
||||
[HttpPost, ActionName("Edit")]
|
||||
[Mvc.FormValueRequired("submit.Save")]
|
||||
public ActionResult EditPOST(int id, string returnUrl) {
|
||||
return EditPOST(id, returnUrl, contentItem => {
|
||||
if (!contentItem.Has<IPublishingControlAspect>() && !contentItem.TypeDefinition.Settings.GetModel<ContentTypeSettings>().Draftable)
|
||||
_contentManager.Publish(contentItem);
|
||||
});
|
||||
}
|
||||
|
||||
[HttpPost, ActionName("Edit")]
|
||||
[Mvc.FormValueRequired("submit.Publish")]
|
||||
public ActionResult EditAndPublishPOST(int id, string returnUrl) {
|
||||
var content = _contentManager.Get(id, VersionOptions.Latest);
|
||||
|
||||
if (content == null)
|
||||
return HttpNotFound();
|
||||
|
||||
if (!Services.Authorizer.Authorize(Permissions.CreateTaxonomy, content, T("Couldn't publish content")))
|
||||
return new HttpUnauthorizedResult();
|
||||
|
||||
return EditPOST(id, returnUrl, contentItem => _contentManager.Publish(contentItem));
|
||||
}
|
||||
|
||||
private ActionResult EditPOST(int id, string returnUrl, Action<ContentItem> conditionallyPublish) {
|
||||
var contentItem = _contentManager.Get(id, VersionOptions.DraftRequired);
|
||||
|
||||
if (contentItem == null)
|
||||
return HttpNotFound();
|
||||
|
||||
if (!Services.Authorizer.Authorize(Permissions.CreateTaxonomy, contentItem, T("Couldn't edit content")))
|
||||
return new HttpUnauthorizedResult();
|
||||
|
||||
string previousRoute = null;
|
||||
if (contentItem.Has<IAliasAspect>()
|
||||
&& !string.IsNullOrWhiteSpace(returnUrl)
|
||||
&& Request.IsLocalUrl(returnUrl)
|
||||
// only if the original returnUrl is the content itself
|
||||
&& String.Equals(returnUrl, Url.ItemDisplayUrl(contentItem), StringComparison.OrdinalIgnoreCase)
|
||||
) {
|
||||
previousRoute = contentItem.As<IAliasAspect>().Path;
|
||||
}
|
||||
|
||||
var model = _contentManager.UpdateEditor(contentItem, this);
|
||||
if (!ModelState.IsValid) {
|
||||
_transactionManager.Cancel();
|
||||
return View("Edit", model);
|
||||
}
|
||||
|
||||
conditionallyPublish(contentItem);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(returnUrl)
|
||||
&& previousRoute != null
|
||||
&& !String.Equals(contentItem.As<IAliasAspect>().Path, previousRoute, StringComparison.OrdinalIgnoreCase)) {
|
||||
returnUrl = Url.ItemDisplayUrl(contentItem);
|
||||
}
|
||||
|
||||
Services.Notifier.Information(string.IsNullOrWhiteSpace(contentItem.TypeDefinition.DisplayName)
|
||||
? T("Your content has been saved.")
|
||||
: T("Your {0} has been saved.", contentItem.TypeDefinition.DisplayName));
|
||||
|
||||
return this.RedirectLocal(returnUrl, () => RedirectToAction("Edit", new RouteValueDictionary { { "Id", contentItem.Id } }));
|
||||
}
|
||||
|
||||
|
||||
[HttpPost]
|
||||
public ActionResult Delete(int id) {
|
||||
if (!Services.Authorizer.Authorize(Permissions.ManageTaxonomies, T("Couldn't delete taxonomy")))
|
||||
|
||||
@@ -76,7 +76,7 @@ namespace Orchard.Taxonomies.Controllers {
|
||||
Services.Notifier.Information(T("No action selected."));
|
||||
break;
|
||||
case TermsAdminIndexBulkAction.Delete:
|
||||
if (!Services.Authorizer.Authorize(Permissions.ManageTerms, T("Couldn't delete term")))
|
||||
if (!Services.Authorizer.Authorize(Permissions.DeleteTerm, T("Couldn't delete term")))
|
||||
return new HttpUnauthorizedResult();
|
||||
|
||||
if(!checkedEntries.Any()) {
|
||||
@@ -93,7 +93,7 @@ namespace Orchard.Taxonomies.Controllers {
|
||||
|
||||
break;
|
||||
case TermsAdminIndexBulkAction.Merge:
|
||||
if (!Services.Authorizer.Authorize(Permissions.ManageTerms, T("Couldn't delete term")))
|
||||
if (!Services.Authorizer.Authorize(Permissions.ManageTerms, T("Couldn't merge term")))
|
||||
return new HttpUnauthorizedResult();
|
||||
|
||||
return RedirectToAction("Merge", new {
|
||||
@@ -101,7 +101,7 @@ namespace Orchard.Taxonomies.Controllers {
|
||||
termIds = string.Join(",", checkedEntries.Select(o => o.Id))
|
||||
});
|
||||
case TermsAdminIndexBulkAction.Move:
|
||||
if (!Services.Authorizer.Authorize(Permissions.ManageTerms, T("Couldn't move terms")))
|
||||
if (!Services.Authorizer.Authorize(Permissions.EditTerm, T("Couldn't move terms")))
|
||||
return new HttpUnauthorizedResult();
|
||||
|
||||
return RedirectToAction("MoveTerm", new {
|
||||
@@ -130,19 +130,19 @@ namespace Orchard.Taxonomies.Controllers {
|
||||
return View(model);
|
||||
}
|
||||
|
||||
return RedirectToAction("Create", new { taxonomyId, parentTermId = -1 });
|
||||
return RedirectToAction("Create", new { taxonomyId, parentTermId = -1, ReturnUrl = Url.Action("Index", new { taxonomyId = taxonomyId }) });
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public ActionResult SelectTerm(int taxonomyId, int selectedTermId) {
|
||||
if (!Services.Authorizer.Authorize(Permissions.ManageTerms, T("Not allowed to select terms")))
|
||||
if (!Services.Authorizer.Authorize(Permissions.CreateTerm, T("Not allowed to select terms")))
|
||||
return new HttpUnauthorizedResult();
|
||||
|
||||
return RedirectToAction("Create", new { taxonomyId, parentTermId = selectedTermId });
|
||||
return RedirectToAction("Create", new { taxonomyId, parentTermId = selectedTermId, ReturnUrl = Url.Action("Index", new { taxonomyId = taxonomyId }) });
|
||||
}
|
||||
|
||||
public ActionResult MoveTerm(int taxonomyId, string termIds) {
|
||||
if (!Services.Authorizer.Authorize(Permissions.CreateTerm, T("Not allowed to move terms")))
|
||||
if (!Services.Authorizer.Authorize(Permissions.EditTerm, T("Not allowed to move terms")))
|
||||
return new HttpUnauthorizedResult();
|
||||
|
||||
var terms = ResolveTermIds(termIds);
|
||||
@@ -164,7 +164,7 @@ namespace Orchard.Taxonomies.Controllers {
|
||||
|
||||
[HttpPost]
|
||||
public ActionResult MoveTerm(int taxonomyId, int selectedTermId, string termIds) {
|
||||
if (!Services.Authorizer.Authorize(Permissions.ManageTerms, T("Not allowed to move terms")))
|
||||
if (!Services.Authorizer.Authorize(Permissions.EditTerm, T("Not allowed to move terms")))
|
||||
return new HttpUnauthorizedResult();
|
||||
|
||||
var taxonomy = _taxonomyService.GetTaxonomy(taxonomyId);
|
||||
@@ -217,7 +217,7 @@ namespace Orchard.Taxonomies.Controllers {
|
||||
|
||||
public ActionResult Edit(int id) {
|
||||
|
||||
if (!Services.Authorizer.Authorize(Permissions.ManageTerms, T("Not allowed to manage terms")))
|
||||
if (!Services.Authorizer.Authorize(Permissions.EditTerm, T("Not allowed to edit terms")))
|
||||
return new HttpUnauthorizedResult();
|
||||
|
||||
var term = _taxonomyService.GetTerm(id);
|
||||
@@ -230,7 +230,7 @@ namespace Orchard.Taxonomies.Controllers {
|
||||
|
||||
[HttpPost, ActionName("Edit")]
|
||||
public ActionResult EditPost(int id) {
|
||||
if (!Services.Authorizer.Authorize(Permissions.ManageTerms, T("Couldn't edit term")))
|
||||
if (!Services.Authorizer.Authorize(Permissions.EditTerm, T("Couldn't edit term")))
|
||||
return new HttpUnauthorizedResult();
|
||||
|
||||
var term = _taxonomyService.GetTerm(id);
|
||||
|
||||
@@ -8,6 +8,7 @@ using Orchard.ContentManagement.Handlers;
|
||||
using Orchard.Data;
|
||||
using Orchard.Taxonomies.Settings;
|
||||
using System;
|
||||
using System.Web.Routing;
|
||||
|
||||
namespace Orchard.Taxonomies.Handlers {
|
||||
public class TaxonomyPartHandler : ContentHandler {
|
||||
@@ -51,5 +52,19 @@ namespace Orchard.Taxonomies.Handlers {
|
||||
}
|
||||
});
|
||||
}
|
||||
protected override void GetItemMetadata(GetContentItemMetadataContext context) {
|
||||
var taxonomy = context.ContentItem.As<TaxonomyPart>();
|
||||
|
||||
if (taxonomy == null)
|
||||
return;
|
||||
|
||||
context.Metadata.EditorRouteValues = new RouteValueDictionary {
|
||||
{"Area", "Orchard.Taxonomies"},
|
||||
{"Controller", "Admin"},
|
||||
{"Action", "Edit"},
|
||||
{"Id", taxonomy.Id}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
using Orchard.Taxonomies.Models;
|
||||
using Orchard.ContentManagement.Handlers;
|
||||
using Orchard.Data;
|
||||
using System.Web.Routing;
|
||||
using Orchard.ContentManagement;
|
||||
|
||||
namespace Orchard.Taxonomies.Handlers {
|
||||
public class TermPartHandler : ContentHandler {
|
||||
@@ -8,5 +10,19 @@ namespace Orchard.Taxonomies.Handlers {
|
||||
Filters.Add(StorageFilter.For(repository));
|
||||
OnInitializing<TermPart>((context, part) => part.Selectable = true);
|
||||
}
|
||||
protected override void GetItemMetadata(GetContentItemMetadataContext context) {
|
||||
var term = context.ContentItem.As<TermPart>();
|
||||
|
||||
if (term == null)
|
||||
return;
|
||||
|
||||
context.Metadata.EditorRouteValues = new RouteValueDictionary {
|
||||
{"Area", "Orchard.Taxonomies"},
|
||||
{"Controller", "TermAdmin"},
|
||||
{"Action", "Edit"},
|
||||
{"Id", term.Id}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
@model TaxonomyAdminIndexViewModel
|
||||
@using Orchard.Taxonomies;
|
||||
@using Orchard.Taxonomies.ViewModels;
|
||||
|
||||
@{
|
||||
@@ -16,7 +17,9 @@
|
||||
</select>
|
||||
<input class="button" type="submit" name="submit.BulkEdit" value="@T("Apply")" />
|
||||
</fieldset>
|
||||
<div class="manage">@Html.ActionLink(T("Add a taxonomy").Text, "Create", new { Area = "Contents", Id = "Taxonomy", ReturnUrl = Request.RawUrl }, new { @class = "button primaryAction" })</div>
|
||||
if (Authorizer.Authorize(Permissions.CreateTaxonomy)) {
|
||||
<div class="manage">@Html.ActionLink(T("Add a taxonomy").Text, "Create", new { Area = "Orchard.Taxonomies", ReturnUrl = Request.RawUrl }, new { @class = "button primaryAction" })</div>
|
||||
}
|
||||
<fieldset>
|
||||
<table class="items" summary="@T("This is a table of the taxonomies in your application")">
|
||||
<colgroup>
|
||||
@@ -36,12 +39,12 @@
|
||||
<tr class="@(taxonomyEntry.IsInternal ? "internal" : null)">
|
||||
<td>
|
||||
<input type="hidden" value="@Model.Taxonomies[taxonomyIndex].Id" name="@Html.NameOf(m => m.Taxonomies[ti].Id)" />
|
||||
@if (!taxonomyEntry.IsInternal || Authorizer.Authorize(Orchard.Security.StandardPermissions.SiteOwner)) {
|
||||
@if (!taxonomyEntry.IsInternal || Authorizer.Authorize(Permissions.ManageTaxonomies)) {
|
||||
<input type="checkbox" value="true" name="@Html.NameOf(m => m.Taxonomies[ti].IsChecked)" />
|
||||
}
|
||||
</td>
|
||||
<td>
|
||||
@if (!taxonomyEntry.IsInternal || Authorizer.Authorize(Orchard.Security.StandardPermissions.SiteOwner)) {
|
||||
@if (!taxonomyEntry.IsInternal || Authorizer.Authorize(Permissions.CreateTaxonomy)) {
|
||||
@Html.ActionLink(taxonomyEntry.Name, "Index", "TermAdmin", new { taxonomyId = taxonomyEntry.Id }, new object { })
|
||||
}
|
||||
else {
|
||||
@@ -49,15 +52,21 @@
|
||||
}
|
||||
</td>
|
||||
<td>
|
||||
@if (!taxonomyEntry.IsInternal || Authorizer.Authorize(Orchard.Security.StandardPermissions.SiteOwner)) {
|
||||
@Html.ItemEditLink(T("Edit").Text, taxonomyEntry.ContentItem) <text>|</text>
|
||||
@if (!taxonomyEntry.IsInternal) {
|
||||
if (Authorizer.Authorize(Permissions.CreateTaxonomy)) {
|
||||
@Html.ItemEditLink(T("Edit").Text, taxonomyEntry.ContentItem, new { ReturnUrl = Request.RawUrl }) <text>|</text>
|
||||
}
|
||||
@Html.ActionLink(T("Terms").Text, "Index", "TermAdmin", new { taxonomyId = taxonomyEntry.Id }, new object { }) <text>|</text>
|
||||
@Html.ActionLink(T("Delete").Text, "Delete", new { id = taxonomyEntry.Id }, new { itemprop = "RemoveUrl UnsafeUrl" }) <text>|</text>
|
||||
@Html.ActionLink(T("Import").Text, "Import", new { id = taxonomyEntry.Id }, new object { })
|
||||
if (Authorizer.Authorize(Permissions.ManageTaxonomies)) {
|
||||
@Html.ActionLink(T("Delete").Text, "Delete", new { id = taxonomyEntry.Id }, new { itemprop = "RemoveUrl UnsafeUrl" }) <text>|</text>
|
||||
}
|
||||
if (Authorizer.Authorize(Permissions.CreateTaxonomy)) {
|
||||
@Html.ActionLink(T("Import").Text, "Import", new { id = taxonomyEntry.Id }, new object { })
|
||||
}
|
||||
}
|
||||
</td>
|
||||
</tr>
|
||||
taxonomyIndex++;
|
||||
taxonomyIndex++;
|
||||
}
|
||||
</table>
|
||||
@Display(Model.Pager)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
@model TermAdminIndexViewModel
|
||||
@using Orchard.Taxonomies
|
||||
@using Orchard.Taxonomies.ViewModels;
|
||||
|
||||
@using Orchard.Taxonomies.Helpers;
|
||||
@{
|
||||
Style.Include("admin-taxonomy.css");
|
||||
@@ -9,9 +9,9 @@
|
||||
var termIndex = 0;
|
||||
}
|
||||
|
||||
@using(Html.BeginFormAntiForgeryPost()) {
|
||||
@using (Html.BeginFormAntiForgeryPost()) {
|
||||
@Html.ValidationSummary()
|
||||
@Html.HiddenFor(m=>m.TaxonomyId)
|
||||
@Html.HiddenFor(m => m.TaxonomyId)
|
||||
<fieldset class="bulk-actions">
|
||||
<label for="publishActions">@T("Actions:")</label>
|
||||
<select id="publishActions" name="@Html.NameOf(m => m.BulkAction)">
|
||||
@@ -21,7 +21,9 @@
|
||||
</select>
|
||||
<input class="button" type="submit" name="submit.BulkEdit" value="@T("Apply")" />
|
||||
</fieldset>
|
||||
<div class="manage">@Html.ActionLink(T("Add a term").ToString(), "SelectTerm", new { taxonomyId = Model.Taxonomy.Id }, new { @class = "button primaryAction" })</div>
|
||||
if (Authorizer.Authorize(Permissions.CreateTerm)) {
|
||||
<div class="manage">@Html.ActionLink(T("Add a term").ToString(), "SelectTerm", new { taxonomyId = Model.Taxonomy.Id }, new { @class = "button primaryAction" })</div>
|
||||
}
|
||||
<fieldset>
|
||||
<table class="items" summary="@T("This is a table of the terms in your application")">
|
||||
<colgroup>
|
||||
@@ -34,20 +36,22 @@
|
||||
<th scope="col"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
@foreach ( var termEntry in Model.Terms) {
|
||||
@foreach (var termEntry in Model.Terms) {
|
||||
var ti = termIndex;
|
||||
<tr>
|
||||
<td>
|
||||
<input type="hidden" value="@Model.Terms[termIndex].Id" name="@Html.NameOf(m => m.Terms[ti].Id)"/>
|
||||
@* Tabs for levels *@ @for ( var i = 1; i <= termEntry.GetLevels(); i++ ) { <span class="gap"> </span> }
|
||||
<input type="checkbox" value="true" name="@Html.NameOf(m => m.Terms[ti].IsChecked)"/>
|
||||
@Html.ItemDisplayLink(termEntry.Name, termEntry.ContentItem)
|
||||
</td>
|
||||
<td>
|
||||
@Html.ItemEditLink(T("Edit").Text, termEntry.ContentItem, new { returnUrl = Url.Action("Index", "TermAdmin", new { taxonomyId = Model.Taxonomy.Id }) }) |
|
||||
@Html.ActionLink(T("Move").ToString(), "MoveTerm", new { taxonomyId = Model.Taxonomy.Id, termIds = termEntry.Id })
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<input type="hidden" value="@Model.Terms[termIndex].Id" name="@Html.NameOf(m => m.Terms[ti].Id)" />
|
||||
@* Tabs for levels *@ @for (var i = 1; i <= termEntry.GetLevels(); i++) { <span class="gap"> </span> }
|
||||
<input type="checkbox" value="true" name="@Html.NameOf(m => m.Terms[ti].IsChecked)" />
|
||||
@Html.ItemDisplayLink(termEntry.Name, termEntry.ContentItem)
|
||||
</td>
|
||||
<td>
|
||||
@if (Authorizer.Authorize(Permissions.EditTerm)) {
|
||||
@Html.ItemEditLink(T("Edit").Text, termEntry.ContentItem, new { returnUrl = Url.Action("Index", "TermAdmin", new { taxonomyId = Model.Taxonomy.Id }) }) <text>|</text>
|
||||
@Html.ActionLink(T("Move").ToString(), "MoveTerm", new { taxonomyId = Model.Taxonomy.Id, termIds = termEntry.Id })
|
||||
}
|
||||
</td>
|
||||
</tr>
|
||||
termIndex++;
|
||||
}
|
||||
</table>
|
||||
|
||||
@@ -105,9 +105,9 @@ namespace Orchard.Themes.Services {
|
||||
var requestTheme = _themeSelectors
|
||||
.Select(x => x.GetTheme(requestContext))
|
||||
.Where(x => x != null)
|
||||
.OrderByDescending(x => x.Priority);
|
||||
.OrderByDescending(x => x.Priority).ToList();
|
||||
|
||||
if (requestTheme.Count() < 1)
|
||||
if (!requestTheme.Any())
|
||||
return null;
|
||||
|
||||
foreach (var theme in requestTheme) {
|
||||
|
||||
@@ -19,9 +19,9 @@ namespace Orchard.Themes {
|
||||
var requestTheme = _themeSelectors
|
||||
.Select(x => x.GetTheme(requestContext))
|
||||
.Where(x => x != null)
|
||||
.OrderByDescending(x => x.Priority);
|
||||
.OrderByDescending(x => x.Priority).ToList();
|
||||
|
||||
if (requestTheme.Count() < 1)
|
||||
if (!requestTheme.Any())
|
||||
return null;
|
||||
|
||||
foreach (var theme in requestTheme) {
|
||||
|
||||
@@ -202,6 +202,7 @@ namespace Orchard.UI.Navigation {
|
||||
var menuItemShape = shapeFactory.MenuItem()
|
||||
.Text(menuItem.Text)
|
||||
.IdHint(menuItem.IdHint)
|
||||
.Url(menuItem.Url)
|
||||
.Href(menuItem.Href)
|
||||
.LinkToFirstChild(menuItem.LinkToFirstChild)
|
||||
.LocalNav(menuItem.LocalNav)
|
||||
@@ -231,6 +232,7 @@ namespace Orchard.UI.Navigation {
|
||||
var menuItemShape = shapeFactory.LocalMenuItem()
|
||||
.Text(menuItem.Text)
|
||||
.IdHint(menuItem.IdHint)
|
||||
.Url(menuItem.Url)
|
||||
.Href(menuItem.Href)
|
||||
.LinkToFirstChild(menuItem.LinkToFirstChild)
|
||||
.LocalNav(menuItem.LocalNav)
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
<PropertyValue name="Indent_FlushLabelsLeft">0</PropertyValue>
|
||||
<PropertyValue name="Indent_UnindentLabels">1</PropertyValue>
|
||||
<PropertyValue name="NewLines_AnonymousTypeInitializer_EachMember">1</PropertyValue>
|
||||
<PropertyValue name="NewLines_Braces_Accessor">1</PropertyValue>
|
||||
<PropertyValue name="NewLines_Braces_Accessor">0</PropertyValue>
|
||||
<PropertyValue name="NewLines_Braces_AnonymousMethod">0</PropertyValue>
|
||||
<PropertyValue name="NewLines_Braces_AnonymousTypeInitializer">0</PropertyValue>
|
||||
<PropertyValue name="NewLines_Braces_ArrayInitializer">0</PropertyValue>
|
||||
@@ -55,7 +55,7 @@
|
||||
<PropertyValue name="NewLines_Braces_LambdaExpressionBody">0</PropertyValue>
|
||||
<PropertyValue name="NewLines_Braces_Method">0</PropertyValue>
|
||||
<PropertyValue name="NewLines_Braces_ObjectInitializer">0</PropertyValue>
|
||||
<PropertyValue name="NewLines_Braces_Property">1</PropertyValue>
|
||||
<PropertyValue name="NewLines_Braces_Property">0</PropertyValue>
|
||||
<PropertyValue name="NewLines_Braces_Type">0</PropertyValue>
|
||||
<PropertyValue name="NewLines_Keywords_Catch">1</PropertyValue>
|
||||
<PropertyValue name="NewLines_Keywords_Else">1</PropertyValue>
|
||||
|
||||
Reference in New Issue
Block a user