I'm running a scheduled publish of my Sitecore master DB using the Sitecore publishing API. I call a web service at scheduled intervals during the day which runs the following code (slightly condensed for readability):
// grab the root content node from sitecore
Item contentNode = dbSource.Items[ID.Parse("{0DE95AE4-41AB-4D01-9EB0-67441B7C2450}")];
PublishOptions options = new PublishOptions(sourceDatabase, targetDatabase, PublishMode.Smart, lang, DateTime.Now);
options.RootItem = contentNode;
options.Deep = true;
Publisher p = new Publisher(options);
p.PublishAsync();
When we run the above code it publishes everything in the content node, including all descendants, regardless of workflow state. It's like it is ignoring the workflow completely. This is not what we are after, and is causing lots of problems on our live website.
If we run the same action from within Sitecore Desktop it publishes everything in the content node, including all descendants, that are publishable (I.e. in the final workflow stage). It does not publish any items in the tree that are still in draft mode. This is the required bahaviour.
I have tried implementing the code as a non-admin user by surrounding the above code with the following using statement:
string userName = @"sitecore\******";
Sitecore.Security.Accounts.User user = Sitecore.Security.Accounts.User.FromName(userName, true);
user.RuntimeSettings.IsAdministrator = false;
using (new Sitecore.Security.Accounts.UserSwitcher(user))
{
...
}
Unfortunately this has had no effect.
Is there something obvious I've missed, or am I doing it right and Sitecore is doing it wrong? Can anyone help please?
The strange thing I noticed, also, is that the draft items that were published, when viewed on the live database, were showing absolutely nothing in the Sitecore Desktop in terms of fields or meta data. They were also showing a warning that "The current item does not have a version in "English : English".
Likely the issue is that your web service is not running within a site context that has workflow enabled.
The easiest way to do this within your code is to use a SiteContextSwitcher
to change to the "shell" site.
using (new SiteContextSwitcher(SiteContextFactory.GetSiteContext("shell")))
{
//do your publish
}
As for the published items without versions: In theory, that would still happen even with regular publishing. Workflow limits the publishing of item versions, not the items themselves. In your code, when iterating items and in other cases, you need to check whether item.Versions.Count > 0
before rendering.
TL;DR Root content node had version in another language, removing that version, or only publishing in English language prevented publishing of items in draft mode
OK, so after trying @techphoria414's suggested code, it became clear that the context wasn't the issue. The publisher WAS adhering to workflow after all, but the problem has turned out to be the root content node having a version in another language (Japanese - don't ask me how this got there), but the descendant nodes having no versions in Japanese at all. In fact, our master database is only configured to have English as a language so it shouldn't even be possible for a user other than admin to add a version in another language.
I have conducted some tests and found that the publisher ignores workflow for items that exist in another language. Consider the following scenario:
1) You add a folder and any item underneath ("test workflow item") which has workflow. Don't commit the item, leaving it at version 1, in draft mode (i.e. shouldn't be publishable). The containing folder only has one version in one language (English):
2) You publish the folder with a deep publish to your web db (using the code in my question). This results in the following (folder added, but draft "test workflow item" not added). This is expected behaviour - yay!
3) Add a new version to the containing folder in a different language.
4) Check the workflow state of the child item now that Japanese is selected as the language. Notice, in the gutter it no longer says it is in draft mode, but there is no version at all in Japanese (as seen to the right).
5) Publish the containing folder in all languages to the web db, exactly the same as before. Notice now that the "test workflow item" has been published, but with no versions at all. This is what happened with our publish, except from the very root content node which meant countless items got published that should not have been published
Now, why our root content node has a version in Japanese is a complete mystery, but at least we have figured out why our draft items got published so we can prevent it in the future. I suspect it has something to do with upgrading Sitecore as there are 2 versions in Japanese which roughly correspond to upgrade dates over the last 2 years.
来源:https://stackoverflow.com/questions/12285080/why-does-sitecore-publish-draft-items-from-the-c-sharp-api-and-how-do-i-stop-it