Fixes: #U4-227 - ensures data is not persisted to the db for members/media if validation fails.

Fixes up (enables) validation summary for members too.
This commit is contained in:
Shannon Deminick
2013-04-17 22:41:43 +06:00
parent 096c5ad69f
commit ff5dc324fe
4 changed files with 217 additions and 209 deletions

View File

@@ -29,6 +29,13 @@ namespace umbraco.controls
/// </summary>
public class ContentControl : TabView
{
public ContentControl()
{
//by default set this to true for content
SavePropertyDataWhenInvalid = true;
}
private readonly Content _content;
private readonly ArrayList _dataFields = new ArrayList();
private UmbracoEnsuredPage _prntpage;
@@ -50,6 +57,19 @@ namespace umbraco.controls
get { return _content; }
}
/// <summary>
/// This property controls whether the content property values are persisted even if validation
/// fails. If set to false, then the values will not be persisted.
/// </summary>
/// <remarks>
/// This is required because when we are editing content we should be persisting invalid values to the database
/// as this makes it easier for editors to come back and fix up their changes before they publish. Of course we
/// don't publish if the page is invalid. In the case of media and members, we don't want to persist the values
/// to the database when the page is invalid because there is no published state.
/// Relates to: http://issues.umbraco.org/issue/U4-227
/// </remarks>
public bool SavePropertyDataWhenInvalid { get; set; }
[Obsolete("This is no longer used and will be removed from the codebase in future versions")]
private string _errorMessage = "";
@@ -261,34 +281,33 @@ namespace umbraco.controls
private void SaveClick(object sender, ImageClickEventArgs e)
{
////TODO: If we are editing media/content we should not continue saving
//// if the page is invalid!
//// http://issues.umbraco.org/issue/U4-227
//if (Page.IsValid)
//{
//}
var doc = this._content as Document;
if (doc != null)
{
//we only continue saving anything if:
// SavePropertyDataWhenInvalid == true
// OR if the page is actually valid.
if (SavePropertyDataWhenInvalid || Page.IsValid)
{
var docArgs = new SaveEventArgs();
doc.FireBeforeSave(docArgs);
if (docArgs.Cancel) //TODO: need to have some notification to the user here
var doc = this._content as Document;
if (doc != null)
{
return;
}
}
foreach (IDataEditor df in _dataFields)
{
df.Save();
}
var docArgs = new SaveEventArgs();
doc.FireBeforeSave(docArgs);
//don't update if the name is empty
if (!NameTxt.Text.IsNullOrWhiteSpace())
{
_content.Text = NameTxt.Text;
if (docArgs.Cancel) //TODO: need to have some notification to the user here
{
return;
}
}
foreach (IDataEditor df in _dataFields)
{
df.Save();
}
//don't update if the name is empty
if (!NameTxt.Text.IsNullOrWhiteSpace())
{
_content.Text = NameTxt.Text;
}
}
if (Save != null)

View File

@@ -265,9 +265,6 @@ namespace umbraco.cms.presentation
}
}
// Run Handler
BusinessLogic.Actions.Action.RunActionHandlers(_document, ActionUpdate.Instance);
_document.Save();

View File

@@ -25,9 +25,9 @@ namespace umbraco.cms.presentation
/// </summary>
public partial class editMedia : BasePages.UmbracoEnsuredPage
{
private uicontrols.Pane mediaPropertiesPane = new uicontrols.Pane();
private LiteralControl updateDateLiteral = new LiteralControl();
private LiteralControl mediaFileLinksLiteral = new LiteralControl();
private readonly uicontrols.Pane _mediaPropertiesPane = new uicontrols.Pane();
private readonly LiteralControl _updateDateLiteral = new LiteralControl();
private readonly LiteralControl _mediaFileLinksLiteral = new LiteralControl();
public editMedia()
{
@@ -35,18 +35,12 @@ namespace umbraco.cms.presentation
}
protected uicontrols.TabView TabView1;
protected System.Web.UI.WebControls.TextBox documentName;
private cms.businesslogic.media.Media _media;
controls.ContentControl tmp;
//protected System.Web.UI.WebControls.Literal SyncPath;
protected TextBox documentName;
private businesslogic.media.Media _media;
controls.ContentControl _contentControl;
override protected void OnInit(EventArgs e)
{
//
// CODEGEN: This call is required by the ASP.NET Web Form Designer.
//
InitializeComponent();
base.OnInit(e);
_media = new cms.businesslogic.media.Media(int.Parse(Request.QueryString["id"]));
@@ -55,88 +49,83 @@ namespace umbraco.cms.presentation
bool exists = SqlHelper.ExecuteScalar<int>("SELECT COUNT(nodeId) FROM cmsContentXml WHERE nodeId = @nodeId",
SqlHelper.CreateParameter("@nodeId", _media.Id)) > 0;
if (!exists)
{
_media.XmlGenerate(new XmlDocument());
}
_contentControl = new controls.ContentControl(_media, controls.ContentControl.publishModes.NoPublish, "TabView1");
_contentControl.Width = Unit.Pixel(666);
_contentControl.Height = Unit.Pixel(666);
tmp = new controls.ContentControl(_media, controls.ContentControl.publishModes.NoPublish, "TabView1");
tmp.Width = Unit.Pixel(666);
tmp.Height = Unit.Pixel(666);
plc.Controls.Add(tmp);
//this must be set to false as we don't want to proceed to save anything if the page is invalid
_contentControl.SavePropertyDataWhenInvalid = false;
tmp.Save += new System.EventHandler(Save);
plc.Controls.Add(_contentControl);
this.updateDateLiteral.ID = "updateDate";
this.updateDateLiteral.Text = _media.VersionDate.ToShortDateString() + " " + _media.VersionDate.ToShortTimeString();
_contentControl.Save += new System.EventHandler(Save);
this.mediaFileLinksLiteral.ID = "mediaFileLinks";
mediaPropertiesPane.addProperty(ui.Text("content", "updateDate", base.getUser()), this.updateDateLiteral);
this._updateDateLiteral.ID = "updateDate";
this._updateDateLiteral.Text = _media.VersionDate.ToShortDateString() + " " + _media.VersionDate.ToShortTimeString();
this._mediaFileLinksLiteral.ID = "mediaFileLinks";
_mediaPropertiesPane.addProperty(ui.Text("content", "updateDate", base.getUser()), this._updateDateLiteral);
this.UpdateMediaFileLinksLiteral();
mediaPropertiesPane.addProperty(ui.Text("content", "mediaLinks"), this.mediaFileLinksLiteral);
_mediaPropertiesPane.addProperty(ui.Text("content", "mediaLinks"), this._mediaFileLinksLiteral);
// add the property pane to the page rendering
tmp.tpProp.Controls.AddAt(1, mediaPropertiesPane);
_contentControl.tpProp.Controls.AddAt(1, _mediaPropertiesPane);
}
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
}
protected void Page_Load(object sender, System.EventArgs e)
protected void Page_Load(object sender, EventArgs e)
{
//if (!IsPostBack)
//{
// SyncPath.Text = _media.Path;
// newName.Text = _media.Text.Replace("'", "\\'");
//}
if (!IsPostBack)
{
ClientTools.SyncTree(_media.Path, false);
}
}
protected void Save(object sender, System.EventArgs e)
protected void Save(object sender, EventArgs e)
{
// error handling test
// do not continue saving anything if the page is invalid!
// http://issues.umbraco.org/issue/U4-227
if (!Page.IsValid)
{
foreach (uicontrols.TabPage tp in tmp.GetPanels())
foreach (uicontrols.TabPage tp in _contentControl.GetPanels())
{
tp.ErrorControl.Visible = true;
tp.ErrorHeader = ui.Text("errorHandling", "errorHeader");
tp.CloseCaption = ui.Text("close");
}
}
else if (Page.IsPostBack)
else
{
// hide validation summaries
foreach (uicontrols.TabPage tp in tmp.GetPanels())
if (Page.IsPostBack)
{
tp.ErrorControl.Visible = false;
}
}
_media.Save();
// hide validation summaries
foreach (uicontrols.TabPage tp in _contentControl.GetPanels())
{
tp.ErrorControl.Visible = false;
}
}
this.updateDateLiteral.Text = _media.VersionDate.ToShortDateString() + " " + _media.VersionDate.ToShortTimeString();
this.UpdateMediaFileLinksLiteral();
_media.Save();
_media.XmlGenerate(new XmlDocument());
ClientTools.ShowSpeechBubble(speechBubbleIcon.save, ui.Text("speechBubbles", "editMediaSaved"), ui.Text("editMediaSavedText"));
ClientTools.SyncTree(_media.Path, true);
this._updateDateLiteral.Text = _media.VersionDate.ToShortDateString() + " " + _media.VersionDate.ToShortTimeString();
this.UpdateMediaFileLinksLiteral();
_media.XmlGenerate(new XmlDocument());
ClientTools.ShowSpeechBubble(speechBubbleIcon.save, ui.Text("speechBubbles", "editMediaSaved"), ui.Text("editMediaSavedText"));
ClientTools.SyncTree(_media.Path, true);
}
}
private void UpdateMediaFileLinksLiteral()
{
var uploadField = new Factory().GetNewObject(new Guid("5032a6e6-69e3-491d-bb28-cd31cd11086c"));
// always clear, incase the upload file was removed
this.mediaFileLinksLiteral.Text = string.Empty;
this._mediaFileLinksLiteral.Text = string.Empty;
try
{
@@ -149,14 +138,14 @@ namespace umbraco.cms.presentation
if (properties.Any())
{
this.mediaFileLinksLiteral.Text += "<table>";
this._mediaFileLinksLiteral.Text += "<table>";
foreach (var property in properties)
{
this.mediaFileLinksLiteral.Text += string.Format("<tr><td>{0}&nbsp;</td><td><a href=\"{1}\" target=\"_blank\">{1}</a></td></tr>", property.PropertyType.Name, property.Value);
this._mediaFileLinksLiteral.Text += string.Format("<tr><td>{0}&nbsp;</td><td><a href=\"{1}\" target=\"_blank\">{1}</a></td></tr>", property.PropertyType.Name, property.Value);
}
this.mediaFileLinksLiteral.Text += "</table>";
this._mediaFileLinksLiteral.Text += "</table>";
}
}
catch

View File

@@ -1,17 +1,9 @@
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using Umbraco.Core.IO;
using umbraco.cms.businesslogic.member;
using System.Web.Security;
using umbraco.IO;
namespace umbraco.cms.presentation.members
{
@@ -25,11 +17,11 @@ namespace umbraco.cms.presentation.members
CurrentApp = BusinessLogic.DefaultApps.member.ToString();
}
protected uicontrols.TabView TabView1;
protected System.Web.UI.WebControls.TextBox documentName;
private cms.businesslogic.member.Member _document;
private MembershipUser m_Member;
controls.ContentControl tmp;
protected umbraco.uicontrols.UmbracoPanel m_MemberShipPanel = new umbraco.uicontrols.UmbracoPanel();
protected TextBox documentName;
private Member _document;
private MembershipUser _member;
controls.ContentControl _contentControl;
protected uicontrols.UmbracoPanel m_MemberShipPanel = new uicontrols.UmbracoPanel();
protected TextBox MemberLoginNameTxt = new TextBox();
protected RequiredFieldValidator MemberLoginNameVal = new RequiredFieldValidator();
@@ -39,7 +31,7 @@ namespace umbraco.cms.presentation.members
protected controls.DualSelectbox _memberGroups = new controls.DualSelectbox();
protected void Page_Load(object sender, System.EventArgs e)
protected void Page_Load(object sender, EventArgs e)
{
// Add password changer
@@ -47,19 +39,23 @@ namespace umbraco.cms.presentation.members
if (Member.InUmbracoMemberMode())
{
_document = new cms.businesslogic.member.Member(int.Parse(Request.QueryString["id"]));
m_Member = Membership.GetUser(_document.Id);
tmp = new controls.ContentControl(_document, controls.ContentControl.publishModes.NoPublish, "TabView1");
tmp.Width = Unit.Pixel(666);
tmp.Height = Unit.Pixel(666);
plc.Controls.Add(tmp);
_document = new Member(int.Parse(Request.QueryString["id"]));
_member = Membership.GetUser(_document.Id);
_contentControl = new controls.ContentControl(_document, controls.ContentControl.publishModes.NoPublish, "TabView1");
_contentControl.Width = Unit.Pixel(666);
_contentControl.Height = Unit.Pixel(666);
//this must be set to false as we don't want to proceed to save anything if the page is invalid
_contentControl.SavePropertyDataWhenInvalid = false;
plc.Controls.Add(_contentControl);
if (!IsPostBack)
{
MemberLoginNameTxt.Text = _document.LoginName;
MemberEmail.Text = _document.Email;
}
PlaceHolder ph = new PlaceHolder();
var ph = new PlaceHolder();
MemberLoginNameTxt.ID = "loginname";
ph.Controls.Add(MemberLoginNameTxt);
ph.Controls.Add(MemberLoginNameVal);
@@ -69,26 +65,27 @@ namespace umbraco.cms.presentation.members
MemberLoginNameVal.EnableClientScript = false;
MemberLoginNameVal.Display = ValidatorDisplay.Dynamic;
tmp.PropertiesPane.addProperty(ui.Text("login"), ph);
tmp.PropertiesPane.addProperty(ui.Text("password"), MemberPasswordTxt);
tmp.PropertiesPane.addProperty("Email", MemberEmail);
_contentControl.PropertiesPane.addProperty(ui.Text("login"), ph);
_contentControl.PropertiesPane.addProperty(ui.Text("password"), MemberPasswordTxt);
_contentControl.PropertiesPane.addProperty("Email", MemberEmail);
}
else
{
m_Member = Membership.GetUser(Request.QueryString["id"]);
MemberLoginNameTxt.Text = m_Member.UserName;
_member = Membership.GetUser(Request.QueryString["id"]);
MemberLoginNameTxt.Text = _member.UserName;
if (!IsPostBack)
{
MemberEmail.Text = m_Member.Email;
MemberEmail.Text = _member.Email;
}
m_MemberShipPanel.Width = 300;
m_MemberShipPanel.Text = ui.Text("edit") + " " + m_Member.UserName;
umbraco.uicontrols.Pane props = new umbraco.uicontrols.Pane();
m_MemberShipPanel.Text = ui.Text("edit") + " " + _member.UserName;
var props = new uicontrols.Pane();
MemberLoginNameTxt.Enabled = false;
// check for pw support
if (!Membership.Provider.EnablePasswordRetrieval) {
if (!Membership.Provider.EnablePasswordRetrieval)
{
MemberPasswordTxt.Controls.Clear();
MemberPasswordTxt.Controls.Add(
new LiteralControl("<em>" + ui.Text("errorHandling", "errorChangingProviderPassword") + "</em>"));
@@ -102,20 +99,20 @@ namespace umbraco.cms.presentation.members
}
// Groups
umbraco.uicontrols.Pane p = new umbraco.uicontrols.Pane();
var p = new uicontrols.Pane();
_memberGroups.ID = "Membergroups";
_memberGroups.Width = 175;
string selectedMembers = "";
foreach(string role in Roles.GetAllRoles())
var selectedMembers = "";
foreach(var role in Roles.GetAllRoles())
{
// if a role starts with __umbracoRole we won't show it as it's an internal role used for public access
if (!role.StartsWith("__umbracoRole"))
{
ListItem li = new ListItem(role);
var li = new ListItem(role);
if (!IsPostBack)
{
if (Roles.IsUserInRole(m_Member.UserName, role))
if (Roles.IsUserInRole(_member.UserName, role))
selectedMembers += role + ",";
}
_memberGroups.Items.Add(li);
@@ -127,113 +124,119 @@ namespace umbraco.cms.presentation.members
if (Member.InUmbracoMemberMode())
{
tmp.tpProp.Controls.Add(p);
tmp.Save += new System.EventHandler(tmp_save);
_contentControl.tpProp.Controls.Add(p);
_contentControl.Save += new System.EventHandler(tmp_save);
}
else
m_MemberShipPanel.Controls.Add(p);
}
void menuSave_Click(object sender, ImageClickEventArgs e)
void MenuSaveClick(object sender, ImageClickEventArgs e)
{
tmp_save(sender, e);
}
protected void tmp_save(object sender, System.EventArgs e) {
Page.Validate();
if (Page.IsValid)
{
if (Member.InUmbracoMemberMode())
protected void tmp_save(object sender, EventArgs e)
{
Page.Validate();
if (!Page.IsValid)
{
foreach (uicontrols.TabPage tp in _contentControl.GetPanels())
{
_document.LoginName = MemberLoginNameTxt.Text;
_document.Email = MemberEmail.Text;
// Check if password should be changed
string tempPassword = ((controls.passwordChanger) MemberPasswordTxt.Controls[0]).Password;
if (tempPassword.Trim() != "")
_document.Password = tempPassword;
// Groups
foreach (ListItem li in _memberGroups.Items)
if (("," + _memberGroups.Value + ",").IndexOf("," + li.Value + ",") > -1)
{
if (!Roles.IsUserInRole(_document.LoginName, li.Value))
Roles.AddUserToRole(_document.LoginName, li.Value);
}
else if (Roles.IsUserInRole(_document.LoginName, li.Value))
{
Roles.RemoveUserFromRole(_document.LoginName, li.Value);
}
// refresh cache
_document.XmlGenerate(new System.Xml.XmlDocument());
_document.Save();
tp.ErrorControl.Visible = true;
tp.ErrorHeader = ui.Text("errorHandling", "errorHeader");
tp.CloseCaption = ui.Text("close");
}
else
}
else
{
if (Page.IsPostBack)
{
m_Member.Email = MemberEmail.Text;
if (Membership.Provider.EnablePasswordRetrieval)
// hide validation summaries
foreach (uicontrols.TabPage tp in _contentControl.GetPanels())
{
string tempPassword = ((controls.passwordChanger) MemberPasswordTxt.Controls[0]).Password;
if (tempPassword.Trim() != "")
m_Member.ChangePassword(m_Member.GetPassword(), tempPassword);
tp.ErrorControl.Visible = false;
}
Membership.UpdateUser(m_Member);
// Groups
foreach (ListItem li in _memberGroups.Items)
if (("," + _memberGroups.Value + ",").IndexOf("," + li.Value + ",") > -1)
{
if (!Roles.IsUserInRole(m_Member.UserName, li.Value))
Roles.AddUserToRole(m_Member.UserName, li.Value);
}
else if (Roles.IsUserInRole(m_Member.UserName, li.Value))
{
Roles.RemoveUserFromRole(m_Member.UserName, li.Value);
}
}
}
if (Member.InUmbracoMemberMode())
{
_document.LoginName = MemberLoginNameTxt.Text;
_document.Email = MemberEmail.Text;
this.speechBubble(BasePages.BasePage.speechBubbleIcon.save,
ui.Text("speechBubbles", "editMemberSaved", base.getUser()), "");
}
}
// Check if password should be changed
string tempPassword = ((controls.passwordChanger) MemberPasswordTxt.Controls[0]).Password;
if (tempPassword.Trim() != "")
_document.Password = tempPassword;
private umbraco.uicontrols.PropertyPanel AddProperty(string Caption, Control C) {
umbraco.uicontrols.PropertyPanel pp = new umbraco.uicontrols.PropertyPanel();
pp.Controls.Add(C);
pp.Text = Caption;
return pp;
}
#region Web Form Designer generated code
override protected void OnInit(EventArgs e)
// Groups
foreach (ListItem li in _memberGroups.Items)
if (("," + _memberGroups.Value + ",").IndexOf("," + li.Value + ",") > -1)
{
if (!Roles.IsUserInRole(_document.LoginName, li.Value))
Roles.AddUserToRole(_document.LoginName, li.Value);
}
else if (Roles.IsUserInRole(_document.LoginName, li.Value))
{
Roles.RemoveUserFromRole(_document.LoginName, li.Value);
}
// refresh cache
_document.XmlGenerate(new System.Xml.XmlDocument());
_document.Save();
}
else
{
_member.Email = MemberEmail.Text;
if (Membership.Provider.EnablePasswordRetrieval)
{
string tempPassword = ((controls.passwordChanger) MemberPasswordTxt.Controls[0]).Password;
if (tempPassword.Trim() != "")
_member.ChangePassword(_member.GetPassword(), tempPassword);
}
Membership.UpdateUser(_member);
// Groups
foreach (ListItem li in _memberGroups.Items)
if (("," + _memberGroups.Value + ",").IndexOf("," + li.Value + ",") > -1)
{
if (!Roles.IsUserInRole(_member.UserName, li.Value))
Roles.AddUserToRole(_member.UserName, li.Value);
}
else if (Roles.IsUserInRole(_member.UserName, li.Value))
{
Roles.RemoveUserFromRole(_member.UserName, li.Value);
}
}
this.speechBubble(speechBubbleIcon.save, ui.Text("speechBubbles", "editMemberSaved", base.getUser()), "");
}
}
private uicontrols.PropertyPanel AddProperty(string caption, Control c)
{
var pp = new uicontrols.PropertyPanel();
pp.Controls.Add(c);
pp.Text = caption;
return pp;
}
override protected void OnInit(EventArgs e)
{
//
// CODEGEN: This call is required by the ASP.NET Web Form Designer.
//
if (!Member.InUmbracoMemberMode()) {
m_MemberShipPanel.hasMenu = true;
umbraco.uicontrols.MenuImageButton menuSave = m_MemberShipPanel.Menu.NewImageButton();
menuSave.ID = m_MemberShipPanel.ID + "_save";
menuSave.ImageUrl = SystemDirectories.Umbraco + "/images/editor/save.gif";
menuSave.Click += new ImageClickEventHandler(menuSave_Click);
menuSave.AltText = ui.Text("buttons", "save", null);
}
InitializeComponent();
base.OnInit(e);
if (!Member.InUmbracoMemberMode())
{
m_MemberShipPanel.hasMenu = true;
umbraco.uicontrols.MenuImageButton menuSave = m_MemberShipPanel.Menu.NewImageButton();
menuSave.ID = m_MemberShipPanel.ID + "_save";
menuSave.ImageUrl = SystemDirectories.Umbraco + "/images/editor/save.gif";
menuSave.Click += new ImageClickEventHandler(MenuSaveClick);
menuSave.AltText = ui.Text("buttons", "save", null);
}
base.OnInit(e);
}
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
}
#endregion
}
}