Added unique zone name validation.

This commit is contained in:
Sipke Schoorstra
2015-04-05 13:49:39 +02:00
parent c044118b3f
commit 1a02d106a8
5 changed files with 84 additions and 15 deletions

View File

@@ -4,6 +4,7 @@ using Orchard.Layouts.Framework.Drivers;
namespace Orchard.Layouts.Drivers {
public class ColumnElementDriver : ElementDriver<Column> {
protected override void OnDisplaying(Column element, ElementDisplayingContext context) {
context.ElementShape.Width = element.Width;
context.ElementShape.Offset = element.Offset;

View File

@@ -2,6 +2,7 @@
namespace Orchard.Layouts.Models {
public interface ILayoutAspect : IContent {
int? TemplateId { get; set; }
string LayoutData { get; set; }
}
}

View File

@@ -60,5 +60,10 @@ namespace Orchard.Layouts.Services {
/// Collects all zones as defined in all layouts in the system.
/// </summary>
IEnumerable<string> GetZones();
/// <summary>
/// Recursively collects all zones of the specified layout and of its selected template, if any.
/// </summary>
IEnumerable<string> GetZones(ILayoutAspect layout);
}
}

View File

@@ -10,6 +10,7 @@ using Orchard.Layouts.Framework.Elements;
using Orchard.Layouts.Helpers;
using Orchard.Layouts.Models;
using Orchard.Layouts.Settings;
using Orchard.Validation;
namespace Orchard.Layouts.Services {
public class LayoutManager : ILayoutManager {
@@ -84,19 +85,32 @@ namespace Orchard.Layouts.Services {
public IEnumerable<string> GetZones() {
return _cacheManager.Get("LayoutZones", context => {
var layouts = GetLayouts().ToList();
var zoneNames = new HashSet<string>();
context.Monitor(_signals.When(Signals.LayoutZones));
return GetZones(GetLayouts());
});
}
foreach (var layoutPart in layouts) {
var elements = LoadElements(layoutPart).Flatten();
var columns = elements.Where(x => x is Column).Cast<Column>().Where(x => !String.IsNullOrWhiteSpace(x.ZoneName)).ToList();
public IEnumerable<string> GetZones(ILayoutAspect layout) {
Argument.ThrowIfNull(layout, "layout");
foreach (var column in columns)
zoneNames.Add(column.ZoneName);
var key = String.Format("LayoutZones-{0}", layout.Id);
return _cacheManager.Get(key, context => {
context.Monitor(_signals.When(Signals.LayoutZones));
var layouts = new List<ILayoutAspect>();
var currentTemplate = layout.TemplateId != null ? GetLayout(layout.TemplateId.Value) : default(LayoutPart);
// Add the layout itself to the chain of layouts to harvest zones from.
layouts.Add(layout);
// Walk up the chain of templates and collect each one for zone harvesting.
while (currentTemplate != null) {
layouts.Add(currentTemplate);
currentTemplate = currentTemplate.TemplateId != null ? GetLayout(currentTemplate.TemplateId.Value) : default(LayoutPart);
}
context.Monitor(_signals.When(Signals.LayoutZones));
return zoneNames;
// Harvest the zones from the chain of layouts.
return GetZones(layouts);
});
}
@@ -199,5 +213,19 @@ namespace Orchard.Layouts.Services {
}
}
}
private IEnumerable<string> GetZones(IEnumerable<ILayoutAspect> layouts) {
var zoneNames = new HashSet<string>();
foreach (var layoutPart in layouts) {
var elements = LoadElements(layoutPart).Flatten();
var columns = elements.Where(x => x is Column).Cast<Column>().Where(x => !String.IsNullOrWhiteSpace(x.ZoneName)).ToList();
foreach (var column in columns)
zoneNames.Add(column.ZoneName);
}
return zoneNames.OrderBy(x => x);
}
}
}

View File

@@ -4,10 +4,11 @@ using System.Linq;
using Orchard.ContentManagement;
using Orchard.ContentManagement.Aspects;
using Orchard.Core.Settings.Models;
using Orchard.Core.Shapes;
using Orchard.Layouts.Elements;
using Orchard.Layouts.Framework.Display;
using Orchard.Layouts.Framework.Drivers;
using Orchard.Layouts.Framework.Elements;
using Orchard.Layouts.Helpers;
using Orchard.Logging;
using Orchard.Widgets.Models;
using Orchard.Widgets.Services;
@@ -24,10 +25,37 @@ namespace Orchard.Widgets.Drivers {
_widgetsService = widgetsService;
}
protected override void OnLayoutSaving(Column element, ElementSavingContext context) {
ValidateZoneName(element, context);
}
protected override void OnDisplaying(Column element, ElementDisplayingContext context) {
RenderWidgets(element, context);
}
private void ValidateZoneName(Column element, ElementSavingContext context) {
if (String.IsNullOrWhiteSpace(element.ZoneName))
return; // Nothing to validate.
if (element.IsTemplated)
return; // No need to validate templated columns.
var blacklist = new HashSet<string>();
// Add theme zones to the blacklist.
var themeZones = _widgetsService.GetZones();
Add(blacklist, themeZones);
// Add any zones from the current layout (except the zone name of the current column) to the blacklist.
var siblingColumns = context.Elements.Flatten().Where(x => x is Column && x != element).Cast<Column>().ToList();
var siblingZones = siblingColumns.Where(x => !String.IsNullOrWhiteSpace(x.ZoneName)).Select(x => x.ZoneName);
Add(blacklist, siblingZones);
// Check if the specified zone is blacklisted.
if (blacklist.Contains(element.ZoneName))
context.Updater.AddModelError("ZoneName", T("The zone name '{0}' is already in use.", element.ZoneName));
}
private void RenderWidgets(Column element, ElementDisplayingContext context) {
var zoneName = element.ZoneName;
@@ -59,22 +87,22 @@ namespace Orchard.Widgets.Drivers {
continue;
}
// ignore widget for different cultures
// Ignore widget for different cultures,
var localizablePart = widgetPart.As<ILocalizableAspect>();
if (localizablePart != null) {
// if localized culture is null then show if current culture is the default
// this allows a user to show a content item for the default culture only
// If localized culture is null then show if current culture is the default
// this allows a user to show a content item for the default culture only.
if (localizablePart.Culture == null && defaultCulture != currentCulture) {
continue;
}
// if culture is set, show only if current culture is the same
// If culture is set, show only if current culture is the same.
if (localizablePart.Culture != null && localizablePart.Culture != currentCulture) {
continue;
}
}
// check permissions
// Check permissions.
if (!_orchardServices.Authorizer.Authorize(Core.Contents.Permissions.ViewContent, widgetPart)) {
continue;
}
@@ -84,5 +112,11 @@ namespace Orchard.Widgets.Drivers {
context.ElementShape.Add(widgetShape, widgetPart.Position);
}
}
private static void Add(ISet<string> set, IEnumerable<string> zones) {
foreach (var zone in zones) {
set.Add(zone);
}
}
}
}