Compare commits
102 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 92f609ff71 | |||
| 7e6f7f8a2b | |||
| c5419e700b | |||
| cb09094632 | |||
| 72404e68a0 | |||
| 2c451c5cfe | |||
| af7f83f0f6 | |||
| 5b3c2178a2 | |||
| 145f789631 | |||
| e27e95cb1a | |||
| cdbc3fa8cd | |||
| 6feb7b222f | |||
| b0a739b4ac | |||
| 728dee070f | |||
| 4a735770e2 | |||
| d54b3a0cc3 | |||
| f962a3db20 | |||
| 39851d2475 | |||
| 28adbc17ef | |||
| 4b9a13078e | |||
| 17cce9a666 | |||
| 39da34e1c7 | |||
| 55dc927c8b | |||
| 6e3ff59dfb | |||
| 08eab00627 | |||
| c4fae9b272 | |||
| 51186bea24 | |||
| 5c5bacaab4 | |||
| 5a4e6df99c | |||
| 22f8a4c5dd | |||
| aaf7ae0331 | |||
| 8459a058c6 | |||
| dc5089a9d6 | |||
| 45a246d8b6 | |||
| 65bcd78872 | |||
| a0fd7001e9 | |||
| 09ceb15d08 | |||
| 25335446d0 | |||
| 63d8ef7560 | |||
| 27428bf545 | |||
| b9c418e458 | |||
| c843e634ba | |||
| 8eb0d254da | |||
| 70921e88f6 | |||
| d9b71995e1 | |||
| f517e750b9 | |||
| 07d91ce9ac | |||
| ac8ee92bb8 | |||
| aee06c4574 | |||
| d0f69907db | |||
| 71db33f4cd | |||
| cec6322a84 | |||
| eb85e8cd78 | |||
| cf7c0dffb0 | |||
| 78d91a353a | |||
| 22d778ed28 | |||
| a3a2b6499e | |||
| 65ed69cf06 | |||
| c09cd95eb6 | |||
| 1d3490eb82 | |||
| b78c334589 | |||
| b41de9b623 | |||
| c51d29da52 | |||
| 54967e0150 | |||
| 73e47402cb | |||
| 79844154fb | |||
| 067a1ba8e6 | |||
| 120cb964a5 | |||
| 147a1daf6d | |||
| 9badb35c05 | |||
| 765decf3b1 | |||
| eb35791003 | |||
| 69775c369a | |||
| 3f25d3637a | |||
| 02136d3060 | |||
| 99d4b13bb0 | |||
| e7b007386a | |||
| 5dc3e0a3fc | |||
| d146df43e6 | |||
| 451826a329 | |||
| 080150baa3 | |||
| c6bc5ae6aa | |||
| f84d3b435b | |||
| 99855bce11 | |||
| d0b2f10a8c | |||
| 70507501bd | |||
| bbfd570b8a | |||
| 4a593a0814 | |||
| 3cc0df0273 | |||
| 712cd29fea | |||
| 3d21448f89 | |||
| 7b4912b1e7 | |||
| 8c6362d947 | |||
| 01dd28fc61 | |||
| b807b84466 | |||
| ab551b2c96 | |||
| 1520fa77d5 | |||
| 81354cea3c | |||
| b88e714050 | |||
| 58f9ff4b79 | |||
| 78bc38fe1b | |||
| edb0a934a1 |
@@ -144,3 +144,4 @@ build/msbuild.log
|
||||
.vs/
|
||||
src/packages/
|
||||
build/tools/
|
||||
src/PrecompiledWeb/*
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
[](https://ci.appveyor.com/project/Umbraco/umbraco-cms-hs8dx/branch/dev-v7)
|
||||
|
||||
Umbraco CMS
|
||||
===========
|
||||
The friendliest, most flexible and fastest growing ASP.NET CMS used by more than 390,000 websites worldwide: [https://umbraco.com](https://umbraco.com)
|
||||
|
||||
@@ -57,6 +57,20 @@ $IndexPath = "../src/umbraco.web.ui.client/docs/api/index.html"
|
||||
|
||||
# Build the solution in debug mode
|
||||
$SolutionPath = Join-Path -Path $SolutionRoot -ChildPath "umbraco.sln"
|
||||
|
||||
# Go get nuget.exe if we don't hae it
|
||||
$NuGet = "$ToolsRoot\nuget.exe"
|
||||
$FileExists = Test-Path $NuGet
|
||||
If ($FileExists -eq $False) {
|
||||
Write-Host "Retrieving nuget.exe..."
|
||||
$SourceNugetExe = "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe"
|
||||
Invoke-WebRequest $SourceNugetExe -OutFile $NuGet
|
||||
}
|
||||
|
||||
#restore nuget packages
|
||||
Write-Host "Restoring nuget packages..."
|
||||
& $NuGet restore $SolutionPath
|
||||
|
||||
& $MSBuild "$SolutionPath" /p:Configuration=Debug /maxcpucount /t:Clean
|
||||
if (-not $?)
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata>
|
||||
<metadata minClientVersion="3.4.4">
|
||||
<id>UmbracoCms.Core</id>
|
||||
<version>7.0.0</version>
|
||||
<title>Umbraco Cms Core Binaries</title>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata minClientVersion="2.8">
|
||||
<metadata minClientVersion="3.4.4">
|
||||
<id>UmbracoCms</id>
|
||||
<version>7.0.0</version>
|
||||
<title>Umbraco Cms</title>
|
||||
|
||||
@@ -332,6 +332,7 @@
|
||||
<dependentAssembly xdt:Locator="Condition(./_defaultNamespace:assemblyIdentity/@name='System.Net.Http.Formatting')" xdt:Transform="Remove" />
|
||||
<dependentAssembly xdt:Locator="Condition(./_defaultNamespace:assemblyIdentity/@name='Microsoft.CodeAnalysis.CSharp')" xdt:Transform="Remove" />
|
||||
<dependentAssembly xdt:Locator="Condition(./_defaultNamespace:assemblyIdentity/@name='log4net')" xdt:Transform="Remove" />
|
||||
<dependentAssembly xdt:Locator="Condition(./_defaultNamespace:assemblyIdentity/@name='System.Data.SqlServerCe')" xdt:Transform="Remove" />
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
|
||||
@@ -389,6 +390,10 @@
|
||||
<assemblyIdentity name="log4net" publicKeyToken="669e0ddf0bb1aa2a" culture="neutral"/>
|
||||
<bindingRedirect oldVersion="0.0.0.0-2.0.8.0" newVersion="2.0.8.0"/>
|
||||
</dependentAssembly>
|
||||
<dependentAssembly xdt:Transform="Insert">
|
||||
<assemblyIdentity name="System.Data.SqlServerCe" publicKeyToken="89845DCD8080CC91" culture="neutral"/>
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.0.1" newVersion="4.0.0.1"/>
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
# Usage: on line 2 put the release version, on line 3 put the version comment (example: beta)
|
||||
7.6.1
|
||||
7.6.3
|
||||
+2
-2
@@ -11,5 +11,5 @@ using System.Resources;
|
||||
|
||||
[assembly: AssemblyVersion("1.0.*")]
|
||||
|
||||
[assembly: AssemblyFileVersion("7.6.1")]
|
||||
[assembly: AssemblyInformationalVersion("7.6.1")]
|
||||
[assembly: AssemblyFileVersion("7.6.3")]
|
||||
[assembly: AssemblyInformationalVersion("7.6.3")]
|
||||
@@ -139,6 +139,12 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
|
||||
internal CommaDelimitedConfigurationElement DisallowedUploadFiles
|
||||
{
|
||||
get { return GetOptionalDelimitedElement("disallowedUploadFiles", new[] {"ashx", "aspx", "ascx", "config", "cshtml", "vbhtml", "asmx", "air", "axd"}); }
|
||||
}
|
||||
|
||||
[ConfigurationProperty("allowedUploadFiles")]
|
||||
internal CommaDelimitedConfigurationElement AllowedUploadFiles
|
||||
{
|
||||
get { return GetOptionalDelimitedElement("allowedUploadFiles", new string[0]); }
|
||||
}
|
||||
|
||||
[ConfigurationProperty("cloneXmlContent")]
|
||||
@@ -307,6 +313,11 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
|
||||
IEnumerable<string> IContentSection.DisallowedUploadFiles
|
||||
{
|
||||
get { return DisallowedUploadFiles; }
|
||||
}
|
||||
|
||||
IEnumerable<string> IContentSection.AllowedUploadFiles
|
||||
{
|
||||
get { return AllowedUploadFiles; }
|
||||
}
|
||||
|
||||
bool IContentSection.CloneXmlContent
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
using System.Linq;
|
||||
|
||||
namespace Umbraco.Core.Configuration.UmbracoSettings
|
||||
{
|
||||
public static class ContentSectionExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Determines if file extension is allowed for upload based on (optional) white list and black list
|
||||
/// held in settings.
|
||||
/// Allow upload if extension is whitelisted OR if there is no whitelist and extension is NOT blacklisted.
|
||||
/// </summary>
|
||||
public static bool IsFileAllowedForUpload(this IContentSection contentSection, string extension)
|
||||
{
|
||||
return contentSection.AllowedUploadFiles.Any(x => x.InvariantEquals(extension)) ||
|
||||
(contentSection.AllowedUploadFiles.Any() == false &&
|
||||
contentSection.DisallowedUploadFiles.Any(x => x.InvariantEquals(extension)) == false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -52,7 +52,9 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
|
||||
|
||||
MacroErrorBehaviour MacroErrorBehaviour { get; }
|
||||
|
||||
IEnumerable<string> DisallowedUploadFiles { get; }
|
||||
IEnumerable<string> DisallowedUploadFiles { get; }
|
||||
|
||||
IEnumerable<string> AllowedUploadFiles { get; }
|
||||
|
||||
bool CloneXmlContent { get; }
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace Umbraco.Core.Configuration
|
||||
{
|
||||
public class UmbracoVersion
|
||||
{
|
||||
private static readonly Version Version = new Version("7.6.1");
|
||||
private static readonly Version Version = new Version("7.6.3");
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current version of Umbraco.
|
||||
|
||||
@@ -159,7 +159,7 @@ namespace Umbraco.Core.IO
|
||||
|
||||
// ReSharper disable once AssignNullToNotNullAttribute
|
||||
var filepath = UmbracoConfig.For.UmbracoSettings().Content.UploadAllowDirectories
|
||||
? Path.Combine(folder, filename)
|
||||
? Path.Combine(folder, filename).Replace('\\', '/')
|
||||
: folder + "-" + filename;
|
||||
|
||||
return filepath;
|
||||
|
||||
@@ -2,6 +2,6 @@
|
||||
{
|
||||
public interface IPartialView : IFile
|
||||
{
|
||||
|
||||
PartialViewType ViewType { get; }
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,8 @@
|
||||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
using Umbraco.Core.Services;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Represents a Partial View file
|
||||
/// </summary>
|
||||
@@ -12,14 +10,21 @@ namespace Umbraco.Core.Models
|
||||
[DataContract(IsReference = true)]
|
||||
public class PartialView : File, IPartialView
|
||||
{
|
||||
[Obsolete("Use the ctor that explicitely sets the view type.")]
|
||||
public PartialView(string path)
|
||||
: this(path, null)
|
||||
: this(PartialViewType.PartialView, path, null)
|
||||
{ }
|
||||
|
||||
internal PartialView(string path, Func<File, string> getFileContent)
|
||||
public PartialView(PartialViewType viewType, string path)
|
||||
: this(viewType, path, null)
|
||||
{ }
|
||||
|
||||
internal PartialView(PartialViewType viewType, string path, Func<File, string> getFileContent)
|
||||
: base(path, getFileContent)
|
||||
{ }
|
||||
{
|
||||
ViewType = viewType;
|
||||
}
|
||||
|
||||
internal PartialViewType ViewType { get; set; }
|
||||
public PartialViewType ViewType { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
internal enum PartialViewType : byte
|
||||
public enum PartialViewType : byte
|
||||
{
|
||||
Unknown = 0, // default
|
||||
PartialView = 1,
|
||||
|
||||
+34
-4
@@ -2,6 +2,7 @@
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
using Umbraco.Core.Persistence.DatabaseAnnotations;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenThreeZero
|
||||
@@ -16,7 +17,7 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenThreeZe
|
||||
|
||||
public override void Up()
|
||||
{
|
||||
var exists = Context.Database.FirstOrDefault<RelationTypeDto>("WHERE alias=@alias", new {alias = Constants.Conventions.RelationTypes.RelateParentDocumentOnDeleteAlias});
|
||||
var exists = Context.Database.FirstOrDefault<RelationTypeDtoCapture>("WHERE alias=@alias", new {alias = Constants.Conventions.RelationTypes.RelateParentDocumentOnDeleteAlias});
|
||||
if (exists == null)
|
||||
{
|
||||
Insert.IntoTable("umbracoRelationType").Row(new
|
||||
@@ -28,13 +29,42 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenThreeZe
|
||||
alias = Constants.Conventions.RelationTypes.RelateParentDocumentOnDeleteAlias
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public override void Down()
|
||||
{ }
|
||||
|
||||
// need to capture the DTO as it is modified in later migrations
|
||||
|
||||
[TableName("umbracoRelationType")]
|
||||
[PrimaryKey("id")]
|
||||
[ExplicitColumns]
|
||||
internal class RelationTypeDtoCapture
|
||||
{
|
||||
public const int NodeIdSeed = 3;
|
||||
|
||||
[Column("id")]
|
||||
[PrimaryKeyColumn(IdentitySeed = NodeIdSeed)]
|
||||
public int Id { get; set; }
|
||||
|
||||
[Column("dual")]
|
||||
public bool Dual { get; set; }
|
||||
|
||||
[Column("parentObjectType")]
|
||||
public Guid ParentObjectType { get; set; }
|
||||
|
||||
[Column("childObjectType")]
|
||||
public Guid ChildObjectType { get; set; }
|
||||
|
||||
[Column("name")]
|
||||
[Index(IndexTypes.UniqueNonClustered, Name = "IX_umbracoRelationType_name")]
|
||||
public string Name { get; set; }
|
||||
|
||||
[Column("alias")]
|
||||
[NullSetting(NullSetting = NullSettings.Null)]
|
||||
[Length(100)]
|
||||
[Index(IndexTypes.UniqueNonClustered, Name = "IX_umbracoRelationType_alias")]
|
||||
public string Alias { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -30,7 +30,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
var updated = FileSystem.GetLastModified(path).UtcDateTime;
|
||||
//var content = GetFileContent(path);
|
||||
|
||||
var view = new PartialView(path, file => GetFileContent(file.OriginalPath))
|
||||
var view = new PartialView(ViewType, path, file => GetFileContent(file.OriginalPath))
|
||||
{
|
||||
//id can be the hash
|
||||
Id = path.GetHashCode(),
|
||||
@@ -38,8 +38,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
//Content = content,
|
||||
CreateDate = created,
|
||||
UpdateDate = updated,
|
||||
VirtualPath = FileSystem.GetUrl(id),
|
||||
ViewType = ViewType
|
||||
VirtualPath = FileSystem.GetUrl(id)
|
||||
};
|
||||
|
||||
//on initial construction we don't want to have dirty properties tracked
|
||||
|
||||
@@ -83,7 +83,7 @@ namespace Umbraco.Core.Services
|
||||
/// <returns></returns>
|
||||
public bool HasContainerInPath(string contentPath)
|
||||
{
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
|
||||
{
|
||||
// can use same repo for both content and media
|
||||
var repository = RepositoryFactory.CreateContentTypeRepository(uow);
|
||||
|
||||
@@ -95,6 +95,16 @@ namespace Umbraco.Core.Services
|
||||
return result.HasValue ? Attempt.Succeed(result.Value) : Attempt<int>.Fail();
|
||||
}
|
||||
|
||||
public Attempt<int> GetIdForUdi(Udi udi)
|
||||
{
|
||||
var guidUdi = udi as GuidUdi;
|
||||
if (guidUdi == null)
|
||||
return Attempt<int>.Fail();
|
||||
|
||||
var umbracoType = Constants.UdiEntityType.ToUmbracoObjectType(guidUdi.EntityType);
|
||||
return GetIdForKey(guidUdi.Guid, umbracoType);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the GUID for a given integer id
|
||||
/// </summary>
|
||||
@@ -124,9 +134,9 @@ namespace Umbraco.Core.Services
|
||||
|
||||
private static Guid GetNodeObjectTypeGuid(UmbracoObjectTypes umbracoObjectType)
|
||||
{
|
||||
var guid = umbracoObjectType.GetGuid();
|
||||
var guid = umbracoObjectType.GetGuid();
|
||||
if (guid == Guid.Empty)
|
||||
throw new NotSupportedException("Unsupported object type (" + umbracoObjectType + ").");
|
||||
throw new NotSupportedException("Unsupported object type (" + umbracoObjectType + ").");
|
||||
|
||||
return guid;
|
||||
}
|
||||
|
||||
@@ -14,8 +14,7 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
public ExternalLoginService(IDatabaseUnitOfWorkProvider provider, RepositoryFactory repositoryFactory, ILogger logger, IEventMessagesFactory eventMessagesFactory)
|
||||
: base(provider, repositoryFactory, logger, eventMessagesFactory)
|
||||
{
|
||||
}
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Returns all user logins assigned
|
||||
@@ -23,30 +22,32 @@ namespace Umbraco.Core.Services
|
||||
/// <param name="userId"></param>
|
||||
/// <returns></returns>
|
||||
public IEnumerable<IIdentityUserLogin> GetAll(int userId)
|
||||
{
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
{
|
||||
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
|
||||
{
|
||||
// ToList is important here, must evaluate within uow!
|
||||
var repo = RepositoryFactory.CreateExternalLoginRepository(uow);
|
||||
var ret = repo.GetByQuery(new Query<IIdentityUserLogin>().Where(x => x.UserId == userId));
|
||||
uow.Commit();
|
||||
return ret;
|
||||
return repo.GetByQuery(new Query<IIdentityUserLogin>()
|
||||
.Where(x => x.UserId == userId))
|
||||
.ToList();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns all logins matching the login info - generally there should only be one but in some cases
|
||||
/// Returns all logins matching the login info - generally there should only be one but in some cases
|
||||
/// there might be more than one depending on if an adminstrator has been editing/removing members
|
||||
/// </summary>
|
||||
/// <param name="login"></param>
|
||||
/// <returns></returns>
|
||||
public IEnumerable<IIdentityUserLogin> Find(UserLoginInfo login)
|
||||
{
|
||||
using (var uow = UowProvider.GetUnitOfWork())
|
||||
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
|
||||
{
|
||||
// ToList is important here, must evaluate within uow!
|
||||
var repo = RepositoryFactory.CreateExternalLoginRepository(uow);
|
||||
var ret = repo.GetByQuery(new Query<IIdentityUserLogin>().Where(x => x.ProviderKey == login.ProviderKey && x.LoginProvider == login.LoginProvider));
|
||||
uow.Commit();
|
||||
return ret;
|
||||
return repo.GetByQuery(new Query<IIdentityUserLogin>()
|
||||
.Where(x => x.ProviderKey == login.ProviderKey && x.LoginProvider == login.LoginProvider))
|
||||
.ToList();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,7 +79,5 @@ namespace Umbraco.Core.Services
|
||||
uow.Commit();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -28,7 +28,14 @@ namespace Umbraco.Core.Services
|
||||
/// <param name="key"></param>
|
||||
/// <param name="umbracoObjectType"></param>
|
||||
/// <returns></returns>
|
||||
Attempt<int> GetIdForKey(Guid key, UmbracoObjectTypes umbracoObjectType);
|
||||
Attempt<int> GetIdForKey(Guid key, UmbracoObjectTypes umbracoObjectType);
|
||||
|
||||
/// <summary>
|
||||
/// Returns the integer id for a given Udi
|
||||
/// </summary>
|
||||
/// <param name="udi"></param>
|
||||
/// <returns></returns>
|
||||
Attempt<int> GetIdForUdi(Udi udi);
|
||||
|
||||
/// <summary>
|
||||
/// Returns the GUID for a given integer id
|
||||
|
||||
@@ -692,11 +692,11 @@ namespace Umbraco.Core.Services
|
||||
}
|
||||
|
||||
Func<string, Sql> createSql = url => new Sql().Select("*")
|
||||
.From<PropertyDataDto>()
|
||||
.InnerJoin<PropertyTypeDto>()
|
||||
.On<PropertyDataDto, PropertyTypeDto>(left => left.PropertyTypeId, right => right.Id)
|
||||
.Where<PropertyTypeDto>(x => x.Alias == "umbracoFile")
|
||||
.Where<PropertyDataDto>(x => x.VarChar == url);
|
||||
.From<PropertyDataDto>()
|
||||
.InnerJoin<PropertyTypeDto>()
|
||||
.On<PropertyDataDto, PropertyTypeDto>(left => left.PropertyTypeId, right => right.Id)
|
||||
.Where<PropertyTypeDto>(x => x.Alias == "umbracoFile")
|
||||
.Where<PropertyDataDto>(x => x.VarChar == url);
|
||||
|
||||
var sql = createSql(umbracoFileValue);
|
||||
|
||||
@@ -899,8 +899,14 @@ namespace Umbraco.Core.Services
|
||||
throw new ArgumentException("Cannot save media with empty name.");
|
||||
}
|
||||
|
||||
var repository = RepositoryFactory.CreateMediaRepository(uow);
|
||||
media.CreatorId = userId;
|
||||
var repository = RepositoryFactory.CreateMediaRepository(uow);
|
||||
|
||||
//set the creator id if it's new
|
||||
if (media.HasIdentity == false)
|
||||
{
|
||||
media.CreatorId = userId;
|
||||
}
|
||||
|
||||
repository.AddOrUpdate(media);
|
||||
repository.AddOrUpdateContentXml(media, m => _entitySerializer.Serialize(this, _dataTypeService, _userService, m));
|
||||
// generate preview for blame history?
|
||||
@@ -1048,7 +1054,7 @@ namespace Umbraco.Core.Services
|
||||
/// <param name="userId">Optional id of the user deleting the media</param>
|
||||
public void DeleteMediaOfType(int mediaTypeId, int userId = 0)
|
||||
{
|
||||
DeleteMediaOfTypes(new[] {mediaTypeId}, userId);
|
||||
DeleteMediaOfTypes(new[] { mediaTypeId }, userId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
@@ -20,7 +21,7 @@ namespace Umbraco.Core
|
||||
/// <param name="entityType">The entity type part of the udi.</param>
|
||||
/// <param name="id">The string id part of the udi.</param>
|
||||
public StringUdi(string entityType, string id)
|
||||
: base(entityType, "umb://" + entityType + "/" + Uri.EscapeUriString(id))
|
||||
: base(entityType, "umb://" + entityType + "/" + EscapeUriString(id))
|
||||
{
|
||||
Id = id;
|
||||
}
|
||||
@@ -35,6 +36,19 @@ namespace Umbraco.Core
|
||||
Id = Uri.UnescapeDataString(uriValue.AbsolutePath.TrimStart('/'));
|
||||
}
|
||||
|
||||
private static string EscapeUriString(string s)
|
||||
{
|
||||
// Uri.EscapeUriString preserves / but also [ and ] which is bad
|
||||
// Uri.EscapeDataString does not preserve / which is bad
|
||||
|
||||
// reserved = : / ? # [ ] @ ! $ & ' ( ) * + , ; =
|
||||
// unreserved = alpha digit - . _ ~
|
||||
|
||||
// we want to preserve the / and the unreserved
|
||||
// so...
|
||||
return string.Join("/", s.Split('/').Select(Uri.EscapeDataString));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the string representation of an entity identifier into the equivalent StringUdi instance.
|
||||
/// </summary>
|
||||
|
||||
@@ -4,6 +4,7 @@ using System.Web;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Configuration.UmbracoSettings;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Core.Logging;
|
||||
|
||||
namespace Umbraco.Core.Sync
|
||||
{
|
||||
@@ -40,8 +41,9 @@ namespace Umbraco.Core.Sync
|
||||
.ToList();
|
||||
|
||||
if (serversA.Length == 0)
|
||||
{
|
||||
{
|
||||
_serverRole = ServerRole.Unknown; // config error, actually
|
||||
LogHelper.Debug<ConfigServerRegistrar>(string.Format("Server Role Unknown: DistributedCalls are enabled but no servers are listed"));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -50,7 +52,10 @@ namespace Umbraco.Core.Sync
|
||||
var serverName = master.ServerName;
|
||||
|
||||
if (appId.IsNullOrWhiteSpace() && serverName.IsNullOrWhiteSpace())
|
||||
{
|
||||
_serverRole = ServerRole.Unknown; // config error, actually
|
||||
LogHelper.Debug<ConfigServerRegistrar>(string.Format("Server Role Unknown: Server Name or AppId missing from Server configuration in DistributedCalls settings"));
|
||||
}
|
||||
else
|
||||
_serverRole = IsCurrentServer(appId, serverName)
|
||||
? ServerRole.Master
|
||||
|
||||
@@ -198,7 +198,13 @@ namespace Umbraco.Core
|
||||
public static StringUdi GetUdi(this IPartialView entity)
|
||||
{
|
||||
if (entity == null) throw new ArgumentNullException("entity");
|
||||
return new StringUdi(Constants.UdiEntityType.PartialView, entity.Path.TrimStart('/')).EnsureClosed();
|
||||
|
||||
// we should throw on Unknown but for the time being, assume it means PartialView
|
||||
var entityType = entity.ViewType == PartialViewType.PartialViewMacro
|
||||
? Constants.UdiEntityType.PartialViewMacro
|
||||
: Constants.UdiEntityType.PartialView;
|
||||
|
||||
return new StringUdi(entityType, entity.Path.TrimStart('/')).EnsureClosed();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -237,6 +237,7 @@
|
||||
<Compile Include="Configuration\UmbracoSettings\ContentError404Collection.cs" />
|
||||
<Compile Include="Configuration\UmbracoSettings\ContentErrorPageElement.cs" />
|
||||
<Compile Include="Configuration\UmbracoSettings\ContentErrorsElement.cs" />
|
||||
<Compile Include="Configuration\UmbracoSettings\ContentSectionExtensions.cs" />
|
||||
<Compile Include="Configuration\UmbracoSettings\ImagingAutoFillPropertiesCollection.cs" />
|
||||
<Compile Include="Configuration\UmbracoSettings\ImagingAutoFillUploadFieldElement.cs" />
|
||||
<Compile Include="Configuration\UmbracoSettings\ContentImagingElement.cs" />
|
||||
|
||||
@@ -79,6 +79,7 @@
|
||||
</system.data>
|
||||
|
||||
<system.web>
|
||||
<httpRuntime targetFramework="4.5" />
|
||||
<compilation defaultLanguage="c#" debug="true" batch="false" targetFramework="4.0"></compilation>
|
||||
<machineKey validationKey="5E7B955FCE36F5F2A867C2A0D85DC61E7FEA9E15F1561E8386F78BFE9EE23FF18B21E6A44AA17300B3B9D5DBEB37AA61A2C73884A5BBEDA6D3B14BA408A7A8CD" decryptionKey="116B853D031219E404E088FCA0986D6CF2DFA77E1957B59FCC9404B8CA3909A1" validation="SHA1" decryption="AES" />
|
||||
<!--<trust level="Medium" originUrl=".*"/>-->
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core;
|
||||
@@ -177,6 +178,39 @@ namespace Umbraco.Tests.Configurations.UmbracoSettings
|
||||
public void DisallowedUploadFiles()
|
||||
{
|
||||
Assert.IsTrue(SettingsSection.Content.DisallowedUploadFiles.All(x => "ashx,aspx,ascx,config,cshtml,vbhtml,asmx,air,axd".Split(',').Contains(x)));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AllowedUploadFiles()
|
||||
{
|
||||
Assert.IsTrue(SettingsSection.Content.AllowedUploadFiles.All(x => "jpg,gif,png".Split(',').Contains(x)));
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCase("png", true)]
|
||||
[TestCase("jpg", true)]
|
||||
[TestCase("gif", true)]
|
||||
// TODO: Why does it flip to TestingDefaults=true for these two tests on AppVeyor. WHY?
|
||||
//[TestCase("bmp", false)]
|
||||
//[TestCase("php", false)]
|
||||
[TestCase("ashx", false)]
|
||||
[TestCase("config", false)]
|
||||
public void IsFileAllowedForUpload_WithWhitelist(string extension, bool expected)
|
||||
{
|
||||
// Make really sure that defaults are NOT used
|
||||
TestingDefaults = false;
|
||||
|
||||
Debug.WriteLine("Extension being tested", extension);
|
||||
Debug.WriteLine("AllowedUploadFiles: {0}", SettingsSection.Content.AllowedUploadFiles);
|
||||
Debug.WriteLine("DisallowedUploadFiles: {0}", SettingsSection.Content.DisallowedUploadFiles);
|
||||
|
||||
var allowedContainsExtension = SettingsSection.Content.AllowedUploadFiles.Any(x => x.InvariantEquals(extension));
|
||||
var disallowedContainsExtension = SettingsSection.Content.DisallowedUploadFiles.Any(x => x.InvariantEquals(extension));
|
||||
|
||||
Debug.WriteLine("AllowedContainsExtension: {0}", allowedContainsExtension);
|
||||
Debug.WriteLine("DisallowedContainsExtension: {0}", disallowedContainsExtension);
|
||||
|
||||
Assert.AreEqual(SettingsSection.Content.IsFileAllowedForUpload(extension), expected);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using System.Configuration;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Configuration.UmbracoSettings;
|
||||
using Umbraco.Tests.TestHelpers;
|
||||
|
||||
@@ -9,20 +9,17 @@ namespace Umbraco.Tests.Configurations.UmbracoSettings
|
||||
{
|
||||
public abstract class UmbracoSettingsTests
|
||||
{
|
||||
|
||||
protected virtual bool TestingDefaults
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
protected virtual bool TestingDefaults { get; set; }
|
||||
|
||||
[SetUp]
|
||||
public void Init()
|
||||
{
|
||||
var config = new FileInfo(TestHelper.MapPathForTest("~/Configurations/UmbracoSettings/web.config"));
|
||||
|
||||
var fileMap = new ExeConfigurationFileMap() { ExeConfigFilename = config.FullName };
|
||||
var configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
|
||||
|
||||
var fileMap = new ExeConfigurationFileMap() { ExeConfigFilename = config.FullName };
|
||||
var configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
|
||||
|
||||
Debug.WriteLine("Testing defaults? {0}", TestingDefaults);
|
||||
if (TestingDefaults)
|
||||
{
|
||||
SettingsSection = configuration.GetSection("umbracoConfiguration/defaultSettings") as UmbracoSettingsSection;
|
||||
@@ -32,8 +29,6 @@ namespace Umbraco.Tests.Configurations.UmbracoSettings
|
||||
SettingsSection = configuration.GetSection("umbracoConfiguration/settings") as UmbracoSettingsSection;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Assert.IsNotNull(SettingsSection);
|
||||
}
|
||||
|
||||
|
||||
@@ -100,6 +100,9 @@
|
||||
<!-- These file types will not be allowed to be uploaded via the upload control for media and content -->
|
||||
<disallowedUploadFiles>ashx,aspx,ascx,config,cshtml,vbhtml,asmx,air,axd</disallowedUploadFiles>
|
||||
|
||||
<!-- If completed, only the file extensions listed below will be allowed to be uploaded. If empty, disallowedUploadFiles will apply to prevent upload of specific file extensions. -->
|
||||
<allowedUploadFiles>jpg,png,gif</allowedUploadFiles>
|
||||
|
||||
<!-- Defines the default document type property used when adding properties in the back-office (if missing or empty, defaults to Textstring -->
|
||||
<defaultDocumentTypeProperty>Textstring</defaultDocumentTypeProperty>
|
||||
</content>
|
||||
|
||||
@@ -37,14 +37,14 @@ namespace Umbraco.Tests.Persistence.Repositories
|
||||
var unitOfWork = provider.GetUnitOfWork();
|
||||
var repository = new PartialViewRepository(unitOfWork, _fileSystem);
|
||||
|
||||
var partialView = new PartialView("test-path-1.cshtml") { Content = "// partialView" };
|
||||
var partialView = new PartialView(PartialViewType.PartialView, "test-path-1.cshtml") { Content = "// partialView" };
|
||||
repository.AddOrUpdate(partialView);
|
||||
unitOfWork.Commit();
|
||||
Assert.IsTrue(_fileSystem.FileExists("test-path-1.cshtml"));
|
||||
Assert.AreEqual("test-path-1.cshtml", partialView.Path);
|
||||
Assert.AreEqual("/Views/Partials/test-path-1.cshtml", partialView.VirtualPath);
|
||||
|
||||
partialView = new PartialView("path-2/test-path-2.cshtml") { Content = "// partialView" };
|
||||
partialView = new PartialView(PartialViewType.PartialView, "path-2/test-path-2.cshtml") { Content = "// partialView" };
|
||||
repository.AddOrUpdate(partialView);
|
||||
unitOfWork.Commit();
|
||||
Assert.IsTrue(_fileSystem.FileExists("path-2/test-path-2.cshtml"));
|
||||
@@ -56,7 +56,7 @@ namespace Umbraco.Tests.Persistence.Repositories
|
||||
Assert.AreEqual("path-2\\test-path-2.cshtml", partialView.Path);
|
||||
Assert.AreEqual("/Views/Partials/path-2/test-path-2.cshtml", partialView.VirtualPath);
|
||||
|
||||
partialView = new PartialView("path-2\\test-path-3.cshtml") { Content = "// partialView" };
|
||||
partialView = new PartialView(PartialViewType.PartialView, "path-2\\test-path-3.cshtml") { Content = "// partialView" };
|
||||
repository.AddOrUpdate(partialView);
|
||||
unitOfWork.Commit();
|
||||
Assert.IsTrue(_fileSystem.FileExists("path-2/test-path-3.cshtml"));
|
||||
@@ -73,7 +73,7 @@ namespace Umbraco.Tests.Persistence.Repositories
|
||||
Assert.AreEqual("path-2\\test-path-3.cshtml", partialView.Path);
|
||||
Assert.AreEqual("/Views/Partials/path-2/test-path-3.cshtml", partialView.VirtualPath);
|
||||
|
||||
partialView = new PartialView("\\test-path-4.cshtml") { Content = "// partialView" };
|
||||
partialView = new PartialView(PartialViewType.PartialView, "\\test-path-4.cshtml") { Content = "// partialView" };
|
||||
Assert.Throws<FileSecurityException>(() => // fixed in 7.3 - 7.2.8 used to strip the \
|
||||
{
|
||||
repository.AddOrUpdate(partialView);
|
||||
|
||||
@@ -59,6 +59,29 @@ namespace Umbraco.Tests
|
||||
Assert.AreEqual("umb://" + Constants.UdiEntityType.AnyString + "/path%20to/this%20is%20a%20test.xyz", udi3.ToString());
|
||||
}
|
||||
|
||||
[Test, Ignore]
|
||||
public void StringEncodingTest2()
|
||||
{
|
||||
// reserved = : / ? # [ ] @ ! $ & ' ( ) * + , ; =
|
||||
// unreserved = alpha digit - . _ ~
|
||||
|
||||
Assert.AreEqual("%3A%2F%3F%23%5B%5D%40%21%24%26%27%28%29%2B%2C%3B%3D.-_~%25", Uri.EscapeDataString(":/?#[]@!$&'()+,;=.-_~%"));
|
||||
Assert.AreEqual(":/?#[]@!$&'()+,;=.-_~%25", Uri.EscapeUriString(":/?#[]@!$&'()+,;=.-_~%"));
|
||||
|
||||
// we cannot have reserved chars at random places
|
||||
// we want to keep the / in string udis
|
||||
|
||||
var r = string.Join("/", "path/to/View[1].cshtml".Split('/').Select(Uri.EscapeDataString));
|
||||
Assert.AreEqual("path/to/View%5B1%5D.cshtml", r);
|
||||
Assert.IsTrue(Uri.IsWellFormedUriString("umb://partial-view-macro/" + r, UriKind.Absolute));
|
||||
|
||||
// with the proper fix in StringUdi this should work:
|
||||
var udi1 = new StringUdi("partial-view-macro", "path/to/View[1].cshtml");
|
||||
Assert.AreEqual("umb://partial-view-macro/path/to/View%5B1%5D.cshtml", udi1.ToString());
|
||||
var udi2 = Udi.Parse("umb://partial-view-macro/path/to/View%5B1%5D.cshtml");
|
||||
Assert.AreEqual("path/to/View[1].cshtml", ((StringUdi) udi2).Id);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GuidEntityCtorTest()
|
||||
{
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
<package id="Moq" version="4.1.1309.0919" targetFramework="net45" />
|
||||
<package id="Newtonsoft.Json" version="10.0.2" targetFramework="net45" />
|
||||
<package id="NUnit" version="2.6.2" targetFramework="net45" />
|
||||
<package id="NUnitTestAdapter" version="2.1.1" targetFramework="net45" />
|
||||
<package id="Owin" version="1.0" targetFramework="net45" />
|
||||
<package id="Selenium.WebDriver" version="2.32.0" targetFramework="net45" />
|
||||
<package id="semver" version="1.1.2" targetFramework="net45" />
|
||||
|
||||
+31
-14
@@ -134,25 +134,42 @@ Use this directive to generate a thumbnail grid of media items.
|
||||
}
|
||||
|
||||
function setItemData(item) {
|
||||
item.isFolder = !mediaHelper.hasFilePropertyType(item);
|
||||
|
||||
// check if item is a folder
|
||||
if(item.image) {
|
||||
// if is has an image path, it is not a folder
|
||||
item.isFolder = false;
|
||||
} else {
|
||||
item.isFolder = !mediaHelper.hasFilePropertyType(item);
|
||||
}
|
||||
|
||||
if (!item.isFolder) {
|
||||
item.thumbnail = mediaHelper.resolveFile(item, true);
|
||||
item.image = mediaHelper.resolveFile(item, false);
|
||||
|
||||
// handle entity
|
||||
if(item.image) {
|
||||
item.thumbnail = mediaHelper.resolveFileFromEntity(item, true);
|
||||
item.extension = mediaHelper.getFileExtension(item.image);
|
||||
// handle full media object
|
||||
} else {
|
||||
item.thumbnail = mediaHelper.resolveFile(item, true);
|
||||
item.image = mediaHelper.resolveFile(item, false);
|
||||
|
||||
var fileProp = _.find(item.properties, function (v) {
|
||||
return (v.alias === "umbracoFile");
|
||||
});
|
||||
|
||||
var fileProp = _.find(item.properties, function (v) {
|
||||
return (v.alias === "umbracoFile");
|
||||
});
|
||||
if (fileProp && fileProp.value) {
|
||||
item.file = fileProp.value;
|
||||
}
|
||||
|
||||
if (fileProp && fileProp.value) {
|
||||
item.file = fileProp.value;
|
||||
}
|
||||
var extensionProp = _.find(item.properties, function (v) {
|
||||
return (v.alias === "umbracoExtension");
|
||||
});
|
||||
|
||||
var extensionProp = _.find(item.properties, function (v) {
|
||||
return (v.alias === "umbracoExtension");
|
||||
});
|
||||
if (extensionProp && extensionProp.value) {
|
||||
item.extension = extensionProp.value;
|
||||
}
|
||||
|
||||
if (extensionProp && extensionProp.value) {
|
||||
item.extension = extensionProp.value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ function logResource($q, $http, umbRequestHelper) {
|
||||
"logApiBaseUrl",
|
||||
"GetCurrentUserLog",
|
||||
[{ logtype: type, sinceDate: since }])),
|
||||
'Failed to retrieve user data for id ' + id);
|
||||
'Failed to retrieve log data for current user of type ' + type + ' since ' + since);
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -99,7 +99,7 @@ function logResource($q, $http, umbRequestHelper) {
|
||||
"logApiBaseUrl",
|
||||
"GetLog",
|
||||
[{ logtype: type, sinceDate: since }])),
|
||||
'Failed to retrieve user data for id ' + id);
|
||||
'Failed to retrieve log data of type ' + type + ' since ' + since);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -365,6 +365,28 @@ function mediaHelper(umbRequestHelper) {
|
||||
|
||||
return newFileTypesArray.join(",");
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* @ngdoc function
|
||||
* @name umbraco.services.mediaHelper#getFileExtension
|
||||
* @methodOf umbraco.services.mediaHelper
|
||||
* @function
|
||||
*
|
||||
* @description
|
||||
* Returns file extension
|
||||
*
|
||||
* @param {string} filePath File path, ex /media/1234/my-image.jpg
|
||||
*/
|
||||
getFileExtension: function(filePath) {
|
||||
|
||||
if (!filePath) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var lowered = filePath.toLowerCase();
|
||||
var ext = lowered.substr(lowered.lastIndexOf(".") + 1);
|
||||
return ext;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@@ -103,15 +103,15 @@ function umbRequestHelper($http, $q, umbDataFormatter, angularHelper, dialogServ
|
||||
* @description
|
||||
* This returns a promise with an underlying http call, it is a helper method to reduce
|
||||
* the amount of duplicate code needed to query http resources and automatically handle any
|
||||
* 500 Http server errors.
|
||||
* Http errors. See /docs/source/using-promises-resources.md
|
||||
*
|
||||
* @param {object} opts A mixed object which can either be a `string` representing the error message to be
|
||||
* returned OR an `object` containing either:
|
||||
* @param {object} opts A mixed object which can either be a string representing the error message to be
|
||||
* returned OR an object containing either:
|
||||
* { success: successCallback, errorMsg: errorMessage }
|
||||
* OR
|
||||
* { success: successCallback, error: errorCallback }
|
||||
* In both of the above, the successCallback must accept these parameters: `data`, `status`, `headers`, `config`
|
||||
* If using the errorCallback it must accept these parameters: `data`, `status`, `headers`, `config`
|
||||
* In both of the above, the successCallback must accept these parameters: data, status, headers, config
|
||||
* If using the errorCallback it must accept these parameters: data, status, headers, config
|
||||
* The success callback must return the data which will be resolved by the deferred object.
|
||||
* The error callback must return an object containing: {errorMsg: errorMessage, data: originalData, status: status }
|
||||
*/
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
.umb-tree li.current > div i.icon,
|
||||
.umb-tree li.current > div ins {
|
||||
color: @white !important;
|
||||
background: @turquoise-d1;
|
||||
background-color: @turquoise-d1;
|
||||
border-color: @turquoise-d1;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
placeholder="@general_url"
|
||||
class="umb-editor umb-textstring"
|
||||
ng-model="model.target.url"
|
||||
ng-disabled="model.target.id"/>
|
||||
ng-disabled="model.target.id"
|
||||
focus-when="{{true}} "/>
|
||||
</umb-control-group>
|
||||
|
||||
<umb-control-group label="@content_nodeName">
|
||||
|
||||
+22
-6
@@ -16,14 +16,22 @@ angular.module("umbraco")
|
||||
$scope.startNodeId = dialogOptions.startNodeId ? dialogOptions.startNodeId : -1;
|
||||
$scope.cropSize = dialogOptions.cropSize;
|
||||
$scope.lastOpenedNode = localStorageService.get("umbLastOpenedMediaNodeId");
|
||||
|
||||
var umbracoSettings = Umbraco.Sys.ServerVariables.umbracoSettings;
|
||||
var allowedUploadFiles = mediaHelper.formatFileTypes(umbracoSettings.allowedUploadFiles);
|
||||
if ($scope.onlyImages) {
|
||||
$scope.acceptedFileTypes = mediaHelper
|
||||
.formatFileTypes(Umbraco.Sys.ServerVariables.umbracoSettings.imageFileTypes);
|
||||
$scope.acceptedFileTypes = mediaHelper.formatFileTypes(umbracoSettings.imageFileTypes);
|
||||
} else {
|
||||
$scope.acceptedFileTypes = !mediaHelper
|
||||
.formatFileTypes(Umbraco.Sys.ServerVariables.umbracoSettings.disallowedUploadFiles);
|
||||
// Use whitelist of allowed file types if provided
|
||||
if (allowedUploadFiles !== '') {
|
||||
$scope.acceptedFileTypes = allowedUploadFiles;
|
||||
} else {
|
||||
// If no whitelist, we pass in a blacklist by adding ! to the file extensions, allowing everything EXCEPT for disallowedUploadFiles
|
||||
$scope.acceptedFileTypes = !mediaHelper.formatFileTypes(umbracoSettings.disallowedUploadFiles);
|
||||
}
|
||||
}
|
||||
$scope.maxFileSize = Umbraco.Sys.ServerVariables.umbracoSettings.maxFileSize + "KB";
|
||||
|
||||
$scope.maxFileSize = umbracoSettings.maxFileSize + "KB";
|
||||
|
||||
$scope.model.selectedImages = [];
|
||||
|
||||
@@ -131,8 +139,16 @@ angular.module("umbraco")
|
||||
} else {
|
||||
eventsService.emit("dialogs.mediaPicker.select", image);
|
||||
if ($scope.showDetails) {
|
||||
|
||||
$scope.target = image;
|
||||
$scope.target.url = mediaHelper.resolveFile(image);
|
||||
|
||||
// handle both entity and full media object
|
||||
if(image.image) {
|
||||
$scope.target.url = image.image;
|
||||
} else {
|
||||
$scope.target.url = mediaHelper.resolveFile(image);
|
||||
}
|
||||
|
||||
$scope.openDetailsDialog();
|
||||
} else {
|
||||
selectImage(image);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<div class="umb-media-grid">
|
||||
<div class="umb-media-grid__item" ng-click="clickItem(item, $event, $index)" ng-repeat="item in items | filter:filterBy" ng-style="item.flexStyle" ng-class="{'-selected': item.selected, '-file': !item.thumbnail, '-svg': item.extension == 'svg'}">
|
||||
<div class="umb-media-grid__item" title="{{item.name}}" ng-click="clickItem(item, $event, $index)" ng-repeat="item in items | filter:filterBy" ng-style="item.flexStyle" ng-class="{'-selected': item.selected, '-file': !item.thumbnail, '-svg': item.extension == 'svg'}">
|
||||
<div>
|
||||
<i ng-show="item.selected" class="icon-check umb-media-grid__checkmark"></i>
|
||||
|
||||
@@ -12,10 +12,10 @@
|
||||
<div class="umb-media-grid__image-background" ng-if="item.thumbnail || item.extension == 'svg'"></div>
|
||||
|
||||
<!-- Image thumbnail -->
|
||||
<img class="umb-media-grid__item-image" width="{{item.width}}" height="{{item.height}}" ng-if="item.thumbnail" ng-src="{{item.thumbnail}}" alt="{{item.name}}" title="{{item.name}}" draggable="false" />
|
||||
<img class="umb-media-grid__item-image" width="{{item.width}}" height="{{item.height}}" ng-if="item.thumbnail" ng-src="{{item.thumbnail}}" alt="{{item.name}}" draggable="false" />
|
||||
|
||||
<!-- SVG -->
|
||||
<img class="umb-media-grid__item-image" width="{{item.width}}" height="{{item.height}}" ng-if="!item.thumbnail && item.extension == 'svg'" ng-src="{{item.file}}" alt="{{item.name}}" title="{{item.name}}" draggable="false" />
|
||||
<img class="umb-media-grid__item-image" width="{{item.width}}" height="{{item.height}}" ng-if="!item.thumbnail && item.extension == 'svg'" ng-src="{{item.image}}" alt="{{item.name}}" draggable="false" />
|
||||
|
||||
<!-- Transparent image - fallback - used to keep image proportions on wrapper-->
|
||||
<img class="umb-media-grid__item-image-placeholder" ng-if="!item.thumbnail && item.extension != 'svg'" src="assets/img/transparent.png" alt="{{item.name}}" draggable="false" />
|
||||
|
||||
+7
-7
@@ -138,15 +138,15 @@ function fileUploadController($scope, $element, $compile, imageHelper, fileManag
|
||||
//cannot just check for !newVal because it might be an empty string which we
|
||||
//want to look for.
|
||||
if (newVal !== null && newVal !== undefined && newVal !== oldVal) {
|
||||
//now we need to check if we need to re-initialize our structure which is kind of tricky
|
||||
// since we only want to do that if the server has changed the value, not if this controller
|
||||
// has changed the value. There's only 2 scenarios where we change the value internall so
|
||||
// we know what those values can be, if they are not either of them, then we'll re-initialize.
|
||||
|
||||
if (newVal.clearFiles !== true && newVal !== $scope.originalValue && !newVal.selectedFiles) {
|
||||
// here we need to check if the value change needs to trigger an update in the UI.
|
||||
// if the value is only changed in the controller and not in the server values, we do not
|
||||
// want to trigger an update yet.
|
||||
// we can however no longer rely on checking values in the controller vs. values from the server
|
||||
// to determine whether to update or not, since you could potentially be uploading a file with
|
||||
// the exact same name - in that case we need to reinitialize to show the newly uploaded file.
|
||||
if (newVal.clearFiles !== true && !newVal.selectedFiles) {
|
||||
initialize($scope.rebuildInput.index + 1);
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
+86
-80
@@ -6,118 +6,124 @@
|
||||
* @description
|
||||
* The controller for the content type editor
|
||||
*/
|
||||
(function() {
|
||||
"use strict";
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
function ListViewGridLayoutController($scope, $routeParams, mediaHelper, mediaResource, $location, listViewHelper, mediaTypeHelper) {
|
||||
function ListViewGridLayoutController($scope, $routeParams, mediaHelper, mediaResource, $location, listViewHelper, mediaTypeHelper) {
|
||||
|
||||
var vm = this;
|
||||
var vm = this;
|
||||
var umbracoSettings = Umbraco.Sys.ServerVariables.umbracoSettings;
|
||||
|
||||
vm.nodeId = $scope.contentId;
|
||||
//we pass in a blacklist by adding ! to the file extensions, allowing everything EXCEPT for disallowedUploadFiles
|
||||
vm.acceptedFileTypes = !mediaHelper.formatFileTypes(Umbraco.Sys.ServerVariables.umbracoSettings.disallowedUploadFiles);
|
||||
vm.maxFileSize = Umbraco.Sys.ServerVariables.umbracoSettings.maxFileSize + "KB";
|
||||
vm.activeDrag = false;
|
||||
vm.mediaDetailsTooltip = {};
|
||||
vm.itemsWithoutFolders = [];
|
||||
vm.isRecycleBin = $scope.contentId === '-21' || $scope.contentId === '-20';
|
||||
vm.acceptedMediatypes = [];
|
||||
vm.nodeId = $scope.contentId;
|
||||
// Use whitelist of allowed file types if provided
|
||||
vm.acceptedFileTypes = mediaHelper.formatFileTypes(umbracoSettings.allowedUploadFiles);
|
||||
if (vm.acceptedFileTypes === '') {
|
||||
// If not provided, we pass in a blacklist by adding ! to the file extensions, allowing everything EXCEPT for disallowedUploadFiles
|
||||
vm.acceptedFileTypes = !mediaHelper.formatFileTypes(umbracoSettings.disallowedUploadFiles);
|
||||
}
|
||||
|
||||
vm.dragEnter = dragEnter;
|
||||
vm.dragLeave = dragLeave;
|
||||
vm.onFilesQueue = onFilesQueue;
|
||||
vm.onUploadComplete = onUploadComplete;
|
||||
vm.maxFileSize = umbracoSettings.maxFileSize + "KB";
|
||||
vm.activeDrag = false;
|
||||
vm.mediaDetailsTooltip = {};
|
||||
vm.itemsWithoutFolders = [];
|
||||
vm.isRecycleBin = $scope.contentId === '-21' || $scope.contentId === '-20';
|
||||
vm.acceptedMediatypes = [];
|
||||
|
||||
vm.hoverMediaItemDetails = hoverMediaItemDetails;
|
||||
vm.selectContentItem = selectContentItem;
|
||||
vm.selectItem = selectItem;
|
||||
vm.selectFolder = selectFolder;
|
||||
vm.goToItem = goToItem;
|
||||
vm.dragEnter = dragEnter;
|
||||
vm.dragLeave = dragLeave;
|
||||
vm.onFilesQueue = onFilesQueue;
|
||||
vm.onUploadComplete = onUploadComplete;
|
||||
|
||||
function activate() {
|
||||
vm.itemsWithoutFolders = filterOutFolders($scope.items);
|
||||
vm.hoverMediaItemDetails = hoverMediaItemDetails;
|
||||
vm.selectContentItem = selectContentItem;
|
||||
vm.selectItem = selectItem;
|
||||
vm.selectFolder = selectFolder;
|
||||
vm.goToItem = goToItem;
|
||||
|
||||
//no need to make another REST/DB call if this data is not used when we are browsing the bin
|
||||
if ($scope.entityType === 'media' && !vm.isRecycleBin) {
|
||||
mediaTypeHelper.getAllowedImagetypes(vm.nodeId).then(function (types) {
|
||||
vm.acceptedMediatypes = types;
|
||||
});
|
||||
}
|
||||
function activate() {
|
||||
vm.itemsWithoutFolders = filterOutFolders($scope.items);
|
||||
|
||||
}
|
||||
//no need to make another REST/DB call if this data is not used when we are browsing the bin
|
||||
if ($scope.entityType === 'media' && !vm.isRecycleBin) {
|
||||
mediaTypeHelper.getAllowedImagetypes(vm.nodeId).then(function (types) {
|
||||
vm.acceptedMediatypes = types;
|
||||
});
|
||||
}
|
||||
|
||||
function filterOutFolders(items) {
|
||||
}
|
||||
|
||||
var newArray = [];
|
||||
function filterOutFolders(items) {
|
||||
|
||||
if(items && items.length ) {
|
||||
var newArray = [];
|
||||
|
||||
for (var i = 0; items.length > i; i++) {
|
||||
var item = items[i];
|
||||
var isFolder = !mediaHelper.hasFilePropertyType(item);
|
||||
if (items && items.length) {
|
||||
|
||||
if (!isFolder) {
|
||||
newArray.push(item);
|
||||
}
|
||||
}
|
||||
for (var i = 0; items.length > i; i++) {
|
||||
var item = items[i];
|
||||
var isFolder = !mediaHelper.hasFilePropertyType(item);
|
||||
|
||||
}
|
||||
if (!isFolder) {
|
||||
newArray.push(item);
|
||||
}
|
||||
}
|
||||
|
||||
return newArray;
|
||||
}
|
||||
}
|
||||
|
||||
function dragEnter(el, event) {
|
||||
vm.activeDrag = true;
|
||||
}
|
||||
return newArray;
|
||||
}
|
||||
|
||||
function dragLeave(el, event) {
|
||||
vm.activeDrag = false;
|
||||
}
|
||||
function dragEnter(el, event) {
|
||||
vm.activeDrag = true;
|
||||
}
|
||||
|
||||
function onFilesQueue() {
|
||||
vm.activeDrag = false;
|
||||
}
|
||||
function dragLeave(el, event) {
|
||||
vm.activeDrag = false;
|
||||
}
|
||||
|
||||
function onUploadComplete() {
|
||||
$scope.getContent($scope.contentId);
|
||||
}
|
||||
function onFilesQueue() {
|
||||
vm.activeDrag = false;
|
||||
}
|
||||
|
||||
function hoverMediaItemDetails(item, event, hover) {
|
||||
function onUploadComplete() {
|
||||
$scope.getContent($scope.contentId);
|
||||
}
|
||||
|
||||
if (hover && !vm.mediaDetailsTooltip.show) {
|
||||
function hoverMediaItemDetails(item, event, hover) {
|
||||
|
||||
vm.mediaDetailsTooltip.event = event;
|
||||
vm.mediaDetailsTooltip.item = item;
|
||||
vm.mediaDetailsTooltip.show = true;
|
||||
if (hover && !vm.mediaDetailsTooltip.show) {
|
||||
|
||||
} else if (!hover && vm.mediaDetailsTooltip.show) {
|
||||
vm.mediaDetailsTooltip.event = event;
|
||||
vm.mediaDetailsTooltip.item = item;
|
||||
vm.mediaDetailsTooltip.show = true;
|
||||
|
||||
vm.mediaDetailsTooltip.show = false;
|
||||
} else if (!hover && vm.mediaDetailsTooltip.show) {
|
||||
|
||||
}
|
||||
vm.mediaDetailsTooltip.show = false;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
function selectContentItem(item, $event, $index) {
|
||||
listViewHelper.selectHandler(item, $index, $scope.items, $scope.selection, $event);
|
||||
}
|
||||
}
|
||||
|
||||
function selectItem(item, $event, $index) {
|
||||
listViewHelper.selectHandler(item, $index, vm.itemsWithoutFolders, $scope.selection, $event);
|
||||
}
|
||||
function selectContentItem(item, $event, $index) {
|
||||
listViewHelper.selectHandler(item, $index, $scope.items, $scope.selection, $event);
|
||||
}
|
||||
|
||||
function selectFolder(folder, $event, $index) {
|
||||
listViewHelper.selectHandler(folder, $index, $scope.folders, $scope.selection, $event);
|
||||
}
|
||||
function selectItem(item, $event, $index) {
|
||||
listViewHelper.selectHandler(item, $index, vm.itemsWithoutFolders, $scope.selection, $event);
|
||||
}
|
||||
|
||||
function goToItem(item, $event, $index) {
|
||||
$location.path($scope.entityType + '/' + $scope.entityType + '/edit/' + item.id);
|
||||
}
|
||||
function selectFolder(folder, $event, $index) {
|
||||
listViewHelper.selectHandler(folder, $index, $scope.folders, $scope.selection, $event);
|
||||
}
|
||||
|
||||
activate();
|
||||
function goToItem(item, $event, $index) {
|
||||
$location.path($scope.entityType + '/' + $scope.entityType + '/edit/' + item.id);
|
||||
}
|
||||
|
||||
}
|
||||
activate();
|
||||
|
||||
angular.module("umbraco").controller("Umbraco.PropertyEditors.ListView.GridLayoutController", ListViewGridLayoutController);
|
||||
}
|
||||
|
||||
angular.module("umbraco").controller("Umbraco.PropertyEditors.ListView.GridLayoutController", ListViewGridLayoutController);
|
||||
|
||||
})();
|
||||
|
||||
+78
-71
@@ -1,89 +1,96 @@
|
||||
(function () {
|
||||
"use strict";
|
||||
"use strict";
|
||||
|
||||
function ListViewListLayoutController($scope, listViewHelper, $location, mediaHelper, mediaTypeHelper) {
|
||||
function ListViewListLayoutController($scope, listViewHelper, $location, mediaHelper, mediaTypeHelper) {
|
||||
|
||||
var vm = this;
|
||||
var vm = this;
|
||||
var umbracoSettings = Umbraco.Sys.ServerVariables.umbracoSettings;
|
||||
|
||||
vm.nodeId = $scope.contentId;
|
||||
//we pass in a blacklist by adding ! to the file extensions, allowing everything EXCEPT for disallowedUploadFiles
|
||||
vm.acceptedFileTypes = !mediaHelper.formatFileTypes(Umbraco.Sys.ServerVariables.umbracoSettings.disallowedUploadFiles);
|
||||
vm.maxFileSize = Umbraco.Sys.ServerVariables.umbracoSettings.maxFileSize + "KB";
|
||||
vm.activeDrag = false;
|
||||
vm.isRecycleBin = $scope.contentId === '-21' || $scope.contentId === '-20';
|
||||
vm.acceptedMediatypes = [];
|
||||
vm.nodeId = $scope.contentId;
|
||||
|
||||
vm.selectItem = selectItem;
|
||||
vm.clickItem = clickItem;
|
||||
vm.selectAll = selectAll;
|
||||
vm.isSelectedAll = isSelectedAll;
|
||||
vm.isSortDirection = isSortDirection;
|
||||
vm.sort = sort;
|
||||
vm.dragEnter = dragEnter;
|
||||
vm.dragLeave = dragLeave;
|
||||
vm.onFilesQueue = onFilesQueue;
|
||||
vm.onUploadComplete = onUploadComplete;
|
||||
|
||||
function activate() {
|
||||
|
||||
if ($scope.entityType === 'media') {
|
||||
mediaTypeHelper.getAllowedImagetypes(vm.nodeId).then(function (types) {
|
||||
vm.acceptedMediatypes = types;
|
||||
});
|
||||
// Use whitelist of allowed file types if provided
|
||||
vm.acceptedFileTypes = mediaHelper.formatFileTypes(umbracoSettings.allowedUploadFiles);
|
||||
if (vm.acceptedFileTypes === '') {
|
||||
// If not provided, we pass in a blacklist by adding ! to the file extensions, allowing everything EXCEPT for disallowedUploadFiles
|
||||
vm.acceptedFileTypes = !mediaHelper.formatFileTypes(umbracoSettings.disallowedUploadFiles);
|
||||
}
|
||||
|
||||
}
|
||||
vm.maxFileSize = umbracoSettings.maxFileSize + "KB";
|
||||
vm.activeDrag = false;
|
||||
vm.isRecycleBin = $scope.contentId === '-21' || $scope.contentId === '-20';
|
||||
vm.acceptedMediatypes = [];
|
||||
|
||||
function selectAll($event) {
|
||||
listViewHelper.selectAllItems($scope.items, $scope.selection, $event);
|
||||
}
|
||||
vm.selectItem = selectItem;
|
||||
vm.clickItem = clickItem;
|
||||
vm.selectAll = selectAll;
|
||||
vm.isSelectedAll = isSelectedAll;
|
||||
vm.isSortDirection = isSortDirection;
|
||||
vm.sort = sort;
|
||||
vm.dragEnter = dragEnter;
|
||||
vm.dragLeave = dragLeave;
|
||||
vm.onFilesQueue = onFilesQueue;
|
||||
vm.onUploadComplete = onUploadComplete;
|
||||
|
||||
function isSelectedAll() {
|
||||
return listViewHelper.isSelectedAll($scope.items, $scope.selection);
|
||||
}
|
||||
function activate() {
|
||||
|
||||
function selectItem(selectedItem, $index, $event) {
|
||||
listViewHelper.selectHandler(selectedItem, $index, $scope.items, $scope.selection, $event);
|
||||
}
|
||||
if ($scope.entityType === 'media') {
|
||||
mediaTypeHelper.getAllowedImagetypes(vm.nodeId).then(function (types) {
|
||||
vm.acceptedMediatypes = types;
|
||||
});
|
||||
}
|
||||
|
||||
function clickItem(item) {
|
||||
// if item.id is 2147483647 (int.MaxValue) use item.key
|
||||
$location.path($scope.entityType + '/' +$scope.entityType + '/edit/' + (item.id === 2147483647 ? item.key : item.id));
|
||||
}
|
||||
}
|
||||
|
||||
function isSortDirection(col, direction) {
|
||||
return listViewHelper.setSortingDirection(col, direction, $scope.options);
|
||||
}
|
||||
function selectAll($event) {
|
||||
listViewHelper.selectAllItems($scope.items, $scope.selection, $event);
|
||||
}
|
||||
|
||||
function sort(field, allow, isSystem) {
|
||||
if (allow) {
|
||||
$scope.options.orderBySystemField = isSystem;
|
||||
listViewHelper.setSorting(field, allow, $scope.options);
|
||||
function isSelectedAll() {
|
||||
return listViewHelper.isSelectedAll($scope.items, $scope.selection);
|
||||
}
|
||||
|
||||
function selectItem(selectedItem, $index, $event) {
|
||||
listViewHelper.selectHandler(selectedItem, $index, $scope.items, $scope.selection, $event);
|
||||
}
|
||||
|
||||
function clickItem(item) {
|
||||
// if item.id is 2147483647 (int.MaxValue) use item.key
|
||||
$location.path($scope.entityType + '/' + $scope.entityType + '/edit/' + (item.id === 2147483647 ? item.key : item.id));
|
||||
}
|
||||
|
||||
function isSortDirection(col, direction) {
|
||||
return listViewHelper.setSortingDirection(col, direction, $scope.options);
|
||||
}
|
||||
|
||||
function sort(field, allow, isSystem) {
|
||||
if (allow) {
|
||||
$scope.options.orderBySystemField = isSystem;
|
||||
listViewHelper.setSorting(field, allow, $scope.options);
|
||||
$scope.getContent($scope.contentId);
|
||||
}
|
||||
}
|
||||
|
||||
// Dropzone upload functions
|
||||
function dragEnter(el, event) {
|
||||
vm.activeDrag = true;
|
||||
}
|
||||
|
||||
function dragLeave(el, event) {
|
||||
vm.activeDrag = false;
|
||||
}
|
||||
|
||||
function onFilesQueue() {
|
||||
vm.activeDrag = false;
|
||||
}
|
||||
|
||||
function onUploadComplete() {
|
||||
$scope.getContent($scope.contentId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Dropzone upload functions
|
||||
function dragEnter(el, event) {
|
||||
vm.activeDrag = true;
|
||||
}
|
||||
activate();
|
||||
|
||||
function dragLeave(el, event) {
|
||||
vm.activeDrag = false;
|
||||
}
|
||||
}
|
||||
|
||||
function onFilesQueue() {
|
||||
vm.activeDrag = false;
|
||||
}
|
||||
angular.module("umbraco").controller("Umbraco.PropertyEditors.ListView.ListLayoutController", ListViewListLayoutController);
|
||||
|
||||
function onUploadComplete() {
|
||||
$scope.getContent($scope.contentId);
|
||||
}
|
||||
|
||||
activate();
|
||||
|
||||
}
|
||||
|
||||
angular.module("umbraco").controller("Umbraco.PropertyEditors.ListView.ListLayoutController", ListViewListLayoutController);
|
||||
|
||||
}) ();
|
||||
})();
|
||||
|
||||
@@ -2376,9 +2376,9 @@ xcopy "$(ProjectDir)"..\packages\SqlServerCE.4.0.0.1\x86\*.* "$(TargetDir)x86\"
|
||||
<WebProjectProperties>
|
||||
<UseIIS>True</UseIIS>
|
||||
<AutoAssignPort>True</AutoAssignPort>
|
||||
<DevelopmentServerPort>7610</DevelopmentServerPort>
|
||||
<DevelopmentServerPort>7630</DevelopmentServerPort>
|
||||
<DevelopmentServerVPath>/</DevelopmentServerVPath>
|
||||
<IISUrl>http://localhost:7610</IISUrl>
|
||||
<IISUrl>http://localhost:7630</IISUrl>
|
||||
<NTLMAuthentication>False</NTLMAuthentication>
|
||||
<UseCustomServer>False</UseCustomServer>
|
||||
<CustomServerUrl>
|
||||
|
||||
@@ -102,6 +102,9 @@
|
||||
<!-- These file types will not be allowed to be uploaded via the upload control for media and content -->
|
||||
<disallowedUploadFiles>ashx,aspx,ascx,config,cshtml,vbhtml,asmx,air,axd,swf,xml,xhtml,html,htm,svg,php,htaccess</disallowedUploadFiles>
|
||||
|
||||
<!-- If completed, only the file extensions listed below will be allowed to be uploaded. If empty, disallowedUploadFiles will apply to prevent upload of specific file extensions. -->
|
||||
<allowedUploadFiles></allowedUploadFiles>
|
||||
|
||||
<!-- Defines the default document type property used when adding properties in the back-office (if missing or empty, defaults to Textstring -->
|
||||
<defaultDocumentTypeProperty>Textstring</defaultDocumentTypeProperty>
|
||||
|
||||
|
||||
@@ -1370,6 +1370,8 @@ To manage your website, simply open the Umbraco back office and start adding con
|
||||
<key alias="templates">Templates</key>
|
||||
<key alias="xslt">XSLT Files</key>
|
||||
<key alias="analytics">Analytics</key>
|
||||
<key alias="partialViews">Partial Views</key>
|
||||
<key alias="partialViewMacros">Partial View Macro Files</key>
|
||||
</area>
|
||||
<area alias="update">
|
||||
<key alias="updateAvailable">New update ready</key>
|
||||
|
||||
@@ -1252,6 +1252,8 @@
|
||||
<key alias="templates">模板</key>
|
||||
<key alias="xslt">XSLT文件</key>
|
||||
<key alias="analytics">分析</key>
|
||||
<key alias="partialViews">分部视图</key>
|
||||
<key alias="partialViewMacros">分部视图宏文件</key>
|
||||
</area>
|
||||
<area alias="update">
|
||||
<key alias="updateAvailable">有可用更新</key>
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
<cc1:Pane ID="pane_uploadFile" runat="server" Text="Upload translation file">
|
||||
<p>
|
||||
When you have completed the translation. Upload the edited XML file here. The related translation tasks will automaticly be closed when a file is uploaded.
|
||||
When you have completed the translation. Upload the edited XML file here. The related translation tasks will automatically be closed when a file is uploaded.
|
||||
</p>
|
||||
|
||||
<cc1:PropertyPanel runat="server">
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
codeVal = UmbEditor.GetCode();
|
||||
}
|
||||
umbraco.presentation.webservices.codeEditorSave.SaveXslt(
|
||||
fileName, self._opts.originalFileName, codeVal, self._opts.skipTestingCheckBox.is(':checked'),
|
||||
fileName, self._opts.originalFileName, codeVal, true,
|
||||
function (t) { self.submitSucces(t); },
|
||||
function (t) { self.submitFailure(t); });
|
||||
|
||||
|
||||
@@ -433,6 +433,10 @@
|
||||
<assemblyIdentity name="log4net" publicKeyToken="669e0ddf0bb1aa2a" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-2.0.8.0" newVersion="2.0.8.0"/>
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Data.SqlServerCe" publicKeyToken="89845DCD8080CC91" culture="neutral"/>
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.0.1" newVersion="4.0.0.1"/>
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace Umbraco.Web.Cache
|
||||
/// <remarks>
|
||||
/// If Load balancing is enabled (by default disabled, is set in umbracoSettings.config) PageCacheRefresher will be called
|
||||
/// everytime content is added/updated/removed to ensure that the content cache is identical on all load balanced servers
|
||||
/// </remarks>
|
||||
/// </remarks>
|
||||
public class PageCacheRefresher : TypedCacheRefresherBase<PageCacheRefresher, IContent>
|
||||
{
|
||||
|
||||
@@ -51,6 +51,7 @@ namespace Umbraco.Web.Cache
|
||||
public override void RefreshAll()
|
||||
{
|
||||
content.Instance.RefreshContentFromDatabase();
|
||||
XmlPublishedContent.ClearRequest();
|
||||
base.RefreshAll();
|
||||
}
|
||||
|
||||
@@ -62,6 +63,7 @@ namespace Umbraco.Web.Cache
|
||||
{
|
||||
ApplicationContext.Current.ApplicationCache.ClearPartialViewCache();
|
||||
content.Instance.UpdateDocumentCache(id);
|
||||
XmlPublishedContent.ClearRequest();
|
||||
DistributedCache.Instance.ClearAllMacroCacheOnCurrentServer();
|
||||
DistributedCache.Instance.ClearXsltCacheOnCurrentServer();
|
||||
base.Refresh(id);
|
||||
@@ -75,6 +77,7 @@ namespace Umbraco.Web.Cache
|
||||
{
|
||||
ApplicationContext.Current.ApplicationCache.ClearPartialViewCache();
|
||||
content.Instance.ClearDocumentCache(id, false);
|
||||
XmlPublishedContent.ClearRequest();
|
||||
DistributedCache.Instance.ClearAllMacroCacheOnCurrentServer();
|
||||
DistributedCache.Instance.ClearXsltCacheOnCurrentServer();
|
||||
ClearAllIsolatedCacheByEntityType<PublicAccessEntry>();
|
||||
|
||||
@@ -204,7 +204,7 @@ namespace Umbraco.Web.Editors
|
||||
if (identityUser != null)
|
||||
{
|
||||
var user = Services.UserService.GetByEmail(model.Email);
|
||||
if (user != null && user.IsLockedOut == false)
|
||||
if (user != null)
|
||||
{
|
||||
var code = await UserManager.GeneratePasswordResetTokenAsync(identityUser.Id);
|
||||
var callbackUrl = ConstructCallbackUrl(identityUser.Id, code);
|
||||
@@ -303,9 +303,31 @@ namespace Umbraco.Web.Editors
|
||||
var result = await UserManager.ResetPasswordAsync(model.UserId, model.ResetCode, model.Password);
|
||||
if (result.Succeeded)
|
||||
{
|
||||
var lockedOut = await UserManager.IsLockedOutAsync(model.UserId);
|
||||
if (lockedOut)
|
||||
{
|
||||
Logger.Info<AuthenticationController>(
|
||||
"User {0} is currently locked out, unlocking and resetting AccessFailedCount",
|
||||
() => model.UserId);
|
||||
|
||||
//var user = await UserManager.FindByIdAsync(model.UserId);
|
||||
var unlockResult = await UserManager.SetLockoutEndDateAsync(model.UserId, DateTimeOffset.Now);
|
||||
if(unlockResult.Succeeded == false)
|
||||
{
|
||||
Logger.Warn<AuthenticationController>("Could not unlock for user {0} - error {1}",
|
||||
() => model.UserId, () => unlockResult.Errors.First());
|
||||
}
|
||||
|
||||
var resetAccessFailedCountResult = await UserManager.ResetAccessFailedCountAsync(model.UserId);
|
||||
if (resetAccessFailedCountResult.Succeeded == false)
|
||||
{
|
||||
Logger.Warn<AuthenticationController>("Could not reset access failed count {0} - error {1}",
|
||||
() => model.UserId, () => unlockResult.Errors.First());
|
||||
}
|
||||
}
|
||||
|
||||
return Request.CreateResponse(HttpStatusCode.OK);
|
||||
}
|
||||
|
||||
return Request.CreateValidationErrorResponse(
|
||||
result.Errors.Any() ? result.Errors.First() : "Set password failed");
|
||||
}
|
||||
|
||||
@@ -391,6 +391,10 @@ namespace Umbraco.Web.Editors
|
||||
{
|
||||
"disallowedUploadFiles",
|
||||
string.Join(",", UmbracoConfig.For.UmbracoSettings().Content.DisallowedUploadFiles)
|
||||
},
|
||||
{
|
||||
"allowedUploadFiles",
|
||||
string.Join(",", UmbracoConfig.For.UmbracoSettings().Content.AllowedUploadFiles)
|
||||
},
|
||||
{
|
||||
"maxFileSize",
|
||||
|
||||
@@ -42,13 +42,13 @@ namespace Umbraco.Web.Editors
|
||||
switch (type)
|
||||
{
|
||||
case Core.Constants.Trees.PartialViews:
|
||||
var view = new PartialView(display.VirtualPath);
|
||||
var view = new PartialView(PartialViewType.PartialView, display.VirtualPath);
|
||||
view.Content = display.Content;
|
||||
var result = Services.FileService.CreatePartialView(view, display.Snippet, Security.CurrentUser.Id);
|
||||
return result.Success == true ? Request.CreateResponse(HttpStatusCode.OK) : Request.CreateNotificationValidationErrorResponse(result.Exception.Message);
|
||||
|
||||
case Core.Constants.Trees.PartialViewMacros:
|
||||
var viewMacro = new PartialView(display.VirtualPath);
|
||||
var viewMacro = new PartialView(PartialViewType.PartialViewMacro, display.VirtualPath);
|
||||
viewMacro.Content = display.Content;
|
||||
var resultMacro = Services.FileService.CreatePartialViewMacro(viewMacro, display.Snippet, Security.CurrentUser.Id);
|
||||
return resultMacro.Success == true ? Request.CreateResponse(HttpStatusCode.OK) : Request.CreateNotificationValidationErrorResponse(resultMacro.Exception.Message);
|
||||
@@ -219,13 +219,13 @@ namespace Umbraco.Web.Editors
|
||||
switch (type)
|
||||
{
|
||||
case Core.Constants.Trees.PartialViews:
|
||||
codeFileDisplay = Mapper.Map<IPartialView, CodeFileDisplay>(new PartialView(string.Empty));
|
||||
codeFileDisplay = Mapper.Map<IPartialView, CodeFileDisplay>(new PartialView(PartialViewType.PartialView, string.Empty));
|
||||
codeFileDisplay.VirtualPath = SystemDirectories.PartialViews;
|
||||
if (snippetName.IsNullOrWhiteSpace() == false)
|
||||
codeFileDisplay.Content = Services.FileService.GetPartialViewSnippetContent(snippetName);
|
||||
break;
|
||||
case Core.Constants.Trees.PartialViewMacros:
|
||||
codeFileDisplay = Mapper.Map<IPartialView, CodeFileDisplay>(new PartialView(string.Empty));
|
||||
codeFileDisplay = Mapper.Map<IPartialView, CodeFileDisplay>(new PartialView(PartialViewType.PartialViewMacro, string.Empty));
|
||||
codeFileDisplay.VirtualPath = SystemDirectories.MacroPartials;
|
||||
if (snippetName.IsNullOrWhiteSpace() == false)
|
||||
codeFileDisplay.Content = Services.FileService.GetPartialViewMacroSnippetContent(snippetName);
|
||||
@@ -475,7 +475,7 @@ namespace Umbraco.Web.Editors
|
||||
}
|
||||
else
|
||||
{
|
||||
view = new PartialView(virtualPath + display.Name);
|
||||
view = new PartialView(PartialViewType.PartialView, virtualPath + display.Name);
|
||||
view.Content = display.Content;
|
||||
partialViewResult = createView(view, display.Snippet, Security.CurrentUser.Id);
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ namespace Umbraco.Web.Editors
|
||||
where TPersisted : IContentBase
|
||||
{
|
||||
//Don't update the name if it is empty
|
||||
if (!contentItem.Name.IsNullOrWhiteSpace())
|
||||
if (contentItem.Name.IsNullOrWhiteSpace() == false)
|
||||
{
|
||||
contentItem.PersistedContent.Name = contentItem.Name;
|
||||
}
|
||||
|
||||
@@ -33,7 +33,8 @@ using Umbraco.Core.Configuration;
|
||||
using Umbraco.Web.UI;
|
||||
using Notification = Umbraco.Web.Models.ContentEditing.Notification;
|
||||
using Umbraco.Core.Persistence;
|
||||
|
||||
using Umbraco.Core.Configuration.UmbracoSettings;
|
||||
|
||||
namespace Umbraco.Web.Editors
|
||||
{
|
||||
/// <remarks>
|
||||
@@ -723,7 +724,7 @@ namespace Umbraco.Web.Editors
|
||||
var safeFileName = fileName.ToSafeFileName();
|
||||
var ext = safeFileName.Substring(safeFileName.LastIndexOf('.') + 1).ToLower();
|
||||
|
||||
if (UmbracoConfig.For.UmbracoSettings().Content.DisallowedUploadFiles.Contains(ext) == false)
|
||||
if (UmbracoConfig.For.UmbracoSettings().Content.IsFileAllowedForUpload(ext))
|
||||
{
|
||||
var mediaType = Constants.Conventions.MediaTypes.File;
|
||||
|
||||
|
||||
@@ -1,23 +1,22 @@
|
||||
using Umbraco.Core;
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Web.Extensions
|
||||
{
|
||||
[Obsolete("Use methods on UmbracoHelper instead")]
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public static class UdiExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// An extension method to easily acquire a typed version of content, media or member item for a given Udi
|
||||
/// </summary>
|
||||
/// <param name="udi"></param>
|
||||
/// <returns>An <see cref="IPublishedContent"/> item if the item is a Document, Media or Member</returns>
|
||||
[Obsolete("Use methods on UmbracoHelper instead")]
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public static IPublishedContent ToPublishedContent(this Udi udi)
|
||||
{
|
||||
Udi identifier;
|
||||
if (Udi.TryParse(udi.ToString(), out identifier) == false)
|
||||
return null;
|
||||
var guidUdi = udi as GuidUdi;
|
||||
if (guidUdi == null) return null;
|
||||
|
||||
var guidUdi = GuidUdi.Parse(udi.ToString());
|
||||
var umbracoType = Constants.UdiEntityType.ToUmbracoObjectType(identifier.EntityType);
|
||||
var umbracoType = Constants.UdiEntityType.ToUmbracoObjectType(guidUdi.EntityType);
|
||||
|
||||
var umbracoHelper = new UmbracoHelper(UmbracoContext.Current);
|
||||
var entityService = ApplicationContext.Current.Services.EntityService;
|
||||
@@ -36,7 +35,7 @@ namespace Umbraco.Web.Extensions
|
||||
return umbracoHelper.TypedMember(memberAttempt.Result);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,8 +11,20 @@ namespace Umbraco.Web
|
||||
/// </summary>
|
||||
public interface ITypedPublishedContentQuery
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets a content item from the cache
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
IPublishedContent TypedContent(int id);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a content item from the cache
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
IPublishedContent TypedContent(Guid id);
|
||||
|
||||
IPublishedContent TypedContentSingleAtXPath(string xpath, params XPathVariable[] vars);
|
||||
IEnumerable<IPublishedContent> TypedContent(IEnumerable<int> ids);
|
||||
IEnumerable<IPublishedContent> TypedContent(IEnumerable<Guid> ids);
|
||||
@@ -20,8 +32,8 @@ namespace Umbraco.Web
|
||||
IEnumerable<IPublishedContent> TypedContentAtXPath(XPathExpression xpath, params XPathVariable[] vars);
|
||||
IEnumerable<IPublishedContent> TypedContentAtRoot();
|
||||
|
||||
// note: we CANNOT implement TypedMedia by Guid in v7 without break-changing IPublishedCache,
|
||||
// since we don't support XPath navigation of the media tree.
|
||||
// TODO: we CANNOT implement TypedMedia by Guid in v7 without break-changing IPublishedCache, since we don't support XPath navigation of the media tree.
|
||||
// surely there is a way we can support this without XPath, it's needed so we can query properly by UDI
|
||||
|
||||
IPublishedContent TypedMedia(int id);
|
||||
//IPublishedContent TypedMedia(Guid id);
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace Umbraco.Web.Models
|
||||
{
|
||||
[Serializable]
|
||||
[DataContract(Name = "validatePasswordReset", Namespace = "")]
|
||||
public class ValidatePasswordResetCodeModel
|
||||
{
|
||||
|
||||
@@ -9,7 +9,8 @@ using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
using umbraco;
|
||||
|
||||
using Umbraco.Core.Configuration.UmbracoSettings;
|
||||
|
||||
namespace Umbraco.Web.PropertyEditors
|
||||
{
|
||||
internal class UploadFileTypeValidator : IPropertyValidator
|
||||
@@ -41,8 +42,9 @@ namespace Umbraco.Web.PropertyEditors
|
||||
internal static bool ValidateFileExtension(string fileName)
|
||||
{
|
||||
if (fileName.IndexOf('.') <= 0) return false;
|
||||
var extension = Path.GetExtension(fileName).TrimStart(".");
|
||||
return UmbracoConfig.For.UmbracoSettings().Content.DisallowedUploadFiles.Any(x => StringExtensions.InvariantEquals(x, extension)) == false;
|
||||
var extension = Path.GetExtension(fileName).TrimStart(".");
|
||||
|
||||
return UmbracoConfig.For.UmbracoSettings().Content.IsFileAllowedForUpload(extension);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -50,10 +50,12 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters
|
||||
/// </returns>
|
||||
public override bool IsConverter(PublishedPropertyType propertyType)
|
||||
{
|
||||
if (propertyType.PropertyEditorAlias.Equals(Constants.PropertyEditors.ContentPicker2Alias))
|
||||
return true;
|
||||
|
||||
if (UmbracoConfig.For.UmbracoSettings().Content.EnablePropertyValueConverters)
|
||||
{
|
||||
return propertyType.PropertyEditorAlias.Equals(Constants.PropertyEditors.ContentPickerAlias)
|
||||
|| propertyType.PropertyEditorAlias.Equals(Constants.PropertyEditors.ContentPicker2Alias);
|
||||
return propertyType.PropertyEditorAlias.Equals(Constants.PropertyEditors.ContentPickerAlias);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -106,25 +108,26 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters
|
||||
return null;
|
||||
}
|
||||
|
||||
if (UmbracoContext.Current != null)
|
||||
if (UmbracoContext.Current == null) return source;
|
||||
|
||||
if ((propertyType.PropertyTypeAlias != null && PropertiesToExclude.Contains(propertyType.PropertyTypeAlias.ToLower(CultureInfo.InvariantCulture))) == false)
|
||||
{
|
||||
if ((propertyType.PropertyTypeAlias != null && PropertiesToExclude.Contains(propertyType.PropertyTypeAlias.ToLower(CultureInfo.InvariantCulture))) == false)
|
||||
IPublishedContent content;
|
||||
if (source is int)
|
||||
{
|
||||
IPublishedContent content;
|
||||
if (source is int)
|
||||
{
|
||||
var sourceInt = (int)source;
|
||||
content = UmbracoContext.Current.ContentCache.GetById(sourceInt);
|
||||
if(content != null)
|
||||
return content;
|
||||
}
|
||||
else
|
||||
{
|
||||
var sourceUdi = source as Udi;
|
||||
content = sourceUdi.ToPublishedContent();
|
||||
if (content != null)
|
||||
return content;
|
||||
}
|
||||
var sourceInt = (int)source;
|
||||
content = UmbracoContext.Current.ContentCache.GetById(sourceInt);
|
||||
if(content != null)
|
||||
return content;
|
||||
}
|
||||
else
|
||||
{
|
||||
var sourceUdi = source as Udi;
|
||||
if (sourceUdi == null) return null;
|
||||
var umbHelper = new UmbracoHelper(UmbracoContext.Current);
|
||||
content = umbHelper.TypedContent(sourceUdi);
|
||||
if (content != null)
|
||||
return content;
|
||||
}
|
||||
}
|
||||
return source;
|
||||
|
||||
+27
-30
@@ -18,16 +18,12 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters
|
||||
[PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Content)]
|
||||
public class LegacyRelatedLinksEditorValueConvertor : PropertyValueConverterBase
|
||||
{
|
||||
private static readonly string[] MatchingEditors = {
|
||||
Constants.PropertyEditors.RelatedLinksAlias,
|
||||
Constants.PropertyEditors.RelatedLinks2Alias
|
||||
};
|
||||
|
||||
public override bool IsConverter(PublishedPropertyType propertyType)
|
||||
{
|
||||
if (UmbracoConfig.For.UmbracoSettings().Content.EnablePropertyValueConverters == false)
|
||||
{
|
||||
return MatchingEditors.Contains(propertyType.PropertyEditorAlias);
|
||||
return propertyType.PropertyEditorAlias.Equals(Constants.PropertyEditors.RelatedLinksAlias);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -42,37 +38,38 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters
|
||||
try
|
||||
{
|
||||
var obj = JsonConvert.DeserializeObject<JArray>(sourceString);
|
||||
|
||||
//update the internal links if we have a context
|
||||
if (UmbracoContext.Current != null)
|
||||
if (UmbracoContext.Current == null) return obj;
|
||||
|
||||
var helper = new UmbracoHelper(UmbracoContext.Current);
|
||||
foreach (var a in obj)
|
||||
{
|
||||
var helper = new UmbracoHelper(UmbracoContext.Current);
|
||||
foreach (var a in obj)
|
||||
var type = a.Value<string>("type");
|
||||
if (type.IsNullOrWhiteSpace() == false)
|
||||
{
|
||||
var type = a.Value<string>("type");
|
||||
if (type.IsNullOrWhiteSpace() == false)
|
||||
if (type == "internal")
|
||||
{
|
||||
if (type == "internal")
|
||||
switch (propertyType.PropertyEditorAlias)
|
||||
{
|
||||
switch (propertyType.PropertyEditorAlias)
|
||||
{
|
||||
case Constants.PropertyEditors.RelatedLinksAlias:
|
||||
var intLinkId = a.Value<int>("link");
|
||||
var intLink = helper.NiceUrl(intLinkId);
|
||||
a["link"] = intLink;
|
||||
break;
|
||||
case Constants.PropertyEditors.RelatedLinks2Alias:
|
||||
var strLinkId = a.Value<string>("link");
|
||||
var udiAttempt = strLinkId.TryConvertTo<Udi>();
|
||||
if (udiAttempt)
|
||||
{
|
||||
var content = udiAttempt.Result.ToPublishedContent();
|
||||
a["link"] = helper.NiceUrl(content.Id);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
case Constants.PropertyEditors.RelatedLinksAlias:
|
||||
var intLinkId = a.Value<int>("link");
|
||||
var intLink = helper.NiceUrl(intLinkId);
|
||||
a["link"] = intLink;
|
||||
break;
|
||||
case Constants.PropertyEditors.RelatedLinks2Alias:
|
||||
var strLinkId = a.Value<string>("link");
|
||||
var udiAttempt = strLinkId.TryConvertTo<Udi>();
|
||||
if (udiAttempt)
|
||||
{
|
||||
var content = helper.TypedContent(udiAttempt.Result);
|
||||
if (content == null) break;
|
||||
a["link"] = helper.NiceUrl(content.Id);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
@@ -122,7 +123,14 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters
|
||||
/// </returns>
|
||||
public override bool IsConverter(PublishedPropertyType propertyType)
|
||||
{
|
||||
return propertyType.PropertyEditorAlias.Equals(Constants.PropertyEditors.MediaPicker2Alias);
|
||||
if (propertyType.PropertyEditorAlias.Equals(Constants.PropertyEditors.MediaPicker2Alias))
|
||||
return true;
|
||||
|
||||
if (UmbracoConfig.For.UmbracoSettings().Content.EnablePropertyValueConverters)
|
||||
{
|
||||
return propertyType.PropertyEditorAlias.Equals(Constants.PropertyEditors.MediaPickerAlias);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -173,11 +181,13 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters
|
||||
|
||||
var udis = (Udi[])source;
|
||||
var mediaItems = new List<IPublishedContent>();
|
||||
if (UmbracoContext.Current == null) return source;
|
||||
var helper = new UmbracoHelper(UmbracoContext.Current);
|
||||
if (udis.Any())
|
||||
{
|
||||
foreach (var udi in udis)
|
||||
{
|
||||
var item = udi.ToPublishedContent();
|
||||
var item = helper.TypedMedia(udi);
|
||||
if (item != null)
|
||||
mediaItems.Add(item);
|
||||
}
|
||||
|
||||
@@ -17,10 +17,12 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters
|
||||
{
|
||||
public override bool IsConverter(PublishedPropertyType propertyType)
|
||||
{
|
||||
if (propertyType.PropertyEditorAlias.Equals(Constants.PropertyEditors.MemberPicker2Alias))
|
||||
return true;
|
||||
|
||||
if (UmbracoConfig.For.UmbracoSettings().Content.EnablePropertyValueConverters)
|
||||
{
|
||||
return propertyType.PropertyEditorAlias.InvariantEquals(Constants.PropertyEditors.MemberPickerAlias)
|
||||
|| propertyType.PropertyEditorAlias.InvariantEquals(Constants.PropertyEditors.MemberPicker2Alias);
|
||||
return propertyType.PropertyEditorAlias.Equals(Constants.PropertyEditors.MemberPickerAlias);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -41,23 +43,22 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters
|
||||
if (source == null)
|
||||
return null;
|
||||
|
||||
if (UmbracoContext.Current != null)
|
||||
if (UmbracoContext.Current == null) return source;
|
||||
|
||||
var umbracoHelper = new UmbracoHelper(UmbracoContext.Current);
|
||||
IPublishedContent member;
|
||||
if (source is int)
|
||||
{
|
||||
member = umbracoHelper.TypedMember((int)source);
|
||||
if (member != null)
|
||||
return member;
|
||||
}
|
||||
else
|
||||
{
|
||||
IPublishedContent member;
|
||||
if (source is int)
|
||||
{
|
||||
var membershipHelper = new MembershipHelper(UmbracoContext.Current);
|
||||
member = membershipHelper.GetById((int)source);
|
||||
if (member != null)
|
||||
return member;
|
||||
}
|
||||
else
|
||||
{
|
||||
var sourceUdi = source as Udi;
|
||||
member = sourceUdi.ToPublishedContent();
|
||||
if (member != null)
|
||||
return member;
|
||||
}
|
||||
var sourceUdi = source as Udi;
|
||||
member = umbracoHelper.TypedMember(sourceUdi);
|
||||
if (member != null)
|
||||
return member;
|
||||
}
|
||||
|
||||
return source;
|
||||
|
||||
+47
-46
@@ -52,10 +52,12 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters
|
||||
/// </returns>
|
||||
public override bool IsConverter(PublishedPropertyType propertyType)
|
||||
{
|
||||
if (propertyType.PropertyEditorAlias.Equals(Constants.PropertyEditors.MultiNodeTreePicker2Alias))
|
||||
return true;
|
||||
|
||||
if (UmbracoConfig.For.UmbracoSettings().Content.EnablePropertyValueConverters)
|
||||
{
|
||||
return propertyType.PropertyEditorAlias.Equals(Constants.PropertyEditors.MultiNodeTreePickerAlias)
|
||||
|| propertyType.PropertyEditorAlias.Equals(Constants.PropertyEditors.MultiNodeTreePicker2Alias);
|
||||
return propertyType.PropertyEditorAlias.Equals(Constants.PropertyEditors.MultiNodeTreePickerAlias);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -119,68 +121,67 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters
|
||||
}
|
||||
|
||||
//TODO: Inject an UmbracoHelper and create a GetUmbracoHelper method based on either injected or singleton
|
||||
if (UmbracoContext.Current != null)
|
||||
if (UmbracoContext.Current == null) return source;
|
||||
|
||||
var umbHelper = new UmbracoHelper(UmbracoContext.Current);
|
||||
|
||||
if (propertyType.PropertyEditorAlias.Equals(Constants.PropertyEditors.MultiNodeTreePickerAlias))
|
||||
{
|
||||
if (propertyType.PropertyEditorAlias.Equals(Constants.PropertyEditors.MultiNodeTreePickerAlias))
|
||||
var nodeIds = (int[])source;
|
||||
|
||||
if ((propertyType.PropertyTypeAlias != null && PropertiesToExclude.InvariantContains(propertyType.PropertyTypeAlias)) == false)
|
||||
{
|
||||
var nodeIds = (int[])source;
|
||||
var multiNodeTreePicker = new List<IPublishedContent>();
|
||||
|
||||
if ((propertyType.PropertyTypeAlias != null && PropertiesToExclude.InvariantContains(propertyType.PropertyTypeAlias)) == false)
|
||||
var objectType = UmbracoObjectTypes.Unknown;
|
||||
|
||||
foreach (var nodeId in nodeIds)
|
||||
{
|
||||
var multiNodeTreePicker = new List<IPublishedContent>();
|
||||
var multiNodeTreePickerItem =
|
||||
GetPublishedContent(nodeId, ref objectType, UmbracoObjectTypes.Document, umbHelper.TypedContent)
|
||||
?? GetPublishedContent(nodeId, ref objectType, UmbracoObjectTypes.Media, umbHelper.TypedMedia)
|
||||
?? GetPublishedContent(nodeId, ref objectType, UmbracoObjectTypes.Member, umbHelper.TypedMember);
|
||||
|
||||
if (nodeIds.Length > 0)
|
||||
if (multiNodeTreePickerItem != null)
|
||||
{
|
||||
var umbHelper = new UmbracoHelper(UmbracoContext.Current);
|
||||
var objectType = UmbracoObjectTypes.Unknown;
|
||||
|
||||
foreach (var nodeId in nodeIds)
|
||||
{
|
||||
var multiNodeTreePickerItem =
|
||||
GetPublishedContent(nodeId, ref objectType, UmbracoObjectTypes.Document, umbHelper.TypedContent)
|
||||
?? GetPublishedContent(nodeId, ref objectType, UmbracoObjectTypes.Media, umbHelper.TypedMedia)
|
||||
?? GetPublishedContent(nodeId, ref objectType, UmbracoObjectTypes.Member, umbHelper.TypedMember);
|
||||
|
||||
if (multiNodeTreePickerItem != null)
|
||||
{
|
||||
multiNodeTreePicker.Add(multiNodeTreePickerItem);
|
||||
}
|
||||
}
|
||||
multiNodeTreePicker.Add(multiNodeTreePickerItem);
|
||||
}
|
||||
|
||||
return multiNodeTreePicker;
|
||||
}
|
||||
|
||||
// return the first nodeId as this is one of the excluded properties that expects a single id
|
||||
return nodeIds.FirstOrDefault();
|
||||
return multiNodeTreePicker;
|
||||
}
|
||||
|
||||
if (propertyType.PropertyEditorAlias.Equals(Constants.PropertyEditors.MultiNodeTreePicker2Alias))
|
||||
// return the first nodeId as this is one of the excluded properties that expects a single id
|
||||
return nodeIds.FirstOrDefault();
|
||||
}
|
||||
|
||||
if (propertyType.PropertyEditorAlias.Equals(Constants.PropertyEditors.MultiNodeTreePicker2Alias))
|
||||
{
|
||||
var udis = (Udi[])source;
|
||||
|
||||
if ((propertyType.PropertyTypeAlias != null && PropertiesToExclude.InvariantContains(propertyType.PropertyTypeAlias)) == false)
|
||||
{
|
||||
var udis = (Udi[])source;
|
||||
var multiNodeTreePicker = new List<IPublishedContent>();
|
||||
|
||||
if ((propertyType.PropertyTypeAlias != null && PropertiesToExclude.InvariantContains(propertyType.PropertyTypeAlias)) == false)
|
||||
var objectType = UmbracoObjectTypes.Unknown;
|
||||
|
||||
foreach (var udi in udis)
|
||||
{
|
||||
var multiNodeTreePicker = new List<IPublishedContent>();
|
||||
|
||||
if (udis.Length > 0)
|
||||
var multiNodeTreePickerItem =
|
||||
GetPublishedContent(udi, ref objectType, UmbracoObjectTypes.Document, umbHelper.TypedContent)
|
||||
?? GetPublishedContent(udi, ref objectType, UmbracoObjectTypes.Media, umbHelper.TypedMedia)
|
||||
?? GetPublishedContent(udi, ref objectType, UmbracoObjectTypes.Member, umbHelper.TypedMember);
|
||||
if (multiNodeTreePickerItem != null)
|
||||
{
|
||||
foreach (var udi in udis)
|
||||
{
|
||||
var item = udi.ToPublishedContent();
|
||||
if (item != null)
|
||||
{
|
||||
multiNodeTreePicker.Add(item);
|
||||
}
|
||||
}
|
||||
multiNodeTreePicker.Add(multiNodeTreePickerItem);
|
||||
}
|
||||
|
||||
return multiNodeTreePicker;
|
||||
}
|
||||
|
||||
// return the first nodeId as this is one of the excluded properties that expects a single id
|
||||
return udis.FirstOrDefault();
|
||||
return multiNodeTreePicker;
|
||||
}
|
||||
|
||||
// return the first nodeId as this is one of the excluded properties that expects a single id
|
||||
return udis.FirstOrDefault();
|
||||
}
|
||||
return source;
|
||||
}
|
||||
@@ -193,7 +194,7 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters
|
||||
/// <param name="expectedType">The type of content expected/supported by <paramref name="contentFetcher"/></param>
|
||||
/// <param name="contentFetcher">A function to fetch content of type <paramref name="expectedType"/></param>
|
||||
/// <returns>The requested content, or null if either it does not exist or <paramref name="actualType"/> does not match <paramref name="expectedType"/></returns>
|
||||
private IPublishedContent GetPublishedContent(int nodeId, ref UmbracoObjectTypes actualType, UmbracoObjectTypes expectedType, Func<int, IPublishedContent> contentFetcher)
|
||||
private IPublishedContent GetPublishedContent<T>(T nodeId, ref UmbracoObjectTypes actualType, UmbracoObjectTypes expectedType, Func<T, IPublishedContent> contentFetcher)
|
||||
{
|
||||
// is the actual type supported by the content fetcher?
|
||||
if (actualType != UmbracoObjectTypes.Unknown && actualType != expectedType)
|
||||
|
||||
@@ -53,10 +53,12 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters
|
||||
/// </returns>
|
||||
public override bool IsConverter(PublishedPropertyType propertyType)
|
||||
{
|
||||
if (propertyType.PropertyEditorAlias.Equals(Constants.PropertyEditors.RelatedLinks2Alias))
|
||||
return true;
|
||||
|
||||
if (UmbracoConfig.For.UmbracoSettings().Content.EnablePropertyValueConverters)
|
||||
{
|
||||
return propertyType.PropertyEditorAlias.Equals(Constants.PropertyEditors.RelatedLinksAlias)
|
||||
|| propertyType.PropertyEditorAlias.Equals(Constants.PropertyEditors.RelatedLinks2Alias);
|
||||
return propertyType.PropertyEditorAlias.Equals(Constants.PropertyEditors.RelatedLinksAlias);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -88,6 +90,10 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters
|
||||
var relatedLinksData = JsonConvert.DeserializeObject<IEnumerable<RelatedLink>>(sourceString);
|
||||
var relatedLinks = new List<RelatedLink>();
|
||||
|
||||
if (UmbracoContext.Current == null) return source;
|
||||
|
||||
var helper = new UmbracoHelper(UmbracoContext.Current);
|
||||
|
||||
foreach (var linkData in relatedLinksData)
|
||||
{
|
||||
var relatedLink = new RelatedLink
|
||||
@@ -111,7 +117,7 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters
|
||||
var udiAttempt = strLinkId.TryConvertTo<Udi>();
|
||||
if (udiAttempt.Success)
|
||||
{
|
||||
var content = udiAttempt.Result.ToPublishedContent();
|
||||
var content = helper.TypedContent(udiAttempt.Result);
|
||||
if (content != null)
|
||||
{
|
||||
relatedLink.Id = content.Id;
|
||||
|
||||
@@ -12,7 +12,11 @@ namespace Umbraco.Web.PublishedCache
|
||||
/// Provides access to cached contents in a specified context.
|
||||
/// </summary>
|
||||
public abstract class ContextualPublishedCache
|
||||
{
|
||||
{
|
||||
//TODO: We need to add:
|
||||
//* GetById(Guid contentId)
|
||||
//* GetById(UDI contentId)
|
||||
|
||||
protected readonly UmbracoContext UmbracoContext;
|
||||
|
||||
/// <summary>
|
||||
@@ -35,6 +39,18 @@ namespace Umbraco.Web.PublishedCache
|
||||
return GetById(UmbracoContext.InPreviewMode, contentId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a content identified by its unique identifier.
|
||||
/// </summary>
|
||||
/// <param name="contentId">The content unique identifier.</param>
|
||||
/// <returns>The content, or null.</returns>
|
||||
/// <remarks>Considers published or unpublished content depending on context.</remarks>
|
||||
public IPublishedContent GetById(Guid contentId)
|
||||
{
|
||||
var intId = UmbracoContext.Application.Services.EntityService.GetIdForKey(contentId, UmbracoObjectTypes.Document);
|
||||
return GetById(intId.Success ? intId.Result : -1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a content identified by its unique identifier.
|
||||
/// </summary>
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Web
|
||||
{
|
||||
public static class PublishedContentQueryExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets a content item from the cache
|
||||
/// </summary>
|
||||
/// <param name="contentQuery"></param>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
public static IPublishedContent TypedContent(this ITypedPublishedContentQuery contentQuery, Udi id)
|
||||
{
|
||||
var guidUdi = id as GuidUdi;
|
||||
if (guidUdi == null)
|
||||
throw new InvalidOperationException("UDIs for content items must be " + typeof(GuidUdi));
|
||||
return contentQuery.TypedContent(guidUdi.Guid);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,13 +17,14 @@ using umbraco;
|
||||
using umbraco.cms.businesslogic.web;
|
||||
using umbraco.cms.businesslogic.language;
|
||||
using umbraco.cms.businesslogic.member;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web.Security;
|
||||
using RenderingEngine = Umbraco.Core.RenderingEngine;
|
||||
|
||||
namespace Umbraco.Web.Routing
|
||||
{
|
||||
internal class PublishedContentRequestEngine
|
||||
internal class PublishedContentRequestEngine
|
||||
{
|
||||
private readonly PublishedContentRequest _pcr;
|
||||
private readonly RoutingContext _routingContext;
|
||||
@@ -518,51 +519,69 @@ namespace Umbraco.Web.Routing
|
||||
const string tracePrefix = "FollowInternalRedirects: ";
|
||||
|
||||
if (_pcr.PublishedContent == null)
|
||||
throw new InvalidOperationException("There is no PublishedContent.");
|
||||
throw new InvalidOperationException("There is no PublishedContent.");
|
||||
|
||||
// don't try to find a redirect if the property doesn't exist
|
||||
if (_pcr.PublishedContent.HasProperty(Constants.Conventions.Content.InternalRedirectId) == false)
|
||||
return false;
|
||||
|
||||
var redirect = false;
|
||||
IPublishedContent internalRedirectNode = null;
|
||||
var internalRedirectId =
|
||||
_pcr.PublishedContent.GetPropertyValue<int>(Constants.Conventions.Content.InternalRedirectId, -1);
|
||||
var valueValid = false;
|
||||
if (internalRedirectId > 0)
|
||||
{
|
||||
valueValid = true;
|
||||
// Try and get the redirect node from a legacy integer ID
|
||||
internalRedirectNode = _routingContext.UmbracoContext.ContentCache.GetById(internalRedirectId);
|
||||
}
|
||||
else
|
||||
{
|
||||
var udiInternalRedirectId =
|
||||
_pcr.PublishedContent.GetPropertyValue<GuidUdi>(Constants.Conventions.Content.InternalRedirectId);
|
||||
if (udiInternalRedirectId != null)
|
||||
{
|
||||
valueValid = true;
|
||||
// Try and get the redirect node from a UDI Guid
|
||||
internalRedirectNode =
|
||||
_routingContext.UmbracoContext.ContentCache.GetById(udiInternalRedirectId.Guid);
|
||||
}
|
||||
}
|
||||
|
||||
if (valueValid == false)
|
||||
{
|
||||
// bad redirect - log and display the current page (legacy behavior)
|
||||
ProfilingLogger
|
||||
.Logger.Debug<PublishedContentRequestEngine>(
|
||||
"{0}Failed to redirect, value of '{1}' is not an int nor a GuidUdi",
|
||||
() => tracePrefix, () => Constants.Conventions.Content.InternalRedirectId);
|
||||
}
|
||||
|
||||
bool redirect = false;
|
||||
var internalRedirect = _pcr.PublishedContent.GetPropertyValue<string>(Constants.Conventions.Content.InternalRedirectId);
|
||||
if (internalRedirectNode == null)
|
||||
{
|
||||
ProfilingLogger.Logger.Debug<PublishedContentRequestEngine>(
|
||||
"{0}Failed to redirect, value of '{1}' does not lead to a published document", () => tracePrefix,
|
||||
() => Constants.Conventions.Content.InternalRedirectId);
|
||||
}
|
||||
else if (internalRedirectNode.Id == _pcr.PublishedContent.Id)
|
||||
{
|
||||
// redirect to self
|
||||
ProfilingLogger.Logger.Debug<PublishedContentRequestEngine>("{0}Redirecting to self, ignore",
|
||||
() => tracePrefix);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Redirect to another page
|
||||
_pcr.SetInternalRedirectPublishedContent(internalRedirectNode);
|
||||
redirect = true;
|
||||
ProfilingLogger.Logger.Debug<PublishedContentRequestEngine>("{0}Redirecting to id={1}", () => tracePrefix,
|
||||
() => internalRedirectNode.Id);
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(internalRedirect) == false)
|
||||
{
|
||||
ProfilingLogger.Logger.Debug<PublishedContentRequestEngine>("{0}Found umbracoInternalRedirectId={1}", () => tracePrefix, () => internalRedirect);
|
||||
|
||||
int internalRedirectId;
|
||||
if (int.TryParse(internalRedirect, out internalRedirectId) == false)
|
||||
internalRedirectId = -1;
|
||||
|
||||
if (internalRedirectId <= 0)
|
||||
{
|
||||
// bad redirect - log and display the current page (legacy behavior)
|
||||
//_pcr.Document = null; // no! that would be to force a 404
|
||||
ProfilingLogger.Logger.Debug<PublishedContentRequestEngine>("{0}Failed to redirect to id={1}: invalid value", () => tracePrefix, () => internalRedirect);
|
||||
}
|
||||
else if (internalRedirectId == _pcr.PublishedContent.Id)
|
||||
{
|
||||
// redirect to self
|
||||
ProfilingLogger.Logger.Debug<PublishedContentRequestEngine>("{0}Redirecting to self, ignore", () => tracePrefix);
|
||||
}
|
||||
else
|
||||
{
|
||||
// redirect to another page
|
||||
var node = _routingContext.UmbracoContext.ContentCache.GetById(internalRedirectId);
|
||||
|
||||
if (node != null)
|
||||
{
|
||||
_pcr.SetInternalRedirectPublishedContent(node); // don't use .PublishedContent here
|
||||
redirect = true;
|
||||
ProfilingLogger.Logger.Debug<PublishedContentRequestEngine>("{0}Redirecting to id={1}", () => tracePrefix, () => internalRedirectId);
|
||||
}
|
||||
else
|
||||
{
|
||||
ProfilingLogger.Logger.Debug<PublishedContentRequestEngine>("{0}Failed to redirect to id={1}: no such published document", () => tracePrefix, () => internalRedirectId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return redirect;
|
||||
return redirect;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Ensures that access to current node is permitted.
|
||||
/// </summary>
|
||||
@@ -719,16 +738,31 @@ namespace Umbraco.Web.Routing
|
||||
/// <remarks>As per legacy, if the redirect does not work, we just ignore it.</remarks>
|
||||
private void FollowExternalRedirect()
|
||||
{
|
||||
if (_pcr.HasPublishedContent == false) return;
|
||||
if (_pcr.HasPublishedContent == false) return;
|
||||
|
||||
// don't try to find a redirect if the property doesn't exist
|
||||
if (_pcr.PublishedContent.HasProperty(Constants.Conventions.Content.Redirect) == false)
|
||||
return;
|
||||
|
||||
var redirectId = _pcr.PublishedContent.GetPropertyValue(Constants.Conventions.Content.Redirect, -1);
|
||||
|
||||
var redirectId = _pcr.PublishedContent.GetPropertyValue(Constants.Conventions.Content.Redirect, -1);
|
||||
var redirectUrl = "#";
|
||||
if (redirectId > 0)
|
||||
redirectUrl = _routingContext.UrlProvider.GetUrl(redirectId);
|
||||
{
|
||||
redirectUrl = _routingContext.UrlProvider.GetUrl(redirectId);
|
||||
}
|
||||
else
|
||||
{
|
||||
// might be a UDI instead of an int Id
|
||||
var redirectUdi = _pcr.PublishedContent.GetPropertyValue<GuidUdi>(Constants.Conventions.Content.Redirect);
|
||||
if (redirectUdi != null)
|
||||
redirectUrl = _routingContext.UrlProvider.GetUrl(redirectUdi.Guid);
|
||||
}
|
||||
if (redirectUrl != "#")
|
||||
{
|
||||
_pcr.SetRedirect(redirectUrl);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,6 +88,22 @@ namespace Umbraco.Web.Scheduling
|
||||
}
|
||||
|
||||
var result = await wc.SendAsync(request, token);
|
||||
var content = await result.Content.ReadAsStringAsync();
|
||||
|
||||
if (result.IsSuccessStatusCode)
|
||||
{
|
||||
LogHelper.Debug<ScheduledPublishing>(
|
||||
() => string.Format(
|
||||
"Request successfully sent to url = \"{0}\". ", url));
|
||||
}
|
||||
else
|
||||
{
|
||||
var msg = string.Format(
|
||||
"Request failed with status code \"{0}\". Request content = \"{1}\".",
|
||||
result.StatusCode, content);
|
||||
var ex = new HttpRequestException(msg);
|
||||
LogHelper.Error<ScheduledPublishing>(msg, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace Umbraco.Web.Trees
|
||||
{
|
||||
[UmbracoTreeAuthorize(Constants.Trees.Templates)]
|
||||
[LegacyBaseTree(typeof (loadTemplates))]
|
||||
[Tree(Constants.Applications.Settings, Constants.Trees.Templates, "Templates", sortOrder:1)]
|
||||
[Tree(Constants.Applications.Settings, Constants.Trees.Templates, null, sortOrder:1)]
|
||||
[PluginController("UmbracoTrees")]
|
||||
[CoreTree]
|
||||
public class TemplatesTreeController : TreeController
|
||||
|
||||
@@ -412,6 +412,7 @@
|
||||
<Compile Include="PropertyEditors\ValueConverters\MemberPickerPropertyConverter.cs" />
|
||||
<Compile Include="PropertyEditors\ValueConverters\MultiNodeTreePickerPropertyConverter.cs" />
|
||||
<Compile Include="PropertyEditors\ValueConverters\MultipleMediaPickerPropertyConverter.cs" />
|
||||
<Compile Include="PublishedContentQueryExtensions.cs" />
|
||||
<Compile Include="Routing\RedirectTrackingEventHandler.cs" />
|
||||
<Compile Include="Editors\RedirectUrlManagementController.cs" />
|
||||
<Compile Include="Models\ContentEditing\RedirectUrlSearchResults.cs" />
|
||||
|
||||
@@ -17,7 +17,6 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Web.Mvc;
|
||||
using System.Web.Routing;
|
||||
using Umbraco.Core.Cache;
|
||||
|
||||
namespace Umbraco.Web
|
||||
@@ -38,6 +37,7 @@ namespace Umbraco.Web
|
||||
private MembershipHelper _membershipHelper;
|
||||
private TagQuery _tag;
|
||||
private IDataTypeService _dataTypeService;
|
||||
private IEntityService _entityService;
|
||||
private UrlProvider _urlProvider;
|
||||
private ICultureDictionary _cultureDictionary;
|
||||
|
||||
@@ -113,6 +113,14 @@ namespace Umbraco.Web
|
||||
get { return _dataTypeService ?? (_dataTypeService = UmbracoContext.Application.Services.DataTypeService); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Lazy instantiates the IEntityService
|
||||
/// </summary>
|
||||
private IEntityService EntityService
|
||||
{
|
||||
get { return _entityService ?? (_entityService = UmbracoContext.Application.Services.EntityService); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Lazy instantiates the IUmbracoComponentRenderer if not specified in the constructor
|
||||
/// </summary>
|
||||
@@ -527,11 +535,23 @@ namespace Umbraco.Web
|
||||
public string UrlAbsolute(int contentId)
|
||||
{
|
||||
return UrlProvider.GetUrl(contentId, true);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Members
|
||||
|
||||
public IPublishedContent TypedMember(Udi id)
|
||||
{
|
||||
var guidUdi = id as GuidUdi;
|
||||
if (guidUdi == null) return null;
|
||||
return TypedMember(guidUdi.Guid);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Members
|
||||
public IPublishedContent TypedMember(Guid id)
|
||||
{
|
||||
return MembershipHelper.GetByProviderKey(id);
|
||||
}
|
||||
|
||||
public IPublishedContent TypedMember(object id)
|
||||
{
|
||||
@@ -593,6 +613,9 @@ namespace Umbraco.Web
|
||||
Guid guidId;
|
||||
if (ConvertIdObjectToGuid(id, out guidId))
|
||||
return ContentQuery.TypedContent(guidId);
|
||||
Udi udiId;
|
||||
if (ConvertIdObjectToUdi(id, out udiId))
|
||||
return ContentQuery.TypedContent(udiId);
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -615,6 +638,16 @@ namespace Umbraco.Web
|
||||
{
|
||||
return ContentQuery.TypedContent(id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a content item from the cache
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
public IPublishedContent TypedContent(Udi id)
|
||||
{
|
||||
return ContentQuery.TypedContent(id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a content item from the cache.
|
||||
@@ -907,6 +940,22 @@ namespace Umbraco.Web
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool ConvertIdObjectToUdi(object id, out Udi guidId)
|
||||
{
|
||||
var s = id as string;
|
||||
if (s != null)
|
||||
{
|
||||
return Udi.TryParse(s, out guidId);
|
||||
}
|
||||
if (id is Udi)
|
||||
{
|
||||
guidId = (Udi)id;
|
||||
return true;
|
||||
}
|
||||
guidId = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool ConvertIdsObjectToInts(IEnumerable<object> ids, out IEnumerable<int> intIds)
|
||||
{
|
||||
var list = new List<int>();
|
||||
@@ -937,29 +986,59 @@ namespace Umbraco.Web
|
||||
}
|
||||
guidIds = list;
|
||||
return true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Media
|
||||
|
||||
public IPublishedContent TypedMedia(Udi id)
|
||||
{
|
||||
var guidUdi = id as GuidUdi;
|
||||
if (guidUdi == null) return null;
|
||||
return TypedMedia(guidUdi.Guid);
|
||||
}
|
||||
|
||||
#endregion
|
||||
public IPublishedContent TypedMedia(Guid id)
|
||||
{
|
||||
//TODO: This is horrible but until the media cache properly supports GUIDs we have no choice here and
|
||||
// currently there won't be any way to add this method correctly to `ITypedPublishedContentQuery` without breaking an interface and adding GUID support for media
|
||||
|
||||
var entityService = UmbracoContext.Application.Services.EntityService;
|
||||
var mediaAttempt = entityService.GetIdForKey(id, UmbracoObjectTypes.Media);
|
||||
return mediaAttempt.Success ? ContentQuery.TypedMedia(mediaAttempt.Result) : null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overloaded method accepting an 'object' type
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// We accept an object type because GetPropertyValue now returns an 'object', we still want to allow people to pass
|
||||
/// this result in to this method.
|
||||
/// This method will throw an exception if the value is not of type int or string.
|
||||
/// </remarks>
|
||||
public IPublishedContent TypedMedia(object id)
|
||||
{
|
||||
return TypedMediaForObject(id);
|
||||
}
|
||||
|
||||
#region Media
|
||||
|
||||
/// <summary>
|
||||
/// Overloaded method accepting an 'object' type
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// We accept an object type because GetPropertyValue now returns an 'object', we still want to allow people to pass
|
||||
/// this result in to this method.
|
||||
/// This method will throw an exception if the value is not of type int or string.
|
||||
/// </remarks>
|
||||
public IPublishedContent TypedMedia(object id)
|
||||
{
|
||||
private IPublishedContent TypedMediaForObject(object id)
|
||||
{
|
||||
int intId;
|
||||
return ConvertIdObjectToInt(id, out intId) ? ContentQuery.TypedMedia(intId) : null;
|
||||
}
|
||||
|
||||
public IPublishedContent TypedMedia(int id)
|
||||
if (ConvertIdObjectToInt(id, out intId))
|
||||
return ContentQuery.TypedMedia(intId);
|
||||
Guid guidId;
|
||||
if (ConvertIdObjectToGuid(id, out guidId))
|
||||
return TypedMedia(guidId);
|
||||
Udi udiId;
|
||||
if (ConvertIdObjectToUdi(id, out udiId))
|
||||
return TypedMedia(udiId);
|
||||
return null;
|
||||
}
|
||||
|
||||
public IPublishedContent TypedMedia(int id)
|
||||
{
|
||||
return ContentQuery.TypedMedia(id);
|
||||
}
|
||||
@@ -1489,5 +1568,10 @@ namespace Umbraco.Web
|
||||
return surfaceRouteParams.EncryptWithMachineKey();
|
||||
}
|
||||
|
||||
public int GetIdForUdi(Udi udi)
|
||||
{
|
||||
var udiToIdAttempt = EntityService.GetIdForUdi(udi);
|
||||
return udiToIdAttempt.Success ? udiToIdAttempt.Result : -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ using AutoMapper;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Web.Models.ContentEditing;
|
||||
using Umbraco.Web.Models.Mapping;
|
||||
|
||||
namespace Umbraco.Web.WebApi.Binders
|
||||
{
|
||||
@@ -33,7 +32,7 @@ namespace Umbraco.Web.WebApi.Binders
|
||||
var contentType = ApplicationContext.Services.ContentTypeService.GetContentType(model.ContentTypeAlias);
|
||||
if (contentType == null)
|
||||
{
|
||||
throw new InvalidOperationException("No content type found wth alias " + model.ContentTypeAlias);
|
||||
throw new InvalidOperationException("No content type found with alias " + model.ContentTypeAlias);
|
||||
}
|
||||
return new Content(model.Name, model.ParentId, contentType);
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ using AutoMapper;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Web.Models.ContentEditing;
|
||||
using Umbraco.Web.Models.Mapping;
|
||||
|
||||
namespace Umbraco.Web.WebApi.Binders
|
||||
{
|
||||
@@ -29,12 +28,12 @@ namespace Umbraco.Web.WebApi.Binders
|
||||
|
||||
protected override IMedia CreateNew(MediaItemSave model)
|
||||
{
|
||||
var contentType = ApplicationContext.Services.ContentTypeService.GetMediaType(model.ContentTypeAlias);
|
||||
if (contentType == null)
|
||||
var mediaType = ApplicationContext.Services.ContentTypeService.GetMediaType(model.ContentTypeAlias);
|
||||
if (mediaType == null)
|
||||
{
|
||||
throw new InvalidOperationException("No content type found wth alias " + model.ContentTypeAlias);
|
||||
throw new InvalidOperationException("No media type found with alias " + model.ContentTypeAlias);
|
||||
}
|
||||
return new Core.Models.Media(model.Name, model.ParentId, contentType);
|
||||
return new Core.Models.Media(model.Name, model.ParentId, mediaType);
|
||||
}
|
||||
|
||||
protected override ContentItemDto<IMedia> MapFromPersisted(MediaItemSave model)
|
||||
|
||||
@@ -103,7 +103,7 @@ namespace Umbraco.Web.WebServices
|
||||
: get(svce, oldname);
|
||||
|
||||
if (currentView == null)
|
||||
currentView = new PartialView(filename);
|
||||
currentView = new PartialView(PartialViewType.PartialView, filename);
|
||||
else
|
||||
currentView.Path = filename;
|
||||
currentView.Content = contents;
|
||||
|
||||
@@ -511,7 +511,7 @@ namespace umbraco
|
||||
private void ClearContextCache()
|
||||
{
|
||||
var items = HttpContextItems;
|
||||
if (items == null || items.Contains(XmlContextContentItemKey)) return;
|
||||
if (items == null || items.Contains(XmlContextContentItemKey) == false) return;
|
||||
items.Remove(XmlContextContentItemKey);
|
||||
}
|
||||
|
||||
|
||||
@@ -137,12 +137,16 @@ namespace umbraco
|
||||
attributeValue = StateHelper.GetCookieValue(keyName);
|
||||
break;
|
||||
case "#":
|
||||
if (pageElements == null)
|
||||
pageElements = GetPageElements();
|
||||
if (pageElements[keyName] != null)
|
||||
attributeValue = pageElements[keyName].ToString();
|
||||
else
|
||||
attributeValue = "";
|
||||
break;
|
||||
case "$":
|
||||
if (pageElements == null)
|
||||
pageElements = GetPageElements();
|
||||
if (pageElements[keyName] != null && pageElements[keyName].ToString() != string.Empty)
|
||||
{
|
||||
attributeValue = pageElements[keyName].ToString();
|
||||
@@ -190,6 +194,14 @@ namespace umbraco
|
||||
return attributeValue;
|
||||
}
|
||||
|
||||
private static IDictionary GetPageElements()
|
||||
{
|
||||
IDictionary pageElements = null;
|
||||
if (HttpContext.Current.Items["pageElements"] != null)
|
||||
pageElements = (IDictionary)HttpContext.Current.Items["pageElements"];
|
||||
return pageElements;
|
||||
}
|
||||
|
||||
[UmbracoWillObsolete("We should really obsolete that one.")]
|
||||
public static string SpaceCamelCasing(string text)
|
||||
{
|
||||
|
||||
@@ -89,7 +89,7 @@ namespace umbraco
|
||||
/// <param name="rootNode">the 'Relation Types' root node</param>
|
||||
protected override void CreateRootNode(ref XmlTreeNode rootNode)
|
||||
{
|
||||
rootNode.Text = "Relation Types";
|
||||
//rootNode.Text = "Relation Types";
|
||||
rootNode.Icon = BaseTree.FolderIcon;
|
||||
rootNode.OpenIcon = BaseTree.FolderIconOpen;
|
||||
rootNode.NodeType = this.TreeAlias; // (Was prefixed with init)
|
||||
|
||||
@@ -46,7 +46,7 @@ namespace umbraco
|
||||
fileName += ".cshtml";
|
||||
}
|
||||
|
||||
var model = new PartialView(fileName);
|
||||
var model = new PartialView(IsPartialViewMacro ? PartialViewType.PartialViewMacro : PartialViewType.PartialView, fileName);
|
||||
var fileService = (FileService)ApplicationContext.Current.Services.FileService;
|
||||
var macroService = ApplicationContext.Current.Services.MacroService;
|
||||
|
||||
|
||||
@@ -117,7 +117,7 @@
|
||||
<tr>
|
||||
<td>
|
||||
<strong style="color: Red;">Remember:</strong> .xslt and .ascx files for your macros
|
||||
will be added automaticly, but you will still need to add <strong>assemblies</strong>,
|
||||
will be added automatically, but you will still need to add <strong>assemblies</strong>,
|
||||
<strong>images</strong> and <strong>script files</strong> manually to the list below.
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@@ -270,6 +270,14 @@ namespace umbraco
|
||||
public static IEnumerable<string> DisallowedUploadFiles
|
||||
{
|
||||
get { return UmbracoConfig.For.UmbracoSettings().Content.DisallowedUploadFiles; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// File types that will be allowed to be uploaded via the content/media upload control
|
||||
/// </summary>
|
||||
public static IEnumerable<string> AllowedUploadFiles
|
||||
{
|
||||
get { return UmbracoConfig.For.UmbracoSettings().Content.AllowedUploadFiles; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -611,21 +611,19 @@ namespace umbraco.cms.businesslogic
|
||||
//its own + inherited property types, which is wrong. Once we are able to fully switch to the new api
|
||||
//this should no longer be a problem as the composition always contains a correct list of property types.
|
||||
var result = new Dictionary<int, PropertyType>();
|
||||
using (var sqlHelper = Application.SqlHelper)
|
||||
using (IRecordsReader dr = sqlHelper.ExecuteReader(
|
||||
"select id from cmsPropertyType where contentTypeId = @ctId order by sortOrder",
|
||||
sqlHelper.CreateParameter("@ctId", Id)))
|
||||
{
|
||||
while (dr.Read())
|
||||
{
|
||||
int id = dr.GetInt("id");
|
||||
PropertyType pt = PropertyType.GetPropertyType(id);
|
||||
if (pt != null)
|
||||
result.Add(pt.Id, pt);
|
||||
}
|
||||
}
|
||||
|
||||
// Get Property Types from the master content type
|
||||
var ids = ApplicationContext.Current.DatabaseContext.Database.Fetch<int>(
|
||||
"select id from cmsPropertyType where contentTypeId = @ctId order by sortOrder",
|
||||
new {ctId = Id});
|
||||
|
||||
foreach (var id in ids)
|
||||
{
|
||||
var pt = PropertyType.GetPropertyType(id);
|
||||
if (pt != null)
|
||||
result.Add(pt.Id, pt);
|
||||
}
|
||||
|
||||
// Get Property Types from the master content type
|
||||
if (MasterContentTypes.Count > 0)
|
||||
{
|
||||
foreach (var mct in MasterContentTypes)
|
||||
|
||||
@@ -9,7 +9,8 @@ using System.Web.UI.WebControls;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.IO;
|
||||
using umbraco.interfaces;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Configuration.UmbracoSettings;
|
||||
using Content = umbraco.cms.businesslogic.Content;
|
||||
using Umbraco.Core;
|
||||
|
||||
@@ -90,8 +91,8 @@ namespace umbraco.editorControls
|
||||
|
||||
//now check the file type
|
||||
var extension = Path.GetExtension(postedFile.FileName).TrimStart(".");
|
||||
|
||||
return UmbracoConfig.For.UmbracoSettings().Content.DisallowedUploadFiles.Any(x => x.InvariantEquals(extension)) == false;
|
||||
|
||||
return UmbracoConfig.For.UmbracoSettings().Content.IsFileAllowedForUpload(extension);
|
||||
}
|
||||
|
||||
public string Text
|
||||
|
||||
Reference in New Issue
Block a user