diff --git a/App_Config/Include/SitecoreSolutions.Commands.config b/App_Config/Include/SitecoreSolutions.Commands.config
new file mode 100644
index 0000000..fd75c1d
--- /dev/null
+++ b/App_Config/Include/SitecoreSolutions.Commands.config
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Extensions/Gutters/ExtendedWorkflowState.cs b/Extensions/Gutters/ExtendedWorkflowState.cs
new file mode 100644
index 0000000..1922188
--- /dev/null
+++ b/Extensions/Gutters/ExtendedWorkflowState.cs
@@ -0,0 +1,65 @@
+using Sitecore;
+using Sitecore.Configuration;
+using Sitecore.Data.Items;
+using Sitecore.Diagnostics;
+using Sitecore.Shell.Applications.ContentEditor.Gutters;
+using Sitecore.Workflows;
+
+///
+/// This class is a straight extract-and-copy of the WorflowState class in Sitecore.Kernel under the namespace
+/// Sitecore.Shell.Applications.ContentEditor.Gutters.WorkflowState.
+/// There is one single change between this file and the base workflowState file, at line 61 , which calls a custom extendedShowWorkflowState
+/// command that contains additional logic to check if user can execute workflow state without locking.
+///
+/// Don't forget to change namespace to your environment
+namespace SS.BaseConfig.Extensions.Gutters
+{
+ public class ExtendedWorkflowState : GutterRenderer
+ {
+ ///
+ /// Determines whether this instance is visible and should be rendered in context menu.
+ ///
+ ///
+ /// true if this instance is visible; otherwise, false.
+ ///
+ public override bool IsVisible()
+ {
+ if (!Settings.Workflows.Enabled)
+ return false;
+ return base.IsVisible();
+ }
+
+ /// Gets the icon.
+ /// The item.
+ /// The icon.
+ protected override GutterIconDescriptor GetIconDescriptor(Item item)
+ {
+ Assert.ArgumentNotNull((object)item, nameof(item));
+ string str1 = item[FieldIDs.Workflow];
+ string str2 = item[FieldIDs.WorkflowState];
+ if (!Settings.Workflows.Enabled || !item.Access.CanWrite())
+ return (GutterIconDescriptor)null;
+ if (string.IsNullOrEmpty(str1) || string.IsNullOrEmpty(str2))
+ return (GutterIconDescriptor)null;
+ IWorkflowProvider workflowProvider = item.Database.WorkflowProvider;
+ if (workflowProvider == null)
+ return (GutterIconDescriptor)null;
+ IWorkflow workflow = workflowProvider.GetWorkflow(item);
+ if (workflow == null)
+ return (GutterIconDescriptor)null;
+ Sitecore.Workflows.WorkflowState state = workflow.GetState(item);
+ if (state == null)
+ return (GutterIconDescriptor)null;
+ if (state.FinalState)
+ return (GutterIconDescriptor)null;
+ GutterIconDescriptor gutterIconDescriptor = new GutterIconDescriptor();
+ gutterIconDescriptor.Icon = state.Icon;
+ gutterIconDescriptor.Tooltip = state.DisplayName;
+ WorkflowCommand[] workflowCommandArray = WorkflowFilterer.FilterVisibleCommands(workflow.GetCommands(item), item);
+ if (workflowCommandArray != null && workflowCommandArray.Length != 0)
+ //Modify the event subscribed to the gutterIconDescriptor to call custom command, found at ExtendedShowWorkflowCommands.cs
+ gutterIconDescriptor.Click = "ss:extendedshowworkflowcommands(id=" + (object)item.ID + ",language=" + (object)item.Language + ",version=" + (object)item.Version + ",database=" + item.Database.Name + ")";
+ return gutterIconDescriptor;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Extensions/ShowWorkflowCommands/ExtendedShowWorkflowCommands.cs b/Extensions/ShowWorkflowCommands/ExtendedShowWorkflowCommands.cs
new file mode 100644
index 0000000..6934a8a
--- /dev/null
+++ b/Extensions/ShowWorkflowCommands/ExtendedShowWorkflowCommands.cs
@@ -0,0 +1,74 @@
+using Sitecore;
+using Sitecore.Configuration;
+using Sitecore.Data;
+using Sitecore.Data.Items;
+using Sitecore.Diagnostics;
+using Sitecore.Globalization;
+using Sitecore.Security.Accounts;
+using Sitecore.Shell.Framework.CommandBuilders;
+using Sitecore.Shell.Framework.Commands;
+using Sitecore.Web.UI.HtmlControls;
+using Sitecore.Web.UI.Sheer;
+using Sitecore.Workflows;
+using System;
+using System.Collections.Generic;
+
+///
+/// This class is a extact-and-copy of the ShowWorkflowCommand in Sitecore.Kernel. This class contains a single modification to the menu.Add code
+/// at line 68 that makes a call to Utilities.canUserRunCommandsWithoutLocking() method to check if context user meets the criteria set out by this method
+/// to allow execution of workflow commands without locking. If they pass this check, the gutter workflow command buttons become active even without
+/// locking the item.
+///
+
+///Don't forget to change Namespace to suit your environment!
+namespace SS.BaseConfig.Extensions.ShowWorkflowCommands
+{
+ [Serializable]
+ public class ExtendedShowWorkflowCommands : Command
+ {
+ /// Queries the state of the command.
+ /// The context.
+ /// The state of the command.
+ public override CommandState QueryState(CommandContext context)
+ {
+ if (!Settings.Workflows.Enabled)
+ return CommandState.Hidden;
+ return base.QueryState(context);
+ }
+
+ /// Executes the command in the specified context.
+ /// The context.
+ public override void Execute(CommandContext context)
+ {
+ Assert.ArgumentNotNull((object)context, nameof(context));
+ string parameter1 = context.Parameters["database"];
+ string parameter2 = context.Parameters["id"];
+ string parameter3 = context.Parameters["language"];
+ string parameter4 = context.Parameters["version"];
+ Database database = Factory.GetDatabase(parameter1);
+ if (database == null)
+ return;
+ Item obj = database.GetItem(parameter2, Language.Parse(parameter3), Sitecore.Data.Version.Parse(parameter4));
+ if (obj == null)
+ return;
+ IWorkflow workflow = obj.Database.WorkflowProvider.GetWorkflow(obj);
+ if (workflow == null)
+ return;
+ WorkflowCommand[] workflowCommandArray = WorkflowFilterer.FilterVisibleCommands(workflow.GetCommands(obj), obj);
+ if (workflowCommandArray == null || workflowCommandArray.Length == 0)
+ return;
+ Menu menu = new Menu();
+ SheerResponse.DisableOutput();
+ foreach (WorkflowCommand command in workflowCommandArray)
+ {
+ string click = new WorkflowCommandBuilder(obj, workflow, command).ToString();
+ //Add new logical condition to call canUserRunCommandsWithoutEdit() in Utilities class to check if user has permissions to execute
+ //workflow commands without locking. The rest of the conditions are same as in default class
+ menu.Add("C" + command.CommandID, command.DisplayName, command.Icon, string.Empty, click, false, string.Empty, MenuItemType.Normal).Disabled
+ = !Utilities.canUserRunCommandsWithoutLocking() && !Context.User.IsAdministrator && !obj.Locking.HasLock() && Settings.RequireLockBeforeEditing;
+ }
+ SheerResponse.EnableOutput();
+ SheerResponse.ShowContextMenu(Context.ClientPage.ClientRequest.Control, "right", (Control)menu);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Extensions/Utilities.cs b/Extensions/Utilities.cs
new file mode 100644
index 0000000..7fff602
--- /dev/null
+++ b/Extensions/Utilities.cs
@@ -0,0 +1,44 @@
+using Sitecore;
+using Sitecore.Security.Accounts;
+using System.Collections.Generic;
+
+/// Don't forget to change the Namespace to suit your environment!
+namespace SS.BaseConfig.Extensions
+{
+ ///
+ /// Contains various generic and/or abstract utility methods to acomplish tasks in specific Extension code files
+ ///
+ public class Utilities
+ {
+ ///
+ /// Determines whether the current context user has the ability to execute workflow commands without locking the item
+ /// for editing. In its current implementation the class simply checks the current user against a list of roles that
+ /// shoudl have this permission. You can extend and expand this class to include all sorts of validation as desired.
+ ///
+ ///
+ /// true if user meets the cireteria set out by the class
+ ///
+ public static bool canUserRunCommandsWithoutLocking()
+ {
+ User user = Context.User;
+ //Define list of roles that are approved to have this access. Add the full name for your environment here
+ List roleList = new List
+ {
+ "sitecore\\Author", //This is the standard Author role provided with Sitecore
+ "sitecore\\anotherRoleHere" //This is a fake role just serving as an example!
+ };
+ //Iterate over each role in the list and check if user is a member of the role. If they are return true
+ foreach (string s in roleList)
+ {
+ if (user.IsInRole(s)) { return true; }
+ }
+ ///
+ /// Add your own validation here. Maybe if a user is of a certain account. Or if they have edit rights to the item. Or if
+ /// their full name contains every vowel in the english langauge! Any validation goes!!!
+ ///
+
+ //Return false if conditions aren't met, indicating user should not have the right to execute commands without locking item
+ return false;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Extensions/ExtendedWorkflowPanel.cs b/Extensions/WorkflowPanel/ExtendedWorkflowPanel.cs
similarity index 77%
rename from Extensions/ExtendedWorkflowPanel.cs
rename to Extensions/WorkflowPanel/ExtendedWorkflowPanel.cs
index e388b6c..a18149b 100644
--- a/Extensions/ExtendedWorkflowPanel.cs
+++ b/Extensions/WorkflowPanel/ExtendedWorkflowPanel.cs
@@ -1,20 +1,4 @@
-/*
- * This class is a standalone, extended copy of the WorkflowPanel class as defined in Sitecore.Client
- * and makes minimal modifications to allow a user who meets certain role criteria (defined by you!) to
- * execute Workflow Commands from the workflow panel without locking the item for editing.
- *
- * This is the way Sitecore worked prior to 8.1 and this class is a reversion to this functionality with the
- * added benefit of allowing you to dole out this 'inline workflow command execute' ability as you desire.
- *
- * The extensiosn to this class are minimal: a new canUserRunCommandsWithoutEdit class is created which returns a
- * Boolean value. This boolean value is used in line 62 in the flag4 definition to allow the workflowpanel to enable
- * user interaction with the Workflow Panel buttons.
- *
- * You can modify the canUserRunCommandsWithoutEdit() method to include additional roles, or expand it even further
- * to suite your needs when it comes to limiting this inline workflow command execution ability.
- */
-
-using Sitecore;
+using Sitecore;
using Sitecore.Configuration;
using Sitecore.Data.Items;
using Sitecore.Diagnostics;
@@ -29,10 +13,13 @@
using System.Collections.Generic;
using System.Web.UI;
-//CHANGE THE NAMESPACE TO SUIT YOUR ENVIRONMENT!
-namespace BaseConfig.Extensions
+///
+/// This class is a straight extract-and-copy from Sitecore.Client's WorkflowPanel method. This extends class makes a single modification to
+/// the flag4 boolean code at line 53, adding a call to Utilities.canUserRunCommandsWithoutLocking() method, which checks if the context user meets
+/// the conditions outlined in the utilities method to execute workflow commands without locking the item.
+///
+namespace SS.BaseConfig.Extensions.WorkflowPanel
{
- /// Represents a WorkflowPanel.
public class ExtendedWorkflowPanel : RibbonPanel
{
/// The _check in item.
@@ -60,8 +47,10 @@ public override void Render(HtmlTextWriter output, Ribbon ribbon, Item button, C
bool flag1 = this.IsCommandEnabled("item:checkout", obj);
bool flag2 = ExtendedWorkflowPanel.CanShowCommands(obj, commands);
bool flag3 = this.IsCommandEnabled("item:checkin", obj);
+ //Add call to Utilities.canUserRunCommandsWithoutLocking() to validate user against custom criteria. If method returns true, this flag4 will be set
+ //to true and the workflow commands will be clickable even if item is not locked by user
bool flag4 = Context.User.IsAdministrator || obj.Locking.HasLock() || !Settings.RequireLockBeforeEditing ||
- canUserRunCommandsWithoutEdit();
+ Utilities.canUserRunCommandsWithoutLocking();
this.RenderText(output, ExtendedWorkflowPanel.GetText(context.Items));
if (!(workflow != null | flag1 | flag2 | flag3))
return;
@@ -207,31 +196,5 @@ private bool IsCommandEnabled(string command, Item item)
return commandState == CommandState.Enabled;
return true;
}
-
- ///
- /// Determines whether the current context user has the ability to execute workflow commands without locking the item
- /// for editing. In its current implementation the class simply checks the current user against a list of roles that
- /// shoudl have this permission. You can extend and expand this class to include all sorts of validation as desired.
- ///
- ///
- /// true if user meets the cireteria set out by the class
- ///
- private bool canUserRunCommandsWithoutEdit()
- {
- User user = Context.User;
- //Define list of roles that are approved to have this access. Add the full name for your environment here
- List roleList = new List
- {
- "sitecore\\Author", //This is the standard Author role provided with Sitecore
- "sitecore\\anotherRoleHere" //This is a fake role just serving as an example!
- };
- //Iterate over each role in the list and check if user is a member of the role. If they are return true
- foreach(string s in roleList)
- {
- if(user.IsInRole(s)) { return true; }
- }
- //Otherwise return false, indicating user should not have the right to execute commands without locking item
- return false;
- }
}
}
\ No newline at end of file