Sitecore

Sitecore Express Migration Tool 2.0 skipping Security and Configuration steps

I recently got to know this wonderful tool when upgrading an old Sitecore version. The tool itself allows you to migrate any Sitecore 6.6 or Sitecore 7.2 versions to Sitecore 8.2. It also includes support for migrating Web Forms for Marketers.

My first experience was upgrading a 7.2 to 8.2. and within a day, the solution was fully upgraded and ready for testers. However, my newest attempt at upgrading a 6.6 solution gave a bit trouble. We decided to run at test upgrade to see if everything was migrated as it should, locally first.

All seemed fine, and we ran the migration again, but from using the production environments databases. This time the tool skipped both Security and Configuration. LEaving all users and roles behind. After some debugging and searching, I found that this was a know issue with the Express Tool:

The tool skips security and configuration steps if at least one migration was completed for the same source version (137519). Source

We needed to reset the tool in order to be able re-run the migration. To reset the tool you have to delete the Database file, created during the first run of the tool:

  • Migration.db

It is located in the root folder of the tools. The database file stores information on previous migrations, and somehow Sitecore skips Security and Configuration, if you already migrated the source version once before.

With the tool reset, the migration works perfectly again ūüôā

 

 

 

Sitecore

Sitecore Intranet Platform? What happened to it?

If you search for Sitecore Intranet, within the Sitecore regime, you will find the old sdn pages about the intranet portal, with a message saying :

The Sitecore Intranet Platform has been discontinued.

Sitecore officially discontinued the SIP product, after the last release October 22, 2013. The last supported version from Sitecore is Sitecore Intranet 4.1, running on a Sitecore 7.x installation. However, at Oxygen A/S, some of our largest customers were using the Sitecore Intranet Platform throughout their entire organization with multiple integrations. Their employees have one point of entry to most of their systems, the Intranet.

Because of this, we started to develop the Sitecore Intranet platform, upgrade it, remove old deprecated Sitecore elements to replace with newer technology, updated work processes and added much needed features. Today, the intranet runs on Sitecore 8.2.

We have updated it, following these four keywords.

  • Easy
  • Accessible
  • Social
  • Integrated

One of the main feature we have added, is the Social wall:

Oxygen itranet

The wall is where the employee can communicate and share knowledge with each other. They can upload videos, images and direct their messages to groups, users or teams if needed.

Another cool new feature is the groups. The groups in Oxygen Intranet are made both for professional and social purposes. This is an effective way to share knowledge with a project group, but it can also be used in non-work related contexts like film or sport groups.

Group

The new Oxygen Intranet comes with a lot more features than mentioned here. This post was to clarify for Sitecore developers / Marketeers what happened to the old SIP (Sitecore Intranet Portal). If you would like to know more about the Oxygen Intranet, have a look at it here.

 

Sitecore

Getting standard Sitecore fields as a list?

I had a task where I needed to get field names present on an item. By getting all fields on an item using Item.Fields, I could easily convert this list to a list of strings, containing the name of the field:

var fieldNames = contextItem.Fields.Select(field => field.Name).ToList();

In my case the client would provide a exclude pipe-separated list of item names which we didn’t need for this operation:

Exlucde

Removing these values:

var excludedFields = templateFieldValue.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
// Removed excludes.
foreach (string fieldName in excludedFields)
{
     fieldNames.RemoveAll(x => x.ToLower().Equals(fieldName.ToLower()));
}

However, this will leave you with a list of custom fields for the item, along with standard fields from Sitecore. In our case we needed to have a complete list of custom fields, without Sitecores standard fields.

To achieve this, Sitecore has a static class which contains all of the standard fields for Sitecore:

Sitecore.FieldIDs

This class has 82 fields, which return a Sitecore.Data.ID. I needed a list of those IDs, so I could filter my field names, and remove all unneeded fields. To get this list you can use reflection:

/// <summary>
/// Use reflection to get all sitecore standard field ids from FieldIDs class
/// </summary>
/// <returns>List of Sitecore standard fields IDs</returns>
private static List<ID> GetStandardSitecoreFields()
{
     Type myType = typeof(FieldIDs);
     FieldInfo[] fields = myType.GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly);
     return fields.Select(field => (ID) field.GetValue(myType)).ToList();
}

With this list you can easily remove Sitecore standard fields, when using Item.Fields:

var fieldNames = contextItem.Fields.Where(f => !sitecoreStandardFieldIDs.Contains(f.ID)).ToList().Select(field => field.Name).ToList();
Sitecore

Pasting ‘CLEAN’ text into Single line text fields

We come across a lot of customers complaining about pasting text into Sitecore fields. When pasting text from e.g Outlook or any other Microsoft applications, you usually get a lot of MSO styling with your text:

<p class="MsoNormal" style="background-image: initial; background-position: initial; background-size: initial; background-repeat: initial; background-attachment: initial; background-origin: initial; background-clip: initial;">
<span style="font-size:10.0pt;font-family:"Arial",sans-serif">
Copied text from Outlook
</span> 
<o:p></o:p> 
</p>

When using the Rich Text Editor, you get the option to “clean” the pasted text. However, this is not the case for Single Line Text fields in Sitecore. Getting styling saved¬†have the potential to break Sitecore Experience editor or any other custom code depending on the usage of the text field.

To clean the pasted text, you can simply implement a javascript on your layout and it will be applied to your fields:

    function handlePaste(e) {
        var clipboardData, pastedData;
 
        // Stop data being pasted into div
        e.stopPropagation();
        e.preventDefault();
 
        // Get pasted data via clipboard API
        clipboardData = e.clipboardData || window.clipboardData;
        pastedContent = clipboardData.getData('Text');
 
        // Execute paste with clean data
        document.execCommand('insertText', false, pastedContent);
    }
 
    document.addEventListener('paste', handlePaste);

 

Sitecore

Editcontext inside editcontext == Bad things.

As a developer, you need to be able to edit a Sitecore item for different reasons. We had a issue were we updated users data on login. The process was a bit complex and we needed to calculate multiple fields and values for each user and set it on their profileitem.

When editing a Sitecore item, the developer uses a editcontext:

using (new EditContext(item))
{
    item["FieldName"] = "Value";
}

However we had multiple fields needed to be edited, so we combined the field edits in one editcontext. At some point a nested method created a new editcontext with the same item.

using (new EditContext(item))
{
    // Update item
    CalculateFieldValueAndSet(item)
    // Update item
    item["Field1"] = "FieldValue";
}
private void CalculateFieldValueAndSet(Item item)
{
     // Calculate value
     var value = "a" + "b";
     using (new EditContext(item))
     {
          item["FieldName"] == value;
     {
}

When the editcontext inside CalculateFieldValueAndSet is closed, it closes all editing of the item resulting in a “Item is not en editing mode” error:

Exception: Sitecore.Exceptions.EditingNotAllowedException
Message: Item '/sitecore/content/user/B/bd/bd' is not in editing mode. Item ID: {0}
Source: Sitecore.Kernel

So be careful when using¬†editcontext for complex and editing multiple fields on a item. ūüôā

Sitecore, Uncategorized

Log files piled up? Cleanup agent log pattern fix.

In Sitecore 7.x they added some new standard logs to the solution.

  • Log – All-purpose, general Sitecore log.
  • WebDAV – Log for WebDAV activity.
  • Search – Activity from searches performed using Sitecore search providers.
  • Crawling – Activity from crawling performed by Sitecore search providers.
  • Publishing – Activity from publishing performed by Sitecore servers.
  • Fxm – Activity from Federated Experience Manager. If you are not using FXM, this log will be empty.

One thing they forgot, was to update the Cleanup agent’s log pattern.

<remove folder="$(dataFolder)/logs" pattern="log.*.txt" maxCount="20" minAge="7.00:00:00" />

This pattern will only match files starting with “log.”. The new log files prefixes with their name:

logs

Without the proper patteren, teh cleanup agent will never delete any of the new log files. To fix this you will need to update the pattern, to match the new Sitecore  standard log names:

<remove folder="$(dataFolder)/logs" pattern="*log.*.txt" maxAge="30.00:00:00" />

This is fixed in Sitecore 8.0 – update 1, however it is still a issue on solutions running older versions of Sitecore.

Sitecore

Sitecore and Events? Creating your own events and how to use them.

Using events can be useful when you need to run multiple operations on a item, if something changes or happens in your solution.

In Sitecore you can use the Sitecore.Events.Event namespace to create your own events, execute them when you need to and add event listeners as needed.

Registering the event:

<sitecore>
  <events>
    <event name="customevent:post">
       <handler type="Business.Pipelines.Events.PostEvent, Business" method="OnPost" />
    </event>
  </events>
</sitecore>

All you need to add an event, is to add your own config element with the name of your event, pointing at the implementation.

Implementing the event:

public virtual void OnPost(object sender, EventArgs args)
{
   var parameters = Event.ExtractParameters(args);            
   _users = parameters.Length > 0 ? parameters[0] as IEnumerable<User> : null; 
   _itemContext = parameters.Length > 1 ? parameters[1] as Item : null;
}

When implementing the event, you can access any parameters provided when raising the event. In this case we need a list for users along with a item.

Raising the event:

Sitecore.Events.Event.RaiseEvent("customevent:post", TargetUsers, item)

After the event have been raised, Sitecore handles everything needed to call your listeners.