diff --git a/src/Orchard.Web/Core/Contents/AdminMenu.cs b/src/Orchard.Web/Core/Contents/AdminMenu.cs index 514c049ca..c4ef1314b 100644 --- a/src/Orchard.Web/Core/Contents/AdminMenu.cs +++ b/src/Orchard.Web/Core/Contents/AdminMenu.cs @@ -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().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().Creatable).OrderBy(ctd => ctd.DisplayName); if (contentTypes.Any()) { builder.Add(T("New"), "-1", menu => { diff --git a/src/Orchard.Web/Modules/Orchard.Blogs/Security/BlogAuthorizationEventHandler.cs b/src/Orchard.Web/Modules/Orchard.Blogs/Security/BlogAuthorizationEventHandler.cs index 175551170..2be6bfb2b 100644 --- a/src/Orchard.Web/Modules/Orchard.Blogs/Security/BlogAuthorizationEventHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.Blogs/Security/BlogAuthorizationEventHandler.cs @@ -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()) { - 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; + } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Blogs/Views/Content-BlogPost.SummaryAdmin.cshtml b/src/Orchard.Web/Modules/Orchard.Blogs/Views/Content-BlogPost.SummaryAdmin.cshtml index 599c9d213..4fc4086fc 100644 --- a/src/Orchard.Web/Modules/Orchard.Blogs/Views/Content-BlogPost.SummaryAdmin.cshtml +++ b/src/Orchard.Web/Modules/Orchard.Blogs/Views/Content-BlogPost.SummaryAdmin.cshtml @@ -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)) { diff --git a/src/Orchard.Web/Modules/Orchard.DesignerTools/Controllers/AlternateController.cs b/src/Orchard.Web/Modules/Orchard.DesignerTools/Controllers/AlternateController.cs index 0c808c528..cbd3ce767 100644 --- a/src/Orchard.Web/Modules/Orchard.DesignerTools/Controllers/AlternateController.cs +++ b/src/Orchard.Web/Modules/Orchard.DesignerTools/Controllers/AlternateController.cs @@ -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("::"); diff --git a/src/Orchard.Web/Modules/Orchard.DesignerTools/Services/ShapeTracingFactory.cs b/src/Orchard.Web/Modules/Orchard.DesignerTools/Services/ShapeTracingFactory.cs index f46026621..6fac2c2e1 100644 --- a/src/Orchard.Web/Modules/Orchard.DesignerTools/Services/ShapeTracingFactory.cs +++ b/src/Orchard.Web/Modules/Orchard.DesignerTools/Services/ShapeTracingFactory.cs @@ -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")) { diff --git a/src/Orchard.Web/Modules/Orchard.DynamicForms/Drivers/TaxonomyElementDriver.cs b/src/Orchard.Web/Modules/Orchard.DynamicForms/Drivers/TaxonomyElementDriver.cs index 7e2b10701..2b3614b1b 100644 --- a/src/Orchard.Web/Modules/Orchard.DynamicForms/Drivers/TaxonomyElementDriver.cs +++ b/src/Orchard.Web/Modules/Orchard.DynamicForms/Drivers/TaxonomyElementDriver.cs @@ -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, diff --git a/src/Orchard.Web/Modules/Orchard.JobsQueue/Controllers/AdminController.cs b/src/Orchard.Web/Modules/Orchard.JobsQueue/Controllers/AdminController.cs index a91d71857..71042f9d7 100644 --- a/src/Orchard.Web/Modules/Orchard.JobsQueue/Controllers/AdminController.cs +++ b/src/Orchard.Web/Modules/Orchard.JobsQueue/Controllers/AdminController.cs @@ -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().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 }); + } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.JobsQueue/Services/IJobsQueueProcessor.cs b/src/Orchard.Web/Modules/Orchard.JobsQueue/Services/IJobsQueueProcessor.cs index f5fb216d1..ec31bd635 100644 --- a/src/Orchard.Web/Modules/Orchard.JobsQueue/Services/IJobsQueueProcessor.cs +++ b/src/Orchard.Web/Modules/Orchard.JobsQueue/Services/IJobsQueueProcessor.cs @@ -1,5 +1,5 @@ namespace Orchard.JobsQueue.Services { public interface IJobsQueueProcessor : ISingletonDependency { - void ProcessQueue(); + void ProcessQueue(int batchSize, uint batchCount); } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.JobsQueue/Services/JobsQueueBackgroundTask.cs b/src/Orchard.Web/Modules/Orchard.JobsQueue/Services/JobsQueueBackgroundTask.cs index 24ec55072..c4a024e87 100644 --- a/src/Orchard.Web/Modules/Orchard.JobsQueue/Services/JobsQueueBackgroundTask.cs +++ b/src/Orchard.Web/Modules/Orchard.JobsQueue/Services/JobsQueueBackgroundTask.cs @@ -8,7 +8,7 @@ namespace Orchard.JobsQueue.Services { } public void Sweep() { - _jobsQueueProcessor.ProcessQueue(); + _jobsQueueProcessor.ProcessQueue(10, uint.MaxValue); } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.JobsQueue/Services/JobsQueueProcessor.cs b/src/Orchard.Web/Modules/Orchard.JobsQueue/Services/JobsQueueProcessor.cs index 8c845f73c..b12ecebad 100644 --- a/src/Orchard.Web/Modules/Orchard.JobsQueue/Services/JobsQueueProcessor.cs +++ b/src/Orchard.Web/Modules/Orchard.JobsQueue/Services/JobsQueueProcessor.cs @@ -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 _jobsQueueManager; private readonly Work _eventBus; private readonly Work _distributedLockService; + private readonly Work _transactionManager; public JobsQueueProcessor( Work jobsQueueManager, Work eventBus, - Work distributedLockService) { + Work distributedLockService, + Work 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 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); - } } } diff --git a/src/Orchard.Web/Modules/Orchard.JobsQueue/Views/Admin/List.cshtml b/src/Orchard.Web/Modules/Orchard.JobsQueue/Views/Admin/List.cshtml index bf5c369e5..0d88634b3 100644 --- a/src/Orchard.Web/Modules/Orchard.JobsQueue/Views/Admin/List.cshtml +++ b/src/Orchard.Web/Modules/Orchard.JobsQueue/Views/Admin/List.cshtml @@ -7,6 +7,7 @@ Layout.Title = T("Jobs Queue"); Style.Include("admin-jobsqueue.css"); + Script.Require("jQuery"); } @using (Html.BeginFormAntiForgeryPost()) {
@@ -62,4 +63,14 @@ else { } @Display(Model.Pager) +} + +@if (Model.ProcessQueue) { + using (Script.Foot()) { + + } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.MediaLibrary/Controllers/AdminController.cs b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Controllers/AdminController.cs index a07b42503..0d0fbaef4 100644 --- a/src/Orchard.Web/Modules/Orchard.MediaLibrary/Controllers/AdminController.cs +++ b/src/Orchard.Web/Modules/Orchard.MediaLibrary/Controllers/AdminController.cs @@ -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(); 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); diff --git a/src/Orchard.Web/Modules/Orchard.OutputCache/Filters/OutputCacheFilter.cs b/src/Orchard.Web/Modules/Orchard.OutputCache/Filters/OutputCacheFilter.cs index 5f2546350..503fc0fdc 100644 --- a/src/Orchard.Web/Modules/Orchard.OutputCache/Filters/OutputCacheFilter.cs +++ b/src/Orchard.Web/Modules/Orchard.OutputCache/Filters/OutputCacheFilter.cs @@ -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; diff --git a/src/Orchard.Web/Modules/Orchard.OutputCache/Services/DefaultTagCache.cs b/src/Orchard.Web/Modules/Orchard.OutputCache/Services/DefaultTagCache.cs index 917b4a8e9..73979772a 100644 --- a/src/Orchard.Web/Modules/Orchard.OutputCache/Services/DefaultTagCache.cs +++ b/src/Orchard.Web/Modules/Orchard.OutputCache/Services/DefaultTagCache.cs @@ -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>; + if ( workContext != null ) { + _dictionary = workContext.HttpContext.Cache.Get(key) as ConcurrentDictionary>; - if (_dictionary == null) { - _dictionary = new ConcurrentDictionary>(StringComparer.OrdinalIgnoreCase); - workContext.HttpContext.Cache.Add(key, _dictionary, null, Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, CacheItemPriority.Normal, null); + if ( _dictionary == null ) { + _dictionary = new ConcurrentDictionary>(StringComparer.OrdinalIgnoreCase); + workContext.HttpContext.Cache.Add(key, _dictionary, null, Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, CacheItemPriority.Normal, null); + } } } diff --git a/src/Orchard.Web/Modules/Orchard.Pages/Commands/PageCommands.cs b/src/Orchard.Web/Modules/Orchard.Pages/Commands/PageCommands.cs index c93421a97..620f8fb7c 100644 --- a/src/Orchard.Web/Modules/Orchard.Pages/Commands/PageCommands.cs +++ b/src/Orchard.Web/Modules/Orchard.Pages/Commands/PageCommands.cs @@ -183,13 +183,15 @@ Aliquam vel sem nibh. Suspendisse vel condimentum tellus.

").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.

").Text; return HttpUtility.UrlEncode(text); } } -} \ No newline at end of file +} diff --git a/src/Orchard.Web/Modules/Orchard.Roles/Activities/AssignRoleActivity.cs b/src/Orchard.Web/Modules/Orchard.Roles/Activities/AssignRoleActivity.cs index c9ae1f67a..76e73f1ba 100644 --- a/src/Orchard.Web/Modules/Orchard.Roles/Activities/AssignRoleActivity.cs +++ b/src/Orchard.Web/Modules/Orchard.Roles/Activities/AssignRoleActivity.cs @@ -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 GetPossibleOutcomes(WorkflowContext workflowContext, ActivityContext activityContext) { - return new[] {T("Done")}; + return new[] { T("Done") }; } public override IEnumerable Execute(WorkflowContext workflowContext, ActivityContext activityContext) { @@ -59,7 +59,7 @@ namespace Orchard.Roles.Activities { if (user == null) { user = _workContextAccessor.GetContext().CurrentUser.As(); } - + 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 GetRoles(ActivityContext context) { var roles = context.GetState("Roles"); @@ -86,7 +86,8 @@ namespace Orchard.Roles.Activities { return Enumerable.Empty(); } - return roles.Split(new [] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim()).ToList(); + return roles.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim()).ToList(); } } -} \ No newline at end of file + +} diff --git a/src/Orchard.Web/Modules/Orchard.Roles/Activities/UnassignRoleActivity.cs b/src/Orchard.Web/Modules/Orchard.Roles/Activities/UnassignRoleActivity.cs new file mode 100644 index 000000000..655bd30ef --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.Roles/Activities/UnassignRoleActivity.cs @@ -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 _repository; + private readonly IRoleService _roleService; + + public UnssignRoleActivity( + IWorkContextAccessor workContextAccessor, + IRepository 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 GetPossibleOutcomes(WorkflowContext workflowContext, ActivityContext activityContext) { + return new[] { T("Done") }; + } + + public override IEnumerable Execute(WorkflowContext workflowContext, ActivityContext activityContext) { + var user = workflowContext.Content.As(); + + // if the current workflow subject is not a user, use current user + if (user == null) { + user = _workContextAccessor.GetContext().CurrentUser.As(); + } + + 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 GetRoles(ActivityContext context) { + var roles = context.GetState("Roles"); + + if (String.IsNullOrEmpty(roles)) { + return Enumerable.Empty(); + } + + return roles.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim()).ToList(); + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Roles/Orchard.Roles.csproj b/src/Orchard.Web/Modules/Orchard.Roles/Orchard.Roles.csproj index eb32adc04..e2ec0af1a 100644 --- a/src/Orchard.Web/Modules/Orchard.Roles/Orchard.Roles.csproj +++ b/src/Orchard.Web/Modules/Orchard.Roles/Orchard.Roles.csproj @@ -90,6 +90,7 @@ + @@ -137,6 +138,7 @@ + @@ -195,6 +197,9 @@ + + + 10.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) diff --git a/src/Orchard.Web/Modules/Orchard.Roles/Styles/workflows-activity-unassign-role.css b/src/Orchard.Web/Modules/Orchard.Roles/Styles/workflows-activity-unassign-role.css new file mode 100644 index 000000000..4c5b78617 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.Roles/Styles/workflows-activity-unassign-role.css @@ -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; +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Roles/Views/Activity-UnassignRole.cshtml b/src/Orchard.Web/Modules/Orchard.Roles/Views/Activity-UnassignRole.cshtml new file mode 100644 index 000000000..862d2f675 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.Roles/Views/Activity-UnassignRole.cshtml @@ -0,0 +1,8 @@ +@{ + var rolesData = (string)Model.State.Roles; + var roles = !String.IsNullOrWhiteSpace(rolesData) ? rolesData.Split(',') : Enumerable.Empty(); + var description = roles.Any() ? T("Unassign roles: {0}", String.Join(", ", roles)) : T("No roles specified"); +} + +
+
\ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Taxonomies/AdminMenu.cs b/src/Orchard.Web/Modules/Orchard.Taxonomies/AdminMenu.cs index debd0dfa4..40ab8f9a8 100644 --- a/src/Orchard.Web/Modules/Orchard.Taxonomies/AdminMenu.cs +++ b/src/Orchard.Web/Modules/Orchard.Taxonomies/AdminMenu.cs @@ -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" })); + } } } + } diff --git a/src/Orchard.Web/Modules/Orchard.Taxonomies/Controllers/AdminController.cs b/src/Orchard.Web/Modules/Orchard.Taxonomies/Controllers/AdminController.cs index bf32c094d..f8217face 100644 --- a/src/Orchard.Web/Modules/Orchard.Taxonomies/Controllers/AdminController.cs +++ b/src/Orchard.Web/Modules/Orchard.Taxonomies/Controllers/AdminController.cs @@ -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() && !contentItem.TypeDefinition.Settings.GetModel().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 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() && !contentItem.TypeDefinition.Settings.GetModel().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 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() + && !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().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().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"))) diff --git a/src/Orchard.Web/Modules/Orchard.Taxonomies/Controllers/TermAdminController.cs b/src/Orchard.Web/Modules/Orchard.Taxonomies/Controllers/TermAdminController.cs index d5b4129c3..4fbfd57b2 100644 --- a/src/Orchard.Web/Modules/Orchard.Taxonomies/Controllers/TermAdminController.cs +++ b/src/Orchard.Web/Modules/Orchard.Taxonomies/Controllers/TermAdminController.cs @@ -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); diff --git a/src/Orchard.Web/Modules/Orchard.Taxonomies/Handlers/TaxonomyPartHandler.cs b/src/Orchard.Web/Modules/Orchard.Taxonomies/Handlers/TaxonomyPartHandler.cs index 3cd2fef4b..c3eca356b 100644 --- a/src/Orchard.Web/Modules/Orchard.Taxonomies/Handlers/TaxonomyPartHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.Taxonomies/Handlers/TaxonomyPartHandler.cs @@ -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(); + + if (taxonomy == null) + return; + + context.Metadata.EditorRouteValues = new RouteValueDictionary { + {"Area", "Orchard.Taxonomies"}, + {"Controller", "Admin"}, + {"Action", "Edit"}, + {"Id", taxonomy.Id} + }; + + } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Taxonomies/Handlers/TermPartHandler.cs b/src/Orchard.Web/Modules/Orchard.Taxonomies/Handlers/TermPartHandler.cs index 587783543..34de4fe93 100644 --- a/src/Orchard.Web/Modules/Orchard.Taxonomies/Handlers/TermPartHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.Taxonomies/Handlers/TermPartHandler.cs @@ -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((context, part) => part.Selectable = true); } + protected override void GetItemMetadata(GetContentItemMetadataContext context) { + var term = context.ContentItem.As(); + + if (term == null) + return; + + context.Metadata.EditorRouteValues = new RouteValueDictionary { + {"Area", "Orchard.Taxonomies"}, + {"Controller", "TermAdmin"}, + {"Action", "Edit"}, + {"Id", term.Id} + }; + + } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Taxonomies/Views/Admin/Index.cshtml b/src/Orchard.Web/Modules/Orchard.Taxonomies/Views/Admin/Index.cshtml index cdd972f2c..faa351f19 100644 --- a/src/Orchard.Web/Modules/Orchard.Taxonomies/Views/Admin/Index.cshtml +++ b/src/Orchard.Web/Modules/Orchard.Taxonomies/Views/Admin/Index.cshtml @@ -1,4 +1,5 @@ @model TaxonomyAdminIndexViewModel +@using Orchard.Taxonomies; @using Orchard.Taxonomies.ViewModels; @{ @@ -16,7 +17,9 @@ -
@Html.ActionLink(T("Add a taxonomy").Text, "Create", new { Area = "Contents", Id = "Taxonomy", ReturnUrl = Request.RawUrl }, new { @class = "button primaryAction" })
+ if (Authorizer.Authorize(Permissions.CreateTaxonomy)) { +
@Html.ActionLink(T("Add a taxonomy").Text, "Create", new { Area = "Orchard.Taxonomies", ReturnUrl = Request.RawUrl }, new { @class = "button primaryAction" })
+ }
@@ -36,12 +39,12 @@ - taxonomyIndex++; + taxonomyIndex++; }
- @if (!taxonomyEntry.IsInternal || Authorizer.Authorize(Orchard.Security.StandardPermissions.SiteOwner)) { + @if (!taxonomyEntry.IsInternal || Authorizer.Authorize(Permissions.ManageTaxonomies)) { } - @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 @@ } - @if (!taxonomyEntry.IsInternal || Authorizer.Authorize(Orchard.Security.StandardPermissions.SiteOwner)) { - @Html.ItemEditLink(T("Edit").Text, taxonomyEntry.ContentItem) | + @if (!taxonomyEntry.IsInternal) { + if (Authorizer.Authorize(Permissions.CreateTaxonomy)) { + @Html.ItemEditLink(T("Edit").Text, taxonomyEntry.ContentItem, new { ReturnUrl = Request.RawUrl }) | + } @Html.ActionLink(T("Terms").Text, "Index", "TermAdmin", new { taxonomyId = taxonomyEntry.Id }, new object { }) | - @Html.ActionLink(T("Delete").Text, "Delete", new { id = taxonomyEntry.Id }, new { itemprop = "RemoveUrl UnsafeUrl" }) | - @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" }) | + } + if (Authorizer.Authorize(Permissions.CreateTaxonomy)) { + @Html.ActionLink(T("Import").Text, "Import", new { id = taxonomyEntry.Id }, new object { }) + } }
@Display(Model.Pager) diff --git a/src/Orchard.Web/Modules/Orchard.Taxonomies/Views/TermAdmin/Index.cshtml b/src/Orchard.Web/Modules/Orchard.Taxonomies/Views/TermAdmin/Index.cshtml index 925eb8190..1185666bd 100644 --- a/src/Orchard.Web/Modules/Orchard.Taxonomies/Views/TermAdmin/Index.cshtml +++ b/src/Orchard.Web/Modules/Orchard.Taxonomies/Views/TermAdmin/Index.cshtml @@ -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)
-
@Html.ActionLink(T("Add a term").ToString(), "SelectTerm", new { taxonomyId = Model.Taxonomy.Id }, new { @class = "button primaryAction" })
+ if (Authorizer.Authorize(Permissions.CreateTerm)) { +
@Html.ActionLink(T("Add a term").ToString(), "SelectTerm", new { taxonomyId = Model.Taxonomy.Id }, new { @class = "button primaryAction" })
+ }
@@ -34,20 +36,22 @@ - @foreach ( var termEntry in Model.Terms) { + @foreach (var termEntry in Model.Terms) { var ti = termIndex; - - - - + + + + termIndex++; }
- - @* Tabs for levels *@ @for ( var i = 1; i <= termEntry.GetLevels(); i++ ) {   } - - @Html.ItemDisplayLink(termEntry.Name, termEntry.ContentItem) - - @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 }) -
+ + @* Tabs for levels *@ @for (var i = 1; i <= termEntry.GetLevels(); i++) {   } + + @Html.ItemDisplayLink(termEntry.Name, termEntry.ContentItem) + + @if (Authorizer.Authorize(Permissions.EditTerm)) { + @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 }) + } +
diff --git a/src/Orchard.Web/Modules/Orchard.Themes/Services/ThemeService.cs b/src/Orchard.Web/Modules/Orchard.Themes/Services/ThemeService.cs index eaeb536b5..c5a05371f 100644 --- a/src/Orchard.Web/Modules/Orchard.Themes/Services/ThemeService.cs +++ b/src/Orchard.Web/Modules/Orchard.Themes/Services/ThemeService.cs @@ -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) { diff --git a/src/Orchard/Themes/ThemeManager.cs b/src/Orchard/Themes/ThemeManager.cs index 0cc182bba..5fb731f04 100644 --- a/src/Orchard/Themes/ThemeManager.cs +++ b/src/Orchard/Themes/ThemeManager.cs @@ -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) { diff --git a/src/Orchard/UI/Navigation/NavigationHelper.cs b/src/Orchard/UI/Navigation/NavigationHelper.cs index eb0803219..3d7c577bc 100644 --- a/src/Orchard/UI/Navigation/NavigationHelper.cs +++ b/src/Orchard/UI/Navigation/NavigationHelper.cs @@ -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) diff --git a/src/Rebracer.xml b/src/Rebracer.xml index c6edfa2e2..ee2bf5fa9 100644 --- a/src/Rebracer.xml +++ b/src/Rebracer.xml @@ -46,7 +46,7 @@ 0 1 1 - 1 + 0 0 0 0 @@ -55,7 +55,7 @@ 0 0 0 - 1 + 0 0 1 1