#7055 changes taxonomy weight (#7709)

Fixes #7055
This commit is contained in:
Julián Alazorza
2017-06-29 21:09:45 +02:00
committed by Sébastien Ros
parent 09cea0f41e
commit fca9bb41af
12 changed files with 168 additions and 17 deletions

View File

@@ -46,9 +46,8 @@ namespace Orchard.Taxonomies.Controllers {
var taxonomy = _taxonomyService.GetTaxonomy(taxonomyId); var taxonomy = _taxonomyService.GetTaxonomy(taxonomyId);
var allTerms = TermPart.Sort(_taxonomyService.GetTermsQuery(taxonomyId).List()); var allTerms = _taxonomyService.GetTermsQuery(taxonomyId).OrderBy(x => x.FullWeight);
var termsPage = pager.PageSize > 0 ? allTerms.Slice(pager.GetStartIndex(), pager.PageSize) : allTerms.Slice(0, 0);
var termsPage = pager.PageSize > 0 ? allTerms.Skip(pager.GetStartIndex()).Take(pager.PageSize) : allTerms;
var pagerShape = Shape.Pager(pager).TotalItemCount(allTerms.Count()); var pagerShape = Shape.Pager(pager).TotalItemCount(allTerms.Count());
@@ -90,7 +89,9 @@ namespace Orchard.Taxonomies.Controllers {
foreach (var entry in checkedEntries) { foreach (var entry in checkedEntries) {
var term = _taxonomyService.GetTerm(entry.Id); var term = _taxonomyService.GetTerm(entry.Id);
_taxonomyService.DeleteTerm(term); if (term != null) {
_taxonomyService.DeleteTerm(term);
}
} }
Services.Notifier.Information(T.Plural("{0} term has been removed.", "{0} terms have been removed.", checkedEntries.Count)); Services.Notifier.Information(T.Plural("{0} term has been removed.", "{0} terms have been removed.", checkedEntries.Count));

View File

@@ -13,6 +13,7 @@ using Orchard.Mvc;
using Orchard.Settings; using Orchard.Settings;
using Orchard.Taxonomies.Settings; using Orchard.Taxonomies.Settings;
using Orchard.UI.Navigation; using Orchard.UI.Navigation;
using System.Text;
namespace Orchard.Taxonomies.Drivers { namespace Orchard.Taxonomies.Drivers {
public class TermPartDriver : ContentPartDriver<TermPart> { public class TermPartDriver : ContentPartDriver<TermPart> {
@@ -93,7 +94,22 @@ namespace Orchard.Taxonomies.Drivers {
} }
protected override DriverResult Editor(TermPart termPart, IUpdateModel updater, dynamic shapeHelper) { protected override DriverResult Editor(TermPart termPart, IUpdateModel updater, dynamic shapeHelper) {
//Moved to TermPartHandler to work also with Taxonomy Localization feature updater.TryUpdateModel(termPart, Prefix, null, null);
StringBuilder fullWeightBuilder = new StringBuilder();
string parentOldFullWeight = termPart.FullWeight == null ? termPart.FullWeight : "";
TermPart containerTerm = termPart;
for (int i = 0; i < termPart.Path.Count(x => x == '/') - 1; i++) {
containerTerm = containerTerm.Container.As<TermPart>();
fullWeightBuilder.Insert(0, containerTerm.Weight.ToString("D6") + "." + containerTerm.Id.ToString() + "/");
}
fullWeightBuilder.Append(termPart.Weight.ToString("D6") + "." + "/");
termPart.FullWeight = fullWeightBuilder.ToString();
foreach (var childTerm in _taxonomyService.GetChildren(termPart)) {
childTerm.FullWeight = _taxonomyService.ProcessChildrenFullWeight(childTerm.FullWeight, termPart.FullWeight, parentOldFullWeight);
}
return Editor(termPart, shapeHelper); return Editor(termPart, shapeHelper);
} }
@@ -102,6 +118,7 @@ namespace Orchard.Taxonomies.Drivers {
context.Element(part.PartDefinition.Name).SetAttributeValue("Count", part.Count); context.Element(part.PartDefinition.Name).SetAttributeValue("Count", part.Count);
context.Element(part.PartDefinition.Name).SetAttributeValue("Selectable", part.Selectable); context.Element(part.PartDefinition.Name).SetAttributeValue("Selectable", part.Selectable);
context.Element(part.PartDefinition.Name).SetAttributeValue("Weight", part.Weight); context.Element(part.PartDefinition.Name).SetAttributeValue("Weight", part.Weight);
context.Element(part.PartDefinition.Name).SetAttributeValue("FullWeight", part.FullWeight);
var taxonomy = _contentManager.Get(part.TaxonomyId); var taxonomy = _contentManager.Get(part.TaxonomyId);
var identity = _contentManager.GetItemMetadata(taxonomy).Identity.ToString(); var identity = _contentManager.GetItemMetadata(taxonomy).Identity.ToString();
@@ -129,6 +146,8 @@ namespace Orchard.Taxonomies.Drivers {
part.Count = Int32.Parse(context.Attribute(part.PartDefinition.Name, "Count")); part.Count = Int32.Parse(context.Attribute(part.PartDefinition.Name, "Count"));
part.Selectable = Boolean.Parse(context.Attribute(part.PartDefinition.Name, "Selectable")); part.Selectable = Boolean.Parse(context.Attribute(part.PartDefinition.Name, "Selectable"));
part.Weight = Int32.Parse(context.Attribute(part.PartDefinition.Name, "Weight")); part.Weight = Int32.Parse(context.Attribute(part.PartDefinition.Name, "Weight"));
context.ImportAttribute(part.PartDefinition.Name, "FullWeight", s => part.FullWeight = s);
bool createFullWeigth = string.IsNullOrWhiteSpace(part.FullWeight);
var identity = context.Attribute(part.PartDefinition.Name, "TaxonomyId"); var identity = context.Attribute(part.PartDefinition.Name, "TaxonomyId");
var contentItem = context.GetItemFromSession(identity); var contentItem = context.GetItemFromSession(identity);
@@ -143,6 +162,12 @@ namespace Orchard.Taxonomies.Drivers {
foreach (var identityPath in context.Attribute(part.PartDefinition.Name, "Path").Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)) { foreach (var identityPath in context.Attribute(part.PartDefinition.Name, "Path").Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)) {
var pathContentItem = context.GetItemFromSession(identityPath); var pathContentItem = context.GetItemFromSession(identityPath);
part.Path += pathContentItem.Id + "/"; part.Path += pathContentItem.Id + "/";
if (createFullWeigth) {
part.FullWeight = part.FullWeight + pathContentItem.As<TermPart>().Weight.ToString("D6") + "." + pathContentItem.Id.ToString() + "/";
}
}
if (createFullWeigth) {
part.FullWeight = part.FullWeight + part.Weight.ToString("D6") + "." + part.Id + "/";
} }
} }

View File

@@ -1,4 +1,5 @@
using Orchard.ContentManagement.MetaData; using Orchard.ContentManagement.MetaData;
using System.Data;
using Orchard.Data.Migration; using Orchard.Data.Migration;
namespace Orchard.Taxonomies { namespace Orchard.Taxonomies {
@@ -100,5 +101,12 @@ namespace Orchard.Taxonomies {
); );
return 7; return 7;
} }
public int UpdateFrom7() {
SchemaBuilder.AlterTable("TermPartRecord", table => {
table.AddColumn("FullWeight", DbType.String);
table.CreateIndex("IDX_FullWeight", "FullWeight");
});
return 8;
}
} }
} }

View File

@@ -51,6 +51,11 @@ namespace Orchard.Taxonomies.Models {
set { Store(x => x.Weight, value); } set { Store(x => x.Weight, value); }
} }
public string FullWeight {
get { return Record.FullWeight; }
set { Record.FullWeight = value; }
}
public string FullPath { get { return String.Concat(Path, Id); } } public string FullPath { get { return String.Concat(Path, Id); } }
public static IEnumerable<TermPart> Sort(IEnumerable<TermPart> terms) { public static IEnumerable<TermPart> Sort(IEnumerable<TermPart> terms) {
@@ -59,6 +64,7 @@ namespace Orchard.Taxonomies.Models {
return list.OrderBy(x => x, new TermsComparer(index)); return list.OrderBy(x => x, new TermsComparer(index));
} }
[Obsolete]
private class TermsComparer : IComparer<TermPart> { private class TermsComparer : IComparer<TermPart> {
private readonly IDictionary<string, TermPart> _index; private readonly IDictionary<string, TermPart> _index;

View File

@@ -9,5 +9,6 @@ namespace Orchard.Taxonomies.Models {
public virtual int Count { get; set; } public virtual int Count { get; set; }
public virtual bool Selectable { get; set; } public virtual bool Selectable { get; set; }
public virtual int Weight { get; set; } public virtual int Weight { get; set; }
public virtual string FullWeight { get; set; }
} }
} }

View File

@@ -64,6 +64,7 @@
<Reference Include="System.ComponentModel.DataAnnotations"> <Reference Include="System.ComponentModel.DataAnnotations">
<RequiredTargetFramework>3.5</RequiredTargetFramework> <RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference> </Reference>
<Reference Include="System.Data" />
<Reference Include="System.Data.DataSetExtensions" /> <Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Net.Http" /> <Reference Include="System.Net.Http" />
<Reference Include="System.Net.Http.Formatting, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> <Reference Include="System.Net.Http.Formatting, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">

View File

@@ -48,6 +48,9 @@ namespace Orchard.Taxonomies.Services {
void DeleteTerm(TermPart termPart); void DeleteTerm(TermPart termPart);
void MoveTerm(TaxonomyPart taxonomy, TermPart term, TermPart parentTerm); void MoveTerm(TaxonomyPart taxonomy, TermPart term, TermPart parentTerm);
void ProcessPath(TermPart term); void ProcessPath(TermPart term);
void ProcessFullWeight(TermPart term, TermPart parentTerm);
string ProcessChildrenFullWeight(string childrenFullWeight, string parentFullWeight, string parentOldFullWeight);
IContentQuery<TermPart, TermPartRecord> GetTermsQuery(int taxonomyId); IContentQuery<TermPart, TermPartRecord> GetTermsQuery(int taxonomyId);
string GenerateTermTypeName(string taxonomyName); string GenerateTermTypeName(string taxonomyName);

View File

@@ -167,17 +167,19 @@ namespace Orchard.Taxonomies.Services {
public IEnumerable<TermPart> GetTerms(int taxonomyId) { public IEnumerable<TermPart> GetTerms(int taxonomyId) {
var result = _contentManager.Query<TermPart, TermPartRecord>() var result = _contentManager.Query<TermPart, TermPartRecord>()
.Where(x => x.TaxonomyId == taxonomyId) .Where(x => x.TaxonomyId == taxonomyId)
.OrderBy(x => x.FullWeight)
.List(); .List();
return TermPart.Sort(result); return result;
} }
public IEnumerable<TermPart> GetRootTerms(int taxonomyId) { public IEnumerable<TermPart> GetRootTerms(int taxonomyId) {
var result = _contentManager.Query<TermPart, TermPartRecord>() var result = _contentManager.Query<TermPart, TermPartRecord>()
.Where(x => x.TaxonomyId == taxonomyId && x.Path == "/") .Where(x => x.TaxonomyId == taxonomyId && x.Path == "/")
.OrderBy(x => x.FullWeight)
.List(); .List();
return TermPart.Sort(result); return result;
} }
public TermPart GetTermByPath(string path) { public TermPart GetTermByPath(string path) {
@@ -191,8 +193,10 @@ namespace Orchard.Taxonomies.Services {
public IEnumerable<TermPart> GetAllTerms() { public IEnumerable<TermPart> GetAllTerms() {
var result = _contentManager var result = _contentManager
.Query<TermPart, TermPartRecord>() .Query<TermPart, TermPartRecord>()
.OrderBy(x=>x.TaxonomyId)
.OrderBy(x=>x.FullWeight)
.List(); .List();
return TermPart.Sort(result); return result;
} }
public int GetTermsCount(int taxonomyId) { public int GetTermsCount(int taxonomyId) {
@@ -331,13 +335,14 @@ namespace Orchard.Taxonomies.Services {
var result = _contentManager.Query<TermPart, TermPartRecord>() var result = _contentManager.Query<TermPart, TermPartRecord>()
.Where(x => x.Path.StartsWith(rootPath)) .Where(x => x.Path.StartsWith(rootPath))
.OrderBy(x=>x.FullWeight)
.List(); .List();
if (includeParent) { if (includeParent) {
result = result.Concat(new[] { term }); result = result.Concat(new[] { term });
} }
return TermPart.Sort(result); return result;
} }
public IEnumerable<TermPart> GetParents(TermPart term) { public IEnumerable<TermPart> GetParents(TermPart term) {
@@ -362,18 +367,33 @@ namespace Orchard.Taxonomies.Services {
var children = GetChildren(term); var children = GetChildren(term);
term.Container = parentTerm == null ? taxonomy.ContentItem : parentTerm.ContentItem; term.Container = parentTerm == null ? taxonomy.ContentItem : parentTerm.ContentItem;
ProcessPath(term); ProcessPath(term);
string previousFullWeight = term.FullWeight;
ProcessFullWeight(term, parentTerm);
var contentItem = _contentManager.Get(term.ContentItem.Id, VersionOptions.DraftRequired); var contentItem = _contentManager.Get(term.ContentItem.Id, VersionOptions.DraftRequired);
_contentManager.Publish(contentItem); _contentManager.Publish(contentItem);
foreach (var childTerm in children) { foreach (var childTerm in children) {
ProcessPath(childTerm); ProcessPath(childTerm);
childTerm.FullWeight = ProcessChildrenFullWeight(childTerm.FullWeight, term.FullWeight, previousFullWeight);
contentItem = _contentManager.Get(childTerm.ContentItem.Id, VersionOptions.DraftRequired); contentItem = _contentManager.Get(childTerm.ContentItem.Id, VersionOptions.DraftRequired);
_contentManager.Publish(contentItem); _contentManager.Publish(contentItem);
} }
} }
public void ProcessFullWeight(TermPart term, TermPart parentTerm) {
term.FullWeight = (parentTerm != null ? parentTerm.FullWeight : "") + term.Weight.ToString("D6") + "." + term.Id + "/";
}
public string ProcessChildrenFullWeight(string childrenFullWeight, string parentFullWeight, string parentOldFullWeight) {
if (string.IsNullOrWhiteSpace(childrenFullWeight)){
childrenFullWeight = parentFullWeight;
}
int pos = childrenFullWeight.IndexOf(parentOldFullWeight);
return childrenFullWeight.Substring(0, pos) + parentFullWeight + childrenFullWeight.Substring(pos + parentOldFullWeight.Length);
}
public void ProcessPath(TermPart term) { public void ProcessPath(TermPart term) {
var parentTerm = term.Container.As<TermPart>(); var parentTerm = term.Container.As<TermPart>();
term.Path = parentTerm != null ? parentTerm.FullPath + "/" : "/"; term.Path = parentTerm != null ? parentTerm.FullPath + "/" : "/";

View File

@@ -97,9 +97,10 @@ namespace Orchard.Taxonomies.Services {
new public IEnumerable<TermPart> GetTerms(int taxonomyId) { new public IEnumerable<TermPart> GetTerms(int taxonomyId) {
var result = _contentManager.Query<TermPart, TermPartRecord>().ForVersion(VersionOptions.Latest) var result = _contentManager.Query<TermPart, TermPartRecord>().ForVersion(VersionOptions.Latest)
.Where(x => x.TaxonomyId == taxonomyId) .Where(x => x.TaxonomyId == taxonomyId)
.OrderBy(x=>x.FullWeight)
.List(); .List();
return TermPart.Sort(result); return result;
} }
new public TermPart GetTermByPath(string path) { new public TermPart GetTermByPath(string path) {
@@ -113,8 +114,10 @@ namespace Orchard.Taxonomies.Services {
new public IEnumerable<TermPart> GetAllTerms() { new public IEnumerable<TermPart> GetAllTerms() {
var result = _contentManager var result = _contentManager
.Query<TermPart, TermPartRecord>().ForVersion(VersionOptions.Latest) .Query<TermPart, TermPartRecord>().ForVersion(VersionOptions.Latest)
.OrderBy(x=>x.TaxonomyId)
.OrderBy(x=>x.FullWeight)
.List(); .List();
return TermPart.Sort(result); return result;
} }
new public TermPart GetTerm(int id) { new public TermPart GetTerm(int id) {

View File

@@ -1,11 +1,15 @@
using System; using System;
using System.Linq; using System.Linq;
using System.Net;
using System.Web.Mvc; using System.Web.Mvc;
using Orchard; using Orchard;
using Orchard.ContentManagement;
using Orchard.Environment.Features; using Orchard.Environment.Features;
using Orchard.Localization; using Orchard.Localization;
using Orchard.Logging; using Orchard.Logging;
using Orchard.Security; using Orchard.Security;
using Orchard.Taxonomies.Models;
using Orchard.Taxonomies.Services;
using Orchard.UI.Admin; using Orchard.UI.Admin;
using Orchard.UI.Notify; using Orchard.UI.Notify;
using Upgrade.Services; using Upgrade.Services;
@@ -15,15 +19,18 @@ namespace Upgrade.Controllers {
public class TaxonomyController : Controller { public class TaxonomyController : Controller {
private readonly IUpgradeService _upgradeService; private readonly IUpgradeService _upgradeService;
private readonly IOrchardServices _orchardServices; private readonly IOrchardServices _orchardServices;
private readonly ITaxonomyService _taxonomyService;
private readonly IFeatureManager _featureManager; private readonly IFeatureManager _featureManager;
public TaxonomyController( public TaxonomyController(
IUpgradeService upgradeService, IUpgradeService upgradeService,
IOrchardServices orchardServices, IOrchardServices orchardServices,
IFeatureManager featureManager) { IFeatureManager featureManager,
ITaxonomyService taxonomyService) {
_upgradeService = upgradeService; _upgradeService = upgradeService;
_orchardServices = orchardServices; _orchardServices = orchardServices;
_featureManager = featureManager; _featureManager = featureManager;
_taxonomyService = taxonomyService;
} }
public Localizer T { get; set; } public Localizer T { get; set; }
@@ -71,5 +78,24 @@ namespace Upgrade.Controllers {
return RedirectToAction("Index"); return RedirectToAction("Index");
} }
[HttpPost]
public JsonResult MigrateTerms(int id) {
var lastContentItemId = id;
foreach (var taxonomy in _taxonomyService.GetTaxonomies()) {
foreach (var term in TermPart.Sort(_taxonomyService.GetTerms(taxonomy.Id))) {
term.FullWeight = "";
var container = term.Container.As<TermPart>();
for (int i = 0; i < term.Path.Count(x => x == '/')-1; i++) {
term.FullWeight = container.Weight.ToString("D6") + "." + container.Id + "/" + term.FullWeight;
container = container.Container.As<TermPart>();
}
term.FullWeight = term.FullWeight + term.Weight.ToString("D6") + "." + term.Id + "/";
lastContentItemId = term.Id;
}
}
return new JsonResult { Data = lastContentItemId };
}
} }
} }

View File

@@ -146,6 +146,10 @@
<Project>{73a7688a-5bd3-4f7e-adfa-ce36c5a10e3b}</Project> <Project>{73a7688a-5bd3-4f7e-adfa-ce36c5a10e3b}</Project>
<Name>Orchard.MediaLibrary</Name> <Name>Orchard.MediaLibrary</Name>
</ProjectReference> </ProjectReference>
<ProjectReference Include="..\Orchard.Taxonomies\Orchard.Taxonomies.csproj">
<Project>{E649EA64-D213-461B-87F7-D67035801443}</Project>
<Name>Orchard.Taxonomies</Name>
</ProjectReference>
<ProjectReference Include="..\Orchard.Widgets\Orchard.Widgets.csproj"> <ProjectReference Include="..\Orchard.Widgets\Orchard.Widgets.csproj">
<Project>{194d3ccc-1153-474d-8176-fde8d7d0d0bd}</Project> <Project>{194d3ccc-1153-474d-8176-fde8d7d0d0bd}</Project>
<Name>Orchard.Widgets</Name> <Name>Orchard.Widgets</Name>

View File

@@ -1,6 +1,11 @@
@using Orchard.Utility.Extensions @using Orchard.Utility.Extensions
@{ Layout.Title = T("Migrate Taxonomies").ToString(); } @{
Script.Require("jQuery");
Layout.Title = T("Migrate Taxonomies").ToString();
}
<div class="message message-Warning" id="message-progress" style="display: none"></div>
@using (Html.BeginFormAntiForgeryPost()) { @using (Html.BeginFormAntiForgeryPost()) {
Html.ValidationSummary(); Html.ValidationSummary();
@@ -15,3 +20,51 @@
} }
</fieldset> </fieldset>
} }
<fieldset>
<legend>@T("Migrating Terms: ")</legend>
<span class="hint">@T("This migration step will update all existing terms so they are lexicographically orderable")</span>
<button type="button" class="button button-migrate" data-url="@Url.Action("MigrateTerms", "Taxonomy")">@T("Migrate")</button>
</fieldset>
@using (Script.Foot()) {
<script type="text/javascript">
$(function() {
var antiForgeryToken = '@HttpUtility.JavaScriptStringEncode(Html.AntiForgeryTokenValueOrchard().ToString())';
var endMessage = '@HttpUtility.JavaScriptStringEncode(T("All terms have been processed").Text)';
$('.button-migrate').click(function () {
var importUrl = $(this).data('url');
var startId = 0;
$('#message-progress').show();
var iId = setInterval(function () {
$.ajax({
type: 'POST',
url: importUrl,
async: false,
data: {
__RequestVerificationToken: antiForgeryToken,
id: startId // start at index 0
},
success: function (data) {
if (Number(data) == startId) {
clearInterval(iId);
$('#message-progress').text(endMessage);
}
else {
startId = Number(data);
$('#message-progress').text('Processing content item ' + startId);
}
},
fail: function(result) {
console.log("An error occured: " + result);
}
});
}, 100);
});
});
</script>
}