Merge remote-tracking branch 'refs/remotes/umbraco/dev-v7' into dev-v7

This commit is contained in:
bjarnef
2015-11-18 22:00:33 +01:00
90 changed files with 617 additions and 216 deletions

View File

@@ -26,7 +26,7 @@
<dependency id="HtmlAgilityPack" version="[1.4.9, 2.0.0)" />
<dependency id="Lucene.Net" version="[2.9.4.1, 3.0.0.0)" />
<dependency id="SharpZipLib" version="[0.86.0, 1.0.0)" />
<dependency id="MySql.Data" version="[6.9.7, 7.0.0)" />
<dependency id="MySql.Data" version="[6.9.8, 7.0.0)" />
<dependency id="xmlrpcnet" version="[2.5.0, 3.0.0)" />
<dependency id="ClientDependency" version="[1.8.4, 2.0.0)" />
<dependency id="ClientDependency-Mvc5" version="[1.8.0, 2.0.0)" />

View File

@@ -63,6 +63,7 @@ if ($project) {
if(Test-Path $umbracoBinFolder\MiniProfiler.dll) { Remove-Item $umbracoBinFolder\MiniProfiler.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\MySql.Data.dll) { Remove-Item $umbracoBinFolder\MySql.Data.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\Newtonsoft.Json.dll) { Remove-Item $umbracoBinFolder\Newtonsoft.Json.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\System.Web.Helpers.dll) { Remove-Item $umbracoBinFolder\System.Web.Helpers.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\System.Net.Http.Formatting.dll) { Remove-Item $umbracoBinFolder\System.Net.Http.Formatting.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\System.Web.Http.dll) { Remove-Item $umbracoBinFolder\System.Web.Http.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\System.Web.Http.WebHost.dll) { Remove-Item $umbracoBinFolder\System.Web.Http.WebHost.dll -Force -Confirm:$false }

View File

@@ -1,2 +1,2 @@
# Usage: on line 2 put the release version, on line 3 put the version comment (example: beta)
7.3.1
7.3.2

View File

@@ -11,7 +11,7 @@ namespace Umbraco.Core
/// <summary>
/// A resolver to return all IAction objects
/// </summary>
internal sealed class ActionsResolver : LazyManyObjectsResolverBase<ActionsResolver, IAction>
public sealed class ActionsResolver : LazyManyObjectsResolverBase<ActionsResolver, IAction>
{
/// <summary>
/// Constructor

View File

@@ -6,7 +6,7 @@ namespace Umbraco.Core.Configuration
{
public class UmbracoVersion
{
private static readonly Version Version = new Version("7.3.1");
private static readonly Version Version = new Version("7.3.2");
/// <summary>
/// Gets the current version of Umbraco.

View File

@@ -310,13 +310,13 @@ namespace Umbraco.Core
public const string TextboxAlias = "Umbraco.Textbox";
/// <summary>
/// Guid for the Textbox multiple datatype.
/// Guid for the Textarea datatype.
/// </summary>
[Obsolete("GUIDs are no longer used to reference Property Editors, use the Alias constant instead. This will be removed in future versions")]
public const string TextboxMultiple = "67DB8357-EF57-493E-91AC-936D305E0F2A";
/// <summary>
/// Alias for the Textbox multiple datatype.
/// Alias for the Textarea datatype.
/// </summary>
public const string TextboxMultipleAlias = "Umbraco.TextboxMultiple";

View File

@@ -154,7 +154,7 @@ namespace Umbraco.Core.IO
{
get
{
return IOHelper.ReturnPath("umbracoWebservicesPath", "~/umbraco/webservices");
return IOHelper.ReturnPath("umbracoWebservicesPath", Umbraco.EnsureEndsWith("/") + "webservices");
}
}

View File

@@ -533,6 +533,18 @@ namespace Umbraco.Core.Models
/// <param name="propertyGroupName">Name of the <see cref="PropertyGroup"/> to remove</param>
public void RemovePropertyGroup(string propertyGroupName)
{
// if no group exists with that name, do nothing
var group = PropertyGroups[propertyGroupName];
if (group == null) return;
// re-assign the group's properties to no group
foreach (var property in group.PropertyTypes)
{
property.PropertyGroupId = new Lazy<int>(() => 0);
_propertyTypes.Add(property);
}
// actually remove the group
PropertyGroups.RemoveItem(propertyGroupName);
OnPropertyChanged(PropertyGroupCollectionSelector);
}

View File

@@ -64,7 +64,7 @@ namespace Umbraco.Core.Models
[IgnoreDataMember]
public CultureInfo CultureInfo
{
get { return CultureInfo.CreateSpecificCulture(IsoCode); }
get { return CultureInfo.GetCultureInfo(IsoCode); }
}
}
}

View File

@@ -11,7 +11,7 @@ namespace Umbraco.Core.Models.Rdbms
internal class MigrationDto
{
[Column("id")]
[PrimaryKeyColumn(AutoIncrement = true)]
[PrimaryKeyColumn(AutoIncrement = true, IdentitySeed = 100)]
public int Id { get; set; }
[Column("name")]

View File

@@ -0,0 +1,38 @@
using System.Collections.Concurrent;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Rdbms;
namespace Umbraco.Core.Persistence.Mappers
{
/// <summary>
/// Represents a <see cref="TaskType"/> to DTO mapper used to translate the properties of the public api
/// implementation to that of the database's DTO as sql: [tableName].[columnName].
/// </summary>
[MapperFor(typeof(TaskType))]
public sealed class TaskTypeMapper : BaseMapper
{
private static readonly ConcurrentDictionary<string, DtoMapModel> PropertyInfoCacheInstance = new ConcurrentDictionary<string, DtoMapModel>();
//NOTE: its an internal class but the ctor must be public since we're using Activator.CreateInstance to create it
// otherwise that would fail because there is no public constructor.
public TaskTypeMapper()
{
BuildMap();
}
#region Overrides of BaseMapper
internal override ConcurrentDictionary<string, DtoMapModel> PropertyInfoCache
{
get { return PropertyInfoCacheInstance; }
}
internal override void BuildMap()
{
CacheMap<TaskType, TaskTypeDto>(src => src.Id, dto => dto.Id);
CacheMap<TaskType, TaskTypeDto>(src => src.Alias, dto => dto.Alias);
}
#endregion
}
}

View File

@@ -108,7 +108,7 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
_database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = -21, Trashed = false, ParentId = -1, UserId = 0, Level = 0, Path = "-1,-21", SortOrder = 0, UniqueId = new Guid("BF7C7CBC-952F-4518-97A2-69E9C7B33842"), Text = "Recycle Bin", NodeObjectType = new Guid(Constants.ObjectTypes.MediaRecycleBin), CreateDate = DateTime.Now });
_database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = -92, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,-92", SortOrder = 35, UniqueId = new Guid("f0bc4bfb-b499-40d6-ba86-058885a5178c"), Text = "Label", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now });
_database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = -90, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,-90", SortOrder = 34, UniqueId = new Guid("84c6b441-31df-4ffe-b67e-67d5bc3ae65a"), Text = "Upload", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now });
_database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = -89, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,-89", SortOrder = 33, UniqueId = new Guid("c6bac0dd-4ab9-45b1-8e30-e4b619ee5da3"), Text = "Textbox multiple", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now });
_database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = -89, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,-89", SortOrder = 33, UniqueId = new Guid("c6bac0dd-4ab9-45b1-8e30-e4b619ee5da3"), Text = "Textarea", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now });
_database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = -88, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,-88", SortOrder = 32, UniqueId = new Guid("0cc0eba1-9960-42c9-bf9b-60e150b429ae"), Text = "Textstring", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now });
_database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = -87, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,-87", SortOrder = 4, UniqueId = new Guid("ca90c950-0aff-4e72-b976-a30b1ac57dad"), Text = "Richtext editor", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now });
_database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = -51, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,-51", SortOrder = 2, UniqueId = new Guid("2e6d3631-066e-44b8-aec4-96f09099b2b5"), Text = "Numeric", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now });

View File

@@ -0,0 +1,34 @@
using Umbraco.Core.Configuration;
using Umbraco.Core.Logging;
using Umbraco.Core.Models.Rdbms;
using Umbraco.Core.Persistence.SqlSyntax;
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenThreeTwo
{
/// <summary>
/// This reinserts all migrations in the migrations table to account for initial rows inserted
/// on creation without identity enabled.
/// </summary>
[Migration("7.3.2", 0, GlobalSettings.UmbracoMigrationName)]
public class EnsureMigrationsTableIdentityIsCorrect : MigrationBase
{
public EnsureMigrationsTableIdentityIsCorrect(ISqlSyntaxProvider sqlSyntax, ILogger logger) : base(sqlSyntax, logger)
{
}
public override void Up()
{
Delete.FromTable("umbracoMigration").AllRows();
var migrations = Context.Database.Fetch<MigrationDto>(new Sql().Select("*").From<MigrationDto>(SqlSyntax));
foreach (var migration in migrations)
{
Insert.IntoTable("umbracoMigration")
.Row(new {name = migration.Name, createDate = migration.CreateDate, version = migration.Version});
}
}
public override void Down()
{
}
}
}

View File

@@ -297,7 +297,7 @@ namespace Umbraco.Core.Persistence.Repositories
//If there's a GetAll zero count cache, ensure it is cleared
RuntimeCache.ClearCacheItem(GetCacheTypeKey<TEntity>());
}
catch (Exception)
catch (Exception ex)
{
//if an exception is thrown we need to remove the entry from cache, this is ONLY a work around because of the way
// that we cache entities: http://issues.umbraco.org/issue/U4-4259

View File

@@ -682,14 +682,16 @@ namespace Umbraco.Core.Persistence.Repositories
public RenderingEngine DetermineTemplateRenderingEngine(ITemplate template)
{
var engine = _templateConfig.DefaultRenderingEngine;
if (template.Content.IsNullOrWhiteSpace() == false && MasterPageHelper.IsMasterPageSyntax(template.Content))
var viewHelper = new ViewHelper(_viewsFileSystem);
if (!viewHelper.ViewExists(template))
{
//there is a design but its definitely a webforms design
return RenderingEngine.WebForms;
if (template.Content.IsNullOrWhiteSpace() == false && MasterPageHelper.IsMasterPageSyntax(template.Content))
{
//there is a design but its definitely a webforms design and we haven't got a MVC view already for it
return RenderingEngine.WebForms;
}
}
var viewHelper = new ViewHelper(_viewsFileSystem);
var masterPageHelper = new MasterPageHelper(_masterpagesFileSystem);
switch (engine)

View File

@@ -117,7 +117,7 @@ namespace Umbraco.Core.Persistence
public override void OnException(Exception x)
{
_logger.Info<UmbracoDatabase>(x.StackTrace);
_logger.Error<UmbracoDatabase>("Database exception occurred", x);
base.OnException(x);
}

View File

@@ -152,6 +152,9 @@ namespace Umbraco.Core.Services
{
var contentType = FindContentTypeByAlias(contentTypeAlias);
var content = new Content(name, parentId, contentType);
var parent = GetById(content.ParentId);
content.Path = string.Concat(parent.IfNotNull(x => x.Path, content.ParentId.ToString()), ",", content.Id);
if (Creating.IsRaisedEventCancelled(new NewEventArgs<IContent>(content, contentTypeAlias, parentId), this))
{
@@ -190,8 +193,11 @@ namespace Umbraco.Core.Services
/// <returns><see cref="IContent"/></returns>
public IContent CreateContent(string name, IContent parent, string contentTypeAlias, int userId = 0)
{
if (parent == null) throw new ArgumentNullException("parent");
var contentType = FindContentTypeByAlias(contentTypeAlias);
var content = new Content(name, parent, contentType);
content.Path = string.Concat(parent.Path, ",", content.Id);
if (Creating.IsRaisedEventCancelled(new NewEventArgs<IContent>(content, contentTypeAlias, parent), this))
{
@@ -225,7 +231,7 @@ namespace Umbraco.Core.Services
public IContent CreateContentWithIdentity(string name, int parentId, string contentTypeAlias, int userId = 0)
{
var contentType = FindContentTypeByAlias(contentTypeAlias);
var content = new Content(name, parentId, contentType);
var content = new Content(name, parentId, contentType);
//NOTE: I really hate the notion of these Creating/Created events - they are so inconsistent, I've only just found
// out that in these 'WithIdentity' methods, the Saving/Saved events were not fired, wtf. Anyways, they're added now.
@@ -276,6 +282,8 @@ namespace Umbraco.Core.Services
/// <returns><see cref="IContent"/></returns>
public IContent CreateContentWithIdentity(string name, IContent parent, string contentTypeAlias, int userId = 0)
{
if (parent == null) throw new ArgumentNullException("parent");
var contentType = FindContentTypeByAlias(contentTypeAlias);
var content = new Content(name, parent, contentType);

View File

@@ -63,6 +63,8 @@ namespace Umbraco.Core.Services
{
var mediaType = FindMediaTypeByAlias(mediaTypeAlias);
var media = new Models.Media(name, parentId, mediaType);
var parent = GetById(media.ParentId);
media.Path = string.Concat(parent.IfNotNull(x => x.Path, media.ParentId.ToString()), ",", media.Id);
if (Creating.IsRaisedEventCancelled(new NewEventArgs<IMedia>(media, mediaTypeAlias, parentId), this))
{
@@ -95,8 +97,12 @@ namespace Umbraco.Core.Services
/// <returns><see cref="IMedia"/></returns>
public IMedia CreateMedia(string name, IMedia parent, string mediaTypeAlias, int userId = 0)
{
if (parent == null) throw new ArgumentNullException("parent");
var mediaType = FindMediaTypeByAlias(mediaTypeAlias);
var media = new Models.Media(name, parent, mediaType);
media.Path = string.Concat(parent.Path, ",", media.Id);
if (Creating.IsRaisedEventCancelled(new NewEventArgs<IMedia>(media, mediaTypeAlias, parent), this))
{
media.WasCancelled = true;
@@ -184,6 +190,8 @@ namespace Umbraco.Core.Services
/// <returns><see cref="IMedia"/></returns>
public IMedia CreateMediaWithIdentity(string name, IMedia parent, string mediaTypeAlias, int userId = 0)
{
if (parent == null) throw new ArgumentNullException("parent");
var mediaType = FindMediaTypeByAlias(mediaTypeAlias);
var media = new Models.Media(name, parent, mediaType);

View File

@@ -0,0 +1,51 @@
using System.Globalization;
using System.Threading;
namespace Umbraco.Core
{
static class ThreadExtensions
{
public static void SanitizeThreadCulture(this Thread thread)
{
// get the current culture
var currentCulture = CultureInfo.CurrentCulture;
// at the top of any culture should be the invariant culture - find it
// doing an .Equals comparison ensure that we *will* find it and not loop
// endlessly
var invariantCulture = currentCulture;
while (invariantCulture.Equals(CultureInfo.InvariantCulture) == false)
invariantCulture = invariantCulture.Parent;
// now that invariant culture should be the same object as CultureInfo.InvariantCulture
// yet for some reasons, sometimes it is not - and this breaks anything that loops on
// culture.Parent until a reference equality to CultureInfo.InvariantCulture. See, for
// example, the following code in PerformanceCounterLib.IsCustomCategory:
//
// CultureInfo culture = CultureInfo.CurrentCulture;
// while (culture != CultureInfo.InvariantCulture)
// {
// library = GetPerformanceCounterLib(machine, culture);
// if (library.IsCustomCategory(category))
// return true;
// culture = culture.Parent;
// }
//
// The reference comparisons never succeeds, hence the loop never ends, and the
// application hangs.
//
// granted, that comparison should probably be a .Equals comparison, but who knows
// how many times the framework assumes that it can do a reference comparison? So,
// better fix the cultures.
if (ReferenceEquals(invariantCulture, CultureInfo.InvariantCulture))
return;
// if we do not have equality, fix cultures by replacing them with a culture with
// the same name, but obtained here and now, with a proper invariant top culture
thread.CurrentCulture = CultureInfo.GetCultureInfo(thread.CurrentCulture.Name);
thread.CurrentUICulture = CultureInfo.GetCultureInfo(thread.CurrentUICulture.Name);
}
}
}

View File

@@ -86,7 +86,7 @@
</Reference>
<Reference Include="MySql.Data">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\MySql.Data.6.9.7\lib\net45\MySql.Data.dll</HintPath>
<HintPath>..\packages\MySql.Data.6.9.8\lib\net45\MySql.Data.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.6.0.8\lib\net45\Newtonsoft.Json.dll</HintPath>
@@ -404,6 +404,8 @@
<Compile Include="Persistence\Mappers\AccessMapper.cs" />
<Compile Include="Persistence\Mappers\DomainMapper.cs" />
<Compile Include="Persistence\Mappers\MigrationEntryMapper.cs" />
<Compile Include="Persistence\Mappers\TaskTypeMapper.cs" />
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSevenThreeTwo\EnsureMigrationsTableIdentityIsCorrect.cs" />
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSevenThreeZero\AddExternalLoginsTable.cs" />
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSevenThreeZero\AddForeignKeysForLanguageAndDictionaryTables.cs" />
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSevenThreeZero\AddServerRegistrationColumnsAndLock.cs" />
@@ -1278,6 +1280,7 @@
<Compile Include="Sync\ApplicationUrlHelper.cs" />
<Compile Include="Sync\RefreshMethodType.cs" />
<Compile Include="Sync\ServerMessengerBase.cs" />
<Compile Include="ThreadExtensions.cs" />
<Compile Include="TopologicalSorter.cs" />
<Compile Include="Strings\DefaultUrlSegmentProvider.cs" />
<Compile Include="Strings\IUrlSegmentProvider.cs" />

View File

@@ -2,6 +2,7 @@
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Web;
using System.Web.Hosting;
using log4net;
@@ -64,6 +65,7 @@ namespace Umbraco.Core
/// <param name="e"></param>
protected void Application_Start(object sender, EventArgs e)
{
Thread.CurrentThread.SanitizeThreadCulture();
StartApplication(sender, e);
}

View File

@@ -14,7 +14,7 @@
<package id="Microsoft.Owin.Security.Cookies" version="3.0.1" targetFramework="net45" />
<package id="Microsoft.Owin.Security.OAuth" version="3.0.1" targetFramework="net45" />
<package id="MiniProfiler" version="2.1.0" targetFramework="net45" />
<package id="MySql.Data" version="6.9.7" targetFramework="net45" />
<package id="MySql.Data" version="6.9.8" targetFramework="net45" />
<package id="Newtonsoft.Json" version="6.0.8" targetFramework="net45" />
<package id="Owin" version="1.0" targetFramework="net45" />
<package id="semver" version="1.1.2" targetFramework="net45" />

View File

@@ -56,7 +56,7 @@
<appSettings>
<add key="umbracoConfigurationStatus" value="6.0.0" />
<add key="umbracoReservedUrls" value="~/config/splashes/booting.aspx,~/install/default.aspx,~/config/splashes/noNodes.aspx,~/VSEnterpriseHelper.axd" />
<add key="umbracoReservedPaths" value="~/umbraco,~/install/" />
<add key="umbracoReservedPaths" value="~/install/" />
<add key="umbracoPath" value="~/umbraco" />
<add key="umbracoHideTopLevelNodeFromPath" value="true" />
<add key="umbracoUseDirectoryUrls" value="false" />
@@ -203,4 +203,4 @@
</assemblyBinding>
</runtime>
</configuration>
</configuration>

View File

@@ -28,7 +28,7 @@
</control>
</tab>
<tab caption="Examine Management">
<control>/umbraco/dashboard/ExamineManagement.ascx</control>
<control>dashboard/ExamineManagement.ascx</control>
</tab>
</section>
@@ -85,7 +85,7 @@
</control>
</tab>
<tab caption="Last Edits">
<control addPanel="true" MaxRecords="30">/umbraco/dashboard/latestEdits.ascx</control>
<control addPanel="true" MaxRecords="30">dashboard/latestEdits.ascx</control>
</tab>
<tab caption="Change Password">
<control addPanel="true">
@@ -104,11 +104,11 @@
views/dashboard/members/membersdashboardintro.html
</control>
<control showOnce="true" addPanel="true" panelCaption="">
/umbraco/members/membersearch.ascx
members/membersearch.ascx
</control>
<control showOnce="true" addPanel="true" panelCaption="">
views/dashboard/members/membersdashboardvideos.html
</control>
</tab>
</section>
</dashBoard>
</dashBoard>

View File

@@ -482,7 +482,7 @@ ALTER TABLE umbracoUser2NodePermission ADD CONSTRAINT PK_umbracoUser2NodePermiss
INSERT INTO umbracoNode (id, trashed, parentID, nodeUser, level, path, sortOrder, uniqueID, text, nodeObjectType, createDate) VALUES
(-92, 0, -1, 0, 11, '-1,-92', 37, 'f0bc4bfb-b499-40d6-ba86-058885a5178c', 'Label', '30a2a501-1978-4ddb-a57b-f7efed43ba3c', '2004/09/30 14:01:49.920'),
(-90, 0, -1, 0, 11, '-1,-90', 35, '84c6b441-31df-4ffe-b67e-67d5bc3ae65a', 'Upload', '30a2a501-1978-4ddb-a57b-f7efed43ba3c', '2004/09/30 14:01:49.920'),
(-89, 0, -1, 0, 11, '-1,-89', 34, 'c6bac0dd-4ab9-45b1-8e30-e4b619ee5da3', 'Textbox multiple', '30a2a501-1978-4ddb-a57b-f7efed43ba3c', '2004/09/30 14:01:49.920'),
(-89, 0, -1, 0, 11, '-1,-89', 34, 'c6bac0dd-4ab9-45b1-8e30-e4b619ee5da3', 'Textarea', '30a2a501-1978-4ddb-a57b-f7efed43ba3c', '2004/09/30 14:01:49.920'),
(-88, 0, -1, 0, 11, '-1,-88', 33, '0cc0eba1-9960-42c9-bf9b-60e150b429ae', 'Textstring', '30a2a501-1978-4ddb-a57b-f7efed43ba3c', '2004/09/30 14:01:49.920'),
(-87, 0, -1, 0, 11, '-1,-87', 32, 'ca90c950-0aff-4e72-b976-a30b1ac57dad', 'Richtext editor', '30a2a501-1978-4ddb-a57b-f7efed43ba3c', '2004/09/30 14:01:49.920'),
(-51, 0, -1, 0, 11, '-1,-51', 4, '2e6d3631-066e-44b8-aec4-96f09099b2b5', 'Numeric', '30a2a501-1978-4ddb-a57b-f7efed43ba3c', '2004/09/30 14:01:49.920'),

View File

@@ -624,7 +624,7 @@ ALTER TABLE [umbracoNode] DROP CONSTRAINT [FK_umbracoNode_umbracoNode]
SET IDENTITY_INSERT [umbracoNode] ON
INSERT INTO [umbracoNode] ([id], [trashed], [parentID], [nodeUser], [level], [path], [sortOrder], [uniqueID], [text], [nodeObjectType], [createDate]) VALUES (-92, 0, -1, 0, 11, N'-1,-92', 37, 'f0bc4bfb-b499-40d6-ba86-058885a5178c', N'Label', '30a2a501-1978-4ddb-a57b-f7efed43ba3c', '20040930 14:01:49.920')
INSERT INTO [umbracoNode] ([id], [trashed], [parentID], [nodeUser], [level], [path], [sortOrder], [uniqueID], [text], [nodeObjectType], [createDate]) VALUES (-90, 0, -1, 0, 11, N'-1,-90', 35, '84c6b441-31df-4ffe-b67e-67d5bc3ae65a', N'Upload', '30a2a501-1978-4ddb-a57b-f7efed43ba3c', '20040930 14:01:49.920')
INSERT INTO [umbracoNode] ([id], [trashed], [parentID], [nodeUser], [level], [path], [sortOrder], [uniqueID], [text], [nodeObjectType], [createDate]) VALUES (-89, 0, -1, 0, 11, N'-1,-89', 34, 'c6bac0dd-4ab9-45b1-8e30-e4b619ee5da3', N'Textbox multiple', '30a2a501-1978-4ddb-a57b-f7efed43ba3c', '20040930 14:01:49.920')
INSERT INTO [umbracoNode] ([id], [trashed], [parentID], [nodeUser], [level], [path], [sortOrder], [uniqueID], [text], [nodeObjectType], [createDate]) VALUES (-89, 0, -1, 0, 11, N'-1,-89', 34, 'c6bac0dd-4ab9-45b1-8e30-e4b619ee5da3', N'Textarea', '30a2a501-1978-4ddb-a57b-f7efed43ba3c', '20040930 14:01:49.920')
INSERT INTO [umbracoNode] ([id], [trashed], [parentID], [nodeUser], [level], [path], [sortOrder], [uniqueID], [text], [nodeObjectType], [createDate]) VALUES (-88, 0, -1, 0, 11, N'-1,-88', 33, '0cc0eba1-9960-42c9-bf9b-60e150b429ae', N'Textstring', '30a2a501-1978-4ddb-a57b-f7efed43ba3c', '20040930 14:01:49.920')
INSERT INTO [umbracoNode] ([id], [trashed], [parentID], [nodeUser], [level], [path], [sortOrder], [uniqueID], [text], [nodeObjectType], [createDate]) VALUES (-87, 0, -1, 0, 11, N'-1,-87', 32, 'ca90c950-0aff-4e72-b976-a30b1ac57dad', N'Richtext editor', '30a2a501-1978-4ddb-a57b-f7efed43ba3c', '20040930 14:01:49.920')
INSERT INTO [umbracoNode] ([id], [trashed], [parentID], [nodeUser], [level], [path], [sortOrder], [uniqueID], [text], [nodeObjectType], [createDate]) VALUES (-51, 0, -1, 0, 11, N'-1,-51', 4, '2e6d3631-066e-44b8-aec4-96f09099b2b5', N'Numeric', '30a2a501-1978-4ddb-a57b-f7efed43ba3c', '20040930 14:01:49.920')

View File

@@ -268,7 +268,7 @@ namespace Umbraco.Tests.Plugins
public void Resolves_Assigned_Mappers()
{
var foundTypes1 = _manager.ResolveAssignedMapperTypes();
Assert.AreEqual(27, foundTypes1.Count());
Assert.AreEqual(28, foundTypes1.Count());
}
[Test]

View File

@@ -141,6 +141,20 @@ namespace Umbraco.Tests.Services
Assert.AreEqual(20, contentService.CountDescendants(parent.Id));
}
[Test]
public void GetAncestors_Returns_Empty_List_When_Path_Is_Null()
{
// Arrange
var contentService = ServiceContext.ContentService;
// Act
var current = new Mock<IContent>();
var res = contentService.GetAncestors(current.Object);
// Assert
Assert.IsEmpty(res);
}
[Test]
public void Tags_For_Entity_Are_Not_Exposed_Via_Tag_Api_When_Content_Is_Recycled()
{

View File

@@ -1168,6 +1168,8 @@ namespace Umbraco.Tests.Services
{
var service = ServiceContext.ContentTypeService;
var basePage = (IContentType)MockedContentTypes.CreateBasicContentType();
basePage.AddPropertyGroup("Content");
basePage.AddPropertyGroup("Meta");
service.Save(basePage);
var authorPropertyType = new PropertyType(Constants.PropertyEditors.TextboxAlias, DataTypeDatabaseType.Ntext, "author")
@@ -1179,6 +1181,16 @@ namespace Umbraco.Tests.Services
DataTypeDefinitionId = -88
};
var authorAdded = basePage.AddPropertyType(authorPropertyType, "Content");
var titlePropertyType = new PropertyType(Constants.PropertyEditors.TextboxAlias, DataTypeDatabaseType.Ntext, "title")
{
Name = "Title",
Description = "",
Mandatory = false,
SortOrder = 1,
DataTypeDefinitionId = -88
};
var titleAdded = basePage.AddPropertyType(authorPropertyType, "Meta");
service.Save(basePage);
basePage = service.GetContentType(basePage.Id);

View File

@@ -0,0 +1,109 @@
using Moq;
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Umbraco.Core;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Persistence.Repositories;
using Umbraco.Core.Persistence.SqlSyntax;
using Umbraco.Core.Persistence.UnitOfWork;
namespace Umbraco.Tests.Templates
{
[TestFixture]
public class TemplateRepositoryTests
{
private readonly Mock<IDatabaseUnitOfWork> _unitOfWorkMock = new Mock<IDatabaseUnitOfWork>();
private readonly Mock<CacheHelper> _cacheMock = new Mock<CacheHelper>();
private TemplateRepository _templateRepository;
private readonly Mock<IFileSystem> _viewFileSystemMock = new Mock<IFileSystem>();
private readonly Mock<IFileSystem> _masterpageFileSystemMock = new Mock<IFileSystem>();
private readonly Mock<ITemplatesSection> _templateConfigMock = new Mock<Core.Configuration.UmbracoSettings.ITemplatesSection>();
[SetUp]
public void Setup()
{
var loggerMock = new Mock<ILogger>();
var sqlSyntaxMock = new Mock<ISqlSyntaxProvider>();
_templateRepository = new TemplateRepository(_unitOfWorkMock.Object, _cacheMock.Object, loggerMock.Object, sqlSyntaxMock.Object, _masterpageFileSystemMock.Object, _viewFileSystemMock.Object, _templateConfigMock.Object);
}
[Test]
public void DetermineTemplateRenderingEngine_Returns_MVC_When_ViewFile_Exists_And_Content_Has_Webform_Markup()
{
// Project in MVC mode
_templateConfigMock.Setup(x => x.DefaultRenderingEngine).Returns(RenderingEngine.Mvc);
// Template has masterpage content
var templateMock = new Mock<ITemplate>();
templateMock.Setup(x => x.Alias).Returns("Something");
templateMock.Setup(x => x.Content).Returns("<asp:Content />");
// but MVC View already exists
_viewFileSystemMock.Setup(x => x.FileExists(It.IsAny<string>())).Returns(true);
var res = _templateRepository.DetermineTemplateRenderingEngine(templateMock.Object);
Assert.AreEqual(RenderingEngine.Mvc, res);
}
[Test]
public void DetermineTemplateRenderingEngine_Returns_WebForms_When_ViewFile_Doesnt_Exist_And_Content_Has_Webform_Markup()
{
// Project in MVC mode
_templateConfigMock.Setup(x => x.DefaultRenderingEngine).Returns(RenderingEngine.Mvc);
// Template has masterpage content
var templateMock = new Mock<ITemplate>();
templateMock.Setup(x => x.Alias).Returns("Something");
templateMock.Setup(x => x.Content).Returns("<asp:Content />");
// MVC View doesn't exist
_viewFileSystemMock.Setup(x => x.FileExists(It.IsAny<string>())).Returns(false);
var res = _templateRepository.DetermineTemplateRenderingEngine(templateMock.Object);
Assert.AreEqual(RenderingEngine.WebForms, res);
}
[Test]
public void DetermineTemplateRenderingEngine_Returns_WebForms_When_MasterPage_Exists_And_In_Mvc_Mode()
{
// Project in MVC mode
_templateConfigMock.Setup(x => x.DefaultRenderingEngine).Returns(RenderingEngine.Mvc);
var templateMock = new Mock<ITemplate>();
templateMock.Setup(x => x.Alias).Returns("Something");
// but masterpage already exists
_viewFileSystemMock.Setup(x => x.FileExists(It.IsAny<string>())).Returns(false);
_masterpageFileSystemMock.Setup(x => x.FileExists(It.IsAny<string>())).Returns(true);
var res = _templateRepository.DetermineTemplateRenderingEngine(templateMock.Object);
Assert.AreEqual(RenderingEngine.WebForms, res);
}
[Test]
public void DetermineTemplateRenderingEngine_Returns_Mvc_When_ViewPage_Exists_And_In_Webforms_Mode()
{
// Project in WebForms mode
_templateConfigMock.Setup(x => x.DefaultRenderingEngine).Returns(RenderingEngine.WebForms);
var templateMock = new Mock<ITemplate>();
templateMock.Setup(x => x.Alias).Returns("Something");
// but MVC View already exists
_viewFileSystemMock.Setup(x => x.FileExists(It.IsAny<string>())).Returns(true);
_masterpageFileSystemMock.Setup(x => x.FileExists(It.IsAny<string>())).Returns(false);
var res = _templateRepository.DetermineTemplateRenderingEngine(templateMock.Object);
Assert.AreEqual(RenderingEngine.Mvc, res);
}
}
}

View File

@@ -361,6 +361,7 @@
<Compile Include="Services\MacroServiceTests.cs" />
<Compile Include="Services\UserServiceTests.cs" />
<Compile Include="Manifest\ManifestParserTests.cs" />
<Compile Include="Templates\TemplateRepositoryTests.cs" />
<Compile Include="TestHelpers\BaseSeleniumTest.cs" />
<Compile Include="Integration\InstallPackage.cs" />
<Compile Include="CoreXml\NavigableNavigatorTests.cs" />

View File

@@ -24,7 +24,7 @@ var app = angular.module("Umbraco.canvasdesigner", ['colorpicker', 'ui.slider',
];
$scope.previewDevice = $scope.devices[0];
var apiController = "/Umbraco/Api/Canvasdesigner/";
var apiController = "../Api/Canvasdesigner/";
/*****************************************************************************/
/* Preview devices */
@@ -40,7 +40,7 @@ var app = angular.module("Umbraco.canvasdesigner", ['colorpicker', 'ui.slider',
/*****************************************************************************/
$scope.exitPreview = function () {
window.top.location.href = "/umbraco/endPreview.aspx?redir=%2f" + $scope.pageId;
window.top.location.href = "../endPreview.aspx?redir=%2f" + $scope.pageId;
};
/*****************************************************************************/

View File

@@ -2,9 +2,9 @@
<html lang="en">
<head>
<title>Umbraco Canvas Designer</title>
<link href="/Umbraco/assets/css/canvasdesigner.css" type="text/css" rel="stylesheet" />
<link href="/Umbraco/lib/spectrum/spectrum.css" type="text/css" rel="stylesheet" />
<link href="/Umbraco/lib/jquery-ui/jquery-ui-1.10.4.custom.min.css" type="text/css" rel="stylesheet" />
<link href="../assets/css/canvasdesigner.css" type="text/css" rel="stylesheet" />
<link href="../lib/spectrum/spectrum.css" type="text/css" rel="stylesheet" />
<link href="../lib/jquery-ui/jquery-ui-1.10.4.custom.min.css" type="text/css" rel="stylesheet" />
</head>
<body id="canvasdesignerPanel" ng-mouseover="outlinePositionHide()" ng-class="{ leftOpen: (showStyleEditor || showPalettePicker) && !showDevicesPreview }" ng-controller="Umbraco.canvasdesignerController">
@@ -20,7 +20,7 @@
<div class="fix-left-menu selected">
<div class="avatar">
<img ng-src="/umbraco/assets/img/application/logo.png">
<img ng-src="../assets/img/application/logo.png">
</div>
<ul class="sections" ng-class="{selected: showDevicesPreview}">
@@ -125,7 +125,7 @@
<div class="canvasdesigner-panel-container" ng-show="categoriesVisibility[category] === true">
<div class="canvasdesigner-panel-property" ng-repeat="item in configItem.editors" ng-show="item.category == category">
<h5>{{item.name}} <i class="icon icon-help-alt"></i></h5>
<div ng-include="'/Umbraco/preview/editors/' + item.type + '.html'"></div>
<div ng-include="'../preview/editors/' + item.type + '.html'"></div>
</div>
</div>
</div>
@@ -154,8 +154,8 @@
<p>Styles saved and published</p>
</div>
<script src="/umbraco/lib/rgrove-lazyload/lazyload.js"></script>
<script src="/umbraco/js/canvasdesigner.loader.js"></script>
<script src="../lib/rgrove-lazyload/lazyload.js"></script>
<script src="../js/canvasdesigner.loader.js"></script>
</body>

View File

@@ -56,7 +56,7 @@ angular.module("umbraco.directives")
if(scope.configuration && scope.configuration.stylesheets){
angular.forEach(scope.configuration.stylesheets, function(stylesheet, key){
stylesheets.push("/css/" + stylesheet + ".css");
stylesheets.push(Umbraco.Sys.ServerVariables.umbracoSettings.cssPath + "/" + stylesheet + ".css");
await.push(stylesheetResource.getRulesByName(stylesheet).then(function (rules) {
angular.forEach(rules, function (rule) {
var r = {};

View File

@@ -94,14 +94,24 @@ function sectionsDirective($timeout, $window, navigationService, treeService, se
navigationService.showHelpDialog();
};
scope.sectionClick = function (section) {
scope.sectionClick = function (event, section) {
if (event.ctrlKey ||
event.shiftKey ||
event.metaKey || // apple
(event.button && event.button === 1) // middle click, >IE9 + everyone else
) {
return;
}
if (navigationService.userDialog) {
navigationService.userDialog.close();
}
if (navigationService.helpDialog) {
navigationService.helpDialog.close();
}
navigationService.hideSearch();
navigationService.showTree(section.alias);
$location.path("/" + section.alias);

View File

@@ -38,9 +38,9 @@ angular.module("umbraco.directives")
'<div ng-class="getNodeCssClass(node)" ng-swipe-right="options(node, $event)" >' +
//NOTE: This ins element is used to display the search icon if the node is a container/listview and the tree is currently in dialog
//'<ins ng-if="tree.enablelistviewsearch && node.metaData.isContainer" class="umb-tree-node-search icon-search" ng-click="searchNode(node, $event)" alt="searchAltText"></ins>' +
'<ins ng-class="{\'icon-navigation-right\': !node.expanded, \'icon-navigation-down\': node.expanded}" ng-click="load(node)"></ins>' +
'<i class="icon umb-tree-icon sprTree"></i>' +
'<a ng-click="select(node, $event)"></a>' +
'<ins ng-class="{\'icon-navigation-right\': !node.expanded, \'icon-navigation-down\': node.expanded}" ng-click="load(node)">&nbsp;</ins>' +
'<i class="icon umb-tree-icon sprTree" ng-click="select(node, $event)"></i>' +
'<a href="#/{{node.routePath}}" ng-click="select(node, $event)"></a>' +
//NOTE: These are the 'option' elipses
'<a class="umb-options" ng-click="options(node, $event)"><i></i><i></i><i></i></a>' +
'<div ng-show="node.loading" class="l"><div></div></div>' +
@@ -148,8 +148,17 @@ angular.module("umbraco.directives")
and emits it as a treeNodeSelect element if there is a callback object
defined on the tree
*/
scope.select = function(n, ev) {
scope.select = function (n, ev) {
if (ev.ctrlKey ||
ev.shiftKey ||
ev.metaKey || // apple
(ev.button && ev.button === 1) // middle click, >IE9 + everyone else
) {
return;
}
emitEvent("treeNodeSelect", { element: element, tree: scope.tree, node: n, event: ev });
ev.preventDefault();
};
/**

View File

@@ -1,5 +1,5 @@
/**
* @description Utillity directives for key and field events
* @description Utility directives for key and field events
**/
angular.module('umbraco.directives')

View File

@@ -4,7 +4,9 @@ angular.module("umbraco.directives").directive('focusWhen', function ($timeout)
link: function (scope, elm, attrs, ctrl) {
attrs.$observe("focusWhen", function (newValue) {
if (newValue === "true") {
elm.focus();
$timeout(function() {
elm.focus();
});
}
});
}

View File

@@ -17,9 +17,9 @@ angular.module("umbraco.install").factory('installerService', function($rootScop
//add to umbraco installer facts here
var facts = ['Umbraco helped millions of people watch a man jump from the edge of space',
'Over 250.000 websites are currently powered by Umbraco',
'Over 300 000 websites are currently powered by Umbraco',
"At least 2 people have named their cat 'Umbraco'",
'On an average day, more than 1.000 people download Umbraco',
'On an average day, more than 1000 people download Umbraco',
'<a target="_blank" href="http://umbraco.tv">umbraco.tv</a> is the premier source of Umbraco video tutorials to get you started',
'You can find the world\'s friendliest CMS community at <a target="_blank" href="http://our.umbraco.org">our.umbraco.org</a>',
'You can become a certified Umbraco developer by attending one of the official courses',
@@ -31,7 +31,7 @@ angular.module("umbraco.install").factory('installerService', function($rootScop
"At least 4 people have the Umbraco logo tattooed on them",
"'Umbraco' is the danish name for an allen key",
"Umbraco has been around since 2005, that's a looong time in IT",
"More than 400 people from all over the world meet each year in Denmark in June for our annual conference <a target='_blank' href='http://codegarden14.com'>CodeGarden</a>",
"More than 400 people from all over the world meet each year in Denmark in June for our annual conference <a target='_blank' href='http://codegarden15.com'>CodeGarden</a>",
"While you are installing Umbraco someone else on the other side of the planet is probably doing it too",
"You can extend Umbraco without modifying the source code and using either JavaScript or C#"
];

View File

@@ -2,8 +2,8 @@
/******* font-face *******/
@font-face {
src: url('/Umbraco/assets/fonts/helveticons/helveticons.eot') !important;
src: url('/Umbraco/assets/fonts/helveticons/helveticons.eot?#iefix') format('embedded-opentype'), url('/Umbraco/assets/fonts/helveticons/helveticons.ttf') format('truetype'), url('/Umbraco/assets/fonts/helveticons/helveticons.svg#icomoon') format('svg') !important;
src: url('assets/fonts/helveticons/helveticons.eot') !important;
src: url('assets/fonts/helveticons/helveticons.eot?#iefix') format('embedded-opentype'), url('assets/fonts/helveticons/helveticons.ttf') format('truetype'), url('assets/fonts/helveticons/helveticons.svg#icomoon') format('svg') !important;
}
/****************************/

View File

@@ -155,7 +155,7 @@ body {
}
#speechbubble {
z-index: 1000;
z-index: 1060;
position: absolute;
bottom: 100px;
left: 0;
@@ -266,4 +266,4 @@ body {
margin-left: 40px;
width: 85%!important;
}
}
}

View File

@@ -148,6 +148,11 @@ h5{
padding-top: 5px;
margin-left: 240px;
}
.umb-user-panel .controls-row {
margin-left: 0px;
}
.controls-row label {
display: inline-block
}
@@ -525,4 +530,4 @@ height:1px;
margin: 10px 0;
overflow: hidden;
}
}

View File

@@ -153,6 +153,7 @@
border-radius: @tabsBorderRadius;
box-shadow: none;
padding: 0;
z-index: 6020;
}
.umb-btn-toolbar .dropdown-menu small {

View File

@@ -37,7 +37,7 @@
<li class="span2" ng-repeat="video in videos">
<div class="thumbnail" style="margin-right: 20px">
<a target="_blank" href="{{video.link}}?utm_source=core&utm_medium=help&utm_content=link&utm_campaign=tv" title="{{video.title}}">
<img ng-src="{{video.thumbnail}}" alt="{{video.title}}">
<img ng-src="{{video.thumbnail}}?width=120" alt="{{video.title}}">
</a>
</div>
</li>

View File

@@ -34,11 +34,12 @@ angular.module("umbraco")
$scope.submitFolder = function(e) {
if (e.keyCode === 13) {
e.preventDefault();
$scope.showFolderInput = false;
mediaResource
.addFolder($scope.newFolderName, $scope.options.formData.currentFolder)
.then(function(data) {
$scope.showFolderInput = false;
$scope.newFolderName = "";
//we've added a new folder so lets clear the tree cache for that specific item
treeService.clearCache({
@@ -80,7 +81,7 @@ angular.module("umbraco")
$scope.options.formData.currentFolder = folder.id;
$scope.currentFolder = folder;
};
//This executes prior to the whole processing which we can use to get the UI going faster,
//this also gives us the start callback to invoke to kick of the whole thing
$scope.$on('fileuploadadd', function (e, data) {

View File

@@ -103,7 +103,8 @@
ng-show="showFolderInput"
ng-model="newFolderName"
ng-keydown="submitFolder($event)"
on-blur="showFolderInput = false">
on-blur="showFolderInput = false"
focus-when="{{showFolderInput}}">
</li>
</ul>
</div>

View File

@@ -1,5 +1,5 @@
angular.module("umbraco")
.controller("Umbraco.Dialogs.UserController", function ($scope, $location, $timeout, userService, historyService, eventsService, externalLoginInfo, authResource) {
.controller("Umbraco.Dialogs.UserController", function ($scope, $location, $timeout, userService, historyService, eventsService, externalLoginInfo, authResource, currentUserResource, formHelper) {
$scope.history = historyService.getCurrent();
$scope.version = Umbraco.Sys.ServerVariables.application.version + " assembly: " + Umbraco.Sys.ServerVariables.application.assemblyVersion;
@@ -102,4 +102,44 @@ angular.module("umbraco")
});
});
//create the initial model for change password property editor
$scope.changePasswordModel = {
alias: "_umb_password",
view: "changepassword",
config: {},
value: {}
};
//go get the config for the membership provider and add it to the model
currentUserResource.getMembershipProviderConfig().then(function (data) {
$scope.changePasswordModel.config = data;
//ensure the hasPassword config option is set to true (the user of course has a password already assigned)
//this will ensure the oldPassword is shown so they can change it
$scope.changePasswordModel.config.hasPassword = true;
$scope.changePasswordModel.config.disableToggle = true;
});
////this is the model we will pass to the service
//$scope.profile = {};
$scope.changePassword = function () {
if (formHelper.submitForm({ scope: $scope })) {
currentUserResource.changePassword($scope.changePasswordModel.value).then(function (data) {
//if the password has been reset, then update our model
if (data.value) {
$scope.changePasswordModel.value.generatedPassword = data.value;
}
formHelper.resetForm({ scope: $scope, notifications: data.notifications });
}, function (err) {
formHelper.handleError(err);
});
}
};
});

View File

@@ -18,18 +18,25 @@
<div class="umb-panel-body umb-scrollable">
<div class="tab-content umb-control-group">
<div class="umb-pane" ng-if="canEditProfile">
<div class="umb-pane">
<h5><localize key="user_yourProfile" /></h5>
<p>
<a href="#/users/framed/%252Fumbraco%252Fusers%252Fedituser.aspx%253Fid%253D{{user.id}}"
<a href="#/users/framed/users%252Fedituser.aspx%253Fid%253D{{user.id}}"
class="btn btn-primary"
ng-click="close()">
ng-click="close()" ng-if="canEditProfile">
<localize key="general_edit">Edit</localize>
</a>
<a href
class="btn"
ng-click="showChangePassword = showChangePassword === true ? false : true;" ng-init="showChangePassword = false;">
<localize key="user_newPassword">Change password</localize>
</a>
</p>
</div>
<div class="umb-pane external-logins" ng-if="externalLoginProviders.length > 0">
<h5>External login providers</h5>
@@ -63,6 +70,24 @@
</div>
<div class="umb-pane" ng-if="showChangePassword">
<form novalidate name="passwordForm"
ng-controller="Umbraco.Dashboard.StartupChangePasswordController"
ng-submit="changePassword()"
val-form-manager>
<h3><localize key="user_changePassword">Change password</localize></h3>
<umb-editor model="changePasswordModel"></umb-editor>
<umb-control-group hideLabel="1">
<button class="btn btn-primary"><localize key="user_change">Change</localize></button>
<!-- Could not get the button to change the showChangePassword scope variable to hide the form again... -->
<!--<button class="btn"><localize key="general_cancel" ng-click="showChangePassword = false;">Cancel</localize></button>-->
</umb-control-group>
</form>
</div>
<div class="umb-pane">
<h5><localize key="user_yourHistory" /></h5>
<ul class="umb-tree">
@@ -78,4 +103,4 @@
<small class="umb-version">Umbraco version {{version}}</small>
</div>
</div>
</div>

View File

@@ -3,15 +3,16 @@
ng-submit="changePassword()"
val-form-manager>
<h3>Change password</h3>
<h3><localize key="user_changePassword">Change password</localize></h3>
<umb-pane>
<umb-editor model="changePasswordModel"></umb-editor>
<umb-control-group hideLabel="1">
<button class="btn btn-primary">Change</button>
<button class="btn btn-primary">
<localize key="user_change">Change</localize>
</button>
</umb-control-group>
</umb-pane>
</form>

View File

@@ -9,7 +9,7 @@
<li ng-repeat="section in sections | limitTo: maxSections" ng-class="{current: section.alias == currentSection}">
<a href="#/{{section.alias}}"
ng-dblclick="sectionDblClick(section)"
ng-click="sectionClick(section)"
ng-click="sectionClick($event, section)"
prevent-default>
<section-icon icon="{{section.cssclass}}"></section-icon>
<span>{{section.name}}</span>
@@ -36,9 +36,9 @@
<li ng-repeat="section in sections | limitTo: overflowingSections" ng-class="{current: section.alias == currentSection}">
<a href="#/{{section.alias}}"
ng-dblclick="sectionDblClick(section)"
ng-click="sectionClick(section)"
ng-click="sectionClick($event, section)"
prevent-default>
<section-icon icon="{{section.cssclass}}"></section-icon>
<section-icon icon="{{section.cssclass}}"></section-icon>
<span>{{section.name}}</span>
</a>
</li>

View File

@@ -1,7 +1,7 @@
//this controller simply tells the dialogs service to open a mediaPicker window
//with a specified callback, this callback will receive an object with a selection on it
function contentPickerController($scope, dialogService, entityResource, editorState, $log, iconHelper, $routeParams, fileManager, contentEditingHelper) {
function contentPickerController($scope, dialogService, entityResource, editorState, $log, iconHelper, $routeParams, fileManager, contentEditingHelper, angularHelper) {
function trim(str, chr) {
var rgxtrim = (!chr) ? new RegExp('^\\s+|\\s+$', 'g') : new RegExp('^' + chr + '+|' + chr + '+$', 'g');
@@ -49,7 +49,8 @@ function contentPickerController($scope, dialogService, entityResource, editorSt
//the default pre-values
var defaultConfig = {
multiPicker: false,
showEditButton: false,
showEditButton: false,
showPathOnHover: false,
startNode: {
query: "",
type: "content",
@@ -65,6 +66,7 @@ function contentPickerController($scope, dialogService, entityResource, editorSt
//Umbraco persists boolean for prevalues as "0" or "1" so we need to convert that!
$scope.model.config.multiPicker = ($scope.model.config.multiPicker === "1" ? true : false);
$scope.model.config.showEditButton = ($scope.model.config.showEditButton === "1" ? true : false);
$scope.model.config.showPathOnHover = ($scope.model.config.showPathOnHover === "1" ? true : false);
var entityType = $scope.model.config.startNode.type === "member"
? "Member"
@@ -87,6 +89,7 @@ function contentPickerController($scope, dialogService, entityResource, editorSt
$scope.clear();
$scope.add(data);
}
angularHelper.getCurrentForm($scope).$setDirty();
},
treeAlias: $scope.model.config.startNode.type,
section: $scope.model.config.startNode.type
@@ -141,6 +144,7 @@ function contentPickerController($scope, dialogService, entityResource, editorSt
$scope.remove = function (index) {
$scope.renderModel.splice(index, 1);
angularHelper.getCurrentForm($scope).$setDirty();
};
$scope.add = function (item) {
@@ -150,7 +154,7 @@ function contentPickerController($scope, dialogService, entityResource, editorSt
if (currIds.indexOf(item.id) < 0) {
item.icon = iconHelper.convertFromLegacyIcon(item.icon);
$scope.renderModel.push({ name: item.name, id: item.id, icon: item.icon });
$scope.renderModel.push({ name: item.name, id: item.id, icon: item.icon, path: item.path });
}
};
@@ -182,7 +186,7 @@ function contentPickerController($scope, dialogService, entityResource, editorSt
if (entity) {
entity.icon = iconHelper.convertFromLegacyIcon(entity.icon);
$scope.renderModel.push({ name: entity.name, id: entity.id, icon: entity.icon });
$scope.renderModel.push({ name: entity.name, id: entity.id, icon: entity.icon, path: entity.path });
}

View File

@@ -5,11 +5,8 @@
<ul class="unstyled list-icons"
ui-sortable
ng-model="renderModel">
<li ng-repeat="node in renderModel">
<li ng-repeat="node in renderModel" ng-attr-title="{{model.config.showPathOnHover && 'Path: ' + node.path || undefined}}">
<i class="icon icon-navigation handle"></i>
<a href="#" prevent-default ng-click="remove($index)">
<i class="icon icon-delete red hover-show"></i>
<i class="{{node.icon}} hover-hide"></i>

View File

@@ -1,7 +1,7 @@
//this controller simply tells the dialogs service to open a mediaPicker window
//with a specified callback, this callback will receive an object with a selection on it
angular.module('umbraco').controller("Umbraco.PropertyEditors.MediaPickerController",
function ($rootScope, $scope, dialogService, entityResource, mediaResource, mediaHelper, $timeout, userService) {
function ($rootScope, $scope, dialogService, entityResource, mediaResource, mediaHelper, $timeout, userService, angularHelper) {
//check the pre-values for multi-picker
var multiPicker = $scope.model.config.multiPicker && $scope.model.config.multiPicker !== '0' ? true : false;
@@ -54,6 +54,7 @@ angular.module('umbraco').controller("Umbraco.PropertyEditors.MediaPickerControl
$scope.remove = function(index) {
$scope.images.splice(index, 1);
$scope.ids.splice(index, 1);
angularHelper.getCurrentForm($scope).$setDirty();
$scope.sync();
};
@@ -76,6 +77,7 @@ angular.module('umbraco').controller("Umbraco.PropertyEditors.MediaPickerControl
$scope.images.push(media);
$scope.ids.push(media.id);
angularHelper.getCurrentForm($scope).$setDirty();
});
$scope.sync();

View File

@@ -1,6 +1,6 @@
//this controller simply tells the dialogs service to open a memberPicker window
//with a specified callback, this callback will receive an object with a selection on it
function memberPickerController($scope, dialogService, entityResource, $log, iconHelper){
function memberPickerController($scope, dialogService, entityResource, $log, iconHelper, angularHelper){
function trim(str, chr) {
var rgxtrim = (!chr) ? new RegExp('^\\s+|\\s+$', 'g') : new RegExp('^' + chr + '+|' + chr + '+$', 'g');
@@ -27,6 +27,7 @@ function memberPickerController($scope, dialogService, entityResource, $log, ico
$scope.clear();
$scope.add(data);
}
angularHelper.getCurrentForm($scope).$setDirty();
}
};

View File

@@ -64,8 +64,7 @@ angular.module("umbraco")
//queue rules loading
angular.forEach(editorConfig.stylesheets, function (val, key) {
stylesheets.push("../css/" + val + ".css?" + new Date().getTime());
stylesheets.push(Umbraco.Sys.ServerVariables.umbracoSettings.cssPath + "/" + val + ".css?" + new Date().getTime());
await.push(stylesheetResource.getRulesByName(val).then(function (rules) {
angular.forEach(rules, function (rule) {
var r = {};

View File

@@ -190,7 +190,7 @@
</Reference>
<Reference Include="MySql.Data">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\MySql.Data.6.9.7\lib\net45\MySql.Data.dll</HintPath>
<HintPath>..\packages\MySql.Data.6.9.8\lib\net45\MySql.Data.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.6.0.8\lib\net45\Newtonsoft.Json.dll</HintPath>
@@ -2413,7 +2413,7 @@ xcopy "$(ProjectDir)"..\packages\SqlServerCE.4.0.0.0\x86\*.* "$(TargetDir)x86\"
<AutoAssignPort>True</AutoAssignPort>
<DevelopmentServerPort>7310</DevelopmentServerPort>
<DevelopmentServerVPath>/</DevelopmentServerVPath>
<IISUrl>http://localhost:7310</IISUrl>
<IISUrl>http://localhost:7320</IISUrl>
<NTLMAuthentication>False</NTLMAuthentication>
<UseCustomServer>False</UseCustomServer>
<CustomServerUrl>

View File

@@ -75,13 +75,16 @@ else
@if (registerModel.MemberProperties != null)
{
@*
It will only displays properties marked as "Member can edit" on the "Info" tab of the Member Type.
*@
for (var i = 0; i < registerModel.MemberProperties.Count; i++)
{
@Html.LabelFor(m => registerModel.MemberProperties[i].Value, registerModel.MemberProperties[i].Name)
@*
By default this will render a textbox but if you want to change the editor template for this property you can
@*
By default this will render a textbox but if you want to change the editor template for this property you can
easily change it. For example, if you wanted to render a custom editor for this field called "MyEditor" you would
create a file at ~/Views/Shared/EditorTemplates/MyEditor.cshtml", then you will change the next line of code to
create a file at ~/Views/Shared/EditorTemplates/MyEditor.cshtml", then you will change the next line of code to
render your specific editor template like:
@Html.EditorFor(m => profileModel.MemberProperties[i].Value, "MyEditor")
*@

View File

@@ -75,11 +75,6 @@
views/dashboard/default/startupdashboardintro.html
</control>
</tab>
<tab caption="Change Password">
<control showOnce="false" addPanel="false" panelCaption="">
views/dashboard/ChangePassword.html
</control>
</tab>
</section>
<section alias="StartupMemberDashboardSection">
<areas>
@@ -96,7 +91,7 @@
<area>contour</area>
</areas>
<tab caption="Dashboard">
<control>/umbraco/plugins/umbracocontour/formsdashboard.ascx</control>
<control>plugins/umbracocontour/formsdashboard.ascx</control>
</tab>
</section>
</dashBoard>
</dashBoard>

View File

@@ -213,6 +213,7 @@
<plugin loadOnFrontend="true">charmap</plugin>
<plugin loadOnFrontend="true">table</plugin>
<plugin loadOnFrontend="true">lists</plugin>
<plugin loadOnFrontend="true">hr</plugin>
</plugins>
<validElements>
<![CDATA[+a[id|style|rel|data-id|rev|charset|hreflang|dir|lang|tabindex|accesskey|type|name|href|target|title|class|onfocus|onblur|onclick|

View File

@@ -213,6 +213,7 @@
<plugin loadOnFrontend="true">charmap</plugin>
<plugin loadOnFrontend="true">table</plugin>
<plugin loadOnFrontend="true">lists</plugin>
<plugin loadOnFrontend="true">hr</plugin>
</plugins>
<validElements>
<![CDATA[+a[id|style|rel|data-id|rev|charset|hreflang|dir|lang|tabindex|accesskey|type|name|href|target|title|class|onfocus|onblur|onclick|

View File

@@ -27,7 +27,7 @@
<package id="Microsoft.Owin.Security.OAuth" version="3.0.1" targetFramework="net45" />
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net45" />
<package id="MiniProfiler" version="2.1.0" targetFramework="net45" />
<package id="MySql.Data" version="6.9.7" targetFramework="net45" />
<package id="MySql.Data" version="6.9.8" targetFramework="net45" />
<package id="Newtonsoft.Json" version="6.0.8" targetFramework="net45" />
<package id="Owin" version="1.0" targetFramework="net45" />
<package id="SharpZipLib" version="0.86.0" targetFramework="net45" />

View File

@@ -52,6 +52,7 @@
</head>
<noscript><h5><strong>&nbsp; JavaScript is disabled. Please enable to continue!</strong></h5></noscript>
<body ng-class="{touch:touchDevice,emptySection:emptySection}" ng-controller="Umbraco.MainController" id="umbracoMainPageBody">
<div ng-hide="!authenticated" ng-cloak id="mainwrapper" id="mainwrapper" class="clearfix" ng-click="closeDialogs($event)">

View File

@@ -923,6 +923,7 @@ Mange hilsner fra Umbraco robotten
<key alias="userTypes">Brugertyper</key>
<key alias="writer">Forfatter</key>
<key alias="translator">Oversætter</key>
<key alias="change">Skift</key>
<key alias="yourProfile">Din profil</key>
<key alias="yourHistory">Din historik</key>
<key alias="sessionExpires">Session udløber</key>

View File

@@ -1057,6 +1057,7 @@ To manage your website, simply open the Umbraco back office and start adding con
<key alias="userTypes">User types</key>
<key alias="writer">Writer</key>
<key alias="translator">Translator</key>
<key alias="change">Change</key>
<key alias="yourProfile" version="7.0">Your profile</key>
<key alias="yourHistory" version="7.0">Your recent history</key>
<key alias="sessionExpires" version="7.0">Session expires in</key>

View File

@@ -1055,6 +1055,7 @@ To manage your website, simply open the Umbraco back office and start adding con
<key alias="userTypes">User types</key>
<key alias="writer">Writer</key>
<key alias="translator">Translator</key>
<key alias="change">Change</key>
<key alias="yourProfile" version="7.0">Your profile</key>
<key alias="yourHistory" version="7.0">Your recent history</key>
<key alias="sessionExpires" version="7.0">Session expires in</key>

View File

@@ -985,6 +985,7 @@ Om een vertalingstaak te sluiten, ga aub naar het detailoverzicht en klik op de
<key alias="usertype">Gebruikerstype</key>
<key alias="userTypes">Gebruikerstypes</key>
<key alias="writer">Auteur</key>
<key alias="change">Wijzig</key>
<key alias="yourProfile" version="7.0">Je profiel</key>
<key alias="yourHistory" version="7.0">Je recente historie</key>

View File

@@ -28,8 +28,8 @@
table.relations td.DataType {}
/* direction icons */
table.relations td.parentToChild { background-image: url('/umbraco/developer/RelationTypes/Images/ParentToChild.png'); }
table.relations td.bidirectional { background-image: url('/umbraco/developer/RelationTypes/Images/Bidirectional.png'); }
table.relations td.parentToChild { background-image: url('../../developer/RelationTypes/Images/ParentToChild.png'); }
table.relations td.bidirectional { background-image: url('../../developer/RelationTypes/Images/Bidirectional.png'); }
</style>
<script type="text/javascript">
@@ -144,4 +144,4 @@
</umb:Pane>
</asp:Content>
</asp:Content>

View File

@@ -3,7 +3,7 @@
if (confirm('Are you sure you want to delete "' + relationTypeName + '"?')) {
$.ajax({
type: "POST",
url: "/umbraco/developer/RelationTypes/RelationTypesWebService.asmx/DeleteRelationType",
url: "developer/RelationTypes/RelationTypesWebService.asmx/DeleteRelationType",
data: "{ 'relationTypeId' : '" + relationTypeId + "' }",
contentType: "application/json; charset=utf-8",
dataType: "json",

View File

@@ -341,6 +341,7 @@ namespace Umbraco.Web.Editors
string.Join(",", UmbracoConfig.For.UmbracoSettings().Content.ImageFileTypes)
},
{"keepUserLoggedIn", UmbracoConfig.For.UmbracoSettings().Security.KeepUserLoggedIn},
{"cssPath", IOHelper.ResolveUrl(SystemDirectories.Css).TrimEnd('/')},
}
},
{
@@ -758,12 +759,29 @@ namespace Umbraco.Web.Editors
//Ensure the forms auth module doesn't do a redirect!
context.HttpContext.Response.SuppressFormsAuthenticationRedirect = true;
var owinCtx = context.HttpContext.GetOwinContext();
//First, see if a custom challenge result callback is specified for the provider
// and use it instead of the default if one is supplied.
var loginProvider = owinCtx.Authentication
.GetExternalAuthenticationTypes()
.FirstOrDefault(p => p.AuthenticationType == LoginProvider);
if (loginProvider != null)
{
var providerChallengeResult = loginProvider.GetSignInChallengeResult(owinCtx);
if (providerChallengeResult != null)
{
owinCtx.Authentication.Challenge(providerChallengeResult, LoginProvider);
return;
}
}
var properties = new AuthenticationProperties() { RedirectUri = RedirectUri.EnsureEndsWith('/') };
if (UserId != null)
{
properties.Dictionary[XsrfKey] = UserId;
}
context.HttpContext.GetOwinContext().Authentication.Challenge(properties, LoginProvider);
owinCtx.Authentication.Challenge(properties, LoginProvider);
}
}
}

View File

@@ -6,6 +6,7 @@ using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Web.Http;
using System.Web.Http.ModelBinding;
using System.Web.Security;
@@ -284,6 +285,9 @@ namespace Umbraco.Web.Editors
case ContentSaveAction.SaveNew:
MembershipCreateStatus status;
CreateWithMembershipProvider(contentItem, out status);
// save the ID of the creator
contentItem.PersistedContent.CreatorId = Security.CurrentUser.Id;
break;
default:
//we don't support anything else for members

View File

@@ -1,6 +1,7 @@
using System.ComponentModel.DataAnnotations;
using System.Runtime.Serialization;
using Umbraco.Core;
using Umbraco.Core.Configuration;
using Umbraco.Core.IO;
namespace Umbraco.Web.Models.ContentEditing
@@ -47,8 +48,8 @@ namespace Umbraco.Web.Models.ContentEditing
get
{
return IconIsClass
? string.Empty
: IOHelper.ResolveUrl("~/umbraco/images/umbraco/" + Icon);
? string.Empty
: string.Format("{0}images/umbraco/{1}", GlobalSettings.Path.EnsureEndsWith("/"), Icon);
}
}
@@ -83,4 +84,4 @@ namespace Umbraco.Web.Models.ContentEditing
}
}
}
}
}

View File

@@ -2,6 +2,7 @@
using Umbraco.Core.IO;
using System.Collections.Generic;
using Umbraco.Core;
using Umbraco.Core.Configuration;
using Umbraco.Web.Models.ContentEditing;
namespace Umbraco.Web.Models.Trees
@@ -109,7 +110,7 @@ namespace Umbraco.Web.Models.Trees
return IOHelper.ResolveUrl("~" + Icon.TrimStart('~'));
//legacy icon path
return IOHelper.ResolveUrl("~/umbraco/images/umbraco/" + Icon);
return string.Format("{0}images/umbraco/{1}", GlobalSettings.Path.EnsureEndsWith("/"), Icon);
}
}

View File

@@ -13,7 +13,8 @@ namespace Umbraco.Web.PropertyEditors
_internalPreValues = new Dictionary<string, object>
{
{"showEditButton", "0"},
{"startNodeId", "-1"}
{"startNodeId", "-1"},
{"showPathOnHover", "0"}
};
}
@@ -37,6 +38,8 @@ namespace Umbraco.Web.PropertyEditors
[PreValueField("startNodeId", "Start node", "treepicker")]
public int StartNodeId { get; set; }
[PreValueField("showPathOnHover", "Show path when hovering items", "boolean")]
public bool ShowPathOnHover { get; set; }
}
}
}

View File

@@ -44,8 +44,6 @@ namespace Umbraco.Web.Routing
response.Write("<p>This page can be replaced with a custom 404. Check the documentation for \"custom 404\".</p>");
response.Write("<p style=\"border-top: 1px solid #ccc; padding-top: 10px\"><small>This page is intentionally left ugly ;-)</small></p>");
response.Write("</body></html>");
response.End();
}
public bool IsReusable

View File

@@ -70,7 +70,7 @@ namespace Umbraco.Web.Scheduling
try
{
var result = await wc.SendAsync(request, token);
var result = await wc.SendAsync(request, token).ConfigureAwait(false); // ConfigureAwait(false) is recommended? http://blog.stephencleary.com/2012/07/dont-block-on-async-code.html
return result.StatusCode == HttpStatusCode.OK;
}
catch (Exception ex)

View File

@@ -195,46 +195,7 @@ namespace Umbraco.Web.Security.Identity
public static void SanitizeThreadCulture(this IAppBuilder app)
{
// get the current culture
var currentCulture = CultureInfo.CurrentCulture;
// at the top of any culture should be the invariant culture - find it
// doing an .Equals comparison ensure that we *will* find it and not loop
// endlessly
var invariantCulture = currentCulture;
while (invariantCulture.Equals(CultureInfo.InvariantCulture) == false)
invariantCulture = invariantCulture.Parent;
// now that invariant culture should be the same object as CultureInfo.InvariantCulture
// yet for some reasons, sometimes it is not - and this breaks anything that loops on
// culture.Parent until a reference equality to CultureInfo.InvariantCulture. See, for
// example, the following code in PerformanceCounterLib.IsCustomCategory:
//
// CultureInfo culture = CultureInfo.CurrentCulture;
// while (culture != CultureInfo.InvariantCulture)
// {
// library = GetPerformanceCounterLib(machine, culture);
// if (library.IsCustomCategory(category))
// return true;
// culture = culture.Parent;
// }
//
// The reference comparisons never succeeds, hence the loop never ends, and the
// application hangs.
//
// granted, that comparison should probably be a .Equals comparison, but who knows
// how many times the framework assumes that it can do a reference comparison? So,
// better fix the cultures.
if (ReferenceEquals(invariantCulture, CultureInfo.InvariantCulture))
return;
// if we do not have equality, fix cultures by replacing them with a culture with
// the same name, but obtained here and now, with a proper invariant top culture
var thread = Thread.CurrentThread;
thread.CurrentCulture = CultureInfo.GetCultureInfo(thread.CurrentCulture.Name);
thread.CurrentUICulture = CultureInfo.GetCultureInfo(thread.CurrentUICulture.Name);
Thread.CurrentThread.SanitizeThreadCulture();
}
}
}

View File

@@ -1,3 +1,4 @@
using System;
using Microsoft.Owin;
using Microsoft.Owin.Security;
using Umbraco.Core;
@@ -7,6 +8,22 @@ namespace Umbraco.Web.Security.Identity
{
public static class AuthenticationOptionsExtensions
{
public static void SetSignInChallengeResultCallback(
this AuthenticationOptions authOptions,
Func<IOwinContext, AuthenticationProperties> authProperties)
{
authOptions.Description.Properties["ChallengeResultCallback"] = authProperties;
}
public static AuthenticationProperties GetSignInChallengeResult(this AuthenticationDescription authenticationDescription, IOwinContext ctx)
{
if (authenticationDescription.Properties.ContainsKey("ChallengeResultCallback") == false) return null;
var cb = authenticationDescription.Properties["ChallengeResultCallback"] as Func<IOwinContext, AuthenticationProperties>;
if (cb == null) return null;
return cb(ctx);
}
/// <summary>
/// Used during the External authentication process to assign external sign-in options
/// that are used by the Umbraco authentication process.

View File

@@ -47,7 +47,7 @@ namespace Umbraco.Web.Trees
language.Id.ToString(CultureInfo.InvariantCulture), "-1", queryStrings, language.CultureInfo.DisplayName, "icon-flag-alt", false,
//TODO: Rebuild the language editor in angular, then we dont need to have this at all (which is just a path to the legacy editor)
"/" + queryStrings.GetValue<string>("application") + "/framed/" +
Uri.EscapeDataString("/umbraco/settings/editLanguage.aspx?id=" + language.Id)));
Uri.EscapeDataString("settings/editLanguage.aspx?id=" + language.Id)));
}
}
@@ -96,4 +96,4 @@ namespace Umbraco.Web.Trees
return menu;
}
}
}
}

View File

@@ -131,9 +131,9 @@ namespace Umbraco.Web.Trees
return Services.FileService.DetermineTemplateRenderingEngine(template) == RenderingEngine.WebForms
? "/" + queryStrings.GetValue<string>("application") + "/framed/" +
Uri.EscapeDataString("/umbraco/settings/editTemplate.aspx?templateID=" + template.Id)
Uri.EscapeDataString("settings/editTemplate.aspx?templateID=" + template.Id)
: "/" + queryStrings.GetValue<string>("application") + "/framed/" +
Uri.EscapeDataString("/umbraco/settings/Views/EditView.aspx?treeType=" + Constants.Trees.Templates + "&templateID=" + template.Id);
Uri.EscapeDataString("settings/Views/EditView.aspx?treeType=" + Constants.Trees.Templates + "&templateID=" + template.Id);
}
}
}
}

View File

@@ -62,60 +62,51 @@ namespace umbraco
else
{
// Loop through XML children we need to find the fields recursive
if (helper.FindAttribute(attributes, "recursive") == "true")
var recursive = helper.FindAttribute(attributes, "recursive") == "true";
if (publishedContent == null)
{
if (publishedContent == null)
{
var recursiveVal = GetRecursiveValueLegacy(elements);
_fieldContent = recursiveVal.IsNullOrWhiteSpace() ? _fieldContent : recursiveVal;
}
else
{
var pval = publishedContent.GetPropertyValue(_fieldName, true);
var rval = pval == null ? string.Empty : pval.ToString();
_fieldContent = rval.IsNullOrWhiteSpace() ? _fieldContent : rval;
}
var recursiveVal = GetRecursiveValueLegacy(elements);
_fieldContent = recursiveVal.IsNullOrWhiteSpace() ? _fieldContent : recursiveVal;
}
//check for published content and get its value using that
if (publishedContent != null && (publishedContent.HasProperty(_fieldName) || recursive))
{
var pval = publishedContent.GetPropertyValue(_fieldName, recursive);
var rval = pval == null ? string.Empty : pval.ToString();
_fieldContent = rval.IsNullOrWhiteSpace() ? _fieldContent : rval;
}
else
{
//check for published content and get its value using that
if (publishedContent != null && publishedContent.HasProperty(_fieldName))
{
var pval = publishedContent.GetPropertyValue(_fieldName);
var rval = pval == null ? string.Empty : pval.ToString();
_fieldContent = rval.IsNullOrWhiteSpace() ? _fieldContent : rval;
}
else
{
//get the vaue the legacy way (this will not parse locallinks, etc... since that is handled with ipublishedcontent)
var elt = elements[_fieldName];
if (elt != null && string.IsNullOrEmpty(elt.ToString()) == false)
_fieldContent = elt.ToString().Trim();
}
//now we check if the value is still empty and if so we'll check useIfEmpty
if (string.IsNullOrEmpty(_fieldContent))
{
var altFieldName = helper.FindAttribute(attributes, "useIfEmpty");
if (string.IsNullOrEmpty(altFieldName) == false)
{
if (publishedContent != null && publishedContent.HasProperty(altFieldName))
{
var pval = publishedContent.GetPropertyValue(altFieldName);
var rval = pval == null ? string.Empty : pval.ToString();
_fieldContent = rval.IsNullOrWhiteSpace() ? _fieldContent : rval;
}
else
{
//get the vaue the legacy way (this will not parse locallinks, etc... since that is handled with ipublishedcontent)
var elt = elements[altFieldName];
if (elt != null && string.IsNullOrEmpty(elt.ToString()) == false)
_fieldContent = elt.ToString().Trim();
}
}
}
//get the vaue the legacy way (this will not parse locallinks, etc... since that is handled with ipublishedcontent)
var elt = elements[_fieldName];
if (elt != null && string.IsNullOrEmpty(elt.ToString()) == false)
_fieldContent = elt.ToString().Trim();
}
//now we check if the value is still empty and if so we'll check useIfEmpty
if (string.IsNullOrEmpty(_fieldContent))
{
var altFieldName = helper.FindAttribute(attributes, "useIfEmpty");
if (string.IsNullOrEmpty(altFieldName) == false)
{
if (publishedContent != null && (publishedContent.HasProperty(altFieldName) || recursive))
{
var pval = publishedContent.GetPropertyValue(altFieldName, recursive);
var rval = pval == null ? string.Empty : pval.ToString();
_fieldContent = rval.IsNullOrWhiteSpace() ? _fieldContent : rval;
}
else
{
//get the vaue the legacy way (this will not parse locallinks, etc... since that is handled with ipublishedcontent)
var elt = elements[altFieldName];
if (elt != null && string.IsNullOrEmpty(elt.ToString()) == false)
_fieldContent = elt.ToString().Trim();
}
}
}
}
ParseItem(attributes);

View File

@@ -1475,7 +1475,8 @@ jQuery(document).ready(function() {{ refreshDropDowns(); }});
var propertyGroup = _contentType.ContentTypeItem.PropertyGroups.FirstOrDefault(x => x.Id == propertyGroupId);
if (propertyGroup != null && string.IsNullOrEmpty(propertyGroup.Name) == false)
{
_contentType.ContentTypeItem.PropertyGroups.Remove(propertyGroup.Name);
// use RemovePropertyGroup so properties become generic
_contentType.ContentTypeItem.RemovePropertyGroup(propertyGroup.Name);
_contentType.Save();
}
//}

View File

@@ -63,7 +63,7 @@ namespace umbraco.cms.presentation.developer.RelationTypes
var newRelationTypeId = relationService.GetRelationTypeByAlias(newRelationTypeAlias).Id;
ClientTools.ChangeContentFrameUrl("/umbraco/developer/RelationTypes/EditRelationType.aspx?id=" + newRelationTypeId).CloseModalWindow().ChildNodeCreated();
ClientTools.ChangeContentFrameUrl("developer/RelationTypes/EditRelationType.aspx?id=" + newRelationTypeId).CloseModalWindow().ChildNodeCreated();
}
}
@@ -87,4 +87,4 @@ namespace umbraco.cms.presentation.developer.RelationTypes
dropDownList.Items.Add(new ListItem(UmbracoObjectTypes.RecycleBin.GetFriendlyName(), Umbraco.Core.Constants.ObjectTypes.ContentRecycleBin));
}
}
}
}

View File

@@ -67,7 +67,7 @@ namespace umbraco.cms.presentation.developer.RelationTypes.TreeMenu
/// </summary>
public string JsSource
{
get { return "~/umbraco/developer/RelationTypes/TreeMenu/ActionDeleteRelationType.js"; }
get { return "developer/RelationTypes/TreeMenu/ActionDeleteRelationType.js"; }
}
/// <summary>

View File

@@ -67,7 +67,7 @@ namespace umbraco.cms.presentation.developer.RelationTypes.TreeMenu
/// </summary>
public string JsSource
{
get { return "~/umbraco/developer/RelationTypes/TreeMenu/ActionNewRelationType.js"; }
get { return "developer/RelationTypes/TreeMenu/ActionNewRelationType.js"; }
}
/// <summary>

View File

@@ -70,7 +70,7 @@ namespace umbraco.presentation.dialogs
// Translators
foreach (var u in BusinessLogic.User.getAll())
if (u.UserType.Alias.ToLower() == "translator")
if (u.UserType.Alias.ToLower() == "translator" || UserHasTranslatePermission(u, _currentPage))
translator.Items.Add(new ListItem(u.Name, u.Id.ToString()));
if (translator.Items.Count == 0) {
@@ -84,6 +84,12 @@ namespace umbraco.presentation.dialogs
}
}
private bool UserHasTranslatePermission(BusinessLogic.User u, CMSNode node)
{
//the permissions column in umbracoUserType is legacy and needs to be rewritten but for now this is the only way to test
return u.GetPermissions(node.Path).Contains("4");
}
protected void doTranslation_Click(object sender, EventArgs e)
{
// testing translate

View File

@@ -19,13 +19,15 @@ namespace umbraco.cms.businesslogic.translation
public static void MakeNew(CMSNode Node, User User, User Translator, Language Language, string Comment,
bool IncludeSubpages, bool SendEmail)
{
// Get translation taskType for obsolete task constructor
var taskType = ApplicationContext.Current.Services.TaskService.GetTaskTypeByAlias("toTranslate");
// Create pending task
Task t = new Task();
Task t = new Task(new Umbraco.Core.Models.Task(taskType));
t.Comment = Comment;
t.Node = Node;
t.ParentUser = User;
t.User = Translator;
t.Type = new TaskType("toTranslate");
t.Save();
// Add log entry

View File

@@ -2,5 +2,5 @@
<packages>
<package id="log4net-mediumtrust" version="2.0.0" targetFramework="net4" />
<package id="Microsoft.ApplicationBlocks.Data" version="1.0.1559.20655" targetFramework="net4" />
<package id="MySql.Data" version="6.9.7" targetFramework="net45" />
<package id="MySql.Data" version="6.9.8" targetFramework="net45" />
</packages>

View File

@@ -78,7 +78,7 @@
</Reference>
<Reference Include="MySql.Data">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\MySql.Data.6.9.7\lib\net45\MySql.Data.dll</HintPath>
<HintPath>..\packages\MySql.Data.6.9.8\lib\net45\MySql.Data.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Configuration" />

View File

@@ -42,7 +42,7 @@ namespace umbraco.editorControls.textfieldmultiple
public override string DataTypeName
{
get {return "Textbox multiple";}
get {return "Textarea";}
}
public override interfaces.IDataPrevalue PrevalueEditor