public override Model.ProvisioningTemplate ExtractObjects(Web web, Model.ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo) { using (var scope = new PnPMonitoredScope(this.Name)) { if (creationInfo.IncludeSiteCollectionTermGroup || creationInfo.IncludeAllTermGroups) { // Find the site collection termgroup, if any TaxonomySession session = TaxonomySession.GetTaxonomySession(web.Context); TermStore termStore = null; try { termStore = session.GetDefaultSiteCollectionTermStore(); web.Context.Load(termStore, t => t.Id, t => t.DefaultLanguage, t => t.OrphanedTermsTermSet); web.Context.ExecuteQueryRetry(); } catch (ServerException) { // Skip the exception and go to the next check } if (null == termStore || termStore.ServerObjectIsNull()) { // If the GetDefaultSiteCollectionTermStore method call fails ... raise a specific Warning WriteMessage(CoreResources.Provisioning_ObjectHandlers_TermGroups_Wrong_Configuration, ProvisioningMessageType.Warning); // and exit skipping the current handler return(template); } var orphanedTermsTermSetId = default(Guid); if (!termStore.OrphanedTermsTermSet.ServerObjectIsNull()) { termStore.OrphanedTermsTermSet.EnsureProperty(ts => ts.Id); orphanedTermsTermSetId = termStore.OrphanedTermsTermSet.Id; if (termStore.ServerObjectIsNull.Value) { termStore = session.GetDefaultKeywordsTermStore(); web.Context.Load(termStore, t => t.Id, t => t.DefaultLanguage); web.Context.ExecuteQueryRetry(); } } var propertyBagKey = $"SiteCollectionGroupId{termStore.Id}"; // Ensure to grab the property from the rootweb var site = (web.Context as ClientContext).Site; web.Context.Load(site, s => s.RootWeb); web.Context.ExecuteQueryRetry(); var siteCollectionTermGroupId = site.RootWeb.GetPropertyBagValueString(propertyBagKey, ""); Guid termGroupGuid; Guid.TryParse(siteCollectionTermGroupId, out termGroupGuid); List <TermGroup> termGroups = new List <TermGroup>(); if (creationInfo.IncludeAllTermGroups) { web.Context.Load(termStore.Groups, groups => groups.Include(tg => tg.Name, tg => tg.Id, tg => tg.Description, tg => tg.TermSets.IncludeWithDefaultProperties(ts => ts.CustomSortOrder))); web.Context.ExecuteQueryRetry(); termGroups = termStore.Groups.ToList(); } else { if (termGroupGuid != Guid.Empty) { var termGroup = termStore.GetGroup(termGroupGuid); web.Context.Load(termGroup, tg => tg.Name, tg => tg.Id, tg => tg.Description, tg => tg.TermSets.IncludeWithDefaultProperties(ts => ts.Description, ts => ts.CustomSortOrder)); web.Context.ExecuteQueryRetry(); termGroups = new List <TermGroup>() { termGroup }; } } foreach (var termGroup in termGroups) { Boolean isSiteCollectionTermGroup = termGroupGuid != Guid.Empty && termGroup.Id == termGroupGuid; var modelTermGroup = new Model.TermGroup { Name = isSiteCollectionTermGroup ? "{sitecollectiontermgroupname}" : termGroup.Name, Id = isSiteCollectionTermGroup ? Guid.Empty : termGroup.Id, Description = termGroup.Description, SiteCollectionTermGroup = isSiteCollectionTermGroup }; #if !ONPREMISES // If we need to include TermGroups security if (creationInfo.IncludeTermGroupsSecurity) { termGroup.EnsureProperties(tg => tg.ContributorPrincipalNames, tg => tg.GroupManagerPrincipalNames); // Extract the TermGroup contributors modelTermGroup.Contributors.AddRange( from c in termGroup.ContributorPrincipalNames select new Model.User { Name = c }); // Extract the TermGroup managers modelTermGroup.Managers.AddRange( from m in termGroup.GroupManagerPrincipalNames select new Model.User { Name = m }); } #endif web.EnsureProperty(w => w.Url); foreach (var termSet in termGroup.TermSets) { // Do not include the orphan term set if (termSet.Id == orphanedTermsTermSetId) { continue; } // Extract all other term sets var modelTermSet = new Model.TermSet(); modelTermSet.Name = termSet.Name; if (!isSiteCollectionTermGroup) { modelTermSet.Id = termSet.Id; } modelTermSet.IsAvailableForTagging = termSet.IsAvailableForTagging; modelTermSet.IsOpenForTermCreation = termSet.IsOpenForTermCreation; modelTermSet.Description = termSet.Description; modelTermSet.Terms.AddRange(GetTerms <TermSet>(web.Context, termSet, termStore.DefaultLanguage, isSiteCollectionTermGroup)); foreach (var property in termSet.CustomProperties) { if (property.Key.Equals("_Sys_Nav_AttachedWeb_SiteId", StringComparison.InvariantCultureIgnoreCase)) { modelTermSet.Properties.Add(property.Key, "{sitecollectionid}"); } else if (property.Key.Equals("_Sys_Nav_AttachedWeb_WebId", StringComparison.InvariantCultureIgnoreCase)) { modelTermSet.Properties.Add(property.Key, "{siteid}"); } else { modelTermSet.Properties.Add(property.Key, Tokenize(property.Value, web.Url, web)); } } modelTermGroup.TermSets.Add(modelTermSet); } template.TermGroups.Add(modelTermGroup); } } } return(template); }
public override Model.ProvisioningTemplate ExtractObjects(Web web, Model.ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo) { if (creationInfo.IncludeSiteCollectionTermGroup || creationInfo.IncludeAllTermGroups) { // Find the site collection termgroup, if any TaxonomySession session = TaxonomySession.GetTaxonomySession(web.Context); var termStore = session.GetDefaultSiteCollectionTermStore(); web.Context.Load(termStore, t => t.Id, t => t.DefaultLanguage); web.Context.ExecuteQueryRetry(); List <TermGroup> termGroups = new List <TermGroup>(); if (creationInfo.IncludeAllTermGroups) { web.Context.Load(termStore.Groups, groups => groups.Include(tg => tg.Name, tg => tg.Id, tg => tg.Description, tg => tg.TermSets.IncludeWithDefaultProperties(ts => ts.CustomSortOrder))); web.Context.ExecuteQueryRetry(); termGroups = termStore.Groups.ToList(); } else { var propertyBagKey = string.Format("SiteCollectionGroupId{0}", termStore.Id); var siteCollectionTermGroupId = web.GetPropertyBagValueString(propertyBagKey, ""); Guid termGroupGuid = Guid.Empty; if (Guid.TryParse(siteCollectionTermGroupId, out termGroupGuid)) { var termGroup = termStore.GetGroup(termGroupGuid); web.Context.Load(termGroup, tg => tg.Name, tg => tg.Id, tg => tg.Description, tg => tg.TermSets.IncludeWithDefaultProperties(ts => ts.CustomSortOrder)); web.Context.ExecuteQueryRetry(); termGroups = new List <TermGroup>() { termGroup }; } } foreach (var termGroup in termGroups) { var modelTermGroup = new Model.TermGroup { Name = termGroup.Name, Id = termGroup.Id, Description = termGroup.Description }; foreach (var termSet in termGroup.TermSets) { var modelTermSet = new Model.TermSet(); modelTermSet.Name = termSet.Name; modelTermSet.Id = termSet.Id; modelTermSet.IsAvailableForTagging = termSet.IsAvailableForTagging; modelTermSet.IsOpenForTermCreation = termSet.IsOpenForTermCreation; modelTermSet.Description = termSet.Description; modelTermSet.Terms.AddRange(GetTerms <TermSet>(web.Context, termSet, termStore.DefaultLanguage)); foreach (var property in termSet.CustomProperties) { modelTermSet.Properties.Add(property.Key, property.Value); } modelTermGroup.TermSets.Add(modelTermSet); } template.TermGroups.Add(modelTermGroup); } } return(template); }
internal static List <ReusedTerm> ProcessGroup(ClientContext context, TaxonomySession session, TermStore termStore, Model.TermGroup modelTermGroup, TermGroup siteCollectionTermGroup, TokenParser parser, PnPMonitoredScope scope) { List <ReusedTerm> reusedTerms = new List <ReusedTerm>(); SiteCollectionTermGroupNameToken siteCollectionTermGroupNameToken = new SiteCollectionTermGroupNameToken(context.Web); #region Group var newGroup = false; var modelGroupName = parser.ParseString(modelTermGroup.Name); var normalizedGroupName = TaxonomyItem.NormalizeName(context, modelGroupName); context.ExecuteQueryRetry(); TermGroup group = termStore.Groups.FirstOrDefault( g => g.Id == modelTermGroup.Id || g.Name == normalizedGroupName.Value); if (group == null) { var parsedDescription = parser.ParseString(modelTermGroup.Description); if (modelTermGroup.Name == "Site Collection" || modelGroupName == siteCollectionTermGroupNameToken.GetReplaceValue() || modelTermGroup.SiteCollectionTermGroup) { var site = (context as ClientContext).Site; group = termStore.GetSiteCollectionGroup(site, true); context.Load(group, g => g.Name, g => g.Id, g => g.TermSets.Include( tset => tset.Name, tset => tset.Id)); context.ExecuteQueryRetry(); } else { group = termStore.Groups.FirstOrDefault(g => g.Name == normalizedGroupName.Value); if (group == null) { if (modelTermGroup.Id == Guid.Empty) { modelTermGroup.Id = Guid.NewGuid(); } group = termStore.CreateGroup(modelGroupName, modelTermGroup.Id); group.Description = parsedDescription; // Handle TermGroup Contributors, if any if (modelTermGroup.Contributors != null && modelTermGroup.Contributors.Count > 0) { foreach (var c in modelTermGroup.Contributors) { group.AddContributor(c.Name); } } // Handle TermGroup Managers, if any if (modelTermGroup.Managers != null && modelTermGroup.Managers.Count > 0) { foreach (var m in modelTermGroup.Managers) { group.AddGroupManager(m.Name); } } termStore.CommitAll(); context.Load(group); context.Load(termStore); context.ExecuteQueryRetry(); newGroup = true; } } } #endregion session.UpdateCache(); session.Context.ExecuteQueryRetry(); #region TermSets foreach (var modelTermSet in modelTermGroup.TermSets) { TermSet set = null; var newTermSet = false; var normalizedTermSetName = TaxonomyItem.NormalizeName(context, parser.ParseString(modelTermSet.Name)); context.ExecuteQueryRetry(); if (!newGroup) { set = group.TermSets.FirstOrDefault( ts => ts.Id == modelTermSet.Id || ts.Name == normalizedTermSetName.Value); } if (set == null) { if (modelTermSet.Id == Guid.Empty) { modelTermSet.Id = Guid.NewGuid(); } else { if (CheckIfTermSetIdIsUnique(termStore, modelTermSet.Id) == false) { throw new Exception($"Termset ID {modelTermSet.Id} is already present in termstore"); } } var termSetLanguage = modelTermSet.Language.HasValue ? modelTermSet.Language.Value : termStore.DefaultLanguage; set = group.CreateTermSet(normalizedTermSetName.Value, modelTermSet.Id, termSetLanguage); parser.AddToken(new TermSetIdToken(context.Web, group.Name, normalizedTermSetName.Value, modelTermSet.Id)); if (siteCollectionTermGroup != null && !siteCollectionTermGroup.ServerObjectIsNull.Value) { if (group.Name == siteCollectionTermGroup.Name) { parser.AddToken((new SiteCollectionTermSetIdToken(context.Web, normalizedTermSetName.Value, modelTermSet.Id))); } } newTermSet = true; if (!string.IsNullOrEmpty(modelTermSet.Description)) { set.Description = parser.ParseString(modelTermSet.Description); } set.IsOpenForTermCreation = modelTermSet.IsOpenForTermCreation; set.IsAvailableForTagging = modelTermSet.IsAvailableForTagging; foreach (var property in modelTermSet.Properties) { set.SetCustomProperty(property.Key, parser.ParseString(property.Value)); } if (modelTermSet.Owner != null) { set.Owner = parser.ParseString(modelTermSet.Owner); } termStore.CommitAll(); context.Load(set); context.ExecuteQueryRetry(); } context.Load(set, s => s.Terms.Include(t => t.Id, t => t.Name)); context.ExecuteQueryRetry(); var terms = set.Terms; foreach (var modelTerm in modelTermSet.Terms) { if (!newTermSet) { if (terms.Any()) { var term = terms.FirstOrDefault(t => t.Id == modelTerm.Id); if (term == null) { var normalizedTermName = TaxonomyItem.NormalizeName(context, parser.ParseString(modelTerm.Name)); context.ExecuteQueryRetry(); term = terms.FirstOrDefault(t => t.Name == normalizedTermName.Value); if (term == null) { var returnTuple = CreateTerm(context, modelTerm, set, termStore, parser, scope); if (returnTuple != null) { modelTerm.Id = returnTuple.Item1; parser = returnTuple.Item2; } reusedTerms.AddRange(returnTuple.Item3); } else { // todo: add handling for reused term? modelTerm.Id = term.Id; } } else { // todo: add handling for reused term? modelTerm.Id = term.Id; } if (term != null) { CheckChildTerms(context, modelTerm, term, termStore, parser, scope); } } else { var returnTuple = CreateTerm(context, modelTerm, set, termStore, parser, scope); if (returnTuple != null) { modelTerm.Id = returnTuple.Item1; parser = returnTuple.Item2; } reusedTerms.AddRange(returnTuple.Item3); } } else { var returnTuple = CreateTerm(context, modelTerm, set, termStore, parser, scope); if (returnTuple != null) { modelTerm.Id = returnTuple.Item1; parser = returnTuple.Item2; } reusedTerms.AddRange(returnTuple.Item3); } } // do we need custom sorting? if (modelTermSet.Terms.Any(t => t.CustomSortOrder > 0)) { var sortedTerms = modelTermSet.Terms.OrderBy(t => t.CustomSortOrder); var customSortString = sortedTerms.Aggregate(string.Empty, (a, i) => a + i.Id.ToString() + ":"); customSortString = customSortString.TrimEnd(new[] { ':' }); set.CustomSortOrder = customSortString; termStore.CommitAll(); context.ExecuteQueryRetry(); } } #endregion return(reusedTerms); }
public override Model.ProvisioningTemplate ExtractObjects(Web web, Model.ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo) { using (var scope = new PnPMonitoredScope(this.Name)) { if (creationInfo.IncludeSiteCollectionTermGroup || creationInfo.IncludeAllTermGroups) { // Find the site collection termgroup, if any TaxonomySession session = TaxonomySession.GetTaxonomySession(web.Context); var termStore = session.GetDefaultSiteCollectionTermStore(); web.Context.Load(termStore, t => t.Id, t => t.DefaultLanguage, t => t.OrphanedTermsTermSet); web.Context.ExecuteQueryRetry(); var orphanedTermsTermSetId = termStore.OrphanedTermsTermSet.Id; if (termStore.ServerObjectIsNull.Value) { termStore = session.GetDefaultKeywordsTermStore(); web.Context.Load(termStore, t => t.Id, t => t.DefaultLanguage); web.Context.ExecuteQueryRetry(); } var propertyBagKey = string.Format("SiteCollectionGroupId{0}", termStore.Id); var siteCollectionTermGroupId = web.GetPropertyBagValueString(propertyBagKey, ""); Guid termGroupGuid = Guid.Empty; Guid.TryParse(siteCollectionTermGroupId, out termGroupGuid); List <TermGroup> termGroups = new List <TermGroup>(); if (creationInfo.IncludeAllTermGroups) { web.Context.Load(termStore.Groups, groups => groups.Include(tg => tg.Name, tg => tg.Id, tg => tg.Description, tg => tg.TermSets.IncludeWithDefaultProperties(ts => ts.CustomSortOrder))); web.Context.ExecuteQueryRetry(); termGroups = termStore.Groups.ToList(); } else { if (termGroupGuid != Guid.Empty) { var termGroup = termStore.GetGroup(termGroupGuid); web.Context.Load(termGroup, tg => tg.Name, tg => tg.Id, tg => tg.Description, tg => tg.TermSets.IncludeWithDefaultProperties(ts => ts.CustomSortOrder)); web.Context.ExecuteQueryRetry(); termGroups = new List <TermGroup>() { termGroup }; } } foreach (var termGroup in termGroups) { Boolean isSiteCollectionTermGroup = termGroupGuid != Guid.Empty && termGroup.Id == termGroupGuid; var modelTermGroup = new Model.TermGroup { Name = isSiteCollectionTermGroup ? "{sitecollectiontermgroupname}" : termGroup.Name, Id = isSiteCollectionTermGroup ? Guid.Empty : termGroup.Id, Description = termGroup.Description }; foreach (var termSet in termGroup.TermSets) { // Do not include the orphan term set if (termSet.Id == orphanedTermsTermSetId) { continue; } // Extract all other term sets var modelTermSet = new Model.TermSet(); modelTermSet.Name = termSet.Name; if (!isSiteCollectionTermGroup) { modelTermSet.Id = termSet.Id; } modelTermSet.IsAvailableForTagging = termSet.IsAvailableForTagging; modelTermSet.IsOpenForTermCreation = termSet.IsOpenForTermCreation; modelTermSet.Description = termSet.Description; modelTermSet.Terms.AddRange(GetTerms <TermSet>(web.Context, termSet, termStore.DefaultLanguage, isSiteCollectionTermGroup)); foreach (var property in termSet.CustomProperties) { modelTermSet.Properties.Add(property.Key, property.Value); } modelTermGroup.TermSets.Add(modelTermSet); } template.TermGroups.Add(modelTermGroup); } } } return(template); }