Skip to content

Instantly share code, notes, and snippets.

@jraps20
Created April 24, 2018 19:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jraps20/16cf7ff22ef26379fdcbe2944bcd8de0 to your computer and use it in GitHub Desktop.
Save jraps20/16cf7ff22ef26379fdcbe2944bcd8de0 to your computer and use it in GitHub Desktop.
TDS Validator to ensure all uses of Translate.Text("some text") have a corresponding item defined in /sitecore/system/dictionary.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Xml.Linq;
using HedgehogDevelopment.SitecoreProject.Tasks;
using HedgehogDevelopment.SitecoreProject.Tasks.ProjectAnalysis;
namespace TDS.Validators
{
[Validator("DictionaryValidator", Status.Warn, Description = "Ensures an item is added to the dictionary that corresponds to a usage of Translate.Text('')")]
public class EnsureDictionaryEntryExistss : UserConfigurableValidator
{
private static readonly Regex TranslateText = new Regex(@"Translate\.Text\(\"".*\""\)", RegexOptions.Compiled);
private const string FileTypes = "*.cs*";
private const string DictionaryPath = "/sitecore/system/dictionary";
public override IEnumerable<Problem> Validate(Dictionary<Guid, SitecoreDeployInfo> projectItems, XDocument scprojDocument)
{
if (!Settings.Properties.Any())
{
yield return new Problem(this, new ProblemLocation("Configuration"), "Must set at least one absolute file path to search.");
}
var fileMatches = new List<FileMatch>();
foreach (var absolutePath in Settings.Properties.Where(i => !string.IsNullOrWhiteSpace(i)))
{
foreach (var file in Directory.GetFiles(absolutePath, FileTypes, SearchOption.AllDirectories))
{
var fileText = File.ReadAllText(file);
FindMatch(TranslateText, file, fileText, fileMatches);
}
}
if (!fileMatches.Any())
yield break;
foreach (var projectItem in projectItems.Values.Where(item => item.Item.SitecoreItemPath.Contains(DictionaryPath)))
{
if (projectItem.ParsedItem == null)
continue;
if (!projectItem.ParsedItem.Fields.Any())
continue;
var keyValue = projectItem.ParsedItem.Fields["Key"];
if (string.IsNullOrWhiteSpace(keyValue))
continue;
foreach (var fileMatch in fileMatches.Where(fileMatch => fileMatch != null))
{
// copy list to avoid changing enumeration
var tempMatches = fileMatch.Matches.ToList();
foreach (var match in fileMatch.Matches.Where(match => match != null))
{
if (match == keyValue)
tempMatches.Remove(match);
}
fileMatch.Matches = tempMatches.ToList();
}
}
foreach (var fileMatch in fileMatches)
{
foreach (var match in fileMatch.Matches)
{
yield return new Problem(this, new ProblemLocation(fileMatch.FilePath), $"Translation key '{match}' is not defined in Sitecore dictionary.");
}
}
}
private static void FindMatch(Regex regex, string file, string fileText, List<FileMatch> fileMatches)
{
var matches = regex.Matches(fileText);
if (matches.Count == 0)
return;
var matchesList = new List<string>();
for (var i = 0; i < matches.Count; i++)
{
matchesList.Add(CleanText(matches[i].Value));
}
fileMatches.Add(new FileMatch(file, matchesList));
}
private static string CleanText(string text)
{
var split = text.Split('"');
return split.Length < 2 ? "" : split[1];
}
public override ValidatorSettings GetDefaultSettings()
{
//Return a default list of locations to check
return new ValidatorSettings
{
Properties = new List<string> { "" }
};
}
}
public class FileMatch
{
public string FilePath { get; set; }
public List<string> Matches { get; set; }
public FileMatch(string filePath, List<string> matches)
{
FilePath = filePath;
Matches = matches;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment