How to Search for Custom Profile Fields in the User Manager (Admins only)

How to Search for Custom Profile Fields in the User Manager (Admins only)

DESCRIPTION

Sitecore User Manager searches only for native fields such as username, full name, email and etc.

This search is very limited however, it is possible to make a more advanced search by interacting with the search pipeline and specify which other custom fields you want to search for.

For example, the image below shows a customized search that was made by a CPF (This is a Brazilian identification document).

 

By passing the instruction ‘CPF: + [document number]‘ Sitecore will execute your custom search algorithm.

SOLUTION

Firstly we need to tell Sitecore we want to interact with the search on the user manager.

Change the default UserProvider to your custom class, UserManagerCustomSearch.

<userManager defaultProvider="default" enabled="true">
      <providers>
        <clear/>
        <!--<add name="default" type="Sitecore.Security.Accounts.UserProvider, Sitecore.Kernel"/>-->
        <add name="default" type="BusinessLayer.Pipelines.UserManagerCustomSearch, BusinessLayer"/>
      </providers>
    </userManager>

If we decompile the Sitecore.Kernel.dll we will find the class that contains the search function.

This class is called UserProvider (namespace Sitecore.Security.Accounts).

Look for the function called GetUsersByName.

/// <summary>
       /// Gets all users matching a specific name.
       /// </summary>
       /// <param name="pageIndex">Index of the page.</param>
       /// <param name="pageSize">Size of the page.</param>
       /// <param name="userNameToMatch">The (partial) user name to match.</param>
       /// <returns></returns>
       protected virtual IEnumerable<User> GetUsersByName(int pageIndex, int pageSize, string userNameToMatch)
       {

           int num;

           Assert.ArgumentNotNull(userNameToMatch, "userNameToMatch");

           return new Enumerable<User>(() => Membership.FindUsersByName(userNameToMatch, pageIndex, pageSize, out num).GetEnumerator(), (object o) => User.FromName(((MembershipUser)o).UserName, false));

       }

We are going to override this function with our own customized search function.

The logic is simple: If there is the instruction ‘CPF:’ then execute our algorithm otherwise execute the Sitecore native function.

class UserManagerCustomSearch : UserProvider
    {

        protected override IEnumerable<User> GetUsersByName(int pageIndex, int pageSize, string userNameToMatch)
        {

            int num;

            Assert.ArgumentNotNull(userNameToMatch, "userNameToMatch");


            if (userNameToMatch.ToLower().Contains("cpf"))
            {

                userNameToMatch = userNameToMatch.Trim().Replace("cpf:", "").Replace("*","");

                //if no CPF typed then return empty (do not return NULL)
                if (string.IsNullOrEmpty(userNameToMatch)) return new User[] {};

                var u = MyNameSpace.CustomProfileIndexManager.GetUserByCpf(userNameToMatch);

                if (u == null) return new User[] { };

                //return user found
                IEnumerable<User> users = new User[]{ u };

                return users;

            }
            else
            {
                return new Enumerable<User>(() => Membership.FindUsersByName(userNameToMatch, pageIndex, pageSize, out num).GetEnumerator(), (object o) => User.FromName(((MembershipUser)o).UserName, false));
            }
        }
    }

Simple, right?

Any questions please do not hesitate to contact me.

Regards.

2 thoughts on “How to Search for Custom Profile Fields in the User Manager (Admins only)”

    • Hello,

      I just replaced it for “MyNameSpace.CustomProfileIndexManager.GetUserByCpf(userNameToMatch)

      You have to create this function and use any namespace.

      This is a simple search for user using GetCustomProperty:

      string cpf= Sitecore.Context.User.Profile.GetCustomProperty("CPF");

      Please let me know if that helps!

Leave a Comment

%d bloggers like this: