Welkom bij WerfNet

2022-02-19 09:28:37

Sitecore

Ik werk al een aantal als jaren als developer met Sitecore.

Hier vind je een aantal interessante artikelen en stukjes code, die je Sitecore-ontwikkelaars leven makkelijker kunnen maken. Ik heb ze in het Engels geschreven om een grotere groep ontwikkelaars aan te kunnen spreken.

 

Extended MultiRoot Treelist

With Sitecore XA came the Multiroot Treelist. A very handy fieldtype where you can select items that can come from multiple datasources. But what if you have to look or edit the source item for a specific selected item that was selected? With multiple datasources only the name of a specific selected item is not enough to find where the source item is stored in the tree. To find out where it is, you would have to go to raw view, select the ID and then search it.
To make it a little more easy I created an "Extended MultiRoot Treelist". It basically inherrits from Sitecore.XA.Foundation.SitecoreExtensions.CustomFields.FieldTypes.MultiRootTreeList and adds the path of the selected item to the help-line underneath the box. From there you can select the path and simply search it.

 

Here is the code:

using System;
using System.Reflection;
using Sitecore.Web.UI.HtmlControls;
using conentEditor = Sitecore.Shell.Applications.ContentEditor;
using sitecoreExtentions = Sitecore.XA.Foundation.SitecoreExtensions.CustomFields.FieldTypes;

namespace MyProject.Foundation.JavaScriptServices.Fields
{
    public class ExtendedMultiRootTreeview : sitecoreExtentions.MultiRootTreeList
    {
        protected Listbox PrivateListbox
        {
            get
            {
                return typeof(conentEditor.TreeList)
                        .GetField("_listBox", BindingFlags.Instance | BindingFlags.NonPublic)
                        .GetValue(this) as Listbox;
            }
        }

        protected override void OnLoad(EventArgs args)
        {
            var db = Sitecore.Context.ContentDatabase;
            base.OnLoad(args);

            if (!Sitecore.Context.ClientPage.IsEvent)
            {
                var listbox = this.PrivateListbox;
                foreach (var li in listbox.Items)
                {
                    var id = li.Value.Split('|')[1];
                    var item = db.GetItem(id);
                    if (item != null)
                    {
                        li.Value += "|" + item.Paths.Path;
                    }
                }

                var js = "this.options[this.selectedIndex].value.split('|').length == 3?this.options[this.selectedIndex].value.split('|')[2]:this.options[this.selectedIndex].innerHTML";
                listbox.Attributes["onchange"] = "javascript:document.getElementById('" + this.ID + "_help').innerHTML=this.selectedIndex>=0?(" + js + "):''";
            }
        }
    }
}

 

Usermanager search by name and email

The Sitecore Usermanager gives you the posibility to search users on their user-account name. But suppose you are connected to the Active directory and the user accounts are not derived from the users' name. For example ABC1234. When you then have to find an account for a user and you do not know the account name, it is hard to find them. Esp. when the list of users is large.

With the help of our great friend Google I was able to find some code that makes it possible to search by account-name AND email address. full name is not so easy, because that information is not available at the moment of search. A piece of code and an extra config is all it takes.
When you have deployed this you can search on both (partial) account-name and email-address. As emailaddresses are often reflecting the real name of the users it is now possible to find users by name.

 

Here is config (MyProject.Foundation.Security.Providers.cs):

<?xml version="1.0" encoding="utf-8" ?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:x="http://www.sitecore.net/xmlconfig/">
    <sitecore>
        <userManager>
            <patch:attribute name="defaultProvider">custom</patch:attribute>
            <providers>
                <clear/>
                <add name="custom" type="MyProject.Foundation.Security.Providers.CustomUserProvider, MyProject.Foundation"/>
            </providers>
        </userManager>
    </sitecore>
</configuration>

Here is the code (CustomUserProvider.cs):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Security;
using Sitecore;
using Sitecore.Common;
using Sitecore.Diagnostics;
using Sitecore.Security.Accounts;

namespace MyProject.Foundation.Security.Providers
{
    public class CustomUserProvider : UserProvider
    {
        public override IFilterable GetUsers()
        {
            return new Filterable(this.GetAllUsers, this.GetAllUsers, this.GetUserCount, this.GetUsersByName, this.GetUsersByNameCount);
        }

        protected override IEnumerable GetUsersByName(int pageIndex, int pageSize, string userNameToMatch)
        {
            Assert.ArgumentNotNull(userNameToMatch, "userNameToMatch");
            int total;
            var userWithNoWildcard = this.GetUserWithNoWildcard(userNameToMatch);
            var membershipUserByName = Membership.FindUsersByName(userNameToMatch, pageIndex, pageSize, out total).OfType().ToList();
            var membershipUserByEmail = Membership.FindUsersByEmail(userNameToMatch, pageIndex, pageSize, out total).OfType().ToList();

            var membershipUser = membershipUserByEmail;

            foreach (var user in membershipUserByName)
            {
                if (!membershipUser.Where(m => m.UserName == user.UserName).Any())
                {
                    membershipUser.Add(user);
                }
            }

            var users = new Enumerable(() => membershipUser.GetEnumerator(), o => User.FromName(((MembershipUser)o).UserName, false));
            return users;
        }

        private string GetUserWithNoWildcard(string userNameToMatch)
        {
            var virtualMembershipWildcard = Sitecore.Configuration.Settings.Authentication.VirtualMembershipWildcard;
            return StringUtil.RemovePostfix(
                virtualMembershipWildcard,
                StringUtil.RemovePrefix(virtualMembershipWildcard, userNameToMatch));
        }

        private bool IsValidEmail(string email)
        {
            try
            {
                var addr = new System.Net.Mail.MailAddress(email);
                return addr.Address.Equals(email, StringComparison.OrdinalIgnoreCase);
            }
            catch
            {
                return false;
            }
        }

        private int GetUsersByNameCount(string userNameToMatch)
        {
            int totalRecords;
            var userWithNoWildcard = this.GetUserWithNoWildcard(userNameToMatch);
            if (this.IsValidEmail(userWithNoWildcard))
            {
                Membership.FindUsersByEmail(userWithNoWildcard, 0, 1, out totalRecords);
            }
            else
            {
                Membership.FindUsersByName(userNameToMatch, 0, 1, out totalRecords);
            }

            return totalRecords;
        }
    }
}