diff --git a/src/Orchard.Web/Modules/Orchard.Taxonomies/Controllers/TermAdminController.cs b/src/Orchard.Web/Modules/Orchard.Taxonomies/Controllers/TermAdminController.cs index 26d78da1f..1d6fac751 100644 --- a/src/Orchard.Web/Modules/Orchard.Taxonomies/Controllers/TermAdminController.cs +++ b/src/Orchard.Web/Modules/Orchard.Taxonomies/Controllers/TermAdminController.cs @@ -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)); diff --git a/src/Orchard.Web/Modules/Orchard.Taxonomies/Drivers/TermPartDriver.cs b/src/Orchard.Web/Modules/Orchard.Taxonomies/Drivers/TermPartDriver.cs index 601d28a49..f6f132c5c 100644 --- a/src/Orchard.Web/Modules/Orchard.Taxonomies/Drivers/TermPartDriver.cs +++ b/src/Orchard.Web/Modules/Orchard.Taxonomies/Drivers/TermPartDriver.cs @@ -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 { @@ -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(); + 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().Weight.ToString("D6") + "." + pathContentItem.Id.ToString() + "/"; + } + } + if (createFullWeigth) { + part.FullWeight = part.FullWeight + part.Weight.ToString("D6") + "." + part.Id + "/"; } } diff --git a/src/Orchard.Web/Modules/Orchard.Taxonomies/Migrations.cs b/src/Orchard.Web/Modules/Orchard.Taxonomies/Migrations.cs index f3b32af00..9f795c32e 100644 --- a/src/Orchard.Web/Modules/Orchard.Taxonomies/Migrations.cs +++ b/src/Orchard.Web/Modules/Orchard.Taxonomies/Migrations.cs @@ -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; + } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Taxonomies/Models/TermPart.cs b/src/Orchard.Web/Modules/Orchard.Taxonomies/Models/TermPart.cs index 34a639f53..7e7455de2 100644 --- a/src/Orchard.Web/Modules/Orchard.Taxonomies/Models/TermPart.cs +++ b/src/Orchard.Web/Modules/Orchard.Taxonomies/Models/TermPart.cs @@ -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 Sort(IEnumerable terms) { @@ -59,6 +64,7 @@ namespace Orchard.Taxonomies.Models { return list.OrderBy(x => x, new TermsComparer(index)); } + [Obsolete] private class TermsComparer : IComparer { private readonly IDictionary _index; diff --git a/src/Orchard.Web/Modules/Orchard.Taxonomies/Models/TermPartRecord.cs b/src/Orchard.Web/Modules/Orchard.Taxonomies/Models/TermPartRecord.cs index 22df72df6..3f5a8f24a 100644 --- a/src/Orchard.Web/Modules/Orchard.Taxonomies/Models/TermPartRecord.cs +++ b/src/Orchard.Web/Modules/Orchard.Taxonomies/Models/TermPartRecord.cs @@ -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; } } } diff --git a/src/Orchard.Web/Modules/Orchard.Taxonomies/Orchard.Taxonomies.csproj b/src/Orchard.Web/Modules/Orchard.Taxonomies/Orchard.Taxonomies.csproj index 8b3584c3b..558129785 100644 --- a/src/Orchard.Web/Modules/Orchard.Taxonomies/Orchard.Taxonomies.csproj +++ b/src/Orchard.Web/Modules/Orchard.Taxonomies/Orchard.Taxonomies.csproj @@ -64,6 +64,7 @@ 3.5 + diff --git a/src/Orchard.Web/Modules/Orchard.Taxonomies/Services/ITaxonomyService.cs b/src/Orchard.Web/Modules/Orchard.Taxonomies/Services/ITaxonomyService.cs index a8da7e4c8..c001fe52a 100644 --- a/src/Orchard.Web/Modules/Orchard.Taxonomies/Services/ITaxonomyService.cs +++ b/src/Orchard.Web/Modules/Orchard.Taxonomies/Services/ITaxonomyService.cs @@ -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 GetTermsQuery(int taxonomyId); string GenerateTermTypeName(string taxonomyName); diff --git a/src/Orchard.Web/Modules/Orchard.Taxonomies/Services/TaxonomyService.cs b/src/Orchard.Web/Modules/Orchard.Taxonomies/Services/TaxonomyService.cs index 2bcd40587..39ef27847 100644 --- a/src/Orchard.Web/Modules/Orchard.Taxonomies/Services/TaxonomyService.cs +++ b/src/Orchard.Web/Modules/Orchard.Taxonomies/Services/TaxonomyService.cs @@ -167,17 +167,19 @@ namespace Orchard.Taxonomies.Services { public IEnumerable GetTerms(int taxonomyId) { var result = _contentManager.Query() .Where(x => x.TaxonomyId == taxonomyId) + .OrderBy(x => x.FullWeight) .List(); - return TermPart.Sort(result); + return result; } public IEnumerable GetRootTerms(int taxonomyId) { var result = _contentManager.Query() .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 GetAllTerms() { var result = _contentManager .Query() + .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() .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 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(); term.Path = parentTerm != null ? parentTerm.FullPath + "/" : "/"; diff --git a/src/Orchard.Web/Modules/Orchard.Taxonomies/Services/TaxonomyServiceDraftable.cs b/src/Orchard.Web/Modules/Orchard.Taxonomies/Services/TaxonomyServiceDraftable.cs index 18f7221ad..dd97fb797 100644 --- a/src/Orchard.Web/Modules/Orchard.Taxonomies/Services/TaxonomyServiceDraftable.cs +++ b/src/Orchard.Web/Modules/Orchard.Taxonomies/Services/TaxonomyServiceDraftable.cs @@ -97,9 +97,10 @@ namespace Orchard.Taxonomies.Services { new public IEnumerable GetTerms(int taxonomyId) { var result = _contentManager.Query().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 GetAllTerms() { var result = _contentManager .Query().ForVersion(VersionOptions.Latest) + .OrderBy(x=>x.TaxonomyId) + .OrderBy(x=>x.FullWeight) .List(); - return TermPart.Sort(result); + return result; } new public TermPart GetTerm(int id) { diff --git a/src/Orchard.Web/Modules/Upgrade/Controllers/TaxonomyController.cs b/src/Orchard.Web/Modules/Upgrade/Controllers/TaxonomyController.cs index 228c462cc..c371a8c47 100644 --- a/src/Orchard.Web/Modules/Upgrade/Controllers/TaxonomyController.cs +++ b/src/Orchard.Web/Modules/Upgrade/Controllers/TaxonomyController.cs @@ -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(); + 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(); + } + term.FullWeight = term.FullWeight + term.Weight.ToString("D6") + "." + term.Id + "/"; + lastContentItemId = term.Id; + } + } + return new JsonResult { Data = lastContentItemId }; + } + } } diff --git a/src/Orchard.Web/Modules/Upgrade/Upgrade.csproj b/src/Orchard.Web/Modules/Upgrade/Upgrade.csproj index d776269c0..a2d206c66 100644 --- a/src/Orchard.Web/Modules/Upgrade/Upgrade.csproj +++ b/src/Orchard.Web/Modules/Upgrade/Upgrade.csproj @@ -146,6 +146,10 @@ {73a7688a-5bd3-4f7e-adfa-ce36c5a10e3b} Orchard.MediaLibrary + + {E649EA64-D213-461B-87F7-D67035801443} + Orchard.Taxonomies + {194d3ccc-1153-474d-8176-fde8d7d0d0bd} Orchard.Widgets diff --git a/src/Orchard.Web/Modules/Upgrade/Views/Taxonomy/Index.cshtml b/src/Orchard.Web/Modules/Upgrade/Views/Taxonomy/Index.cshtml index 5287ca6b1..9840a7442 100644 --- a/src/Orchard.Web/Modules/Upgrade/Views/Taxonomy/Index.cshtml +++ b/src/Orchard.Web/Modules/Upgrade/Views/Taxonomy/Index.cshtml @@ -1,6 +1,11 @@ @using Orchard.Utility.Extensions -@{ Layout.Title = T("Migrate Taxonomies").ToString(); } +@{ + Script.Require("jQuery"); + Layout.Title = T("Migrate Taxonomies").ToString(); +} + + @using (Html.BeginFormAntiForgeryPost()) { Html.ValidationSummary(); @@ -14,4 +19,52 @@ } -} \ No newline at end of file +} + +
+ @T("Migrating Terms: ") + @T("This migration step will update all existing terms so they are lexicographically orderable") + +
+ +@using (Script.Foot()) { + +}