Skip to content

Commit 9227517

Browse files
authored
Split force for publish descendants into separate options for publish unpublish and re-publish unedited (13) (#18249)
* Split force for publish descendents into separate options for publish unpublish and re-publish unedited. * Added integration task verifying updated behaviour. * Variant integration test. * Update test data controller. * Remove usued function parameters. * Refactor to enum. * Fixed flags enum. * Variable name refactor. * Applied changes from code review. * Refactored method name. * Aligned js boolean checks.
1 parent 5322d0f commit 9227517

File tree

17 files changed

+417
-93
lines changed

17 files changed

+417
-93
lines changed

src/Umbraco.Core/EmbeddedResources/Lang/en.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,7 @@
309309
<key alias="removeTextBox">Remove this text box</key>
310310
<key alias="contentRoot">Content root</key>
311311
<key alias="includeUnpublished">Include unpublished content items.</key>
312+
<key alias="forceRepublish">Publish unchanged items.</key>
312313
<key alias="isSensitiveValue">This value is hidden. If you need access to view this value please contact your
313314
website administrator.
314315
</key>

src/Umbraco.Core/EmbeddedResources/Lang/en_us.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,7 @@
308308
<key alias="removeTextBox">Remove this text box</key>
309309
<key alias="contentRoot">Content root</key>
310310
<key alias="includeUnpublished">Include unpublished content items.</key>
311+
<key alias="forceRepublish">Publish unchanged items.</key>
311312
<key alias="isSensitiveValue">This value is hidden. If you need access to view this value please contact your
312313
website administrator.
313314
</key>
Lines changed: 46 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,69 +1,101 @@
11
namespace Umbraco.Cms.Core.Models.ContentEditing;
22

33
/// <summary>
4-
/// The action associated with saving a content item
4+
/// The action associated with saving a content item.
55
/// </summary>
66
public enum ContentSaveAction
77
{
88
/// <summary>
9-
/// Saves the content item, no publish
9+
/// Saves the content item, no publish.
1010
/// </summary>
1111
Save = 0,
1212

1313
/// <summary>
14-
/// Creates a new content item
14+
/// Creates a new content item.
1515
/// </summary>
1616
SaveNew = 1,
1717

1818
/// <summary>
19-
/// Saves and publishes the content item
19+
/// Saves and publishes the content item.
2020
/// </summary>
2121
Publish = 2,
2222

2323
/// <summary>
24-
/// Creates and publishes a new content item
24+
/// Creates and publishes a new content item.
2525
/// </summary>
2626
PublishNew = 3,
2727

2828
/// <summary>
29-
/// Saves and sends publish notification
29+
/// Saves and sends publish notification.
3030
/// </summary>
3131
SendPublish = 4,
3232

3333
/// <summary>
34-
/// Creates and sends publish notification
34+
/// Creates and sends publish notification.
3535
/// </summary>
3636
SendPublishNew = 5,
3737

3838
/// <summary>
39-
/// Saves and schedules publishing
39+
/// Saves and schedules publishing.
4040
/// </summary>
4141
Schedule = 6,
4242

4343
/// <summary>
44-
/// Creates and schedules publishing
44+
/// Creates and schedules publishing.
4545
/// </summary>
4646
ScheduleNew = 7,
4747

4848
/// <summary>
49-
/// Saves and publishes the content item including all descendants that have a published version
49+
/// Saves and publishes the content item including all descendants that have a published version.
5050
/// </summary>
5151
PublishWithDescendants = 8,
5252

5353
/// <summary>
54-
/// Creates and publishes the content item including all descendants that have a published version
54+
/// Creates and publishes the new content item including all descendants that have a published version.
5555
/// </summary>
5656
PublishWithDescendantsNew = 9,
5757

5858
/// <summary>
5959
/// Saves and publishes the content item including all descendants regardless of whether they have a published version
60-
/// or not
60+
/// or not.
6161
/// </summary>
62+
[Obsolete("This option is no longer used as the 'force' aspect has been extended into options for publishing unpublished and re-publishing changed content. Please use one of those options instead.")]
6263
PublishWithDescendantsForce = 10,
6364

6465
/// <summary>
65-
/// Creates and publishes the content item including all descendants regardless of whether they have a published
66-
/// version or not
66+
/// Creates and publishes the new content item including all descendants regardless of whether they have a published
67+
/// version or not.
6768
/// </summary>
69+
[Obsolete("This option is no longer used as the 'force' aspect has been extended into options for publishing unpublished and re-publishing changed content. Please use one of those options instead.")]
6870
PublishWithDescendantsForceNew = 11,
71+
72+
/// <summary>
73+
/// Saves and publishes the content item including all descendants including publishing previously unpublished content.
74+
/// </summary>
75+
PublishWithDescendantsIncludeUnpublished = 12,
76+
77+
/// <summary>
78+
/// Saves and publishes the new content item including all descendants including publishing previously unpublished content.
79+
/// </summary>
80+
PublishWithDescendantsIncludeUnpublishedNew = 13,
81+
82+
/// <summary>
83+
/// Saves and publishes the content item including all descendants irrespective of whether there are any pending changes.
84+
/// </summary>
85+
PublishWithDescendantsForceRepublish = 14,
86+
87+
/// <summary>
88+
/// Saves and publishes the new content item including all descendants including publishing previously unpublished content.
89+
/// </summary>
90+
PublishWithDescendantsForceRepublishNew = 15,
91+
92+
/// <summary>
93+
/// Saves and publishes the content item including all descendants including publishing previously unpublished content and irrespective of whether there are any pending changes.
94+
/// </summary>
95+
PublishWithDescendantsIncludeUnpublishedAndForceRepublish = 16,
96+
97+
/// <summary>
98+
/// Saves and publishes the new content item including all descendants including publishing previously unpublished content and irrespective of whether there are any pending changes.
99+
/// </summary>
100+
PublishWithDescendantsIncludeUnpublishedAndForceRepublishNew = 17,
69101
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
namespace Umbraco.Cms.Core.Models;
2+
3+
/// <summary>
4+
/// Describes the options available with publishing a content branch for force publishing.
5+
/// </summary>
6+
[Flags]
7+
public enum PublishBranchFilter
8+
{
9+
/// <summary>
10+
/// The default behavior is to publish only the published content that has changed.
11+
/// </summary>
12+
Default = 0,
13+
14+
/// <summary>
15+
/// For publishing a branch, publish all changed content, including content that is not published.
16+
/// </summary>
17+
IncludeUnpublished = 1,
18+
19+
/// <summary>
20+
/// For publishing a branch, force republishing of all published content, including content that has not changed.
21+
/// </summary>
22+
ForceRepublish = 2,
23+
24+
/// <summary>
25+
/// For publishing a branch, publish all content, including content that is not published and content that has not changed.
26+
/// </summary>
27+
All = IncludeUnpublished | ForceRepublish,
28+
}

src/Umbraco.Core/Services/ContentService.cs

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1963,17 +1963,14 @@ private bool SaveAndPublishBranch_PublishCultures(IContent content, HashSet<stri
19631963
}
19641964

19651965
// utility 'ShouldPublish' func used by SaveAndPublishBranch
1966-
private HashSet<string>? SaveAndPublishBranch_ShouldPublish(ref HashSet<string>? cultures, string c, bool published, bool edited, bool isRoot, bool force)
1966+
private HashSet<string>? SaveAndPublishBranch_ShouldPublish(ref HashSet<string>? cultures, string c, bool published, bool edited, bool isRoot, PublishBranchFilter publishBranchFilter)
19671967
{
19681968
// if published, republish
19691969
if (published)
19701970
{
1971-
if (cultures == null)
1972-
{
1973-
cultures = new HashSet<string>(); // empty means 'already published'
1974-
}
1971+
cultures ??= []; // empty means 'already published'
19751972

1976-
if (edited)
1973+
if (edited || publishBranchFilter.HasFlag(PublishBranchFilter.ForceRepublish))
19771974
{
19781975
cultures.Add(c); // <culture> means 'republish this culture'
19791976
}
@@ -1982,22 +1979,23 @@ private bool SaveAndPublishBranch_PublishCultures(IContent content, HashSet<stri
19821979
}
19831980

19841981
// if not published, publish if force/root else do nothing
1985-
if (!force && !isRoot)
1982+
if (!publishBranchFilter.HasFlag(PublishBranchFilter.IncludeUnpublished) && !isRoot)
19861983
{
19871984
return cultures; // null means 'nothing to do'
19881985
}
19891986

1990-
if (cultures == null)
1991-
{
1992-
cultures = new HashSet<string>();
1993-
}
1987+
cultures ??= [];
19941988

19951989
cultures.Add(c); // <culture> means 'publish this culture'
19961990
return cultures;
19971991
}
19981992

19991993
/// <inheritdoc />
20001994
public IEnumerable<PublishResult> SaveAndPublishBranch(IContent content, bool force, string culture = "*", int userId = Constants.Security.SuperUserId)
1995+
=> SaveAndPublishBranch(content, force ? PublishBranchFilter.IncludeUnpublished : PublishBranchFilter.Default, culture, userId);
1996+
1997+
/// <inheritdoc />
1998+
public IEnumerable<PublishResult> SaveAndPublishBranch(IContent content, PublishBranchFilter publishBranchFilter, string culture = "*", int userId = Constants.Security.SuperUserId)
20011999
{
20022000
// note: EditedValue and PublishedValue are objects here, so it is important to .Equals()
20032001
// and not to == them, else we would be comparing references, and that is a bad thing
@@ -2016,13 +2014,13 @@ public IEnumerable<PublishResult> SaveAndPublishBranch(IContent content, bool fo
20162014
// invariant content type
20172015
if (!c.ContentType.VariesByCulture())
20182016
{
2019-
return SaveAndPublishBranch_ShouldPublish(ref culturesToPublish, "*", c.Published, c.Edited, isRoot, force);
2017+
return SaveAndPublishBranch_ShouldPublish(ref culturesToPublish, "*", c.Published, c.Edited, isRoot, publishBranchFilter);
20202018
}
20212019

20222020
// variant content type, specific culture
20232021
if (culture != "*")
20242022
{
2025-
return SaveAndPublishBranch_ShouldPublish(ref culturesToPublish, culture, c.IsCulturePublished(culture), c.IsCultureEdited(culture), isRoot, force);
2023+
return SaveAndPublishBranch_ShouldPublish(ref culturesToPublish, culture, c.IsCulturePublished(culture), c.IsCultureEdited(culture), isRoot, publishBranchFilter);
20262024
}
20272025

20282026
// variant content type, all cultures
@@ -2032,23 +2030,27 @@ public IEnumerable<PublishResult> SaveAndPublishBranch(IContent content, bool fo
20322030
// others will have to 'republish this culture'
20332031
foreach (var x in c.AvailableCultures)
20342032
{
2035-
SaveAndPublishBranch_ShouldPublish(ref culturesToPublish, x, c.IsCulturePublished(x), c.IsCultureEdited(x), isRoot, force);
2033+
SaveAndPublishBranch_ShouldPublish(ref culturesToPublish, x, c.IsCulturePublished(x), c.IsCultureEdited(x), isRoot, publishBranchFilter);
20362034
}
20372035

20382036
return culturesToPublish;
20392037
}
20402038

2041-
// if not published, publish if force/root else do nothing
2042-
return force || isRoot
2039+
// if not published, publish if forcing unpublished/root else do nothing
2040+
return publishBranchFilter.HasFlag(PublishBranchFilter.IncludeUnpublished) || isRoot
20432041
? new HashSet<string> { "*" } // "*" means 'publish all'
20442042
: null; // null means 'nothing to do'
20452043
}
20462044

2047-
return SaveAndPublishBranch(content, force, ShouldPublish, SaveAndPublishBranch_PublishCultures, userId);
2045+
return SaveAndPublishBranch(content, ShouldPublish, SaveAndPublishBranch_PublishCultures, userId);
20482046
}
20492047

20502048
/// <inheritdoc />
20512049
public IEnumerable<PublishResult> SaveAndPublishBranch(IContent content, bool force, string[] cultures, int userId = Constants.Security.SuperUserId)
2050+
=> SaveAndPublishBranch(content, force ? PublishBranchFilter.IncludeUnpublished : PublishBranchFilter.Default, cultures, userId);
2051+
2052+
/// <inheritdoc />
2053+
public IEnumerable<PublishResult> SaveAndPublishBranch(IContent content, PublishBranchFilter publishBranchFilter, string[] cultures, int userId = Constants.Security.SuperUserId)
20522054
{
20532055
// note: EditedValue and PublishedValue are objects here, so it is important to .Equals()
20542056
// and not to == them, else we would be comparing references, and that is a bad thing
@@ -2064,7 +2066,7 @@ public IEnumerable<PublishResult> SaveAndPublishBranch(IContent content, bool fo
20642066
// invariant content type
20652067
if (!c.ContentType.VariesByCulture())
20662068
{
2067-
return SaveAndPublishBranch_ShouldPublish(ref culturesToPublish, "*", c.Published, c.Edited, isRoot, force);
2069+
return SaveAndPublishBranch_ShouldPublish(ref culturesToPublish, "*", c.Published, c.Edited, isRoot, publishBranchFilter);
20682070
}
20692071

20702072
// variant content type, specific cultures
@@ -2074,24 +2076,23 @@ public IEnumerable<PublishResult> SaveAndPublishBranch(IContent content, bool fo
20742076
// others will have to 'republish this culture'
20752077
foreach (var x in cultures)
20762078
{
2077-
SaveAndPublishBranch_ShouldPublish(ref culturesToPublish, x, c.IsCulturePublished(x), c.IsCultureEdited(x), isRoot, force);
2079+
SaveAndPublishBranch_ShouldPublish(ref culturesToPublish, x, c.IsCulturePublished(x), c.IsCultureEdited(x), isRoot, publishBranchFilter);
20782080
}
20792081

20802082
return culturesToPublish;
20812083
}
20822084

2083-
// if not published, publish if force/root else do nothing
2084-
return force || isRoot
2085+
// if not published, publish if forcing unpublished/root else do nothing
2086+
return publishBranchFilter.HasFlag(PublishBranchFilter.IncludeUnpublished) || isRoot
20852087
? new HashSet<string>(cultures) // means 'publish specified cultures'
20862088
: null; // null means 'nothing to do'
20872089
}
20882090

2089-
return SaveAndPublishBranch(content, force, ShouldPublish, SaveAndPublishBranch_PublishCultures, userId);
2091+
return SaveAndPublishBranch(content, ShouldPublish, SaveAndPublishBranch_PublishCultures, userId);
20902092
}
20912093

20922094
internal IEnumerable<PublishResult> SaveAndPublishBranch(
20932095
IContent document,
2094-
bool force,
20952096
Func<IContent, HashSet<string>?> shouldPublish,
20962097
Func<IContent, HashSet<string>, IReadOnlyCollection<ILanguage>, bool> publishCultures,
20972098
int userId = Constants.Security.SuperUserId)

src/Umbraco.Core/Services/IContentService.cs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,7 @@ public interface IContentService : IContentServiceBase<IContent>
431431
/// published. The root of the branch is always published, regardless of <paramref name="force" />.
432432
/// </para>
433433
/// </remarks>
434+
[Obsolete("This method is not longer used as the 'force' parameter has been extended into options for publishing unpublished and re-publishing changed content. Please use the overload containing the parameter for those options instead.")]
434435
IEnumerable<PublishResult> SaveAndPublishBranch(IContent content, bool force, string culture = "*", int userId = Constants.Security.SuperUserId);
435436

436437
/// <summary>
@@ -447,8 +448,47 @@ public interface IContentService : IContentServiceBase<IContent>
447448
/// published. The root of the branch is always published, regardless of <paramref name="force" />.
448449
/// </para>
449450
/// </remarks>
451+
[Obsolete("This method is not longer used as the 'force' parameter has been extended into options for publishing unpublished and re-publishing changed content. Please use the overload containing the parameter for those options instead.")]
450452
IEnumerable<PublishResult> SaveAndPublishBranch(IContent content, bool force, string[] cultures, int userId = Constants.Security.SuperUserId);
451453

454+
/// <summary>
455+
/// Saves and publishes a document branch.
456+
/// </summary>
457+
/// <param name="content">The root document.</param>
458+
/// <param name="publishBranchFilter">A value indicating options for force publishing unpublished or re-publishing unchanged content.</param>
459+
/// <param name="culture">A culture, or "*" for all cultures.</param>
460+
/// <param name="userId">The identifier of the user performing the operation.</param>
461+
/// <remarks>
462+
/// <para>
463+
/// Unless specified, all cultures are re-published. Otherwise, one culture can be specified. To act on more
464+
/// than one culture, see the other overloads of this method.
465+
/// </para>
466+
/// <para>
467+
/// The root of the branch is always published, regardless of <paramref name="publishBranchFilter" />.
468+
/// </para>
469+
/// </remarks>
470+
IEnumerable<PublishResult> SaveAndPublishBranch(IContent content, PublishBranchFilter publishBranchFilter, string culture = "*", int userId = Constants.Security.SuperUserId)
471+
#pragma warning disable CS0618 // Type or member is obsolete
472+
=> SaveAndPublishBranch(content, publishBranchFilter.HasFlag(PublishBranchFilter.IncludeUnpublished), culture, userId);
473+
#pragma warning restore CS0618 // Type or member is obsolete
474+
475+
/// <summary>
476+
/// Saves and publishes a document branch.
477+
/// </summary>
478+
/// <param name="content">The root document.</param>
479+
/// <param name="publishBranchFilter">A value indicating options for force publishing unpublished or re-publishing unchanged content.</param>
480+
/// <param name="cultures">The cultures to publish.</param>
481+
/// <param name="userId">The identifier of the user performing the operation.</param>
482+
/// <remarks>
483+
/// <para>
484+
/// The root of the branch is always published, regardless of <paramref name="publishBranchFilter" />.
485+
/// </para>
486+
/// </remarks>
487+
IEnumerable<PublishResult> SaveAndPublishBranch(IContent content, PublishBranchFilter publishBranchFilter, string[] cultures, int userId = Constants.Security.SuperUserId)
488+
#pragma warning disable CS0618 // Type or member is obsolete
489+
=> SaveAndPublishBranch(content, publishBranchFilter.HasFlag(PublishBranchFilter.IncludeUnpublished), cultures, userId);
490+
#pragma warning restore CS0618 // Type or member is obsolete
491+
452492
///// <summary>
453493
///// Saves and publishes a document branch.
454494
///// </summary>

0 commit comments

Comments
 (0)