Merge branch 'netcore/netcore' into netcore/members-userstore
This commit is contained in:
@@ -167,6 +167,23 @@ JOIN umbracoNode ON umbracoRedirectUrl.contentKey=umbracoNode.uniqueID");
|
||||
return dto == null ? null : Map(dto);
|
||||
}
|
||||
|
||||
public IRedirectUrl GetMostRecentUrl(string url, string culture)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(culture)) return GetMostRecentUrl(url);
|
||||
var urlHash = url.GenerateHash<SHA1>();
|
||||
var sql = GetBaseQuery(false)
|
||||
.Where<RedirectUrlDto>(x => x.Url == url && x.UrlHash == urlHash &&
|
||||
(x.Culture == culture.ToLower() || x.Culture == string.Empty))
|
||||
.OrderByDescending<RedirectUrlDto>(x => x.CreateDateUtc);
|
||||
var dtos = Database.Fetch<RedirectUrlDto>(sql);
|
||||
var dto = dtos.FirstOrDefault(f => f.Culture == culture.ToLower());
|
||||
|
||||
if (dto == null)
|
||||
dto = dtos.FirstOrDefault(f => f.Culture == string.Empty);
|
||||
|
||||
return dto == null ? null : Map(dto);
|
||||
}
|
||||
|
||||
public IEnumerable<IRedirectUrl> GetContentUrls(Guid contentKey)
|
||||
{
|
||||
var sql = GetBaseQuery(false)
|
||||
@@ -208,17 +225,5 @@ JOIN umbracoNode ON umbracoRedirectUrl.contentKey=umbracoNode.uniqueID");
|
||||
var rules = result.Items.Select(Map);
|
||||
return rules;
|
||||
}
|
||||
|
||||
public IRedirectUrl GetMostRecentUrl(string url, string culture)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(culture)) return GetMostRecentUrl(url);
|
||||
var urlHash = url.GenerateHash<SHA1>();
|
||||
var sql = GetBaseQuery(false)
|
||||
.Where<RedirectUrlDto>(x => x.Url == url && x.UrlHash == urlHash && x.Culture == culture.ToLower())
|
||||
.OrderByDescending<RedirectUrlDto>(x => x.CreateDateUtc);
|
||||
var dtos = Database.Fetch<RedirectUrlDto>(sql);
|
||||
var dto = dtos.FirstOrDefault();
|
||||
return dto == null ? null : Map(dto);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -260,7 +260,7 @@ namespace Umbraco.Core.Services.Implement
|
||||
// this method must exist in this service as an implementation (legacy)
|
||||
void IMembershipMemberService<IUser>.SetLastLogin(string username, DateTime date)
|
||||
{
|
||||
throw new NotSupportedException("This method is not implemented or supported for users");
|
||||
_logger.LogWarning("This method is not implemented. Using membership providers users is not advised, use ASP.NET Identity instead. See issue #9224 for more information.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) Umbraco.
|
||||
// Copyright (c) Umbraco.
|
||||
// See LICENSE for more details.
|
||||
|
||||
using System;
|
||||
@@ -46,6 +46,10 @@ namespace Umbraco.Tests.Integration.Testing
|
||||
Subpage2 = ContentBuilder.CreateSimpleContent(ContentType, "Text Page 2", Textpage.Id);
|
||||
ContentService.Save(Subpage2, 0);
|
||||
|
||||
|
||||
Subpage3 = ContentBuilder.CreateSimpleContent(ContentType, "Text Page 3", Textpage.Id);
|
||||
ContentService.Save(Subpage3, 0);
|
||||
|
||||
// Create and Save Content "Text Page Deleted" based on "umbTextpage" -> 1056
|
||||
Trashed = ContentBuilder.CreateSimpleContent(ContentType, "Text Page Deleted", -20);
|
||||
Trashed.Trashed = true;
|
||||
@@ -55,6 +59,7 @@ namespace Umbraco.Tests.Integration.Testing
|
||||
protected Content Trashed { get; private set; }
|
||||
|
||||
protected Content Subpage2 { get; private set; }
|
||||
protected Content Subpage3 { get; private set; }
|
||||
|
||||
protected Content Subpage { get; private set; }
|
||||
|
||||
|
||||
@@ -2009,7 +2009,7 @@ namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Services
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void HasInitialContent() => Assert.AreEqual(4, ContentService.Count());
|
||||
public void HasInitialContent() => Assert.AreEqual(5, ContentService.Count());
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
@@ -363,7 +363,7 @@ namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Services
|
||||
}
|
||||
|
||||
// Assert
|
||||
Assert.AreEqual(24, ContentService.Count());
|
||||
Assert.AreEqual(25, ContentService.Count());
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -1634,7 +1634,7 @@ namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Services
|
||||
|
||||
Assert.AreNotEqual(-20, content.ParentId);
|
||||
Assert.IsFalse(content.Trashed);
|
||||
Assert.AreEqual(3, descendants.Count);
|
||||
Assert.AreEqual(4, descendants.Count);
|
||||
Assert.IsFalse(descendants.Any(x => x.Path.StartsWith("-1,-20,")));
|
||||
Assert.IsFalse(descendants.Any(x => x.Trashed));
|
||||
|
||||
@@ -1649,7 +1649,7 @@ namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Services
|
||||
|
||||
Assert.AreEqual(-20, content.ParentId);
|
||||
Assert.IsTrue(content.Trashed);
|
||||
Assert.AreEqual(3, descendants.Count);
|
||||
Assert.AreEqual(4, descendants.Count);
|
||||
Assert.IsTrue(descendants.All(x => x.Path.StartsWith("-1,-20,")));
|
||||
Assert.True(descendants.All(x => x.Trashed));
|
||||
|
||||
@@ -1942,7 +1942,7 @@ namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Services
|
||||
// Arrange
|
||||
IContent temp = ContentService.GetById(Textpage.Id);
|
||||
Assert.AreEqual("Home", temp.Name);
|
||||
Assert.AreEqual(2, ContentService.CountChildren(temp.Id));
|
||||
Assert.AreEqual(3, ContentService.CountChildren(temp.Id));
|
||||
|
||||
// Act
|
||||
IContent copy = ContentService.Copy(temp, temp.ParentId, false, true, Constants.Security.SuperUserId);
|
||||
@@ -1952,7 +1952,7 @@ namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Services
|
||||
Assert.That(copy, Is.Not.Null);
|
||||
Assert.That(copy.Id, Is.Not.EqualTo(content.Id));
|
||||
Assert.AreNotSame(content, copy);
|
||||
Assert.AreEqual(2, ContentService.CountChildren(copy.Id));
|
||||
Assert.AreEqual(3, ContentService.CountChildren(copy.Id));
|
||||
|
||||
IContent child = ContentService.GetById(Subpage.Id);
|
||||
IContent childCopy = ContentService.GetPagedChildren(copy.Id, 0, 500, out long total).First();
|
||||
@@ -1967,7 +1967,7 @@ namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Services
|
||||
// Arrange
|
||||
IContent temp = ContentService.GetById(Textpage.Id);
|
||||
Assert.AreEqual("Home", temp.Name);
|
||||
Assert.AreEqual(2, ContentService.CountChildren(temp.Id));
|
||||
Assert.AreEqual(3, ContentService.CountChildren(temp.Id));
|
||||
|
||||
// Act
|
||||
IContent copy = ContentService.Copy(temp, temp.ParentId, false, false, Constants.Security.SuperUserId);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) Umbraco.
|
||||
// Copyright (c) Umbraco.
|
||||
// See LICENSE for more details.
|
||||
|
||||
using System;
|
||||
|
||||
@@ -6,6 +6,8 @@ using System.Threading;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Persistence.Repositories.Implement;
|
||||
@@ -21,11 +23,14 @@ namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Services
|
||||
[UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest)]
|
||||
public class RedirectUrlServiceTests : UmbracoIntegrationTestWithContent
|
||||
{
|
||||
private IContent _testPage;
|
||||
private IContent _altTestPage;
|
||||
private IContent _firstSubPage;
|
||||
private IContent _secondSubPage;
|
||||
private IContent _thirdSubPage;
|
||||
private const string Url = "blah";
|
||||
private const string CultureA = "en";
|
||||
private const string CultureB = "de";
|
||||
private const string UrlAlt = "alternativeUrl";
|
||||
private const string CultureEnglish = "en";
|
||||
private const string CultureGerman = "de";
|
||||
private const string UnusedCulture = "es";
|
||||
|
||||
private IRedirectUrlService RedirectUrlService => GetRequiredService<IRedirectUrlService>();
|
||||
|
||||
@@ -37,22 +42,33 @@ namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Services
|
||||
{
|
||||
var repository = new RedirectUrlRepository((IScopeAccessor)ScopeProvider, AppCaches.Disabled, Mock.Of<ILogger<RedirectUrlRepository>>());
|
||||
IContent rootContent = ContentService.GetRootContent().First();
|
||||
var subPages = ContentService.GetPagedChildren(rootContent.Id, 0, 2, out _).ToList();
|
||||
_testPage = subPages[0];
|
||||
_altTestPage = subPages[1];
|
||||
var subPages = ContentService.GetPagedChildren(rootContent.Id, 0, 3, out _).ToList();
|
||||
_firstSubPage = subPages[0];
|
||||
_secondSubPage = subPages[1];
|
||||
_thirdSubPage = subPages[2];
|
||||
|
||||
|
||||
repository.Save(new RedirectUrl
|
||||
{
|
||||
ContentKey = _testPage.Key,
|
||||
ContentKey = _firstSubPage.Key,
|
||||
Url = Url,
|
||||
Culture = CultureA
|
||||
Culture = CultureEnglish
|
||||
});
|
||||
Thread.Sleep(1000); //Added delay to ensure timestamp difference as sometimes they seem to have the same timestamp
|
||||
repository.Save(new RedirectUrl
|
||||
{
|
||||
ContentKey = _altTestPage.Key,
|
||||
ContentKey = _secondSubPage.Key,
|
||||
Url = Url,
|
||||
Culture = CultureB
|
||||
Culture = CultureGerman
|
||||
});
|
||||
Thread.Sleep(1000);
|
||||
repository.Save(new RedirectUrl
|
||||
{
|
||||
ContentKey = _thirdSubPage.Key,
|
||||
Url = UrlAlt,
|
||||
Culture = string.Empty
|
||||
});
|
||||
|
||||
scope.Complete();
|
||||
}
|
||||
}
|
||||
@@ -61,14 +77,22 @@ namespace Umbraco.Tests.Integration.Umbraco.Infrastructure.Services
|
||||
public void Can_Get_Most_Recent_RedirectUrl()
|
||||
{
|
||||
IRedirectUrl redirect = RedirectUrlService.GetMostRecentRedirectUrl(Url);
|
||||
Assert.AreEqual(redirect.ContentId, _altTestPage.Id);
|
||||
Assert.AreEqual(redirect.ContentId, _secondSubPage.Id);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Get_Most_Recent_RedirectUrl_With_Culture()
|
||||
{
|
||||
IRedirectUrl redirect = RedirectUrlService.GetMostRecentRedirectUrl(Url, CultureA);
|
||||
Assert.AreEqual(redirect.ContentId, _testPage.Id);
|
||||
var redirect = RedirectUrlService.GetMostRecentRedirectUrl(Url, CultureEnglish);
|
||||
Assert.AreEqual(redirect.ContentId, _firstSubPage.Id);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Get_Most_Recent_RedirectUrl_With_Culture_When_No_CultureVariant_Exists()
|
||||
{
|
||||
var redirect = RedirectUrlService.GetMostRecentRedirectUrl(UrlAlt, UnusedCulture);
|
||||
Assert.AreEqual(redirect.ContentId, _thirdSubPage.Id);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,6 +41,9 @@ namespace Umbraco.Tests.Services
|
||||
Content subpage2 = MockedContent.CreateSimpleContent(contentType, "Text Page 2", textpage.Id);
|
||||
ServiceContext.ContentService.Save(subpage2, 0);
|
||||
|
||||
Content subpage3 = MockedContent.CreateSimpleContent(contentType, "Text Page 3", textpage.Id);
|
||||
ServiceContext.ContentService.Save(subpage3, 0);
|
||||
|
||||
//Create and Save Content "Text Page Deleted" based on "umbTextpage" -> 1064
|
||||
Content trashed = MockedContent.CreateSimpleContent(contentType, "Text Page Deleted", -20);
|
||||
trashed.Trashed = true;
|
||||
|
||||
@@ -10,18 +10,14 @@ angular.module("umbraco.directives")
|
||||
}
|
||||
};
|
||||
|
||||
//check if there's a value for the attribute, if there is and it's false then we conditionally don't
|
||||
//use auto focus.
|
||||
if (attrs.umbAutoFocus) {
|
||||
attrs.$observe("umbAutoFocus", function (newVal) {
|
||||
var enabled = (newVal === "false" || newVal === 0 || newVal === false) ? false : true;
|
||||
if (enabled) {
|
||||
$timeout(function() {
|
||||
update();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
attrs.$observe("umbAutoFocus", function (newVal) {
|
||||
var enabled = (newVal === "false" || newVal === 0 || newVal === false) ? false : true;
|
||||
if (enabled) {
|
||||
$timeout(function() {
|
||||
update();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
};
|
||||
});
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
function UmbRadiobuttonController($timeout) {
|
||||
function UmbRadiobuttonController($timeout, localizationService) {
|
||||
|
||||
var vm = this;
|
||||
|
||||
|
||||
@@ -11,6 +11,11 @@ function angularHelper($q) {
|
||||
var requiredFormProps = ["$error", "$name", "$dirty", "$pristine", "$valid", "$submitted", "$pending"];
|
||||
|
||||
function collectAllFormErrorsRecursively(formCtrl, allErrors) {
|
||||
// skip if the control is already added to the array
|
||||
if (allErrors.indexOf(formCtrl) !== -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
// loop over the error dictionary (see https://docs.angularjs.org/api/ng/type/form.FormController#$error)
|
||||
var keys = Object.keys(formCtrl.$error);
|
||||
if (keys.length === 0) {
|
||||
@@ -31,6 +36,7 @@ function angularHelper($q) {
|
||||
allErrors.push(ctrl); // add the error
|
||||
return;
|
||||
}
|
||||
|
||||
// recurse with the sub form
|
||||
collectAllFormErrorsRecursively(ctrl, allErrors);
|
||||
}
|
||||
@@ -43,6 +49,7 @@ function angularHelper($q) {
|
||||
}
|
||||
|
||||
function isForm(obj) {
|
||||
|
||||
// a method to check that the collection of object prop names contains the property name expected
|
||||
function allPropertiesExist(objectPropNames) {
|
||||
//ensure that every required property name exists on the current object
|
||||
@@ -89,9 +96,9 @@ function angularHelper($q) {
|
||||
|
||||
/**
|
||||
* Method used to re-run the $parsers for a given ngModel
|
||||
* @param {} scope
|
||||
* @param {} ngModel
|
||||
* @returns {}
|
||||
* @param {} scope
|
||||
* @param {} ngModel
|
||||
* @returns {}
|
||||
*/
|
||||
revalidateNgModel: function (scope, ngModel) {
|
||||
this.safeApply(scope, function() {
|
||||
@@ -103,8 +110,8 @@ function angularHelper($q) {
|
||||
|
||||
/**
|
||||
* Execute a list of promises sequentially. Unlike $q.all which executes all promises at once, this will execute them in sequence.
|
||||
* @param {} promises
|
||||
* @returns {}
|
||||
* @param {} promises
|
||||
* @returns {}
|
||||
*/
|
||||
executeSequentialPromises: function (promises) {
|
||||
|
||||
@@ -178,7 +185,7 @@ function angularHelper($q) {
|
||||
//NOTE: There isn't a way in angular to get a reference to the current form object since the form object
|
||||
// is just defined as a property of the scope when it is named but you'll always need to know the name which
|
||||
// isn't very convenient. If we want to watch for validation changes we need to get a form reference.
|
||||
// The way that we detect the form object is a bit hackerific in that we detect all of the required properties
|
||||
// The way that we detect the form object is a bit hackerific in that we detect all of the required properties
|
||||
// that exist on a form object.
|
||||
//
|
||||
//The other way to do it in a directive is to require "^form", but in a controller the only other way to do it
|
||||
@@ -239,7 +246,7 @@ function angularHelper($q) {
|
||||
$submitted: false,
|
||||
$pending: undefined,
|
||||
$addControl: Utilities.noop,
|
||||
$removeControl: Utilities.noop,
|
||||
$removeControl: Utilities.noop,
|
||||
$setValidity: Utilities.noop,
|
||||
$setDirty: Utilities.noop,
|
||||
$setPristine: Utilities.noop,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<div class="umb-node-preview" ng-class="{'umb-node-preview--sortable': sortable, 'umb-node-preview--unpublished': published === false }">
|
||||
<div class="flex"> <!-- div keeps icon and nodename from wrapping -->
|
||||
<umb-icon ng-if="icon" icon="{{icon}}" class="umb-node-preview__icon"></umb-icon>
|
||||
<umb-icon ng-if="icon" icon="{{icon}}" class="umb-node-preview__icon {{icon}}"></umb-icon>
|
||||
|
||||
<div class="umb-node-preview__content">
|
||||
|
||||
|
||||
Reference in New Issue
Block a user