Reza Fard
Reza Fard

Reputation: 21

Kentico Global Events (ObjectEvents) Causes Loop

I'm using ObjectEvents to give ActivityPoints to current user based on fields user filled. Now for example if user register and fill FirstName I will give 10 points to user. The problem is that I'm handling ObjectEvents.Update.After and inside it I'm updating userSettings.This causes a unlimited loop and application stops working. is there any work around?

this is the code block:

var className = e.Object.TypeInfo.ObjectClassName;
        DataClassInfo dci = DataClassInfoProvider.GetDataClass(className);
        if (dci != null)
        {
            var fi = new FormInfo(dci.ClassFormDefinition);
            if (fi != null)
            {
                var stopProccess = true;
                var fields = new List<FormFieldInfo>();
                foreach (var changedColumn in e.Object.ChangedColumns())
                {
                    var field = fi.GetFormField(changedColumn);
                    var activityPointMacro = ValidationHelper.GetString(field.Settings["ActivityPointMacro"], "");
                    if (!string.IsNullOrEmpty(activityPointMacro))
                    {
                        fields.Add(field);
                        stopProccess = false;
                    }
                }
                if (!stopProccess)
                {
                    var contextResolver = CMSContext.CurrentResolver.CreateContextChild();
                    foreach (FormCategoryInfo info in fi.ItemsList.OfType<FormCategoryInfo>())
                    {
                        contextResolver.SetNamedSourceData(info.CategoryName, info);
                    }
                    EditingFormControl data = new EditingFormControl();
                    foreach (FormFieldInfo info2 in fi.ItemsList.OfType<FormFieldInfo>())
                    {
                        contextResolver.SetNamedSourceData(info2.Name, data);
                    }

                    foreach (var field in fields)
                    {

                        {
                            var activityPointMacro = ValidationHelper.GetString(field.Settings["ActivityPointMacro"], "");
                            var activityPoint =
                                ValidationHelper.GetInteger(contextResolver.ResolveMacros(activityPointMacro), 0);
                            CMSContext.CurrentUser.UserSettings.UserActivityPoints += activityPoint;
                            CMSContext.CurrentUser.UserSettings.Update();
                        }
                    }
                }

            }
        }

Upvotes: 0

Views: 558

Answers (1)

mivra
mivra

Reputation: 1400

If you just need to give points for user fields then you could just use ObjectEvents.Update.Before, check fields are not empty and assign points. But i can see from the code, you want to have something more complex bulit over macro expressions. So I have a few suggestions for you.

1) ObjectEvents.Update.Before instead of ObjectEvents.Update.After still may be a good idea. Ideally you set your additional values and all is set during one update.

2) Watch only the class names you need

3) Always prefer Provider.SetInfo methods over info.Update(). In case of user settings it's best to set whole user info, so UserInfoProvider.SetUserInfo. Provider methods may add some additional important logic.

4) The code seems like it'll add the points with every update of a user

5) if you are still running into a loop, you need to flag somehow, that some part of code should not be executed again. The best way is to use RequestStockHelper class - add a bool value with a specificname like "PointsProcessed".

Upvotes: 0

Related Questions