forked from OrchardCMS/Orchard
-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathContentPickerFieldLocalizationExtensionHandler.cs
More file actions
112 lines (105 loc) · 7.24 KB
/
ContentPickerFieldLocalizationExtensionHandler.cs
File metadata and controls
112 lines (105 loc) · 7.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
using System;
using System.Collections.Generic;
using System.Linq;
using Orchard.ContentManagement;
using Orchard.ContentManagement.Handlers;
using Orchard.ContentPicker.Fields;
using Orchard.ContentPicker.Settings;
using Orchard.Environment.Extensions;
using Orchard.Localization;
using Orchard.Localization.Models;
using Orchard.Localization.Services;
using Orchard.UI.Notify;
namespace Orchard.ContentPicker.Handlers {
[OrchardFeature("Orchard.ContentPicker.LocalizationExtensions")]
public class ContentPickerFieldLocalizationExtensionHandler : ContentHandler {
private readonly IOrchardServices _orchardServices;
private readonly IContentManager _contentManager;
private readonly ILocalizationService _localizationService;
public Localizer T { get; set; }
public ContentPickerFieldLocalizationExtensionHandler(
IOrchardServices orchardServices,
IContentManager contentManager,
ILocalizationService localizationService) {
_orchardServices = orchardServices;
_contentManager = contentManager;
_localizationService = localizationService;
T = NullLocalizer.Instance;
}
protected override void UpdateEditorShape(UpdateEditorContext context) {
base.UpdateEditorShape(context);
//Here we implement the logic based on the settings introduced in ContentPickerFieldLocalizationSettings
//These settings should only be active if the ContentItem that is being updated has a LocalizationPart
if (context.ContentItem.Parts.Any(part => part is LocalizationPart)) {
var lPart = (LocalizationPart)context.ContentItem.Parts.Single(part => part is LocalizationPart);
var fields = context.ContentItem.Parts.SelectMany(x => x.Fields.Where(f => f.FieldDefinition.Name == typeof(ContentPickerField).Name)).Cast<ContentPickerField>();
foreach (var field in fields) {
var settings = field.PartFieldDefinition.Settings.GetModel<ContentPickerFieldLocalizationSettings>();
if (settings.TryToLocalizeItems) {
//try to replace items in the field with their translation
var itemsInField = _contentManager.GetMany<ContentItem>(field.Ids, VersionOptions.Published, QueryHints.Empty);
if (settings.RemoveItemsWithNoLocalizationPart && itemsInField.Where(ci => !ci.Parts.Any(part => part is LocalizationPart)).Any()) {
//keep only items that have a LocalizationPart
_orchardServices.Notifier.Warning(T(
"{0}: The following items could have no localization, so they were removed: {1}",
field.DisplayName,
string.Join(", ", itemsInField.Where(ci => !ci.Parts.Any(part => part is LocalizationPart)).Select(ci => ci.Id.ToString()))
));
itemsInField = itemsInField.Where(ci => ci.Parts.Any(part => part is LocalizationPart));
}
//use an (int, int) tuple to track translations
var newIds = itemsInField.Select(ci => {
if (ci.Parts.Any(part => part is LocalizationPart)) {
if (_localizationService.GetContentCulture(ci) == lPart.Culture.Culture)
return new Tuple<int, int>(ci.Id, ci.Id); //this item is fine
var localized = _localizationService.GetLocalizations(ci).FirstOrDefault(lp => lp.Culture == lPart.Culture);
return localized == null ? new Tuple<int, int>(ci.Id, -ci.Id) : new Tuple<int, int>(ci.Id, localized.Id); //return negative id where we found no translation
}
else {
//we only go here if RemoveItemsWithNoLocalizationPart == false
return new Tuple<int, int>(ci.Id, ci.Id);
}
});
if (settings.RemoveItemsWithoutLocalization) {
//remove the items for which we could not find a localization
_orchardServices.Notifier.Warning(T(
"{0}: We could not find a localization for the following items, so they were removed: {1}",
field.DisplayName,
string.Join(", ", newIds.Where(tup => tup.Item2 < 0).Select(tup => tup.Item1.ToString()))
));
newIds = newIds.Where(tup => tup.Item2 > 0);
}
else {
//negative Ids are made positive again
newIds = newIds.Select(tup => tup = new Tuple<int, int>(tup.Item1, Math.Abs(tup.Item2)));
}
if (newIds.Where(tup => tup.Item1 != tup.Item2).Any()) {
_orchardServices.Notifier.Warning(T(
"{0}: The following items were replaced by their correct localization: {1}",
field.DisplayName,
string.Join(", ", newIds.Where(tup => tup.Item1 != tup.Item2).Select(tup => tup.Item1.ToString()))
));
}
field.Ids = newIds.Select(tup => tup.Item2).Distinct().ToArray();
}
if (settings.AssertItemsHaveSameCulture) {
//verify that the items in the ContentPickerField are all in the culture of the ContentItem whose editor we are updating
var itemsInField = _contentManager.GetMany<ContentItem>(field.Ids, VersionOptions.Published, QueryHints.Empty);
var itemsWithoutLocalizationPart = itemsInField.Where(ci => !ci.Parts.Any(part => part is LocalizationPart));
List<int> badItemIds = itemsInField.Where(ci => ci.Parts.Any(part => part is LocalizationPart && ((LocalizationPart)part).Culture == lPart.Culture)).Select(ci => ci.Id).ToList();
if (itemsWithoutLocalizationPart.Count() > 0) {
//Verify items from the ContentPickerField that cannot be localized
_orchardServices.Notifier.Warning(T("{0}: Some of the selected items cannot be localized. Ids: {1}", field.DisplayName, string.Join(", ", itemsWithoutLocalizationPart.Select(ci => ci.Id))));
if (settings.BlockForItemsWithNoLocalizationPart) {
badItemIds.AddRange(itemsWithoutLocalizationPart.Select(ci => ci.Id));
}
}
if (badItemIds.Count > 0) {
context.Updater.AddModelError(field.DisplayName, T("Some of the items selected have the wrong localization. Ids: {0}", string.Join(", ", badItemIds.Select(id => id.ToString()))));
}
}
}
}
}
}
}