diff --git a/build/NuSpecs/UmbracoCms.Core.nuspec b/build/NuSpecs/UmbracoCms.Core.nuspec index 4bf105df18..8d4aeb69c8 100644 --- a/build/NuSpecs/UmbracoCms.Core.nuspec +++ b/build/NuSpecs/UmbracoCms.Core.nuspec @@ -1,4 +1,4 @@ - + UmbracoCms.Core @@ -20,12 +20,12 @@ - + - - + + @@ -68,4 +68,5 @@ + \ No newline at end of file diff --git a/build/NuSpecs/UmbracoCms.nuspec b/build/NuSpecs/UmbracoCms.nuspec index 07ef412ce5..858407f80a 100644 --- a/build/NuSpecs/UmbracoCms.nuspec +++ b/build/NuSpecs/UmbracoCms.nuspec @@ -1,4 +1,4 @@ - + UmbracoCms diff --git a/src/Umbraco.Core/DatabaseContext.cs b/src/Umbraco.Core/DatabaseContext.cs index 2f0efcbfc0..dbbc476ae9 100644 --- a/src/Umbraco.Core/DatabaseContext.cs +++ b/src/Umbraco.Core/DatabaseContext.cs @@ -112,7 +112,7 @@ namespace Umbraco.Core public void ConfigureEmbeddedDatabaseConnection() { const string providerName = "System.Data.SqlServerCe.4.0"; - const string connectionString = @"Data Source=|DataDirectory|\Umbraco.sdf;Flush Interval=1;File Access Retry Timeout=10"; + const string connectionString = @"Data Source=|DataDirectory|\Umbraco.sdf;Flush Interval=1;"; SaveConnectionString(connectionString, providerName); diff --git a/src/Umbraco.Core/Models/MemberType.cs b/src/Umbraco.Core/Models/MemberType.cs index ed7d5cd3ab..2b32681392 100644 --- a/src/Umbraco.Core/Models/MemberType.cs +++ b/src/Umbraco.Core/Models/MemberType.cs @@ -114,5 +114,26 @@ namespace Umbraco.Core.Models MemberTypePropertyTypes.Add(propertyTypeAlias, tuple); } } + + /// + /// Method to call when Entity is being saved + /// + /// Created date is set and a Unique key is assigned + internal override void AddingEntity() + { + base.AddingEntity(); + + if (Key == Guid.Empty) + Key = Guid.NewGuid(); + } + + /// + /// Method to call when Entity is being updated + /// + /// Modified Date is set and a new Version guid is set + internal override void UpdatingEntity() + { + base.UpdatingEntity(); + } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Models/Rdbms/PropertyTypeReadOnlyDto.cs b/src/Umbraco.Core/Models/Rdbms/PropertyTypeReadOnlyDto.cs index 9a6610e5d8..f46c4e9dae 100644 --- a/src/Umbraco.Core/Models/Rdbms/PropertyTypeReadOnlyDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/PropertyTypeReadOnlyDto.cs @@ -17,7 +17,7 @@ namespace Umbraco.Core.Models.Rdbms [Column("contentTypeId")] public int ContentTypeId { get; set; } - [Column("propertyTypeGroupId")] + [Column("PropertyTypesGroupId")] public int? PropertyTypeGroupId { get; set; } [Column("Alias")] diff --git a/src/Umbraco.Core/Persistence/Factories/MemberReadOnlyFactory.cs b/src/Umbraco.Core/Persistence/Factories/MemberReadOnlyFactory.cs index eb6e2c787d..09d4765eb3 100644 --- a/src/Umbraco.Core/Persistence/Factories/MemberReadOnlyFactory.cs +++ b/src/Umbraco.Core/Persistence/Factories/MemberReadOnlyFactory.cs @@ -61,7 +61,7 @@ namespace Umbraco.Core.Persistence.Factories ? propertyType.CreatePropertyFromValue(null) : propertyType.CreatePropertyFromRawValue(propertyDataDto.GetValue, propertyDataDto.VersionId, - propertyDataDto.Id); + propertyDataDto.PropertyDataId.Value); //on initial construction we don't want to have dirty properties tracked property.CreateDate = createDate; property.UpdateDate = createDate; diff --git a/src/Umbraco.Core/Persistence/Factories/MemberTypeReadOnlyFactory.cs b/src/Umbraco.Core/Persistence/Factories/MemberTypeReadOnlyFactory.cs index 3ce07ed2c8..3462cef894 100644 --- a/src/Umbraco.Core/Persistence/Factories/MemberTypeReadOnlyFactory.cs +++ b/src/Umbraco.Core/Persistence/Factories/MemberTypeReadOnlyFactory.cs @@ -55,51 +55,75 @@ namespace Umbraco.Core.Persistence.Factories private PropertyGroupCollection GetPropertyTypeGroupCollection(MemberTypeReadOnlyDto dto, MemberType memberType) { - var propertyTypeGroupCollection = new PropertyGroupCollection(); - foreach (var propertyTypeGroup in dto.PropertyTypeGroups.Where(x => x.Id.HasValue)) + var propertyGroups = new PropertyGroupCollection(); + foreach (var groupDto in dto.PropertyTypeGroups.Where(x => x.Id.HasValue)) { - //Find PropertyTypes that belong to the current PropertyTypeGroup - var groupId = propertyTypeGroup.Id.Value; - var propertyTypesByGroup = - dto.PropertyTypes.Where( - x => x.Id.HasValue && x.PropertyTypeGroupId.HasValue && x.PropertyTypeGroupId.Value.Equals(groupId)); - //Create PropertyTypeCollection for passing into the PropertyTypeGroup, and loop through the above result to create PropertyTypes - var propertyTypeCollection = new PropertyTypeCollection(); - foreach (var propTypeDto in propertyTypesByGroup) + var group = new PropertyGroup(); + + //Only assign an Id if the PropertyGroup belongs to this ContentType + if (groupDto.Id.HasValue + /*SD: I've commented this out since it's never correct, why would the group id be the same as the type?? + * && groupDto.Id == memberType.Id*/) { - //Internal dictionary for adding "MemberCanEdit" and "VisibleOnProfile" properties to each PropertyType - memberType.MemberTypePropertyTypes.Add(propTypeDto.Alias, - new Tuple(propTypeDto.CanEdit, propTypeDto.ViewOnProfile, propTypeDto.Id.Value)); - //PropertyType Collection - propertyTypeCollection.Add(new PropertyType(propTypeDto.PropertyEditorAlias, - propTypeDto.DbType.EnumParse(true)) - { - Alias = propTypeDto.Alias, - DataTypeDefinitionId = propTypeDto.DataTypeId, - Description = propTypeDto.Description, - HelpText = propTypeDto.HelpText, - Id = propTypeDto.Id.Value, - Mandatory = propTypeDto.Mandatory, - Name = propTypeDto.Name, - SortOrder = propTypeDto.SortOrder, - ValidationRegExp = propTypeDto.ValidationRegExp, - PropertyGroupId = new Lazy(() => propTypeDto.PropertyTypeGroupId.Value), - CreateDate = dto.CreateDate, - UpdateDate = dto.CreateDate - }); + group.Id = groupDto.Id.Value; + + if (groupDto.ParentGroupId.HasValue) + group.ParentId = groupDto.ParentGroupId.Value; + } + else + { + //If the PropertyGroup is inherited, we add a reference to the group as a Parent. + group.ParentId = groupDto.Id; } - var group = new PropertyGroup(propertyTypeCollection) {Id = groupId}; - propertyTypeGroupCollection.Add(@group); + group.Name = groupDto.Text; + group.SortOrder = groupDto.SortOrder; + group.PropertyTypes = new PropertyTypeCollection(); + + //Because we are likely to have a group with no PropertyTypes we need to ensure that these are excluded + var typeDtos = dto.PropertyTypes.Where(x => x.Id.HasValue && x.Id > 0 && x.PropertyTypeGroupId.HasValue && x.PropertyTypeGroupId.Value == groupDto.Id.Value); + foreach (var typeDto in typeDtos) + { + //Internal dictionary for adding "MemberCanEdit" and "VisibleOnProfile" properties to each PropertyType + memberType.MemberTypePropertyTypes.Add(typeDto.Alias, + new Tuple(typeDto.CanEdit, typeDto.ViewOnProfile, typeDto.Id.Value)); + + var tempGroupDto = groupDto; + var propertyType = new PropertyType(typeDto.PropertyEditorAlias, + typeDto.DbType.EnumParse(true)) + { + Alias = typeDto.Alias, + DataTypeDefinitionId = typeDto.DataTypeId, + Description = typeDto.Description, + Id = typeDto.Id.Value, + Name = typeDto.Name, + HelpText = typeDto.HelpText, + Mandatory = typeDto.Mandatory, + SortOrder = typeDto.SortOrder, + ValidationRegExp = typeDto.ValidationRegExp, + PropertyGroupId = new Lazy(() => tempGroupDto.Id.Value), + CreateDate = memberType.CreateDate, + UpdateDate = memberType.UpdateDate + }; + //on initial construction we don't want to have dirty properties tracked + // http://issues.umbraco.org/issue/U4-1946 + propertyType.ResetDirtyProperties(false); + group.PropertyTypes.Add(propertyType); + } + //on initial construction we don't want to have dirty properties tracked + // http://issues.umbraco.org/issue/U4-1946 + group.ResetDirtyProperties(false); + propertyGroups.Add(group); } - return propertyTypeGroupCollection; + + return propertyGroups; } private List GetPropertyTypes(MemberTypeReadOnlyDto dto, MemberType memberType) { //Find PropertyTypes that does not belong to a PropertyTypeGroup var propertyTypes = new List(); - foreach (var propertyType in dto.PropertyTypes.Where(x => x.PropertyTypeGroupId.HasValue == false && x.Id.HasValue)) + foreach (var propertyType in dto.PropertyTypes.Where(x => (x.PropertyTypeGroupId.HasValue == false || x.PropertyTypeGroupId.Value == 0) && x.Id.HasValue)) { //Internal dictionary for adding "MemberCanEdit" and "VisibleOnProfile" properties to each PropertyType memberType.MemberTypePropertyTypes.Add(propertyType.Alias, diff --git a/src/Umbraco.Core/Persistence/Relators/PropertyDataRelator.cs b/src/Umbraco.Core/Persistence/Relators/PropertyDataRelator.cs index 3fd6e154c9..31fd430118 100644 --- a/src/Umbraco.Core/Persistence/Relators/PropertyDataRelator.cs +++ b/src/Umbraco.Core/Persistence/Relators/PropertyDataRelator.cs @@ -15,6 +15,8 @@ namespace Umbraco.Core.Persistence.Relators if (a == null) return Current; + p.VersionId = a.VersionId; + // Is this the same MemberReadOnlyDto as the current one we're processing if (Current != null && Current.UniqueId == a.UniqueId) { diff --git a/src/Umbraco.Core/Persistence/Relators/PropertyTypePropertyGroupRelator.cs b/src/Umbraco.Core/Persistence/Relators/PropertyTypePropertyGroupRelator.cs index e16a61db6f..a9129498c5 100644 --- a/src/Umbraco.Core/Persistence/Relators/PropertyTypePropertyGroupRelator.cs +++ b/src/Umbraco.Core/Persistence/Relators/PropertyTypePropertyGroupRelator.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Linq; using Umbraco.Core.Models.Rdbms; namespace Umbraco.Core.Persistence.Relators @@ -21,7 +22,7 @@ namespace Umbraco.Core.Persistence.Relators // Yes, just add this PropertyTypeReadOnlyDto to the current MemberTypeReadOnlyDto's collection Current.PropertyTypes.Add(p); - if(g.Id.HasValue) + if (g.Id.HasValue && Current.PropertyTypeGroups != null && Current.PropertyTypeGroups.Any(x => x.Id == g.Id.Value) == false) Current.PropertyTypeGroups.Add(g); // Return null to indicate we're not done with this MemberTypeReadOnlyDto yet diff --git a/src/Umbraco.Core/Persistence/Repositories/MemberRepository.cs b/src/Umbraco.Core/Persistence/Repositories/MemberRepository.cs index 6f060fc2e3..67273312dd 100644 --- a/src/Umbraco.Core/Persistence/Repositories/MemberRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/MemberRepository.cs @@ -229,10 +229,8 @@ namespace Umbraco.Core.Persistence.Repositories dto.NodeId = nodeDto.NodeId; Database.Insert(dto); - //TODO ContentType for the Member entity - //Create the PropertyData for this version - cmsPropertyData - /*var propertyFactory = new PropertyFactory(entity.ContentType, entity.Version, entity.Id); + var propertyFactory = new PropertyFactory(entity.ContentType, entity.Version, entity.Id); var propertyDataDtos = propertyFactory.BuildDto(((Member)entity).Properties); var keyDictionary = new Dictionary(); @@ -247,7 +245,7 @@ namespace Umbraco.Core.Persistence.Repositories foreach (var property in ((Member)entity).Properties) { property.Id = keyDictionary[property.PropertyTypeId]; - }*/ + } ((Member)entity).ResetDirtyProperties(); } @@ -300,7 +298,7 @@ namespace Umbraco.Core.Persistence.Repositories //TODO ContentType for the Member entity //Create the PropertyData for this version - cmsPropertyData - /*var propertyFactory = new PropertyFactory(entity.ContentType, entity.Version, entity.Id); + var propertyFactory = new PropertyFactory(entity.ContentType, entity.Version, entity.Id); var propertyDataDtos = propertyFactory.BuildDto(((Member)entity).Properties); var keyDictionary = new Dictionary(); @@ -325,7 +323,7 @@ namespace Umbraco.Core.Persistence.Repositories { property.Id = keyDictionary[property.PropertyTypeId]; } - }*/ + } ((ICanBeDirty)entity).ResetDirtyProperties(); } diff --git a/src/Umbraco.Core/Persistence/Repositories/MemberTypeRepository.cs b/src/Umbraco.Core/Persistence/Repositories/MemberTypeRepository.cs index 35b301da9b..778a47ea69 100644 --- a/src/Umbraco.Core/Persistence/Repositories/MemberTypeRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/MemberTypeRepository.cs @@ -101,7 +101,7 @@ namespace Umbraco.Core.Persistence.Repositories sql.Select("umbracoNode.*", "cmsContentType.*", "cmsPropertyType.id AS PropertyTypeId", "cmsPropertyType.Alias", "cmsPropertyType.Name", "cmsPropertyType.Description", "cmsPropertyType.helpText", "cmsPropertyType.mandatory", "cmsPropertyType.validationRegExp", "cmsPropertyType.dataTypeId", "cmsPropertyType.sortOrder AS PropertyTypeSortOrder", - "cmsPropertyType.propertyTypeGroupId", "cmsMemberType.memberCanEdit", "cmsMemberType.viewOnProfile", + "cmsPropertyType.propertyTypeGroupId AS PropertyTypesGroupId", "cmsMemberType.memberCanEdit", "cmsMemberType.viewOnProfile", "cmsDataType.propertyEditorAlias", "cmsDataType.dbType", "cmsPropertyTypeGroup.id AS PropertyTypeGroupId", "cmsPropertyTypeGroup.text AS PropertyGroupName", "cmsPropertyTypeGroup.parentGroupId", "cmsPropertyTypeGroup.sortorder AS PropertyGroupSortOrder") diff --git a/src/Umbraco.Core/Services/IMemberService.cs b/src/Umbraco.Core/Services/IMemberService.cs index a6a2a14424..737e142c3b 100644 --- a/src/Umbraco.Core/Services/IMemberService.cs +++ b/src/Umbraco.Core/Services/IMemberService.cs @@ -14,6 +14,8 @@ namespace Umbraco.Core.Services IEnumerable GetMembersByMemberType(string memberTypeAlias); IEnumerable GetMembersByGroup(string memberGroupName); IEnumerable GetAllMembers(params int[] ids); + + //TODO: Need to get all members that start with a certain letter } /// diff --git a/src/Umbraco.Tests/App.config b/src/Umbraco.Tests/App.config index 68af84d0d7..4aec13b940 100644 --- a/src/Umbraco.Tests/App.config +++ b/src/Umbraco.Tests/App.config @@ -66,7 +66,7 @@ - + diff --git a/src/Umbraco.Tests/Migrations/Upgrades/SqlCeDataUpgradeTest.cs b/src/Umbraco.Tests/Migrations/Upgrades/SqlCeDataUpgradeTest.cs index 9f8a3be793..f75a215763 100644 --- a/src/Umbraco.Tests/Migrations/Upgrades/SqlCeDataUpgradeTest.cs +++ b/src/Umbraco.Tests/Migrations/Upgrades/SqlCeDataUpgradeTest.cs @@ -57,7 +57,7 @@ namespace Umbraco.Tests.Migrations.Upgrades public override UmbracoDatabase GetConfiguredDatabase() { - return new UmbracoDatabase("Datasource=|DataDirectory|UmbracoPetaPocoTests.sdf;Flush Interval=1;File Access Retry Timeout=10", "System.Data.SqlServerCe.4.0"); + return new UmbracoDatabase("Datasource=|DataDirectory|UmbracoPetaPocoTests.sdf;Flush Interval=1;", "System.Data.SqlServerCe.4.0"); } public override DatabaseProviders GetDatabaseProvider() diff --git a/src/Umbraco.Tests/Migrations/Upgrades/SqlCeUpgradeTest.cs b/src/Umbraco.Tests/Migrations/Upgrades/SqlCeUpgradeTest.cs index 3dfc059358..238256499c 100644 --- a/src/Umbraco.Tests/Migrations/Upgrades/SqlCeUpgradeTest.cs +++ b/src/Umbraco.Tests/Migrations/Upgrades/SqlCeUpgradeTest.cs @@ -63,7 +63,7 @@ namespace Umbraco.Tests.Migrations.Upgrades public override UmbracoDatabase GetConfiguredDatabase() { - return new UmbracoDatabase("Datasource=|DataDirectory|UmbracoPetaPocoTests.sdf;Flush Interval=1;File Access Retry Timeout=10", "System.Data.SqlServerCe.4.0"); + return new UmbracoDatabase("Datasource=|DataDirectory|UmbracoPetaPocoTests.sdf;Flush Interval=1;", "System.Data.SqlServerCe.4.0"); } public override DatabaseProviders GetDatabaseProvider() diff --git a/src/Umbraco.Tests/Migrations/Upgrades/ValidateOlderSchemaTest.cs b/src/Umbraco.Tests/Migrations/Upgrades/ValidateOlderSchemaTest.cs index 011b14aed2..c427eec1b2 100644 --- a/src/Umbraco.Tests/Migrations/Upgrades/ValidateOlderSchemaTest.cs +++ b/src/Umbraco.Tests/Migrations/Upgrades/ValidateOlderSchemaTest.cs @@ -101,7 +101,7 @@ namespace Umbraco.Tests.Migrations.Upgrades public UmbracoDatabase GetConfiguredDatabase() { - return new UmbracoDatabase("Datasource=|DataDirectory|UmbracoPetaPocoTests.sdf;Flush Interval=1;File Access Retry Timeout=10", "System.Data.SqlServerCe.4.0"); + return new UmbracoDatabase("Datasource=|DataDirectory|UmbracoPetaPocoTests.sdf;Flush Interval=1;", "System.Data.SqlServerCe.4.0"); } public string GetDatabaseSpecificSqlScript() diff --git a/src/Umbraco.Tests/Persistence/DatabaseContextTests.cs b/src/Umbraco.Tests/Persistence/DatabaseContextTests.cs index 15104530b0..c942f4fa81 100644 --- a/src/Umbraco.Tests/Persistence/DatabaseContextTests.cs +++ b/src/Umbraco.Tests/Persistence/DatabaseContextTests.cs @@ -69,7 +69,7 @@ namespace Umbraco.Tests.Persistence //Get the connectionstring settings from config var settings = ConfigurationManager.ConnectionStrings[Core.Configuration.GlobalSettings.UmbracoConnectionName]; - //by default the conn string is: Datasource=|DataDirectory|UmbracoPetaPocoTests.sdf;Flush Interval=1;File Access Retry Timeout=10 + //by default the conn string is: Datasource=|DataDirectory|UmbracoPetaPocoTests.sdf;Flush Interval=1; //we'll just replace the sdf file with our custom one: //Create the Sql CE database var engine = new SqlCeEngine(settings.ConnectionString.Replace("UmbracoPetaPocoTests", "DatabaseContextTests")); diff --git a/src/Umbraco.Tests/Persistence/Repositories/MemberRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/MemberRepositoryTest.cs index fc39f1a416..a630bfaed6 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/MemberRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/MemberRepositoryTest.cs @@ -15,6 +15,7 @@ using Umbraco.Core.Persistence.UnitOfWork; using Umbraco.Core.Publishing; using Umbraco.Core.Services; using Umbraco.Tests.TestHelpers; +using Umbraco.Tests.TestHelpers.Entities; namespace Umbraco.Tests.Persistence.Repositories { @@ -174,6 +175,31 @@ namespace Umbraco.Tests.Persistence.Repositories } } + [Test] + public void MemberRepository_Can_Persist_Member() + { + IMember sut; + var unitOfWork = UnitOfWorkProvider.GetUnitOfWork(); + MemberTypeRepository memberTypeRepository; + using (var repository = CreateRepository(unitOfWork, out memberTypeRepository)) + { + var memberType = MockedContentTypes.CreateSimpleMemberType(); + memberTypeRepository.AddOrUpdate(memberType); + unitOfWork.Commit(); + + var member = MockedMember.CreateSimpleContent(memberType, "Johnny Hefty", "johnny@example.com", "123", "hefty", -1); + repository.AddOrUpdate(member); + unitOfWork.Commit(); + + sut = repository.Get(member.Id); + + Assert.That(sut, Is.Not.Null); + Assert.That(sut.ContentType.PropertyGroups.Count(), Is.EqualTo(1)); + Assert.That(sut.ContentType.PropertyTypes.Count(), Is.EqualTo(12)); + Assert.That(sut.Properties.Count(), Is.EqualTo(12)); + } + } + [Test] public void Can_Create_Correct_Subquery() { diff --git a/src/Umbraco.Tests/Persistence/Repositories/MemberTypeRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/MemberTypeRepositoryTest.cs index cc4553cce5..c9a88878d4 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/MemberTypeRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/MemberTypeRepositoryTest.cs @@ -29,7 +29,7 @@ namespace Umbraco.Tests.Persistence.Repositories public override string ConnectionString { - get { return @"server=.\SQLEXPRESS;database=Kloud-Website-Production;user id=umbraco;password=umbraco"; } + get { return @"server=.\SQLEXPRESS;database=EmptyForTest;user id=umbraco;password=umbraco"; } } public override string ProviderName diff --git a/src/Umbraco.Tests/Persistence/SqlCeTableByTableTest.cs b/src/Umbraco.Tests/Persistence/SqlCeTableByTableTest.cs index 7147dea975..54b427e2eb 100644 --- a/src/Umbraco.Tests/Persistence/SqlCeTableByTableTest.cs +++ b/src/Umbraco.Tests/Persistence/SqlCeTableByTableTest.cs @@ -35,12 +35,12 @@ namespace Umbraco.Tests.Persistence } //Create the Sql CE database - var engine = new SqlCeEngine("Datasource=|DataDirectory|test.sdf;Flush Interval=1;File Access Retry Timeout=10"); + var engine = new SqlCeEngine("Datasource=|DataDirectory|test.sdf;Flush Interval=1;"); engine.CreateDatabase(); SqlSyntaxContext.SqlSyntaxProvider = SqlCeSyntax.Provider; - _database = new Database("Datasource=|DataDirectory|test.sdf;Flush Interval=1;File Access Retry Timeout=10", + _database = new Database("Datasource=|DataDirectory|test.sdf;Flush Interval=1;", "System.Data.SqlServerCe.4.0"); } diff --git a/src/Umbraco.Tests/PluginManagerTests.cs b/src/Umbraco.Tests/PluginManagerTests.cs index 74f1d98cc8..df7ede9de5 100644 --- a/src/Umbraco.Tests/PluginManagerTests.cs +++ b/src/Umbraco.Tests/PluginManagerTests.cs @@ -296,7 +296,7 @@ namespace Umbraco.Tests public void Resolves_Trees() { var trees = PluginManager.Current.ResolveTrees(); - Assert.AreEqual(36, trees.Count()); + Assert.AreEqual(40, trees.Count()); } [Test] diff --git a/src/Umbraco.Tests/TestHelpers/BaseDatabaseFactoryTest.cs b/src/Umbraco.Tests/TestHelpers/BaseDatabaseFactoryTest.cs index 5ed1c7ec09..1a259e4424 100644 --- a/src/Umbraco.Tests/TestHelpers/BaseDatabaseFactoryTest.cs +++ b/src/Umbraco.Tests/TestHelpers/BaseDatabaseFactoryTest.cs @@ -111,7 +111,7 @@ namespace Umbraco.Tests.TestHelpers /// protected virtual string GetDbConnectionString() { - return @"Datasource=|DataDirectory|UmbracoPetaPocoTests.sdf;Flush Interval=1;File Access Retry Timeout=10"; + return @"Datasource=|DataDirectory|UmbracoPetaPocoTests.sdf;Flush Interval=1;"; } /// diff --git a/src/Umbraco.Tests/TestHelpers/Entities/MockedContentTypes.cs b/src/Umbraco.Tests/TestHelpers/Entities/MockedContentTypes.cs index 8d725b976a..430172916a 100644 --- a/src/Umbraco.Tests/TestHelpers/Entities/MockedContentTypes.cs +++ b/src/Umbraco.Tests/TestHelpers/Entities/MockedContentTypes.cs @@ -279,5 +279,32 @@ namespace Umbraco.Tests.TestHelpers.Entities return mediaType; } + + public static MemberType CreateSimpleMemberType() + { + var contentType = new MemberType(-1) + { + Alias = "simple", + Name = "Simple Page", + Description = "ContentType used for simple text pages", + Icon = ".sprTreeDoc3", + Thumbnail = "doc.png", + SortOrder = 1, + CreatorId = 0, + Trashed = false + }; + + var contentCollection = new PropertyTypeCollection(); + contentCollection.Add(new PropertyType(Constants.PropertyEditors.TextboxAlias, DataTypeDatabaseType.Ntext) { Alias = "title", Name = "Title", Description = "", Mandatory = false, SortOrder = 1, DataTypeDefinitionId = -88 }); + contentCollection.Add(new PropertyType(Constants.PropertyEditors.TextboxAlias, DataTypeDatabaseType.Ntext) { Alias = "bodyText", Name = "Body Text", Description = "", Mandatory = false, SortOrder = 2, DataTypeDefinitionId = -87 }); + contentCollection.Add(new PropertyType(Constants.PropertyEditors.TextboxAlias, DataTypeDatabaseType.Ntext) { Alias = "author", Name = "Author", Description = "Name of the author", Mandatory = false, SortOrder = 3, DataTypeDefinitionId = -88 }); + + contentType.PropertyGroups.Add(new PropertyGroup(contentCollection) { Name = "Content", SortOrder = 1 }); + + //ensure that nothing is marked as dirty + contentType.ResetDirtyProperties(false); + + return contentType; + } } } \ No newline at end of file diff --git a/src/Umbraco.Tests/TestHelpers/Entities/MockedMember.cs b/src/Umbraco.Tests/TestHelpers/Entities/MockedMember.cs new file mode 100644 index 0000000000..4aeb406811 --- /dev/null +++ b/src/Umbraco.Tests/TestHelpers/Entities/MockedMember.cs @@ -0,0 +1,26 @@ +using Umbraco.Core.Models; + +namespace Umbraco.Tests.TestHelpers.Entities +{ + public class MockedMember + { + public static Member CreateSimpleContent(IMemberType contentType, string name, string email, string password, string username, int parentId) + { + var member = new Member(name, parentId, contentType, new PropertyCollection()) + { + CreatorId = 0, + Email = email, + Password = password, + Username = username + }; + + member.SetValue("title", name + " member"); + member.SetValue("bodyText", "This is a subpage"); + member.SetValue("author", "John Doe"); + + member.ResetDirtyProperties(false); + + return member; + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Tests/UI/LegacyDialogTests.cs b/src/Umbraco.Tests/UI/LegacyDialogTests.cs index 1a5b01964f..11633b7f88 100644 --- a/src/Umbraco.Tests/UI/LegacyDialogTests.cs +++ b/src/Umbraco.Tests/UI/LegacyDialogTests.cs @@ -42,14 +42,12 @@ namespace Umbraco.Tests.UI [TestCase(typeof(memberTasks), DefaultApps.member)] [TestCase(typeof(MemberGroupTasks), DefaultApps.member)] [TestCase(typeof(MediaTypeTasks), DefaultApps.settings)] - [TestCase(typeof(mediaTasks), DefaultApps.media)] [TestCase(typeof(dictionaryTasks), DefaultApps.settings)] [TestCase(typeof(macroTasks), DefaultApps.developer)] [TestCase(typeof(languageTasks), DefaultApps.settings)] [TestCase(typeof(DLRScriptingTasks), DefaultApps.developer)] [TestCase(typeof(DataTypeTasks), DefaultApps.developer)] [TestCase(typeof(CreatedPackageTasks), DefaultApps.developer)] - [TestCase(typeof(contentTasks), DefaultApps.content)] [TestCase(typeof(PartialViewTasks), DefaultApps.settings)] public void Check_Assigned_Apps_For_Tasks(Type taskType, DefaultApps app) { diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj index dd84e8706c..a33551f070 100644 --- a/src/Umbraco.Tests/Umbraco.Tests.csproj +++ b/src/Umbraco.Tests/Umbraco.Tests.csproj @@ -368,6 +368,7 @@ + diff --git a/src/Umbraco.Web.UI.Client/src/common/resources/auth.resource.js b/src/Umbraco.Web.UI.Client/src/common/resources/auth.resource.js index 710ee58e52..604ba4b582 100644 --- a/src/Umbraco.Web.UI.Client/src/common/resources/auth.resource.js +++ b/src/Umbraco.Web.UI.Client/src/common/resources/auth.resource.js @@ -34,16 +34,28 @@ function authResource($q, $http, umbRequestHelper, angularHelper) { "PostLogout"))); }, - /** Sends a request to the server to check if the current cookie value is valid for the user */ - isAuthenticated: function () { + /** Sends a request to the server to get the current user details, will return a 401 if the user is not logged in */ + getCurrentUser: function () { return umbRequestHelper.resourcePromise( $http.get( umbRequestHelper.getApiUrl( "authenticationApiBaseUrl", "GetCurrentUser")), - 'Server call failed for checking authorization'); - } + 'Server call failed for getting current user'); + }, + + /** Checks if the user is logged in or not - does not return 401 or 403 */ + isAuthenticated: function () { + + return umbRequestHelper.resourcePromise( + $http.get( + umbRequestHelper.getApiUrl( + "authenticationApiBaseUrl", + "IsAuthenticated")), + 'Server call failed for checking authentication'); + }, + }; } diff --git a/src/Umbraco.Web.UI.Client/src/common/resources/member.resource.js b/src/Umbraco.Web.UI.Client/src/common/resources/member.resource.js index d879aa322c..bf726be952 100644 --- a/src/Umbraco.Web.UI.Client/src/common/resources/member.resource.js +++ b/src/Umbraco.Web.UI.Client/src/common/resources/member.resource.js @@ -26,7 +26,7 @@ function memberResource($q, $http, umbDataFormatter, umbRequestHelper) { /** * @ngdoc method - * @name umbraco.resources.memberResource#getByLogin + * @name umbraco.resources.memberResource#getByKey * @methodOf umbraco.resources.memberResource * * @description @@ -34,7 +34,7 @@ function memberResource($q, $http, umbDataFormatter, umbRequestHelper) { * * ##usage *
-         * memberResource.getByLogin("tom")
+         * memberResource.getByKey("0000-0000-000-00000-000")
          *    .then(function(member) {
          *        var mymember = member; 
          *        alert('its here!');
@@ -45,20 +45,20 @@ function memberResource($q, $http, umbDataFormatter, umbRequestHelper) {
          * @returns {Promise} resourcePromise object containing the member item.
          *
          */
-        getByLogin: function (loginName) {
+        getByKey: function (key) {
             
             return umbRequestHelper.resourcePromise(
                $http.get(
                    umbRequestHelper.getApiUrl(
                        "memberApiBaseUrl",
-                       "GetByLogin",
-                       [{ loginName: loginName }])),
-               'Failed to retreive data for member id ' + loginName);
+                       "GetByKey",
+                       [{ key: key }])),
+               'Failed to retreive data for member id ' + key);
         },
 
         /**
          * @ngdoc method
-         * @name umbraco.resources.memberResource#deleteByLogin
+         * @name umbraco.resources.memberResource#deleteByKey
          * @methodOf umbraco.resources.memberResource
          *
          * @description
@@ -66,7 +66,7 @@ function memberResource($q, $http, umbDataFormatter, umbRequestHelper) {
          *
          * ##usage
          * 
-         * memberResource.deleteByLogin(1234)
+         * memberResource.deleteByKey("0000-0000-000-00000-000")
          *    .then(function() {
          *        alert('its gone!');
          *    });
@@ -76,14 +76,14 @@ function memberResource($q, $http, umbDataFormatter, umbRequestHelper) {
          * @returns {Promise} resourcePromise object.
          *
          */
-        deleteByLogin: function (id) {
+        deleteByKey: function (key) {
             return umbRequestHelper.resourcePromise(
                 $http.delete(
                     umbRequestHelper.getApiUrl(
                         "memberApiBaseUrl",
-                        "DeleteById",
-                        [{ id: id }])),
-                'Failed to delete item ' + id);
+                        "DeleteByKey",
+                        [{ key: key }])),
+                'Failed to delete item ' + key);
         },
 
         /**
diff --git a/src/Umbraco.Web.UI.Client/src/common/services/user.service.js b/src/Umbraco.Web.UI.Client/src/common/services/user.service.js
index 626b11b98f..811ed55c18 100644
--- a/src/Umbraco.Web.UI.Client/src/common/services/user.service.js
+++ b/src/Umbraco.Web.UI.Client/src/common/services/user.service.js
@@ -53,30 +53,20 @@ angular.module('umbraco.services')
 
     return {
 
+        /** Internal method to display the login dialog */
+        _showLoginDialog: function () {
+            openLoginDialog();
+        },
+
         /** Returns a promise, sends a request to the server to check if the current cookie is authorized  */
-        isAuthenticated: function (args) {
-            
-            return authResource.isAuthenticated()
-                .then(function(data) {
-
-                    //note, this can return null if they are not authenticated
-                    if (!data) {                        
-                        throw "Not authenticated";
-                    }
-                    else {
-
-                        var result = { user: data, authenticated: true, lastUserId: lastUserId };
-
-                        if (args.broadcastEvent) {
-                            //broadcast a global event, will inform listening controllers to load in the user specific data
-                            $rootScope.$broadcast("authenticated", result);
-                        }
-
-                        currentUser = data;
-                        currentUser.avatar = 'http://www.gravatar.com/avatar/' + data.emailHash + '?s=40&d=404';
-                        return result;
-                    }
-                });
+        isAuthenticated: function () {
+            //if we've got a current user then just return true
+            if (currentUser) {
+                var deferred = $q.defer();
+                deferred.resolve(true);
+                return deferred.promise;
+            }
+            return authResource.isAuthenticated();
         },
 
         /** Returns a promise, sends a request to the server to validate the credentials  */
@@ -97,6 +87,7 @@ angular.module('umbraco.services')
                 });
         },
 
+        /** Logs the user out and redirects to the login page */
         logout: function () {
             return authResource.performLogout()
                 .then(function (data) {                   
@@ -107,14 +98,38 @@ angular.module('umbraco.services')
                     //broadcast a global event
                     $rootScope.$broadcast("notAuthenticated");
 
-                    openLoginDialog();
+                    $location.path("/login").search({check: false});
+
                     return null;
                 });
         },
 
-        /** Returns the current user object, if null then calls to authenticated or authenticate must be called  */
-        getCurrentUser: function () {
-            return currentUser;
+        /** Returns the current user object in a promise  */
+        getCurrentUser: function (args) {
+            var deferred = $q.defer();
+            
+            if (!currentUser) {
+                authResource.getCurrentUser()
+                    .then(function(data) {
+
+                        var result = { user: data, authenticated: true, lastUserId: lastUserId };
+
+                        if (args.broadcastEvent) {
+                            //broadcast a global event, will inform listening controllers to load in the user specific data
+                            $rootScope.$broadcast("authenticated", result);
+                        }
+
+                        currentUser = data;
+                        currentUser.avatar = 'http://www.gravatar.com/avatar/' + data.emailHash + '?s=40&d=404';
+                        deferred.resolve(currentUser);
+                    });
+
+            }
+            else {
+                deferred.resolve(currentUser);
+            }
+            
+            return deferred.promise;
         }
     };
 
diff --git a/src/Umbraco.Web.UI.Client/src/routes.js b/src/Umbraco.Web.UI.Client/src/routes.js
index b3bd6791cd..bbda26b835 100644
--- a/src/Umbraco.Web.UI.Client/src/routes.js
+++ b/src/Umbraco.Web.UI.Client/src/routes.js
@@ -1,15 +1,62 @@
 app.config(function ($routeProvider) {
+
+    /** This checks if the user is authenticated for a route and what the isRequired is set to. 
+        Depending on whether isRequired = true, it first check if the user is authenticated and will resolve successfully
+        otherwise the route will fail and the $routeChangeError event will execute, in that handler we will redirect to the rejected
+        path that is resolved from this method and prevent default (prevent the route from executing) */
+    var checkAuth = function(isRequired) {
+        return {
+            isAuthenticated: function ($q, userService, $route) {
+                var deferred = $q.defer();
+
+                //don't need to check if we've redirected to login and we've already checked auth
+                if (!$route.current.params.section && $route.current.params.check === false) {
+                    deferred.resolve(true);
+                    return deferred.promise;
+                }
+                
+                userService.isAuthenticated()
+                    .then(function () {
+                        if (isRequired) {
+                            //this will resolve successfully so the route will continue
+                            deferred.resolve(true);
+                        }
+                        else {
+                            deferred.reject({ path: "/" });
+                        }
+                    }, function () {
+                        if (isRequired) {                            
+                            //the check=false is checked above so that we don't have to make another http call to check
+                            //if they are logged in since we already know they are not.
+                            deferred.reject({ path: "/login", search: { check: false } });
+                        }
+                        else {
+                            //this will resolve successfully so the route will continue
+                            deferred.resolve(true);
+                        }
+                    });                
+                return deferred.promise;
+            }
+        };
+    };
+
     $routeProvider
+        .when('/login', {
+            templateUrl: 'views/common/login.html',
+            //ensure auth is *not* required so it will redirect to /content otherwise
+            resolve: checkAuth(false)
+        })
         .when('/:section', {
             templateUrl: function (rp) {
-                if (rp.section === "default" || rp.section === "")
+                if (rp.section.toLowerCase() === "default" || rp.section.toLowerCase() === "umbraco" || rp.section === "")
                 {
                     rp.section = "content";
                 }
 
                 rp.url = "dashboard.aspx?app=" + rp.section;
                 return 'views/common/dashboard.html';
-            }
+            },
+            resolve: checkAuth(true)
         })
         .when('/framed/:url', {
             //This occurs when we need to launch some content in an iframe
@@ -18,7 +65,8 @@ app.config(function ($routeProvider) {
                     throw "A framed resource must have a url route parameter";
 
                 return 'views/common/legacy.html';
-            }
+            },
+            resolve: checkAuth(true)
         })
         .when('/:section/:method', {
             templateUrl: function(rp) {
@@ -32,7 +80,8 @@ app.config(function ($routeProvider) {
                 // dashboards (as tabs if we wanted) and each tab could actually be a route link to one of these views?
 
                 return 'views/' + rp.section + '/' + rp.method + '.html';
-            }
+            },
+            resolve: checkAuth(true)
         })
         .when('/:section/:tree/:method/:id', {
             templateUrl: function (rp) {
@@ -43,9 +92,10 @@ app.config(function ($routeProvider) {
                 //we don't need to put views into section folders since theoretically trees
                 // could be moved among sections, we only need folders for specific trees.
                 return 'views/' + rp.tree + '/' + rp.method + '.html';
-            }
+            },
+            resolve: checkAuth(true)
         })        
-        .otherwise({ redirectTo: '/content' });
+        .otherwise({ redirectTo: '/login' });
     }).config(function ($locationProvider) {
 
         //$locationProvider.html5Mode(false).hashPrefix('!'); //turn html5 mode off
@@ -53,10 +103,28 @@ app.config(function ($routeProvider) {
 });
 
 
-app.run(['userService', '$log', '$rootScope', function (userService, $log, $rootScope) {
+app.run(['userService', '$log', '$rootScope', '$location', function (userService, $log, $rootScope, $location) {
 
-    // Get the current user when the application starts
-    // (in case they are still logged in from a previous session)
+    var firstRun = true;
+
+    /** when we have a successful first route that is not the login page - meaning the user is authenticated
+        we'll get the current user from the user service and ensure it broadcasts it's events. If the route
+        is successful from after a login then this will not actually do anything since the authenticated event would
+        have alraedy fired, but if the user is loading the angularjs app for the first time and they are already authenticated
+        then this is when the authenticated event will be fired.
+    */
+    $rootScope.$on('$routeChangeSuccess', function (event, current, previous) {
+        if (firstRun && !$location.url().toLowerCase().startsWith("/login")) {
+            firstRun = false;
+            userService.getCurrentUser({ broadcastEvent: true });
+        }
+    });
+
+    /** When the route change is rejected - based on checkAuth - we'll prevent the rejected route from executing including
+        wiring up it's controller, etc... and then redirect to the rejected URL.   */
+    $rootScope.$on('$routeChangeError', function (event, current, previous, rejection) {
+        event.preventDefault();
+        $location.path(rejection.path).search(rejection.search);
+    });
 
-    userService.isAuthenticated({broadcastEvent: true});
 }]);  
diff --git a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/user.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/user.controller.js
index e683c831d1..a7ecbada40 100644
--- a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/user.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/user.controller.js
@@ -5,9 +5,9 @@ angular.module("umbraco")
         $scope.history = historyService.current;
 
         $scope.logout = function () {
-	        userService.logout();
-	        $scope.hide();
-	        $location.path("/");
+            userService.logout().then(function() {
+                $scope.hide();                
+            });
     	};
 
 	    $scope.gotoHistory = function (link) {
diff --git a/src/Umbraco.Web.UI.Client/src/views/common/login.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/login.controller.js
new file mode 100644
index 0000000000..8b94debf39
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/views/common/login.controller.js
@@ -0,0 +1,11 @@
+/** This controller is simply here to launch the login dialog when the route is explicitly changed to /login */
+angular.module('umbraco').controller("Umbraco.LoginController", function ($scope, userService, $location) {
+
+    userService._showLoginDialog();
+    
+    //when a user is authorized redirect - this will only be handled here when we are actually on the /login route
+    $scope.$on("authenticated", function(evt, data) {
+        $location.path("/").search("");
+    });
+
+});
\ No newline at end of file
diff --git a/src/Umbraco.Web.UI.Client/src/views/common/login.html b/src/Umbraco.Web.UI.Client/src/views/common/login.html
new file mode 100644
index 0000000000..d490d395eb
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/views/common/login.html
@@ -0,0 +1,3 @@
+
+ +
\ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/views/common/main.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/main.controller.js index 502a379aa9..5a0347254d 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/main.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/main.controller.js @@ -8,7 +8,7 @@ * The main application controller * */ -function MainController($scope, $routeParams, $rootScope, $timeout, $http, $log, notificationsService, userService, navigationService, legacyJsLoader) { +function MainController($scope, $location, $routeParams, $rootScope, $timeout, $http, $log, notificationsService, userService, navigationService, legacyJsLoader) { var legacyTreeJsLoaded = false; @@ -78,6 +78,12 @@ function MainController($scope, $routeParams, $rootScope, $timeout, $http, $log, $scope.authenticated = data.authenticated; $scope.user = data.user; + //if the user has changed we need to redirect to the root so they don't try to continue editing the + //last item in the URL + if (data.lastUserId && data.lastUserId !== data.user.id) { + $location.path("/").search(""); + } + //var url = "http://www.gravatar.com/avatar/" + $scope.user.emailHash + ".json?404=404"; //$http.jsonp(url).then(function(response){ // $log.log("found: " + response); diff --git a/src/Umbraco.Web.UI.Client/src/views/member/member.delete.controller.js b/src/Umbraco.Web.UI.Client/src/views/member/member.delete.controller.js index 27d01f6a4a..dc86b21731 100644 --- a/src/Umbraco.Web.UI.Client/src/views/member/member.delete.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/member/member.delete.controller.js @@ -13,7 +13,7 @@ function MemberDeleteController($scope, memberResource, treeService, navigationS //mark it for deletion (used in the UI) $scope.currentNode.loading = true; - memberResource.deleteByLogin($scope.currentNode.id).then(function () { + memberResource.deleteByKey($scope.currentNode.id).then(function () { $scope.currentNode.loading = false; //TODO: Need to sync tree, etc... diff --git a/src/Umbraco.Web.UI.Client/src/views/member/member.edit.controller.js b/src/Umbraco.Web.UI.Client/src/views/member/member.edit.controller.js index 4ff85a6f95..493739842b 100644 --- a/src/Umbraco.Web.UI.Client/src/views/member/member.edit.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/member/member.edit.controller.js @@ -22,7 +22,7 @@ function MemberEditController($scope, $routeParams, $q, $timeout, $window, membe } else { //we are editing so get the content item from the server - memberResource.getByLogin($routeParams.id) + memberResource.getByKey($routeParams.id) .then(function(data) { $scope.loaded = true; $scope.content = data; diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/boolean/boolean.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/boolean/boolean.controller.js index db185da7d0..bafd28e90b 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/boolean/boolean.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/boolean/boolean.controller.js @@ -1,14 +1,26 @@ function booleanEditorController($scope, $rootScope, assetsService) { - $scope.renderModel = { - value: false - }; - if ($scope.model && $scope.model.value && ($scope.model.value.toString() === "1" || angular.lowercase($scope.model.value) === "true")) { - $scope.renderModel.value = true; + + function setupViewModel() { + $scope.renderModel = { + value: false + }; + if ($scope.model && $scope.model.value && ($scope.model.value.toString() === "1" || angular.lowercase($scope.model.value) === "true")) { + $scope.renderModel.value = true; + } } + setupViewModel(); + $scope.$watch("renderModel.value", function (newVal) { $scope.model.value = newVal === true ? "1" : "0"; }); + + //here we declare a special method which will be called whenever the value has changed from the server + //this is instead of doing a watch on the model.value = faster + $scope.model.onValueChanged = function (newVal, oldVal) { + //update the display val again if it has changed from the server + setupViewModel(); + }; } angular.module("umbraco").controller("Umbraco.Editors.BooleanController", booleanEditorController); \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/checkboxlist/checkboxlist.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/checkboxlist/checkboxlist.controller.js index eaeaef2860..d343fe903e 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/checkboxlist/checkboxlist.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/checkboxlist/checkboxlist.controller.js @@ -1,22 +1,27 @@ angular.module("umbraco").controller("Umbraco.Editors.CheckboxListController", function($scope) { - - $scope.selectedItems = []; - + if (!angular.isObject($scope.model.config.items)) { throw "The model.config.items property must be either a dictionary"; } - - //now we need to check if the value is null/undefined, if it is we need to set it to "" so that any value that is set - // to "" gets selected by default - if ($scope.model.value === null || $scope.model.value === undefined) { - $scope.model.value = []; + + function setupViewModel() { + $scope.selectedItems = []; + + //now we need to check if the value is null/undefined, if it is we need to set it to "" so that any value that is set + // to "" gets selected by default + if ($scope.model.value === null || $scope.model.value === undefined) { + $scope.model.value = []; + } + + for (var i in $scope.model.config.items) { + var isChecked = _.contains($scope.model.value, i); + $scope.selectedItems.push({ checked: isChecked, key: i, val: $scope.model.config.items[i] }); + } } - for (var i in $scope.model.config.items) { - var isChecked = _.contains($scope.model.value, i); - $scope.selectedItems.push({ checked: isChecked, key: i, val: $scope.model.config.items[i] }); - } + setupViewModel(); + //update the model when the items checked changes $scope.$watch("selectedItems", function(newVal, oldVal) { @@ -29,5 +34,12 @@ angular.module("umbraco").controller("Umbraco.Editors.CheckboxListController", } }, true); + + //here we declare a special method which will be called whenever the value has changed from the server + //this is instead of doing a watch on the model.value = faster + $scope.model.onValueChanged = function (newVal, oldVal) { + //update the display val again if it has changed from the server + setupViewModel(); + }; }); diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/googlemaps/googlemaps.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/googlemaps/googlemaps.controller.js index bbd76874b5..c7e85c2138 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/googlemaps/googlemaps.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/googlemaps/googlemaps.controller.js @@ -1,75 +1,84 @@ angular.module("umbraco") .controller("Umbraco.Editors.GoogleMapsController", function ($rootScope, $scope, notificationsService, dialogService, assetsService, $log, $timeout) { - - assetsService.loadJs('http://www.google.com/jsapi') - .then(function(){ - google.load("maps", "3", - { - callback: initMap, - other_params: "sensor=false" + + assetsService.loadJs('http://www.google.com/jsapi') + .then(function () { + google.load("maps", "3", + { + callback: initMap, + other_params: "sensor=false" + }); + }); + + function initMap() { + //Google maps is available and all components are ready to use. + var valueArray = $scope.model.value.split(','); + var latLng = new google.maps.LatLng(valueArray[0], valueArray[1]); + var mapDiv = document.getElementById($scope.model.alias + '_map'); + var mapOptions = { + zoom: $scope.model.config.zoom, + center: latLng, + mapTypeId: google.maps.MapTypeId[$scope.model.config.mapType] + }; + var geocoder = new google.maps.Geocoder(); + var map = new google.maps.Map(mapDiv, mapOptions); + + var marker = new google.maps.Marker({ + map: map, + position: latLng, + draggable: true + }); + + google.maps.event.addListener(map, 'click', function (event) { + + dialogService.mediaPicker({ + scope: $scope, callback: function (data) { + var image = data.selection[0].src; + + var latLng = event.latLng; + var marker = new google.maps.Marker({ + map: map, + icon: image, + position: latLng, + draggable: true }); - }); - function initMap(){ - //Google maps is available and all components are ready to use. - var valueArray = $scope.model.value.split(','); - var latLng = new google.maps.LatLng(valueArray[0], valueArray[1]); - var mapDiv = document.getElementById($scope.model.alias + '_map'); - var mapOptions = { - zoom: $scope.model.config.zoom, - center: latLng, - mapTypeId: google.maps.MapTypeId[$scope.model.config.mapType] - }; - var geocoder = new google.maps.Geocoder(); - var map = new google.maps.Map(mapDiv, mapOptions); + google.maps.event.addListener(marker, "dragend", function (e) { + var newLat = marker.getPosition().lat(); + var newLng = marker.getPosition().lng(); - var marker = new google.maps.Marker({ - map: map, - position: latLng, - draggable: true - }); + codeLatLng(marker.getPosition(), geocoder); - google.maps.event.addListener(map, 'click', function(event) { + //set the model value + $scope.model.vvalue = newLat + "," + newLng; + }); - dialogService.mediaPicker({scope: $scope, callback: function(data){ - var image = data.selection[0].src; - - var latLng = event.latLng; - var marker = new google.maps.Marker({ - map: map, - icon: image, - position: latLng, - draggable: true + } }); + }); - google.maps.event.addListener(marker, "dragend", function(e){ - var newLat = marker.getPosition().lat(); - var newLng = marker.getPosition().lng(); + $('a[data-toggle="tab"]').on('shown', function (e) { + google.maps.event.trigger(map, 'resize'); + }); + } - codeLatLng(marker.getPosition(), geocoder); - - //set the model value - $scope.model.vvalue = newLat + "," + newLng; - }); - - }}); - }); - - $('a[data-toggle="tab"]').on('shown', function (e) { - google.maps.event.trigger(map, 'resize'); - }); - } - - function codeLatLng(latLng, geocoder) { - geocoder.geocode({'latLng': latLng}, - function(results, status) { - if (status == google.maps.GeocoderStatus.OK) { - var location = results[0].formatted_address; + function codeLatLng(latLng, geocoder) { + geocoder.geocode({ 'latLng': latLng }, + function (results, status) { + if (status == google.maps.GeocoderStatus.OK) { + var location = results[0].formatted_address; $rootScope.$apply(function () { notificationsService.success("Peter just went to: ", location); }); - } - }); - } -}); \ No newline at end of file + } + }); + } + + //here we declare a special method which will be called whenever the value has changed from the server + //this is instead of doing a watch on the model.value = faster + $scope.model.onValueChanged = function (newVal, oldVal) { + //update the display val again if it has changed from the server + initMap(); + }; + }); \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker/mediapicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker/mediapicker.controller.js index c028217f71..59a8193866 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker/mediapicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker/mediapicker.controller.js @@ -1,54 +1,68 @@ //this controller simply tells the dialogs service to open a mediaPicker window //with a specified callback, this callback will receive an object with a selection on it -angular.module('umbraco').controller("Umbraco.Editors.MediaPickerController", - function($rootScope, $scope, dialogService, mediaResource, imageHelper, $log){ - - - $scope.images = []; - $scope.ids = []; +angular.module('umbraco').controller("Umbraco.Editors.MediaPickerController", + function($rootScope, $scope, dialogService, mediaResource, imageHelper, $log) { - if($scope.model.value){ - $scope.ids = $scope.model.value.split(','); - mediaResource.getByIds($scope.ids).then(function(medias){ - //img.media = media; - $(medias).each(function(i, media){ - //shortcuts - //TODO, do something better then this for searching - var img = {}; - img.src = imageHelper.getImagePropertyValue({imageModel: media}); - img.thumbnail = imageHelper.getThumbnailFromPath(img.src); - $scope.images.push(img); - }); - }); - } + function setupViewModel() { + $scope.images = []; + $scope.ids = []; - $scope.remove = function(index){ - $scope.images.splice(index, 1); - $scope.ids.splice(index, 1); - $scope.sync(); - }; + if ($scope.model.value) { + $scope.ids = $scope.model.value.split(','); - $scope.add = function(){ - dialogService.mediaPicker({multipicker:true, callback: function(data){ - $(data.selection).each(function(i, media){ - //shortcuts - //TODO, do something better then this for searching + mediaResource.getByIds($scope.ids).then(function (medias) { + //img.media = media; + _.each(medias, function (media, i) { + //shortcuts + //TODO, do something better then this for searching + var img = {}; + img.src = imageHelper.getImagePropertyValue({ imageModel: media }); + img.thumbnail = imageHelper.getThumbnailFromPath(img.src); + $scope.images.push(img); + }); + }); + } + } - var img = {}; - img.id = media.id; - img.src = imageHelper.getImagePropertyValue({imageModel: media}); - img.thumbnail = imageHelper.getThumbnailFromPath(img.src); - $scope.images.push(img); - $scope.ids.push(img.id); - }); + setupViewModel(); - $scope.sync(); - }}); - }; + $scope.remove = function(index) { + $scope.images.splice(index, 1); + $scope.ids.splice(index, 1); + $scope.sync(); + }; - $scope.sync = function(){ - $scope.model.value = $scope.ids.join(); - }; + $scope.add = function() { + dialogService.mediaPicker({ + multipicker: true, + callback: function(data) { + _.each(data.selection, function(media, i) { + //shortcuts + //TODO, do something better then this for searching -}); \ No newline at end of file + var img = {}; + img.id = media.id; + img.src = imageHelper.getImagePropertyValue({ imageModel: media }); + img.thumbnail = imageHelper.getThumbnailFromPath(img.src); + $scope.images.push(img); + $scope.ids.push(img.id); + }); + + $scope.sync(); + } + }); + }; + + $scope.sync = function() { + $scope.model.value = $scope.ids.join(); + }; + + //here we declare a special method which will be called whenever the value has changed from the server + //this is instead of doing a watch on the model.value = faster + $scope.model.onValueChanged = function (newVal, oldVal) { + //update the display val again if it has changed from the server + setupViewModel(); + }; + + }); \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js index 1cf64e286f..c87be39b71 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js @@ -32,65 +32,79 @@ angular.module("umbraco") var plugins = "code"; assetsService.loadJs("lib/tinymce/tinymce.min.js", $scope).then(function () { - //we need to add a timeout here, to force a redraw so TinyMCE can find - //the elements needed - $timeout(function () { - tinymce.DOM.events.domLoaded = true; - tinymce.init({ - mode: "exact", - elements: $scope.model.alias + "_rte", - skin: "umbraco", - plugins: plugins, - valid_elements: validElements, - menubar: false, - statusbar: false, - height: 340, - toolbar: toolbar, - setup: function (editor) { - - //We need to listen on multiple things here because of the nature of tinymce, it doesn't - //fire events when you think! - //The change event doesn't fire when content changes, only when cursor points are changed and undo points - //are created. the blur event doesn't fire if you insert content into the editor with a button and then - //press save. - //We have a couple of options, one is to do a set timeout and check for isDirty on the editor, or we can - //listen to both change and blur and also on our own 'saving' event. I think this will be best because a - //timer might end up using unwanted cpu and we'd still have to listen to our saving event in case they clicked - //save before the timeout elapsed. - editor.on('change', function (e) { - angularHelper.safeApply($scope, function() { - $scope.model.value = editor.getContent(); - }); - }); - editor.on('blur', function (e) { - angularHelper.safeApply($scope, function () { + + /** Loads in the editor */ + function loadTinyMce() { + + //we need to add a timeout here, to force a redraw so TinyMCE can find + //the elements needed + $timeout(function () { + tinymce.DOM.events.domLoaded = true; + tinymce.init({ + mode: "exact", + elements: $scope.model.alias + "_rte", + skin: "umbraco", + plugins: plugins, + valid_elements: validElements, + menubar: false, + statusbar: false, + height: 340, + toolbar: toolbar, + setup: function (editor) { + + //We need to listen on multiple things here because of the nature of tinymce, it doesn't + //fire events when you think! + //The change event doesn't fire when content changes, only when cursor points are changed and undo points + //are created. the blur event doesn't fire if you insert content into the editor with a button and then + //press save. + //We have a couple of options, one is to do a set timeout and check for isDirty on the editor, or we can + //listen to both change and blur and also on our own 'saving' event. I think this will be best because a + //timer might end up using unwanted cpu and we'd still have to listen to our saving event in case they clicked + //save before the timeout elapsed. + editor.on('change', function (e) { + angularHelper.safeApply($scope, function () { + $scope.model.value = editor.getContent(); + }); + }); + editor.on('blur', function (e) { + angularHelper.safeApply($scope, function () { + $scope.model.value = editor.getContent(); + }); + }); + var unsubscribe = $scope.$on("saving", function () { $scope.model.value = editor.getContent(); }); - }); - var unsubscribe = $scope.$on("saving", function() { - $scope.model.value = editor.getContent(); - }); - //when the element is disposed we need to unsubscribe! - // NOTE: this is very important otherwise if this is part of a modal, the listener still exists because the dom - // element might still be there even after the modal has been hidden. - $element.bind('$destroy', function () { - unsubscribe(); - }); + //when the element is disposed we need to unsubscribe! + // NOTE: this is very important otherwise if this is part of a modal, the listener still exists because the dom + // element might still be there even after the modal has been hidden. + $element.bind('$destroy', function () { + unsubscribe(); + }); - //Create the insert media plugin - tinyMceService.createMediaPicker(editor, $scope); + //Create the insert media plugin + tinyMceService.createMediaPicker(editor, $scope); - //Create the insert icon plugin - tinyMceService.createInsertEmbeddedMedia(editor, $scope); + //Create the insert icon plugin + tinyMceService.createInsertEmbeddedMedia(editor, $scope); - //Create the insert macro plugin - tinyMceService.createInsertMacro(editor, $scope); + //Create the insert macro plugin + tinyMceService.createInsertMacro(editor, $scope); - } - }); - }, 1); + } + }); + }, 1); + } + + loadTinyMce(); + + //here we declare a special method which will be called whenever the value has changed from the server + //this is instead of doing a watch on the model.value = faster + $scope.model.onValueChanged = function (newVal, oldVal) { + //update the display val again if it has changed from the server + loadTinyMce(); + }; }); }); \ No newline at end of file diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index 46951cb098..fa90a61110 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -46,6 +46,7 @@ ..\ true + true bin\ @@ -421,13 +422,6 @@ ImageViewer.ascx - - create.aspx - ASPXCodeBehind - - - create.aspx - PartialView.ascx ASPXCodeBehind @@ -587,13 +581,6 @@ treeInit.aspx - - umbraco.aspx - ASPXCodeBehind - - - umbraco.aspx - @@ -694,7 +681,6 @@ - @@ -2047,7 +2033,6 @@ UserControl - Designer @@ -2181,7 +2166,6 @@ - @@ -2190,8 +2174,6 @@ - - @@ -2396,8 +2378,6 @@ - - Form @@ -2421,7 +2401,6 @@ - diff --git a/src/Umbraco.Web.UI/umbraco/Create.aspx.cs b/src/Umbraco.Web.UI/umbraco/Create.aspx.cs deleted file mode 100644 index 304e7ffdb1..0000000000 --- a/src/Umbraco.Web.UI/umbraco/Create.aspx.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Web; -using System.Xml; -using Umbraco.Core; -using Umbraco.Core.IO; -using umbraco.cms.presentation.Trees; - -namespace Umbraco.Web.UI.Umbraco -{ - public partial class CreateDialog : global::umbraco.cms.presentation.Create - { - - protected override void OnLoad(EventArgs e) - { - if (SecurityCheck(Request.QueryString["nodeType"])) - { - //if we're allowed, then continue - base.OnLoad(e); - } - else - { - //otherwise show an error - UI.Visible = false; - AccessError.Visible = true; - } - } - - private bool SecurityCheck(string nodeTypeAlias) - { - return LegacyDialogHandler.UserHasCreateAccess( - new HttpContextWrapper(Context), - getUser(), - nodeTypeAlias); - } - - } -} \ No newline at end of file diff --git a/src/Umbraco.Web.UI/umbraco/Create.aspx.designer.cs b/src/Umbraco.Web.UI/umbraco/Create.aspx.designer.cs deleted file mode 100644 index 1e11eaf00d..0000000000 --- a/src/Umbraco.Web.UI/umbraco/Create.aspx.designer.cs +++ /dev/null @@ -1,25 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace Umbraco.Web.UI.Umbraco { - - - public partial class CreateDialog - { - - /// - /// AccessError control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.PlaceHolder AccessError; - } -} diff --git a/src/Umbraco.Web.UI/umbraco/Umbraco.aspx.cs b/src/Umbraco.Web.UI/umbraco/Umbraco.aspx.cs deleted file mode 100644 index 02b0feee92..0000000000 --- a/src/Umbraco.Web.UI/umbraco/Umbraco.aspx.cs +++ /dev/null @@ -1,185 +0,0 @@ -using System; -using System.IO; -using System.Linq; -using System.Text; -using System.Text.RegularExpressions; -using System.Web; -using System.Web.UI; -using Umbraco.Core.IO; -using umbraco; -using Umbraco.Core; - -namespace Umbraco.Web.UI.Umbraco -{ - public partial class Umbraco : Pages.UmbracoEnsuredPage - { - public string DefaultApp { get; private set; } - - protected void Page_Load(object sender, System.EventArgs e) - { - var apps = UmbracoUser.Applications.ToList(); - bool userHasAccesstodefaultApp = apps.Any(x => x.alias == Constants.Applications.Content); - - // Load user module icons .. - if (apps.Count() > 1) - { - - var jsEvents = new StringBuilder(); - - PlaceHolderAppIcons.Text = ui.Text("main", "sections", UmbracoUser); - plcIcons.Text = ""; - foreach (global::umbraco.BusinessLogic.Application a in apps.OrderBy(x => x.sortOrder)) - { - - string appClass = a.icon.StartsWith(".") ? a.icon.Substring(1, a.icon.Length - 1) : a.alias; - - //adds client side event handlers to the icon buttons - jsEvents.Append(@"jQuery('." + appClass + "').click(function() { appClick.call(this, '" + a.alias + "'); } );"); - jsEvents.Append(@"jQuery('." + appClass + "').dblclick(function() { appDblClick.call(this, '" + a.alias + "'); } );"); - - string iconElement = String.Format("
  • ", appClass); - if (a.icon.StartsWith(".")) - iconElement += - "\"\"
  • "; - else - iconElement += "\"""; - plcIcons.Text += iconElement; - - } - - //registers the jquery event handlers. - Page.ClientScript.RegisterStartupScript(this.GetType(), "AppIcons", "jQuery(document).ready(function() { " + jsEvents.ToString() + " } );", true); - - } - else - PlaceHolderAppIcons.Visible = false; - - - //if user does not have access to content (ie, he's probably a translator)... - //then change the default tree app - if (!userHasAccesstodefaultApp) - { - JTree.App = apps[0].alias; - DefaultApp = apps[0].alias; - } - else - { - DefaultApp = Constants.Applications.Content; - } - - - // Load globalized labels - treeWindow.Text = ui.Text("main", "tree", UmbracoUser); - - RenderActionJs(); - - // Version check goes here! - - // zb-00004 #29956 : refactor cookies names & handling - var updChkCookie = new global::umbraco.BusinessLogic.StateHelper.Cookies.Cookie("UMB_UPDCHK", GlobalSettings.VersionCheckPeriod); // was "updateCheck" - string updateCheckCookie = updChkCookie.HasValue ? updChkCookie.GetValue() : ""; - - if (GlobalSettings.VersionCheckPeriod > 0 && String.IsNullOrEmpty(updateCheckCookie) && UmbracoUser.UserType.Alias == "admin") - { - - // Add scriptmanager version check - ScriptManager sm = ScriptManager.GetCurrent(Page); - sm.Scripts.Add(new ScriptReference(SystemDirectories.Umbraco + "/js/umbracoUpgradeChecker.js")); - sm.Services.Add(new ServiceReference(SystemDirectories.WebServices + "/CheckForUpgrade.asmx")); - - Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "upgradeChecker", "jQuery(document).ready(function() {umbraco.presentation.webservices.CheckForUpgrade.CallUpgradeService(umbracoCheckUpgrade);});", true); - - updChkCookie.SetValue("1"); - } - DataBind(); - - AddIe9Meta(); - } - - private void AddIe9Meta() - { - if (Request.Browser.Browser == "IE" && Request.Browser.MajorVersion == 9) - { - var metadata = new StringBuilder(); - metadata.AppendFormat( - @" - - - - - ", - IOHelper.ResolveUrl(SystemDirectories.Umbraco + "/Images/PinnedIcons/umb.ico"), - HttpContext.Current.Request.Url.Host.ToLower().Replace("www.", "")); - - var user = UmbracoUser; - if (user != null && user.Applications != null && user.Applications.Length > 0) - { - foreach (var app in user.Applications) - { - metadata.AppendFormat( - @"", - ui.Text("sections", app.alias, user), - IOHelper.ResolveUrl(string.Format("{0}/umbraco.aspx#{1}", SystemDirectories.Umbraco, app.alias)), - File.Exists( - IOHelper.MapPath( - IOHelper.ResolveUrl( - string.Format("{0}/Images/PinnedIcons/task_{1}.ico", SystemDirectories.Umbraco, app.alias)))) - ? "/umbraco/Images/PinnedIcons/task_" + app.alias + ".ico" - : "/umbraco/Images/PinnedIcons/task_default.ico"); - } - } - - this.Header.Controls.Add(new LiteralControl(metadata.ToString())); - } - } - - /// - /// Renders out all JavaScript references that have bee declared in IActions - /// - private void RenderActionJs() - { - var item = 0; - foreach (var jsFile in global::umbraco.BusinessLogic.Actions.Action.GetJavaScriptFileReferences()) - { - //validate that this is a url, if it is not, we'll assume that it is a text block and render it as a text - //block instead. - var isValid = true; - try - { - var jsUrl = new Uri(jsFile, UriKind.RelativeOrAbsolute); - //ok it validates, but so does alert('hello'); ! so we need to do more checks - - //here are the valid chars in a url without escaping - if (Regex.IsMatch(jsFile, @"[^a-zA-Z0-9-._~:/?#\[\]@!$&'\(\)*\+,%;=]")) - isValid = false; - - //we'll have to be smarter and just check for certain js patterns now too! - var jsPatterns = new string[] { @"\+\s*\=", @"\);", @"function\s*\(", @"!=", @"==" }; - if (jsPatterns.Any(p => Regex.IsMatch(jsFile, p))) - { - isValid = false; - } - - if (isValid) - { - //add to page - Page.ClientScript.RegisterClientScriptInclude(this.GetType(), item.ToString(), jsFile); - } - } - catch (UriFormatException) - { - isValid = false; - } - - if (!isValid) - { - //it is invalid, let's render it as a script block instead as devs may have written real Javascript instead - //of a JS path - Page.ClientScript.RegisterClientScriptBlock(this.GetType(), item.ToString(), jsFile, true); - } - - item++; - } - } - } -} \ No newline at end of file diff --git a/src/Umbraco.Web.UI/umbraco/Umbraco.aspx.designer.cs b/src/Umbraco.Web.UI/umbraco/Umbraco.aspx.designer.cs deleted file mode 100644 index f7e448af08..0000000000 --- a/src/Umbraco.Web.UI/umbraco/Umbraco.aspx.designer.cs +++ /dev/null @@ -1,286 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace Umbraco.Web.UI.Umbraco { - - - public partial class Umbraco - { - - /// - /// ClientLoader control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::umbraco.uicontrols.UmbracoClientDependencyLoader ClientLoader; - - /// - /// CssInclude1 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.CssInclude CssInclude1; - - /// - /// CssInclude2 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.CssInclude CssInclude2; - - /// - /// JsInclude1 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude1; - - /// - /// JSON2 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JSON2; - - /// - /// JsInclude2 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude2; - - /// - /// JsInclude3 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude3; - - /// - /// JsInclude14 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude14; - - /// - /// JsInclude5 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude5; - - /// - /// JsInclude6 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude6; - - /// - /// JsInclude13 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude13; - - /// - /// JsInclude7 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude7; - - /// - /// JsInclude8 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude8; - - /// - /// JsInclude9 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude9; - - /// - /// JsInclude10 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude10; - - /// - /// JsInclude11 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude11; - - /// - /// JsInclude4 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude4; - - /// - /// JsInclude17 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude17; - - /// - /// JsInclude12 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude12; - - /// - /// JsInclude15 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude15; - - /// - /// JsInclude16 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude16; - - /// - /// Form1 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.HtmlControls.HtmlForm Form1; - - /// - /// umbracoScriptManager control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.ScriptManager umbracoScriptManager; - - /// - /// FindDocuments control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.Panel FindDocuments; - - /// - /// Search control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::Umbraco.Web.UI.Umbraco.Search.QuickSearch Search; - - /// - /// treeWindow control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::umbraco.uicontrols.UmbracoPanel treeWindow; - - /// - /// JTree control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::umbraco.controls.Tree.TreeControl JTree; - - /// - /// PlaceHolderAppIcons control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::umbraco.uicontrols.UmbracoPanel PlaceHolderAppIcons; - - /// - /// plcIcons control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.Literal plcIcons; - - /// - /// bubbleText control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.PlaceHolder bubbleText; - } -} diff --git a/src/Umbraco.Web.UI/umbraco/cacheBrowser.aspx b/src/Umbraco.Web.UI/umbraco/cacheBrowser.aspx deleted file mode 100644 index 7aa26dda00..0000000000 --- a/src/Umbraco.Web.UI/umbraco/cacheBrowser.aspx +++ /dev/null @@ -1,16 +0,0 @@ -<%@ Page language="c#" Codebehind="cacheBrowser.aspx.cs" AutoEventWireup="True" Inherits="umbraco.cms.presentation.cacheBrowser" trace="true" %> - - - - cacheBrowser - - - - - - -
    - -
    - - diff --git a/src/Umbraco.Web.UI/umbraco/config/create/UI.Release.xml b/src/Umbraco.Web.UI/umbraco/config/create/UI.Release.xml index 569defa824..3d7bca0afd 100644 --- a/src/Umbraco.Web.UI/umbraco/config/create/UI.Release.xml +++ b/src/Umbraco.Web.UI/umbraco/config/create/UI.Release.xml @@ -59,14 +59,6 @@ - -
    Page
    - /create/content.ascx - - - - -
    User
    /create/simple.ascx @@ -138,15 +130,7 @@ -
    - -
    Media
    - /create/media.ascx - - - - -
    +
    member
    /create/member.ascx diff --git a/src/Umbraco.Web.UI/umbraco/config/create/UI.xml b/src/Umbraco.Web.UI/umbraco/config/create/UI.xml index 86dceaf5c0..15a3f1d3e2 100644 --- a/src/Umbraco.Web.UI/umbraco/config/create/UI.xml +++ b/src/Umbraco.Web.UI/umbraco/config/create/UI.xml @@ -59,14 +59,6 @@
    - -
    Page
    - /create/content.ascx - - - - -
    User
    /create/simple.ascx @@ -138,15 +130,7 @@ -
    - -
    Media
    - /create/media.ascx - - - - -
    +
    member
    /create/member.ascx diff --git a/src/Umbraco.Web.UI/umbraco/create.aspx b/src/Umbraco.Web.UI/umbraco/create.aspx deleted file mode 100644 index 782b7f178d..0000000000 --- a/src/Umbraco.Web.UI/umbraco/create.aspx +++ /dev/null @@ -1,43 +0,0 @@ -<%@ Page Language="c#" MasterPageFile="masterpages/umbracoDialog.Master" Codebehind="CreateDialog.aspx.cs" AutoEventWireup="True" Inherits="Umbraco.Web.UI.Umbraco.CreateDialog" %> -<%@ Register Namespace="umbraco" TagPrefix="umb" Assembly="umbraco" %> - - - - - - - - - -
    -

    - The current user does not have access to create this type of object -

    -
    -
    -
    - - - - \ No newline at end of file diff --git a/src/Umbraco.Web.UI/umbraco/dashboard.aspx b/src/Umbraco.Web.UI/umbraco/dashboard.aspx deleted file mode 100644 index 91a4de4c0d..0000000000 --- a/src/Umbraco.Web.UI/umbraco/dashboard.aspx +++ /dev/null @@ -1,11 +0,0 @@ -<%@ Page language="c#" MasterPageFile="masterpages/umbracoPage.Master" Title="dashboard" Codebehind="dashboard.aspx.cs" AutoEventWireup="True" Inherits="umbraco.cms.presentation.dashboard" trace="false" validateRequest="false"%> -<%@ Register TagPrefix="cc1" Namespace="umbraco.uicontrols" Assembly="controls" %> - - - -
    - -
    -
    - -
    \ No newline at end of file diff --git a/src/Umbraco.Web.UI/umbraco/editContent.aspx b/src/Umbraco.Web.UI/umbraco/editContent.aspx deleted file mode 100644 index 8c7ec1317f..0000000000 --- a/src/Umbraco.Web.UI/umbraco/editContent.aspx +++ /dev/null @@ -1,62 +0,0 @@ -<%@ Page Title="Edit content" Language="c#" MasterPageFile="masterpages/umbracoPage.Master" - CodeBehind="editContent.aspx.cs" ValidateRequest="false" AutoEventWireup="True" - Inherits="umbraco.cms.presentation.editContent" Trace="false" %> - -<%@ Register TagPrefix="cc1" Namespace="umbraco.uicontrols" Assembly="controls" %> -<%@ Register TagPrefix="umb" Namespace="ClientDependency.Core.Controls" Assembly="ClientDependency.Core" %> - - - - - - - - - - - -
    - - -
    - - - -
    diff --git a/src/Umbraco.Web.UI/umbraco/editMedia.aspx b/src/Umbraco.Web.UI/umbraco/editMedia.aspx deleted file mode 100644 index 50368f0cd7..0000000000 --- a/src/Umbraco.Web.UI/umbraco/editMedia.aspx +++ /dev/null @@ -1,28 +0,0 @@ -<%@ Page Language="c#" CodeBehind="editMedia.aspx.cs" ValidateRequest="false" MasterPageFile="masterpages/umbracoPage.Master" - AutoEventWireup="True" Inherits="umbraco.cms.presentation.editMedia" %> - - - - - - - - - diff --git a/src/Umbraco.Web.UI/umbraco/login.aspx b/src/Umbraco.Web.UI/umbraco/login.aspx deleted file mode 100644 index 5d299e9e0c..0000000000 --- a/src/Umbraco.Web.UI/umbraco/login.aspx +++ /dev/null @@ -1,129 +0,0 @@ -<%@ Page Language="c#" CodeBehind="login.aspx.cs" AutoEventWireup="True" Inherits="umbraco.cms.presentation.login" %> - -<%@ Register TagPrefix="cc1" Namespace="umbraco.uicontrols" Assembly="controls" %> -<%@ Register Namespace="umbraco" TagPrefix="umb" Assembly="umbraco" %> -<%@ Register TagPrefix="umb" Namespace="ClientDependency.Core.Controls" Assembly="ClientDependency.Core" %> - - - - Login - Umbraco - <%=Request.Url.Host.ToLower().Replace("www.", "") %> - - - - - - - - -
    - -
    -

    - -

    - - - - - - - - - - - - - - - - - - -
    - - - -
    -
    - - - -
    -
    - -
    -
    -
    - - - - - - - - - - - - - diff --git a/src/Umbraco.Web.UI/umbraco/logout.aspx b/src/Umbraco.Web.UI/umbraco/logout.aspx deleted file mode 100644 index 41289b10d2..0000000000 --- a/src/Umbraco.Web.UI/umbraco/logout.aspx +++ /dev/null @@ -1,18 +0,0 @@ -<%@ Page language="c#" Codebehind="logout.aspx.cs" AutoEventWireup="True" Inherits="umbraco.logout" %> - - - - - logout - - - - - - - -
    -
    - - - diff --git a/src/Umbraco.Web.UI/umbraco/umbraco.aspx b/src/Umbraco.Web.UI/umbraco/umbraco.aspx deleted file mode 100644 index 0bcb810d20..0000000000 --- a/src/Umbraco.Web.UI/umbraco/umbraco.aspx +++ /dev/null @@ -1,399 +0,0 @@ -<%@ Page Trace="false" Language="c#" CodeBehind="umbraco.aspx.cs" AutoEventWireup="True" - Inherits="Umbraco.Web.UI.Umbraco.Umbraco" %> - -<%@ Import Namespace="System.Web.Script.Serialization" %> - -<%@ Register Src="controls/Tree/TreeControl.ascx" TagName="TreeControl" TagPrefix="umbraco" %> -<%@ Import Namespace="StackExchange.Profiling" %> -<%@ Import Namespace="Umbraco.Core.Profiling" %> -<%@ Import Namespace="Umbraco.Web" %> -<%@ Register TagPrefix="cc1" Namespace="umbraco.uicontrols" Assembly="controls" %> -<%@ Register TagPrefix="uc1" TagName="quickSearch" Src="Search/QuickSearch.ascx" %> -<%@ Register TagPrefix="umb" Namespace="ClientDependency.Core.Controls" Assembly="ClientDependency.Core" %> - - - - Umbraco CMS - - <%=Request.Url.Host.ToLower().Replace("www.", "") %> - - " /> - - - - - - - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - -
    -
    - -
    -
    - -
    - -
    - -
    -
    -
    - - - -
    -
    -
    - -   -
    -
    - - - - -
      - -
    -
    -
    -
    - - -
    -
    - -
    -
    -
    -
    -
    - × -
    - -
    -
    - - - <%if(string.IsNullOrEmpty(Request["umbDebug"]) == false && umbraco.GlobalSettings.DebugMode) - { - Response.Write(Html.RenderProfiler()); - }%> - - diff --git a/src/Umbraco.Web/Editors/AuthenticationController.cs b/src/Umbraco.Web/Editors/AuthenticationController.cs index f2a8996203..793ca4be62 100644 --- a/src/Umbraco.Web/Editors/AuthenticationController.cs +++ b/src/Umbraco.Web/Editors/AuthenticationController.cs @@ -33,7 +33,26 @@ namespace Umbraco.Web.Editors } /// - /// Simply checks if the current user's cookie is valid and if so returns the user object associated + /// Checks if the current user's cookie is valid and if so returns OK or a 400 (BadRequest) + /// + /// + [HttpGet] + public HttpResponseMessage IsAuthenticated() + { + var attempt = UmbracoContext.Security.AuthorizeRequest(); + if (attempt == ValidateRequestAttempt.Success) + { + return Request.CreateResponse(HttpStatusCode.OK); + } + //return Forbidden (403), we don't want to return a 401 because that get's intercepted + // by our angular helper because it thinks that we need to re-perform the request once we are + // authorized. + return Request.CreateResponse(HttpStatusCode.Forbidden); + } + + + /// + /// Checks if the current user's cookie is valid and if so returns the user object associated /// /// public UserDetail GetCurrentUser() diff --git a/src/Umbraco.Web/Editors/ContentController.cs b/src/Umbraco.Web/Editors/ContentController.cs index a1e4754bf2..bc19ee4ad2 100644 --- a/src/Umbraco.Web/Editors/ContentController.cs +++ b/src/Umbraco.Web/Editors/ContentController.cs @@ -366,55 +366,86 @@ namespace Umbraco.Web.Editors /// /// Change the sort order for media /// - /// + /// /// [EnsureUserPermissionForContent("move.ParentId", 'M')] - public HttpResponseMessage PostMove(ContentMove move) + public HttpResponseMessage PostMove(MoveOrCopy move) { - if (move == null) - { - return Request.CreateResponse(HttpStatusCode.NotFound); - } + var toMove = ValidateMoveOrCopy(move); - var contentService = Services.ContentService; - try - { - contentService.Move(contentService.GetById(move.Id), move.ParentId); - return Request.CreateResponse(HttpStatusCode.OK); - } - catch (Exception ex) - { - LogHelper.Error("Could not move content", ex); - throw; - } + Services.ContentService.Move(toMove, move.ParentId); + + return Request.CreateResponse(HttpStatusCode.OK); } /// /// Copies a /// - /// + /// /// [EnsureUserPermissionForContent("copy.ParentId", 'C')] - public HttpResponseMessage PostCopy(ContentMove copy) + public HttpResponseMessage PostCopy(MoveOrCopy copy) { - if (copy == null) + var toCopy = ValidateMoveOrCopy(copy); + + Services.ContentService.Copy(toCopy, copy.ParentId, copy.RelateToOriginal); + + return Request.CreateResponse(HttpStatusCode.OK); + } + + /// + /// Ensures the item can be moved/copied to the new location + /// + /// + /// + private IContent ValidateMoveOrCopy(MoveOrCopy model) + { + if (model == null) { - return Request.CreateResponse(HttpStatusCode.NotFound); + throw new HttpResponseException(HttpStatusCode.NotFound); } var contentService = Services.ContentService; - try + var toMove = contentService.GetById(model.Id); + if (toMove == null) { - contentService.Copy(contentService.GetById(copy.Id), copy.ParentId, true); - return Request.CreateResponse(HttpStatusCode.OK); + throw new HttpResponseException(HttpStatusCode.NotFound); } - catch (Exception ex) + if (model.ParentId < 0) { - LogHelper.Error("Could not copy content", ex); - throw; + //cannot move if the content item is not allowed at the root + if (toMove.ContentType.AllowedAsRoot == false) + { + throw new HttpResponseException( + Request.CreateValidationErrorResponse(ui.Text("moveOrCopy", "notAllowedAtRoot", Security.CurrentUser))); + } } - } + else + { + var parent = contentService.GetById(model.ParentId); + if (parent == null) + { + throw new HttpResponseException(HttpStatusCode.NotFound); + } + //check if the item is allowed under this one + if (parent.ContentType.AllowedContentTypes.Select(x => x.Id).ToArray() + .Any(x => x.Value == toMove.ContentType.Id) == false) + { + throw new HttpResponseException( + Request.CreateValidationErrorResponse(ui.Text("moveOrCopy", "notAllowedByContentType", Security.CurrentUser))); + } + + // Check on paths + if ((string.Format(",{0},", parent.Path)).IndexOf(string.Format(",{0},", toMove.Id), StringComparison.Ordinal) > -1) + { + throw new HttpResponseException( + Request.CreateValidationErrorResponse(ui.Text("moveOrCopy", "notAllowedByPath", Security.CurrentUser))); + } + } + + return toMove; + } private void ShowMessageForStatus(PublishStatus status, ContentItemDisplay display) { diff --git a/src/Umbraco.Web/Editors/MemberController.cs b/src/Umbraco.Web/Editors/MemberController.cs index a424324b3c..9ce07c1fa5 100644 --- a/src/Umbraco.Web/Editors/MemberController.cs +++ b/src/Umbraco.Web/Editors/MemberController.cs @@ -1,6 +1,8 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Net; +using System.Net.Http; using System.Text; using System.Threading.Tasks; using System.Web.Http; @@ -50,16 +52,16 @@ namespace Umbraco.Web.Editors /// /// Gets the content json for the member /// - /// + /// /// - public MemberDisplay GetByLogin(string loginName) + public MemberDisplay GetByKey(Guid key) { if (Member.InUmbracoMemberMode()) { - var foundMember = Services.MemberService.GetByUsername(loginName); + var foundMember = Services.MemberService.GetByKey(key); if (foundMember == null) { - HandleContentNotFound(loginName); + HandleContentNotFound(key); } return Mapper.Map(foundMember); } @@ -89,6 +91,11 @@ namespace Umbraco.Web.Editors UpdateName(contentItem); + //map the custom properties + contentItem.PersistedContent.Email = contentItem.Email; + //TODO: If we allow changing the alias then we'll need to change URLs, etc... in the editor, would prefer to use + // a unique id but then need to figure out how to handle that with custom membership providers - waiting on feedback from morten. + MapPropertyValues(contentItem); //We need to manually check the validation results here because: @@ -130,5 +137,24 @@ namespace Umbraco.Web.Editors return display; } + + + /// + /// Permanently deletes a member + /// + /// + /// + public HttpResponseMessage DeleteByKey(Guid key) + { + var foundMember = Services.MemberService.GetByKey(key); + if (foundMember == null) + { + return HandleContentNotFound(key, false); + } + + Services.MemberService.Delete(foundMember); + + return Request.CreateResponse(HttpStatusCode.OK); + } } } diff --git a/src/Umbraco.Web/Models/ContentEditing/ContentMove.cs b/src/Umbraco.Web/Models/ContentEditing/MoveOrCopy.cs similarity index 62% rename from src/Umbraco.Web/Models/ContentEditing/ContentMove.cs rename to src/Umbraco.Web/Models/ContentEditing/MoveOrCopy.cs index 7b1e209504..6aa87f9e74 100644 --- a/src/Umbraco.Web/Models/ContentEditing/ContentMove.cs +++ b/src/Umbraco.Web/Models/ContentEditing/MoveOrCopy.cs @@ -8,10 +8,10 @@ using System.Text; namespace Umbraco.Web.Models.ContentEditing { /// - /// A model representing a new sort order for a content/media item + /// A model representing a model for moving or copying /// [DataContract(Name = "content", Namespace = "")] - public class ContentMove + public class MoveOrCopy { /// /// The Id of the node to move or copy to @@ -21,11 +21,18 @@ namespace Umbraco.Web.Models.ContentEditing public int ParentId { get; set; } /// - /// ´The id of the node to move or copy + /// The id of the node to move or copy /// [DataMember(Name = "id", IsRequired = true)] [Required] public int Id { get; set; } + + /// + /// Boolean indicating whether copying the object should create a relation to it's original + /// + [DataMember(Name = "relateToOriginal", IsRequired = true)] + [Required] + public bool RelateToOriginal { get; set; } } } diff --git a/src/Umbraco.Web/Trees/ContentTreeController.cs b/src/Umbraco.Web/Trees/ContentTreeController.cs index 0136510628..20b17babf9 100644 --- a/src/Umbraco.Web/Trees/ContentTreeController.cs +++ b/src/Umbraco.Web/Trees/ContentTreeController.cs @@ -26,36 +26,13 @@ namespace Umbraco.Web.Trees { protected override TreeNode CreateRootNode(FormDataCollection queryStrings) { - TreeNode node; - - //if the user's start node is not default, then return their start node as the root node. + var node = base.CreateRootNode(queryStrings); + //if the user's start node is not default, then ensure the root doesn't have a menu if (Security.CurrentUser.StartContentId != Constants.System.Root) { - var currApp = queryStrings.GetValue(TreeQueryStringParameters.Application); - var userRoot = Services.EntityService.Get(Security.CurrentUser.StartContentId, UmbracoObjectTypes.Document); - if (userRoot == null) - { - throw new HttpResponseException(HttpStatusCode.NotFound); - } - - node = new TreeNode( - userRoot.Id.ToInvariantString(), - "", //root nodes aren't expandable, no need to lookup the child nodes url - Url.GetMenuUrl(GetType(), userRoot.Id.ToInvariantString(), queryStrings)) - { - HasChildren = true, - RoutePath = currApp, - Title = userRoot.Name - }; - - - } - else - { - node = base.CreateRootNode(queryStrings); + node.MenuUrl = ""; } return node; - } protected override int RecycleBinId @@ -68,6 +45,11 @@ namespace Umbraco.Web.Trees get { return Services.ContentService.RecycleBinSmells(); } } + protected override int UserStartNode + { + get { return Security.CurrentUser.StartContentId; } + } + protected override TreeNodeCollection PerformGetTreeNodes(string id, FormDataCollection queryStrings) { var entities = GetChildEntities(id); @@ -111,10 +93,17 @@ namespace Umbraco.Web.Trees { var menu = new MenuItemCollection(); + //if the user's start node is not the root then ensure the root menu is empty/doesn't exist + if (Security.CurrentUser.StartContentId != Constants.System.Root) + { + return menu; + } + //set the default to create menu.DefaultMenuAlias = ActionNew.Instance.Alias; // we need to get the default permissions as you can't set permissions on the very root node + //TODO: Use the new services to get permissions var nodeActions = global::umbraco.BusinessLogic.Actions.Action.FromString( UmbracoUser.GetPermissions(Constants.System.Root.ToInvariantString())) .Select(x => new MenuItem(x)); diff --git a/src/Umbraco.Web/Trees/ContentTreeControllerBase.cs b/src/Umbraco.Web/Trees/ContentTreeControllerBase.cs index b3ebabb0f9..a1e646e70a 100644 --- a/src/Umbraco.Web/Trees/ContentTreeControllerBase.cs +++ b/src/Umbraco.Web/Trees/ContentTreeControllerBase.cs @@ -23,6 +23,11 @@ namespace Umbraco.Web.Trees /// protected abstract bool RecycleBinSmells { get; } + /// + /// Returns the user's start node for this tree + /// + protected abstract int UserStartNode { get; } + protected abstract TreeNodeCollection PerformGetTreeNodes(string id, FormDataCollection queryStrings); protected abstract MenuItemCollection PerformGetMenuForNode(string id, FormDataCollection queryStrings); @@ -39,9 +44,11 @@ namespace Umbraco.Web.Trees //if a request is made for the root node data but the user's start node is not the default, then // we need to return their start node data - if (iid == Constants.System.Root && UmbracoUser.StartNodeId != Constants.System.Root) + if (iid == Constants.System.Root && UserStartNode != Constants.System.Root) { - return Services.EntityService.GetChildren(UmbracoUser.StartNodeId, UmbracoObjectType).ToArray(); + //just return their single start node, it will show up under the 'Content' label + var startNode = Services.EntityService.Get(UserStartNode, UmbracoObjectType); + return new[] {startNode}; } return Services.EntityService.GetChildren(iid, UmbracoObjectType).ToArray(); @@ -56,7 +63,7 @@ namespace Umbraco.Web.Trees /// protected sealed override TreeNodeCollection GetTreeNodes(string id, FormDataCollection queryStrings) { - if (id == Constants.System.Root.ToInvariantString()) + if (id == Constants.System.Root.ToInvariantString() && UserStartNode == Constants.System.Root) { //we need to append the recycle bin to the end (if not in dialog mode) var nodes = PerformGetTreeNodes(id, queryStrings); diff --git a/src/Umbraco.Web/Trees/MediaTreeController.cs b/src/Umbraco.Web/Trees/MediaTreeController.cs index ee2432bf15..3df864cbd7 100644 --- a/src/Umbraco.Web/Trees/MediaTreeController.cs +++ b/src/Umbraco.Web/Trees/MediaTreeController.cs @@ -1,11 +1,9 @@ using System; -using System.Globalization; using System.Linq; using System.Net; using System.Net.Http.Formatting; using System.Web; using System.Web.Http; -using System.Web.Security; using Umbraco.Core; using Umbraco.Core.Models; using Umbraco.Core.Services; @@ -14,91 +12,25 @@ using Umbraco.Web.Trees.Menu; using umbraco; using umbraco.BusinessLogic.Actions; using Constants = Umbraco.Core.Constants; -using LegacyMember = umbraco.cms.businesslogic.member.Member; namespace Umbraco.Web.Trees { - [LegacyBaseTree(typeof (loadMembers))] - [Tree(Constants.Applications.Members, Constants.Trees.Members, "Members")] - [PluginController("UmbracoTrees")] - public class MemberTreeController : TreeController - { - protected override TreeNodeCollection GetTreeNodes(string id, FormDataCollection queryStrings) - { - var nodes = new TreeNodeCollection(); - - if (id == Constants.System.Root.ToInvariantString()) - { - //list out all the letters - for (var i = 97; i < 123; i++) - { - var charString = ((char) i).ToString(CultureInfo.InvariantCulture); - nodes.Add(CreateTreeNode(charString, queryStrings, charString, "icon-folder-close", true)); - } - //list out 'Others' if the membership provider is umbraco - if (LegacyMember.InUmbracoMemberMode()) - { - nodes.Add(CreateTreeNode("others", queryStrings, "Others", "icon-folder-close", true)); - } - } - else - { - //if it is a letter - if (id.Length == 1 && char.IsLower(id, 0)) - { - if (LegacyMember.InUmbracoMemberMode()) - { - //get the members from our member data layer - nodes.AddRange( - LegacyMember.getMemberFromFirstLetter(id.ToCharArray()[0]) - .Select(m => CreateTreeNode(m.LoginName, queryStrings, m.Text, "icon-user"))); - } - else - { - //get the members from the provider - int total; - nodes.AddRange( - Membership.Provider.FindUsersByName(id + "%", 0, 9999, out total).Cast() - .Select(m => CreateTreeNode(m.UserName, queryStrings, m.UserName, "icon-user"))); - } - } - else if (id == "others") - { - //others will only show up when in umbraco membership mode - nodes.AddRange( - LegacyMember.getAllOtherMembers() - .Select(m => CreateTreeNode(m.Id.ToInvariantString(), queryStrings, m.Text, "icon-user"))); - } - } - return nodes; - } - - protected override MenuItemCollection GetMenuForNode(string id, FormDataCollection queryStrings) - { - var menu = new MenuItemCollection(); - - if (id == Constants.System.Root.ToInvariantString()) - { - //set default - menu.DefaultMenuAlias = ActionNew.Instance.Alias; - - // root actions - menu.AddMenuItem(); - menu.AddMenuItem(true); - return menu; - } - - menu.AddMenuItem(); - return menu; - } - } - - [LegacyBaseTree(typeof(loadMedia))] [Tree(Constants.Applications.Media, Constants.Trees.Media, "Media")] [PluginController("UmbracoTrees")] public class MediaTreeController : ContentTreeControllerBase { + protected override TreeNode CreateRootNode(FormDataCollection queryStrings) + { + var node = base.CreateRootNode(queryStrings); + //if the user's start node is not default, then ensure the root doesn't have a menu + if (Security.CurrentUser.StartMediaId != Constants.System.Root) + { + node.MenuUrl = ""; + } + return node; + } + protected override int RecycleBinId { get { return Constants.System.RecycleBinContent; } @@ -109,6 +41,11 @@ namespace Umbraco.Web.Trees get { return Services.MediaService.RecycleBinSmells(); } } + protected override int UserStartNode + { + get { return Security.CurrentUser.StartMediaId; } + } + protected override TreeNodeCollection PerformGetTreeNodes(string id, FormDataCollection queryStrings) { var entities = GetChildEntities(id); @@ -132,6 +69,12 @@ namespace Umbraco.Web.Trees if (id == Constants.System.Root.ToInvariantString()) { + //if the user's start node is not the root then ensure the root menu is empty/doesn't exist + if (Security.CurrentUser.StartMediaId != Constants.System.Root) + { + return menu; + } + // root actions menu.AddMenuItem(); menu.AddMenuItem(true); diff --git a/src/Umbraco.Web/Trees/MemberTreeController.cs b/src/Umbraco.Web/Trees/MemberTreeController.cs new file mode 100644 index 0000000000..081f7c8c33 --- /dev/null +++ b/src/Umbraco.Web/Trees/MemberTreeController.cs @@ -0,0 +1,92 @@ +using System.Globalization; +using System.Linq; +using System.Net.Http.Formatting; +using System.Web.Security; +using Umbraco.Core; +using Umbraco.Web.Mvc; +using Umbraco.Web.Trees.Menu; +using umbraco; +using umbraco.BusinessLogic.Actions; +using umbraco.cms.businesslogic.member; +using Constants = Umbraco.Core.Constants; + +namespace Umbraco.Web.Trees +{ + //TODO: Upgrade thsi to use the new Member Service! + + [LegacyBaseTree(typeof (loadMembers))] + [Tree(Constants.Applications.Members, Constants.Trees.Members, "Members")] + [PluginController("UmbracoTrees")] + public class MemberTreeController : TreeController + { + protected override TreeNodeCollection GetTreeNodes(string id, FormDataCollection queryStrings) + { + var nodes = new TreeNodeCollection(); + + if (id == Constants.System.Root.ToInvariantString()) + { + //list out all the letters + for (var i = 97; i < 123; i++) + { + var charString = ((char) i).ToString(CultureInfo.InvariantCulture); + nodes.Add(CreateTreeNode(charString, queryStrings, charString, "icon-folder-close", true)); + } + //list out 'Others' if the membership provider is umbraco + if (Member.InUmbracoMemberMode()) + { + nodes.Add(CreateTreeNode("others", queryStrings, "Others", "icon-folder-close", true)); + } + } + else + { + //if it is a letter + if (id.Length == 1 && char.IsLower(id, 0)) + { + if (Member.InUmbracoMemberMode()) + { + //get the members from our member data layer + nodes.AddRange( + Member.getMemberFromFirstLetter(id.ToCharArray()[0]) + .Select(m => CreateTreeNode(m.UniqueId.ToString("N"), queryStrings, m.Text, "icon-user"))); + } + else + { + //get the members from the provider + int total; + nodes.AddRange( + Membership.Provider.FindUsersByName(id + "%", 0, 9999, out total).Cast() + .Select(m => CreateTreeNode(m.ProviderUserKey.ToString(), queryStrings, m.UserName, "icon-user"))); + } + } + else if (id == "others") + { + //others will only show up when in umbraco membership mode + nodes.AddRange( + Member.getAllOtherMembers() + .Select(m => CreateTreeNode(m.Id.ToInvariantString(), queryStrings, m.Text, "icon-user"))); + } + } + return nodes; + } + + protected override MenuItemCollection GetMenuForNode(string id, FormDataCollection queryStrings) + { + var menu = new MenuItemCollection(); + + if (id == Constants.System.Root.ToInvariantString()) + { + //set default + menu.DefaultMenuAlias = ActionNew.Instance.Alias; + + // root actions + menu.AddMenuItem(); + menu.AddMenuItem(true); + return menu; + } + + menu.AddMenuItem(); + menu.AddMenuItem(true); + return menu; + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Web/Trees/TreeNode.cs b/src/Umbraco.Web/Trees/TreeNode.cs index fd62dff815..fefd5e6f80 100644 --- a/src/Umbraco.Web/Trees/TreeNode.cs +++ b/src/Umbraco.Web/Trees/TreeNode.cs @@ -53,13 +53,6 @@ namespace Umbraco.Web.Trees [DataMember(Name = "name")] public string Title { get; set; } - //TODO: This doesn't seem to be used by anything! - /// - /// Gets or sets the node path. - /// - [DataMember(Name = "nodePath")] - public string NodePath { get; set; } - /// /// The icon to use for the node, this can be either a path to an image or a Css class. /// If a '/' is found in the string then it will be considered a path to an image. diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 729585950c..cd713f4daa 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -313,7 +313,7 @@ - + @@ -370,6 +370,7 @@ + @@ -690,9 +691,6 @@ - - ASPXCodeBehind - ASPXCodeBehind @@ -705,21 +703,9 @@ ASPXCodeBehind - - ASPXCodeBehind - - - ASPXCodeBehind - ASPXCodeBehind - - ASPXCodeBehind - - - ASPXCodeBehind - ASPXCodeBehind @@ -727,12 +713,6 @@ ASPXCodeBehind - - ASPXCodeBehind - - - ASPXCodeBehind - ASPXCodeBehind @@ -1009,7 +989,6 @@ - @@ -1022,7 +1001,6 @@ - @@ -1559,9 +1537,6 @@ True Resources.resx - - Code - default.aspx ASPXCodeBehind @@ -1633,12 +1608,6 @@ XmlTree.xsd - - ASPXCodeBehind - - - Code - EditUser.aspx diff --git a/src/Umbraco.Web/WebApi/Binders/MemberBinder.cs b/src/Umbraco.Web/WebApi/Binders/MemberBinder.cs index ee02c4e076..be399b88a6 100644 --- a/src/Umbraco.Web/WebApi/Binders/MemberBinder.cs +++ b/src/Umbraco.Web/WebApi/Binders/MemberBinder.cs @@ -3,6 +3,8 @@ using AutoMapper; using Umbraco.Core; using Umbraco.Core.Models; using Umbraco.Web.Models.ContentEditing; +using Umbraco.Web.WebApi.Filters; +using System.Linq; namespace Umbraco.Web.WebApi.Binders { @@ -23,9 +25,17 @@ namespace Umbraco.Web.WebApi.Binders protected override IMember GetExisting(MemberSave model) { - return ApplicationContext.Services.MemberService.GetByUsername(model.Username); - } + //TODO: We're going to remove the built-in member properties from this editor - not sure if we should be persisting them elsewhere ? + var toRemove = Constants.Conventions.Member.StandardPropertyTypeStubs.Select(x => x.Value.Alias).ToArray(); + var member = ApplicationContext.Services.MemberService.GetByUsername(model.Username); + foreach (var remove in toRemove) + { + member.Properties.Remove(remove); + } + return member; + } + protected override IMember CreateNew(MemberSave model) { var contentType = ApplicationContext.Services.ContentTypeService.GetMemberType(model.ContentTypeAlias); diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/cacheBrowser.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/cacheBrowser.aspx.cs deleted file mode 100644 index 0e923ffc03..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/cacheBrowser.aspx.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System.Collections; -using umbraco.BasePages; - -namespace umbraco.cms.presentation -{ - /// - /// Summary description for cacheBrowser. - /// - public partial class cacheBrowser : UmbracoEnsuredPage - { - public cacheBrowser() - { - CurrentApp = BusinessLogic.DefaultApps.developer.ToString(); - - } - protected void Page_Load(object sender, System.EventArgs e) - { - // Cache removal checks - if (Request.QueryString["clearByType"] != null) - ApplicationContext.ApplicationCache.ClearCacheObjectTypes(Request.QueryString["clearByType"]); - else if (Request.QueryString["clearByKey"] != null) - ApplicationContext.ApplicationCache.ClearCacheItem(Request.QueryString["clearByKey"]); - - // Put user code to initialize the page here - Hashtable ht = cms.businesslogic.cache.Cache.ReturnCacheItemsOrdred(); - foreach (string key in ht.Keys) - { - Response.Write("" + key + ": " + ((ArrayList)ht[key]).Count.ToString() + " (Delete)
    "); - if (Request.QueryString["key"] == key) - for (int i = 0; i < ((ArrayList)ht[key]).Count; i++) - Response.Write(" - " + ((ArrayList)ht[key])[i] + " (Delete)
    "); - } - } - protected void Button1_Click(object sender, System.EventArgs e) - { - ApplicationContext.ApplicationCache.ClearAllCache(); - } - - protected System.Web.UI.HtmlControls.HtmlForm Form1; - protected System.Web.UI.WebControls.Button Button1; - } -} diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/create.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/create.aspx.cs deleted file mode 100644 index c8ec4a581d..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/create.aspx.cs +++ /dev/null @@ -1,50 +0,0 @@ -using System; -using System.Web.UI.WebControls; - -using System.Xml; -using Umbraco.Core.IO; - -namespace umbraco.cms.presentation -{ - public class Create : BasePages.UmbracoEnsuredPage - { - [Obsolete("This property is no longer used")] - protected umbWindow createWindow; - protected Label helpText; - protected TextBox rename; - protected Label Label1; - protected ListBox nodeType; - protected PlaceHolder UI; - - protected override void OnLoad(EventArgs e) - { - base.OnLoad(e); - - // Load create definitions - var nodeType = Request.QueryString["nodeType"]; - - var createDef = new XmlDocument(); - var defReader = new XmlTextReader(IOHelper.MapPath(SystemFiles.CreateUiXml)); - createDef.Load(defReader); - defReader.Close(); - - // Find definition for current nodeType - var def = createDef.SelectSingleNode("//nodeType [@alias = '" + nodeType + "']"); - if (def == null) - { - throw new ArgumentException("The create dialog for \"" + nodeType + "\" does not match anything defined in the \"" + SystemFiles.CreateUiXml + "\". This could mean an incorrectly installed package or a corrupt UI file"); - } - - try - { - var virtualPath = SystemDirectories.Umbraco + def.SelectSingleNode("./usercontrol").FirstChild.Value; - var mainControl = LoadControl(virtualPath); - UI.Controls.Add(mainControl); - } - catch (Exception ex) - { - throw new ArgumentException("ERROR CREATING CONTROL FOR NODETYPE: " + nodeType, ex); - } - } - } -} diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/create/contentTasks.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/create/contentTasks.cs deleted file mode 100644 index 160cb7b610..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/create/contentTasks.cs +++ /dev/null @@ -1,58 +0,0 @@ -using System; -using System.Data; -using System.Web.Security; -using Umbraco.Web.UI; -using umbraco.BusinessLogic; -using umbraco.DataLayer; -using umbraco.BasePages; -using umbraco.IO; -using umbraco.cms.businesslogic.member; - -namespace umbraco -{ - public class contentTasks : LegacyDialogTask - { - private string _returnUrl = ""; - - public override string ReturnUrl - { - get { return _returnUrl; } - } - - public override string AssignedApp - { - get { return DefaultApps.content.ToString(); } - } - - public override bool PerformSave() - { - var dt = new cms.businesslogic.web.DocumentType(TypeID); - var d = cms.businesslogic.web.Document.MakeNew(Alias, dt, User, ParentID); - if (d == null) - { - //TODO: Slace - Fix this to use the language files - BasePage.Current.ClientTools.ShowSpeechBubble(BasePage.speechBubbleIcon.error, "Document Creation", "Document creation was canceled"); - return false; - } - else - { - _returnUrl = "editContent.aspx?id=" + d.Id.ToString() + "&isNew=true"; - return true; - } - } - - public override bool PerformDelete() - { - var d = new cms.businesslogic.web.Document(ParentID); - - d.delete(); - - // Log - Log.Add(LogTypes.Delete, User.GetCurrent(), d.Id, ""); - - return true; - - } - - } -} diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/create/mediaTasks.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/create/mediaTasks.cs deleted file mode 100644 index aadd439a00..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/create/mediaTasks.cs +++ /dev/null @@ -1,50 +0,0 @@ -using System; -using System.Data; -using System.Web.Security; -using Umbraco.Core.Logging; -using Umbraco.Web.UI; -using umbraco.BusinessLogic; -using umbraco.DataLayer; -using umbraco.BasePages; -using umbraco.IO; -using umbraco.cms.businesslogic.member; - -namespace umbraco -{ - public class mediaTasks : LegacyDialogTask - { - private string _returnUrl = ""; - - public override string ReturnUrl - { - get { return _returnUrl; } - } - - public override string AssignedApp - { - get { return DefaultApps.media.ToString(); } - } - - public override bool PerformSave() - { - var dt = new cms.businesslogic.media.MediaType(TypeID); - var m = cms.businesslogic.media.Media.MakeNew(Alias, dt, User, ParentID); - _returnUrl = "editMedia.aspx?id=" + m.Id.ToString() + "&isNew=true"; - - return true; - } - - public override bool PerformDelete() - { - var d = new cms.businesslogic.media.Media(ParentID); - - // Log - LogHelper.Debug(string.Format("Delete media item {0} by user {1}", d.Id, User.GetCurrent().Id)); - - d.delete(); - return true; - - } - - } -} diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/dashboard.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/dashboard.aspx.cs deleted file mode 100644 index ee3798c660..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/dashboard.aspx.cs +++ /dev/null @@ -1,377 +0,0 @@ -using System; -using System.Collections; -using System.ComponentModel; -using System.Data; -using System.Drawing; -using System.Reflection; -using System.Web; -using System.Web.SessionState; -using System.Web.UI; -using System.Web.UI.WebControls; -using System.Web.UI.HtmlControls; -using System.IO; -using System.Xml; -using System.Xml.XPath; -using umbraco.uicontrols; -using umbraco.IO; -using umbraco.cms.helpers; -using umbraco.BusinessLogic; - -namespace umbraco.cms.presentation -{ - /// - /// Summary description for dashboard. - /// - /// - - public partial class dashboard : BasePages.UmbracoEnsuredPage - { - - - private string _section = ""; - - protected void Page_Load(object sender, System.EventArgs e) - { - // Put user code to initialize the page here - Panel2.Text = ui.Text("dashboard", "welcome", UmbracoUser) + " " + UmbracoUser.Name; - } - - private Control CreateDashBoardWrapperControl(Control control) - { - PlaceHolder placeHolder = new PlaceHolder(); - placeHolder.Controls.Add(new LiteralControl("
    ")); - placeHolder.Controls.Add(control); - placeHolder.Controls.Add(new LiteralControl("
    ")); - return placeHolder; - } - - override protected void OnInit(EventArgs e) - { - - base.OnInit(e); - - /* - // Load dashboard content - if (helper.Request("app") != "") - _section = helper.Request("app"); - else if (getUser().Applications.Length > 0) - _section = "default"; - else - _section = getUser().Applications[0].alias; - - XmlDocument dashBoardXml = new XmlDocument(); - dashBoardXml.Load(IOHelper.MapPath(SystemFiles.DashboardConfig)); - - var control = dashBoardXml.DocumentElement.SelectSingleNode("//control [areas/area = '" + _section.ToLower() + "']"); - */ - /* - // test for new tab interface - foreach (XmlNode section in dashBoardXml.DocumentElement.SelectNodes("//section [areas/area = '" + _section.ToLower() + "']")) - { - if (section != null && validateAccess(section)) - { - Panel2.Visible = false; - dashboardTabs.Visible = true; - - foreach (XmlNode entry in section.SelectNodes("./tab")) - { - if (validateAccess(entry)) - { - TabPage tab = dashboardTabs.NewTabPage(entry.Attributes.GetNamedItem("caption").Value); - tab.HasMenu = true; - tab.Style.Add("padding", "0 10px"); - - foreach (XmlNode uc in entry.SelectNodes("./control")) - { - if (validateAccess(uc)) - { - string control = getFirstText(uc).Trim(' ', '\r', '\n'); - string path = IOHelper.FindFile(control); - - - try - { - Control c = LoadControl(path); - - // set properties - Type type = c.GetType(); - if (type != null) - { - foreach (XmlAttribute att in uc.Attributes) - { - string attributeName = att.Name; - string attributeValue = parseControlValues(att.Value).ToString(); - // parse special type of values - - - PropertyInfo prop = type.GetProperty(attributeName); - if (prop == null) - { - continue; - } - - prop.SetValue(c, Convert.ChangeType(attributeValue, prop.PropertyType), - null); - - } - } - - //resolving files from dashboard config which probably does not map to a virtual fi - tab.Controls.Add(AddPanel(uc, c)); - } - catch (Exception ee) - { - tab.Controls.Add( - new LiteralControl( - "

    Could not load control: '" + path + - "'.
    Error message: " + - ee.ToString() + "

    ")); - } - } - } - } - } - } - else - { - - - foreach ( - XmlNode entry in dashBoardXml.SelectNodes("//entry [@section='" + _section.ToLower() + "']")) - { - PlaceHolder placeHolder = new PlaceHolder(); - if (entry == null || entry.FirstChild == null) - { - placeHolder.Controls.Add( - CreateDashBoardWrapperControl(new LiteralControl("Error loading DashBoard Content"))); - } - else - { - string path = IOHelper.FindFile(entry.FirstChild.Value); - - try - { - placeHolder.Controls.Add(CreateDashBoardWrapperControl(LoadControl(path))); - } - catch (Exception err) - { - Trace.Warn("Dashboard", string.Format("error loading control '{0}'", - path), err); - placeHolder.Controls.Clear(); - placeHolder.Controls.Add(CreateDashBoardWrapperControl(new LiteralControl(string.Format( - "Error loading DashBoard Content '{0}'; {1}", path, - err.Message)))); - } - } - dashBoardContent.Controls.Add(placeHolder); - } - } - }*/ - } - - private object parseControlValues(string value) - { - if (!String.IsNullOrEmpty(value)) - { - if (value.StartsWith("[#")) - { - value = value.Substring(2, value.Length - 3).ToLower(); - switch (value) - { - case "usertype": - return BusinessLogic.User.GetCurrent().UserType.Alias; - case "username": - return BusinessLogic.User.GetCurrent().Name; - case "userlogin": - return BusinessLogic.User.GetCurrent().LoginName; - case "usercontentstartnode": - return BusinessLogic.User.GetCurrent().StartNodeId; - case "usermediastartnode": - return BusinessLogic.User.GetCurrent().StartMediaId; - default: - return value; - } - } - } - - return value; - } - - private Control AddPanel(XmlNode node, Control c) - { - LiteralControl hide = AddShowOnceLink(node); - if (node.Attributes.GetNamedItem("addPanel") != null && - node.Attributes.GetNamedItem("addPanel").Value == "true") - { - Pane p = new Pane(); - PropertyPanel pp = new PropertyPanel(); - if (node.Attributes.GetNamedItem("panelCaption") != null && - !String.IsNullOrEmpty(node.Attributes.GetNamedItem("panelCaption").Value)) - { - string panelCaption = node.Attributes.GetNamedItem("panelCaption").Value; - if (panelCaption.StartsWith("#")) - { - panelCaption = ui.Text(panelCaption.Substring(1)); - } - pp.Text = panelCaption; - } - // check for hide in the future link - if (!String.IsNullOrEmpty(hide.Text)) - { - pp.Controls.Add(hide); - } - pp.Controls.Add(c); - p.Controls.Add(pp); - return p; - } - - if (!String.IsNullOrEmpty(hide.Text)) - { - PlaceHolder ph = new PlaceHolder(); - ph.Controls.Add(hide); - ph.Controls.Add(c); - return ph; - } - else - { - return c; - } - } - - private LiteralControl AddShowOnceLink(XmlNode node) - { - LiteralControl onceLink = new LiteralControl(); - if (node.Attributes.GetNamedItem("showOnce") != null && - node.Attributes.GetNamedItem("showOnce").Value.ToLower() == "true") - { - onceLink.Text = "" + ui.Text("dashboard", "dontShowAgain") + ""; - } - return onceLink; - } - - private string getFirstText(XmlNode node) - { - foreach (XmlNode n in node.ChildNodes) - { - if (n.NodeType == XmlNodeType.Text) - return n.Value; - } - - return ""; - } - - private string generateCookieKey(XmlNode node) - { - string key = String.Empty; - if (node.Name.ToLower() == "control") - { - key = node.FirstChild.Value + "_" + generateCookieKey(node.ParentNode); - } - else if (node.Name.ToLower() == "tab") - { - key = node.Attributes.GetNamedItem("caption").Value; - } - - return Casing.SafeAlias(key.ToLower()); - } - - private bool validateAccess(XmlNode node) - { - // check if this area should be shown at all - string onlyOnceValue = StateHelper.GetCookieValue(generateCookieKey(node)); - if (!String.IsNullOrEmpty(onlyOnceValue)) - { - return false; - } - - // the root user can always see everything - if (CurrentUser.IsRoot()) - { - return true; - } - else if (node != null) - { - XmlNode accessRules = node.SelectSingleNode("access"); - bool retVal = true; - if (accessRules != null && accessRules.HasChildNodes) - { - string currentUserType = CurrentUser.UserType.Alias.ToLowerInvariant(); - - //Update access rules so we'll be comparing lower case to lower case always - - var denies = accessRules.SelectNodes("deny"); - foreach (XmlNode deny in denies) - { - deny.InnerText = deny.InnerText.ToLowerInvariant(); - } - - var grants = accessRules.SelectNodes("grant"); - foreach (XmlNode grant in grants) - { - grant.InnerText = grant.InnerText.ToLowerInvariant(); - } - - string allowedSections = ","; - foreach (BusinessLogic.Application app in CurrentUser.Applications) - { - allowedSections += app.alias.ToLower() + ","; - } - XmlNodeList grantedTypes = accessRules.SelectNodes("grant"); - XmlNodeList grantedBySectionTypes = accessRules.SelectNodes("grantBySection"); - XmlNodeList deniedTypes = accessRules.SelectNodes("deny"); - - // if there's a grant type, everyone who's not granted is automatically denied - if (grantedTypes.Count > 0 || grantedBySectionTypes.Count > 0) - { - retVal = false; - if (grantedBySectionTypes.Count > 0 && accessRules.SelectSingleNode(String.Format("grantBySection [contains('{0}', concat(',',.,','))]", allowedSections)) != null) - { - retVal = true; - } - else if (grantedTypes.Count > 0 && accessRules.SelectSingleNode(String.Format("grant [. = '{0}']", currentUserType)) != null) - { - retVal = true; - } - } - // if the current type of user is denied we'll say nay - if (deniedTypes.Count > 0 && accessRules.SelectSingleNode(String.Format("deny [. = '{0}']", currentUserType)) != null) - { - retVal = false; - } - - } - - return retVal; - } - return false; - } - - /// - /// Panel2 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::umbraco.uicontrols.UmbracoPanel Panel2; - - /// - /// dashBoardContent control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.PlaceHolder dashBoardContent; - - /// - /// dashboardTabs control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::umbraco.uicontrols.TabView dashboardTabs; - - } -} diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/editContent.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/editContent.aspx.cs deleted file mode 100644 index 60a6f9048b..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/editContent.aspx.cs +++ /dev/null @@ -1,642 +0,0 @@ -using System; -using System.Web.UI; -using System.Web.UI.WebControls; -using Umbraco.Core.Models; -using Umbraco.Core.Persistence.Caching; -using Umbraco.Core.IO; -using Umbraco.Core.Publishing; -using Umbraco.Core.Services; -using umbraco.BusinessLogic.Actions; -using umbraco.uicontrols.DatePicker; -using umbraco.BusinessLogic; -using umbraco.cms.businesslogic.web; -using umbraco.presentation; -using System.Linq; -using Image = System.Web.UI.WebControls.Image; -using Umbraco.Core; - -namespace umbraco.cms.presentation -{ - public class editContent : BasePages.UmbracoEnsuredPage - { - protected uicontrols.TabView TabView1; - protected TextBox documentName; - private Document _document; - private bool _documentHasPublishedVersion = false; - protected Literal jsIds; - private readonly LiteralControl _dp = new LiteralControl(); - private readonly DateTimePicker _dpRelease = new DateTimePicker(); - private readonly DateTimePicker _dpExpire = new DateTimePicker(); - - private controls.ContentControl _cControl; - - private readonly DropDownList _ddlDefaultTemplate = new DropDownList(); - - private readonly uicontrols.Pane _publishProps = new uicontrols.Pane(); - private readonly uicontrols.Pane _linkProps = new uicontrols.Pane(); - - private readonly Button _unPublish = new Button(); - private readonly Literal _littPublishStatus = new Literal(); - - private controls.ContentControl.publishModes _canPublish = controls.ContentControl.publishModes.Publish; - - private int? _contentId = null; - - override protected void OnInit(EventArgs e) - { - base.OnInit(e); - - //validate! - int id; - if (int.TryParse(Request.QueryString["id"], out id) == false) - { - //if this is invalid show an error - this.DisplayFatalError("Invalid query string"); - return; - } - _contentId = id; - - - _unPublish.Click += UnPublishDo; - - //Loading Content via new public service to ensure that the Properties are loaded correct - var content = ApplicationContext.Current.Services.ContentService.GetById(id); - _document = new Document(content); - - //check if the doc exists - if (string.IsNullOrEmpty(_document.Path)) - { - //if this is invalid show an error - this.DisplayFatalError("No document found with id " + _contentId); - //reset the content id to null so processing doesn't continue on OnLoad - _contentId = null; - return; - } - - // we need to check if there's a published version of this document - _documentHasPublishedVersion = _document.Content.HasPublishedVersion(); - - // Check publishing permissions - if (!UmbracoUser.GetPermissions(_document.Path).Contains(ActionPublish.Instance.Letter.ToString())) - { - // Check to see if the user has send to publish permissions - if (!UmbracoUser.GetPermissions(_document.Path).Contains(ActionToPublish.Instance.Letter.ToString())) - { - //If no send to publish permission then revert to NoPublish mode - _canPublish = controls.ContentControl.publishModes.NoPublish; - } - else - { - _canPublish = controls.ContentControl.publishModes.SendToPublish; - } - } - - _cControl = new controls.ContentControl(_document, _canPublish, "TabView1"); - - _cControl.ID = "TabView1"; - - _cControl.Width = Unit.Pixel(666); - _cControl.Height = Unit.Pixel(666); - - // Add preview button - - foreach (uicontrols.TabPage tp in _cControl.GetPanels()) - { - AddPreviewButton(tp.Menu, _document.Id); - } - - plc.Controls.Add(_cControl); - - - var publishStatus = new PlaceHolder(); - if (_documentHasPublishedVersion) - { - _littPublishStatus.Text = ui.Text("content", "lastPublished", UmbracoUser) + ": " + _document.VersionDate.ToShortDateString() + "   "; - - publishStatus.Controls.Add(_littPublishStatus); - if (UmbracoUser.GetPermissions(_document.Path).IndexOf("U") > -1) - _unPublish.Visible = true; - else - _unPublish.Visible = false; - } - else - { - _littPublishStatus.Text = ui.Text("content", "itemNotPublished", UmbracoUser); - publishStatus.Controls.Add(_littPublishStatus); - _unPublish.Visible = false; - } - - _unPublish.Text = ui.Text("content", "unPublish", UmbracoUser); - _unPublish.ID = "UnPublishButton"; - _unPublish.Attributes.Add("onClick", "if (!confirm('" + ui.Text("defaultdialogs", "confirmSure", UmbracoUser) + "')) return false; "); - publishStatus.Controls.Add(_unPublish); - - _publishProps.addProperty(ui.Text("content", "publishStatus", UmbracoUser), publishStatus); - - // Template - var template = new PlaceHolder(); - var documentType = new DocumentType(_document.ContentType.Id); - _cControl.PropertiesPane.addProperty(ui.Text("documentType"), new LiteralControl(documentType.Text)); - - - //template picker - _cControl.PropertiesPane.addProperty(ui.Text("template"), template); - int defaultTemplate; - if (_document.Template != 0) - defaultTemplate = _document.Template; - else - defaultTemplate = documentType.DefaultTemplate; - - if (UmbracoUser.UserType.Name == "writer") - { - if (defaultTemplate != 0) - template.Controls.Add(new LiteralControl(businesslogic.template.Template.GetTemplate(defaultTemplate).Text)); - else - template.Controls.Add(new LiteralControl(ui.Text("content", "noDefaultTemplate"))); - } - else - { - _ddlDefaultTemplate.Items.Add(new ListItem(ui.Text("choose") + "...", "")); - foreach (var t in documentType.allowedTemplates) - { - - var tTemp = new ListItem(t.Text, t.Id.ToString()); - if (t.Id == defaultTemplate) - tTemp.Selected = true; - _ddlDefaultTemplate.Items.Add(tTemp); - } - template.Controls.Add(_ddlDefaultTemplate); - } - - - // Editable update date, release date and expire date added by NH 13.12.04 - _dp.ID = "updateDate"; - _dp.Text = _document.UpdateDate.ToShortDateString() + " " + _document.UpdateDate.ToShortTimeString(); - _publishProps.addProperty(ui.Text("content", "updateDate", UmbracoUser), _dp); - - _dpRelease.ID = "releaseDate"; - _dpRelease.DateTime = _document.ReleaseDate; - _dpRelease.ShowTime = true; - _publishProps.addProperty(ui.Text("content", "releaseDate", UmbracoUser), _dpRelease); - - _dpExpire.ID = "expireDate"; - _dpExpire.DateTime = _document.ExpireDate; - _dpExpire.ShowTime = true; - _publishProps.addProperty(ui.Text("content", "expireDate", UmbracoUser), _dpExpire); - - _cControl.Save += Save; - _cControl.SaveAndPublish += Publish; - _cControl.SaveToPublish += SendToPublish; - - // Add panes to property page... - _cControl.tpProp.Controls.AddAt(1, _publishProps); - _cControl.tpProp.Controls.AddAt(2, _linkProps); - - // add preview to properties pane too - AddPreviewButton(_cControl.tpProp.Menu, _document.Id); - - - } - - protected void Page_Load(object sender, EventArgs e) - { - if (!_contentId.HasValue) - return; - - if (!CheckUserValidation()) - return; - - // clear preview cookie - // zb-00004 #29956 : refactor cookies names & handling - StateHelper.Cookies.Preview.Clear(); - - if (!IsPostBack) - { - - Log.Add(LogTypes.Open, UmbracoUser, _document.Id, ""); - ClientTools.SyncTree(_document.Path, false); - } - - - jsIds.Text = "var umbPageId = " + _document.Id.ToString() + ";\nvar umbVersionId = '" + _document.Version.ToString() + "';\n"; - - } - - protected override void OnPreRender(EventArgs e) - { - base.OnPreRender(e); - UpdateNiceUrls(); - } - - /// - /// Handles the Save event for the ContentControl. - /// - /// - /// - /// - /// This will set the document's properties and persist a new document revision - /// - protected void Save(object sender, EventArgs e) - { - //NOTE: This is only here because we have to keep backwards compatibility with events in the ContentControl. - // see: http://issues.umbraco.org/issue/U4-1660 - // in this case both Save and SaveAndPublish will fire when we are publishing but we only want to handle that once, - // so if this is actually doing a publish, we'll exit and rely on the SaveAndPublish handler to do all the work. - if (_cControl.DoesPublish) - { - return; - } - - //update UI and set document properties - PerformSaveLogic(); - - //persist the document - _document.Save(); - - // Run Handler - BusinessLogic.Actions.Action.RunActionHandlers(_document, ActionUpdate.Instance); - - ClientTools.ShowSpeechBubble( - speechBubbleIcon.save, ui.Text("speechBubbles", "editContentSavedHeader"), - ui.Text("speechBubbles", "editContentSavedText")); - - ClientTools.SyncTree(_document.Path, true); - } - - /// - /// Handles the SendToPublish event - /// - /// - /// - protected void SendToPublish(object sender, EventArgs e) - { - if (Page.IsValid) - { - ClientTools.ShowSpeechBubble( - speechBubbleIcon.save, ui.Text("speechBubbles", "editContentSendToPublish", UmbracoUser), - ui.Text("speechBubbles", "editContentSendToPublishText", UmbracoUser)); - _document.SendToPublication(UmbracoUser); - } - } - - /// - /// Handles the SaveAndPublish event - /// - /// - /// - /// - /// Sets the document's properties and if the page is valid continues to publish it, otherwise just saves a revision. - /// - protected void Publish(object sender, EventArgs e) - { - //update UI and set document properties - PerformSaveLogic(); - - //the business logic here will check to see if the doc can actually be published and will return the - // appropriate result so we can display the correct error messages (or success). - var savePublishResult = _document.SaveAndPublishWithResult(UmbracoUser); - - ShowMessageForStatus(savePublishResult.Result); - - if (savePublishResult.Success) - { - _littPublishStatus.Text = string.Format("{0}: {1}
    ", ui.Text("content", "lastPublished", UmbracoUser), _document.VersionDate.ToString()); - - if (UmbracoUser.GetPermissions(_document.Path).IndexOf("U") > -1) - { - _unPublish.Visible = true; - } - - _documentHasPublishedVersion = _document.Content.HasPublishedVersion(); - } - - ClientTools.SyncTree(_document.Path, true); - } - - private void ShowMessageForStatus(PublishStatus status) - { - switch (status.StatusType) - { - case PublishStatusType.Success: - case PublishStatusType.SuccessAlreadyPublished: - ClientTools.ShowSpeechBubble( - speechBubbleIcon.save, - ui.Text("speechBubbles", "editContentPublishedHeader", UmbracoUser), - ui.Text("speechBubbles", "editContentPublishedText", UmbracoUser)); - break; - case PublishStatusType.FailedPathNotPublished: - ClientTools.ShowSpeechBubble( - speechBubbleIcon.warning, - ui.Text("publish"), - ui.Text("publish", "contentPublishedFailedByParent", - string.Format("{0} ({1})", status.ContentItem.Name, status.ContentItem.Id), - UmbracoUser).Trim()); - break; - case PublishStatusType.FailedCancelledByEvent: - ClientTools.ShowSpeechBubble( - speechBubbleIcon.warning, - ui.Text("publish"), - ui.Text("speechBubbles", "contentPublishedFailedByEvent")); - break; - case PublishStatusType.FailedHasExpired: - case PublishStatusType.FailedAwaitingRelease: - case PublishStatusType.FailedIsTrashed: - case PublishStatusType.FailedContentInvalid: - ClientTools.ShowSpeechBubble( - speechBubbleIcon.warning, - ui.Text("publish"), - ui.Text("publish", "contentPublishedFailedInvalid", - new[] - { - string.Format("{0} ({1})", status.ContentItem.Name, status.ContentItem.Id), - string.Join(",", status.InvalidProperties.Select(x => x.Alias)) - }, - UmbracoUser).Trim()); - break; - default: - throw new IndexOutOfRangeException(); - } - } - - protected void UnPublishDo(object sender, EventArgs e) - { - _document.UnPublish(); - _littPublishStatus.Text = ui.Text("content", "itemNotPublished", UmbracoUser); - _unPublish.Visible = false; - _documentHasPublishedVersion = false; - - //library.UnPublishSingleNode(_document.Id); - - Current.ClientTools.SyncTree(_document.Path, true); - ClientTools.ShowSpeechBubble(speechBubbleIcon.success, ui.Text("unpublish"), ui.Text("speechBubbles", "contentUnpublished")); - - //newPublishStatus.Text = "0"; - } - - void UpdateNiceUrlProperties(string niceUrlText, string altUrlsText) - { - _linkProps.Controls.Clear(); - - var lit = new Literal(); - lit.Text = niceUrlText; - _linkProps.addProperty(ui.Text("content", "urls", UmbracoUser), lit); - - if (!string.IsNullOrWhiteSpace(altUrlsText)) - { - lit = new Literal(); - lit.Text = altUrlsText; - _linkProps.addProperty(ui.Text("content", "alternativeUrls", UmbracoUser), lit); - } - } - - void UpdateNiceUrls() - { - if (_documentHasPublishedVersion == false) - { - UpdateNiceUrlProperties("" + ui.Text("content", "itemNotPublished", UmbracoUser) + "", null); - return; - } - - var urlProvider = Umbraco.Web.UmbracoContext.Current.RoutingContext.UrlProvider; - var url = urlProvider.GetUrl(_document.Id); - string niceUrlText = null; - var altUrlsText = new System.Text.StringBuilder(); - - if (url == "#") - { - // document as a published version yet it's url is "#" => a parent must be - // unpublished, walk up the tree until we find it, and report. - var parent = _document; - do - { - parent = parent.ParentId > 0 ? new Document(parent.ParentId) : null; - } - while (parent != null && parent.Published); - - if (parent == null) // oops - internal error - niceUrlText = "" + ui.Text("content", "parentNotPublishedAnomaly", UmbracoUser) + ""; - else - niceUrlText = "" + ui.Text("content", "parentNotPublished", parent.Text, UmbracoUser) + ""; - } - else - { - niceUrlText = string.Format("{0}", url); - - foreach (var otherUrl in urlProvider.GetOtherUrls(_document.Id)) - altUrlsText.AppendFormat("{0}
    ", otherUrl); - } - - UpdateNiceUrlProperties(niceUrlText, altUrlsText.ToString()); - } - - /// - /// When a document is saved or published all of this logic must be performed. - /// - /// - /// This updates both UI controls and business logic object properties but does not persist any data to - /// business logic repositories. - /// - private void PerformSaveLogic() - { - // error handling test - if (!Page.IsValid) - { - foreach (uicontrols.TabPage tp in _cControl.GetPanels()) - { - tp.ErrorControl.Visible = true; - tp.ErrorHeader = ui.Text("errorHandling", "errorButDataWasSaved"); - tp.CloseCaption = ui.Text("close"); - } - } - else if (Page.IsPostBack) - { - // hide validation summaries - foreach (uicontrols.TabPage tp in _cControl.GetPanels()) - { - tp.ErrorControl.Visible = false; - } - } - - if (_dpRelease.DateTime > new DateTime(1753, 1, 1) && _dpRelease.DateTime < new DateTime(9999, 12, 31)) - _document.ReleaseDate = _dpRelease.DateTime; - else - _document.ReleaseDate = new DateTime(1, 1, 1, 0, 0, 0); - if (_dpExpire.DateTime > new DateTime(1753, 1, 1) && _dpExpire.DateTime < new DateTime(9999, 12, 31)) - _document.ExpireDate = _dpExpire.DateTime; - else - _document.ExpireDate = new DateTime(1, 1, 1, 0, 0, 0); - - // Update default template - if (_ddlDefaultTemplate.SelectedIndex > 0) - { - _document.Template = int.Parse(_ddlDefaultTemplate.SelectedValue); - } - else - { - if (new DocumentType(_document.ContentType.Id).allowedTemplates.Length == 0) - { - _document.RemoveTemplate(); - } - } - - //The value of the properties has been set on IData through IDataEditor in the ContentControl - //so we need to 'retrieve' that value and set it on the property of the new IContent object. - //NOTE This is a workaround for the legacy approach to saving values through the DataType instead of the Property - //- (The DataType shouldn't be responsible for saving the value - especically directly to the db). - foreach (var item in _cControl.DataTypes) - { - _document.getProperty(item.Key).Value = item.Value.Data.Value; - } - - // Update the update date - _dp.Text = _document.UpdateDate.ToShortDateString() + " " + _document.UpdateDate.ToShortTimeString(); - } - - /// - /// Clears the page of all controls and shows a simple message. Used if users don't have visible access to the page. - /// - /// - private void ShowUserValidationError(string message) - { - this.Controls.Clear(); - this.Controls.Add(new LiteralControl(String.Format("

    Access denied

    Access denied{0}
    ", message))); - } - - /// - /// Checks if the user cannot view/browse this page/app and displays an html message to the user if this is not the case. - /// - /// - private bool CheckUserValidation() - { - // Validate permissions - if (!base.ValidateUserApp(Constants.Applications.Content)) - { - ShowUserValidationError("

    The current user doesn't have access to this application

    Please contact the system administrator if you think that you should have access.

    "); - return false; - } - if (!ValidateUserNodeTreePermissions(_document.Path, ActionBrowse.Instance.Letter.ToString())) - { - ShowUserValidationError( - "

    The current user doesn't have permissions to browse this document

    Please contact the system administrator if you think that you should have access.

    "); - return false; - } - //TODO: Change this, when we add view capabilities, the user will be able to view but not edit! - if (!ValidateUserNodeTreePermissions(_document.Path, ActionUpdate.Instance.Letter.ToString())) - { - ShowUserValidationError("

    The current user doesn't have permissions to edit this document

    Please contact the system administrator if you think that you should have access.

    "); - return false; - } - return true; - } - - private void AddPreviewButton(uicontrols.ScrollingMenu menu, int id) - { - uicontrols.MenuIconI menuItem; - - // Find the first splitter in the Menu - Should be the rte toolbar's splitter - var startIndex = menu.FindSplitter(1); - - if (startIndex == -1) - { - // No Splitter found - rte toolbar isn't loaded - menu.InsertSplitter(); - menuItem = menu.NewIcon(); - } - else - { - // Rte toolbar is loaded, inject after it's Splitter - menuItem = menu.NewIcon(startIndex + 1); - menu.InsertSplitter(startIndex + 2); - } - - menuItem.ImageURL = SystemDirectories.Umbraco + "/images/editor/vis.gif"; - - if (EnablePreviewButton()) - { - menuItem.AltText = ui.Text("buttons", "showPage", UmbracoUser); - menuItem.OnClickCommand = "window.open('dialogs/preview.aspx?id=" + id + "','umbPreview')"; - } - else - { - var showPageDisabledText = ui.Text("buttons", "showPageDisabled", UmbracoUser); - if (showPageDisabledText.StartsWith("[")) - showPageDisabledText = ui.GetText("buttons", "showPageDisabled", null, "en"); - - menuItem.AltText = showPageDisabledText; - ((Image) menuItem).Attributes.Add("style", "opacity: 0.5"); - } - } - - private bool EnablePreviewButton() - { - // Fix for U4-862, if there's no template, disable the preview button - // Fixed again for U4-2587, apparently at some point "no template" changed from -1 to 0? -SJ - // Now also catches when template doesn't exist any more or is not allowed any more - // Don't think there's a better way to check if the template exists besides trying to instantiate it.. - try - { - var template = new businesslogic.template.Template(_document.Template); - // If template is found check if it's in the list of allowed templates for this document - return _document.Content.ContentType.AllowedTemplates.ToList().Any(t => t.Id == template.Id); - } - catch (Exception) { } - - return false; - } - - /// - /// JsInclude1 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude1; - - /// - /// JsInclude2 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude2; - - /// - /// JsInclude3 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude3; - - /// - /// plc control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.PlaceHolder plc; - - /// - /// doSave control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.HtmlControls.HtmlInputHidden doSave; - - /// - /// doPublish control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.HtmlControls.HtmlInputHidden doPublish; - - } -} diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/editMedia.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/editMedia.aspx.cs deleted file mode 100644 index 0245097ce5..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/editMedia.aspx.cs +++ /dev/null @@ -1,191 +0,0 @@ -using System; -using System.Web.UI; -using System.Web.UI.WebControls; -using System.Xml; -using Umbraco.Core; -using umbraco.cms.businesslogic.datatype.controls; -using System.Collections.Generic; -using System.Linq; -using System.IO; -using Umbraco.Core.IO; -using umbraco.cms.businesslogic.property; -using Umbraco.Core; - -namespace umbraco.cms.presentation -{ - /// - /// Summary description for editMedia. - /// - public partial class editMedia : BasePages.UmbracoEnsuredPage - { - private readonly uicontrols.Pane _mediaPropertiesPane = new uicontrols.Pane(); - private readonly LiteralControl _updateDateLiteral = new LiteralControl(); - private readonly LiteralControl _mediaFileLinksLiteral = new LiteralControl(); - - public editMedia() - { - CurrentApp = BusinessLogic.DefaultApps.media.ToString(); - } - - protected uicontrols.TabView TabView1; - protected TextBox documentName; - private businesslogic.media.Media _media; - controls.ContentControl _contentControl; - - override protected void OnInit(EventArgs e) - { - base.OnInit(e); - - int id = int.Parse(Request.QueryString["id"]); - - //Loading Media via new public service to ensure that the Properties are loaded correct - var media = ApplicationContext.Current.Services.MediaService.GetById(id); - _media = new cms.businesslogic.media.Media(media); - - // Save media on first load - bool exists = SqlHelper.ExecuteScalar("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); - - //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); - - _contentControl.Save += new System.EventHandler(Save); - - 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); - - // add the property pane to the page rendering - _contentControl.tpProp.Controls.AddAt(1, _mediaPropertiesPane); - } - - protected void Page_Load(object sender, System.EventArgs e) - { - if (!IsPostBack) - { - ClientTools.SyncTree(_media.Path, false); - } - } - - protected void Save(object sender, EventArgs e) - { - // 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 _contentControl.GetPanels()) - { - tp.ErrorControl.Visible = true; - tp.ErrorHeader = ui.Text("errorHandling", "errorHeader"); - tp.CloseCaption = ui.Text("close"); - } - } - else - { - if (Page.IsPostBack) - { - // hide validation summaries - foreach (uicontrols.TabPage tp in _contentControl.GetPanels()) - { - tp.ErrorControl.Visible = false; - } - } - - //The value of the properties has been set on IData through IDataEditor in the ContentControl - //so we need to 'retrieve' that value and set it on the property of the new IContent object. - //NOTE This is a workaround for the legacy approach to saving values through the DataType instead of the Property - //- (The DataType shouldn't be responsible for saving the value - especically directly to the db). - foreach (var item in _contentControl.DataTypes) - { - _media.getProperty(item.Key).Value = item.Value.Data.Value; - } - - _media.Save(); - - 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 = DataTypesResolver.Current.GetById(new Guid(Constants.PropertyEditors.UploadField)); - - // always clear, incase the upload file was removed - this._mediaFileLinksLiteral.Text = string.Empty; - - try - { - var uploadProperties = _media.GenericProperties - .Where(p => p.PropertyType.DataTypeDefinition.DataType.Id == uploadField.Id - && p.Value.ToString() != "" - && File.Exists(IOHelper.MapPath(p.Value.ToString()))); - - var properties = uploadProperties as List ?? uploadProperties.ToList(); - - if (properties.Any()) - { - this._mediaFileLinksLiteral.Text += ""; - - foreach (var property in properties) - { - this._mediaFileLinksLiteral.Text += string.Format("", property.PropertyType.Name, property.Value); - } - - this._mediaFileLinksLiteral.Text += "
    {0} {1}
    "; - } - } - catch - { - //the data type definition may not exist anymore at this point because another thread may - //have deleted it. - } - } - - /// - /// plc control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.PlaceHolder plc; - - /// - /// doSave control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.HtmlControls.HtmlInputHidden doSave; - - /// - /// doPublish control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.HtmlControls.HtmlInputHidden doPublish; - } -} diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/login.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/login.aspx.cs deleted file mode 100644 index f5bb290d47..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/login.aspx.cs +++ /dev/null @@ -1,307 +0,0 @@ -using System; -using System.Collections; -using System.ComponentModel; -using System.Data; -using System.Drawing; -using System.Globalization; -using System.Security; -using System.Web; -using System.Web.SessionState; -using System.Web.UI; -using System.Web.UI.WebControls; -using System.Web.UI.HtmlControls; -using Umbraco.Core.Configuration; -using Umbraco.Core.Logging; -using Umbraco.Core.Models.Membership; -using System.Web.Security; -using umbraco.businesslogic.Exceptions; -using umbraco.IO; -using umbraco.cms.businesslogic.web; -using System.Linq; -using Umbraco.Core; -using User = umbraco.BusinessLogic.User; - -namespace umbraco.cms.presentation -{ - /// - /// Summary description for login. - /// - [Obsolete("This class is no longer used and will be removed")] - public partial class login : BasePages.BasePage - { - [Obsolete("This property is no longer used")] - protected umbWindow treeWindow; - - protected override void OnLoad(EventArgs e) - { - base.OnLoad(e); - ClientLoader.DataBind(); - - // validate redirect url - string redirUrl = Request["redir"]; - if (!String.IsNullOrEmpty(redirUrl)) - { - validateRedirectUrl(redirUrl); - } - } - - - protected override void OnPreRender(EventArgs e) - { - base.OnPreRender(e); - Button1.Text = ui.Text("general", "login"); - Panel1.Text = ui.Text("general", "welcome"); - Panel1.Style.Add("padding", "10px;"); - username.Text = ui.Text("general", "username"); - password.Text = ui.Text("general", "password"); - - // Add bottom and top texts - TopText.Text = ui.Text("login", "topText"); - - - BottomText.Text = ui.Text("login", "bottomText", DateTime.Now.Year.ToString(CultureInfo.InvariantCulture)); - - //added this little hack to remove unessary formatting, without breaking all current language files. - if (BottomText.Text.Contains("

    ")) - BottomText.Text = BottomText.Text.Substring(29).Replace("
    ", "").Replace("

    ", ""); - } - - - protected void Button1_Click(object sender, System.EventArgs e) - { - // Authenticate users by using the provider specified in umbracoSettings.config - if (Membership.Providers[UmbracoConfig.For.UmbracoSettings().Providers.DefaultBackOfficeUserProvider].ValidateUser(lname.Text, passw.Text)) - { - if (Membership.Providers[UmbracoConfig.For.UmbracoSettings().Providers.DefaultBackOfficeUserProvider] is ActiveDirectoryMembershipProvider) - ActiveDirectoryMapping(lname.Text, Membership.Providers[UmbracoConfig.For.UmbracoSettings().Providers.DefaultBackOfficeUserProvider].GetUser(lname.Text, false).Email); - - var u = new User(lname.Text); - doLogin(u); - - if (hf_height.Value != "undefined") - { - Session["windowHeight"] = hf_height.Value; - Session["windowWidth"] = hf_width.Value; - } - - string redirUrl = Request["redir"]; - - if (string.IsNullOrEmpty(redirUrl)) - Response.Redirect("umbraco.aspx"); - else if (validateRedirectUrl(redirUrl)) - { - Response.Redirect(redirUrl, true); - } - } - else - { - loginError.Visible = true; - } - } - - private bool validateRedirectUrl(string url) - { - if (!isUrlLocalToHost(url)) - { - LogHelper.Info(String.Format("Security warning: Login redirect was attempted to a site at another domain: '{0}'", url)); - - throw new UserAuthorizationException( - String.Format(@"There was attempt to redirect to '{0}' which is another domain than where you've logged in. If you clicked a link to reach this login - screen, please double check that the link came from someone you trust. You *might* have been exposed to an *attempt* to breach the security of your website. Nothing - have been compromised, though!", url)); - } - - return true; - } - - private bool isUrlLocalToHost(string url) - { - if (String.IsNullOrEmpty(url)) - { - return false; - } - - Uri absoluteUri; - if (Uri.TryCreate(url, UriKind.Absolute, out absoluteUri)) - { - return String.Equals(HttpContext.Current.Request.Url.Host, absoluteUri.Host, - StringComparison.OrdinalIgnoreCase); - } - - bool isLocal = !url.StartsWith("http:", StringComparison.OrdinalIgnoreCase) - && !url.StartsWith("https:", StringComparison.OrdinalIgnoreCase) - && Uri.IsWellFormedUriString(url, UriKind.Relative); - return isLocal; - } - - /// - /// Maps active directory account to umbraco user account - /// - /// Name of the login. - /// Email address of the user - private void ActiveDirectoryMapping(string loginName, string email) - { - // Password is not copied over because it is stored in active directory for security! - // The user is create with default access to content and as a writer user type - if (BusinessLogic.User.getUserId(loginName) == -1) - { - BusinessLogic.User.MakeNew(loginName, loginName, string.Empty, email ?? "", BusinessLogic.UserType.GetUserType(2)); - var u = new User(loginName); - u.addApplication(Constants.Applications.Content); - } - } - - /// - /// ClientLoader control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::umbraco.uicontrols.UmbracoClientDependencyLoader ClientLoader; - - /// - /// CssInclude1 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.CssInclude CssInclude1; - - /// - /// JsInclude1 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude1; - - /// - /// JsInclude3 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude3; - - /// - /// JsInclude2 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude2; - - /// - /// Form1 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.HtmlControls.HtmlForm Form1; - - /// - /// Panel1 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::umbraco.uicontrols.UmbracoPanel Panel1; - - /// - /// TopText control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.Literal TopText; - - /// - /// username control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.Label username; - - /// - /// lname control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.TextBox lname; - - /// - /// password control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.Label password; - - /// - /// passw control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.TextBox passw; - - /// - /// Button1 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.Button Button1; - - /// - /// BottomText control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.Literal BottomText; - - /// - /// hf_height control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.HiddenField hf_height; - - /// - /// hf_width control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.HiddenField hf_width; - - /// - /// loginError control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.PlaceHolder loginError; - } -} diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/logout.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/logout.aspx.cs deleted file mode 100644 index 15f8be030f..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/logout.aspx.cs +++ /dev/null @@ -1,28 +0,0 @@ -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; - -namespace umbraco -{ - /// - /// Summary description for logout. - /// - public partial class logout : BasePages.BasePage - { - protected void Page_Load(object sender, System.EventArgs e) - { - // Put user code to initialize the page here - if (umbracoUserContextID != "") - base.ClearLogin(); - } - - protected System.Web.UI.HtmlControls.HtmlForm Form1; - } -} diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/timerModule.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/timerModule.cs deleted file mode 100644 index 2f747cf79d..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/timerModule.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System.Data; -using System.Threading; -using System.Web; -using Umbraco.Core.Logging; -using umbraco.BusinessLogic; - -namespace umbraco -{ - /// - /// Summary description for timerModule. - /// - public class timerModule : IHttpModule - { - protected Timer t; - - #region IHttpModule Members - - public void Init(HttpApplication context) - { - LogHelper.Debug("timer init"); - - t = new Timer(new TimerCallback(this.doStuff), context.Context, 1000, 1000); - } - - private void doStuff(object sender) - { - LogHelper.Debug("timer ping"); - } - - public void Dispose() - { - if(t != null) - t.Dispose(); - t = null; - } - - #endregion - } -} \ No newline at end of file diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/umbWindow.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/umbWindow.cs deleted file mode 100644 index 4094c4fe2f..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/umbWindow.cs +++ /dev/null @@ -1,148 +0,0 @@ -using System; -using System.Web.UI; -using System.Web.UI.WebControls; -using System.ComponentModel; - -namespace umbraco -{ - /// - /// Summary description for umbWindow. - /// - [DefaultProperty("Text"), ToolboxData("<{0}:umbWindow runat=server>")] - [Obsolete("This class is no longer used and will be removed from the codebase in future versions")] - public class umbWindow : System.Web.UI.WebControls.PlaceHolder - { - private string content; - private string windowName; - private int width; - private int height; - private string margin; - private bool scroll; - private bool bottomLabel = false; - private string imageUrlPreFix = ""; - private string label; - - [Bindable(true), - Category("Umbraco"), - DefaultValue("")] - public string ImageUrlPreFix - { - get {return imageUrlPreFix;} - set {imageUrlPreFix = value;} - } - - [Bindable(true), - Category("Appearance"), - DefaultValue("")] - public string Content - { - get {return content;} - set {content = value;} - } - [Bindable(true), - Category("Appearance"), - DefaultValue("")] - public int Height - { - get {return height;} - set {height = value;} - } - [Bindable(true), - Category("Appearance"), - DefaultValue("")] - public int Width - { - get {return width;} - set {width = value;} - } - [Bindable(true), - Category("Appearance"), - DefaultValue("")] - public string Margin - { - get {return margin;} - set {margin = value;} - } - [Bindable(true), - Category("Appearance"), - DefaultValue("")] - public string Label - { - get {return label;} - set {label = value;} - } - [Bindable(true), - Category("Appearance"), - DefaultValue("")] - public bool Scroll - { - get {return scroll;} - set {scroll = value;} - } - [Bindable(true), - Category("Appearance"), - DefaultValue("")] - public bool ShowBottomLabel - { - get {return bottomLabel;} - set {bottomLabel = value;} - } - [Bindable(true), - Category("Appearance"), - DefaultValue("")] - public string WindowName - { - get {return windowName;} - set {windowName = value;} - } - - protected override void Render(HtmlTextWriter output) - { - output.Write( - "
    " + - "" + - "" + - "" + - "" + - "" + - "
    \"\"\"\"
    " + label + "
    \"\"
    " + - - "" + - "" + - "" + - "" + - " " + - "" + - "
    "); - if (scroll) - output.Write( - "
    "); - else - output.Write( - "
    "); - - base.RenderChildren(output); - output.Write( - "
    " + - "
    " + - - " " + - ""); - - if (bottomLabel) - output.Write( - "" + - "" + - ""); - else - output.Write( - "" + - "" + - ""); - - output.Write( - "" + - "
    \"\"" + label + "\"\"\"\"\"\"
    "); - } - } -} diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/umbraco.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/umbraco.aspx.cs deleted file mode 100644 index 223cedccb3..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/umbraco.aspx.cs +++ /dev/null @@ -1,460 +0,0 @@ -using System; -using System.Collections; -using System.ComponentModel; -using System.Data; -using System.Drawing; -using System.IO; -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.BasePages; -using System.Xml; -using System.Xml.XPath; -using umbraco.BusinessLogic.Actions; -using ClientDependency.Core; -using System.Linq; -using System.Text; -using ClientDependency.Core.Controls; -using System.Text.RegularExpressions; - -namespace umbraco.cms.presentation -{ - /// - /// The back office rendering page - /// - public class _umbraco : UmbracoEnsuredPage - { - [Obsolete("This property is no longer used")] - protected umbWindow UmbWindow1; - protected System.Web.UI.WebControls.PlaceHolder bubbleText; - - public string DefaultApp { get; private set; } - - protected void Page_Load(object sender, System.EventArgs e) - { - var apps = UmbracoUser.Applications.ToList(); - bool userHasAccesstodefaultApp = apps.Where(x => x.alias == Umbraco.Core.Constants.Applications.Content).Count() > 0; - - // Load user module icons .. - if (apps.Count() > 1) - { - - var jsEvents = new StringBuilder(); - - PlaceHolderAppIcons.Text = ui.Text("main", "sections", UmbracoUser); - plcIcons.Text = ""; - foreach (var a in apps.OrderBy(x => x.sortOrder)) - { - - string appClass = a.icon.StartsWith(".") ? a.icon.Substring(1, a.icon.Length - 1) : a.alias; - - //adds client side event handlers to the icon buttons - jsEvents.Append(@"jQuery('." + appClass + "').click(function() { appClick.call(this, '" + a.alias + "'); } );"); - jsEvents.Append(@"jQuery('." + appClass + "').dblclick(function() { appDblClick.call(this, '" + a.alias + "'); } );"); - - string iconElement = String.Format("
  • ", appClass); - if (a.icon.StartsWith(".")) - iconElement += - "\"\"
  • "; - else - iconElement += "\"""; - plcIcons.Text += iconElement; - - } - - //registers the jquery event handlers. - Page.ClientScript.RegisterStartupScript(this.GetType(), "AppIcons", "jQuery(document).ready(function() { " + jsEvents.ToString() + " } );", true); - - } - else - PlaceHolderAppIcons.Visible = false; - - - //if user does not have access to content (ie, he's probably a translator)... - //then change the default tree app - if (!userHasAccesstodefaultApp) - { - JTree.App = apps[0].alias; - DefaultApp = apps[0].alias; - } - else - { - DefaultApp = Umbraco.Core.Constants.Applications.Content; - } - - - // Load globalized labels - treeWindow.Text = ui.Text("main", "tree", UmbracoUser); - - RenderActionJS(); - - // Version check goes here! - - // zb-00004 #29956 : refactor cookies names & handling - var updChkCookie = new umbraco.BusinessLogic.StateHelper.Cookies.Cookie("UMB_UPDCHK", GlobalSettings.VersionCheckPeriod); // was "updateCheck" - string updateCheckCookie = updChkCookie.HasValue ? updChkCookie.GetValue() : ""; - - if (GlobalSettings.VersionCheckPeriod > 0 && String.IsNullOrEmpty(updateCheckCookie) && UmbracoUser.UserType.Alias == "admin") - { - - // Add scriptmanager version check - ScriptManager sm = ScriptManager.GetCurrent(Page); - sm.Scripts.Add(new ScriptReference(SystemDirectories.Umbraco + "/js/umbracoUpgradeChecker.js")); - sm.Services.Add(new ServiceReference(SystemDirectories.WebServices + "/CheckForUpgrade.asmx")); - - Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "upgradeChecker", "jQuery(document).ready(function() {umbraco.presentation.webservices.CheckForUpgrade.CallUpgradeService(umbracoCheckUpgrade);});", true); - - updChkCookie.SetValue("1"); - } - DataBind(); - - AddIe9Meta(); - } - - private void AddIe9Meta() - { - if (Request.Browser.Browser == "IE" && Request.Browser.MajorVersion == 9) - { - StringBuilder metadata = new StringBuilder(); - metadata.AppendFormat( - @" - - - - - ", - IOHelper.ResolveUrl(SystemDirectories.Umbraco + "/images/pinnedIcons/umb.ico"), - HttpContext.Current.Request.Url.Host.ToLower().Replace("www.", "")); - - var user = UmbracoUser; - if (user != null && user.Applications != null && user.Applications.Length > 0) - { - foreach (var app in user.Applications) - { - metadata.AppendFormat( - @"", - ui.Text("sections", app.alias, user), - IOHelper.ResolveUrl(string.Format("{0}/umbraco.aspx#{1}", SystemDirectories.Umbraco, app.alias)), - File.Exists( - IOHelper.MapPath( - IOHelper.ResolveUrl( - string.Format("{0}/images/pinnedIcons/task_{1}.ico", SystemDirectories.Umbraco, app.alias)))) - ? "/umbraco/images/pinnedIcons/task_" + app.alias + ".ico" - : "/umbraco/images/pinnedIcons/task_default.ico"); - } - } - - this.Header.Controls.Add(new LiteralControl(metadata.ToString())); - } - } - - /// - /// Renders out all JavaScript references that have bee declared in IActions - /// - private void RenderActionJS() - { - var item = 0; - foreach (var jsFile in umbraco.BusinessLogic.Actions.Action.GetJavaScriptFileReferences()) - { - //validate that this is a url, if it is not, we'll assume that it is a text block and render it as a text - //block instead. - var isValid = true; - try - { - var jsUrl = new Uri(jsFile, UriKind.RelativeOrAbsolute); - //ok it validates, but so does alert('hello'); ! so we need to do more checks - - //here are the valid chars in a url without escaping - if (Regex.IsMatch(jsFile, @"[^a-zA-Z0-9-._~:/?#\[\]@!$&'\(\)*\+,%;=]")) - isValid = false; - - //we'll have to be smarter and just check for certain js patterns now too! - var jsPatterns = new string[] { @"\+\s*\=", @"\);", @"function\s*\(", @"!=", @"==" }; - foreach (var p in jsPatterns) - { - if (Regex.IsMatch(jsFile, p)) - { - isValid = false; - break; - } - } - - if (isValid) - { - //add to page - Page.ClientScript.RegisterClientScriptInclude(this.GetType(), item.ToString(), jsFile); - } - } - catch (UriFormatException) - { - isValid = false; - } - - if (!isValid) - { - //it is invalid, let's render it as a script block instead as devs may have written real Javascript instead - //of a JS path - Page.ClientScript.RegisterClientScriptBlock(this.GetType(), item.ToString(), jsFile, true); - } - - item++; - } - } - - /// - /// ClientLoader control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::umbraco.uicontrols.UmbracoClientDependencyLoader ClientLoader; - - /// - /// CssInclude1 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.CssInclude CssInclude1; - - /// - /// CssInclude2 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.CssInclude CssInclude2; - - /// - /// JsInclude1 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude1; - - /// - /// JsInclude2 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude2; - - /// - /// JsInclude3 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude3; - - /// - /// JsInclude14 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude14; - - /// - /// JsInclude5 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude5; - - /// - /// JsInclude6 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude6; - - /// - /// JsInclude13 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude13; - - /// - /// JsInclude7 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude7; - - /// - /// JsInclude8 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude8; - - /// - /// JsInclude9 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude9; - - /// - /// JsInclude10 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude10; - - /// - /// JsInclude11 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude11; - - /// - /// JsInclude4 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude4; - - /// - /// JsInclude17 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude17; - - /// - /// JsInclude12 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude12; - - /// - /// JsInclude15 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude15; - - /// - /// JsInclude16 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude16; - - /// - /// Form1 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.HtmlControls.HtmlForm Form1; - - /// - /// umbracoScriptManager control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.ScriptManager umbracoScriptManager; - - /// - /// FindDocuments control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.Panel FindDocuments; - - /// - /// Search control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::umbraco.presentation.Search.QuickSearch Search; - - /// - /// treeWindow control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::umbraco.uicontrols.UmbracoPanel treeWindow; - - /// - /// JTree control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::umbraco.controls.Tree.TreeControl JTree; - - /// - /// PlaceHolderAppIcons control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::umbraco.uicontrols.UmbracoPanel PlaceHolderAppIcons; - - /// - /// plcIcons control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.Literal plcIcons; - - } -} diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/users/EditUser.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/users/EditUser.aspx.cs index 1901515fdf..cc26cdbd91 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/users/EditUser.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/users/EditUser.aspx.cs @@ -69,8 +69,7 @@ namespace umbraco.cms.presentation.user { throw new UserAuthorizationException("Access denied"); } - - int UID = int.Parse(Request.QueryString["id"]); + int UID = int.Parse(Request.QueryString["id"]); u = BusinessLogic.User.GetUser(UID); //the true admin can only edit the true admin