///TODO: Include update with html mail notification and document contents private static void sendNotification(User performingUser, User mailingUser, Document documentObject, IAction Action) { // retrieve previous version of the document DocumentVersionList[] versions = documentObject.GetVersions(); int versionCount = (versions.Length > 1) ? (versions.Length - 2) : (versions.Length - 1); var oldDoc = new Document(documentObject.Id, versions[versionCount].Version); // build summary var summary = new StringBuilder(); var props = documentObject.GenericProperties; foreach (Property p in props) { // check if something was changed and display the changes otherwise display the fields Property oldProperty = oldDoc.getProperty(p.PropertyType.Alias); string oldText = oldProperty.Value.ToString(); string newText = p.Value.ToString(); // replace html with char equivalent ReplaceHTMLSymbols(ref oldText); ReplaceHTMLSymbols(ref newText); // make sure to only highlight changes done using TinyMCE editor... other changes will be displayed using default summary ///TODO PPH: Had to change this, as a reference to the editorcontrols is not allowed, so a string comparison is the only way, this should be a DIFF or something instead.. if (p.PropertyType.DataTypeDefinition.DataType.ToString() == "umbraco.editorControls.tinymce.TinyMCEDataType" && string.Compare(oldText, newText) != 0) { summary.Append("<tr>"); summary.Append("<th style='text-align: left; vertical-align: top; width: 25%;'> Note: </th>"); summary.Append( "<td style='text-align: left; vertical-align: top;'> <span style='background-color:red;'>Red for deleted characters</span> <span style='background-color:yellow;'>Yellow for inserted characters</span></td>"); summary.Append("</tr>"); summary.Append("<tr>"); summary.Append("<th style='text-align: left; vertical-align: top; width: 25%;'> New " + p.PropertyType.Name + "</th>"); summary.Append("<td style='text-align: left; vertical-align: top;'>" + replaceLinks(CompareText(oldText, newText, true, false, "<span style='background-color:yellow;'>", string.Empty)) + "</td>"); summary.Append("</tr>"); summary.Append("<tr>"); summary.Append("<th style='text-align: left; vertical-align: top; width: 25%;'> Old " + oldProperty.PropertyType.Name + "</th>"); summary.Append("<td style='text-align: left; vertical-align: top;'>" + replaceLinks(CompareText(newText, oldText, true, false, "<span style='background-color:red;'>", string.Empty)) + "</td>"); summary.Append("</tr>"); } else { summary.Append("<tr>"); summary.Append("<th style='text-align: left; vertical-align: top; width: 25%;'>" + p.PropertyType.Name + "</th>"); summary.Append("<td style='text-align: left; vertical-align: top;'>" + p.Value.ToString() + "</td>"); summary.Append("</tr>"); } summary.Append( "<tr><td colspan=\"2\" style=\"border-bottom: 1px solid #CCC; font-size: 2px;\"> </td></tr>"); } string protocol = GlobalSettings.UseSSL ? "https" : "http"; string[] subjectVars = { HttpContext.Current.Request.ServerVariables["SERVER_NAME"] + ":" + HttpContext.Current.Request.Url.Port + IOHelper.ResolveUrl(SystemDirectories.Umbraco), ui.Text(Action.Alias) , documentObject.Text }; string[] bodyVars = { mailingUser.Name, ui.Text(Action.Alias), documentObject.Text, performingUser.Name, HttpContext.Current.Request.ServerVariables["SERVER_NAME"] + ":" + HttpContext.Current.Request.Url.Port + IOHelper.ResolveUrl(SystemDirectories.Umbraco), documentObject.Id.ToString(), summary.ToString(), String.Format("{2}://{0}/{1}", HttpContext.Current.Request.ServerVariables["SERVER_NAME"] + ":" + HttpContext.Current.Request.Url.Port, /*umbraco.library.NiceUrl(documentObject.Id))*/ documentObject.Id + ".aspx", protocol) ///TODO: PPH removed the niceURL reference... cms.dll cannot reference the presentation project... ///TODO: This should be moved somewhere else.. }; // create the mail message var mail = new MailMessage(UmbracoSettings.NotificationEmailSender, mailingUser.Email); // populate the message mail.Subject = ui.Text("notifications", "mailSubject", subjectVars, mailingUser); if (UmbracoSettings.NotificationDisableHtmlEmail) { mail.IsBodyHtml = false; mail.Body = ui.Text("notifications", "mailBody", bodyVars, mailingUser); } else { mail.IsBodyHtml = true; mail.Body = @"<html><head> </head> <body style='font-family: Trebuchet MS, arial, sans-serif; font-color: black;'> " + ui.Text("notifications", "mailBodyHtml", bodyVars, mailingUser) + "</body></html>"; } // nh, issue 30724. Due to hardcoded http strings in resource files, we need to check for https replacements here // adding the server name to make sure we don't replace external links if (GlobalSettings.UseSSL && !String.IsNullOrEmpty(mail.Body)) { string serverName = HttpContext.Current.Request.ServerVariables["SERVER_NAME"]; mail.Body = mail.Body.Replace( string.Format("http://{0}", serverName), string.Format("https://{0}", serverName)); } // send it var sender = new SmtpClient(); sender.Send(mail); }
/// <summary> /// Moves a Post if the Post Date Changes /// </summary> /// <param name="sender">Document Being Published</param> /// <param name="e">Publish Event Args</param> void Document_BeforePublish(Document sender, umbraco.cms.businesslogic.PublishEventArgs e) { if (sender.ContentType.Alias == "BlogPost") //As this runs for every publish event, only proceed if this is BlogPost { Log.Add(LogTypes.Debug, sender.User, sender.Id, string.Format("Start Before Publish Event for Blog Post {0}", sender.Id)); if (sender.getProperty("PostDate") != null) //If no post date, skip { if (sender.Parent != null) //If top of tree, something is wrong. Skip. { try { DocumentVersionList[] postVersions = sender.GetVersions(); bool _versionCheck = true; DateTime postDate; postDate = System.Convert.ToDateTime(sender.getProperty("PostDate").Value); if (postVersions.Length > 1) //If it has been published, check post date info { //Length -1 is current version Length -2 is past version (if it exists) Guid previousVersion = postVersions[postVersions.Length - 2].Version; Document doc = new Document(sender.Id, previousVersion); DateTime previousPostDate = System.Convert.ToDateTime(doc.getProperty("PostDate").Value); _versionCheck = (postDate != previousPostDate); } if (_versionCheck) //Only do the date folder movement if the PostDate is changed or is new Post. { string[] strArray = { postDate.Year.ToString(), postDate.Month.ToString(), postDate.Day.ToString() }; if (strArray.Length == 3) { Node topBlogLevel = new Node(sender.Parent.Id); //Traverse up the tree to Find the Blog Node since we are likely in a Date Folder path while (topBlogLevel != null && topBlogLevel.NodeTypeAlias != "Blog") { if (topBlogLevel.Parent != null) { topBlogLevel = new Node(topBlogLevel.Parent.Id); } else { topBlogLevel = null; } } if (topBlogLevel != null) { Document document = null; Node folderNode = null; foreach (Node ni in topBlogLevel.Children) { if (ni.Name == strArray[0]) { folderNode = new Node(ni.Id); document = new Document(ni.Id); break; } } if (folderNode == null) { document = Document.MakeNew(strArray[0], DocumentType.GetByAlias("DateFolder"), sender.User, topBlogLevel.Id); document.Publish(sender.User); library.UpdateDocumentCache(document.Id); folderNode = new Node(document.Id); } Node folderNode2 = null; foreach (Node ni in folderNode.Children) { if (ni.Name == strArray[1]) { folderNode2 = new Node(ni.Id); break; } } if (folderNode2 == null) { Document document2 = Document.MakeNew(strArray[1], DocumentType.GetByAlias("DateFolder"), sender.User, folderNode.Id); document2.Publish(sender.User); library.UpdateDocumentCache(document2.Id); folderNode2 = new Node(document2.Id); } Document document3 = null; //As this is the last check, a document object is fine foreach (Node ni in folderNode2.Children) { if (ni.Name == strArray[2]) { document3 = new Document(ni.Id); break; } } if (document3 == null) { document3 = Document.MakeNew(strArray[2], DocumentType.GetByAlias("DateFolder"), sender.User, folderNode2.Id); document3.Publish(sender.User); library.UpdateDocumentCache(document3.Id); } if (sender.Parent.Id != document3.Id) { sender.Move(document3.Id); Log.Add(LogTypes.Debug, sender.User, sender.Id, string.Format("Move Required for BlogPost {0} for PostDate {1}. Moved Under Node {2}", sender.Id, postDate.ToShortDateString(), document3.Id)); } } else { Log.Add(LogTypes.Debug, sender.User, sender.Id, string.Format("Unable to determine top of Blog for BlogPost {0} while attempting to move to new Post Date", sender.Id)); } } } } catch (Exception Exp) { Log.Add(LogTypes.Debug, sender.User, sender.Id, string.Format("Error while Finding Blog Folders for BlogPost {0} while trying to move to new Post Date. Error: {1}", sender.Id, Exp.Message)); } umbraco.library.RefreshContent(); } } } }
private bool HasDateChanged(Document document) { DocumentVersionList[] versions = document.GetVersions(); bool dateHasChanged = true; DateTime itemDate = Convert.ToDateTime(document.getProperty(ItemDateProperty).Value); if (versions.Length > 1) { Guid version = versions[versions.Length - 2].Version; DateTime oldItemDate = Convert.ToDateTime(new Document(document.Id, version).getProperty(ItemDateProperty).Value); dateHasChanged = itemDate != oldItemDate; } return dateHasChanged; }