|
16 | 16 | using Nop.Services.Events; |
17 | 17 | using Nop.Services.Localization; |
18 | 18 | using Nop.Services.Stores; |
19 | | -using Nop.Services.Messages; // customized |
| 19 | +using Nop.Services.Messages; |
| 20 | +// customized |
| 21 | +using RazorEngine; |
| 22 | +using RazorEngine.Templating; |
| 23 | +using System.Security.Cryptography; |
| 24 | +using System.Text; |
20 | 25 |
|
21 | 26 | namespace ToSic.Nop.Plugins.RazorMessageService |
22 | 27 | { |
@@ -89,27 +94,30 @@ protected virtual int SendNotification(MessageTemplate messageTemplate, |
89 | 94 | var subject = messageTemplate.GetLocalized(mt => mt.Subject, languageId); |
90 | 95 | var body = messageTemplate.GetLocalized(mt => mt.Body, languageId); |
91 | 96 |
|
92 | | - //Replace subject and body tokens |
93 | | - var subjectReplaced = _tokenizer.Replace(subject, tokens, false); |
94 | | - var bodyReplaced = _tokenizer.Replace(body, tokens, true); |
95 | | - |
96 | 97 | #region Customized |
| 98 | + // Run Razor befor tokenizer to prevent unneded recompilation of the Razor-Template which would be very resource intensive |
| 99 | + |
97 | 100 | // Razor-Parse Subject |
98 | 101 | bool subjectSuccess; |
99 | | - var subjectParsed = RazorParseSafe(subjectReplaced, razorModel, out subjectSuccess); |
| 102 | + var subjectRazorParsed = RazorParseSafe(messageTemplate.Id, subject, razorModel, out subjectSuccess); |
100 | 103 | if (subjectSuccess) |
101 | | - subjectReplaced = subjectParsed; |
| 104 | + subject = subjectRazorParsed; |
102 | 105 | else |
103 | | - subjectReplaced += subjectParsed; |
| 106 | + subject += subjectRazorParsed; // in case of an error, append the error-text returned |
| 107 | + |
104 | 108 | // Razor-Parse Body |
105 | 109 | bool bodySuccess; |
106 | | - var bodyParsed = RazorParseSafe(bodyReplaced, razorModel, out bodySuccess); |
| 110 | + var bodyRazorParsed = RazorParseSafe(messageTemplate.Id, body, razorModel, out bodySuccess); |
107 | 111 | if (bodySuccess) |
108 | | - bodyReplaced = bodyParsed; |
| 112 | + body = bodyRazorParsed; |
109 | 113 | else |
110 | | - bodyReplaced += bodyParsed; |
| 114 | + body += bodyRazorParsed; // in case of an error, append the error-text returned |
111 | 115 | #endregion |
112 | 116 |
|
| 117 | + //Replace subject and body tokens |
| 118 | + var subjectReplaced = _tokenizer.Replace(subject, tokens, false); |
| 119 | + var bodyReplaced = _tokenizer.Replace(body, tokens, true); |
| 120 | + |
113 | 121 | var email = new QueuedEmail |
114 | 122 | { |
115 | 123 | Priority = QueuedEmailPriority.High, |
@@ -137,15 +145,38 @@ protected virtual int SendNotification(MessageTemplate messageTemplate, |
137 | 145 | } |
138 | 146 |
|
139 | 147 | #region Customized |
| 148 | + |
| 149 | + /// <summary> |
| 150 | + /// work arounf MD5 has for razorengine caching. |
| 151 | + /// </summary> |
| 152 | + /// <param name="input"></param> |
| 153 | + /// <returns></returns> |
| 154 | + private static string GetMd5Hash(string input) |
| 155 | + { |
| 156 | + var md5 = MD5.Create(); |
| 157 | + var inputBytes = System.Text.Encoding.ASCII.GetBytes(input); |
| 158 | + var hash = md5.ComputeHash(inputBytes); |
| 159 | + var sb = new StringBuilder(); |
| 160 | + foreach (byte t in hash) |
| 161 | + { |
| 162 | + sb.Append(t.ToString("X2")); |
| 163 | + } |
| 164 | + |
| 165 | + return sb.ToString(); |
| 166 | + } |
| 167 | + |
140 | 168 | /// <summary> |
141 | 169 | /// Parse text with Razor and handle Template Exception |
142 | 170 | /// </summary> |
143 | | - private static string RazorParseSafe(string text, object model, out bool success) |
| 171 | + private static string RazorParseSafe(int templateId, string text, object model, out bool success) |
144 | 172 | { |
145 | 173 | string result; |
146 | 174 | try |
147 | 175 | { |
148 | | - result = RazorEngine.Razor.Parse(text, model); |
| 176 | + var key = "MailTemplate" + templateId + GetMd5Hash(text); |
| 177 | + |
| 178 | + result = Engine.Razor.RunCompile(text, key, model: model); |
| 179 | + |
149 | 180 | success = true; |
150 | 181 | } |
151 | 182 | catch (RazorEngine.Templating.TemplateCompilationException ex) |
@@ -183,7 +214,7 @@ protected virtual EmailAccount GetEmailAccountOfMessageTemplate(MessageTemplate |
183 | 214 | if (emailAccountId == 0) |
184 | 215 | emailAccountId = messageTemplate.EmailAccountId; |
185 | 216 |
|
186 | | - var emailAccount = _emailAccountService.GetEmailAccountById(emailAccountId); |
| 217 | + var emailAccount = _emailAccountService.GetEmailAccountById(emailAccountId); |
187 | 218 | if (emailAccount == null) |
188 | 219 | emailAccount = _emailAccountService.GetEmailAccountById(_emailAccountSettings.DefaultEmailAccountId); |
189 | 220 | if (emailAccount == null) |
|
0 commit comments