Skip to content

Instantly share code, notes, and snippets.

@PNergard
Created January 7, 2025 13:43
Show Gist options
  • Save PNergard/d0accbbc46cc756b04c309257b69c902 to your computer and use it in GitHub Desktop.
Save PNergard/d0accbbc46cc756b04c309257b69c902 to your computer and use it in GitHub Desktop.
Optimizely Validation attribute for checking a image "alt"-text property before publishing
using EPiServer;
using EPiServer.Core;
using EPiServer.ServiceLocation;
using EPiServer.Validation;
using EPiServer.Web.Routing;
using HtmlAgilityPack;
using Pure.Core.Models.Media;
using System;
using System.Collections.Generic;
namespace DempProject.Validators
{
public class ImageFileValidator : IValidate<ContentData>
{
IEnumerable<ValidationError> IValidate<ContentData>.Validate(ContentData page)
{
var errorMessageTemplate = @"Bilden med namn: ""{0}"" saknar beskrivning!";
var errorMesageTemplateXhtml = @"Bilden med namn: ""{0}"" som används i fritext editorn saknar beskrivning!";
var severityError = ValidationErrorSeverity.Error;
var errors = new List<ValidationError>();
var pageProperties = page.Property;
var _contentLoader = ServiceLocator.Current.GetInstance<IContentLoader>();
var _urlResolver = ServiceLocator.Current.GetInstance<UrlResolver>();
foreach (PropertyData propertyData in pageProperties)
{
//Built-in properties that we want to ignore
if (propertyData.OwnerTab == -1) continue;
try
{
//ContentArea
if (propertyData.PropertyValueType == typeof(ContentArea))
{
var contentArea = (ContentArea)propertyData.Value;
if (contentArea?.Items != null)
{
foreach (var item in contentArea.Items)
{
var content = item.GetContent();
if (content as ImageFile != null)
{
if (string.IsNullOrEmpty(((ImageFile)content).Description))
{
errors.Add(
new ValidationError
{
ErrorMessage = string.Format(errorMessageTemplate, ((ImageFile)content).Name),
PropertyName = propertyData.Name,
Severity = severityError
});
}
}
}
}
}
//ContentReference
else if (propertyData.PropertyValueType == typeof(ContentReference))
{
var reference = propertyData.IsNull ? null : propertyData.Value as ContentReference;
if (!ContentReference.IsNullOrEmpty(reference))
{
ImageFile file = null;
try
{
file = _contentLoader.Get<ImageFile>(reference);
}
catch (Exception)
{
file = null;
}
if (file != null)
{
if (string.IsNullOrEmpty(((ImageFile)file).Description))
{
errors.Add(
new ValidationError
{
ErrorMessage = string.Format(errorMessageTemplate, file.Name),
PropertyName = propertyData.Name,
Severity = severityError
});
}
}
}
}
else if (propertyData.PropertyValueType == typeof(XhtmlString))
{
var doc = new HtmlDocument();
doc.LoadHtml(propertyData.Value?.ToString());
var imageNodes = doc.DocumentNode.SelectNodes("//img");
if (imageNodes != null)
{
foreach (var img in imageNodes)
{
var src = img.Attributes["src"].Value;
var alt = img.Attributes["alt"].Value;
if (src.ToLower().EndsWith(".aspx"))
{
var mediaContent = _urlResolver.Route(new UrlBuilder(src));
if (mediaContent != null)
{
if (mediaContent.Name == alt || string.IsNullOrEmpty(alt))
{
errors.Add(
new ValidationError
{
ErrorMessage = string.Format(errorMesageTemplateXhtml, mediaContent.Name),
PropertyName = propertyData.Name,
Severity = severityError
});
}
}
}
}
}
}
}
catch
{
}
}
return errors;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment