Sitecore Lock / Unlock Item without modifying Statistics

Sitecore updates the item statistics (Updated and Updated by fields) on each lock or unlock operation on an item. Sometimes this is misleading for content authors.

When this is misleading

  • When a user is just locking an item and not done any modifications in it but this creates dilemma for other users that the user already had some changes on that item or not. In our multisite environment where hundreds of users work on a single Sitecore instance, this confusion occurs frequently.
  • Even some content authors demand to auto-unlock their items after publishing without updating modified Date time.

How we can achieve this?

We will see how we can lock or unlock items without modifying item statistics.

Approach#1

The best way to achieve it is using Item's RuntimeSettings itself.
public void LockItem(Item item)
{
    if (!item.Locking.IsLocked())
    {
        item.RuntimeSettings.ReadOnlyStatistics = true;
        item.Locking.Lock();
        item.RuntimeSettings.ReadOnlyStatistics = false;
    }
}
public void UnlockItem(Item item)
{
    if (item.Locking.IsLocked())
    {
        item.RuntimeSettings.ReadOnlyStatistics = true;
        item.Locking.Unlock();
        item.RuntimeSettings.ReadOnlyStatistics = false;
     }
 }
Here, item.RuntimeSettings.ReadOnlyStatistics = true; will not update statistics for current context of item. So, while locking or unlocking, it will not update statistics.

Approach#2

Another simple way is to update the __lock field though APIs with updateStatistics to set as false as below. I personally do not recommend this approach, but still works great in many cases where above approach does not work.
public void LockItem(Item item)
{
    if (!item.Locking.IsLocked())
    {
        using (new EditContext(item, false, false))
        {
            item["__lock"] = "<r owner=\"" + Context.User.Name + "\" date=\"" + DateTime.Now.ToString("yyyyMMddTHHmmss") + "\" />";
        }
    }
}
public void UnlockItem(Item item)
{
    if (item.Locking.IsLocked())
    {
        using (new EditContext(item, false, false))
        {
            item["__lock"] = "<r />";
        }
    }
}
Happy to see it works and happy to see our content authors happy!

Get Optimized Images For Sitecore Responsive Websites

If you are having Responsive or Adaptive websites built in Sitecore and using Sitecore Image Parameters to resize images on-the-fly, this post is helpful to you!

Recently while working for responsive websites, we found that while resizing image with less dimensions, Sitecore produces image with more file size than its original one. It's really not expected because it also increases page load time.

Example

Below is the image I found from Sitecore Website's Homepage, which is having dimensions of 660px × 441px and having size of 48.45 kB (49,614 bytes). Image: http://dijaxps1e29ue.cloudfront.net/~/media/Redesign/Common/Heros/600x441/Homepage_hero_600x441.ashx?ts=121514021455931&la=en



Now if I request Sitecore to produce image with less resolution. i.e., with width of 600px. So, it generates an image of dimensions of 600px × 401px and having size of 57.4 kB (58,778 bytes). Image: http://dijaxps1e29ue.cloudfront.net/~/media/Redesign/Common/Heros/600x441/Homepage_hero_600x441.ashx?ts=121514021455931&la=en&w=600


Is it a bug from Sitecore?

No. But Sitecore by default uses "Lossy Compression Algorithm" to resize images, so reducing image dimensions will not reduce file size. Also, Sitecore uses 95% of image quality by default, that will generate image with bigger file size. To know more about it, you can check code from Sitecore.Resources.Media.ImageEffectsResize class ResizeImageStream() function.
<setting name="Media.UseLegacyResizing" value="false" />
<setting name="Media.Resizing.Quality" value="95" />
Reducing above quality setting may give us image with less file size but should we compromize with quality of image?

Then how to solve this?

There is an alternate way Sitecore gives which was the default behavior in Sitecore in earlier versions that is by enabling Sitecore's ImageLegacyResizing. You can know more about it from Sitecore.Resources.Media.ImageEffectsResize class ResizeLegacy() function. You can do below settings for getting reduced file size. Thank to Sitecore Support guy (Paul Kravchenko) for guiding me in this direction.
<setting name="Media.UseLegacyResizing" value="true" />
<setting name="Media.InterpolationMode" value="Low" />

Media.UseLegacyResizing
This setting controls whether to use legacy resizing (ie. bypass the Sitecore.ImageLib library).

Possible values can be:
true
false (Sitecore's default value)


Media.InterpolationMode
The interpolation mode to use when resizing images, which are available on System.Drawing.Drawing2D.InterpolationMode enum. Read more about InterpolationMode. We can any of below values as per our need.

Possible values can be:
Bicubic
Bilinear
Default
High (Sitecore's default value)
HighQualityBicubic
HighQualityBilinear
Low
NearestNeighbor

Again, Sitecore defines these settings in configuration file so values of the setting remains same for each image resize, so not that much useful to get a generic solution. Eager to know if someone has such generic solution to resize any kind of image, by maintaining quality with reduced file size what Photoshop or Paint.Net gives.