Rules rule

My content editors usually use the Content Editor to edit their items. For some reason, if there’s errors (i.e. required fields or items on the same level with the same name) they don’t always notice. I decided to make it a bit more noticeable, by creating one of those yellow bars on top of the item if there’s errors leading to not being able to go through workflow.

I figured there’d be something like Sitecore.Context.Item.Validation.IsValid or similar, but that wasn’t the case. There also wasn’t an existing Rule I could find that would give me whether the item was valid. Time to do some customization then!

Using Sitecore Rocks I created a class based on a Rule (Sidenote: Don’t have Sitecore Rocks yet? Get it here, now! It makes things a lot easier).

Insert through Rocks

Supposedly Sitecore would automatically make the Sitecore Item as well, but that didn’t happen in my case. That’s fine, I just created a Rule Item linking it up to my code.

rule item

As you can see, I could make an easy rule as I don’t need any variables apart from the item. I just want it to tell me when it’s either a critical error, fatal error or error.

The actual condition code I created was very easy, as I decided to make an extension method for the Item. This is the code for the condition:

publicclassItemValidCondition<T> : WhenCondition<T> where T : RuleContext
{
    protectedoverridebool Execute(T ruleContext)
    {
// Return true, if the condition is satisfied.
        return ruleContext.Item.IsValid();
    }
}

Then all I need to do is create the extension method. This was more tricky than I would’ve liked at first (although it ended up being fairly simple). I came across this blogpost by Aaron Blake:

That all seemed a bit too much to just validate an item. I ended up with something very similar – I just removed a lot of code, so I’d end up with the following:

var formValue = WebUtil.GetFormValue(“scValidatorsKey”);

if (!string.IsNullOrEmpty(formValue))
{
    var validators = ValidatorManager.GetValidators(ValidatorsMode.ValidatorBar, formValue);
    var options = newValidatorOptions(true);
    ValidatorManager.Validate(validators, options);

    foreach (BaseValidator baseValidator in validators)
    {
        if (baseValidator.Result == ValidatorResult.CriticalError ||
            baseValidator.Result == ValidatorResult.FatalError ||
baseValidator.Result == 
ValidatorResult.Error)
        {

            return false;
        }
    }
}

Initially, this seemed to work, but I ended up having 2 issues.

1 – Doesn’t show the errors in Sitecore Rocks – Rocks doesn’t have the scValidatorsKey since it’s not using a form to get the key out of.
2 – When browsing around I noticed it had a ‘delay’ of 1 item. When I selected an item I knew had an error it showed me that it was fine, when I then browsed to a different item (which I knew to be correct) it displayed my warning. I don’t know whether Aaron’s code also has this issue as I haven’t tested that, I just started modifying it.

What I thought was interesting was the ValidatorManager. I figured I could get the validators from the item that way then, instead of using the key.

That meant the GetValidators() method was out, since that requires a key. Other options are:
– GetGlobalValidatorsForItem
– GetItemValidators
– GetFieldsValidators

The GlobalValidatorsForItem returned some for me, but not the ones I expected. GetItemValidators returned none, which I kind of expected as I didn’t have any validators on the item – just on the fields.

I couldn’t figure out the second parameter in GetFieldsValidators though.

GetFieldsValidators

It doesn’t take in the actual fields, but an enumeration of FieldDescriptor. I didn’t want to create a FieldDescriptor for each field, so I decided to look further. If you have any information on this FieldDescriptor or how the GetFieldsValidator works, please leave it in a comment below.

I started some Googling again, and came across this StackOverflow question in which Stephen Pope mentions the ValidatorManager.BuildValidator method. That kind of does what I want, but I want to validate all rules, not just the one (or ones) I select. I want to keep in mind that if a validator gets added, I still want my validator to work. Turns out, there’s also a ValidatorManager.BuildValidators() method.

My final code for the extension method:

public static class ItemExtensions
{
    ///<summary>
    /// Check if the validators of the Workflow validators are valid
    ///</summary>
    ///<param name=”item”>The item</param>
    ///<returns>True if all validators return ValidatorResult.Valid. False otherwise</returns>
    public static bool IsValid(thisItem item)
    {
        var validators = ValidatorManager.BuildValidators(ValidatorsMode.Workflow, item);
        var validatorOptions = newValidatorOptions(true);
        ValidatorManager.Validate(validators, validatorOptions);

        foreach (BaseValidator baseValidator in validators)
        {
            if (baseValidator.Result == ValidatorResult.CriticalError ||
baseValidator.Result ==
ValidatorResult.FatalError ||
baseValidator.Result == 
ValidatorResult.Error)
            {
                return false;
            }
        }

        return true;
    }
}

Notice I’m using the ValidatorMode.Workflow, which is how I only validate the items in the worflow validation that’s been applied.

So now I could create my custom rule:

 rule

rule text

Which uses the existing action to show the warning.

And this is what it looks like in Sitecore Rocks:

result

Advertisements

2 thoughts on “Rules rule

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s