#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 allTerms = TermPart.Sort(_taxonomyService.GetTermsQuery(taxonomyId).List());
var termsPage = pager.PageSize > 0 ? allTerms.Skip(pager.GetStartIndex()).Take(pager.PageSize) : allTerms;
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 pagerShape = Shape.Pager(pager).TotalItemCount(allTerms.Count());
@@ -90,7 +89,9 @@ namespace Orchard.Taxonomies.Controllers {
foreach (var entry in checkedEntries) {
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));

View File

@@ -13,6 +13,7 @@ using Orchard.Mvc;
using Orchard.Settings;
using Orchard.Taxonomies.Settings;
using Orchard.UI.Navigation;
using System.Text;
namespace Orchard.Taxonomies.Drivers {
public class TermPartDriver : ContentPartDriver<TermPart> {
@@ -93,7 +94,22 @@ namespace Orchard.Taxonomies.Drivers {
}
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);
}
@@ -102,6 +118,7 @@ namespace Orchard.Taxonomies.Drivers {
context.Element(part.PartDefinition.Name).SetAttributeValue("Count", part.Count);
context.Element(part.PartDefinition.Name).SetAttributeValue("Selectable", part.Selectable);
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 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.Selectable = Boolean.Parse(context.Attribute(part.PartDefinition.Name, "Selectable"));
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 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)) {
var pathContentItem = context.GetItemFromSession(identityPath);
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 System.Data;
using Orchard.Data.Migration;
namespace Orchard.Taxonomies {
@@ -100,5 +101,12 @@ namespace Orchard.Taxonomies {
);
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); }
}
public string FullWeight {
get { return Record.FullWeight; }
set { Record.FullWeight = value; }
}
public string FullPath { get { return String.Concat(Path, Id); } }
public static IEnumerable<TermPart> Sort(IEnumerable<TermPart> terms) {
@@ -59,6 +64,7 @@ namespace Orchard.Taxonomies.Models {
return list.OrderBy(x => x, new TermsComparer(index));
}
[Obsolete]
private class TermsComparer : IComparer<TermPart> {
private readonly IDictionary<string, TermPart> _index;

View File

@@ -9,5 +9,6 @@ namespace Orchard.Taxonomies.Models {
public virtual int Count { get; set; }
public virtual bool Selectable { 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">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Net.Http" />
<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 MoveTerm(TaxonomyPart taxonomy, TermPart term, TermPart parentTerm);
void ProcessPath(TermPart term);
void ProcessFullWeight(TermPart term, TermPart parentTerm);
string ProcessChildrenFullWeight(string childrenFullWeight, string parentFullWeight, string parentOldFullWeight);
IContentQuery<TermPart, TermPartRecord> GetTermsQuery(int taxonomyId);
string GenerateTermTypeName(string taxonomyName);

View File

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

View File

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

View File

@@ -1,11 +1,15 @@
using System;
using System.Linq;
using System.Net;
using System.Web.Mvc;
using Orchard;
using Orchard.ContentManagement;
using Orchard.Environment.Features;
using Orchard.Localization;
using Orchard.Logging;
using Orchard.Security;
using Orchard.Taxonomies.Models;
using Orchard.Taxonomies.Services;
using Orchard.UI.Admin;
using Orchard.UI.Notify;
using Upgrade.Services;
@@ -15,22 +19,25 @@ namespace Upgrade.Controllers {
public class TaxonomyController : Controller {
private readonly IUpgradeService _upgradeService;
private readonly IOrchardServices _orchardServices;
private readonly ITaxonomyService _taxonomyService;
private readonly IFeatureManager _featureManager;
public TaxonomyController(
IUpgradeService upgradeService,
IOrchardServices orchardServices,
IFeatureManager featureManager) {
IFeatureManager featureManager,
ITaxonomyService taxonomyService) {
_upgradeService = upgradeService;
_orchardServices = orchardServices;
_featureManager = featureManager;
_taxonomyService = taxonomyService;
}
public Localizer T { get; set; }
public ILogger Logger { get; set; }
public ActionResult Index() {
ViewBag.CanMigrate = false;
ViewBag.CanMigrate = false;
if(_featureManager.GetEnabledFeatures().All(x => x.Id != "Orchard.Taxonomies")) {
_orchardServices.Notifier.Warning(T("You need to enable Orchard.Taxonomies in order to migrate Contrib.Taxonomies to Orchard.Taxonomies."));
@@ -45,7 +52,7 @@ namespace Upgrade.Controllers {
_orchardServices.Notifier.Warning(T("This migration step might have been done already."));
}
ViewBag.CanMigrate = true;
ViewBag.CanMigrate = true;
}
return View();
@@ -71,5 +78,24 @@ namespace Upgrade.Controllers {
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>
<Name>Orchard.MediaLibrary</Name>
</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">
<Project>{194d3ccc-1153-474d-8176-fde8d7d0d0bd}</Project>
<Name>Orchard.Widgets</Name>

View File

@@ -1,6 +1,11 @@
@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()) {
Html.ValidationSummary();
@@ -14,4 +19,52 @@
<button type="submit">@T("Migrate")</button>
}
</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>
}