File: D:/HostingSpaces/TDijk1/erp-apps.eu/wwwroot/CMSModules/Content/Controls/ViewVersion.ascx.cs
using System;
using System.Collections;
using System.Data;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using CMS.Base;
using CMS.Controls;
using CMS.DataEngine;
using CMS.DocumentEngine;
using CMS.EventLog;
using CMS.ExtendedControls;
using CMS.FormEngine;
using CMS.Globalization;
using CMS.Helpers;
using CMS.Localization;
using CMS.MacroEngine;
using CMS.Membership;
using CMS.PortalEngine;
using CMS.SiteProvider;
using CMS.UIControls;
using CMS.WorkflowEngine;
using TimeZoneInfo = CMS.Globalization.TimeZoneInfo;
using TreeNode = CMS.DocumentEngine.TreeNode;
public partial class CMSModules_Content_Controls_ViewVersion : VersionHistoryControl, IPostBackEventHandler
{
#region "Variables"
private FormInfo fi;
private int versionHistoryId;
private int versionCompare;
private AttachmentsDataSource dsAttachments;
private AttachmentsDataSource dsAttachmentsCompare;
private Hashtable attachments;
private Hashtable attachmentsCompare;
private bool noCompare;
private bool error;
private TimeZoneInfo usedTimeZone;
private TimeZoneInfo serverTimeZone;
public CMSModules_Content_Controls_ViewVersion()
{
CompareNode = null;
}
/// <summary>
/// Column marked as unsorted - default string.
/// </summary>
private const string UNSORTED = "##UNSORTED##";
#endregion
#region "Properties"
/// <summary>
/// Messages placeholder
/// </summary>
public override MessagesPlaceHolder MessagesPlaceHolder
{
get
{
return plcMess;
}
}
/// <summary>
/// Indicates if control is used on live site.
/// </summary>
public override bool IsLiveSite
{
get
{
return base.IsLiveSite;
}
set
{
plcMess.IsLiveSite = value;
base.IsLiveSite = value;
}
}
/// <summary>
/// Current edited node.
/// </summary>
public override TreeNode Node
{
get;
set;
}
/// <summary>
/// Compare node.
/// </summary>
public TreeNode CompareNode
{
get;
set;
}
#endregion
#region "Methods"
/// <summary>
/// Shows the specified error message, optionally with a tooltip text.
/// </summary>
/// <param name="text">Error message text</param>
/// <param name="description">Additional description</param>
/// <param name="tooltipText">Tooltip text</param>
/// <param name="persistent">Indicates if the message is persistent</param>
public override void ShowError(string text, string description = null, string tooltipText = null, bool persistent = true)
{
base.ShowError(text, description, tooltipText, persistent);
error = true;
}
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
ControlsHelper.EnsureScriptManager(Page);
DocumentManager.RegisterSaveChangesScript = false;
}
protected void Page_Load(object sender, EventArgs e)
{
// Register WOpener script
ScriptHelper.RegisterWOpenerScript(Page);
if (QueryHelper.GetBoolean("rollbackok", false))
{
ShowConfirmation(GetString("VersionProperties.RollbackOK"));
}
noCompare = QueryHelper.GetBoolean("noCompare", false);
versionHistoryId = QueryHelper.GetInteger("versionhistoryid", 0);
versionCompare = QueryHelper.GetInteger("compareHistoryId", 0);
// Converting modified time to correct time zone
usedTimeZone = TimeZoneHelper.GetTimeZoneInfo(CurrentUser, SiteContext.CurrentSite);
serverTimeZone = TimeZoneHelper.ServerTimeZone;
// No comparing available in Recycle bin
pnlControl.Visible = !noCompare;
if (versionHistoryId > 0)
{
try
{
// Get original version of document
Node = VersionManager.GetVersion(versionHistoryId);
CompareNode = VersionManager.GetVersion(versionCompare);
if (Node != null)
{
// Check read permissions
if (MembershipContext.AuthenticatedUser.IsAuthorizedPerDocument(Node, NodePermissionsEnum.Read) != AuthorizationResultEnum.Allowed)
{
RedirectToAccessDenied(String.Format(GetString("cmsdesk.notauthorizedtoreaddocument"), Node.NodeAliasPath));
}
if (!RequestHelper.IsPostBack())
{
LoadDropDown(Node.DocumentID, versionHistoryId);
ReloadData();
}
drpCompareTo.SelectedIndexChanged += drpCompareTo_SelectedIndexChanged;
}
else
{
ShowInformation(GetString("editeddocument.notexists"));
pnlAdditionalControls.Visible = false;
}
}
catch (Exception ex)
{
if (Node == null)
{
RedirectToInformation(GetString("editeddocument.notexists"));
}
else
{
ShowError(GetString("document.viewversionerror") + " " + ex.Message);
}
EventLogProvider.LogException("Content", "VIEWVERSION", ex);
}
}
}
/// <summary>
/// Reloads control with new data.
/// </summary>
private void ReloadData()
{
tblDocument.Rows.Clear();
DataClassInfo ci = DataClassInfoProvider.GetDataClassInfo(Node.NodeClassName);
if (ci != null)
{
fi = FormHelper.GetFormInfo(ci.ClassName, false);
TableHeaderCell labelCell = new TableHeaderCell();
TableHeaderCell valueCell;
// Add header column with version number
if (CompareNode == null)
{
labelCell.Text = GetString("General.FieldName");
labelCell.EnableViewState = false;
valueCell = new TableHeaderCell();
valueCell.EnableViewState = false;
valueCell.Text = GetString("General.Value");
// Add table header
AddRow(labelCell, valueCell, "unigrid-head", true);
}
else
{
labelCell.Text = GetString("lock.versionnumber");
valueCell = GetRollbackTableHeaderCell("source", Node.DocumentID, versionHistoryId);
TableHeaderCell valueCompare = GetRollbackTableHeaderCell("compare", CompareNode.DocumentID, versionCompare);
// Add table header
AddRow(labelCell, valueCell, valueCompare, true, "unigrid-head", true);
}
if (ci.ClassIsProduct)
{
// Add coupled class fields
ClassStructureInfo skuCsi = ClassStructureInfo.GetClassInfo("ecommerce.sku");
if (skuCsi != null)
{
foreach (string columnName in skuCsi.ColumnNames)
{
AddField(Node, CompareNode, columnName);
}
}
}
if (ci.ClassIsCoupledClass)
{
// Add coupled class fields
ClassStructureInfo coupledCsi = ClassStructureInfo.GetClassInfo(Node.NodeClassName);
if (coupledCsi != null)
{
foreach (string columnName in coupledCsi.ColumnNames)
{
// If comparing with other version and current coupled column is not versioned do not display it
if (!((CompareNode != null) && !(VersionManager.IsVersionedCoupledColumn(Node.NodeClassName, columnName))))
{
AddField(Node, CompareNode, columnName);
}
}
}
}
// Add versioned document class fields
ClassStructureInfo docCsi = ClassStructureInfo.GetClassInfo("cms.document");
if (docCsi != null)
{
foreach (string columnName in docCsi.ColumnNames)
{
// If comparing with other version and current document column is not versioned do not display it
// One exception is DocumentNamePath column which will be displayed even if it is not marked as a versioned column
if (!((CompareNode != null) && (!(VersionManager.IsVersionedDocumentColumn(columnName) || (columnName.ToLowerCSafe() == "documentnamepath")))))
{
AddField(Node, CompareNode, columnName);
}
}
}
// Add versioned document class fields
ClassStructureInfo treeCsi = ClassStructureInfo.GetClassInfo("cms.tree");
if (treeCsi != null)
{
foreach (string column in treeCsi.ColumnNames)
{
// Do not display cms_tree columns when comparing with other version
// cms_tree columns are not versioned
if (CompareNode == null)
{
AddField(Node, CompareNode, column);
}
}
}
// Add unsorted attachments to the table
AddField(Node, CompareNode, UNSORTED);
}
}
/// <summary>
/// Gets new table header cell which contains label and rollback image.
/// </summary>
/// <param name="suffixID">ID suffix</param>
/// <param name="documentID">Document ID</param>
/// <param name="versionID">Version history ID</param>
private TableHeaderCell GetRollbackTableHeaderCell(string suffixID, int documentID, int versionID)
{
TableHeaderCell tblHeaderCell = new TableHeaderCell();
tblHeaderCell.EnableViewState = false;
string tooltip = GetString("history.versionrollbacktooltip");
// Label
Label lblValue = new Label();
lblValue.ID = "lbl" + suffixID;
lblValue.Text = HTMLHelper.HTMLEncode(GetVersionNumber(documentID, versionID)) + " ";
lblValue.EnableViewState = false;
// Rollback image
var imgRollback = new HyperLink();
imgRollback.ID = "imgRollback" + suffixID;
imgRollback.NavigateUrl = "#";
imgRollback.Text = tooltip;
imgRollback.EnableViewState = false;
imgRollback.CssClass = "table-header-action";
// Disable buttons according to permissions
bool canApprove = WorkflowManager.CheckStepPermissions(Node, WorkflowActionEnum.Approve);
if (!canApprove || !CanModify || (CheckedOutByAnotherUser && !CanCheckIn))
{
imgRollback.Enabled = false;
}
else
{
// Prepare onclick script
string confirmScript = "if (confirm(" + ScriptHelper.GetString(GetString("Unigrid.VersionHistory.Actions.Rollback.Confirmation")) + ")) { ";
confirmScript += Page.ClientScript.GetPostBackEventReference(this, versionID.ToString()) + "; } return false;";
imgRollback.Attributes.Add("onclick", confirmScript);
}
tblHeaderCell.Controls.Add(lblValue);
tblHeaderCell.Controls.Add(imgRollback);
return tblHeaderCell;
}
/// <summary>
/// Loads dropdown list with versions.
/// </summary>
/// <param name="documentId">ID of current document</param>
/// <param name="historyId">ID of current version history</param>
private void LoadDropDown(int documentId, int historyId)
{
DataSet ds = VersionManager.GetDocumentHistory(documentId, "VersionHistoryID !=" + historyId, "ModifiedWhen DESC, VersionNumber DESC", -1, "VersionHistoryID, VersionNumber, ModifiedWhen");
// Converting modified time to correct time zone
if (!DataHelper.DataSourceIsEmpty(ds))
{
foreach (DataRow dr in ds.Tables[0].Rows)
{
string version = ValidationHelper.GetString(dr["VersionNumber"], null);
version += " (" + GetUserDate(dr["ModifiedWhen"]) + ")";
drpCompareTo.Items.Add(new ListItem(version, ValidationHelper.GetString(dr["VersionHistoryID"], "0")));
}
}
// If history to be compared is available
if (drpCompareTo.Items.Count > 0)
{
drpCompareTo.Items.Insert(0, GetString("history.select"));
}
// Otherwise hide dropdown list
else
{
pnlControl.Visible = false;
}
// Pre-select dropdown list
if (drpCompareTo.Items.FindByValue(versionCompare.ToString()) != null)
{
drpCompareTo.SelectedValue = versionCompare.ToString();
}
}
/// <summary>
/// Returns string with converted DateTime parameters according to specific user timezone settings.
/// </summary>
private string GetUserDate(object dateTimeVal)
{
DateTime date = ValidationHelper.GetDateTime(dateTimeVal, DateTimeHelper.ZERO_TIME);
return TimeZoneHelper.ConvertTimeZoneDateTime(date, serverTimeZone, usedTimeZone) + " " + TimeZoneHelper.GetUTCStringOffset(usedTimeZone);
}
/// <summary>
/// Returns version number with date for given document.
/// </summary>
private string GetVersionNumber(int documentId, int version)
{
DataSet ds = VersionManager.GetDocumentHistory(documentId, "VersionHistoryID =" + version, null, 1, "VersionNumber, ModifiedWhen");
if (DataHelper.DataSourceIsEmpty(ds))
{
return null;
}
else
{
string versionNumber = ValidationHelper.GetString(ds.Tables[0].Rows[0]["VersionNumber"], null);
versionNumber += " (" + GetUserDate(ds.Tables[0].Rows[0]["ModifiedWhen"]) + ")";
return versionNumber;
}
}
/// <summary>
/// Adds the field to the form.
/// </summary>
/// <param name="node">Document node</param>
/// <param name="compareNode">Document compare node</param>
/// <param name="columnName">Column name</param>
private void AddField(TreeNode node, TreeNode compareNode, string columnName)
{
FormFieldInfo ffi = null;
if (fi != null)
{
ffi = fi.GetFormField(columnName);
}
TableCell valueCell = new TableCell();
valueCell.EnableViewState = false;
TableCell valueCompare = new TableCell();
valueCompare.EnableViewState = false;
TableCell labelCell = new TableCell();
labelCell.EnableViewState = false;
TextComparison comparefirst;
TextComparison comparesecond;
bool loadValue = true;
bool empty = true;
bool allowLabel = true;
// Get the caption
if ((columnName == UNSORTED) || (ffi != null))
{
AttachmentInfo aiCompare = null;
// Compare attachments
if ((columnName == UNSORTED) || ((ffi != null) && (ffi.DataType == DocumentFieldDataType.DocAttachments)))
{
allowLabel = false;
string title = String.Empty;
if (columnName == UNSORTED)
{
title = GetString("attach.unsorted") + ":";
}
else if (ffi != null)
{
string caption = ffi.GetPropertyValue(FormFieldPropertyEnum.FieldCaption, MacroContext.CurrentResolver);
title = (String.IsNullOrEmpty(caption) ? ffi.Name : caption) + ":";
}
// Prepare DataSource for original node
loadValue = false;
dsAttachments = new AttachmentsDataSource();
dsAttachments.DocumentVersionHistoryID = versionHistoryId;
if ((ffi != null) && (columnName != UNSORTED))
{
dsAttachments.AttachmentGroupGUID = ffi.Guid;
}
dsAttachments.Path = node.NodeAliasPath;
dsAttachments.CultureCode = LocalizationContext.PreferredCultureCode;
SiteInfo si = SiteInfoProvider.GetSiteInfo(node.NodeSiteID);
dsAttachments.SiteName = si.SiteName;
dsAttachments.OrderBy = "AttachmentOrder, AttachmentName, AttachmentHistoryID";
dsAttachments.SelectedColumns = "AttachmentHistoryID, AttachmentGUID, AttachmentImageWidth, AttachmentImageHeight, AttachmentExtension, AttachmentName, AttachmentSize, AttachmentOrder, AttachmentTitle, AttachmentDescription";
dsAttachments.IsLiveSite = false;
dsAttachments.DataSource = null;
dsAttachments.DataBind();
// Get the attachments table
attachments = GetAttachmentsTable((DataSet)dsAttachments.DataSource, versionHistoryId, node.DocumentID);
// Prepare data source for compared node
if (compareNode != null)
{
dsAttachmentsCompare = new AttachmentsDataSource();
dsAttachmentsCompare.DocumentVersionHistoryID = versionCompare;
if ((ffi != null) && (columnName != UNSORTED))
{
dsAttachmentsCompare.AttachmentGroupGUID = ffi.Guid;
}
dsAttachmentsCompare.Path = compareNode.NodeAliasPath;
dsAttachmentsCompare.CultureCode = LocalizationContext.PreferredCultureCode;
dsAttachmentsCompare.SiteName = si.SiteName;
dsAttachmentsCompare.OrderBy = "AttachmentOrder, AttachmentName, AttachmentHistoryID";
dsAttachmentsCompare.SelectedColumns = "AttachmentHistoryID, AttachmentGUID, AttachmentImageWidth, AttachmentImageHeight, AttachmentExtension, AttachmentName, AttachmentSize, AttachmentOrder, AttachmentTitle, AttachmentDescription";
dsAttachmentsCompare.IsLiveSite = false;
dsAttachmentsCompare.DataSource = null;
dsAttachmentsCompare.DataBind();
// Get the table to compare
attachmentsCompare = GetAttachmentsTable((DataSet)dsAttachmentsCompare.DataSource, versionCompare, node.DocumentID);
// Switch the sides if older version is on the right
if (versionHistoryId > versionCompare)
{
Hashtable dummy = attachmentsCompare;
attachmentsCompare = attachments;
attachments = dummy;
}
// Add comparison
AddTableComparison(attachments, attachmentsCompare, "<strong>" + title + "</strong>", true, true);
}
else
{
// Normal display
if (attachments.Count != 0)
{
bool first = true;
foreach (DictionaryEntry item in attachments)
{
string itemValue = ValidationHelper.GetString(item.Value, null);
if (!String.IsNullOrEmpty(itemValue))
{
valueCell = new TableCell();
labelCell = new TableCell();
if (first)
{
labelCell.Text = "<strong>" + String.Format(title, item.Key) + "</strong>";
first = false;
}
valueCell.Text = itemValue;
AddRow(labelCell, valueCell);
}
}
}
}
}
// Compare single file attachment
else if ((ffi != null) && (ffi.DataType == FieldDataType.File))
{
// Get the attachment
AttachmentInfo ai = DocumentHelper.GetAttachment(ValidationHelper.GetGuid(node.GetValue(columnName), Guid.Empty), versionHistoryId, TreeProvider, false);
if (compareNode != null)
{
aiCompare = DocumentHelper.GetAttachment(ValidationHelper.GetGuid(compareNode.GetValue(columnName), Guid.Empty), versionCompare, TreeProvider, false);
}
loadValue = false;
// Prepare text comparison controls
if ((ai != null) || (aiCompare != null))
{
string textorig = null;
if (ai != null)
{
textorig = CreateAttachment(ai, versionHistoryId);
}
string textcompare = null;
if (aiCompare != null)
{
textcompare = CreateAttachment(aiCompare, versionCompare);
}
comparefirst = new TextComparison();
comparefirst.SynchronizedScrolling = false;
comparefirst.IgnoreHTMLTags = true;
comparefirst.ConsiderHTMLTagsEqual = true;
comparefirst.BalanceContent = false;
comparesecond = new TextComparison();
comparesecond.SynchronizedScrolling = false;
comparesecond.IgnoreHTMLTags = true;
// Source text must be older version
if (versionHistoryId < versionCompare)
{
comparefirst.SourceText = textorig;
comparefirst.DestinationText = textcompare;
}
else
{
comparefirst.SourceText = textcompare;
comparefirst.DestinationText = textorig;
}
comparefirst.PairedControl = comparesecond;
comparesecond.RenderingMode = TextComparisonTypeEnum.DestinationText;
valueCell.Controls.Add(comparefirst);
valueCompare.Controls.Add(comparesecond);
// Add both cells
if (compareNode != null)
{
AddRow(labelCell, valueCell, valueCompare);
}
// Add one cell only
else
{
valueCell.Controls.Clear();
Literal ltl = new Literal();
ltl.Text = textorig;
valueCell.Controls.Add(ltl);
AddRow(labelCell, valueCell);
}
}
}
}
if (allowLabel && String.IsNullOrEmpty(labelCell.Text))
{
labelCell.Text = "<strong>" + columnName + ":</strong>";
}
if (loadValue)
{
string textcompare = null;
switch (columnName.ToLowerCSafe())
{
// Document content - display content of editable regions and editable web parts
case "documentcontent":
EditableItems ei = new EditableItems();
ei.LoadContentXml(ValidationHelper.GetString(node.GetValue(columnName), String.Empty));
// Add text comparison control
if (compareNode != null)
{
EditableItems eiCompare = new EditableItems();
eiCompare.LoadContentXml(ValidationHelper.GetString(compareNode.GetValue(columnName), String.Empty));
// Create editable regions comparison
Hashtable hashtable;
Hashtable hashtableCompare;
// Source text must be older version
if (versionHistoryId < versionCompare)
{
hashtable = ei.EditableRegions;
hashtableCompare = eiCompare.EditableRegions;
}
else
{
hashtable = eiCompare.EditableRegions;
hashtableCompare = ei.EditableRegions;
}
// Add comparison
AddTableComparison(hashtable, hashtableCompare, "<strong>" + columnName + " ({0}):</strong>", false, false);
// Create editable webparts comparison
// Source text must be older version
if (versionHistoryId < versionCompare)
{
hashtable = ei.EditableWebParts;
hashtableCompare = eiCompare.EditableWebParts;
}
else
{
hashtable = eiCompare.EditableWebParts;
hashtableCompare = ei.EditableWebParts;
}
// Add comparison
AddTableComparison(hashtable, hashtableCompare, "<strong>" + columnName + " ({0}):</strong>", false, false);
}
// No compare node
else
{
// Editable regions
Hashtable hashtable = ei.EditableRegions;
if (hashtable.Count != 0)
{
foreach (DictionaryEntry region in hashtable)
{
string regionValue = ValidationHelper.GetString(region.Value, null);
if (!String.IsNullOrEmpty(regionValue))
{
string regionKey = ValidationHelper.GetString(region.Key, null);
valueCell = new TableCell();
labelCell = new TableCell();
labelCell.Text = "<strong>" + columnName + " (" + DictionaryHelper.GetFirstKey(regionKey) + "):</strong>";
valueCell.Text = HttpUtility.HtmlDecode(HTMLHelper.StripTags(regionValue, false));
AddRow(labelCell, valueCell);
}
}
}
// Editable web parts
hashtable = ei.EditableWebParts;
if (hashtable.Count != 0)
{
foreach (DictionaryEntry part in hashtable)
{
string partValue = ValidationHelper.GetString(part.Value, null);
if (!String.IsNullOrEmpty(partValue))
{
string partKey = ValidationHelper.GetString(part.Key, null);
valueCell = new TableCell();
labelCell = new TableCell();
labelCell.Text = "<strong>" + columnName + " (" + DictionaryHelper.GetFirstKey(partKey) + "):</strong>";
valueCell.Text = HttpUtility.HtmlDecode(HTMLHelper.StripTags(partValue, false));
AddRow(labelCell, valueCell);
}
}
}
}
break;
case "documentwebparts":
StringBuilder sbOriginal = new StringBuilder();
StringBuilder sbCompared = new StringBuilder();
// Set original web parts
string originalWebParts = Convert.ToString(node.GetValue(columnName));
GenerateWebPartsMarkup(ref sbOriginal, originalWebParts, true);
// Add text comparison control
if (compareNode != null)
{
string compareWebParts = Convert.ToString(compareNode.GetValue(columnName));
GenerateWebPartsMarkup(ref sbCompared, compareWebParts, false);
}
// Set empty flag
empty = ((sbOriginal.Length == 0) && (sbCompared.Length == 0));
if (!empty)
{
valueCell.Text += sbOriginal.ToString();
valueCompare.Text = sbCompared.ToString();
}
break;
// Others, display the string value
default:
// Shift date time values to user time zone
object origobject = node.GetValue(columnName);
string textorig;
if (origobject is DateTime)
{
textorig = TimeZoneHelper.ConvertToUserTimeZone(ValidationHelper.GetDateTime(origobject, DateTimeHelper.ZERO_TIME), true, CurrentUser, SiteContext.CurrentSite);
}
else
{
textorig = ValidationHelper.GetString(origobject, String.Empty);
}
// Add text comparison control
if (compareNode != null)
{
// Shift date time values to user time zone
object compareobject = compareNode.GetValue(columnName);
if (compareobject is DateTime)
{
textcompare = TimeZoneHelper.ConvertToUserTimeZone(ValidationHelper.GetDateTime(compareobject, DateTimeHelper.ZERO_TIME), true, CurrentUser, SiteContext.CurrentSite);
}
else
{
textcompare = ValidationHelper.GetString(compareobject, String.Empty);
}
comparefirst = new TextComparison();
comparefirst.SynchronizedScrolling = false;
comparesecond = new TextComparison();
comparesecond.SynchronizedScrolling = false;
comparesecond.RenderingMode = TextComparisonTypeEnum.DestinationText;
// Source text must be older version
if (versionHistoryId < versionCompare)
{
comparefirst.SourceText = HttpUtility.HtmlDecode(HTMLHelper.StripTags(textorig, false));
comparefirst.DestinationText = HttpUtility.HtmlDecode(HTMLHelper.StripTags(textcompare, false));
}
else
{
comparefirst.SourceText = HttpUtility.HtmlDecode(HTMLHelper.StripTags(textcompare, false));
comparefirst.DestinationText = HttpUtility.HtmlDecode(HTMLHelper.StripTags(textorig, false));
}
comparefirst.PairedControl = comparesecond;
if (Math.Max(comparefirst.SourceText.Length, comparefirst.DestinationText.Length) < 100)
{
comparefirst.BalanceContent = false;
}
valueCell.Controls.Add(comparefirst);
valueCompare.Controls.Add(comparesecond);
}
else
{
valueCell.Text = HttpUtility.HtmlDecode(HTMLHelper.StripTags(textorig, false));
}
empty = (String.IsNullOrEmpty(textorig)) && (String.IsNullOrEmpty(textcompare));
break;
}
}
if (!empty)
{
if (compareNode != null)
{
AddRow(labelCell, valueCell, valueCompare);
}
else
{
AddRow(labelCell, valueCell);
}
}
}
/// <summary>
/// Generates basic web parts markup
/// </summary>
/// <param name="sb">String builder</param>
/// <param name="xml">Web part xml</param>
private void GenerateWebPartsMarkup(ref StringBuilder sb, string xml, bool isLeft)
{
if (!String.IsNullOrEmpty(xml))
{
PageTemplateInstance inst = new PageTemplateInstance(xml);
if (inst.WebPartZones.Count > 0)
{
sb.Append(@"<a href=""#"" onclick=""versionExpandWebParts()"" id=""", isLeft ? "vWpLeftLink" : "vWpRightLink" , "\">"+ GetString("General.Expand") +"</a>");
sb.Append("<div style=\"display:none\" id=\"", isLeft ? "vWpLeft" : "vWpRight" , "\">");
foreach (WebPartZoneInstance zone in inst.WebPartZones)
{
sb.Append("<b>Zone</b>: ", HTMLHelper.HTMLEncode(zone.ZoneID));
sb.Append(@"<div class=""VZoneEnvelope"">");
foreach (WebPartInstance webPart in zone.WebParts)
{
sb.Append(HTMLHelper.HTMLEncode(webPart.ControlID), " (", HTMLHelper.HTMLEncode(webPart.WebPartType), ")");
sb.Append(@"<div class=""VWebPartEnvelope"">");
foreach (DictionaryEntry item in webPart.Properties)
{
string itemValue = Convert.ToString(item.Value);
string itemKey = Convert.ToString(item.Key);
if (!String.IsNullOrEmpty(itemValue))
{
sb.Append(HTMLHelper.HTMLEncode(itemKey), " : ", HTMLHelper.HTMLEncode(itemValue), "<br />");
}
}
sb.Append("</div>");
}
sb.Append("</div>");
}
sb.Append("</div>");
}
}
}
/// <summary>
/// Gets the hashtable of attachments from the DataSet.
/// </summary>
/// <param name="ds">Source DataSet</param>
/// <param name="versionId">Version history ID</param>
/// <param name="documentId">Document ID</param>
protected Hashtable GetAttachmentsTable(DataSet ds, int versionId, int documentId)
{
Hashtable result = new Hashtable();
if (!DataHelper.DataSourceIsEmpty(ds))
{
foreach (DataRow dr in ds.Tables[0].Rows)
{
// Get attachment GUID
Guid attachmentGuid = ValidationHelper.GetGuid(dr["AttachmentGUID"], Guid.Empty);
result[attachmentGuid.ToString()] = CreateAttachment(new DataRowContainer(dr), versionId);
}
}
return result;
}
/// <summary>
/// Adds the table comparison for matching objects.
/// </summary>
/// <param name="hashtable">Left side table</param>
/// <param name="hashtableCompare">Right side table</param>
/// <param name="titleFormat">Title format string</param>
/// <param name="includeAttachments">If true, the HTML code is kept (attachment comparison)</param>
/// <param name="renderOnlyFirstTitle">If true, only first title is rendered</param>
protected void AddTableComparison(Hashtable hashtable, Hashtable hashtableCompare, string titleFormat, bool includeAttachments, bool renderOnlyFirstTitle)
{
TableCell valueCell;
TableCell valueCompare;
TableCell labelCell;
TextComparison comparefirst;
TextComparison comparesecond;
bool firstTitle = true;
// Go through left column regions
if (hashtable != null)
{
foreach (DictionaryEntry entry in hashtable)
{
object value = entry.Value;
if (value != null)
{
// Initialize comparators
comparefirst = new TextComparison();
comparefirst.SynchronizedScrolling = false;
comparesecond = new TextComparison();
comparesecond.SynchronizedScrolling = false;
comparesecond.RenderingMode = TextComparisonTypeEnum.DestinationText;
if (includeAttachments)
{
comparefirst.IgnoreHTMLTags = true;
comparefirst.ConsiderHTMLTagsEqual = true;
comparesecond.IgnoreHTMLTags = true;
}
comparefirst.PairedControl = comparesecond;
// Initialize cells
valueCell = new TableCell();
valueCompare = new TableCell();
labelCell = new TableCell();
string key = ValidationHelper.GetString(entry.Key, null);
string strValue = ValidationHelper.GetString(value, null);
if (firstTitle || !renderOnlyFirstTitle)
{
labelCell.Text = String.Format(titleFormat, DictionaryHelper.GetFirstKey(key));
firstTitle = false;
}
comparefirst.SourceText = includeAttachments ? strValue : HttpUtility.HtmlDecode(HTMLHelper.StripTags(strValue, false));
if ((hashtableCompare != null) && hashtableCompare.Contains(key))
{
// Compare to the existing other version
string compareKey = ValidationHelper.GetString(hashtableCompare[key], null);
comparefirst.DestinationText = includeAttachments ? compareKey : HttpUtility.HtmlDecode(HTMLHelper.StripTags(compareKey, false));
hashtableCompare.Remove(key);
}
else
{
// Compare to an empty string
comparefirst.DestinationText = String.Empty;
}
// Do not balance content if too short
if (includeAttachments)
{
comparefirst.BalanceContent = false;
}
else if (Math.Max(comparefirst.SourceText.Length, comparefirst.DestinationText.Length) < 100)
{
comparefirst.BalanceContent = false;
}
// Create cell comparison
valueCell.Controls.Add(comparefirst);
valueCompare.Controls.Add(comparesecond);
AddRow(labelCell, valueCell, valueCompare);
}
}
}
// Go through right column regions which left
if (hashtableCompare != null)
{
foreach (DictionaryEntry entry in hashtableCompare)
{
object value = entry.Value;
if (value != null)
{
// Initialize comparators
comparefirst = new TextComparison();
comparefirst.SynchronizedScrolling = false;
comparesecond = new TextComparison();
comparesecond.SynchronizedScrolling = false;
comparesecond.RenderingMode = TextComparisonTypeEnum.DestinationText;
comparefirst.PairedControl = comparesecond;
if (includeAttachments)
{
comparefirst.IgnoreHTMLTags = true;
comparefirst.ConsiderHTMLTagsEqual = true;
comparesecond.IgnoreHTMLTags = true;
}
// Initialize cells
valueCell = new TableCell();
valueCompare = new TableCell();
labelCell = new TableCell();
if (firstTitle || !renderOnlyFirstTitle)
{
labelCell.Text = String.Format(titleFormat, DictionaryHelper.GetFirstKey(ValidationHelper.GetString(entry.Key, null)));
firstTitle = false;
}
comparefirst.SourceText = String.Empty;
string strValue = ValidationHelper.GetString(value, null);
comparefirst.DestinationText = includeAttachments ? strValue : HttpUtility.HtmlDecode(HTMLHelper.StripTags(strValue, false));
if (includeAttachments)
{
comparefirst.BalanceContent = false;
}
else if (Math.Max(comparefirst.SourceText.Length, comparefirst.DestinationText.Length) < 100)
{
comparefirst.BalanceContent = false;
}
// Create cell comparison
valueCell.Controls.Add(comparefirst);
valueCompare.Controls.Add(comparesecond);
AddRow(labelCell, valueCell, valueCompare);
}
}
}
}
/// <summary>
/// Returns new TableRow with CSS class.
/// </summary>
private TableRow CreateRow(string cssClass, bool isHeader)
{
TableRow newRow = isHeader ? new TableHeaderRow() { TableSection = TableRowSection.TableHeader } : new TableRow();
// Set CSS
if (!String.IsNullOrEmpty(cssClass))
{
newRow.CssClass = cssClass;
}
return newRow;
}
/// <summary>
/// Creates 2 column table.
/// </summary>
/// <param name="labelCell">Cell with label</param>
/// <param name="valueCell">Cell with content</param>
/// <param name="cssClass">CSS class</param>
/// <param name="isHeader">Indicates if created row is header row</param>
/// <returns>Returns TableRow object</returns>
private void AddRow(TableCell labelCell, TableCell valueCell, string cssClass = null, bool isHeader = false)
{
TableRow newRow = CreateRow(cssClass, isHeader);
newRow.Cells.Add(labelCell);
valueCell.Width = new Unit(100, UnitType.Percentage);
newRow.Cells.Add(valueCell);
tblDocument.Rows.Add(newRow);
}
/// <summary>
/// Creates 3 column table. Older version must be always in the left column.
/// </summary>
/// <param name="labelCell">Cell with label</param>
/// <param name="valueCell">Cell with content</param>
/// <param name="compareCell">Cell with compare content</param>
/// <param name="switchSides">Indicates if cells should be switched to match corresponding version (False by default)</param>
/// <param name="cssClass">CSS class</param>
/// <param name="isHeader">Indicates if created row is header row (False by default)</param>
/// <returns>Returns TableRow object</returns>
private void AddRow(TableCell labelCell, TableCell valueCell, TableCell compareCell, bool switchSides = false, string cssClass = null, bool isHeader = false)
{
TableRow newRow = CreateRow(cssClass, isHeader);
newRow.Cells.Add(labelCell);
const int cellWidth = 40;
// Switch sides to match version
if (switchSides)
{
// Older version must be in the left column
if (versionHistoryId < versionCompare)
{
valueCell.Width = new Unit(cellWidth, UnitType.Percentage);
newRow.Cells.Add(valueCell);
compareCell.Width = new Unit(cellWidth, UnitType.Percentage);
newRow.Cells.Add(compareCell);
}
else
{
compareCell.Width = new Unit(cellWidth, UnitType.Percentage);
newRow.Cells.Add(compareCell);
valueCell.Width = new Unit(cellWidth, UnitType.Percentage);
newRow.Cells.Add(valueCell);
}
}
// Do not switch sides
else
{
valueCell.Width = new Unit(cellWidth, UnitType.Percentage);
newRow.Cells.Add(valueCell);
compareCell.Width = new Unit(cellWidth, UnitType.Percentage);
newRow.Cells.Add(compareCell);
}
tblDocument.Rows.Add(newRow);
}
/// <summary>
/// Creates attachment string.
/// </summary>
private string CreateAttachment(IDataContainer dc, int versionId)
{
if (dc == null)
{
return null;
}
// Get attachment GUID
Guid attachmentGuid = ValidationHelper.GetGuid(dc.GetValue("AttachmentGUID"), Guid.Empty);
// Get attachment extension
string attachmentExt = ValidationHelper.GetString(dc.GetValue("AttachmentExtension"), null);
// Get link for attachment
string attName = ValidationHelper.GetString(dc.GetValue("AttachmentName"), null);
string attachmentUrl = AuthenticationHelper.ResolveUIUrl(AttachmentURLProvider.GetAttachmentUrl(attachmentGuid, URLHelper.GetSafeFileName(attName, SiteContext.CurrentSiteName), null, versionId));
// Ensure correct URL
attachmentUrl = URLHelper.AddParameterToUrl(attachmentUrl, "sitename", SiteContext.CurrentSiteName);
// Optionally trim attachment name
string attachmentName = TextHelper.LimitLength(attName, 90);
bool isImage = ImageHelper.IsImage(attachmentExt);
// Tooltip
string tooltip = null;
if (isImage)
{
int attachmentWidth = ValidationHelper.GetInteger(dc.GetValue("AttachmentImageWidth"), 0);
if (attachmentWidth > 300)
{
attachmentWidth = 300;
}
tooltip = "onmouseout=\"UnTip()\" onmouseover=\"TipImage(" + attachmentWidth + ", '" + URLHelper.AddParameterToUrl(attachmentUrl, "width", "300") + "', " + ScriptHelper.GetString(HTMLHelper.HTMLEncode(attachmentName)) + ")\"";
}
string attachmentSize = DataHelper.GetSizeString(ValidationHelper.GetLong(dc.GetValue("AttachmentSize"), 0));
string title = ValidationHelper.GetString(dc.GetValue("AttachmentTitle"), string.Empty);
string description = ValidationHelper.GetString(dc.GetValue("AttachmentDescription"), string.Empty);
// Icon
var additional = new StringBuilder();
additional.Append(tooltip, "onclick=\"javascript: window.open(", ScriptHelper.GetString(attachmentUrl), "); return false;\" style=\"cursor: pointer;\"");
var sb = new StringBuilder();
sb.Append(UIHelper.GetFileIcon(Page, attachmentExt, tooltip: HTMLHelper.HTMLEncode(attachmentName), additionalAttributes: additional.ToString()));
sb.Append(" ", HTMLHelper.HTMLEncode(attachmentName), " (", HTMLHelper.HTMLEncode(attachmentSize), ")<br />");
sb.Append("<table class=\"table-blank\"><tr><td><strong>", GetString("general.title"), ":</strong></td><td>", HTMLHelper.HTMLEncode(title), "</td></tr>");
sb.Append("<tr><td><strong>", GetString("general.description"), ":</strong></td><td>", HTMLHelper.HTMLEncode(description), "</td></tr></table>");
return sb.ToString();
}
#endregion
#region "Events"
/// <summary>
/// Dropdown list selection changed.
/// </summary>
private void drpCompareTo_SelectedIndexChanged(object sender, EventArgs e)
{
string url = RequestContext.CurrentURL;
url = URLHelper.RemoveParameterFromUrl(url, "rollbackok");
url = drpCompareTo.SelectedIndex == 0 ? URLHelper.RemoveParameterFromUrl(url, "compareHistoryId") : URLHelper.AddParameterToUrl(url, "compareHistoryId", drpCompareTo.SelectedValue);
URLHelper.Redirect(url);
}
#endregion
#region "IPostBackEventHandler Members"
/// <summary>
/// Raises event postback event.
/// </summary>
/// <param name="eventArgument">Argument</param>
public void RaisePostBackEvent(string eventArgument)
{
int rollbackVersionId = ValidationHelper.GetInteger(eventArgument, 0);
if (rollbackVersionId > 0)
{
if (Node == null)
{
return;
}
if (CheckedOutByUserID > 0)
{
// Document is checked out
ShowError(GetString("VersionProperties.CannotRollbackCheckedOut"));
}
else
{
// Check permissions
bool canApprove = WorkflowManager.CheckStepPermissions(Node, WorkflowActionEnum.Approve);
if (!canApprove || !CanModify)
{
ShowError(String.Format(GetString("cmsdesk.notauthorizedtoeditdocument"), Node.NodeAliasPath));
}
else
{
try
{
// Rollback version
int newVersionHistoryId = VersionManager.RollbackVersion(rollbackVersionId);
ShowConfirmation(GetString("VersionProperties.RollbackOK"));
string url = RequestContext.CurrentURL;
// Add URL parameters
url = URLHelper.AddParameterToUrl(url, "versionHistoryId", newVersionHistoryId.ToString());
url = URLHelper.AddParameterToUrl(url, "compareHistoryId", versionCompare.ToString());
url = URLHelper.AddParameterToUrl(url, "rollbackok", "1");
// Prepare URL
url = ScriptHelper.GetString(URLHelper.ResolveUrl(url), true);
// Prepare script for refresh parent window and this dialog
StringBuilder builder = new StringBuilder();
builder.Append("if (wopener != null) {\n");
builder.Append("if (wopener.RefreshTree != null) {wopener.RefreshTree(", Node.NodeParentID, ", ", Node.NodeID, "); }");
builder.Append("wopener.document.location.replace(wopener.document.location);}\n");
builder.Append("window.document.location.replace(" + url + ");");
string script = ScriptHelper.GetScript(builder.ToString());
ScriptHelper.RegisterStartupScript(this, typeof(string), "RefreshAndReload", script);
}
catch (Exception ex)
{
ShowError(GetString("versionproperties.rollbackerror"));
EventLogProvider.LogException("Content", "ROLLBACKVERSION", ex);
}
}
}
// Display form if error occurs
if (error)
{
ReloadData();
}
}
}
#endregion
}