From bd3ad153d29bbe7555c63a7b1bb9b5e0ed098578 Mon Sep 17 00:00:00 2001 From: Rasmus Fjord Date: Mon, 26 Sep 2016 11:05:15 +0200 Subject: [PATCH 01/49] bah --- .hgignore | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 .hgignore diff --git a/.hgignore b/.hgignore new file mode 100644 index 0000000000..13307d790b --- /dev/null +++ b/.hgignore @@ -0,0 +1,58 @@ +syntax: glob +*.obj +*.exe +*.pdb +*.user +*.aps +*.pch +*.vspscc +[Bb]in +[Db]ebug*/ +obj/ +[Rr]elease*/ +_ReSharper*/ +*.ncrunchsolution +*.ncrunchsolution.user +*.ncrunchproject +*.crunchsolution.cache +[Tt]est[Rr]esult* +[Bb]uild[Ll]og.* +*.[Pp]ublish.xml +*.suo +[sS]ource +[sS]andbox +umbraco.config +*.vs10x +App_Data\TEMP\* +umbraco\presentation\umbraco\plugins\* +umbraco\presentation\usercontrols\* +umbraco\presentation\scripts\* +umbraco\presentation\fonts\* +umbraco\presentation\css\* + +src\Umbraco.Web.UI\css\* +src\Umbraco.Web.UI\App_Code\* +src\Umbraco.Web.UI\App_Data\* +src\Umbraco.Tests\App_Data\* +src\Umbraco.Web.UI\media\* +src\Umbraco.Web.UI\masterpages\* +src\Umbraco.Web.UI\macroScripts\* +src\Umbraco.Web.UI\xslt\* +umbraco\presentation\umbraco\plugins\uComponents\uComponentsInstaller.ascx +umbraco\presentation\packages\uComponents\MultiNodePicker\CustomTreeService.asmx +_BuildOutput/* +*.ncrunchsolution +build/UmbracoCms.AllBinaries.zip +build/UmbracoCms.WebPI.zip +build/UmbracoCms.zip +build/*.nupkg +src/Umbraco.Tests/config/applications.config +src/Umbraco.Tests/config/trees.config +src/Umbraco.Web.UI/web.config +*.orig +src/Umbraco.Tests/config/404handlers.config +src/Umbraco.Web.UI/Views/*.cshtml +src/Umbraco.Web.UI/Views/*.vbhtml +src/Umbraco.Tests/config/umbracoSettings.config +src/Umbraco.Web.UI/App_Plugins/* +src/Umbraco.Web.UI/Views/* From 221354a7d8c2bcb41646c56fe3602e8a57b90152 Mon Sep 17 00:00:00 2001 From: Claus Date: Thu, 27 Oct 2016 10:47:32 +0200 Subject: [PATCH 02/49] U4-9104 Update the UmbracoExamine logic for Media to read the data directly from the umbracoXml table. updated some tests to use the testbehavior attribute so they dont rely on being run in a specific order. --- .../Interfaces/IMediaRepository.cs | 10 ++ .../Repositories/MediaRepository.cs | 24 ++++ src/Umbraco.Core/Services/IMediaService.cs | 14 ++ src/Umbraco.Core/Services/MediaService.cs | 21 +++ .../LegacyExamineBackedMediaTests.cs | 1 + .../UmbracoExamine/EventsTest.cs | 4 +- .../UmbracoExamine/IndexInitializer.cs | 60 ++++++-- src/Umbraco.Tests/UmbracoExamine/IndexTest.cs | 13 +- .../UmbracoExamine/SearchTests.cs | 2 + src/UmbracoExamine/UmbracoContentIndexer.cs | 130 +++++++++--------- 10 files changed, 193 insertions(+), 86 deletions(-) diff --git a/src/Umbraco.Core/Persistence/Repositories/Interfaces/IMediaRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Interfaces/IMediaRepository.cs index 907f9b62c5..64989f9269 100644 --- a/src/Umbraco.Core/Persistence/Repositories/Interfaces/IMediaRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/Interfaces/IMediaRepository.cs @@ -38,5 +38,15 @@ namespace Umbraco.Core.Persistence.Repositories /// An Enumerable list of objects IEnumerable GetPagedResultsByQuery(IQuery query, long pageIndex, int pageSize, out long totalRecords, string orderBy, Direction orderDirection, bool orderBySystemField, string filter = ""); + + /// + /// Gets paged media descendants as XML by path + /// + /// Path starts with + /// Page number + /// Page size + /// Total records the query would return without paging + /// A paged enumerable of XML entries of media items + IEnumerable GetPagedXmlEntriesByPath(string path, long pageIndex, int pageSize, out long totalRecords); } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Repositories/MediaRepository.cs b/src/Umbraco.Core/Persistence/Repositories/MediaRepository.cs index 598c9e912d..7a6fa4c34e 100644 --- a/src/Umbraco.Core/Persistence/Repositories/MediaRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/MediaRepository.cs @@ -465,6 +465,30 @@ namespace Umbraco.Core.Persistence.Repositories } + /// + /// Gets paged media descendants as XML by path + /// + /// Path starts with + /// Page number + /// Page size + /// Total records the query would return without paging + /// A paged enumerable of XML entries of media items + public IEnumerable GetPagedXmlEntriesByPath(string path, long pageIndex, int pageSize, out long totalRecords) + { + Sql query; + if (path == "-1") + { + query = new Sql().Select("nodeId, xml").From("cmsContentXml").Where("nodeId IN (SELECT id FROM umbracoNode WHERE nodeObjectType = @0)", Guid.Parse(Constants.ObjectTypes.Media)).OrderBy("nodeId"); + } + else + { + query = new Sql().Select("nodeId, xml").From("cmsContentXml").Where("nodeId IN (SELECT id FROM umbracoNode WHERE path LIKE @0)", path.EnsureEndsWith(",%")).OrderBy("nodeId"); + } + var pagedResult = Database.Page(pageIndex+1, pageSize, query); + totalRecords = pagedResult.TotalItems; + return pagedResult.Items.Select(dto => XElement.Parse(dto.Xml)); + } + private IEnumerable ProcessQuery(Sql sql) { //NOTE: This doesn't allow properties to be part of the query diff --git a/src/Umbraco.Core/Services/IMediaService.cs b/src/Umbraco.Core/Services/IMediaService.cs index 6ff8f75402..d25ddf7f58 100644 --- a/src/Umbraco.Core/Services/IMediaService.cs +++ b/src/Umbraco.Core/Services/IMediaService.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.ComponentModel; +using System.Xml.Linq; using Umbraco.Core.Configuration; using Umbraco.Core.Models; using Umbraco.Core.Persistence.DatabaseModelDefinitions; @@ -57,6 +58,19 @@ namespace Umbraco.Core.Services /// public interface IMediaService : IService { + /// + /// Gets all XML entries found in the cmsContentXml table based on the given path + /// + /// Path starts with + /// Page number + /// Page size + /// Total records the query would return without paging + /// A paged enumerable of XML entries of media items + /// + /// If -1 is passed, then this will return all media xml entries, otherwise will return all descendents from the path + /// + IEnumerable GetPagedXmlEntries(string path, long pageIndex, int pageSize, out long totalRecords); + /// /// Rebuilds all xml content in the cmsContentXml table for all media /// diff --git a/src/Umbraco.Core/Services/MediaService.cs b/src/Umbraco.Core/Services/MediaService.cs index 29235cc7ab..a1182ce80a 100644 --- a/src/Umbraco.Core/Services/MediaService.cs +++ b/src/Umbraco.Core/Services/MediaService.cs @@ -1199,6 +1199,27 @@ namespace Umbraco.Core.Services return true; } + /// + /// Gets paged media descendants as XML by path + /// + /// Path starts with + /// Page number + /// Page size + /// Total records the query would return without paging + /// A paged enumerable of XML entries of media items + public IEnumerable GetPagedXmlEntries(string path, long pageIndex, int pageSize, out long totalRecords) + { + Mandate.ParameterCondition(pageIndex >= 0, "pageIndex"); + Mandate.ParameterCondition(pageSize > 0, "pageSize"); + + var uow = UowProvider.GetUnitOfWork(); + using (var repository = RepositoryFactory.CreateMediaRepository(uow)) + { + var contents = repository.GetPagedXmlEntriesByPath(path, pageIndex, pageSize, out totalRecords); + return contents; + } + } + /// /// Rebuilds all xml content in the cmsContentXml table for all media /// diff --git a/src/Umbraco.Tests/PublishedContent/LegacyExamineBackedMediaTests.cs b/src/Umbraco.Tests/PublishedContent/LegacyExamineBackedMediaTests.cs index 8a83bea75a..5bf6a4edc5 100644 --- a/src/Umbraco.Tests/PublishedContent/LegacyExamineBackedMediaTests.cs +++ b/src/Umbraco.Tests/PublishedContent/LegacyExamineBackedMediaTests.cs @@ -13,6 +13,7 @@ using Umbraco.Core.Persistence.Mappers; namespace Umbraco.Tests.PublishedContent { + [DatabaseTestBehavior(DatabaseBehavior.NewDbFileAndSchemaPerTest)] public class LegacyExamineBackedMediaTests : ExamineBaseTest { public override void Initialize() diff --git a/src/Umbraco.Tests/UmbracoExamine/EventsTest.cs b/src/Umbraco.Tests/UmbracoExamine/EventsTest.cs index 6bd01c7f1c..3e7377f3b6 100644 --- a/src/Umbraco.Tests/UmbracoExamine/EventsTest.cs +++ b/src/Umbraco.Tests/UmbracoExamine/EventsTest.cs @@ -3,11 +3,13 @@ using System.Linq; using Examine; using Lucene.Net.Store; using NUnit.Framework; +using Umbraco.Tests.TestHelpers; using UmbracoExamine; namespace Umbraco.Tests.UmbracoExamine { - [TestFixture] + [DatabaseTestBehavior(DatabaseBehavior.NewDbFileAndSchemaPerTest)] + [TestFixture] public class EventsTest : ExamineBaseTest { [Test] diff --git a/src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs b/src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs index b303eed997..89a9df8052 100644 --- a/src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs +++ b/src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs @@ -1,5 +1,7 @@ using System; +using System.Collections.Generic; using System.Linq; +using System.Xml.Linq; using Examine; using Examine.LuceneEngine.Config; using Examine.LuceneEngine.Providers; @@ -7,10 +9,14 @@ using Lucene.Net.Analysis; using Lucene.Net.Analysis.Standard; using Lucene.Net.Store; using Moq; +using Umbraco.Core; +using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Core.Models.Membership; +using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.DatabaseModelDefinitions; using Umbraco.Core.Persistence.Querying; +using Umbraco.Core.Persistence.SqlSyntax; using Umbraco.Core.Services; using UmbracoExamine; using UmbracoExamine.Config; @@ -34,7 +40,8 @@ namespace Umbraco.Tests.UmbracoExamine IMediaService mediaService = null, IDataTypeService dataTypeService = null, IMemberService memberService = null, - IUserService userService = null) + IUserService userService = null, + IContentTypeService contentTypeService = null) { if (dataService == null) { @@ -94,7 +101,8 @@ namespace Umbraco.Tests.UmbracoExamine long longTotalRecs; int intTotalRecs; - var allRecs = dataService.MediaService.GetLatestMediaByXpath("//node") + var mediaXml = dataService.MediaService.GetLatestMediaByXpath("//node"); + var allRecs = mediaXml .Root .Elements() .Select(x => Mock.Of( @@ -114,20 +122,29 @@ namespace Umbraco.Tests.UmbracoExamine mt.Id == (int)x.Attribute("nodeType")))) .ToArray(); + // MOCK! + var mediaServiceMock = new Mock(); + + mediaServiceMock + .Setup(x => x.GetPagedDescendants( + It.IsAny(), It.IsAny(), It.IsAny(), out longTotalRecs, It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny()) + ).Returns(() => allRecs); + + mediaServiceMock + .Setup(x => x.GetPagedDescendants( + It.IsAny(), It.IsAny(), It.IsAny(), out longTotalRecs, It.IsAny(), It.IsAny(), It.IsAny()) + ).Returns(() => allRecs); + + mediaServiceMock + .Setup(x => x.GetPagedDescendants( + It.IsAny(), It.IsAny(), It.IsAny(), out intTotalRecs, It.IsAny(), It.IsAny(), It.IsAny()) + ).Returns(() => allRecs); + + mediaServiceMock.Setup(service => service.GetPagedXmlEntries(It.IsAny(), It.IsAny(), It.IsAny(), out longTotalRecs)) + .Returns(() => allRecs.Select(x => x.ToXml())); + + mediaService = mediaServiceMock.Object; - mediaService = Mock.Of( - x => x.GetPagedDescendants( - It.IsAny(), It.IsAny(), It.IsAny(), out longTotalRecs, It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny()) - == - allRecs - && x.GetPagedDescendants( - It.IsAny(), It.IsAny(), It.IsAny(), out longTotalRecs, It.IsAny(), It.IsAny(), It.IsAny()) - == - allRecs - && x.GetPagedDescendants( - It.IsAny(), It.IsAny(), It.IsAny(), out intTotalRecs, It.IsAny(), It.IsAny(), It.IsAny()) - == - allRecs); } if (dataTypeService == null) { @@ -139,6 +156,18 @@ namespace Umbraco.Tests.UmbracoExamine memberService = Mock.Of(); } + if (contentTypeService == null) + { + var contentTypeServiceMock = new Mock(); + contentTypeServiceMock.Setup(x => x.GetAllContentTypes()) + .Returns(new List() + { + new ContentType(-1) {Alias = "Folder", Name = "Folder", Id = 1031, Icon = "icon-folder"}, + new ContentType(-1) {Alias = "Image", Name = "Image", Id = 1032, Icon = "icon-picture"} + }); + contentTypeService = contentTypeServiceMock.Object; + } + if (analyzer == null) { analyzer = new StandardAnalyzer(Version.LUCENE_29); @@ -154,6 +183,7 @@ namespace Umbraco.Tests.UmbracoExamine mediaService, dataTypeService, userService, + contentTypeService, analyzer, false); diff --git a/src/Umbraco.Tests/UmbracoExamine/IndexTest.cs b/src/Umbraco.Tests/UmbracoExamine/IndexTest.cs index 7c36dd2953..3bc635bb23 100644 --- a/src/Umbraco.Tests/UmbracoExamine/IndexTest.cs +++ b/src/Umbraco.Tests/UmbracoExamine/IndexTest.cs @@ -10,15 +10,17 @@ using Lucene.Net.Index; using Lucene.Net.Search; using Lucene.Net.Store; using NUnit.Framework; +using Umbraco.Tests.TestHelpers; using UmbracoExamine; namespace Umbraco.Tests.UmbracoExamine { - /// - /// Tests the standard indexing capabilities - /// - [TestFixture, RequiresSTA] + /// + /// Tests the standard indexing capabilities + /// + //[DatabaseTestBehavior(DatabaseBehavior.NewDbFileAndSchemaPerTest)] + [TestFixture, RequiresSTA] public class IndexTest : ExamineBaseTest { @@ -85,12 +87,11 @@ namespace Umbraco.Tests.UmbracoExamine //RESET the parent id existingCriteria = ((IndexCriteria)_indexer.IndexerData); _indexer.IndexerData = new IndexCriteria(existingCriteria.StandardFields, existingCriteria.UserFields, existingCriteria.IncludeNodeTypes, existingCriteria.ExcludeNodeTypes, - null); + null); //now ensure it's deleted var newResults = _searcher.Search(_searcher.CreateSearchCriteria().Id(2112).Compile()); Assert.AreEqual(1, newResults.Count()); - } [Test] diff --git a/src/Umbraco.Tests/UmbracoExamine/SearchTests.cs b/src/Umbraco.Tests/UmbracoExamine/SearchTests.cs index bcd9922e21..9b8b3d50d7 100644 --- a/src/Umbraco.Tests/UmbracoExamine/SearchTests.cs +++ b/src/Umbraco.Tests/UmbracoExamine/SearchTests.cs @@ -8,9 +8,11 @@ using Examine.LuceneEngine.Providers; using Lucene.Net.Store; using NUnit.Framework; using Examine.LuceneEngine.SearchCriteria; +using Umbraco.Tests.TestHelpers; namespace Umbraco.Tests.UmbracoExamine { + [DatabaseTestBehavior(DatabaseBehavior.NewDbFileAndSchemaPerTest)] [TestFixture] public class SearchTests : ExamineBaseTest { diff --git a/src/UmbracoExamine/UmbracoContentIndexer.cs b/src/UmbracoExamine/UmbracoContentIndexer.cs index 4fcf51deae..ce3583a6be 100644 --- a/src/UmbracoExamine/UmbracoContentIndexer.cs +++ b/src/UmbracoExamine/UmbracoContentIndexer.cs @@ -1,20 +1,12 @@ using System; -using System.Collections; using System.Collections.Generic; using System.Collections.Specialized; using System.IO; using System.Linq; -using System.Security; -using System.Text; -using System.Web; using System.Xml.Linq; using Examine; -using Examine.Config; -using Examine.Providers; using Lucene.Net.Documents; -using Lucene.Net.Index; using Umbraco.Core; -using umbraco.cms.businesslogic; using Umbraco.Core.Models; using Umbraco.Core.Persistence.DatabaseModelDefinitions; using Umbraco.Core.Services; @@ -22,12 +14,9 @@ using UmbracoExamine.DataServices; using Examine.LuceneEngine; using Examine.LuceneEngine.Config; using UmbracoExamine.Config; -using Examine.LuceneEngine.Providers; using Lucene.Net.Analysis; -using umbraco.BasePages; using Umbraco.Core.Persistence.Querying; using IContentService = Umbraco.Core.Services.IContentService; -using UmbracoExamine.LocalStorage; using IMediaService = Umbraco.Core.Services.IMediaService; @@ -42,6 +31,7 @@ namespace UmbracoExamine private readonly IMediaService _mediaService; private readonly IDataTypeService _dataTypeService; private readonly IUserService _userService; + private readonly IContentTypeService _contentTypeService; #region Constructors @@ -55,6 +45,7 @@ namespace UmbracoExamine _mediaService = ApplicationContext.Current.Services.MediaService; _dataTypeService = ApplicationContext.Current.Services.DataTypeService; _userService = ApplicationContext.Current.Services.UserService; + _contentTypeService = ApplicationContext.Current.Services.ContentTypeService; } /// @@ -73,6 +64,7 @@ namespace UmbracoExamine _mediaService = ApplicationContext.Current.Services.MediaService; _dataTypeService = ApplicationContext.Current.Services.DataTypeService; _userService = ApplicationContext.Current.Services.UserService; + _contentTypeService = ApplicationContext.Current.Services.ContentTypeService; } /// @@ -91,6 +83,7 @@ namespace UmbracoExamine _mediaService = ApplicationContext.Current.Services.MediaService; _dataTypeService = ApplicationContext.Current.Services.DataTypeService; _userService = ApplicationContext.Current.Services.UserService; + _contentTypeService = ApplicationContext.Current.Services.ContentTypeService; } /// @@ -105,6 +98,7 @@ namespace UmbracoExamine /// /// /// + [Obsolete("Use the overload that specifies the Umbraco services")] public UmbracoContentIndexer(IIndexCriteria indexerData, Lucene.Net.Store.Directory luceneDirectory, IDataService dataService, IContentService contentService, IMediaService mediaService, @@ -117,13 +111,43 @@ namespace UmbracoExamine _mediaService = mediaService; _dataTypeService = dataTypeService; _userService = userService; + _contentTypeService = ApplicationContext.Current.Services.ContentTypeService; + } + + /// + /// Constructor to allow for creating an indexer at runtime + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + public UmbracoContentIndexer(IIndexCriteria indexerData, Lucene.Net.Store.Directory luceneDirectory, IDataService dataService, + IContentService contentService, + IMediaService mediaService, + IDataTypeService dataTypeService, + IUserService userService, + IContentTypeService contentTypeService, + Analyzer analyzer, bool async) + : base(indexerData, luceneDirectory, dataService, analyzer, async) + { + _contentService = contentService; + _mediaService = mediaService; + _dataTypeService = dataTypeService; + _userService = userService; + _contentTypeService = contentTypeService; } #endregion #region Constants & Fields - + /// /// Used to store the path of a content object @@ -206,13 +230,8 @@ namespace UmbracoExamine SupportProtectedContent = supportProtected; else SupportProtectedContent = false; - - + base.Initialize(name, config); - - - - } #endregion @@ -285,10 +304,7 @@ namespace UmbracoExamine #endregion #region Public methods - - - /// /// Overridden for logging /// @@ -308,7 +324,6 @@ namespace UmbracoExamine { DataService.LogService.AddErrorLog(-1, string.Format("ReIndexNode cannot proceed, the format of the XElement is invalid, the xml has no 'id' attribute. {0}", node)); } - } /// @@ -355,8 +370,6 @@ namespace UmbracoExamine switch (type) { case IndexTypes.Content: - - var contentParentId = -1; if (IndexerData.ParentNodeId.HasValue && IndexerData.ParentNodeId.Value > 0) { @@ -391,69 +404,63 @@ namespace UmbracoExamine { content = descendants.ToArray(); } - AddNodesToIndex(GetSerializedContent(content), type); pageIndex++; - - } while (content.Length == pageSize); break; case IndexTypes.Media: - var mediaParentId = -1; + if (IndexerData.ParentNodeId.HasValue && IndexerData.ParentNodeId.Value > 0) { mediaParentId = IndexerData.ParentNodeId.Value; } - IMedia[] media; + XElement[] mediaXElements; + + var nodeTypes = _contentTypeService.GetAllContentTypes().ToArray(); + var icons = nodeTypes.ToDictionary(x => x.Id, y => y.Icon); + do { long total; - var descendants = _mediaService.GetPagedDescendants(mediaParentId, pageIndex, pageSize, out total); + if (mediaParentId == -1) + { + mediaXElements = _mediaService.GetPagedXmlEntries("-1", pageIndex, pageSize, out total).ToArray(); + } + else + { + //Get the parent + var parent = _mediaService.GetById(mediaParentId); + if (parent == null) + mediaXElements = new XElement[0]; + else + mediaXElements = _mediaService.GetPagedXmlEntries(parent.Path, pageIndex, pageSize, out total).ToArray(); + } //if specific types are declared we need to post filter them //TODO: Update the service layer to join the cmsContentType table so we can query by content type too if (IndexerData.IncludeNodeTypes.Any()) { - media = descendants.Where(x => IndexerData.IncludeNodeTypes.Contains(x.ContentType.Alias)).ToArray(); + var includeNodeTypeIds = nodeTypes.Where(x => IndexerData.IncludeNodeTypes.Contains(x.Alias)).Select(x => x.Id); + mediaXElements = mediaXElements.Where(elm => includeNodeTypeIds.Contains(elm.AttributeValue("nodeType"))).ToArray(); } - else + + // ReSharper disable once ForCanBeConvertedToForeach + for (var i = 0; i < mediaXElements.Length; i++) { - media = descendants.ToArray(); + mediaXElements[i].Add(new XAttribute("icon", icons[mediaXElements[i].AttributeValue("nodeType")])); } - - AddNodesToIndex(GetSerializedMedia(media), type); + + AddNodesToIndex(mediaXElements, type); pageIndex++; - } while (media.Length == pageSize); + } while (mediaXElements.Length == pageSize); break; } } - private IEnumerable GetSerializedMedia(IEnumerable media) - { - var serializer = new EntityXmlSerializer(); - foreach (var m in media) - { - var xml = serializer.Serialize( - _mediaService, - _dataTypeService, - _userService, - m); - - //add a custom 'icon' attribute - if (m.ContentType.Icon.IsNullOrWhiteSpace() == false) - { - xml.Add(new XAttribute("icon", m.ContentType.Icon)); - } - - - yield return xml; - } - } - private IEnumerable GetSerializedContent(IEnumerable content) { var serializer = new EntityXmlSerializer(); @@ -510,7 +517,6 @@ namespace UmbracoExamine protected override void OnGatheringNodeData(IndexingNodeDataEventArgs e) { - //strip html of all users fields if we detect it has HTML in it. //if that is the case, we'll create a duplicate 'raw' copy of it so that we can return //the value of the field 'as-is'. @@ -546,7 +552,6 @@ namespace UmbracoExamine var icon = (string)e.Node.Attribute("icon"); if (!e.Fields.ContainsKey(IconFieldName)) e.Fields.Add(IconFieldName, icon); - } /// @@ -584,7 +589,6 @@ namespace UmbracoExamine } return fields; - } /// @@ -605,7 +609,6 @@ namespace UmbracoExamine { return base.GetIndexerData(indexSet); } - } /// @@ -635,10 +638,9 @@ namespace UmbracoExamine { return false; } - return base.ValidateDocument(node); } #endregion } -} +} \ No newline at end of file From 563f8fbdca8703650c0e326649d804ce3de3a82c Mon Sep 17 00:00:00 2001 From: Claus Date: Thu, 27 Oct 2016 11:07:41 +0200 Subject: [PATCH 03/49] forgot one :) --- src/Umbraco.Tests/UmbracoExamine/IndexTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Tests/UmbracoExamine/IndexTest.cs b/src/Umbraco.Tests/UmbracoExamine/IndexTest.cs index 3bc635bb23..5d6812f94a 100644 --- a/src/Umbraco.Tests/UmbracoExamine/IndexTest.cs +++ b/src/Umbraco.Tests/UmbracoExamine/IndexTest.cs @@ -19,7 +19,7 @@ namespace Umbraco.Tests.UmbracoExamine /// /// Tests the standard indexing capabilities /// - //[DatabaseTestBehavior(DatabaseBehavior.NewDbFileAndSchemaPerTest)] + [DatabaseTestBehavior(DatabaseBehavior.NewDbFileAndSchemaPerTest)] [TestFixture, RequiresSTA] public class IndexTest : ExamineBaseTest { From 4d13622432e0fc83423ab42d174d3228cca043da Mon Sep 17 00:00:00 2001 From: Claus Date: Mon, 31 Oct 2016 14:55:11 +0100 Subject: [PATCH 04/49] U4-9132 Macros from packages are empty when restored changing the package installer to use the new API macroservice instead of the old legacy classes. marked a few methods as obsoleted. --- .../businesslogic/Packager/Installer.cs | 15 ++----- src/umbraco.cms/businesslogic/macro/Macro.cs | 39 ++++++++++--------- 2 files changed, 24 insertions(+), 30 deletions(-) diff --git a/src/umbraco.cms/businesslogic/Packager/Installer.cs b/src/umbraco.cms/businesslogic/Packager/Installer.cs index bc1c062631..dbbdf08e21 100644 --- a/src/umbraco.cms/businesslogic/Packager/Installer.cs +++ b/src/umbraco.cms/businesslogic/Packager/Installer.cs @@ -411,19 +411,12 @@ namespace umbraco.cms.businesslogic.packager #endregion #region Macros - foreach (XmlNode n in Config.DocumentElement.SelectNodes("//macro")) + var macroItemsElement = rootElement.Descendants("Macros").FirstOrDefault(); + if (macroItemsElement != null) { - //TODO: Fix this, this should not use the legacy API - Macro m = Macro.Import(n); - - if (m != null) - { - insPack.Data.Macros.Add(m.Id.ToString(CultureInfo.InvariantCulture)); - //saveNeeded = true; - } + var insertedMacros = packagingService.ImportMacros(macroItemsElement); + insPack.Data.Macros.AddRange(insertedMacros.Select(m => m.Id.ToString())); } - - //if (saveNeeded) { insPack.Save(); saveNeeded = false; } #endregion #region Templates diff --git a/src/umbraco.cms/businesslogic/macro/Macro.cs b/src/umbraco.cms/businesslogic/macro/Macro.cs index 4ff30c404f..4031f54150 100644 --- a/src/umbraco.cms/businesslogic/macro/Macro.cs +++ b/src/umbraco.cms/businesslogic/macro/Macro.cs @@ -1,11 +1,8 @@ using System; -using System.Data; -using System.Globalization; using System.Security.Cryptography; using System.Text; using System.Text.RegularExpressions; using System.Xml; -using System.Runtime.CompilerServices; using Umbraco.Core; using Umbraco.Core.Cache; using Umbraco.Core.IO; @@ -185,23 +182,26 @@ namespace umbraco.cms.businesslogic.macro }).ToArray(); } } - - /// - /// Macro initializer - /// - public Macro() + + /// + /// Macro initializer + /// + [Obsolete("This should no longer be used, use the IMacroService and related models instead")] + public Macro() { } - /// - /// Macro initializer - /// - /// The id of the macro - public Macro(int Id) + /// + /// Macro initializer + /// + /// The id of the macro + [Obsolete("This should no longer be used, use the IMacroService and related models instead")] + public Macro(int Id) { Setup(Id); } + [Obsolete("This should no longer be used, use the IMacroService and related models instead")] internal Macro(IMacro macro) { MacroEntity = macro; @@ -211,15 +211,17 @@ namespace umbraco.cms.businesslogic.macro /// Initializes a new instance of the class. /// /// The alias. + [Obsolete("This should no longer be used, use the IMacroService and related models instead")] public Macro(string alias) { Setup(alias); } - /// - /// Used to persist object changes to the database. In Version3.0 it's just a stub for future compatibility - /// - public virtual void Save() + /// + /// Used to persist object changes to the database. In Version3.0 it's just a stub for future compatibility + /// + [Obsolete("This should no longer be used, use the IMacroService and related models instead")] + public virtual void Save() { //event var e = new SaveEventArgs(); @@ -250,8 +252,7 @@ namespace umbraco.cms.businesslogic.macro } } - //TODO: Fix this, this should wrap a new API! - + [Obsolete("This is no longer used, use the IMacroService and related models instead")] public static Macro Import(XmlNode n) { var alias = XmlHelper.GetNodeValue(n.SelectSingleNode("alias")); From e8237f61900cbff261cdc1824b28d54ff9f796ce Mon Sep 17 00:00:00 2001 From: Claus Date: Mon, 31 Oct 2016 15:09:10 +0100 Subject: [PATCH 05/49] adding culture parameters for this and a few others that were missing. --- src/umbraco.cms/businesslogic/Packager/Installer.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/umbraco.cms/businesslogic/Packager/Installer.cs b/src/umbraco.cms/businesslogic/Packager/Installer.cs index dbbdf08e21..1f17da3922 100644 --- a/src/umbraco.cms/businesslogic/Packager/Installer.cs +++ b/src/umbraco.cms/businesslogic/Packager/Installer.cs @@ -396,7 +396,7 @@ namespace umbraco.cms.businesslogic.packager if (languageItemsElement != null) { var insertedLanguages = packagingService.ImportLanguages(languageItemsElement); - insPack.Data.Languages.AddRange(insertedLanguages.Select(l => l.Id.ToString())); + insPack.Data.Languages.AddRange(insertedLanguages.Select(l => l.Id.ToString(CultureInfo.InvariantCulture))); } #endregion @@ -406,7 +406,7 @@ namespace umbraco.cms.businesslogic.packager if (dictionaryItemsElement != null) { var insertedDictionaryItems = packagingService.ImportDictionaryItems(dictionaryItemsElement); - insPack.Data.DictionaryItems.AddRange(insertedDictionaryItems.Select(d => d.Id.ToString())); + insPack.Data.DictionaryItems.AddRange(insertedDictionaryItems.Select(d => d.Id.ToString(CultureInfo.InvariantCulture))); } #endregion @@ -415,7 +415,7 @@ namespace umbraco.cms.businesslogic.packager if (macroItemsElement != null) { var insertedMacros = packagingService.ImportMacros(macroItemsElement); - insPack.Data.Macros.AddRange(insertedMacros.Select(m => m.Id.ToString())); + insPack.Data.Macros.AddRange(insertedMacros.Select(m => m.Id.ToString(CultureInfo.InvariantCulture))); } #endregion @@ -454,7 +454,7 @@ namespace umbraco.cms.businesslogic.packager { StyleSheet s = StyleSheet.Import(n, currentUser); - insPack.Data.Stylesheets.Add(s.Id.ToString()); + insPack.Data.Stylesheets.Add(s.Id.ToString(CultureInfo.InvariantCulture)); //saveNeeded = true; } From 3a6e2e673518ccccecf1fa03bbfe81a7e6a2e9d8 Mon Sep 17 00:00:00 2001 From: Stephan Date: Wed, 2 Nov 2016 12:39:41 +0100 Subject: [PATCH 06/49] U4-9136 - rebuild Xml data in a more resilient way --- .../Repositories/ContentRepository.cs | 101 ++++++------------ .../Repositories/MediaRepository.cs | 93 ++++++---------- .../Repositories/MemberRepository.cs | 93 ++++++---------- .../Repositories/ContentRepositoryTest.cs | 36 +++---- .../Repositories/MediaRepositoryTest.cs | 38 ++++++- .../Repositories/MemberRepositoryTest.cs | 8 +- 6 files changed, 155 insertions(+), 214 deletions(-) diff --git a/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs b/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs index 84caeb2a3e..70b968032b 100644 --- a/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs @@ -175,85 +175,50 @@ namespace Umbraco.Core.Persistence.Repositories public void RebuildXmlStructures(Func serializer, int groupSize = 5000, IEnumerable contentTypeIds = null) { + // the previous way of doing this was to run it all in one big transaction, + // and to bulk-insert groups of xml rows - which works, until the transaction + // times out - and besides, because v7 transactions are ReadCommited, it does + // not bring much safety - so this reverts to updating each record individually, + // and it may be slower in the end, but should be more resilient. - //Ok, now we need to remove the data and re-insert it, we'll do this all in one transaction too. - using (var tr = Database.GetTransaction()) + var baseId = 0; + var contentTypeIdsA = contentTypeIds == null ? new int[0] : contentTypeIds.ToArray(); + while (true) { - //Remove all the data first, if anything fails after this it's no problem the transaction will be reverted - if (contentTypeIds == null) - { - var subQuery = new Sql() - .Select("id") - .From(SqlSyntax) - .Where(x => x.NodeObjectType == NodeObjectTypeId); + // get the next group of nodes + var query = GetBaseQuery(false); + if (contentTypeIdsA.Length > 0) + query = query + .WhereIn(x => x.ContentTypeId, contentTypeIdsA, SqlSyntax); + query = query + .Where(x => x.NodeId > baseId && x.Trashed == false) + .Where(x => x.Published) + .OrderBy(x => x.NodeId, SqlSyntax); + var xmlItems = ProcessQuery(SqlSyntax.SelectTop(query, groupSize)) + .Select(x => new ContentXmlDto { NodeId = x.Id, Xml = serializer(x).ToString() }) + .ToList(); - var deleteSql = SqlSyntax.GetDeleteSubquery("cmsContentXml", "nodeId", subQuery); - Database.Execute(deleteSql); - } - else - { - var subQuery = new Sql() - .Select("umbracoNode.id as nodeId") - .From(SqlSyntax) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.NodeId, right => right.NodeId) - .WhereIn(dto => dto.ContentTypeId, contentTypeIds, SqlSyntax) - .Where(x => x.NodeObjectType == NodeObjectTypeId); + // no more nodes, break + if (xmlItems.Count == 0) break; - var deleteSql = SqlSyntax.GetDeleteSubquery("cmsContentXml", "nodeId", subQuery); - Database.Execute(deleteSql); - } - - //now insert the data, again if something fails here, the whole transaction is reversed - if (contentTypeIds == null) + foreach (var xmlItem in xmlItems) { - var query = Query.Builder.Where(x => x.Published == true); - RebuildXmlStructuresProcessQuery(serializer, query, tr, groupSize); - } - else - { - foreach (var contentTypeId in contentTypeIds) + try { - //copy local - var id = contentTypeId; - var query = Query.Builder.Where(x => x.Published == true && x.ContentTypeId == id && x.Trashed == false); - RebuildXmlStructuresProcessQuery(serializer, query, tr, groupSize); + // InsertOrUpdate tries to update first, which is good since it is what + // should happen in most cases, then it tries to insert, and it should work + // unless the node has been deleted, and we just report the exception + Database.InsertOrUpdate(xmlItem); + } + catch (Exception e) + { + Logger.Error("Could not rebuild XML for nodeId=" + xmlItem.NodeId, e); } } - - tr.Complete(); + baseId = xmlItems.Last().NodeId; } } - private void RebuildXmlStructuresProcessQuery(Func serializer, IQuery query, Transaction tr, int pageSize) - { - var pageIndex = 0; - var total = long.MinValue; - var processed = 0; - do - { - //NOTE: This is an important call, we cannot simply make a call to: - // GetPagedResultsByQuery(query, pageIndex, pageSize, out total, "Path", Direction.Ascending); - // because that method is used to query 'latest' content items where in this case we don't necessarily - // want latest content items because a pulished content item might not actually be the latest. - // see: http://issues.umbraco.org/issue/U4-6322 & http://issues.umbraco.org/issue/U4-5982 - var descendants = GetPagedResultsByQuery(query, pageIndex, pageSize, out total, - new Tuple("cmsDocument", "nodeId"), - ProcessQuery, "Path", Direction.Ascending, true); - - var xmlItems = (from descendant in descendants - let xml = serializer(descendant) - select new ContentXmlDto { NodeId = descendant.Id, Xml = xml.ToDataString() }); - - //bulk insert it into the database - var count = Database.BulkInsertRecords(xmlItems, tr, SqlSyntax); - - processed += count; - - pageIndex++; - } while (processed < total); - } - public override IContent GetByVersion(Guid versionId) { var sql = GetBaseQuery(false); diff --git a/src/Umbraco.Core/Persistence/Repositories/MediaRepository.cs b/src/Umbraco.Core/Persistence/Repositories/MediaRepository.cs index 598c9e912d..d3356cd4f6 100644 --- a/src/Umbraco.Core/Persistence/Repositories/MediaRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/MediaRepository.cs @@ -165,78 +165,49 @@ namespace Umbraco.Core.Persistence.Repositories public void RebuildXmlStructures(Func serializer, int groupSize = 5000, IEnumerable contentTypeIds = null) { + // the previous way of doing this was to run it all in one big transaction, + // and to bulk-insert groups of xml rows - which works, until the transaction + // times out - and besides, because v7 transactions are ReadCommited, it does + // not bring much safety - so this reverts to updating each record individually, + // and it may be slower in the end, but should be more resilient. - //Ok, now we need to remove the data and re-insert it, we'll do this all in one transaction too. - using (var tr = Database.GetTransaction()) + var baseId = 0; + var contentTypeIdsA = contentTypeIds == null ? new int[0] : contentTypeIds.ToArray(); + while (true) { - //Remove all the data first, if anything fails after this it's no problem the transaction will be reverted - if (contentTypeIds == null) - { - var subQuery = new Sql() - .Select("id") - .From(SqlSyntax) - .Where(x => x.NodeObjectType == NodeObjectTypeId); + // get the next group of nodes + var query = GetBaseQuery(false); + if (contentTypeIdsA.Length > 0) + query = query + .WhereIn(x => x.ContentTypeId, contentTypeIdsA, SqlSyntax); + query = query + .Where(x => x.NodeId > baseId) + .OrderBy(x => x.NodeId, SqlSyntax); + var xmlItems = ProcessQuery(SqlSyntax.SelectTop(query, groupSize)) + .Select(x => new ContentXmlDto { NodeId = x.Id, Xml = serializer(x).ToString() }) + .ToList(); - var deleteSql = SqlSyntax.GetDeleteSubquery("cmsContentXml", "nodeId", subQuery); - Database.Execute(deleteSql); - } - else - { - var subQuery = new Sql() - .Select("umbracoNode.id as nodeId") - .From(SqlSyntax) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.NodeId, right => right.NodeId) - .WhereIn(dto => dto.ContentTypeId, contentTypeIds, SqlSyntax) - .Where(x => x.NodeObjectType == NodeObjectTypeId); + // no more nodes, break + if (xmlItems.Count == 0) break; - var deleteSql = SqlSyntax.GetDeleteSubquery("cmsContentXml", "nodeId", subQuery); - Database.Execute(deleteSql); - } - - //now insert the data, again if something fails here, the whole transaction is reversed - if (contentTypeIds == null) + foreach (var xmlItem in xmlItems) { - var query = Query.Builder; - RebuildXmlStructuresProcessQuery(serializer, query, tr, groupSize); - } - else - { - foreach (var contentTypeId in contentTypeIds) + try { - //copy local - var id = contentTypeId; - var query = Query.Builder.Where(x => x.ContentTypeId == id && x.Trashed == false); - RebuildXmlStructuresProcessQuery(serializer, query, tr, groupSize); + // InsertOrUpdate tries to update first, which is good since it is what + // should happen in most cases, then it tries to insert, and it should work + // unless the node has been deleted, and we just report the exception + Database.InsertOrUpdate(xmlItem); + } + catch (Exception e) + { + Logger.Error("Could not rebuild XML for nodeId=" + xmlItem.NodeId, e); } } - - tr.Complete(); + baseId = xmlItems.Last().NodeId; } } - private void RebuildXmlStructuresProcessQuery(Func serializer, IQuery query, Transaction tr, int pageSize) - { - var pageIndex = 0; - var total = long.MinValue; - var processed = 0; - do - { - var descendants = GetPagedResultsByQuery(query, pageIndex, pageSize, out total, "Path", Direction.Ascending, true); - - var xmlItems = (from descendant in descendants - let xml = serializer(descendant) - select new ContentXmlDto { NodeId = descendant.Id, Xml = xml.ToDataString() }).ToArray(); - - //bulk insert it into the database - Database.BulkInsertRecords(xmlItems, tr); - - processed += xmlItems.Length; - - pageIndex++; - } while (processed < total); - } - public void AddOrUpdateContentXml(IMedia content, Func xml) { _contentXmlRepository.AddOrUpdate(new ContentXmlEntity(content, xml)); diff --git a/src/Umbraco.Core/Persistence/Repositories/MemberRepository.cs b/src/Umbraco.Core/Persistence/Repositories/MemberRepository.cs index 216fc223db..05f030f51d 100644 --- a/src/Umbraco.Core/Persistence/Repositories/MemberRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/MemberRepository.cs @@ -382,78 +382,49 @@ namespace Umbraco.Core.Persistence.Repositories public void RebuildXmlStructures(Func serializer, int groupSize = 5000, IEnumerable contentTypeIds = null) { + // the previous way of doing this was to run it all in one big transaction, + // and to bulk-insert groups of xml rows - which works, until the transaction + // times out - and besides, because v7 transactions are ReadCommited, it does + // not bring much safety - so this reverts to updating each record individually, + // and it may be slower in the end, but should be more resilient. - //Ok, now we need to remove the data and re-insert it, we'll do this all in one transaction too. - using (var tr = Database.GetTransaction()) + var baseId = 0; + var contentTypeIdsA = contentTypeIds == null ? new int[0] : contentTypeIds.ToArray(); + while (true) { - //Remove all the data first, if anything fails after this it's no problem the transaction will be reverted - if (contentTypeIds == null) - { - var subQuery = new Sql() - .Select("id") - .From(SqlSyntax) - .Where(x => x.NodeObjectType == NodeObjectTypeId); + // get the next group of nodes + var query = GetBaseQuery(false); + if (contentTypeIdsA.Length > 0) + query = query + .WhereIn(x => x.ContentTypeId, contentTypeIdsA, SqlSyntax); + query = query + .Where(x => x.NodeId > baseId) + .OrderBy(x => x.NodeId, SqlSyntax); + var xmlItems = ProcessQuery(SqlSyntax.SelectTop(query, groupSize)) + .Select(x => new ContentXmlDto { NodeId = x.Id, Xml = serializer(x).ToString() }) + .ToList(); - var deleteSql = SqlSyntax.GetDeleteSubquery("cmsContentXml", "nodeId", subQuery); - Database.Execute(deleteSql); - } - else - { - var subQuery = new Sql() - .Select("umbracoNode.id as nodeId") - .From(SqlSyntax) - .InnerJoin(SqlSyntax) - .On(SqlSyntax, left => left.NodeId, right => right.NodeId) - .WhereIn(dto => dto.ContentTypeId, contentTypeIds, SqlSyntax) - .Where(x => x.NodeObjectType == NodeObjectTypeId); + // no more nodes, break + if (xmlItems.Count == 0) break; - var deleteSql = SqlSyntax.GetDeleteSubquery("cmsContentXml", "nodeId", subQuery); - Database.Execute(deleteSql); - } - - //now insert the data, again if something fails here, the whole transaction is reversed - if (contentTypeIds == null) + foreach (var xmlItem in xmlItems) { - var query = Query.Builder; - RebuildXmlStructuresProcessQuery(serializer, query, tr, groupSize); - } - else - { - foreach (var contentTypeId in contentTypeIds) + try { - //copy local - var id = contentTypeId; - var query = Query.Builder.Where(x => x.ContentTypeId == id && x.Trashed == false); - RebuildXmlStructuresProcessQuery(serializer, query, tr, groupSize); + // InsertOrUpdate tries to update first, which is good since it is what + // should happen in most cases, then it tries to insert, and it should work + // unless the node has been deleted, and we just report the exception + Database.InsertOrUpdate(xmlItem); + } + catch (Exception e) + { + Logger.Error("Could not rebuild XML for nodeId=" + xmlItem.NodeId, e); } } - - tr.Complete(); + baseId = xmlItems.Last().NodeId; } } - private void RebuildXmlStructuresProcessQuery(Func serializer, IQuery query, Transaction tr, int pageSize) - { - var pageIndex = 0; - var total = long.MinValue; - var processed = 0; - do - { - var descendants = GetPagedResultsByQuery(query, pageIndex, pageSize, out total, "Path", Direction.Ascending, true); - - var xmlItems = (from descendant in descendants - let xml = serializer(descendant) - select new ContentXmlDto { NodeId = descendant.Id, Xml = xml.ToDataString() }).ToArray(); - - //bulk insert it into the database - Database.BulkInsertRecords(xmlItems, tr); - - processed += xmlItems.Length; - - pageIndex++; - } while (processed < total); - } - public override IMember GetByVersion(Guid versionId) { var sql = GetBaseQuery(false); diff --git a/src/Umbraco.Tests/Persistence/Repositories/ContentRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/ContentRepositoryTest.cs index abcb5b3d6a..311ea52071 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/ContentRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/ContentRepositoryTest.cs @@ -101,7 +101,7 @@ namespace Umbraco.Tests.Persistence.Repositories for (int i = 0; i < allCreated.Count; i++) { allCreated[i].Name = "blah" + i; - //IMPORTANT testing note here: We need to changed the published state here so that + //IMPORTANT testing note here: We need to changed the published state here so that // it doesn't automatically think this is simply publishing again - this forces the latest // version to be Saved and not published allCreated[i].ChangePublishedState(PublishedState.Saved); @@ -109,7 +109,7 @@ namespace Umbraco.Tests.Persistence.Repositories } unitOfWork.Commit(); - //delete all xml + //delete all xml unitOfWork.Database.Execute("DELETE FROM cmsContentXml"); Assert.AreEqual(0, unitOfWork.Database.ExecuteScalar("SELECT COUNT(*) FROM cmsContentXml")); @@ -156,7 +156,7 @@ namespace Umbraco.Tests.Persistence.Repositories } unitOfWork.Commit(); - //delete all xml + //delete all xml unitOfWork.Database.Execute("DELETE FROM cmsContentXml"); Assert.AreEqual(0, unitOfWork.Database.ExecuteScalar("SELECT COUNT(*) FROM cmsContentXml")); @@ -221,7 +221,7 @@ namespace Umbraco.Tests.Persistence.Repositories } unitOfWork.Commit(); - //delete all xml + //delete all xml unitOfWork.Database.Execute("DELETE FROM cmsContentXml"); Assert.AreEqual(0, unitOfWork.Database.ExecuteScalar("SELECT COUNT(*) FROM cmsContentXml")); @@ -234,10 +234,10 @@ namespace Umbraco.Tests.Persistence.Repositories /// /// This test ensures that when property values using special database fields are saved, the actual data in the /// object being stored is also transformed in the same way as the data being stored in the database is. - /// Before you would see that ex: a decimal value being saved as 100 or "100", would be that exact value in the + /// Before you would see that ex: a decimal value being saved as 100 or "100", would be that exact value in the /// object, but the value saved to the database was actually 100.000000. - /// When querying the database for the value again - the value would then differ from what is in the object. - /// This caused inconsistencies between saving+publishing and simply saving and then publishing, due to the former + /// When querying the database for the value again - the value would then differ from what is in the object. + /// This caused inconsistencies between saving+publishing and simply saving and then publishing, due to the former /// sending the non-transformed data directly on to publishing. /// [Test] @@ -269,10 +269,10 @@ namespace Umbraco.Tests.Persistence.Repositories var contentType = MockedContentTypes.CreateSimpleContentType("umbTextpage1", "Textpage", propertyTypeCollection); contentTypeRepository.AddOrUpdate(contentType); unitOfWork.Commit(); - + // Int and decimal values are passed in as strings as they would be from the backoffice UI var textpage = MockedContent.CreateSimpleContentWithSpecialDatabaseTypes(contentType, "test@umbraco.org", -1, "100", "150", dateValue); - + // Act repository.AddOrUpdate(textpage); unitOfWork.Commit(); @@ -280,7 +280,7 @@ namespace Umbraco.Tests.Persistence.Repositories // Assert Assert.That(contentType.HasIdentity, Is.True); Assert.That(textpage.HasIdentity, Is.True); - + var persistedTextpage = repository.Get(textpage.Id); Assert.That(persistedTextpage.Name, Is.EqualTo(textpage.Name)); Assert.AreEqual(100m, persistedTextpage.GetValue(decimalPropertyAlias)); @@ -342,12 +342,12 @@ namespace Umbraco.Tests.Persistence.Repositories contentTypeRepository.AddOrUpdate(contentType); repository.AddOrUpdate(textpage); unitOfWork.Commit(); - + // Assert Assert.That(contentType.HasIdentity, Is.True); Assert.That(textpage.HasIdentity, Is.True); - + } } @@ -631,9 +631,9 @@ namespace Umbraco.Tests.Persistence.Repositories // Act var query = Query.Builder.Where(x => x.Name.Contains("Text")); long totalRecords; - + try - { + { DatabaseContext.Database.EnableSqlTrace = true; DatabaseContext.Database.EnableSqlCount(); @@ -643,14 +643,14 @@ namespace Umbraco.Tests.Persistence.Repositories Assert.AreEqual(2, result.Count()); result = repository.GetPagedResultsByQuery(query, 1, 2, out totalRecords, "title", Direction.Ascending, false); - + Assert.AreEqual(1, result.Count()); } finally - { + { DatabaseContext.Database.EnableSqlTrace = false; DatabaseContext.Database.DisableSqlCount(); - } + } } } @@ -761,7 +761,7 @@ namespace Umbraco.Tests.Persistence.Repositories // Act var query = Query.Builder.Where(x => x.Level == 2); var filterQuery = Query.Builder.Where(x => x.Name.Contains("Page 2")); - + long totalRecords; var result = repository.GetPagedResultsByQuery(query, 0, 1, out totalRecords, "Name", Direction.Ascending, true, filterQuery); diff --git a/src/Umbraco.Tests/Persistence/Repositories/MediaRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/MediaRepositoryTest.cs index a216eaaa45..1566441d5a 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/MediaRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/MediaRepositoryTest.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Linq; using System.Xml.Linq; using Moq; @@ -59,7 +60,7 @@ namespace Umbraco.Tests.Persistence.Repositories } unitOfWork.Commit(); - //delete all xml + //delete all xml unitOfWork.Database.Execute("DELETE FROM cmsContentXml"); Assert.AreEqual(0, unitOfWork.Database.ExecuteScalar("SELECT COUNT(*) FROM cmsContentXml")); @@ -69,6 +70,39 @@ namespace Umbraco.Tests.Persistence.Repositories } } + [Test] + public void Rebuild_Some_Xml_Structures() + { + var provider = new PetaPocoUnitOfWorkProvider(Logger); + var unitOfWork = provider.GetUnitOfWork(); + MediaTypeRepository mediaTypeRepository; + using (var repository = CreateRepository(unitOfWork, out mediaTypeRepository)) + { + + var mediaType = mediaTypeRepository.Get(1032); + + IMedia img50 = null; + for (var i = 0; i < 100; i++) + { + var image = MockedMedia.CreateMediaImage(mediaType, -1); + repository.AddOrUpdate(image); + if (i == 50) img50 = image; + } + unitOfWork.Commit(); + + // assume this works (see other test) + repository.RebuildXmlStructures(media => new XElement("test"), 10); + + //delete some xml + unitOfWork.Database.Execute("DELETE FROM cmsContentXml WHERE nodeId < " + img50.Id); + Assert.AreEqual(50, unitOfWork.Database.ExecuteScalar("SELECT COUNT(*) FROM cmsContentXml")); + + repository.RebuildXmlStructures(media => new XElement("test"), 10); + + Assert.AreEqual(103, unitOfWork.Database.ExecuteScalar("SELECT COUNT(*) FROM cmsContentXml")); + } + } + [Test] public void Rebuild_All_Xml_Structures_For_Content_Type() { @@ -99,7 +133,7 @@ namespace Umbraco.Tests.Persistence.Repositories } unitOfWork.Commit(); - //delete all xml + //delete all xml unitOfWork.Database.Execute("DELETE FROM cmsContentXml"); Assert.AreEqual(0, unitOfWork.Database.ExecuteScalar("SELECT COUNT(*) FROM cmsContentXml")); diff --git a/src/Umbraco.Tests/Persistence/Repositories/MemberRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/MemberRepositoryTest.cs index bb13f055c9..e97fff03c8 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/MemberRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/MemberRepositoryTest.cs @@ -54,7 +54,7 @@ namespace Umbraco.Tests.Persistence.Repositories using (var repository = CreateRepository(unitOfWork, out memberTypeRepository, out memberGroupRepository)) { var memberType1 = CreateTestMemberType(); - + for (var i = 0; i < 100; i++) { var member = MockedMember.CreateSimpleMember(memberType1, "blah" + i, "blah" + i + "@example.com", "blah", "blah" + i); @@ -103,7 +103,7 @@ namespace Umbraco.Tests.Persistence.Repositories } unitOfWork.Commit(); - //delete all xml + //delete all xml unitOfWork.Database.Execute("DELETE FROM cmsContentXml"); Assert.AreEqual(0, unitOfWork.Database.ExecuteScalar("SELECT COUNT(*) FROM cmsContentXml")); @@ -216,7 +216,7 @@ namespace Umbraco.Tests.Persistence.Repositories var sut = repository.Get(member.Id); Assert.That(sut, Is.Not.Null); - Assert.That(sut.HasIdentity, Is.True); + Assert.That(sut.HasIdentity, Is.True); Assert.That(sut.Properties.Any(x => x.HasIdentity == false || x.Id == 0), Is.False); Assert.That(sut.Name, Is.EqualTo("Johnny Hefty")); Assert.That(sut.Email, Is.EqualTo("johnny@example.com")); @@ -350,7 +350,7 @@ namespace Umbraco.Tests.Persistence.Repositories { memberType = MockedContentTypes.CreateSimpleMemberType(); memberTypeRepository.AddOrUpdate(memberType); - unitOfWork.Commit(); + unitOfWork.Commit(); } var member = MockedMember.CreateSimpleMember(memberType, name ?? "Johnny Hefty", email ?? "johnny@example.com", password ?? "123", username ?? "hefty", key); From 5426c570fcd04215cc517ba6af4506b41e0527f1 Mon Sep 17 00:00:00 2001 From: Stephan Date: Wed, 2 Nov 2016 12:41:38 +0100 Subject: [PATCH 07/49] U4-9136 - group size 200 --- src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs | 2 +- src/Umbraco.Core/Persistence/Repositories/MediaRepository.cs | 2 +- src/Umbraco.Core/Persistence/Repositories/MemberRepository.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs b/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs index 70b968032b..608189a4bd 100644 --- a/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs @@ -173,7 +173,7 @@ namespace Umbraco.Core.Persistence.Repositories #region Overrides of VersionableRepositoryBase - public void RebuildXmlStructures(Func serializer, int groupSize = 5000, IEnumerable contentTypeIds = null) + public void RebuildXmlStructures(Func serializer, int groupSize = 200, IEnumerable contentTypeIds = null) { // the previous way of doing this was to run it all in one big transaction, // and to bulk-insert groups of xml rows - which works, until the transaction diff --git a/src/Umbraco.Core/Persistence/Repositories/MediaRepository.cs b/src/Umbraco.Core/Persistence/Repositories/MediaRepository.cs index d3356cd4f6..fdc92ce3af 100644 --- a/src/Umbraco.Core/Persistence/Repositories/MediaRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/MediaRepository.cs @@ -163,7 +163,7 @@ namespace Umbraco.Core.Persistence.Repositories return media; } - public void RebuildXmlStructures(Func serializer, int groupSize = 5000, IEnumerable contentTypeIds = null) + public void RebuildXmlStructures(Func serializer, int groupSize = 200, IEnumerable contentTypeIds = null) { // the previous way of doing this was to run it all in one big transaction, // and to bulk-insert groups of xml rows - which works, until the transaction diff --git a/src/Umbraco.Core/Persistence/Repositories/MemberRepository.cs b/src/Umbraco.Core/Persistence/Repositories/MemberRepository.cs index 05f030f51d..66f803f9cd 100644 --- a/src/Umbraco.Core/Persistence/Repositories/MemberRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/MemberRepository.cs @@ -380,7 +380,7 @@ namespace Umbraco.Core.Persistence.Repositories #region Overrides of VersionableRepositoryBase - public void RebuildXmlStructures(Func serializer, int groupSize = 5000, IEnumerable contentTypeIds = null) + public void RebuildXmlStructures(Func serializer, int groupSize = 200, IEnumerable contentTypeIds = null) { // the previous way of doing this was to run it all in one big transaction, // and to bulk-insert groups of xml rows - which works, until the transaction From 0426f1f17de01c817c78e78fbe1e38def6478fa0 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 2 Nov 2016 14:24:17 +0100 Subject: [PATCH 08/49] Changes from Gerard Konings + a couple of small fixes --- .../upload/umbfiledropzone.directive.js | 86 +++++++++++++++---- .../services/mediatypehelper.service.js | 42 +++++++++ .../common/dialogs/mediapicker.controller.js | 14 ++- .../src/views/common/dialogs/mediapicker.html | 4 +- .../mediaPicker/mediapicker.controller.js | 11 ++- .../overlays/mediaPicker/mediapicker.html | 2 + .../mediapicktypepicker.controller.js | 10 +++ .../mediatypepicker/mediatypepicker.html | 15 ++++ .../components/upload/umb-file-dropzone.html | 7 ++ .../listview/layouts/grid/grid.html | 3 +- .../grid/grid.listviewlayout.controller.js | 10 ++- .../listview/layouts/list/list.html | 3 +- .../list/list.listviewlayout.controller.js | 37 +++++--- 13 files changed, 206 insertions(+), 38 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/common/services/mediatypehelper.service.js create mode 100644 src/Umbraco.Web.UI.Client/src/views/common/overlays/mediatypepicker/mediapicktypepicker.controller.js create mode 100644 src/Umbraco.Web.UI.Client/src/views/common/overlays/mediatypepicker/mediatypepicker.html diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/upload/umbfiledropzone.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/upload/umbfiledropzone.directive.js index e0678c1065..52704855bb 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/upload/umbfiledropzone.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/upload/umbfiledropzone.directive.js @@ -25,7 +25,7 @@ TODO angular.module("umbraco.directives") -.directive('umbFileDropzone', function ($timeout, Upload, localizationService, umbRequestHelper) { +.directive('umbFileDropzone', function ($timeout, Upload, localizationService, umbRequestHelper, editorState) { return { restrict: 'E', @@ -42,6 +42,7 @@ angular.module("umbraco.directives") compact: '@', hideDropzone: '@', + acceptedMediatypes: '=', filesQueued: '=', handleFile: '=', @@ -49,14 +50,15 @@ angular.module("umbraco.directives") }, link: function(scope, element, attrs) { - + scope.queue = []; scope.done = []; scope.rejected = []; + scope.currentFile = undefined; function _filterFile(file) { - + var ignoreFileNames = ['Thumbs.db']; var ignoreFileTypes = ['directory']; @@ -85,20 +87,38 @@ angular.module("umbraco.directives") } else { scope.queue.push(file); } - } }); - + //when queue is done, kick the uploader if(!scope.working){ - _processQueueItem(); - } + + // Upload not allowed + if(!scope.acceptedMediatypes || !scope.acceptedMediatypes.length){ + files.map(function(file){ + file.uploadStatus = "error"; + file.serverErrorMessage = "File type is not allowed here"; + scope.rejected.push(file); + }); + scope.queue = []; + } + + // One allowed mediaType, pick this one + if(scope.acceptedMediatypes && scope.acceptedMediatypes.length === 1){ + scope.contentTypeAlias = scope.acceptedMediatypes[0].alias; + _processQueueItem(); + } + + // More than one, open dialog + if(scope.acceptedMediatypes && scope.acceptedMediatypes.length > 1){ + _chooseMediaType(); + } + } } - function _processQueueItem(){ - + if(scope.queue.length > 0){ scope.currentFile = scope.queue.shift(); _upload(scope.currentFile); @@ -118,10 +138,10 @@ angular.module("umbraco.directives") } function _upload(file) { - + scope.propertyAlias = scope.propertyAlias ? scope.propertyAlias : "umbracoFile"; scope.contentTypeAlias = scope.contentTypeAlias ? scope.contentTypeAlias : "Image"; - + Upload.upload({ url: umbRequestHelper.getApiUrl("mediaApiBaseUrl", "PostAddFile"), fields: { @@ -204,18 +224,48 @@ angular.module("umbraco.directives") }); } + function _chooseMediaType() { + + scope.mediatypepickerOverlay = { + view: "mediatypepicker", + title: "Choose media type", + acceptedMediatypes: scope.acceptedMediatypes, + hideSubmitButton: true, + show: true, + submit: function(model) { + scope.contentTypeAlias = model.selectedType.alias; + + scope.mediatypepickerOverlay.show = false; + scope.mediatypepickerOverlay = null; + + _processQueueItem(); + }, + close: function(oldModel) { + + scope.queue.map(function(file){ + file.uploadStatus = "error"; + file.serverErrorMessage = "Cannot upload this file, no mediatype selected"; + scope.rejected.push(file); + }); + scope.queue = []; + + scope.mediatypepickerOverlay.show = false; + scope.mediatypepickerOverlay = null; + + } + }; + + } scope.handleFiles = function(files, event){ if(scope.filesQueued){ scope.filesQueued(files, event); } - - _filesQueued(files, event); + + _filesQueued(files, event); }; - } - - - }; - }); + } + }; +}); diff --git a/src/Umbraco.Web.UI.Client/src/common/services/mediatypehelper.service.js b/src/Umbraco.Web.UI.Client/src/common/services/mediatypehelper.service.js new file mode 100644 index 0000000000..919a803456 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/common/services/mediatypehelper.service.js @@ -0,0 +1,42 @@ +/** + * @ngdoc service + * @name umbraco.services.mediaTypeHelper + * @description A helper service for the media types + **/ +function mediaTypeHelper(mediaTypeResource, $q) { + + var mediaTypeHelperService = { + + getAllowedImagetypes: function (mediaId){ + + // Get All allowedTypes + return mediaTypeResource.getAllowedTypes(mediaId) + .then(function(types){ + + var allowedQ = types.map(function(type){ + return mediaTypeResource.getById(type.id); + }); + + // Get full list + return $q.all(allowedQ).then(function(fullTypes){ + // Only mediatypes with 'umbracoFile' property + + return fullTypes.filter(function(mediatype){ + for(var i = 0; i < mediatype.groups.length; i++){ + var group = mediatype.groups[i]; + for(var j = 0; j < group.properties.length; j++){ + var property = group.properties[j]; + if(property.editor === 'Umbraco.ImageCropper' || property.editor === 'Umbraco.UploadField'){ + return mediatype; + } + } + } + }); + }); + }); + } + }; + + return mediaTypeHelperService; +} +angular.module('umbraco.services').factory('mediaTypeHelper', mediaTypeHelper); diff --git a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/mediapicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/mediapicker.controller.js index b29388be23..504f547182 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/mediapicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/mediapicker.controller.js @@ -1,7 +1,7 @@ //used for the media picker dialog angular.module("umbraco") .controller("Umbraco.Dialogs.MediaPickerController", - function ($scope, mediaResource, umbRequestHelper, entityResource, $log, mediaHelper, eventsService, treeService, $cookies, $element, $timeout) { + function ($scope, mediaResource, umbRequestHelper, entityResource, $log, mediaHelper, mediaTypeHelper, eventsService, treeService, $cookies, $element, $timeout) { var dialogOptions = $scope.dialogOptions; @@ -11,13 +11,17 @@ angular.module("umbraco") $scope.startNodeId = dialogOptions.startNodeId ? dialogOptions.startNodeId : -1; $scope.cropSize = dialogOptions.cropSize; - //preload selected item $scope.target = undefined; if(dialogOptions.currentTarget){ $scope.target = dialogOptions.currentTarget; } + $scope.acceptedMediatypes = []; + mediaTypeHelper.getAllowedImagetypes($scope.startNodeId).then(function(types){ + $scope.acceptedMediatypes = types; + }); + $scope.upload = function(v){ angular.element(".umb-file-dropzone-directive .file-select").click(); }; @@ -65,6 +69,10 @@ angular.module("umbraco") return f.path.indexOf($scope.startNodeId) !== -1; }); }); + + mediaTypeHelper.getAllowedImagetypes(folder.id).then(function(types){ + $scope.acceptedMediatypes = types; + }); } else { $scope.path = []; @@ -76,7 +84,7 @@ angular.module("umbraco") $scope.searchTerm = ""; $scope.images = data.items ? data.items : []; }); - + $scope.currentFolder = folder; }; diff --git a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/mediapicker.html b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/mediapicker.html index 540a19d64a..78d8e41127 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/mediapicker.html +++ b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/mediapicker.html @@ -116,8 +116,10 @@ diff --git a/src/Umbraco.Web.UI.Client/src/views/components/upload/umb-file-dropzone.html b/src/Umbraco.Web.UI.Client/src/views/components/upload/umb-file-dropzone.html index 6a05d234f0..35d375e94d 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/upload/umb-file-dropzone.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/upload/umb-file-dropzone.html @@ -98,4 +98,11 @@ + + + diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/layouts/grid/grid.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/layouts/grid/grid.html index 4360996b55..16c5efe799 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/layouts/grid/grid.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/layouts/grid/grid.html @@ -39,7 +39,8 @@ on-drag-enter="vm.dragEnter()"> Date: Thu, 3 Nov 2016 00:12:44 +0700 Subject: [PATCH 09/49] Update ru.xml UI language file Dictionary item editor keys added --- src/Umbraco.Web.UI/umbraco/config/lang/ru.xml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/ru.xml b/src/Umbraco.Web.UI/umbraco/config/lang/ru.xml index 75c5630678..d71b4423aa 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/ru.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/ru.xml @@ -380,6 +380,12 @@ Ниже Вы можете указать различные переводы данной статьи словаря '%0%'
Добавить другие языки можно, воспользовавшись пунктом 'Языки' в меню слева ]]> Название языка (культуры) + Редактировать элемент (ключ) словаря + + + Допустим как корневой @@ -655,7 +661,7 @@ Медиа - всего в XML: %0%, всего: %1%Б с ошибками: %2% Содержимое - всего в XML: %0%, всего опубликовано: %1%, с ошибками: %2% - Сертификат Вашего сайта отмечен как проверенный. + Сертификат Вашего веб-сайта отмечен как проверенный. Ошибка проверки сертификата: '%0%' Ошибка проверки адреса URL %0% - '%1%' Сейчас Вы %0% просматриваете сайт, используя протокол HTTPS. From a5b0fbb83dfdd9f46391d4374425e26b67aa8b6c Mon Sep 17 00:00:00 2001 From: Anders Bjerner Date: Wed, 2 Nov 2016 19:51:54 +0100 Subject: [PATCH 10/49] Headline in the "Republish entire site" dialog is now translated --- src/Umbraco.Web/Trees/LegacyTreeDataConverter.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web/Trees/LegacyTreeDataConverter.cs b/src/Umbraco.Web/Trees/LegacyTreeDataConverter.cs index 41f4ae232a..1d142158e3 100644 --- a/src/Umbraco.Web/Trees/LegacyTreeDataConverter.cs +++ b/src/Umbraco.Web/Trees/LegacyTreeDataConverter.cs @@ -254,7 +254,7 @@ namespace Umbraco.Web.Trees return Attempt.Succeed( new LegacyUrlAction( "dialogs/republish.aspx?rnd=" + DateTime.UtcNow.Ticks, - "Republishing entire site")); + ui.GetText("actions", "republish"))); case "UmbClientMgr.appActions().actionAssignDomain()": return Attempt.Succeed( new LegacyUrlAction( @@ -415,4 +415,4 @@ namespace Umbraco.Web.Trees } } -} \ No newline at end of file +} From 030708194ab579cfde58fa4ba8dd95e390baa09b Mon Sep 17 00:00:00 2001 From: Rasmus Fjord Date: Wed, 2 Nov 2016 20:15:55 +0100 Subject: [PATCH 11/49] Oversat publish events --- src/Umbraco.Web.UI/umbraco/config/lang/da.xml | 192 ++++++++++-------- 1 file changed, 108 insertions(+), 84 deletions(-) diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/da.xml b/src/Umbraco.Web.UI/umbraco/config/lang/da.xml index ffb0a9d96b..6ac936533b 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/da.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/da.xml @@ -202,12 +202,12 @@ Færdig - + Slettede %0% element Slettede %0% elementer Slettede %0% ud af %1% element Slettede %0% ud af %1% elementer - + Udgav %0% element Udgav %0% elementer Udgav %0% ud af %1% element @@ -293,20 +293,22 @@ Vælg indhold Vælg medlem Vælg medlemsgruppe - + Der er ingen parametre for denne makro Link dit - Fjern link fra dit - + Fjern link fra dit + konto - + Vælg editor - + Du tilføjer flere sprog under 'sprog' i menuen til venstre - ]]> + ]]> + Kulturnavn Rediger navnet på ordbogselementet. @@ -327,17 +329,17 @@ Indtast nøgleord (tryk på Enter efter hvert nøgleord)... - Tillad på rodniveau + Tillad på rodniveau Kun dokumenttyper med denne indstilling aktiveret oprettes i rodniveau under Inhold og Mediearkiv Tilladte typer - Sammensætning af dokumenttyper + Sammensætning af dokumenttyper Opret Slet fane Beskrivelse Ny fane Fane Thumbnail - Aktiver listevisning + Aktiver listevisning Viser undersider i en søgbar liste, undersider vises ikke i indholdstræet Nuværende listevisning Den aktive listevisningsdatatype @@ -372,7 +374,7 @@ Der skete en fejl på severen - Denne filttype er blevet deaktiveret af administratoren + Denne filttype er blevet deaktiveret af administratoren OBS! Selvom CodeMirror er slået til i konfigurationen, så er den deaktiveret i Internet Explorer fordi den ikke er stabil nok. Du skal udfylde både Alias & Navn på den nye egenskabstype! Der mangler læse/skrive rettigheder til bestemte filer og mapper @@ -388,7 +390,7 @@ Du kan ikke opdele en celle, som ikke allerede er delt. Fejl i XSLT kode Din XSLT er ikke opdateret, da det indeholdt en fejl - Der er et problem med den datatype, der bruges til denn egenskab. Kontroller konfigurationen og prøv igen. + Der er et problem med den datatype, der bruges til denn egenskab. Kontroller konfigurationen og prøv igen. Om @@ -474,7 +476,8 @@ Hvilken side skal vises efter at formularen er sendt Størrelse Sortér - Indsend + Indsend + Type Skriv for at søge... Op @@ -513,22 +516,22 @@ - Tilføj fane - Tilføj egenskab - Tilføj editor - Tilføj skabelon - Tilføj child node - Tilføj child + Tilføj fane + Tilføj egenskab + Tilføj editor + Tilføj skabelon + Tilføj child node + Tilføj child - Rediger datatype + Rediger datatype - Naviger sektioner + Naviger sektioner - Genveje - Vis genveje + Genveje + Vis genveje - Brug listevisning - Tillad på rodniveau + Brug listevisning + Tillad på rodniveau @@ -546,13 +549,17 @@ Kunne ikke gemme web.config filen. Du bedes venligst manuelt ændre database forbindelses strengen. Din database er blevet fundet og identificeret som Database konfiguration - + installér knappen for at installere Umbraco %0% databasen - ]]> + ]]> + installér knappen for at installere Umbraco %0% databasen]]> Næste for at fortsætte.]]> - Databasen er ikke fundet. Kontrollér venligst at informationen i database forbindelsesstrengen i "web.config" filen er korrekt.

-

For at fortsætte bedes du venligst rette "web.config" filen (ved at bruge Visual Studio eller dit favoritprogram), scroll til bunden, tilføj forbindelsesstrengen til din database i feltet som hedder "umbracoDbDSN" og gem filen.

Klik på Forsøg igen knappen når du er færdig.
Mere information om at redigere web.config her.

]]>
+ + Databasen er ikke fundet. Kontrollér venligst at informationen i database forbindelsesstrengen i "web.config" filen er korrekt.

+

For at fortsætte bedes du venligst rette "web.config" filen (ved at bruge Visual Studio eller dit favoritprogram), scroll til bunden, tilføj forbindelsesstrengen til din database i feltet som hedder "umbracoDbDSN" og gem filen.

Klik på Forsøg igen knappen når du er færdig.
Mere information om at redigere web.config her.

]]> +
Kontakt venligst din ISP hvis det er nødvendigt. Hvis du installerer på en lokal maskine eller server kan du muligvis få informationerne fra din systemadministrator.]]> Tryk på Opgradér knappen for at opgradere din database til Umbraco %0%

Bare rolig - intet indhold vil blive slettet og alt vil stadig fungere bagefter!

]]>
Tryk på Næste for at fortsætte.]]> @@ -598,8 +605,10 @@ Yderligere hjælpe og informationer Få hjælp fra vores prisvindende fællesskab, gennemse dokumentationen eller se nogle gratis videoer om hvordan du opsætter et simpelt site, hvordan du bruger pakker og en 'quick guide' til Umbraco terminologier]]> Umbraco %0% er installeret og klar til brug /web.config filen og opdatére 'AppSetting' feltet UmbracoConfigurationStatus i bunden til '%0%'.]]> - komme igang med det samme ved at klikke på "Start Umbraco" knappen nedenfor.
Hvis du er ny med Umbraco, kan du finde masser af ressourcer på vores 'getting started' sider. -]]>
+ + komme igang med det samme ved at klikke på "Start Umbraco" knappen nedenfor.
Hvis du er ny med Umbraco, kan du finde masser af ressourcer på vores 'getting started' sider. +]]> +
Start UmbracoFor at administrere dit website skal du blot åbne Umbraco administrationen og begynde at tilføje indhold, opdatere skabelonerne og stylesheets'ene eller tilføje ny funktionalitet.]]> Forbindelse til databasen fejlede. Umbraco Version 3 @@ -674,12 +683,15 @@ Gå til http://%4%/#/content/content/edit/%5% for at redigere. Ha' en dejlig dag! Mange hilsner fra Umbraco robotten - ]]> - Hej %0%

+ ]]> +
+ + Hej %0%

Dette er en automatisk mail for at informere dig om at opgaven '%1%' er blevet udførtpå siden '%2%' af brugeren '%3%'

Opdateringssammendrag:

%6%

Hav en fortsat god dag!

De bedste hilsner fra umbraco robotten

]]>
+      RET       

Opdateringssammendrag:

%6%

Hav en fortsat god dag!

De bedste hilsner fra umbraco robotten

]]> + [%0%] Notificering om %1% udført på %2% Notificeringer @@ -700,8 +712,10 @@ Mange hilsner fra Umbraco robotten Pakken blev fjernet Pakken er på succefuld vis blevet fjernet Afinstallér pakke - -Bemærk: at dokumenter og medier som afhænger af denne pakke vil muligvis holde op med at virke, så vær forsigtig. Hvis i tvivl, kontakt personen som har udviklet pakken.]]> + + +Bemærk: at dokumenter og medier som afhænger af denne pakke vil muligvis holde op med at virke, så vær forsigtig. Hvis i tvivl, kontakt personen som har udviklet pakken.]]> + Download opdatering fra opbevaringsbasen Opdatér pakke Opdateringsinstrukser @@ -734,6 +748,19 @@ Mange hilsner fra Umbraco robotten Hvis du blot ønsker at opsætte simpel beskyttelse ved hjælp af et enkelt login og kodeord + Udgivelsen kunne ikke udgives da publiceringsdato er sat + + + + + + + Udgivelsen fejlede fordi en overordnet side ikke er publiceret + %0% kunne ikke udgives, fordi et 3. parts modul annullerede handlingen Medtag ikke-udgivede undersider Publicerer - vent venligst... @@ -807,58 +834,58 @@ Mange hilsner fra Umbraco robotten - Kompositioner - Du har ikke tilføjet nogle faner - Tilføj ny fane - Tilføj endnu en fane - Nedarvet fra - Tilføj property - Påkrævet label + Kompositioner + Du har ikke tilføjet nogle faner + Tilføj ny fane + Tilføj endnu en fane + Nedarvet fra + Tilføj property + Påkrævet label - Aktiver listevisning - Konfigurer indholdet til at blive vist i en sorterbar og søgbar liste, dens børn vil ikke blive vist i træet + Aktiver listevisning + Konfigurer indholdet til at blive vist i en sorterbar og søgbar liste, dens børn vil ikke blive vist i træet - Tilladte skabeloner - Vælg hvilke skabeloner der er tilladt at bruge på dette indhold + Tilladte skabeloner + Vælg hvilke skabeloner der er tilladt at bruge på dette indhold - Tillad på rodniveau - Kun dokumenttyper med denne indstilling aktiveret oprettes i rodniveau under inhold og mediearkiv - Ja – indhold af denne type er tilladt i roden + Tillad på rodniveau + Kun dokumenttyper med denne indstilling aktiveret oprettes i rodniveau under inhold og mediearkiv + Ja – indhold af denne type er tilladt i roden - Tilladte typer - Tillad at oprette indhold af en specifik type under denne + Tilladte typer + Tillad at oprette indhold af en specifik type under denne - Vælg child node + Vælg child node - Nedarv faner og egenskaber fra en anden dokumenttype. Nye faner vil blive tilføjet den nuværende dokumenttype eller sammenflettet hvis fanenavnene er ens. - Indholdstypen bliver brugt i en komposition og kan derfor ikke blive anvendt som komposition - Der er ingen indholdstyper tilgængelige at bruge som komposition + Nedarv faner og egenskaber fra en anden dokumenttype. Nye faner vil blive tilføjet den nuværende dokumenttype eller sammenflettet hvis fanenavnene er ens. + Indholdstypen bliver brugt i en komposition og kan derfor ikke blive anvendt som komposition + Der er ingen indholdstyper tilgængelige at bruge som komposition - Tilgængelige editors - Genbrug - Editor indstillinger + Tilgængelige editors + Genbrug + Editor indstillinger - Konfiguration + Konfiguration - Ja, slet + Ja, slet - blev flyttet til - Vælg hvor - skal flyttes til + blev flyttet til + Vælg hvor + skal flyttes til - Alle dokumenttyper - Alle dokumenter - Alle medier + Alle dokumenttyper + Alle dokumenter + Alle medier - som benytter denne dokumenttype vil blive slettet permanent. Bekræft at du også vil slette dem. - som benytter denne medietype vil blive slettet permanent. Bekræft at du også vil slette dem. - som benytter denne medlemstype vil blive slettet permanent. Bekræft at du også vil slette dem. + som benytter denne dokumenttype vil blive slettet permanent. Bekræft at du også vil slette dem. + som benytter denne medietype vil blive slettet permanent. Bekræft at du også vil slette dem. + som benytter denne medlemstype vil blive slettet permanent. Bekræft at du også vil slette dem. - og alle dokumenter, som benytter denne type - og alle medier, som benytter denne type - og alle medlemmer, som benytter denne type + og alle dokumenter, som benytter denne type + og alle medier, som benytter denne type + og alle medlemmer, som benytter denne type - der bruger denne editor vil blive opdateret med de nye indstillinger + der bruger denne editor vil blive opdateret med de nye indstillinger @@ -922,8 +949,6 @@ Mange hilsner fra Umbraco robotten Annulleret Handlingen blev annulleret af et 3. part tilføjelsesprogram - Udgivelsen blev standset af et 3. parts modul - Udgivelsen kunne ikke udgives da publiceringsdato er sat Property type eksisterer allerede Egenskabstype oprettet DataType: %1%]]> @@ -937,7 +962,6 @@ Mange hilsner fra Umbraco robotten Stylesheet gemt uden fejl Datatype gemt Ordbogsnøgle gemt - Udgivelsen fejlede fordi en overordnet side ikke er publiceret Indhold publiceret og nu synligt for besøgende Indhold gemt @@ -1139,11 +1163,11 @@ Mange hilsner fra Umbraco robotten Session udløber - Validation - Valider som email - Valider som tal - Valider som Url - ...eller indtast din egen validering - Feltet er påkrævet + Validation + Valider som email + Valider som tal + Valider som Url + ...eller indtast din egen validering + Feltet er påkrævet From 0624d224a9a9a93021c4b7e847be0a7bb4d1ae8b Mon Sep 17 00:00:00 2001 From: Rasmus Fjord Date: Wed, 2 Nov 2016 20:30:05 +0100 Subject: [PATCH 12/49] Translated set permissions windows --- src/Umbraco.Web.UI/umbraco/config/lang/da.xml | 1 + src/Umbraco.Web.UI/umbraco/config/lang/en.xml | 1 + src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml | 1 + .../umbraco.presentation/umbraco/dialogs/cruds.aspx.cs | 2 +- 4 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/da.xml b/src/Umbraco.Web.UI/umbraco/config/lang/da.xml index 6ac936533b..ad05703939 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/da.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/da.xml @@ -30,6 +30,7 @@ Genindlæs elementer Genudgiv hele sitet Gendan + Sæt rettigheder for siden %0% Rettigheder Fortryd ændringer Send til udgivelse diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/en.xml b/src/Umbraco.Web.UI/umbraco/config/lang/en.xml index f710e54215..d1624d75d4 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/en.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/en.xml @@ -28,6 +28,7 @@ Reload Republish entire site Restore + Set permissions for the page %0% Permissions Rollback Send To Publish diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml b/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml index 80c6faf07b..8d5348bc87 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml @@ -27,6 +27,7 @@ Unpublish Reload Republish entire site + Set permissions for the page %0% Restore Permissions Rollback diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/cruds.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/cruds.aspx.cs index 1634fd370f..3808547db1 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/cruds.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/cruds.aspx.cs @@ -34,7 +34,7 @@ namespace umbraco.dialogs protected void Page_Load(object sender, EventArgs e) { Button1.Text = ui.Text("update"); - pane_form.Text = "Set permissions for the page " + _node.Text; + pane_form.Text = ui.Text("actions", "SetPermissionsForThePage",_node.Text); } override protected void OnInit(EventArgs e) From e015e73abe4793d69ff38135cb9bfd4d92b0d7b5 Mon Sep 17 00:00:00 2001 From: Rasmus Fjord Date: Wed, 2 Nov 2016 20:55:15 +0100 Subject: [PATCH 13/49] Translation of Moving item(media / content) --- src/Umbraco.Web.UI.Client/src/views/content/move.html | 6 ++++-- src/Umbraco.Web.UI.Client/src/views/media/move.html | 6 ++++-- src/Umbraco.Web.UI/umbraco/config/lang/da.xml | 2 ++ src/Umbraco.Web.UI/umbraco/config/lang/en.xml | 2 ++ src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml | 2 ++ 5 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/content/move.html b/src/Umbraco.Web.UI.Client/src/views/content/move.html index b64511ec22..6bf3ca817a 100644 --- a/src/Umbraco.Web.UI.Client/src/views/content/move.html +++ b/src/Umbraco.Web.UI.Client/src/views/content/move.html @@ -3,9 +3,11 @@

- Choose where to move {{currentNode.name}} to in the tree structure below + Choose where to move + {{currentNode.name}} + to in the tree structure below

- +
diff --git a/src/Umbraco.Web.UI.Client/src/views/media/move.html b/src/Umbraco.Web.UI.Client/src/views/media/move.html index 95c30dfc40..3f71340ee3 100644 --- a/src/Umbraco.Web.UI.Client/src/views/media/move.html +++ b/src/Umbraco.Web.UI.Client/src/views/media/move.html @@ -3,8 +3,10 @@

- Choose where to move {{currentNode.name}} to in the tree structure below -

+ Choose where to move + {{currentNode.name}} + to in the tree structure below +

{{error.errorMsg}}

diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/da.xml b/src/Umbraco.Web.UI/umbraco/config/lang/da.xml index ad05703939..c6d18c26f8 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/da.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/da.xml @@ -31,6 +31,8 @@ Genudgiv hele sitet Gendan Sæt rettigheder for siden %0% + Hvor vil du flytte + hen til i træstrukturen? Rettigheder Fortryd ændringer Send til udgivelse diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/en.xml b/src/Umbraco.Web.UI/umbraco/config/lang/en.xml index d1624d75d4..1c646d41db 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/en.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/en.xml @@ -29,6 +29,8 @@ Republish entire site Restore Set permissions for the page %0% + Choose where to move + to in the tree structure below Permissions Rollback Send To Publish diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml b/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml index 8d5348bc87..673c202117 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml @@ -28,6 +28,8 @@ Reload Republish entire site Set permissions for the page %0% + Choose where to move + to in the tree structure below Restore Permissions Rollback From cc5f127dcf8e520556ac4ed2e8ad3f400120a1e4 Mon Sep 17 00:00:00 2001 From: Rasmus Fjord Date: Wed, 2 Nov 2016 20:57:17 +0100 Subject: [PATCH 14/49] Translated "openInNewWindow" to a better sound in danish. --- src/Umbraco.Web.UI/umbraco/config/lang/da.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/da.xml b/src/Umbraco.Web.UI/umbraco/config/lang/da.xml index c6d18c26f8..9c0f3a80f8 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/da.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/da.xml @@ -282,7 +282,7 @@ Link til side - Åbner det linket dokument i et nyt vindue eller fane + Åben linket i et nyt vindue eller fane Åbner det linket dokument i fuld visning af vinduet Åbner det linket dokument i "parent frame" From a83739c269d789f9daf6f7d2645ed72e7e2b2173 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pjengaard=20Bank?= Date: Wed, 2 Nov 2016 20:58:21 +0100 Subject: [PATCH 15/49] Removed old options for linked targets and replaced with checkbox instead in linkpicker --- .../common/overlays/linkpicker/linkpicker.html | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/common/overlays/linkpicker/linkpicker.html b/src/Umbraco.Web.UI.Client/src/views/common/overlays/linkpicker/linkpicker.html index aba5818e01..e063b7bab3 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/overlays/linkpicker/linkpicker.html +++ b/src/Umbraco.Web.UI.Client/src/views/common/overlays/linkpicker/linkpicker.html @@ -18,18 +18,9 @@ - +
From ea67e217960a34f485a1aa9010d3c69544e0204e Mon Sep 17 00:00:00 2001 From: Thomas Nielsen Date: Wed, 2 Nov 2016 21:20:03 +0100 Subject: [PATCH 16/49] Link to mediatype from media properties --- .../Models/Mapping/MediaModelMapper.cs | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web/Models/Mapping/MediaModelMapper.cs b/src/Umbraco.Web/Models/Mapping/MediaModelMapper.cs index d13da67e1f..5f2a8bfd1d 100644 --- a/src/Umbraco.Web/Models/Mapping/MediaModelMapper.cs +++ b/src/Umbraco.Web/Models/Mapping/MediaModelMapper.cs @@ -155,7 +155,27 @@ namespace Umbraco.Web.Models.Mapping genericProperties.Add(link); } - TabsAndPropertiesResolver.MapGenericProperties(media, display, localizedText, genericProperties); + TabsAndPropertiesResolver.MapGenericProperties(media, display, localizedText, genericProperties, properties => { + if (HttpContext.Current != null && UmbracoContext.Current != null && UmbracoContext.Current.Security.CurrentUser != null + && UmbracoContext.Current.Security.CurrentUser.AllowedSections.Any(x => x.Equals(Constants.Applications.Settings))) + { + var docTypeLink = string.Format("#/settings/mediatypes/edit/{0}", media.ContentTypeId); + + //Replace the doc type property + var docTypeProp = properties.First(x => x.Alias == string.Format("{0}doctype", Constants.PropertyEditors.InternalGenericPropertiesPrefix)); + docTypeProp.Value = new List + { + new + { + linkText = media.ContentType.Name, + url = docTypeLink, + target = "_self", icon = "icon-item-arrangement" + } + }; + docTypeProp.View = "urllist"; + } + + }); } } From 71f3948de2d52eb8af0661122faf538806a1eb01 Mon Sep 17 00:00:00 2001 From: Rasmus Fjord Date: Wed, 2 Nov 2016 21:23:02 +0100 Subject: [PATCH 17/49] Translated copy dialog (relate to and include descendants) to dk --- src/Umbraco.Web.UI.Client/src/views/content/copy.html | 7 ++++--- src/Umbraco.Web.UI/umbraco/config/lang/da.xml | 1 + src/Umbraco.Web.UI/umbraco/config/lang/en.xml | 1 + src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml | 1 + 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/content/copy.html b/src/Umbraco.Web.UI.Client/src/views/content/copy.html index 3f2bfcdd3b..371e156513 100644 --- a/src/Umbraco.Web.UI.Client/src/views/content/copy.html +++ b/src/Umbraco.Web.UI.Client/src/views/content/copy.html @@ -51,13 +51,14 @@ - - + + + - + diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/da.xml b/src/Umbraco.Web.UI/umbraco/config/lang/da.xml index 9c0f3a80f8..dee20dd3f6 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/da.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/da.xml @@ -279,6 +279,7 @@ Opret mappe... Relatér til original + Inkludér undersider Link til side diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/en.xml b/src/Umbraco.Web.UI/umbraco/config/lang/en.xml index 1c646d41db..54d54f14ec 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/en.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/en.xml @@ -291,6 +291,7 @@ Create folder... Relate to original + Include descendants The friendliest community Link to page diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml b/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml index 673c202117..58eed32205 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml @@ -293,6 +293,7 @@ Create folder... Relate to original + Include descendants The friendliest community Link to page From 018f9f17769263c04e82b952a076e7fde95c883e Mon Sep 17 00:00:00 2001 From: Rasmus Fjord Date: Wed, 2 Nov 2016 21:30:18 +0100 Subject: [PATCH 18/49] removed hg ignore --- .hgignore | 58 ------------------------------------------------------- 1 file changed, 58 deletions(-) delete mode 100644 .hgignore diff --git a/.hgignore b/.hgignore deleted file mode 100644 index 13307d790b..0000000000 --- a/.hgignore +++ /dev/null @@ -1,58 +0,0 @@ -syntax: glob -*.obj -*.exe -*.pdb -*.user -*.aps -*.pch -*.vspscc -[Bb]in -[Db]ebug*/ -obj/ -[Rr]elease*/ -_ReSharper*/ -*.ncrunchsolution -*.ncrunchsolution.user -*.ncrunchproject -*.crunchsolution.cache -[Tt]est[Rr]esult* -[Bb]uild[Ll]og.* -*.[Pp]ublish.xml -*.suo -[sS]ource -[sS]andbox -umbraco.config -*.vs10x -App_Data\TEMP\* -umbraco\presentation\umbraco\plugins\* -umbraco\presentation\usercontrols\* -umbraco\presentation\scripts\* -umbraco\presentation\fonts\* -umbraco\presentation\css\* - -src\Umbraco.Web.UI\css\* -src\Umbraco.Web.UI\App_Code\* -src\Umbraco.Web.UI\App_Data\* -src\Umbraco.Tests\App_Data\* -src\Umbraco.Web.UI\media\* -src\Umbraco.Web.UI\masterpages\* -src\Umbraco.Web.UI\macroScripts\* -src\Umbraco.Web.UI\xslt\* -umbraco\presentation\umbraco\plugins\uComponents\uComponentsInstaller.ascx -umbraco\presentation\packages\uComponents\MultiNodePicker\CustomTreeService.asmx -_BuildOutput/* -*.ncrunchsolution -build/UmbracoCms.AllBinaries.zip -build/UmbracoCms.WebPI.zip -build/UmbracoCms.zip -build/*.nupkg -src/Umbraco.Tests/config/applications.config -src/Umbraco.Tests/config/trees.config -src/Umbraco.Web.UI/web.config -*.orig -src/Umbraco.Tests/config/404handlers.config -src/Umbraco.Web.UI/Views/*.cshtml -src/Umbraco.Web.UI/Views/*.vbhtml -src/Umbraco.Tests/config/umbracoSettings.config -src/Umbraco.Web.UI/App_Plugins/* -src/Umbraco.Web.UI/Views/* From 7b345d6cb0243db4620af6eb66435288ea62e191 Mon Sep 17 00:00:00 2001 From: AronGreen Date: Wed, 2 Nov 2016 22:02:47 +0100 Subject: [PATCH 19/49] Danish translations related to Redirect URL Management --- src/Umbraco.Web.UI/umbraco/config/lang/da.xml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/da.xml b/src/Umbraco.Web.UI/umbraco/config/lang/da.xml index ffb0a9d96b..b0c7f9d639 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/da.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/da.xml @@ -1146,4 +1146,21 @@ Mange hilsner fra Umbraco robotten ...eller indtast din egen validering Feltet er påkrævet + + Slå URL tracker fra + Slå URL tracker til + Original URL + Viderestillet til + Der er ikke lavet nogen viderestillinger + Når en udgivet side bliver omdøbt eller flyttet, vil en viderestilling automatisk blive lavet til den nye side. + Fjern + Er du sikker på at du vil fjerne viderestillingen fra '%0%' til '%1%'? + Viderestillings URL fjernet. + Fejl under fjernelse af viderestillings URL. + Er du sikker på at du vil slå URL trackeren fra? + URL tracker er nu slået fra. + Der opstod en fejl under forsøget på at slå URL trackeren fra, der findes mere information i logfilen. + URL tracker er nu slået fra. + Der opstod en fejl under forsøget på at slå URL trackeren til, der findes mere information i logfilen. + From 24402388b4b8b669987e65c2a1131e031dca77a2 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 3 Nov 2016 09:57:10 +0100 Subject: [PATCH 20/49] position the overlay to the right --- .../src/views/components/upload/umb-file-dropzone.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/components/upload/umb-file-dropzone.html b/src/Umbraco.Web.UI.Client/src/views/components/upload/umb-file-dropzone.html index 35d375e94d..6b05593e11 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/upload/umb-file-dropzone.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/upload/umb-file-dropzone.html @@ -102,7 +102,7 @@ ng-if="mediatypepickerOverlay.show" model="mediatypepickerOverlay" view="mediatypepickerOverlay.view" - position="center"> + position="right"> From 85c2ec68ac641ed013ec12dd5b3d3079b8d0c7d9 Mon Sep 17 00:00:00 2001 From: Claus Date: Thu, 3 Nov 2016 10:39:59 +0100 Subject: [PATCH 21/49] allowing default image and file media types at root. --- .../Persistence/Migrations/Initial/BaseDataCreation.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Core/Persistence/Migrations/Initial/BaseDataCreation.cs b/src/Umbraco.Core/Persistence/Migrations/Initial/BaseDataCreation.cs index 9570024b09..8b33599436 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Initial/BaseDataCreation.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Initial/BaseDataCreation.cs @@ -149,8 +149,8 @@ namespace Umbraco.Core.Persistence.Migrations.Initial private void CreateCmsContentTypeData() { _database.Insert("cmsContentType", "pk", false, new ContentTypeDto { PrimaryKey = 532, NodeId = 1031, Alias = Constants.Conventions.MediaTypes.Folder, Icon = "icon-folder", Thumbnail = "icon-folder", IsContainer = false, AllowAtRoot = true }); - _database.Insert("cmsContentType", "pk", false, new ContentTypeDto { PrimaryKey = 533, NodeId = 1032, Alias = Constants.Conventions.MediaTypes.Image, Icon = "icon-picture", Thumbnail = "icon-picture" }); - _database.Insert("cmsContentType", "pk", false, new ContentTypeDto { PrimaryKey = 534, NodeId = 1033, Alias = Constants.Conventions.MediaTypes.File, Icon = "icon-document", Thumbnail = "icon-document" }); + _database.Insert("cmsContentType", "pk", false, new ContentTypeDto { PrimaryKey = 533, NodeId = 1032, Alias = Constants.Conventions.MediaTypes.Image, Icon = "icon-picture", Thumbnail = "icon-picture", AllowAtRoot = true }); + _database.Insert("cmsContentType", "pk", false, new ContentTypeDto { PrimaryKey = 534, NodeId = 1033, Alias = Constants.Conventions.MediaTypes.File, Icon = "icon-document", Thumbnail = "icon-document", AllowAtRoot = true }); _database.Insert("cmsContentType", "pk", false, new ContentTypeDto { PrimaryKey = 531, NodeId = 1044, Alias = Constants.Conventions.MemberTypes.DefaultAlias, Icon = "icon-user", Thumbnail = "icon-user" }); } From 0441827578eb3d27dcba2cd585771645e0957799 Mon Sep 17 00:00:00 2001 From: Claus Date: Thu, 3 Nov 2016 10:41:06 +0100 Subject: [PATCH 22/49] using the provided media type when uploading images, instead of using default Image media type. --- src/Umbraco.Web/Editors/MediaController.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web/Editors/MediaController.cs b/src/Umbraco.Web/Editors/MediaController.cs index 08140f9c66..41551d099d 100644 --- a/src/Umbraco.Web/Editors/MediaController.cs +++ b/src/Umbraco.Web/Editors/MediaController.cs @@ -532,7 +532,16 @@ namespace Umbraco.Web.Editors var mediaType = Constants.Conventions.MediaTypes.File; if (UmbracoConfig.For.UmbracoSettings().Content.ImageFileTypes.Contains(ext)) - mediaType = Constants.Conventions.MediaTypes.Image; + { + if (result.FormData.ContainsKey("contentTypeAlias")) + { + mediaType = result.FormData["contentTypeAlias"]; + } + else + { + mediaType = Constants.Conventions.MediaTypes.Image; + } + } //TODO: make the media item name "nice" since file names could be pretty ugly, we have // string extensions to do much of this but we'll need: From 22f37d02dc7efbaec066bedc04051fa40c3529e4 Mon Sep 17 00:00:00 2001 From: Andy Felton Date: Thu, 3 Nov 2016 16:00:04 +0000 Subject: [PATCH 23/49] Added missing colon --- src/Umbraco.Web.UI/umbraco/config/lang/en.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/en.xml b/src/Umbraco.Web.UI/umbraco/config/lang/en.xml index f710e54215..58a8a26c2b 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/en.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/en.xml @@ -1359,8 +1359,8 @@ To manage your website, simply open the Umbraco back office and start adding con There was an error, check log for full error: %0%. Members - Total XML: %0%, Total: %1%, Total invalid: %2% - Media - Total XML: %0%, Total: %1%, Total invalid %2% - Content - Total XML: %0%, Total published: %1%, Total invalid %2% + Media - Total XML: %0%, Total: %1%, Total invalid: %2% + Content - Total XML: %0%, Total published: %1%, Total invalid: %2% Your site certificate was marked as valid. Certificate validation error: '%0%' From b198ecbc022976fe765fb050b6525e46f34586c9 Mon Sep 17 00:00:00 2001 From: Andy Felton Date: Thu, 3 Nov 2016 16:51:06 +0000 Subject: [PATCH 24/49] Modifed grammer as follows MacroErrors are set to 'throw' which will prevent some or all pages in your site from loading completely when there's any errors in macros. Rectifying this will set the value to 'inline'. modifed to "when there's any errors in macros" should be replaced with "if there are any errors in macros" --- src/Umbraco.Web.UI/umbraco/config/lang/en.xml | 2 +- src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/en.xml b/src/Umbraco.Web.UI/umbraco/config/lang/en.xml index f710e54215..fc8deca43d 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/en.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/en.xml @@ -1341,7 +1341,7 @@ To manage your website, simply open the Umbraco back office and start adding con Custom errors successfully set to '%0%'. MacroErrors are set to '%0%'. - MacroErrors are set to '%0%' which will prevent some or all pages in your site from loading completely when there's any errors in macros. Rectifying this will set the value to '%1%'. + MacroErrors are set to '%0%' which will prevent some or all pages in your site from loading completely if there are any errors in macros. Rectifying this will set the value to '%1%'. MacroErrors are now set to '%0%'. + Zatwierdź Typ Szukaj W górę @@ -356,8 +356,8 @@ Możesz dodać dodatkowe języki w menu "Języki" po lewej stronie.]]> Witaj... Szerokość Tak - Reorder - I am done reordering + Zmień kolejność + Kolejność została zmieniona Kolor tła @@ -786,7 +786,7 @@ Miłego dnia!]]> Administrator Pole kategorii - TRANSLATE ME: 'Change Your Password' + Zmień hasło! TRANSLATE ME: 'You can change your password for accessing the Umbraco Back Office by filling out the form below and click the 'Change Password' button' Zawartość Opis @@ -800,10 +800,10 @@ Miłego dnia!]]> Sekcje Wyłącz dostęp do Umbraco Hasło - TRANSLATE ME: 'Your password has been changed!' - TRANSLATE ME: 'Please confirm the new password' - TRANSLATE ME: 'Enter your new password' - TRANSLATE ME: 'Your new password cannot be blank!' + Twoje hasło zostało zmienione! + Proszę potwierdź nowe hasło! + Wprowadź nowe hasło + Nowe hasło nie może byc puste! TRANSLATE ME: 'There was a difference between the new password and the confirmed password. Please try again!' TRANSLATE ME: 'The confirmed password doesn't match the new password!' Zastąp prawa dostępu dla węzłów potomnych From a96f48d0a8b02e7558ebfdee938af3226ea2a59b Mon Sep 17 00:00:00 2001 From: Claus Date: Fri, 4 Nov 2016 13:52:36 +0100 Subject: [PATCH 27/49] changing media controller logic. --- src/Umbraco.Web/Editors/MediaController.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Umbraco.Web/Editors/MediaController.cs b/src/Umbraco.Web/Editors/MediaController.cs index 41551d099d..932b3f6766 100644 --- a/src/Umbraco.Web/Editors/MediaController.cs +++ b/src/Umbraco.Web/Editors/MediaController.cs @@ -531,17 +531,17 @@ namespace Umbraco.Web.Editors { var mediaType = Constants.Conventions.MediaTypes.File; - if (UmbracoConfig.For.UmbracoSettings().Content.ImageFileTypes.Contains(ext)) + if (result.FormData["contentTypeAlias"] == Constants.Conventions.MediaTypes.Image) { - if (result.FormData.ContainsKey("contentTypeAlias")) - { - mediaType = result.FormData["contentTypeAlias"]; - } - else + if (UmbracoConfig.For.UmbracoSettings().Content.ImageFileTypes.Contains(ext)) { mediaType = Constants.Conventions.MediaTypes.Image; } } + else + { + mediaType = result.FormData["contentTypeAlias"]; + } //TODO: make the media item name "nice" since file names could be pretty ugly, we have // string extensions to do much of this but we'll need: From 8944870d4ff9a14bf02fdf0d2f7079b100b0b523 Mon Sep 17 00:00:00 2001 From: Ivar Date: Mon, 24 Oct 2016 22:41:44 +0000 Subject: [PATCH 28/49] Renamed icon-globe---europe-africa to icon-globe-europe-africa --- src/Umbraco.Web.UI.Client/src/less/helveticons.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/less/helveticons.less b/src/Umbraco.Web.UI.Client/src/less/helveticons.less index a3c2072d86..0e4695d761 100644 --- a/src/Umbraco.Web.UI.Client/src/less/helveticons.less +++ b/src/Umbraco.Web.UI.Client/src/less/helveticons.less @@ -1569,7 +1569,7 @@ i.small{ .icon-hd:before { content: "\e1f9"; } -.icon-globe-europe---africa:before { +.icon-globe-europe-africa:before { content: "\e1fa"; } .icon-hat:before { From fcca95787b30d88d6733f22faa7e848e055df331 Mon Sep 17 00:00:00 2001 From: Claus Date: Mon, 7 Nov 2016 13:03:43 +0100 Subject: [PATCH 29/49] fixing backwards compatibility. --- src/Umbraco.Web.UI.Client/src/less/helveticons.less | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/less/helveticons.less b/src/Umbraco.Web.UI.Client/src/less/helveticons.less index 0e4695d761..9a317e09fb 100644 --- a/src/Umbraco.Web.UI.Client/src/less/helveticons.less +++ b/src/Umbraco.Web.UI.Client/src/less/helveticons.less @@ -1569,7 +1569,8 @@ i.small{ .icon-hd:before { content: "\e1f9"; } -.icon-globe-europe-africa:before { +.icon-globe-europe-africa:before, +.icon-globe-europe---africa:before { content: "\e1fa"; } .icon-hat:before { From e429f8611ec4e837276ca668770f47c0f3c70e04 Mon Sep 17 00:00:00 2001 From: crgrieve Date: Mon, 7 Nov 2016 20:53:59 +0000 Subject: [PATCH 30/49] Remove all whitespace when parsing MNTP allowed doctypes. --- .../src/views/common/dialogs/treepicker.controller.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/treepicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/treepicker.controller.js index 2d8d38cf50..740791abf9 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/treepicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/treepicker.controller.js @@ -259,7 +259,7 @@ angular.module("umbraco").controller("Umbraco.Dialogs.TreePickerController", } }); } else { - var a = dialogOptions.filter.toLowerCase().split(','); + var a = dialogOptions.filter.toLowerCase().replace(/\s/g, '').split(','); angular.forEach(nodes, function (value, key) { var found = a.indexOf(value.metaData.contentType.toLowerCase()) >= 0; From c0a2326a8d2ccce554f16247fc740c3c55da6443 Mon Sep 17 00:00:00 2001 From: crgrieve Date: Mon, 7 Nov 2016 21:03:57 +0000 Subject: [PATCH 31/49] Removing whitespace when parsing MNTP comma separated list. --- .../src/views/common/dialogs/treepicker.controller.js | 2 +- .../views/common/overlays/treepicker/treepicker.controller.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/treepicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/treepicker.controller.js index 740791abf9..2d8d38cf50 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/treepicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/treepicker.controller.js @@ -259,7 +259,7 @@ angular.module("umbraco").controller("Umbraco.Dialogs.TreePickerController", } }); } else { - var a = dialogOptions.filter.toLowerCase().replace(/\s/g, '').split(','); + var a = dialogOptions.filter.toLowerCase().split(','); angular.forEach(nodes, function (value, key) { var found = a.indexOf(value.metaData.contentType.toLowerCase()) >= 0; diff --git a/src/Umbraco.Web.UI.Client/src/views/common/overlays/treepicker/treepicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/overlays/treepicker/treepicker.controller.js index e74bfd20a4..8e87a2daff 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/overlays/treepicker/treepicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/overlays/treepicker/treepicker.controller.js @@ -326,7 +326,7 @@ angular.module("umbraco").controller("Umbraco.Overlays.TreePickerController", } }); } else { - var a = dialogOptions.filter.toLowerCase().split(','); + var a = dialogOptions.filter.toLowerCase().replace(/\s/g, '').split(','); angular.forEach(nodes, function (value, key) { var found = a.indexOf(value.metaData.contentType.toLowerCase()) >= 0; From 957096a70a6930955361654ed9a9b562852f1269 Mon Sep 17 00:00:00 2001 From: Claus Date: Tue, 8 Nov 2016 10:33:05 +0100 Subject: [PATCH 32/49] fixing links to be https. --- .../default/StartupDashboardIntro.html | 166 +++++++++--------- 1 file changed, 83 insertions(+), 83 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/dashboard/default/StartupDashboardIntro.html b/src/Umbraco.Web.UI.Client/src/views/dashboard/default/StartupDashboardIntro.html index 73a6399b67..3782898312 100644 --- a/src/Umbraco.Web.UI.Client/src/views/dashboard/default/StartupDashboardIntro.html +++ b/src/Umbraco.Web.UI.Client/src/views/dashboard/default/StartupDashboardIntro.html @@ -1,44 +1,44 @@ -
- - - -
- -
-
- - -
-
- - -
-
- - -
-
-
-
-
- -
-
- -
-
-
- - -
-
- - - - -
-

Welcome to The Friendly CMS

+
+ + + +
+ +
+
+ + +
+
+ + +
+
+ + +
+
+
+
+
+ +
+
+ +
+
+
+ + +
+
+ + + + +
+

Welcome to The Friendly CMS

Thank you for choosing Umbraco - we think this could be the beginning of something beautiful. While it may feel overwhelming at first, we've done a lot to make the learning curve as smooth and fast as possible.

@@ -50,46 +50,46 @@
  • Watch our tutorial videos (some are free, some require a subscription)
  • Find out about our productivity boosting tools and commercial support
  • Find out about real-life training and certification opportunities
  • - - -
    -
    - - Umbraco.TV - Hours of Umbraco Video Tutorials - - - - -

    Umbraco.TV - Learn from the source!

    -
    - -

    - Umbraco.TV will help you go from zero to Umbraco - hero at a pace that suits you. Our easy to follow - online training videos will give you the fundamental - knowledge to start building awesome Umbraco websites. -

    -
    - -
    - - - Our Umbraco - - - -

    Our Umbraco - The Friendliest Community

    -
    - -

    - Our Umbraco - the official community site is your one - stop for everything Umbraco. Whether you need a - question answered or looking for cool plugins, the - worlds best community is just a click away. -

    - -
    -
    -
    - + + +
    +
    + + Umbraco.TV - Hours of Umbraco Video Tutorials + + + + +

    Umbraco.TV - Learn from the source!

    +
    + +

    + Umbraco.TV will help you go from zero to Umbraco + hero at a pace that suits you. Our easy to follow + online training videos will give you the fundamental + knowledge to start building awesome Umbraco websites. +

    +
    + +
    + + + Our Umbraco + + + +

    Our Umbraco - The Friendliest Community

    +
    + +

    + Our Umbraco - the official community site is your one + stop for everything Umbraco. Whether you need a + question answered or looking for cool plugins, the + worlds best community is just a click away. +

    + +
    +
    +
    +
    \ No newline at end of file From 4a42bfa9bbdfbe0be124f8ec179ca764a0d5bbf3 Mon Sep 17 00:00:00 2001 From: Claus Date: Tue, 8 Nov 2016 10:53:29 +0100 Subject: [PATCH 33/49] U4-9160 Headline in the "Republish entire site" dialog is not translated --- .../umbraco_client/Application/UmbracoApplicationActions.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI/umbraco_client/Application/UmbracoApplicationActions.js b/src/Umbraco.Web.UI/umbraco_client/Application/UmbracoApplicationActions.js index 46b7a15e48..4c9017e159 100644 --- a/src/Umbraco.Web.UI/umbraco_client/Application/UmbracoApplicationActions.js +++ b/src/Umbraco.Web.UI/umbraco_client/Application/UmbracoApplicationActions.js @@ -281,7 +281,7 @@ Umbraco.Application.Actions = function() { actionRePublish: function() { /// - UmbClientMgr.openModalWindow('dialogs/republish.aspx?rnd=' + this._utils.generateRandom(), 'Republishing entire site', true, 450, 210); + UmbClientMgr.openModalWindow('dialogs/republish.aspx?rnd=' + this._utils.generateRandom(), uiKeys['actions_republish'], true, 450, 210); }, actionAssignDomain: function() { From 16ae5cf6345122395d944e91fd3937027198fcc0 Mon Sep 17 00:00:00 2001 From: Thomas Nielsen Date: Tue, 8 Nov 2016 23:00:14 +0100 Subject: [PATCH 34/49] Link to member type from member properties --- .../Models/Mapping/MemberModelMapper.cs | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web/Models/Mapping/MemberModelMapper.cs b/src/Umbraco.Web/Models/Mapping/MemberModelMapper.cs index 050fe3c726..6d4bdd7941 100644 --- a/src/Umbraco.Web/Models/Mapping/MemberModelMapper.cs +++ b/src/Umbraco.Web/Models/Mapping/MemberModelMapper.cs @@ -233,7 +233,26 @@ namespace Umbraco.Web.Models.Mapping }; - TabsAndPropertiesResolver.MapGenericProperties(member, display, localizedText, genericProperties); + TabsAndPropertiesResolver.MapGenericProperties(member, display, localizedText, genericProperties, properties => { + if (HttpContext.Current != null && UmbracoContext.Current != null && UmbracoContext.Current.Security.CurrentUser != null + && UmbracoContext.Current.Security.CurrentUser.AllowedSections.Any(x => x.Equals(Constants.Applications.Settings))) + { + var docTypeLink = string.Format("#/member/memberTypes/edit/{0}", member.ContentTypeId); + + //Replace the doc type property + var docTypeProp = properties.First(x => x.Alias == string.Format("{0}doctype", Constants.PropertyEditors.InternalGenericPropertiesPrefix)); + docTypeProp.Value = new List + { + new + { + linkText = member.ContentType.Name, + url = docTypeLink, + target = "_self", icon = "icon-item-arrangement" + } + }; + docTypeProp.View = "urllist"; + } + }); //check if there's an approval field var provider = membersProvider as global::umbraco.providers.members.UmbracoMembershipProvider; From 981c0b83d3ea2784173f4273a57dee2457f75cfb Mon Sep 17 00:00:00 2001 From: Thomas Nielsen Date: Tue, 8 Nov 2016 23:16:10 +0100 Subject: [PATCH 35/49] Oops wrong pull request --- .../Models/Mapping/MemberModelMapper.cs | 21 +------------------ 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/src/Umbraco.Web/Models/Mapping/MemberModelMapper.cs b/src/Umbraco.Web/Models/Mapping/MemberModelMapper.cs index 6d4bdd7941..050fe3c726 100644 --- a/src/Umbraco.Web/Models/Mapping/MemberModelMapper.cs +++ b/src/Umbraco.Web/Models/Mapping/MemberModelMapper.cs @@ -233,26 +233,7 @@ namespace Umbraco.Web.Models.Mapping }; - TabsAndPropertiesResolver.MapGenericProperties(member, display, localizedText, genericProperties, properties => { - if (HttpContext.Current != null && UmbracoContext.Current != null && UmbracoContext.Current.Security.CurrentUser != null - && UmbracoContext.Current.Security.CurrentUser.AllowedSections.Any(x => x.Equals(Constants.Applications.Settings))) - { - var docTypeLink = string.Format("#/member/memberTypes/edit/{0}", member.ContentTypeId); - - //Replace the doc type property - var docTypeProp = properties.First(x => x.Alias == string.Format("{0}doctype", Constants.PropertyEditors.InternalGenericPropertiesPrefix)); - docTypeProp.Value = new List - { - new - { - linkText = member.ContentType.Name, - url = docTypeLink, - target = "_self", icon = "icon-item-arrangement" - } - }; - docTypeProp.View = "urllist"; - } - }); + TabsAndPropertiesResolver.MapGenericProperties(member, display, localizedText, genericProperties); //check if there's an approval field var provider = membersProvider as global::umbraco.providers.members.UmbracoMembershipProvider; From cbfd04e95006308d70905a0e3c6007c0373535d6 Mon Sep 17 00:00:00 2001 From: Thomas Nielsen Date: Tue, 8 Nov 2016 23:37:29 +0100 Subject: [PATCH 36/49] Link to member type from member properties --- .../Models/Mapping/MemberModelMapper.cs | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web/Models/Mapping/MemberModelMapper.cs b/src/Umbraco.Web/Models/Mapping/MemberModelMapper.cs index 050fe3c726..6d4bdd7941 100644 --- a/src/Umbraco.Web/Models/Mapping/MemberModelMapper.cs +++ b/src/Umbraco.Web/Models/Mapping/MemberModelMapper.cs @@ -233,7 +233,26 @@ namespace Umbraco.Web.Models.Mapping }; - TabsAndPropertiesResolver.MapGenericProperties(member, display, localizedText, genericProperties); + TabsAndPropertiesResolver.MapGenericProperties(member, display, localizedText, genericProperties, properties => { + if (HttpContext.Current != null && UmbracoContext.Current != null && UmbracoContext.Current.Security.CurrentUser != null + && UmbracoContext.Current.Security.CurrentUser.AllowedSections.Any(x => x.Equals(Constants.Applications.Settings))) + { + var docTypeLink = string.Format("#/member/memberTypes/edit/{0}", member.ContentTypeId); + + //Replace the doc type property + var docTypeProp = properties.First(x => x.Alias == string.Format("{0}doctype", Constants.PropertyEditors.InternalGenericPropertiesPrefix)); + docTypeProp.Value = new List + { + new + { + linkText = member.ContentType.Name, + url = docTypeLink, + target = "_self", icon = "icon-item-arrangement" + } + }; + docTypeProp.View = "urllist"; + } + }); //check if there's an approval field var provider = membersProvider as global::umbraco.providers.members.UmbracoMembershipProvider; From 7018969d14186c2f643ee3b2241f933f8b383a8c Mon Sep 17 00:00:00 2001 From: Claus Date: Wed, 9 Nov 2016 09:29:43 +0100 Subject: [PATCH 37/49] removing unused language keys. --- src/Umbraco.Web.UI/umbraco/config/lang/da.xml | 11 ---- src/Umbraco.Web.UI/umbraco/config/lang/en.xml | 12 ---- .../umbraco/config/lang/en_us.xml | 12 ---- src/Umbraco.Web.UI/umbraco/config/lang/fr.xml | 58 ++++++++----------- src/Umbraco.Web.UI/umbraco/config/lang/ja.xml | 14 +---- src/Umbraco.Web.UI/umbraco/config/lang/ru.xml | 12 ---- 6 files changed, 24 insertions(+), 95 deletions(-) diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/da.xml b/src/Umbraco.Web.UI/umbraco/config/lang/da.xml index b6dac0afc9..b0452fb631 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/da.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/da.xml @@ -277,18 +277,11 @@ Vælg Se cache element Opret mappe... - Relatér til original Inkludér undersider - Link til side - Åben linket i et nyt vindue eller fane - Åbner det linket dokument i fuld visning af vinduet - Åbner det linket dokument i "parent frame" - Link til medie - Vælg medie Vælg ikon Vælg item @@ -297,14 +290,10 @@ Vælg indhold Vælg medlem Vælg medlemsgruppe - Der er ingen parametre for denne makro - Link dit Fjern link fra dit - konto - Vælg editor diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/en.xml b/src/Umbraco.Web.UI/umbraco/config/lang/en.xml index 545c32480f..bdc2647563 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/en.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/en.xml @@ -289,19 +289,12 @@ Pick item View Cache Item Create folder... - Relate to original Include descendants The friendliest community - Link to page - Opens the linked document in a new window or tab - Opens the linked document in the full body of the window - Opens the linked document in the parent frame - Link to media - Select media Select icon Select item @@ -311,19 +304,14 @@ Select member Select member group No icons were found - There are no parameters for this macro - External login providers Exception Details Stacktrace Inner Exception - Link your Un-Link your - account - Select editor diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml b/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml index c0ef0b8c37..7544cacc0c 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml @@ -291,19 +291,12 @@ Pick item View Cache Item Create folder... - Relate to original Include descendants The friendliest community - Link to page - Opens the linked document in a new window or tab - Opens the linked document in the full body of the window - Opens the linked document in the parent frame - Link to media - Select media Select icon Select item @@ -312,19 +305,14 @@ Select content Select member Select member group - There are no parameters for this macro - External login providers Exception Details Stacktrace Inner Exception - Link your Un-Link your - account - Select editor diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/fr.xml b/src/Umbraco.Web.UI/umbraco/config/lang/fr.xml index 40e18ce298..39cafeef7f 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/fr.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/fr.xml @@ -287,41 +287,29 @@ Cliquez sur l'image pour la voir en taille réelle Sélectionner un élément Voir l'élément de cache - Créer un répertoire... - - Lier à l'original - La communauté la plus amicale - - Lier à la page - - Ouvre le document lié dans une nouvelle fenêtre ou un nouvel onglet - Ouvre le document lié dans l'entièreté de la fenêtre - Ouvre le document lié dans le conteneur parent - - Lier à un media - - Sélectionner le media - Sélectionner l'icône - Sélectionner l'élément - Sélectionner le lien - Sélectionner la macro - Sélectionner le contenu - Sélectionner le membre - Sélectionner le groupe de membres - - Il n'y a pas de paramètres pour cette macro - - Fournisseurs externes d'identification - Détails de l'exception - Trace d'exécution - Exception interne - - Liez votre - Enlevez votre - - compte - - Sélectionner un éditeur + Créer un répertoire... + Lier à l'original + La communauté la plus amicale + Lier à la page + Ouvre le document lié dans une nouvelle fenêtre ou un nouvel onglet + Lier à un media + Sélectionner le media + Sélectionner l'icône + Sélectionner l'élément + Sélectionner le lien + Sélectionner la macro + Sélectionner le contenu + Sélectionner le membre + Sélectionner le groupe de membres + Il n'y a pas de paramètres pour cette macro + Fournisseurs externes d'identification + Détails de l'exception + Trace d'exécution + Exception interne + Liez votre + Enlevez votre + compte + Sélectionner un éditeur クリックすると画像がフルサイズで表示されます 項目の選択 キャッシュされている項目の表示 - フォルダーの作成... - + フォルダーの作成... オリジナルに関連付ける フレンドリーなコミュニティ - ページへリンク - リンク ドキュメントを新しいウィンドウまたはタブで開く - リンク ドキュメントをウィンドウ全文表示で開く - 親フレームでリンク ドキュメントを開く - メディアへリンク - メディアの選択 アイコンの選択 アイテムの選択 @@ -296,19 +289,14 @@ コンテンツの選択 メンバーの選択 メンバー グループの選択 - このマクロのパラメーターはありません - 外部ログイン プロバイダー 例外の詳細 スタックトレース Inner Exception - 次をリンク: 次をリンク解除: - アカウント - エディターの選択 diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/ru.xml b/src/Umbraco.Web.UI/umbraco/config/lang/ru.xml index d71b4423aa..255bf62d5d 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/ru.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/ru.xml @@ -340,18 +340,11 @@ Выберите элемент Просмотр элемента кэша Создать папку... - Связать с оригиналом Самое дружелюбное сообщество - Ссылка на страницу - Открывает документ по ссылке в новом окне или вкладке браузера - Открывает документ по ссылке в полноэкранном режиме - Открывает документ по ссылке в родительском фрейме - Ссылка на медиа-файл - Выбрать медиа Выбрать значок Выбрать элемент @@ -360,19 +353,14 @@ Выбрать содержимое Выбрать участника Выбрать группу участников - Это макрос без параметров - Провайдеры аутентификации Подробное сообщение об ошибке Трассировка стека Внутренняя ошибка - Связать Разорвать связь - учетную запись - Выбрать редактор From ff2805c428b4ef7318297fb7dd8f0331cb54a7d9 Mon Sep 17 00:00:00 2001 From: Claus Date: Wed, 9 Nov 2016 11:13:35 +0100 Subject: [PATCH 38/49] mostly just formatting and cleanup - no changes as such. --- .../Models/Mapping/ContentModelMapper.cs | 132 +++++--------- .../Models/Mapping/MediaModelMapper.cs | 96 ++++------- .../Models/Mapping/MemberModelMapper.cs | 161 +++++++----------- 3 files changed, 144 insertions(+), 245 deletions(-) diff --git a/src/Umbraco.Web/Models/Mapping/ContentModelMapper.cs b/src/Umbraco.Web/Models/Mapping/ContentModelMapper.cs index b7a6ac1f4a..e179159e7c 100644 --- a/src/Umbraco.Web/Models/Mapping/ContentModelMapper.cs +++ b/src/Umbraco.Web/Models/Mapping/ContentModelMapper.cs @@ -6,7 +6,6 @@ using System.Web; using System.Web.Mvc; using System.Web.Routing; using AutoMapper; -using umbraco; using Umbraco.Core; using Umbraco.Core.Models; using Umbraco.Core.Models.Mapping; @@ -29,38 +28,18 @@ namespace Umbraco.Web.Models.Mapping //FROM IContent TO ContentItemDisplay config.CreateMap() - .ForMember( - dto => dto.Owner, - expression => expression.ResolveUsing(new OwnerResolver())) - .ForMember( - dto => dto.Updater, - expression => expression.ResolveUsing(new CreatorResolver())) - .ForMember( - dto => dto.Icon, - expression => expression.MapFrom(content => content.ContentType.Icon)) - .ForMember( - dto => dto.ContentTypeAlias, - expression => expression.MapFrom(content => content.ContentType.Alias)) - .ForMember( - dto => dto.ContentTypeName, - expression => expression.MapFrom(content => content.ContentType.Name)) - .ForMember( - dto => dto.IsContainer, - expression => expression.MapFrom(content => content.ContentType.IsContainer)) - .ForMember(display => display.IsChildOfListView, expression => expression.Ignore()) - .ForMember( - dto => dto.Trashed, - expression => expression.MapFrom(content => content.Trashed)) - .ForMember( - dto => dto.PublishDate, - expression => expression.MapFrom(content => GetPublishedDate(content, applicationContext))) - .ForMember( - dto => dto.TemplateAlias, expression => expression.MapFrom(content => content.Template.Alias)) - .ForMember( - dto => dto.HasPublishedVersion, - expression => expression.MapFrom(content => content.HasPublishedVersion)) - .ForMember( - dto => dto.Urls, + .ForMember(display => display.Owner, expression => expression.ResolveUsing(new OwnerResolver())) + .ForMember(display => display.Updater, expression => expression.ResolveUsing(new CreatorResolver())) + .ForMember(display => display.Icon, expression => expression.MapFrom(content => content.ContentType.Icon)) + .ForMember(display => display.ContentTypeAlias, expression => expression.MapFrom(content => content.ContentType.Alias)) + .ForMember(display => display.ContentTypeName, expression => expression.MapFrom(content => content.ContentType.Name)) + .ForMember(display => display.IsContainer, expression => expression.MapFrom(content => content.ContentType.IsContainer)) + .ForMember(display => display.IsChildOfListView, expression => expression.Ignore()) + .ForMember(display => display.Trashed, expression => expression.MapFrom(content => content.Trashed)) + .ForMember(display => display.PublishDate, expression => expression.MapFrom(content => GetPublishedDate(content, applicationContext))) + .ForMember(display => display.TemplateAlias, expression => expression.MapFrom(content => content.Template.Alias)) + .ForMember(display => display.HasPublishedVersion, expression => expression.MapFrom(content => content.HasPublishedVersion)) + .ForMember(display => display.Urls, expression => expression.MapFrom(content => UmbracoContext.Current == null ? new[] {"Cannot generate urls without a current Umbraco Context"} @@ -74,47 +53,28 @@ namespace Umbraco.Web.Models.Mapping .ForMember(display => display.Tabs, expression => expression.ResolveUsing(new TabsAndPropertiesResolver(applicationContext.Services.TextService))) .ForMember(display => display.AllowedActions, expression => expression.ResolveUsing( new ActionButtonsResolver(new Lazy(() => applicationContext.Services.UserService)))) - .AfterMap((media, display) => AfterMap(media, display, applicationContext.Services.DataTypeService, applicationContext.Services.TextService, + .AfterMap((content, display) => AfterMap(content, display, applicationContext.Services.DataTypeService, applicationContext.Services.TextService, applicationContext.Services.ContentTypeService)); //FROM IContent TO ContentItemBasic config.CreateMap>() - .ForMember( - dto => dto.Owner, - expression => expression.ResolveUsing(new OwnerResolver())) - .ForMember( - dto => dto.Updater, - expression => expression.ResolveUsing(new CreatorResolver())) - .ForMember( - dto => dto.Icon, - expression => expression.MapFrom(content => content.ContentType.Icon)) - .ForMember( - dto => dto.Trashed, - expression => expression.MapFrom(content => content.Trashed)) - .ForMember( - dto => dto.HasPublishedVersion, - expression => expression.MapFrom(content => content.HasPublishedVersion)) - .ForMember( - dto => dto.ContentTypeAlias, - expression => expression.MapFrom(content => content.ContentType.Alias)) - .ForMember(display => display.Alias, expression => expression.Ignore()); + .ForMember(dto => dto.Owner, expression => expression.ResolveUsing(new OwnerResolver())) + .ForMember(dto => dto.Updater, expression => expression.ResolveUsing(new CreatorResolver())) + .ForMember(dto => dto.Icon, expression => expression.MapFrom(content => content.ContentType.Icon)) + .ForMember(dto => dto.Trashed, expression => expression.MapFrom(content => content.Trashed)) + .ForMember(dto => dto.HasPublishedVersion, expression => expression.MapFrom(content => content.HasPublishedVersion)) + .ForMember(dto => dto.ContentTypeAlias, expression => expression.MapFrom(content => content.ContentType.Alias)) + .ForMember(dto => dto.Alias, expression => expression.Ignore()); //FROM IContent TO ContentItemDto config.CreateMap>() - .ForMember( - dto => dto.Owner, - expression => expression.ResolveUsing(new OwnerResolver())) - .ForMember( - dto => dto.HasPublishedVersion, - expression => expression.MapFrom(content => content.HasPublishedVersion)) - .ForMember(display => display.Updater, expression => expression.Ignore()) - .ForMember(display => display.Icon, expression => expression.Ignore()) - .ForMember(display => display.Alias, expression => expression.Ignore()); - - + .ForMember(dto => dto.Owner, expression => expression.ResolveUsing(new OwnerResolver())) + .ForMember(dto => dto.HasPublishedVersion, expression => expression.MapFrom(content => content.HasPublishedVersion)) + .ForMember(dto => dto.Updater, expression => expression.Ignore()) + .ForMember(dto => dto.Icon, expression => expression.Ignore()) + .ForMember(dto => dto.Alias, expression => expression.Ignore()); } - /// /// Maps the generic tab with custom properties for content /// @@ -123,7 +83,7 @@ namespace Umbraco.Web.Models.Mapping /// /// /// - private static void AfterMap(IContent content, ContentItemDisplay display, IDataTypeService dataTypeService, + private static void AfterMap(IContent content, ContentItemDisplay display, IDataTypeService dataTypeService, ILocalizedTextService localizedText, IContentTypeService contentTypeService) { //map the IsChildOfListView (this is actually if it is a descendant of a list view!) @@ -151,7 +111,6 @@ namespace Umbraco.Web.Models.Mapping display.IsChildOfListView = ancesctorListView != null; } } - //map the tree node url if (HttpContext.Current != null) @@ -160,9 +119,9 @@ namespace Umbraco.Web.Models.Mapping var url = urlHelper.GetUmbracoApiService(controller => controller.GetTreeNode(display.Id.ToString(), null)); display.TreeNodeUrl = url; } - + //fill in the template config to be passed to the template drop down. - var templateItemConfig = new Dictionary { { "", "Choose..." } }; + var templateItemConfig = new Dictionary {{"", "Choose..."}}; foreach (var t in content.ContentType.AllowedTemplates .Where(t => t.Alias.IsNullOrWhiteSpace() == false && t.Name.IsNullOrWhiteSpace() == false)) { @@ -173,7 +132,7 @@ namespace Umbraco.Web.Models.Mapping { TabsAndPropertiesResolver.AddListView(display, "content", dataTypeService, localizedText); } - + var properties = new List { new ContentPropertyDisplay @@ -183,26 +142,26 @@ namespace Umbraco.Web.Models.Mapping Value = localizedText.UmbracoDictionaryTranslate(display.ContentTypeName), View = PropertyEditorResolver.Current.GetByAlias(Constants.PropertyEditors.NoEditAlias).ValueEditor.View }, - new ContentPropertyDisplay + new ContentPropertyDisplay { Alias = string.Format("{0}releasedate", Constants.PropertyEditors.InternalGenericPropertiesPrefix), Label = localizedText.Localize("content/releaseDate"), Value = display.ReleaseDate.HasValue ? display.ReleaseDate.Value.ToIsoString() : null, //Not editible for people without publish permission (U4-287) - View = display.AllowedActions.Contains(ActionPublish.Instance.Letter) ? "datepicker" : PropertyEditorResolver.Current.GetByAlias(Constants.PropertyEditors.NoEditAlias).ValueEditor.View, + View = display.AllowedActions.Contains(ActionPublish.Instance.Letter) ? "datepicker" : PropertyEditorResolver.Current.GetByAlias(Constants.PropertyEditors.NoEditAlias).ValueEditor.View, Config = new Dictionary { {"offsetTime", "1"} } //TODO: Fix up hard coded datepicker - } , + }, new ContentPropertyDisplay { Alias = string.Format("{0}expiredate", Constants.PropertyEditors.InternalGenericPropertiesPrefix), Label = localizedText.Localize("content/unpublishDate"), Value = display.ExpireDate.HasValue ? display.ExpireDate.Value.ToIsoString() : null, //Not editible for people without publish permission (U4-287) - View = display.AllowedActions.Contains(ActionPublish.Instance.Letter) ? "datepicker" : PropertyEditorResolver.Current.GetByAlias(Constants.PropertyEditors.NoEditAlias).ValueEditor.View, + View = display.AllowedActions.Contains(ActionPublish.Instance.Letter) ? "datepicker" : PropertyEditorResolver.Current.GetByAlias(Constants.PropertyEditors.NoEditAlias).ValueEditor.View, Config = new Dictionary { {"offsetTime", "1"} @@ -246,21 +205,21 @@ namespace Umbraco.Web.Models.Mapping var docTypeLink = string.Format("#/settings/documenttypes/edit/{0}", currentDocumentTypeId); //Replace the doc type property - var docTypeProp = genericProperties.First(x => x.Alias == string.Format("{0}doctype", Constants.PropertyEditors.InternalGenericPropertiesPrefix)); - docTypeProp.Value = new List + var docTypeProperty = genericProperties.First(x => x.Alias == string.Format("{0}doctype", Constants.PropertyEditors.InternalGenericPropertiesPrefix)); + docTypeProperty.Value = new List { new { linkText = currentDocumentTypeName, url = docTypeLink, - target = "_self", icon = "icon-item-arrangement" + target = "_self", + icon = "icon-item-arrangement" } }; //TODO: Hard coding this because the templatepicker doesn't necessarily need to be a resolvable (real) property editor - docTypeProp.View = "urllist"; + docTypeProperty.View = "urllist"; } }); - } /// @@ -305,13 +264,13 @@ namespace Umbraco.Web.Models.Mapping var svc = _userService.Value; var permissions = svc.GetPermissions( - //TODO: This is certainly not ideal usage here - perhaps the best way to deal with this in the future is - // with the IUmbracoContextAccessor. In the meantime, if used outside of a web app this will throw a null - // refrence exception :( - UmbracoContext.Current.Security.CurrentUser, - // Here we need to do a special check since this could be new content, in which case we need to get the permissions - // from the parent, not the existing one otherwise permissions would be coming from the root since Id is 0. - source.HasIdentity ? source.Id : source.ParentId) + //TODO: This is certainly not ideal usage here - perhaps the best way to deal with this in the future is + // with the IUmbracoContextAccessor. In the meantime, if used outside of a web app this will throw a null + // refrence exception :( + UmbracoContext.Current.Security.CurrentUser, + // Here we need to do a special check since this could be new content, in which case we need to get the permissions + // from the parent, not the existing one otherwise permissions would be coming from the root since Id is 0. + source.HasIdentity ? source.Id : source.ParentId) .FirstOrDefault(); return permissions == null @@ -319,6 +278,5 @@ namespace Umbraco.Web.Models.Mapping : permissions.AssignedPermissions.Where(x => x.Length == 1).Select(x => x.ToUpperInvariant()[0]); } } - } } \ No newline at end of file diff --git a/src/Umbraco.Web/Models/Mapping/MediaModelMapper.cs b/src/Umbraco.Web/Models/Mapping/MediaModelMapper.cs index 5f2a8bfd1d..c3f9412401 100644 --- a/src/Umbraco.Web/Models/Mapping/MediaModelMapper.cs +++ b/src/Umbraco.Web/Models/Mapping/MediaModelMapper.cs @@ -1,13 +1,9 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; -using System.Text; -using System.Threading.Tasks; using System.Web; using System.Web.Mvc; using System.Web.Routing; using AutoMapper; -using umbraco; using Umbraco.Core; using Umbraco.Core.Configuration; using Umbraco.Core.Logging; @@ -29,22 +25,12 @@ namespace Umbraco.Web.Models.Mapping { //FROM IMedia TO MediaItemDisplay config.CreateMap() - .ForMember( - dto => dto.Owner, - expression => expression.ResolveUsing(new OwnerResolver())) - .ForMember( - dto => dto.Icon, - expression => expression.MapFrom(content => content.ContentType.Icon)) - .ForMember( - dto => dto.ContentTypeAlias, - expression => expression.MapFrom(content => content.ContentType.Alias)) + .ForMember(display => display.Owner, expression => expression.ResolveUsing(new OwnerResolver())) + .ForMember(display => display.Icon, expression => expression.MapFrom(content => content.ContentType.Icon)) + .ForMember(display => display.ContentTypeAlias, expression => expression.MapFrom(content => content.ContentType.Alias)) .ForMember(display => display.IsChildOfListView, expression => expression.Ignore()) - .ForMember( - dto => dto.Trashed, - expression => expression.MapFrom(content => content.Trashed)) - .ForMember( - dto => dto.ContentTypeName, - expression => expression.MapFrom(content => content.ContentType.Name)) + .ForMember(display => display.Trashed, expression => expression.MapFrom(content => content.Trashed)) + .ForMember(display => display.ContentTypeName, expression => expression.MapFrom(content => content.ContentType.Name)) .ForMember(display => display.Properties, expression => expression.Ignore()) .ForMember(display => display.TreeNodeUrl, expression => expression.Ignore()) .ForMember(display => display.Notifications, expression => expression.Ignore()) @@ -53,39 +39,29 @@ namespace Umbraco.Web.Models.Mapping .ForMember(display => display.Updater, expression => expression.Ignore()) .ForMember(display => display.Alias, expression => expression.Ignore()) .ForMember(display => display.IsContainer, expression => expression.Ignore()) - .ForMember(member => member.HasPublishedVersion, expression => expression.Ignore()) + .ForMember(display => display.HasPublishedVersion, expression => expression.Ignore()) .ForMember(display => display.Tabs, expression => expression.ResolveUsing(new TabsAndPropertiesResolver(applicationContext.Services.TextService))) .AfterMap((media, display) => AfterMap(media, display, applicationContext.Services.DataTypeService, applicationContext.Services.TextService, applicationContext.ProfilingLogger.Logger)); //FROM IMedia TO ContentItemBasic config.CreateMap>() - .ForMember( - dto => dto.Owner, - expression => expression.ResolveUsing(new OwnerResolver())) - .ForMember( - dto => dto.Icon, - expression => expression.MapFrom(content => content.ContentType.Icon)) - .ForMember( - dto => dto.Trashed, - expression => expression.MapFrom(content => content.Trashed)) - .ForMember( - dto => dto.ContentTypeAlias, - expression => expression.MapFrom(content => content.ContentType.Alias)) - .ForMember(x => x.Published, expression => expression.Ignore()) - .ForMember(x => x.Updater, expression => expression.Ignore()) - .ForMember(x => x.Alias, expression => expression.Ignore()) - .ForMember(member => member.HasPublishedVersion, expression => expression.Ignore()); + .ForMember(dto => dto.Owner, expression => expression.ResolveUsing(new OwnerResolver())) + .ForMember(dto => dto.Icon, expression => expression.MapFrom(content => content.ContentType.Icon)) + .ForMember(dto => dto.Trashed, expression => expression.MapFrom(content => content.Trashed)) + .ForMember(dto => dto.ContentTypeAlias, expression => expression.MapFrom(content => content.ContentType.Alias)) + .ForMember(dto => dto.Published, expression => expression.Ignore()) + .ForMember(dto => dto.Updater, expression => expression.Ignore()) + .ForMember(dto => dto.Alias, expression => expression.Ignore()) + .ForMember(dto => dto.HasPublishedVersion, expression => expression.Ignore()); //FROM IMedia TO ContentItemDto config.CreateMap>() - .ForMember( - dto => dto.Owner, - expression => expression.ResolveUsing(new OwnerResolver())) - .ForMember(x => x.Published, expression => expression.Ignore()) - .ForMember(x => x.Updater, expression => expression.Ignore()) - .ForMember(x => x.Icon, expression => expression.Ignore()) - .ForMember(x => x.Alias, expression => expression.Ignore()) - .ForMember(member => member.HasPublishedVersion, expression => expression.Ignore()); + .ForMember(dto => dto.Owner, expression => expression.ResolveUsing(new OwnerResolver())) + .ForMember(dto => dto.Published, expression => expression.Ignore()) + .ForMember(dto => dto.Updater, expression => expression.Ignore()) + .ForMember(dto => dto.Icon, expression => expression.Ignore()) + .ForMember(dto => dto.Alias, expression => expression.Ignore()) + .ForMember(dto => dto.HasPublishedVersion, expression => expression.Ignore()); } private static void AfterMap(IMedia media, MediaItemDisplay display, IDataTypeService dataTypeService, ILocalizedTextService localizedText, ILogger logger) @@ -155,28 +131,28 @@ namespace Umbraco.Web.Models.Mapping genericProperties.Add(link); } - TabsAndPropertiesResolver.MapGenericProperties(media, display, localizedText, genericProperties, properties => { + TabsAndPropertiesResolver.MapGenericProperties(media, display, localizedText, genericProperties, properties => + { if (HttpContext.Current != null && UmbracoContext.Current != null && UmbracoContext.Current.Security.CurrentUser != null && UmbracoContext.Current.Security.CurrentUser.AllowedSections.Any(x => x.Equals(Constants.Applications.Settings))) { - var docTypeLink = string.Format("#/settings/mediatypes/edit/{0}", media.ContentTypeId); + var mediaTypeLink = string.Format("#/settings/mediatypes/edit/{0}", media.ContentTypeId); - //Replace the doc type property - var docTypeProp = properties.First(x => x.Alias == string.Format("{0}doctype", Constants.PropertyEditors.InternalGenericPropertiesPrefix)); - docTypeProp.Value = new List + //Replace the doctype property + var docTypeProperty = properties.First(x => x.Alias == string.Format("{0}doctype", Constants.PropertyEditors.InternalGenericPropertiesPrefix)); + docTypeProperty.Value = new List + { + new { - new - { - linkText = media.ContentType.Name, - url = docTypeLink, - target = "_self", icon = "icon-item-arrangement" - } - }; - docTypeProp.View = "urllist"; + linkText = media.ContentType.Name, + url = mediaTypeLink, + target = "_self", + icon = "icon-item-arrangement" + } + }; + docTypeProperty.View = "urllist"; } - }); } - } } diff --git a/src/Umbraco.Web/Models/Mapping/MemberModelMapper.cs b/src/Umbraco.Web/Models/Mapping/MemberModelMapper.cs index 6d4bdd7941..edb44d36ce 100644 --- a/src/Umbraco.Web/Models/Mapping/MemberModelMapper.cs +++ b/src/Umbraco.Web/Models/Mapping/MemberModelMapper.cs @@ -11,7 +11,6 @@ using Umbraco.Core.Models.Mapping; using Umbraco.Core.Models.Membership; using Umbraco.Core.Services; using Umbraco.Web.Models.ContentEditing; -using umbraco; using System.Linq; using Umbraco.Core.PropertyEditors; using Umbraco.Core.Security; @@ -29,10 +28,10 @@ namespace Umbraco.Web.Models.Mapping //FROM MembershipUser TO MediaItemDisplay - used when using a non-umbraco membership provider config.CreateMap() .ConvertUsing(user => - { - var member = Mapper.Map(user); - return Mapper.Map(member); - }); + { + var member = Mapper.Map(user); + return Mapper.Map(member); + }); //FROM MembershipUser TO IMember - used when using a non-umbraco membership provider config.CreateMap() @@ -62,23 +61,13 @@ namespace Umbraco.Web.Models.Mapping //FROM IMember TO MediaItemDisplay config.CreateMap() - .ForMember( - dto => dto.Owner, - expression => expression.ResolveUsing(new OwnerResolver())) - .ForMember( - dto => dto.Icon, - expression => expression.MapFrom(content => content.ContentType.Icon)) - .ForMember( - dto => dto.ContentTypeAlias, - expression => expression.MapFrom(content => content.ContentType.Alias)) - .ForMember( - dto => dto.ContentTypeName, - expression => expression.MapFrom(content => content.ContentType.Name)) + .ForMember(display => display.Owner, expression => expression.ResolveUsing(new OwnerResolver())) + .ForMember(display => display.Icon, expression => expression.MapFrom(content => content.ContentType.Icon)) + .ForMember(display => display.ContentTypeAlias, expression => expression.MapFrom(content => content.ContentType.Alias)) + .ForMember(display => display.ContentTypeName, expression => expression.MapFrom(content => content.ContentType.Name)) .ForMember(display => display.Properties, expression => expression.Ignore()) - .ForMember(display => display.Tabs, - expression => expression.ResolveUsing(new MemberTabsAndPropertiesResolver(applicationContext.Services.TextService))) - .ForMember(display => display.MemberProviderFieldMapping, - expression => expression.ResolveUsing(new MemberProviderFieldMappingResolver())) + .ForMember(display => display.Tabs, expression => expression.ResolveUsing(new MemberTabsAndPropertiesResolver(applicationContext.Services.TextService))) + .ForMember(display => display.MemberProviderFieldMapping, expression => expression.ResolveUsing(new MemberProviderFieldMappingResolver())) .ForMember(display => display.MembershipScenario, expression => expression.ResolveUsing(new MembershipScenarioMappingResolver(new Lazy(() => applicationContext.Services.MemberTypeService)))) .ForMember(display => display.Notifications, expression => expression.Ignore()) @@ -90,31 +79,21 @@ namespace Umbraco.Web.Models.Mapping .ForMember(display => display.Trashed, expression => expression.Ignore()) .ForMember(display => display.IsContainer, expression => expression.Ignore()) .ForMember(display => display.TreeNodeUrl, expression => expression.Ignore()) - .ForMember(member => member.HasPublishedVersion, expression => expression.Ignore()) + .ForMember(display => display.HasPublishedVersion, expression => expression.Ignore()) .AfterMap((member, display) => MapGenericCustomProperties(applicationContext.Services.MemberService, member, display, applicationContext.Services.TextService)); //FROM IMember TO MemberBasic config.CreateMap() - .ForMember( - dto => dto.Owner, - expression => expression.ResolveUsing(new OwnerResolver())) - .ForMember( - dto => dto.Icon, - expression => expression.MapFrom(content => content.ContentType.Icon)) - .ForMember( - dto => dto.ContentTypeAlias, - expression => expression.MapFrom(content => content.ContentType.Alias)) - .ForMember( - dto => dto.Email, - expression => expression.MapFrom(content => content.Email)) - .ForMember( - dto => dto.Username, - expression => expression.MapFrom(content => content.Username)) - .ForMember(display => display.Trashed, expression => expression.Ignore()) - .ForMember(x => x.Published, expression => expression.Ignore()) - .ForMember(x => x.Updater, expression => expression.Ignore()) - .ForMember(x => x.Alias, expression => expression.Ignore()) - .ForMember(member => member.HasPublishedVersion, expression => expression.Ignore()); + .ForMember(dto => dto.Owner, expression => expression.ResolveUsing(new OwnerResolver())) + .ForMember(dto => dto.Icon, expression => expression.MapFrom(content => content.ContentType.Icon)) + .ForMember(dto => dto.ContentTypeAlias, expression => expression.MapFrom(content => content.ContentType.Alias)) + .ForMember(dto => dto.Email, expression => expression.MapFrom(content => content.Email)) + .ForMember(dto => dto.Username, expression => expression.MapFrom(content => content.Username)) + .ForMember(dto => dto.Trashed, expression => expression.Ignore()) + .ForMember(dto => dto.Published, expression => expression.Ignore()) + .ForMember(dto => dto.Updater, expression => expression.Ignore()) + .ForMember(dto => dto.Alias, expression => expression.Ignore()) + .ForMember(dto => dto.HasPublishedVersion, expression => expression.Ignore()); //FROM MembershipUser TO MemberBasic config.CreateMap() @@ -123,41 +102,31 @@ namespace Umbraco.Web.Models.Mapping .ForMember(member => member.CreateDate, expression => expression.MapFrom(user => user.CreationDate)) .ForMember(member => member.UpdateDate, expression => expression.MapFrom(user => user.LastActivityDate)) .ForMember(member => member.Key, expression => expression.MapFrom(user => user.ProviderUserKey.TryConvertTo().Result.ToString("N"))) - .ForMember( - dto => dto.Owner, - expression => expression.UseValue(new UserBasic {Name = "Admin", UserId = 0})) - .ForMember( - dto => dto.Icon, - expression => expression.UseValue("icon-user")) + .ForMember(member => member.Owner, expression => expression.UseValue(new UserBasic {Name = "Admin", UserId = 0})) + .ForMember(member => member.Icon, expression => expression.UseValue("icon-user")) .ForMember(member => member.Name, expression => expression.MapFrom(user => user.UserName)) - .ForMember( - dto => dto.Email, - expression => expression.MapFrom(content => content.Email)) - .ForMember( - dto => dto.Username, - expression => expression.MapFrom(content => content.UserName)) + .ForMember(member => member.Email, expression => expression.MapFrom(content => content.Email)) + .ForMember(member => member.Username, expression => expression.MapFrom(content => content.UserName)) .ForMember(member => member.Properties, expression => expression.Ignore()) .ForMember(member => member.ParentId, expression => expression.Ignore()) .ForMember(member => member.Path, expression => expression.Ignore()) .ForMember(member => member.SortOrder, expression => expression.Ignore()) .ForMember(member => member.AdditionalData, expression => expression.Ignore()) - .ForMember(x => x.Published, expression => expression.Ignore()) - .ForMember(x => x.Updater, expression => expression.Ignore()) - .ForMember(dto => dto.Trashed, expression => expression.Ignore()) - .ForMember(x => x.Alias, expression => expression.Ignore()) - .ForMember(x => x.ContentTypeAlias, expression => expression.Ignore()) + .ForMember(member => member.Published, expression => expression.Ignore()) + .ForMember(member => member.Updater, expression => expression.Ignore()) + .ForMember(member => member.Trashed, expression => expression.Ignore()) + .ForMember(member => member.Alias, expression => expression.Ignore()) + .ForMember(member => member.ContentTypeAlias, expression => expression.Ignore()) .ForMember(member => member.HasPublishedVersion, expression => expression.Ignore()); //FROM IMember TO ContentItemDto config.CreateMap>() - .ForMember( - dto => dto.Owner, - expression => expression.ResolveUsing(new OwnerResolver())) - .ForMember(x => x.Published, expression => expression.Ignore()) - .ForMember(x => x.Updater, expression => expression.Ignore()) - .ForMember(x => x.Icon, expression => expression.Ignore()) - .ForMember(x => x.Alias, expression => expression.Ignore()) - .ForMember(member => member.HasPublishedVersion, expression => expression.Ignore()) + .ForMember(dto => dto.Owner, expression => expression.ResolveUsing(new OwnerResolver())) + .ForMember(dto => dto.Published, expression => expression.Ignore()) + .ForMember(dto => dto.Updater, expression => expression.Ignore()) + .ForMember(dto => dto.Icon, expression => expression.Ignore()) + .ForMember(dto => dto.Alias, expression => expression.Ignore()) + .ForMember(dto => dto.HasPublishedVersion, expression => expression.Ignore()) //do no map the custom member properties (currently anyways, they were never there in 6.x) .ForMember(dto => dto.Properties, expression => expression.ResolveUsing(new MemberDtoPropertiesValueResolver())); } @@ -232,25 +201,26 @@ namespace Umbraco.Web.Models.Mapping } }; - - TabsAndPropertiesResolver.MapGenericProperties(member, display, localizedText, genericProperties, properties => { + TabsAndPropertiesResolver.MapGenericProperties(member, display, localizedText, genericProperties, properties => + { if (HttpContext.Current != null && UmbracoContext.Current != null && UmbracoContext.Current.Security.CurrentUser != null && UmbracoContext.Current.Security.CurrentUser.AllowedSections.Any(x => x.Equals(Constants.Applications.Settings))) { - var docTypeLink = string.Format("#/member/memberTypes/edit/{0}", member.ContentTypeId); + var memberTypeLink = string.Format("#/member/memberTypes/edit/{0}", member.ContentTypeId); - //Replace the doc type property - var docTypeProp = properties.First(x => x.Alias == string.Format("{0}doctype", Constants.PropertyEditors.InternalGenericPropertiesPrefix)); - docTypeProp.Value = new List + //Replace the doctype property + var docTypeProperty = properties.First(x => x.Alias == string.Format("{0}doctype", Constants.PropertyEditors.InternalGenericPropertiesPrefix)); + docTypeProperty.Value = new List + { + new { - new - { - linkText = member.ContentType.Name, - url = docTypeLink, - target = "_self", icon = "icon-item-arrangement" - } - }; - docTypeProp.View = "urllist"; + linkText = member.ContentType.Name, + url = memberTypeLink, + target = "_self", + icon = "icon-item-arrangement" + } + }; + docTypeProperty.View = "urllist"; } }); @@ -265,7 +235,6 @@ namespace Umbraco.Web.Models.Mapping prop.Value = 1; } } - } /// @@ -274,6 +243,7 @@ namespace Umbraco.Web.Models.Mapping /// /// /// + /// /// /// /// If the membership provider installed is the umbraco membership provider, then we will allow changing the username, however if @@ -283,11 +253,11 @@ namespace Umbraco.Web.Models.Mapping internal static ContentPropertyDisplay GetLoginProperty(IMemberService memberService, IMember member, MemberDisplay display, ILocalizedTextService localizedText) { var prop = new ContentPropertyDisplay - { - Alias = string.Format("{0}login", Constants.PropertyEditors.InternalGenericPropertiesPrefix), - Label = localizedText.Localize("login"), - Value = display.Username - }; + { + Alias = string.Format("{0}login", Constants.PropertyEditors.InternalGenericPropertiesPrefix), + Label = localizedText.Localize("login"), + Value = display.Username + }; var scenario = memberService.GetMembershipScenario(); @@ -340,8 +310,8 @@ namespace Umbraco.Web.Models.Mapping var exclude = defaultProps.Select(x => x.Value.Alias).ToArray(); return source.Properties - .Where(x => exclude.Contains(x.Alias) == false) - .Select(Mapper.Map); + .Where(x => exclude.Contains(x.Alias) == false) + .Select(Mapper.Map); } } @@ -394,7 +364,7 @@ namespace Umbraco.Web.Models.Mapping } else { - var umbracoProvider = (IUmbracoMemberTypeMembershipProvider)provider; + var umbracoProvider = (IUmbracoMemberTypeMembershipProvider) provider; //This is kind of a hack because a developer is supposed to be allowed to set their property editor - would have been much easier // if we just had all of the membeship provider fields on the member table :( @@ -408,8 +378,6 @@ namespace Umbraco.Web.Models.Mapping return result; } - - } } @@ -432,8 +400,8 @@ namespace Umbraco.Web.Models.Mapping } var memberType = _memberTypeService.Value.Get(Constants.Conventions.MemberTypes.DefaultAlias); return memberType != null - ? MembershipScenario.CustomProviderWithUmbracoLink - : MembershipScenario.StandaloneCustomProvider; + ? MembershipScenario.CustomProviderWithUmbracoLink + : MembershipScenario.StandaloneCustomProvider; } } @@ -457,7 +425,7 @@ namespace Umbraco.Web.Models.Mapping } else { - var umbracoProvider = (IUmbracoMemberTypeMembershipProvider)provider; + var umbracoProvider = (IUmbracoMemberTypeMembershipProvider) provider; return new Dictionary { @@ -466,10 +434,7 @@ namespace Umbraco.Web.Models.Mapping {Constants.Conventions.Member.Comments, umbracoProvider.CommentPropertyTypeAlias} }; } - - } } - } } \ No newline at end of file From cdb0c57416cc57679b25bf437a22c561e19c1804 Mon Sep 17 00:00:00 2001 From: Claus Date: Wed, 9 Nov 2016 11:48:32 +0100 Subject: [PATCH 39/49] readding the fix crgrieve did for treepicker.controller.js. --- .../src/views/common/dialogs/treepicker.controller.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/treepicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/treepicker.controller.js index 2d8d38cf50..740791abf9 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/treepicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/treepicker.controller.js @@ -259,7 +259,7 @@ angular.module("umbraco").controller("Umbraco.Dialogs.TreePickerController", } }); } else { - var a = dialogOptions.filter.toLowerCase().split(','); + var a = dialogOptions.filter.toLowerCase().replace(/\s/g, '').split(','); angular.forEach(nodes, function (value, key) { var found = a.indexOf(value.metaData.contentType.toLowerCase()) >= 0; From e77bddd0f216f6eaafd7e6e1f59e3f6d02cd7253 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 10 Nov 2016 11:08:28 +0100 Subject: [PATCH 40/49] add filtering of media types --- .../services/mediatypehelper.service.js | 42 +++++++++++++------ 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/services/mediatypehelper.service.js b/src/Umbraco.Web.UI.Client/src/common/services/mediatypehelper.service.js index 919a803456..20e5e3799b 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/mediatypehelper.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/mediatypehelper.service.js @@ -19,22 +19,38 @@ function mediaTypeHelper(mediaTypeResource, $q) { // Get full list return $q.all(allowedQ).then(function(fullTypes){ - // Only mediatypes with 'umbracoFile' property - return fullTypes.filter(function(mediatype){ - for(var i = 0; i < mediatype.groups.length; i++){ - var group = mediatype.groups[i]; - for(var j = 0; j < group.properties.length; j++){ - var property = group.properties[j]; - if(property.editor === 'Umbraco.ImageCropper' || property.editor === 'Umbraco.UploadField'){ - return mediatype; - } - } - } - }); + // Find all the media types with an Image Cropper property editor + var filteredTypes = mediaTypeHelperService.getTypeWithEditor(fullTypes, ['Umbraco.ImageCropper']); + + // If there is only one media type with an Image Cropper we will return this one + if(filteredTypes.length === 1) { + return filteredTypes; + // If there is more than one Image cropper, custom media types have been added, and we return all media types with and Image cropper or UploadField + } else { + return mediaTypeHelperService.getTypeWithEditor(fullTypes, ['Umbraco.ImageCropper', 'Umbraco.UploadField']); + } + }); }); - } + }, + + getTypeWithEditor: function (types, editors) { + + return types.filter(function (mediatype) { + for (var i = 0; i < mediatype.groups.length; i++) { + var group = mediatype.groups[i]; + for (var j = 0; j < group.properties.length; j++) { + var property = group.properties[j]; + if( editors.indexOf(property.editor) !== -1 ) { + return mediatype; + } + } + } + }); + + } + }; return mediaTypeHelperService; From 07c2a1432183e9dfc6f4cfd766320af64c2bd028 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 10 Nov 2016 11:13:00 +0100 Subject: [PATCH 41/49] If there is only 1 allowed media type set the alias to auto to let the server decide --- .../components/upload/umbfiledropzone.directive.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/upload/umbfiledropzone.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/upload/umbfiledropzone.directive.js index 52704855bb..fdf949a613 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/upload/umbfiledropzone.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/upload/umbfiledropzone.directive.js @@ -104,9 +104,10 @@ angular.module("umbraco.directives") scope.queue = []; } - // One allowed mediaType, pick this one + // One allowed mediaType if(scope.acceptedMediatypes && scope.acceptedMediatypes.length === 1){ - scope.contentTypeAlias = scope.acceptedMediatypes[0].alias; + // set alias to auto to let the server best decide which media type to use + scope.contentTypeAlias = "umbracoAuto"; _processQueueItem(); } From f9d8754d888cfd7dbf46df4e4af8cc33fbf1ef19 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 10 Nov 2016 12:00:07 +0100 Subject: [PATCH 42/49] add support for one custom media type --- .../components/upload/umbfiledropzone.directive.js | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/upload/umbfiledropzone.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/upload/umbfiledropzone.directive.js index fdf949a613..65e35a16d1 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/upload/umbfiledropzone.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/upload/umbfiledropzone.directive.js @@ -104,10 +104,16 @@ angular.module("umbraco.directives") scope.queue = []; } - // One allowed mediaType - if(scope.acceptedMediatypes && scope.acceptedMediatypes.length === 1){ - // set alias to auto to let the server best decide which media type to use - scope.contentTypeAlias = "umbracoAuto"; + // One allowed type + if(scope.acceptedMediatypes && scope.acceptedMediatypes.length === 1) { + + // Standard setup - set alias to auto select to let the server best decide which media type to use + if(scope.acceptedMediatypes[0].alias === 'Image') { + scope.contentTypeAlias = "umbracoAutoSelect"; + } else { + scope.contentTypeAlias = scope.acceptedMediatypes[0].alias; + } + _processQueueItem(); } From 4f5bc9eb89d672befe82b8d0c83443e96ea72e23 Mon Sep 17 00:00:00 2001 From: Claus Date: Thu, 10 Nov 2016 12:36:52 +0100 Subject: [PATCH 43/49] updating MediaController with AutoSelect option. --- src/Umbraco.Core/Constants-Conventions.cs | 5 +++++ src/Umbraco.Web/Editors/MediaController.cs | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Core/Constants-Conventions.cs b/src/Umbraco.Core/Constants-Conventions.cs index 7e2bb88964..d7f4576137 100644 --- a/src/Umbraco.Core/Constants-Conventions.cs +++ b/src/Umbraco.Core/Constants-Conventions.cs @@ -122,6 +122,11 @@ namespace Umbraco.Core /// MediaType alias for an image. /// public const string Image = "Image"; + + /// + /// MediaType alias indicating allowing auto-selection. + /// + public const string AutoSelect = "umbracoAutoSelect"; } /// diff --git a/src/Umbraco.Web/Editors/MediaController.cs b/src/Umbraco.Web/Editors/MediaController.cs index 932b3f6766..6604aee507 100644 --- a/src/Umbraco.Web/Editors/MediaController.cs +++ b/src/Umbraco.Web/Editors/MediaController.cs @@ -531,7 +531,7 @@ namespace Umbraco.Web.Editors { var mediaType = Constants.Conventions.MediaTypes.File; - if (result.FormData["contentTypeAlias"] == Constants.Conventions.MediaTypes.Image) + if (result.FormData["contentTypeAlias"] == Constants.Conventions.MediaTypes.AutoSelect) { if (UmbracoConfig.For.UmbracoSettings().Content.ImageFileTypes.Contains(ext)) { From 9e24b694b3c1ca7754d4f3177a453ab7fbac36aa Mon Sep 17 00:00:00 2001 From: Claus Date: Thu, 10 Nov 2016 13:09:22 +0100 Subject: [PATCH 44/49] adding migration to retain functionality as it has always been in root when upgrading. --- .../UpdateAllowedMediaTypesAtRoot.cs | 25 +++++++++++++++++++ src/Umbraco.Core/Umbraco.Core.csproj | 1 + 2 files changed, 26 insertions(+) create mode 100644 src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenFiveFive/UpdateAllowedMediaTypesAtRoot.cs diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenFiveFive/UpdateAllowedMediaTypesAtRoot.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenFiveFive/UpdateAllowedMediaTypesAtRoot.cs new file mode 100644 index 0000000000..565b7f6f13 --- /dev/null +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenFiveFive/UpdateAllowedMediaTypesAtRoot.cs @@ -0,0 +1,25 @@ +using Umbraco.Core.Configuration; +using Umbraco.Core.Logging; +using Umbraco.Core.Persistence.SqlSyntax; + +namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenFiveFive +{ + /// + /// See: http://issues.umbraco.org/issue/U4-4196 + /// + [Migration("7.5.5", 1, GlobalSettings.UmbracoMigrationName)] + public class UpdateAllowedMediaTypesAtRoot : MigrationBase + { + public UpdateAllowedMediaTypesAtRoot(ISqlSyntaxProvider sqlSyntax, ILogger logger) + : base(sqlSyntax, logger) + { } + + public override void Up() + { + Execute.Sql("UPDATE cmsContentType SET allowAtRoot = 1 WHERE nodeId = 1031 OR nodeId = 1032 OR nodeId = 1033"); + } + + public override void Down() + { } + } +} diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index c28cea24cd..d6b2e0c438 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -429,6 +429,7 @@ + From 2115367353e8e9ef6373209780fd10e5fe0e1995 Mon Sep 17 00:00:00 2001 From: Claus Date: Mon, 14 Nov 2016 09:57:17 +0100 Subject: [PATCH 45/49] updating the migration to include only needed ids. formatting stuff in js. --- .../UpdateAllowedMediaTypesAtRoot.cs | 2 +- .../upload/umbfiledropzone.directive.js | 444 ++++++++---------- .../common/dialogs/mediapicker.controller.js | 75 +-- .../mediaPicker/mediapicker.controller.js | 230 ++++----- 4 files changed, 338 insertions(+), 413 deletions(-) diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenFiveFive/UpdateAllowedMediaTypesAtRoot.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenFiveFive/UpdateAllowedMediaTypesAtRoot.cs index 565b7f6f13..c9a0d509e6 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenFiveFive/UpdateAllowedMediaTypesAtRoot.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenFiveFive/UpdateAllowedMediaTypesAtRoot.cs @@ -16,7 +16,7 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenFiveFiv public override void Up() { - Execute.Sql("UPDATE cmsContentType SET allowAtRoot = 1 WHERE nodeId = 1031 OR nodeId = 1032 OR nodeId = 1033"); + Execute.Sql("UPDATE cmsContentType SET allowAtRoot = 1 WHERE nodeId = 1032 OR nodeId = 1033"); } public override void Down() diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/upload/umbfiledropzone.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/upload/umbfiledropzone.directive.js index 65e35a16d1..6cafa05bc8 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/upload/umbfiledropzone.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/upload/umbfiledropzone.directive.js @@ -10,269 +10,223 @@ /* TODO .directive("umbFileDrop", function ($timeout, $upload, localizationService, umbRequestHelper){ - - return{ - restrict: "A", - link: function(scope, element, attrs){ - - //load in the options model - - - } - } + return{ + restrict: "A", + link: function(scope, element, attrs){ + //load in the options model + } + } }) */ angular.module("umbraco.directives") + .directive('umbFileDropzone', + function($timeout, Upload, localizationService, umbRequestHelper) { + return { + restrict: 'E', + replace: true, + templateUrl: 'views/components/upload/umb-file-dropzone.html', + scope: { + parentId: '@', + contentTypeAlias: '@', + propertyAlias: '@', + accept: '@', + maxFileSize: '@', -.directive('umbFileDropzone', function ($timeout, Upload, localizationService, umbRequestHelper, editorState) { - return { + compact: '@', + hideDropzone: '@', + acceptedMediatypes: '=', - restrict: 'E', - replace: true, + filesQueued: '=', + handleFile: '=', + filesUploaded: '=' + }, + link: function(scope, element, attrs) { + scope.queue = []; + scope.done = []; + scope.rejected = []; + scope.currentFile = undefined; - templateUrl: 'views/components/upload/umb-file-dropzone.html', + function _filterFile(file) { + var ignoreFileNames = ['Thumbs.db']; + var ignoreFileTypes = ['directory']; - scope: { - parentId: '@', - contentTypeAlias: '@', - propertyAlias: '@', - accept: '@', - maxFileSize: '@', + // ignore files with names from the list + // ignore files with types from the list + // ignore files which starts with "." + if (ignoreFileNames.indexOf(file.name) === -1 && + ignoreFileTypes.indexOf(file.type) === -1 && + file.name.indexOf(".") !== 0) { + return true; + } else { + return false; + } + } - compact: '@', - hideDropzone: '@', - acceptedMediatypes: '=', + function _filesQueued(files, event) { + //Push into the queue + angular.forEach(files, + function(file) { - filesQueued: '=', - handleFile: '=', - filesUploaded: '=' - }, + if (_filterFile(file) === true) { - link: function(scope, element, attrs) { - - scope.queue = []; - scope.done = []; - scope.rejected = []; + if (file.$error) { + scope.rejected.push(file); + } else { + scope.queue.push(file); + } + } + }); - scope.currentFile = undefined; + //when queue is done, kick the uploader + if (!scope.working) { + // Upload not allowed + if (!scope.acceptedMediatypes || !scope.acceptedMediatypes.length) { + files.map(function(file) { + file.uploadStatus = "error"; + file.serverErrorMessage = "File type is not allowed here"; + scope.rejected.push(file); + }); + scope.queue = []; + } + // One allowed type + if (scope.acceptedMediatypes && scope.acceptedMediatypes.length === 1) { + // Standard setup - set alias to auto select to let the server best decide which media type to use + if (scope.acceptedMediatypes[0].alias === 'Image') { + scope.contentTypeAlias = "umbracoAutoSelect"; + } else { + scope.contentTypeAlias = scope.acceptedMediatypes[0].alias; + } - function _filterFile(file) { - - var ignoreFileNames = ['Thumbs.db']; - var ignoreFileTypes = ['directory']; + _processQueueItem(); + } + // More than one, open dialog + if (scope.acceptedMediatypes && scope.acceptedMediatypes.length > 1) { + _chooseMediaType(); + } + } + } - // ignore files with names from the list - // ignore files with types from the list - // ignore files which starts with "." - if(ignoreFileNames.indexOf(file.name) === -1 && - ignoreFileTypes.indexOf(file.type) === -1 && - file.name.indexOf(".") !== 0) { - return true; - } else { - return false; - } + function _processQueueItem() { + if (scope.queue.length > 0) { + scope.currentFile = scope.queue.shift(); + _upload(scope.currentFile); + } else if (scope.done.length > 0) { + if (scope.filesUploaded) { + //queue is empty, trigger the done action + scope.filesUploaded(scope.done); + } - } + //auto-clear the done queue after 3 secs + var currentLength = scope.done.length; + $timeout(function() { + scope.done.splice(0, currentLength); + }, + 3000); + } + } - function _filesQueued(files, event){ + function _upload(file) { - //Push into the queue - angular.forEach(files, function(file){ + scope.propertyAlias = scope.propertyAlias ? scope.propertyAlias : "umbracoFile"; + scope.contentTypeAlias = scope.contentTypeAlias ? scope.contentTypeAlias : "Image"; - if(_filterFile(file) === true) { + Upload.upload({ + url: umbRequestHelper.getApiUrl("mediaApiBaseUrl", "PostAddFile"), + fields: { + 'currentFolder': scope.parentId, + 'contentTypeAlias': scope.contentTypeAlias, + 'propertyAlias': scope.propertyAlias, + 'path': file.path + }, + file: file + }) + .progress(function(evt) { + // calculate progress in percentage + var progressPercentage = parseInt(100.0 * evt.loaded / evt.total, 10); + // set percentage property on file + file.uploadProgress = progressPercentage; + // set uploading status on file + file.uploadStatus = "uploading"; + }) + .success(function(data, status, headers, config) { + if (data.notifications && data.notifications.length > 0) { + // set error status on file + file.uploadStatus = "error"; + // Throw message back to user with the cause of the error + file.serverErrorMessage = data.notifications[0].message; + // Put the file in the rejected pool + scope.rejected.push(file); + } else { + // set done status on file + file.uploadStatus = "done"; + // set date/time for when done - used for sorting + file.doneDate = new Date(); + // Put the file in the done pool + scope.done.push(file); + } + scope.currentFile = undefined; + //after processing, test if everthing is done + _processQueueItem(); + }) + .error(function(evt, status, headers, config) { + // set status done + file.uploadStatus = "error"; + //if the service returns a detailed error + if (evt.InnerException) { + file.serverErrorMessage = evt.InnerException.ExceptionMessage; + //Check if its the common "too large file" exception + if (evt.InnerException.StackTrace && + evt.InnerException.StackTrace.indexOf("ValidateRequestEntityLength") > 0) { + file.serverErrorMessage = "File too large to upload"; + } + } else if (evt.Message) { + file.serverErrorMessage = evt.Message; + } + // If file not found, server will return a 404 and display this message + if (status === 404) { + file.serverErrorMessage = "File not found"; + } + //after processing, test if everthing is done + scope.rejected.push(file); + scope.currentFile = undefined; + _processQueueItem(); + }); + } - if(file.$error) { - scope.rejected.push(file); - } else { - scope.queue.push(file); - } - } + function _chooseMediaType() { + scope.mediatypepickerOverlay = { + view: "mediatypepicker", + title: "Choose media type", + acceptedMediatypes: scope.acceptedMediatypes, + hideSubmitButton: true, + show: true, + submit: function(model) { + scope.contentTypeAlias = model.selectedType.alias; + scope.mediatypepickerOverlay.show = false; + scope.mediatypepickerOverlay = null; + _processQueueItem(); + }, + close: function(oldModel) { - }); - - //when queue is done, kick the uploader - if(!scope.working){ + scope.queue.map(function(file) { + file.uploadStatus = "error"; + file.serverErrorMessage = "Cannot upload this file, no mediatype selected"; + scope.rejected.push(file); + }); + scope.queue = []; + scope.mediatypepickerOverlay.show = false; + scope.mediatypepickerOverlay = null; + } + }; + } - // Upload not allowed - if(!scope.acceptedMediatypes || !scope.acceptedMediatypes.length){ - files.map(function(file){ - file.uploadStatus = "error"; - file.serverErrorMessage = "File type is not allowed here"; - scope.rejected.push(file); - }); - scope.queue = []; - } - - // One allowed type - if(scope.acceptedMediatypes && scope.acceptedMediatypes.length === 1) { - - // Standard setup - set alias to auto select to let the server best decide which media type to use - if(scope.acceptedMediatypes[0].alias === 'Image') { - scope.contentTypeAlias = "umbracoAutoSelect"; - } else { - scope.contentTypeAlias = scope.acceptedMediatypes[0].alias; - } - - _processQueueItem(); - } - - // More than one, open dialog - if(scope.acceptedMediatypes && scope.acceptedMediatypes.length > 1){ - _chooseMediaType(); - } - } - } - - function _processQueueItem(){ - - if(scope.queue.length > 0){ - scope.currentFile = scope.queue.shift(); - _upload(scope.currentFile); - }else if(scope.done.length > 0){ - - if(scope.filesUploaded){ - //queue is empty, trigger the done action - scope.filesUploaded(scope.done); - } - - //auto-clear the done queue after 3 secs - var currentLength = scope.done.length; - $timeout(function(){ - scope.done.splice(0, currentLength); - }, 3000); - } - } - - function _upload(file) { - - scope.propertyAlias = scope.propertyAlias ? scope.propertyAlias : "umbracoFile"; - scope.contentTypeAlias = scope.contentTypeAlias ? scope.contentTypeAlias : "Image"; - - Upload.upload({ - url: umbRequestHelper.getApiUrl("mediaApiBaseUrl", "PostAddFile"), - fields: { - 'currentFolder': scope.parentId, - 'contentTypeAlias': scope.contentTypeAlias, - 'propertyAlias': scope.propertyAlias, - 'path': file.path - }, - file: file - }).progress(function (evt) { - - // calculate progress in percentage - var progressPercentage = parseInt(100.0 * evt.loaded / evt.total, 10); - - // set percentage property on file - file.uploadProgress = progressPercentage; - - // set uploading status on file - file.uploadStatus = "uploading"; - - }).success(function (data, status, headers, config) { - - if(data.notifications && data.notifications.length > 0) { - - // set error status on file - file.uploadStatus = "error"; - - // Throw message back to user with the cause of the error - file.serverErrorMessage = data.notifications[0].message; - - // Put the file in the rejected pool - scope.rejected.push(file); - - } else { - - // set done status on file - file.uploadStatus = "done"; - - // set date/time for when done - used for sorting - file.doneDate = new Date(); - - // Put the file in the done pool - scope.done.push(file); - - } - - scope.currentFile = undefined; - - //after processing, test if everthing is done - _processQueueItem(); - - }).error( function (evt, status, headers, config) { - - // set status done - file.uploadStatus = "error"; - - //if the service returns a detailed error - if (evt.InnerException) { - file.serverErrorMessage = evt.InnerException.ExceptionMessage; - - //Check if its the common "too large file" exception - if (evt.InnerException.StackTrace && evt.InnerException.StackTrace.indexOf("ValidateRequestEntityLength") > 0) { - file.serverErrorMessage = "File too large to upload"; - } - - } else if (evt.Message) { - file.serverErrorMessage = evt.Message; - } - - // If file not found, server will return a 404 and display this message - if(status === 404 ) { - file.serverErrorMessage = "File not found"; - } - - //after processing, test if everthing is done - scope.rejected.push(file); - scope.currentFile = undefined; - - _processQueueItem(); - }); - } - - function _chooseMediaType() { - - scope.mediatypepickerOverlay = { - view: "mediatypepicker", - title: "Choose media type", - acceptedMediatypes: scope.acceptedMediatypes, - hideSubmitButton: true, - show: true, - submit: function(model) { - scope.contentTypeAlias = model.selectedType.alias; - - scope.mediatypepickerOverlay.show = false; - scope.mediatypepickerOverlay = null; - - _processQueueItem(); - }, - close: function(oldModel) { - - scope.queue.map(function(file){ - file.uploadStatus = "error"; - file.serverErrorMessage = "Cannot upload this file, no mediatype selected"; - scope.rejected.push(file); - }); - scope.queue = []; - - scope.mediatypepickerOverlay.show = false; - scope.mediatypepickerOverlay = null; - - } - }; - - } - - scope.handleFiles = function(files, event){ - if(scope.filesQueued){ - scope.filesQueued(files, event); - } - - _filesQueued(files, event); - - }; - - } - }; -}); + scope.handleFiles = function(files, event) { + if (scope.filesQueued) { + scope.filesQueued(files, event); + } + _filesQueued(files, event); + }; + } + }; + }); diff --git a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/mediapicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/mediapicker.controller.js index 504f547182..f337dbce18 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/mediapicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/mediapicker.controller.js @@ -1,7 +1,7 @@ //used for the media picker dialog angular.module("umbraco") .controller("Umbraco.Dialogs.MediaPickerController", - function ($scope, mediaResource, umbRequestHelper, entityResource, $log, mediaHelper, mediaTypeHelper, eventsService, treeService, $cookies, $element, $timeout) { + function($scope, mediaResource, umbRequestHelper, entityResource, $log, mediaHelper, mediaTypeHelper, eventsService, treeService) { var dialogOptions = $scope.dialogOptions; @@ -13,31 +13,32 @@ angular.module("umbraco") //preload selected item $scope.target = undefined; - if(dialogOptions.currentTarget){ + if (dialogOptions.currentTarget) { $scope.target = dialogOptions.currentTarget; } $scope.acceptedMediatypes = []; - mediaTypeHelper.getAllowedImagetypes($scope.startNodeId).then(function(types){ - $scope.acceptedMediatypes = types; - }); + mediaTypeHelper.getAllowedImagetypes($scope.startNodeId) + .then(function(types) { + $scope.acceptedMediatypes = types; + }); - $scope.upload = function(v){ - angular.element(".umb-file-dropzone-directive .file-select").click(); + $scope.upload = function(v) { + angular.element(".umb-file-dropzone-directive .file-select").click(); }; - $scope.dragLeave = function(el, event){ + $scope.dragLeave = function(el, event) { $scope.activeDrag = false; }; - $scope.dragEnter = function(el, event){ + $scope.dragEnter = function(el, event) { $scope.activeDrag = true; }; $scope.submitFolder = function(e) { if (e.keyCode === 13) { e.preventDefault(); - + mediaResource .addFolder($scope.newFolderName, $scope.currentFolder.id) .then(function(data) { @@ -56,25 +57,25 @@ angular.module("umbraco") }; $scope.gotoFolder = function(folder) { - - if(!folder){ - folder = {id: -1, name: "Media", icon: "icon-folder"}; + if (!folder) { + folder = { id: -1, name: "Media", icon: "icon-folder" }; } if (folder.id > 0) { entityResource.getAncestors(folder.id, "media") .then(function(anc) { // anc.splice(0,1); - $scope.path = _.filter(anc, function (f) { - return f.path.indexOf($scope.startNodeId) !== -1; - }); + $scope.path = _.filter(anc, + function(f) { + return f.path.indexOf($scope.startNodeId) !== -1; + }); }); - mediaTypeHelper.getAllowedImagetypes(folder.id).then(function(types){ - $scope.acceptedMediatypes = types; - }); - } - else { + mediaTypeHelper.getAllowedImagetypes(folder.id) + .then(function(types) { + $scope.acceptedMediatypes = types; + }); + } else { $scope.path = []; } @@ -84,50 +85,50 @@ angular.module("umbraco") $scope.searchTerm = ""; $scope.images = data.items ? data.items : []; }); - - $scope.currentFolder = folder; + + $scope.currentFolder = folder; }; - - + + $scope.clickHandler = function(image, ev, select) { ev.preventDefault(); - + if (image.isFolder && !select) { $scope.gotoFolder(image); - }else{ + } else { eventsService.emit("dialogs.mediaPicker.select", image); - + //we have 3 options add to collection (if multi) show details, or submit it right back to the callback if ($scope.multiPicker) { $scope.select(image); image.cssclass = ($scope.dialogData.selection.indexOf(image) > -1) ? "selected" : ""; - }else if($scope.showDetails) { - $scope.target= image; + } else if ($scope.showDetails) { + $scope.target = image; $scope.target.url = mediaHelper.resolveFile(image); - }else{ + } else { $scope.submit(image); } } }; - $scope.exitDetails = function(){ - if(!$scope.currentFolder){ + $scope.exitDetails = function() { + if (!$scope.currentFolder) { $scope.gotoFolder(); } $scope.target = undefined; }; - $scope.onUploadComplete = function () { + $scope.onUploadComplete = function() { $scope.gotoFolder($scope.currentFolder); }; - $scope.onFilesQueue = function(){ + $scope.onFilesQueue = function() { $scope.activeDrag = false; }; //default root item - if(!$scope.target){ - $scope.gotoFolder({ id: $scope.startNodeId, name: "Media", icon: "icon-folder" }); + if (!$scope.target) { + $scope.gotoFolder({ id: $scope.startNodeId, name: "Media", icon: "icon-folder" }); } }); \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/views/common/overlays/mediaPicker/mediapicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/overlays/mediaPicker/mediapicker.controller.js index 27bc380fd3..43c65d99ee 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/overlays/mediaPicker/mediapicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/overlays/mediaPicker/mediapicker.controller.js @@ -1,9 +1,9 @@ //used for the media picker dialog angular.module("umbraco") .controller("Umbraco.Overlays.MediaPickerController", - function ($scope, mediaResource, umbRequestHelper, entityResource, $log, mediaHelper, mediaTypeHelper, eventsService, treeService, $element, $timeout, $cookies, $cookieStore, localizationService) { + function($scope, mediaResource, umbRequestHelper, entityResource, $log, mediaHelper, mediaTypeHelper, eventsService, treeService, $element, $timeout, $cookies, $cookieStore, localizationService) { - if(!$scope.model.title) { + if (!$scope.model.title) { $scope.model.title = localizationService.localize("defaultdialogs_selectMedia"); } @@ -16,65 +16,59 @@ angular.module("umbraco") $scope.startNodeId = dialogOptions.startNodeId ? dialogOptions.startNodeId : -1; $scope.cropSize = dialogOptions.cropSize; $scope.lastOpenedNode = $cookieStore.get("umbLastOpenedMediaNodeId"); - if($scope.onlyImages){ - $scope.acceptedFileTypes = mediaHelper.formatFileTypes(Umbraco.Sys.ServerVariables.umbracoSettings.imageFileTypes); - } - else { - $scope.acceptedFileTypes = !mediaHelper.formatFileTypes(Umbraco.Sys.ServerVariables.umbracoSettings.disallowedUploadFiles); + if ($scope.onlyImages) { + $scope.acceptedFileTypes = mediaHelper + .formatFileTypes(Umbraco.Sys.ServerVariables.umbracoSettings.imageFileTypes); + } else { + $scope.acceptedFileTypes = !mediaHelper + .formatFileTypes(Umbraco.Sys.ServerVariables.umbracoSettings.disallowedUploadFiles); } $scope.maxFileSize = Umbraco.Sys.ServerVariables.umbracoSettings.maxFileSize + "KB"; $scope.model.selectedImages = []; $scope.acceptedMediatypes = []; - mediaTypeHelper.getAllowedImagetypes($scope.startNodeId).then(function(types){ - $scope.acceptedMediatypes = types; - }); + mediaTypeHelper.getAllowedImagetypes($scope.startNodeId) + .then(function(types) { + $scope.acceptedMediatypes = types; + }); //preload selected item $scope.target = undefined; - if(dialogOptions.currentTarget){ + if (dialogOptions.currentTarget) { $scope.target = dialogOptions.currentTarget; } - $scope.upload = function(v){ - angular.element(".umb-file-dropzone-directive .file-select").click(); + $scope.upload = function(v) { + angular.element(".umb-file-dropzone-directive .file-select").click(); }; - $scope.dragLeave = function(el, event){ + $scope.dragLeave = function(el, event) { $scope.activeDrag = false; }; - $scope.dragEnter = function(el, event){ + $scope.dragEnter = function(el, event) { $scope.activeDrag = true; }; $scope.submitFolder = function() { + if ($scope.newFolderName) { + mediaResource + .addFolder($scope.newFolderName, $scope.currentFolder.id) + .then(function(data) { + //we've added a new folder so lets clear the tree cache for that specific item + treeService.clearCache({ + cacheKey: "__media", //this is the main media tree cache key + childrenOf: data.parentId //clear the children of the parent + }); - if ($scope.newFolderName) { - - mediaResource - .addFolder($scope.newFolderName, $scope.currentFolder.id) - .then(function(data) { - - //we've added a new folder so lets clear the tree cache for that specific item - treeService.clearCache({ - cacheKey: "__media", //this is the main media tree cache key - childrenOf: data.parentId //clear the children of the parent + $scope.gotoFolder(data); + $scope.showFolderInput = false; + $scope.newFolderName = ""; }); - - $scope.gotoFolder(data); - - $scope.showFolderInput = false; - - $scope.newFolderName = ""; - - }); - - } else { - $scope.showFolderInput = false; - } - + } else { + $scope.showFolderInput = false; + } }; $scope.enterSubmitFolder = function(event) { @@ -86,62 +80,61 @@ angular.module("umbraco") $scope.gotoFolder = function(folder) { - if(!$scope.multiPicker) { + if (!$scope.multiPicker) { deselectAllImages($scope.model.selectedImages); } - if(!folder){ - folder = {id: -1, name: "Media", icon: "icon-folder"}; + if (!folder) { + folder = { id: -1, name: "Media", icon: "icon-folder" }; } if (folder.id > 0) { entityResource.getAncestors(folder.id, "media") .then(function(anc) { // anc.splice(0,1); - $scope.path = _.filter(anc, function (f) { - return f.path.indexOf($scope.startNodeId) !== -1; - }); + $scope.path = _.filter(anc, + function(f) { + return f.path.indexOf($scope.startNodeId) !== -1; + }); }); - mediaTypeHelper.getAllowedImagetypes(folder.id).then(function(types){ + mediaTypeHelper.getAllowedImagetypes(folder.id) + .then(function(types) { $scope.acceptedMediatypes = types; }); - } - else { + } else { $scope.path = []; } //mediaResource.rootMedia() mediaResource.getChildren(folder.id) - .then(function(data) { - $scope.searchTerm = ""; - $scope.images = data.items ? data.items : []; + .then(function(data) { + $scope.searchTerm = ""; + $scope.images = data.items ? data.items : []; - // set already selected images to selected - for (var folderImageIndex = 0; folderImageIndex < $scope.images.length; folderImageIndex++) { + // set already selected images to selected + for (var folderImageIndex = 0; folderImageIndex < $scope.images.length; folderImageIndex++) { + var folderImage = $scope.images[folderImageIndex]; + var imageIsSelected = false; - var folderImage = $scope.images[folderImageIndex]; - var imageIsSelected = false; + for (var selectedImageIndex = 0; + selectedImageIndex < $scope.model.selectedImages.length; + selectedImageIndex++) { + var selectedImage = $scope.model.selectedImages[selectedImageIndex]; - for (var selectedImageIndex = 0; selectedImageIndex < $scope.model.selectedImages.length; selectedImageIndex++) { - var selectedImage = $scope.model.selectedImages[selectedImageIndex]; - - if(folderImage.key === selectedImage.key) { - imageIsSelected = true; + if (folderImage.key === selectedImage.key) { + imageIsSelected = true; + } } - } - - if(imageIsSelected) { - folderImage.selected = true; - } - } - - }); - + if (imageIsSelected) { + folderImage.selected = true; + } + } + }); $scope.currentFolder = folder; // for some reason i cannot set cookies with cookieStore - document.cookie="umbLastOpenedMediaNodeId=" + folder.id; + document.cookie = "umbLastOpenedMediaNodeId=" + folder.id; }; @@ -153,52 +146,40 @@ angular.module("umbraco") eventsService.emit("dialogs.mediaPicker.select", image); selectImage(image); } - } else { - eventsService.emit("dialogs.mediaPicker.select", image); - - if($scope.showDetails) { + if ($scope.showDetails) { $scope.target = image; $scope.target.url = mediaHelper.resolveFile(image); $scope.openDetailsDialog(); } else { selectImage(image); } - } - }; $scope.clickItemName = function(item) { - if(item.isFolder) { + if (item.isFolder) { $scope.gotoFolder(item); } }; function selectImage(image) { - - if(image.selected) { - - for(var i = 0; $scope.model.selectedImages.length > i; i++) { - + if (image.selected) { + for (var i = 0; $scope.model.selectedImages.length > i; i++) { var imageInSelection = $scope.model.selectedImages[i]; - if(image.key === imageInSelection.key) { + if (image.key === imageInSelection.key) { image.selected = false; $scope.model.selectedImages.splice(i, 1); } } - } else { - - if(!$scope.multiPicker) { + if (!$scope.multiPicker) { deselectAllImages($scope.model.selectedImages); } - image.selected = true; $scope.model.selectedImages.push(image); } - } function deselectAllImages(images) { @@ -209,64 +190,53 @@ angular.module("umbraco") images.length = 0; } - $scope.onUploadComplete = function () { + $scope.onUploadComplete = function() { $scope.gotoFolder($scope.currentFolder); }; - $scope.onFilesQueue = function(){ + $scope.onFilesQueue = function() { $scope.activeDrag = false; }; //default root item if (!$scope.target) { + if ($scope.lastOpenedNode && $scope.lastOpenedNode !== -1) { + entityResource.getById($scope.lastOpenedNode, "media") + .then(function(node) { + // make sure that las opened node is on the same path as start node + var nodePath = node.path.split(","); - if($scope.lastOpenedNode && $scope.lastOpenedNode !== -1) { - - entityResource.getById($scope.lastOpenedNode, "media") - .then(function(node){ - - // make sure that las opened node is on the same path as start node - var nodePath = node.path.split(","); - - if(nodePath.indexOf($scope.startNodeId.toString()) !== -1) { - $scope.gotoFolder({id: $scope.lastOpenedNode, name: "Media", icon: "icon-folder"}); - } else { - $scope.gotoFolder({id: $scope.startNodeId, name: "Media", icon: "icon-folder"}); - } - - }, function (err) { - $scope.gotoFolder({id: $scope.startNodeId, name: "Media", icon: "icon-folder"}); - }); - - } else { - - $scope.gotoFolder({id: $scope.startNodeId, name: "Media", icon: "icon-folder"}); - - } - + if (nodePath.indexOf($scope.startNodeId.toString()) !== -1) { + $scope + .gotoFolder({ id: $scope.lastOpenedNode, name: "Media", icon: "icon-folder" }); + } else { + $scope.gotoFolder({ id: $scope.startNodeId, name: "Media", icon: "icon-folder" }); + } + }, + function(err) { + $scope.gotoFolder({ id: $scope.startNodeId, name: "Media", icon: "icon-folder" }); + }); + } else { + $scope.gotoFolder({ id: $scope.startNodeId, name: "Media", icon: "icon-folder" }); + } } $scope.openDetailsDialog = function() { - $scope.mediaPickerDetailsOverlay = {}; - $scope.mediaPickerDetailsOverlay.show = true; + $scope.mediaPickerDetailsOverlay = {}; + $scope.mediaPickerDetailsOverlay.show = true; - $scope.mediaPickerDetailsOverlay.submit = function(model) { + $scope.mediaPickerDetailsOverlay.submit = function(model) { + $scope.model.selectedImages.push($scope.target); + $scope.model.submit($scope.model); - $scope.model.selectedImages.push($scope.target); - $scope.model.submit($scope.model); - - $scope.mediaPickerDetailsOverlay.show = false; - $scope.mediaPickerDetailsOverlay = null; - - }; - - $scope.mediaPickerDetailsOverlay.close = function(oldModel) { - $scope.mediaPickerDetailsOverlay.show = false; - $scope.mediaPickerDetailsOverlay = null; - }; + $scope.mediaPickerDetailsOverlay.show = false; + $scope.mediaPickerDetailsOverlay = null; + }; + $scope.mediaPickerDetailsOverlay.close = function(oldModel) { + $scope.mediaPickerDetailsOverlay.show = false; + $scope.mediaPickerDetailsOverlay = null; + }; }; - - }); From 199c5023969bbc7cdbd357cb3b65daf5d5ba811a Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Mon, 14 Nov 2016 15:24:41 +0100 Subject: [PATCH 46/49] Get the correct types --- src/UmbracoExamine/UmbracoContentIndexer.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/UmbracoExamine/UmbracoContentIndexer.cs b/src/UmbracoExamine/UmbracoContentIndexer.cs index ce3583a6be..a9405b7755 100644 --- a/src/UmbracoExamine/UmbracoContentIndexer.cs +++ b/src/UmbracoExamine/UmbracoContentIndexer.cs @@ -419,8 +419,8 @@ namespace UmbracoExamine XElement[] mediaXElements; - var nodeTypes = _contentTypeService.GetAllContentTypes().ToArray(); - var icons = nodeTypes.ToDictionary(x => x.Id, y => y.Icon); + var mediaTypes = _contentTypeService.GetAllMediaTypes().ToArray(); + var icons = mediaTypes.ToDictionary(x => x.Id, y => y.Icon); do { @@ -443,7 +443,7 @@ namespace UmbracoExamine //TODO: Update the service layer to join the cmsContentType table so we can query by content type too if (IndexerData.IncludeNodeTypes.Any()) { - var includeNodeTypeIds = nodeTypes.Where(x => IndexerData.IncludeNodeTypes.Contains(x.Alias)).Select(x => x.Id); + var includeNodeTypeIds = mediaTypes.Where(x => IndexerData.IncludeNodeTypes.Contains(x.Alias)).Select(x => x.Id); mediaXElements = mediaXElements.Where(elm => includeNodeTypeIds.Contains(elm.AttributeValue("nodeType"))).ToArray(); } From 935d010dd2fd2d9e0acbbf15377dda741009a336 Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Mon, 14 Nov 2016 15:26:25 +0100 Subject: [PATCH 47/49] The foreach is actually more readable --- src/UmbracoExamine/UmbracoContentIndexer.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/UmbracoExamine/UmbracoContentIndexer.cs b/src/UmbracoExamine/UmbracoContentIndexer.cs index a9405b7755..301491c975 100644 --- a/src/UmbracoExamine/UmbracoContentIndexer.cs +++ b/src/UmbracoExamine/UmbracoContentIndexer.cs @@ -446,11 +446,10 @@ namespace UmbracoExamine var includeNodeTypeIds = mediaTypes.Where(x => IndexerData.IncludeNodeTypes.Contains(x.Alias)).Select(x => x.Id); mediaXElements = mediaXElements.Where(elm => includeNodeTypeIds.Contains(elm.AttributeValue("nodeType"))).ToArray(); } - - // ReSharper disable once ForCanBeConvertedToForeach - for (var i = 0; i < mediaXElements.Length; i++) + + foreach (var element in mediaXElements) { - mediaXElements[i].Add(new XAttribute("icon", icons[mediaXElements[i].AttributeValue("nodeType")])); + element.Add(new XAttribute("icon", icons[element.AttributeValue("nodeType")])); } AddNodesToIndex(mediaXElements, type); From 714b7019c5e5085d54e983ef49bbe5a02d400731 Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Mon, 14 Nov 2016 15:38:50 +0100 Subject: [PATCH 48/49] Fix unit tests to have the correct types as well --- src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs b/src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs index 89a9df8052..00e94ced63 100644 --- a/src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs +++ b/src/Umbraco.Tests/UmbracoExamine/IndexInitializer.cs @@ -159,11 +159,11 @@ namespace Umbraco.Tests.UmbracoExamine if (contentTypeService == null) { var contentTypeServiceMock = new Mock(); - contentTypeServiceMock.Setup(x => x.GetAllContentTypes()) - .Returns(new List() + contentTypeServiceMock.Setup(x => x.GetAllMediaTypes()) + .Returns(new List() { - new ContentType(-1) {Alias = "Folder", Name = "Folder", Id = 1031, Icon = "icon-folder"}, - new ContentType(-1) {Alias = "Image", Name = "Image", Id = 1032, Icon = "icon-picture"} + new MediaType(-1) {Alias = "Folder", Name = "Folder", Id = 1031, Icon = "icon-folder"}, + new MediaType(-1) {Alias = "Image", Name = "Image", Id = 1032, Icon = "icon-picture"} }); contentTypeService = contentTypeServiceMock.Object; } From 5b714572e3d2d80a087ed90ba185465e46971d17 Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Mon, 14 Nov 2016 17:04:40 +0100 Subject: [PATCH 49/49] Bump version --- build/UmbracoVersion.txt | 2 +- src/SolutionInfo.cs | 4 ++-- src/Umbraco.Core/Configuration/UmbracoVersion.cs | 2 +- src/Umbraco.Web.UI/Umbraco.Web.UI.csproj | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/build/UmbracoVersion.txt b/build/UmbracoVersion.txt index 469bf7a466..df03fe8381 100644 --- a/build/UmbracoVersion.txt +++ b/build/UmbracoVersion.txt @@ -1,2 +1,2 @@ # Usage: on line 2 put the release version, on line 3 put the version comment (example: beta) -7.5.4 \ No newline at end of file +7.5.5 \ No newline at end of file diff --git a/src/SolutionInfo.cs b/src/SolutionInfo.cs index 39cbd18c2a..b3b5633864 100644 --- a/src/SolutionInfo.cs +++ b/src/SolutionInfo.cs @@ -11,5 +11,5 @@ using System.Resources; [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyFileVersion("7.5.4")] -[assembly: AssemblyInformationalVersion("7.5.4")] \ No newline at end of file +[assembly: AssemblyFileVersion("7.5.5")] +[assembly: AssemblyInformationalVersion("7.5.5")] \ No newline at end of file diff --git a/src/Umbraco.Core/Configuration/UmbracoVersion.cs b/src/Umbraco.Core/Configuration/UmbracoVersion.cs index ddde8fbd5f..ccf4aecf13 100644 --- a/src/Umbraco.Core/Configuration/UmbracoVersion.cs +++ b/src/Umbraco.Core/Configuration/UmbracoVersion.cs @@ -6,7 +6,7 @@ namespace Umbraco.Core.Configuration { public class UmbracoVersion { - private static readonly Version Version = new Version("7.5.4"); + private static readonly Version Version = new Version("7.5.5"); /// /// Gets the current version of Umbraco. diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index 6f2728a241..a31d174e14 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -2412,9 +2412,9 @@ xcopy "$(ProjectDir)"..\packages\SqlServerCE.4.0.0.1\x86\*.* "$(TargetDir)x86\" True True - 7540 + 7550 / - http://localhost:7540 + http://localhost:7550 False False