Compare commits
117 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 294452a6aa | |||
| fca74ad8d7 | |||
| 7bc7dba86d | |||
| ca75a25802 | |||
| ece31733a9 | |||
| 28a8027179 | |||
| a97604d6c4 | |||
| 308f929f7b | |||
| c8d7df1515 | |||
| 2c795662d2 | |||
| 8a43e3a87e | |||
| 210e43fcb0 | |||
| beb8c7ac7c | |||
| 2f8979bbc3 | |||
| a8ed7f2c17 | |||
| 1c6bf55e5d | |||
| c246044ac7 | |||
| 5126521d37 | |||
| 27223738c6 | |||
| 2faa4defd8 | |||
| bb8356d7db | |||
| 686f6752f3 | |||
| 66ff4d191a | |||
| 21218b0332 | |||
| 23ccdeb2cf | |||
| 6148ce4e52 | |||
| 06850ed25c | |||
| 0320a56cb5 | |||
| 968463912a | |||
| b9e44f381b | |||
| cd27bb210f | |||
| 67f680a675 | |||
| 47c3e3a79f | |||
| 02f49a0039 | |||
| 05c6b856f9 | |||
| b07df63422 | |||
| 487e45b45b | |||
| 929c84822a | |||
| 993f11cd2c | |||
| 6544b5c272 | |||
| 817a458334 | |||
| f3bfc1ffb2 | |||
| 3603090421 | |||
| 6fe3089207 | |||
| 79159b684d | |||
| 26d4d056be | |||
| 6ad28f1103 | |||
| 89cd655df2 | |||
| 14c4c4815d | |||
| bfb69a34ef | |||
| b675f6252c | |||
| d52420183e | |||
| 0cbe0b4796 | |||
| 06b136fdf6 | |||
| c6246b5404 | |||
| 3062f40ef5 | |||
| dcd0d38419 | |||
| 0feb053e51 | |||
| c01a8f8f13 | |||
| 09c8ae4e7e | |||
| da71a94c39 | |||
| f6413af3f4 | |||
| 2aaca865e7 | |||
| 77dda5a70f | |||
| 440e649d6d | |||
| f6a8d487cc | |||
| 47dcd37d1d | |||
| d60fc63e78 | |||
| b0c4042e87 | |||
| da525513a3 | |||
| 2ac5e61e44 | |||
| 101a8b6c78 | |||
| f7a10e3a15 | |||
| 4e0dd728a8 | |||
| 320ccf8105 | |||
| 62f924a757 | |||
| c47a08b553 | |||
| de9241bcf5 | |||
| 7c03fe3c1f | |||
| 82eb241119 | |||
| 1073e6257c | |||
| bc3e4847fe | |||
| 1a7251909c | |||
| 61a18297d9 | |||
| bdd413f9ee | |||
| fd8ca35e63 | |||
| fdd9aee773 | |||
| 59bf24c461 | |||
| 2748c3635d | |||
| 3c2a92d3b6 | |||
| cf49e6160a | |||
| 2252db0d55 | |||
| ec93030e21 | |||
| 1d49c8626e | |||
| 89bb94aa1a | |||
| 03a4b75176 | |||
| 943b54dcf7 | |||
| 39bd18ec1a | |||
| df896af476 | |||
| e93ddff46b | |||
| 3144b51c91 | |||
| e92f68d040 | |||
| 469054e9b3 | |||
| d17022d87d | |||
| 6865629090 | |||
| a4749f201d | |||
| ad90264ef1 | |||
| 9ba7e7742a | |||
| 6473f600c7 | |||
| 4b605b2580 | |||
| 80d7f1b2c9 | |||
| 6329dfa629 | |||
| 5ada85df29 | |||
| 2cd0173534 | |||
| a0bcfeddcc | |||
| c4b5483d8c | |||
| 7557c584d8 |
@@ -12,7 +12,7 @@ thoroughly. Then, proceed by filling out the rest of the details in the issue
|
||||
template below. The more details you can give us, the easier it will be for us
|
||||
to determine the cause of a problem.
|
||||
|
||||
See: https://github.com/umbraco/Umbraco-CMS/blob/dev-v7/.github/CONTRIBUTING.md
|
||||
See: https://github.com/umbraco/Umbraco-CMS/blob/v8/dev/.github/CONTRIBUTING.md
|
||||
|
||||
-->
|
||||
|
||||
|
||||
+2
-2
@@ -18,5 +18,5 @@ using System.Resources;
|
||||
[assembly: AssemblyVersion("8.0.0")]
|
||||
|
||||
// these are FYI and changed automatically
|
||||
[assembly: AssemblyFileVersion("8.1.0")]
|
||||
[assembly: AssemblyInformationalVersion("8.1.0")]
|
||||
[assembly: AssemblyFileVersion("8.2.0")]
|
||||
[assembly: AssemblyInformationalVersion("8.2.0")]
|
||||
|
||||
@@ -67,31 +67,34 @@ namespace Umbraco.Core
|
||||
: new NamedSemaphoreReleaser(_semaphore2);
|
||||
}
|
||||
|
||||
public Task<IDisposable> LockAsync()
|
||||
{
|
||||
var wait = _semaphore != null
|
||||
? _semaphore.WaitAsync()
|
||||
: _semaphore2.WaitOneAsync();
|
||||
//NOTE: We don't use the "Async" part of this lock at all
|
||||
//TODO: Remove this and rename this class something like SystemWideLock, then we can re-instate this logic if we ever need an Async lock again
|
||||
|
||||
return wait.IsCompleted
|
||||
? _releaserTask ?? Task.FromResult(CreateReleaser()) // anonymous vs named
|
||||
: wait.ContinueWith((_, state) => (((AsyncLock) state).CreateReleaser()),
|
||||
this, CancellationToken.None,
|
||||
TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);
|
||||
}
|
||||
//public Task<IDisposable> LockAsync()
|
||||
//{
|
||||
// var wait = _semaphore != null
|
||||
// ? _semaphore.WaitAsync()
|
||||
// : _semaphore2.WaitOneAsync();
|
||||
|
||||
public Task<IDisposable> LockAsync(int millisecondsTimeout)
|
||||
{
|
||||
var wait = _semaphore != null
|
||||
? _semaphore.WaitAsync(millisecondsTimeout)
|
||||
: _semaphore2.WaitOneAsync(millisecondsTimeout);
|
||||
// return wait.IsCompleted
|
||||
// ? _releaserTask ?? Task.FromResult(CreateReleaser()) // anonymous vs named
|
||||
// : wait.ContinueWith((_, state) => (((AsyncLock) state).CreateReleaser()),
|
||||
// this, CancellationToken.None,
|
||||
// TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);
|
||||
//}
|
||||
|
||||
return wait.IsCompleted
|
||||
? _releaserTask ?? Task.FromResult(CreateReleaser()) // anonymous vs named
|
||||
: wait.ContinueWith((_, state) => (((AsyncLock)state).CreateReleaser()),
|
||||
this, CancellationToken.None,
|
||||
TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);
|
||||
}
|
||||
//public Task<IDisposable> LockAsync(int millisecondsTimeout)
|
||||
//{
|
||||
// var wait = _semaphore != null
|
||||
// ? _semaphore.WaitAsync(millisecondsTimeout)
|
||||
// : _semaphore2.WaitOneAsync(millisecondsTimeout);
|
||||
|
||||
// return wait.IsCompleted
|
||||
// ? _releaserTask ?? Task.FromResult(CreateReleaser()) // anonymous vs named
|
||||
// : wait.ContinueWith((_, state) => (((AsyncLock)state).CreateReleaser()),
|
||||
// this, CancellationToken.None,
|
||||
// TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);
|
||||
//}
|
||||
|
||||
public IDisposable Lock()
|
||||
{
|
||||
|
||||
@@ -14,6 +14,23 @@ namespace Umbraco.Core
|
||||
/// </summary>
|
||||
public const string InternalGenericPropertiesPrefix = "_umb_";
|
||||
|
||||
public static class Legacy
|
||||
{
|
||||
public static class Aliases
|
||||
{
|
||||
public const string Textbox = "Umbraco.Textbox";
|
||||
public const string Date = "Umbraco.Date";
|
||||
public const string ContentPicker2 = "Umbraco.ContentPicker2";
|
||||
public const string MediaPicker2 = "Umbraco.MediaPicker2";
|
||||
public const string MemberPicker2 = "Umbraco.MemberPicker2";
|
||||
public const string MultiNodeTreePicker2 = "Umbraco.MultiNodeTreePicker2";
|
||||
public const string TextboxMultiple = "Umbraco.TextboxMultiple";
|
||||
public const string RelatedLinks2 = "Umbraco.RelatedLinks2";
|
||||
public const string RelatedLinks = "Umbraco.RelatedLinks";
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines Umbraco built-in property editor aliases.
|
||||
/// </summary>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Web.Hosting;
|
||||
@@ -113,7 +114,7 @@ namespace Umbraco.Core
|
||||
|
||||
lock (_locko)
|
||||
{
|
||||
_logger.Debug<MainDom>("Signaled {Signaled} ({SignalSource})", _signaled ? "(again)" : string.Empty, source);
|
||||
_logger.Debug<MainDom>("Signaled ({Signaled}) ({SignalSource})", _signaled ? "again" : "first", source);
|
||||
if (_signaled) return;
|
||||
if (_isMainDom == false) return; // probably not needed
|
||||
_signaled = true;
|
||||
@@ -171,6 +172,7 @@ namespace Umbraco.Core
|
||||
// if more than 1 instance reach that point, one will get the lock
|
||||
// and the other one will timeout, which is accepted
|
||||
|
||||
//TODO: This can throw a TimeoutException - in which case should this be in a try/finally to ensure the signal is always reset?
|
||||
_asyncLocker = _asyncLock.Lock(LockTimeoutMilliseconds);
|
||||
_isMainDom = true;
|
||||
|
||||
@@ -181,6 +183,9 @@ namespace Umbraco.Core
|
||||
// which is accepted
|
||||
|
||||
_signal.Reset();
|
||||
|
||||
//WaitOneAsync (ext method) will wait for a signal without blocking the main thread, the waiting is done on a background thread
|
||||
|
||||
_signal.WaitOneAsync()
|
||||
.ContinueWith(_ => OnSignal("signal"));
|
||||
|
||||
|
||||
@@ -19,8 +19,8 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
|
||||
var sqlDataTypes = Sql()
|
||||
.Select<DataTypeDto>()
|
||||
.From<DataTypeDto>()
|
||||
.Where<DataTypeDto>(x => x.EditorAlias == "Umbraco.RelatedLinks"
|
||||
|| x.EditorAlias == "Umbraco.RelatedLinks2");
|
||||
.Where<DataTypeDto>(x => x.EditorAlias == Constants.PropertyEditors.Legacy.Aliases.RelatedLinks
|
||||
|| x.EditorAlias == Constants.PropertyEditors.Legacy.Aliases.RelatedLinks2);
|
||||
|
||||
var dataTypes = Database.Fetch<DataTypeDto>(sqlDataTypes);
|
||||
var dataTypeIds = dataTypes.Select(x => x.NodeId).ToList();
|
||||
@@ -50,10 +50,10 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
|
||||
var properties = Database.Fetch<PropertyDataDto>(sqlPropertyData);
|
||||
|
||||
// Create a Multi URL Picker datatype for the converted RelatedLinks data
|
||||
|
||||
|
||||
foreach (var property in properties)
|
||||
{
|
||||
var value = property.Value.ToString();
|
||||
var value = property.Value?.ToString();
|
||||
if (string.IsNullOrWhiteSpace(value))
|
||||
continue;
|
||||
|
||||
@@ -89,7 +89,7 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
|
||||
Name = relatedLink.Caption,
|
||||
Target = relatedLink.NewWindow ? "_blank" : null,
|
||||
Udi = udi,
|
||||
// Should only have a URL if it's an external link otherwise it wil be a UDI
|
||||
// Should only have a URL if it's an external link otherwise it wil be a UDI
|
||||
Url = relatedLink.IsInternal == false ? relatedLink.Link : null
|
||||
};
|
||||
|
||||
@@ -103,7 +103,7 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
|
||||
Database.Update(property);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Newtonsoft.Json;
|
||||
using Umbraco.Core.Composing;
|
||||
@@ -18,6 +19,18 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
|
||||
private readonly PropertyEditorCollection _propertyEditors;
|
||||
private readonly ILogger _logger;
|
||||
|
||||
private static readonly ISet<string> LegacyAliases = new HashSet<string>()
|
||||
{
|
||||
Constants.PropertyEditors.Legacy.Aliases.Date,
|
||||
Constants.PropertyEditors.Legacy.Aliases.Textbox,
|
||||
Constants.PropertyEditors.Legacy.Aliases.ContentPicker2,
|
||||
Constants.PropertyEditors.Legacy.Aliases.MediaPicker2,
|
||||
Constants.PropertyEditors.Legacy.Aliases.MemberPicker2,
|
||||
Constants.PropertyEditors.Legacy.Aliases.RelatedLinks2,
|
||||
Constants.PropertyEditors.Legacy.Aliases.TextboxMultiple,
|
||||
Constants.PropertyEditors.Legacy.Aliases.MultiNodeTreePicker2,
|
||||
};
|
||||
|
||||
public DataTypeMigration(IMigrationContext context, PreValueMigratorCollection preValueMigrators, PropertyEditorCollection propertyEditors, ILogger logger)
|
||||
: base(context)
|
||||
{
|
||||
@@ -70,16 +83,23 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
|
||||
var newAlias = migrator.GetNewAlias(dataType.EditorAlias);
|
||||
if (newAlias == null)
|
||||
{
|
||||
_logger.Warn<DataTypeMigration>("Skipping validation of configuration for data type {NodeId} : {EditorAlias}."
|
||||
+ " Please ensure that the configuration is valid. The site may fail to start and / or load data types and run.",
|
||||
dataType.NodeId, dataType.EditorAlias);
|
||||
if (!LegacyAliases.Contains(dataType.EditorAlias))
|
||||
{
|
||||
_logger.Warn<DataTypeMigration>(
|
||||
"Skipping validation of configuration for data type {NodeId} : {EditorAlias}."
|
||||
+ " Please ensure that the configuration is valid. The site may fail to start and / or load data types and run.",
|
||||
dataType.NodeId, dataType.EditorAlias);
|
||||
}
|
||||
}
|
||||
else if (!_propertyEditors.TryGet(newAlias, out var propertyEditor))
|
||||
{
|
||||
_logger.Warn<DataTypeMigration>("Skipping validation of configuration for data type {NodeId} : {NewEditorAlias} (was: {EditorAlias})"
|
||||
+ " because no property editor with that alias was found."
|
||||
+ " Please ensure that the configuration is valid. The site may fail to start and / or load data types and run.",
|
||||
dataType.NodeId, newAlias, dataType.EditorAlias);
|
||||
if (!LegacyAliases.Contains(newAlias))
|
||||
{
|
||||
_logger.Warn<DataTypeMigration>("Skipping validation of configuration for data type {NodeId} : {NewEditorAlias} (was: {EditorAlias})"
|
||||
+ " because no property editor with that alias was found."
|
||||
+ " Please ensure that the configuration is valid. The site may fail to start and / or load data types and run.",
|
||||
dataType.NodeId, newAlias, dataType.EditorAlias);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
class ContentPickerPreValueMigrator : DefaultPreValueMigrator
|
||||
{
|
||||
public override bool CanMigrate(string editorAlias)
|
||||
=> editorAlias == "Umbraco.ContentPicker2";
|
||||
=> editorAlias == Constants.PropertyEditors.Legacy.Aliases.ContentPicker2;
|
||||
|
||||
public override string GetNewAlias(string editorAlias)
|
||||
=> null;
|
||||
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0.DataTypes
|
||||
{
|
||||
class DropDownFlexiblePreValueMigrator : IPreValueMigrator
|
||||
{
|
||||
public bool CanMigrate(string editorAlias)
|
||||
=> editorAlias == "Umbraco.DropDown.Flexible";
|
||||
|
||||
public virtual string GetNewAlias(string editorAlias)
|
||||
=> null;
|
||||
|
||||
public object GetConfiguration(int dataTypeId, string editorAlias, Dictionary<string, PreValueDto> preValues)
|
||||
{
|
||||
var config = new DropDownFlexibleConfiguration();
|
||||
foreach (var preValue in preValues.Values)
|
||||
{
|
||||
if (preValue.Alias == "multiple")
|
||||
{
|
||||
config.Multiple = (preValue.Value == "1");
|
||||
}
|
||||
else
|
||||
{
|
||||
config.Items.Add(new ValueListConfiguration.ValueListItem { Id = preValue.Id, Value = preValue.Value });
|
||||
}
|
||||
}
|
||||
return config;
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -6,15 +6,15 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0.DataTypes
|
||||
{
|
||||
private readonly string[] _editors =
|
||||
{
|
||||
"Umbraco.MediaPicker2",
|
||||
"Umbraco.MediaPicker"
|
||||
Constants.PropertyEditors.Legacy.Aliases.MediaPicker2,
|
||||
Constants.PropertyEditors.Aliases.MediaPicker
|
||||
};
|
||||
|
||||
public override bool CanMigrate(string editorAlias)
|
||||
=> _editors.Contains(editorAlias);
|
||||
|
||||
public override string GetNewAlias(string editorAlias)
|
||||
=> "Umbraco.MediaPicker";
|
||||
=> Constants.PropertyEditors.Aliases.MediaPicker;
|
||||
|
||||
// you wish - but MediaPickerConfiguration lives in Umbraco.Web
|
||||
/*
|
||||
|
||||
@@ -19,6 +19,7 @@ public class PreValueMigratorComposer : ICoreComposer
|
||||
.Append<NestedContentPreValueMigrator>()
|
||||
.Append<DecimalPreValueMigrator>()
|
||||
.Append<ListViewPreValueMigrator>()
|
||||
.Append<DropDownFlexiblePreValueMigrator>()
|
||||
.Append<ValueListPreValueMigrator>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0.DataTypes
|
||||
private readonly string[] _editors =
|
||||
{
|
||||
"Umbraco.RadioButtonList",
|
||||
"Umbraco.CheckBoxList",
|
||||
"Umbraco.DropDown",
|
||||
"Umbraco.DropdownlistPublishingKeys",
|
||||
"Umbraco.DropDownMultiple",
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
|
||||
|
||||
public override void Migrate()
|
||||
{
|
||||
var dataTypes = GetDataTypes("Umbraco.Date");
|
||||
var dataTypes = GetDataTypes(Constants.PropertyEditors.Legacy.Aliases.Date);
|
||||
|
||||
foreach (var dataType in dataTypes)
|
||||
{
|
||||
@@ -25,6 +25,14 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
|
||||
{
|
||||
config = (DateTimeConfiguration) new CustomDateTimeConfigurationEditor().FromDatabase(
|
||||
dataType.Configuration);
|
||||
|
||||
// If the Umbraco.Date type is the default from V7 and it has never been updated, then the
|
||||
// configuration is empty, and the format stuff is handled by in JS by moment.js. - We can't do that
|
||||
// after the migration, so we force the format to the default from V7.
|
||||
if (string.IsNullOrEmpty(dataType.Configuration))
|
||||
{
|
||||
config.Format = "YYYY-MM-DD";
|
||||
};
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
@@ -12,12 +12,12 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
|
||||
|
||||
public override void Migrate()
|
||||
{
|
||||
RenameDataType(Constants.PropertyEditors.Aliases.ContentPicker + "2", Constants.PropertyEditors.Aliases.ContentPicker);
|
||||
RenameDataType(Constants.PropertyEditors.Aliases.MediaPicker + "2", Constants.PropertyEditors.Aliases.MediaPicker);
|
||||
RenameDataType(Constants.PropertyEditors.Aliases.MemberPicker + "2", Constants.PropertyEditors.Aliases.MemberPicker);
|
||||
RenameDataType(Constants.PropertyEditors.Aliases.MultiNodeTreePicker + "2", Constants.PropertyEditors.Aliases.MultiNodeTreePicker);
|
||||
RenameDataType("Umbraco.TextboxMultiple", Constants.PropertyEditors.Aliases.TextArea, false);
|
||||
RenameDataType("Umbraco.Textbox", Constants.PropertyEditors.Aliases.TextBox, false);
|
||||
RenameDataType(Constants.PropertyEditors.Legacy.Aliases.ContentPicker2, Constants.PropertyEditors.Aliases.ContentPicker);
|
||||
RenameDataType(Constants.PropertyEditors.Legacy.Aliases.MediaPicker2, Constants.PropertyEditors.Aliases.MediaPicker);
|
||||
RenameDataType(Constants.PropertyEditors.Legacy.Aliases.MemberPicker2, Constants.PropertyEditors.Aliases.MemberPicker);
|
||||
RenameDataType(Constants.PropertyEditors.Legacy.Aliases.MultiNodeTreePicker2, Constants.PropertyEditors.Aliases.MultiNodeTreePicker);
|
||||
RenameDataType(Constants.PropertyEditors.Legacy.Aliases.TextboxMultiple, Constants.PropertyEditors.Aliases.TextArea, false);
|
||||
RenameDataType(Constants.PropertyEditors.Legacy.Aliases.Textbox, Constants.PropertyEditors.Aliases.TextBox, false);
|
||||
}
|
||||
|
||||
private void RenameDataType(string fromAlias, string toAlias, bool checkCollision = true)
|
||||
@@ -43,7 +43,7 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
|
||||
$"Property Editors. Before upgrading to v8, any Data Types using property editors that are named with the prefix '(Obsolete)' must be migrated " +
|
||||
$"to the non-obsolete v7 property editors of the same type.");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
Database.Execute(Sql()
|
||||
|
||||
@@ -14,11 +14,18 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
|
||||
public override void Migrate()
|
||||
{
|
||||
//Get anything currently scheduled
|
||||
var scheduleSql = new Sql()
|
||||
.Select("nodeId", "releaseDate", "expireDate")
|
||||
var releaseSql = new Sql()
|
||||
.Select("nodeId", "releaseDate")
|
||||
.From("umbracoDocument")
|
||||
.Where("releaseDate IS NOT NULL OR expireDate IS NOT NULL");
|
||||
var schedules = Database.Dictionary<int, (DateTime? releaseDate, DateTime? expireDate)> (scheduleSql);
|
||||
.Where("releaseDate IS NOT NULL");
|
||||
var releases = Database.Dictionary<int, DateTime> (releaseSql);
|
||||
|
||||
var expireSql = new Sql()
|
||||
.Select("nodeId", "expireDate")
|
||||
.From("umbracoDocument")
|
||||
.Where("expireDate IS NOT NULL");
|
||||
var expires = Database.Dictionary<int, DateTime>(expireSql);
|
||||
|
||||
|
||||
//drop old cols
|
||||
Delete.Column("releaseDate").FromTable("umbracoDocument").Do();
|
||||
@@ -27,20 +34,25 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
|
||||
Create.Table<ContentScheduleDto>(true).Do();
|
||||
|
||||
//migrate the schedule
|
||||
foreach(var s in schedules)
|
||||
foreach(var s in releases)
|
||||
{
|
||||
var date = s.Value.releaseDate;
|
||||
var date = s.Value;
|
||||
var action = ContentScheduleAction.Release.ToString();
|
||||
if (!date.HasValue)
|
||||
{
|
||||
date = s.Value.expireDate;
|
||||
action = ContentScheduleAction.Expire.ToString();
|
||||
}
|
||||
|
||||
Insert.IntoTable(ContentScheduleDto.TableName)
|
||||
.Row(new { nodeId = s.Key, date = date.Value, action = action })
|
||||
.Row(new { id = Guid.NewGuid(), nodeId = s.Key, date = date, action = action })
|
||||
.Do();
|
||||
}
|
||||
|
||||
foreach (var s in expires)
|
||||
{
|
||||
var date = s.Value;
|
||||
var action = ContentScheduleAction.Expire.ToString();
|
||||
|
||||
Insert.IntoTable(ContentScheduleDto.TableName)
|
||||
.Row(new { id = Guid.NewGuid(), nodeId = s.Key, date = date, action = action })
|
||||
.Do();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+31
-8
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using Newtonsoft.Json;
|
||||
@@ -36,6 +37,7 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_1_0
|
||||
|
||||
var properties = Database.Fetch<PropertyDataDto>(sqlPropertyData);
|
||||
|
||||
var exceptions = new List<Exception>();
|
||||
foreach (var property in properties)
|
||||
{
|
||||
var value = property.TextValue;
|
||||
@@ -43,19 +45,34 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_1_0
|
||||
|
||||
if (property.PropertyTypeDto.DataTypeDto.EditorAlias == Constants.PropertyEditors.Aliases.Grid)
|
||||
{
|
||||
var obj = JsonConvert.DeserializeObject<JObject>(value);
|
||||
var allControls = obj.SelectTokens("$.sections..rows..areas..controls");
|
||||
|
||||
foreach (var control in allControls.SelectMany(c => c))
|
||||
try
|
||||
{
|
||||
var controlValue = control["value"];
|
||||
if (controlValue.Type == JTokenType.String)
|
||||
var obj = JsonConvert.DeserializeObject<JObject>(value);
|
||||
var allControls = obj.SelectTokens("$.sections..rows..areas..controls");
|
||||
|
||||
foreach (var control in allControls.SelectMany(c => c))
|
||||
{
|
||||
control["value"] = UpdateMediaUrls(mediaLinkPattern, controlValue.Value<string>());
|
||||
var controlValue = control["value"];
|
||||
if (controlValue.Type == JTokenType.String)
|
||||
{
|
||||
control["value"] = UpdateMediaUrls(mediaLinkPattern, controlValue.Value<string>());
|
||||
}
|
||||
}
|
||||
|
||||
property.TextValue = JsonConvert.SerializeObject(obj);
|
||||
}
|
||||
catch (JsonException e)
|
||||
{
|
||||
exceptions.Add(new InvalidOperationException(
|
||||
"Cannot deserialize the value as json. This can be because the property editor " +
|
||||
"type is changed from another type into a grid. Old versions of the value in this " +
|
||||
"property can have the structure from the old property editor type. This needs to be " +
|
||||
"changed manually before updating the database.\n" +
|
||||
$"Property info: Id = {property.Id}, LanguageId = {property.LanguageId}, VersionId = {property.VersionId}, Value = {property.Value}"
|
||||
, e));
|
||||
continue;
|
||||
}
|
||||
|
||||
property.TextValue = JsonConvert.SerializeObject(obj);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -65,6 +82,12 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_1_0
|
||||
Database.Update(property);
|
||||
}
|
||||
|
||||
|
||||
if (exceptions.Any())
|
||||
{
|
||||
throw new AggregateException("One or more errors related to unexpected data in grid values occurred.", exceptions);
|
||||
}
|
||||
|
||||
Context.AddPostMigration<RebuildPublishedSnapshot>();
|
||||
}
|
||||
|
||||
|
||||
@@ -114,7 +114,7 @@ namespace Umbraco.Core.Models
|
||||
/// Gets of sets the alias of the property type.
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public string Alias
|
||||
public virtual string Alias
|
||||
{
|
||||
get => _alias;
|
||||
set => SetPropertyValueAndDetectChanges(SanitizeAlias(value), ref _alias, nameof(Alias));
|
||||
|
||||
@@ -103,18 +103,26 @@ namespace Umbraco.Core
|
||||
/// Gets the children of the content item.
|
||||
/// </summary>
|
||||
/// <param name="content">The content item.</param>
|
||||
/// <param name="culture">The specific culture to get the url children for. If null is used the current culture is used (Default is null).</param>
|
||||
/// <param name="culture">
|
||||
/// The specific culture to get the url children for. Default is null which will use the current culture in <see cref="VariationContext"/>
|
||||
/// </param>
|
||||
/// <remarks>
|
||||
/// <para>Gets children that are available for the specified culture.</para>
|
||||
/// <para>Children are sorted by their sortOrder.</para>
|
||||
/// <para>The '*' culture and supported and returns everything.</para>
|
||||
/// <para>
|
||||
/// For culture,
|
||||
/// if null is used the current culture is used.
|
||||
/// If an empty string is used only invariant children are returned.
|
||||
/// If "*" is used all children are returned.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// If a variant culture is specified or there is a current culture in the <see cref="VariationContext"/> then the Children returned
|
||||
/// will include both the variant children matching the culture AND the invariant children because the invariant children flow with the current culture.
|
||||
/// However, if an empty string is specified only invariant children are returned.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public static IEnumerable<IPublishedContent> Children(this IPublishedContent content, string culture = null)
|
||||
{
|
||||
// invariant has invariant value (whatever the requested culture)
|
||||
if (!content.ContentType.VariesByCulture() && culture != "*")
|
||||
culture = "";
|
||||
|
||||
// handle context culture for variant
|
||||
if (culture == null)
|
||||
culture = VariationContextAccessor?.VariationContext?.Culture ?? "";
|
||||
|
||||
@@ -139,7 +139,7 @@ namespace Umbraco.Core.Runtime
|
||||
// there should be none, really - this is here "just in case"
|
||||
Compose(composition);
|
||||
|
||||
// acquire the main domain
|
||||
// acquire the main domain - if this fails then anything that should be registered with MainDom will not operate
|
||||
AcquireMainDom(mainDom);
|
||||
|
||||
// determine our runtime level
|
||||
@@ -218,13 +218,13 @@ namespace Umbraco.Core.Runtime
|
||||
IOHelper.SetRootDirectory(path);
|
||||
}
|
||||
|
||||
private void AcquireMainDom(MainDom mainDom)
|
||||
private bool AcquireMainDom(MainDom mainDom)
|
||||
{
|
||||
using (var timer = ProfilingLogger.DebugDuration<CoreRuntime>("Acquiring MainDom.", "Acquired."))
|
||||
{
|
||||
try
|
||||
{
|
||||
mainDom.Acquire();
|
||||
return mainDom.Acquire();
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
@@ -97,6 +97,11 @@ namespace Umbraco.Core
|
||||
/// <param name="request"></param>
|
||||
internal void EnsureApplicationUrl(HttpRequestBase request = null)
|
||||
{
|
||||
//Fixme: This causes problems with site swap on azure because azure pre-warms a site by calling into `localhost` and when it does that
|
||||
// it changes the URL to `localhost:80` which actually doesn't work for pinging itself, it only works internally in Azure. The ironic part
|
||||
// about this is that this is here specifically for the slot swap scenario https://issues.umbraco.org/issue/U4-10626
|
||||
|
||||
|
||||
// see U4-10626 - in some cases we want to reset the application url
|
||||
// (this is a simplified version of what was in 7.x)
|
||||
// note: should this be optional? is it expensive?
|
||||
|
||||
@@ -241,6 +241,7 @@
|
||||
<Compile Include="Migrations\Upgrade\V_8_0_0\DataTypes\DefaultPreValueMigrator.cs" />
|
||||
<Compile Include="Migrations\Upgrade\V_8_0_0\DataTypes\RenamingPreValueMigrator.cs" />
|
||||
<Compile Include="Migrations\Upgrade\V_8_0_0\DataTypes\RichTextPreValueMigrator.cs" />
|
||||
<Compile Include="Migrations\Upgrade\V_8_0_0\DataTypes\DropDownFlexiblePreValueMigrator.cs" />
|
||||
<Compile Include="Migrations\Upgrade\V_8_0_0\MergeDateAndDateTimePropertyEditor.cs" />
|
||||
<Compile Include="Models\Entities\EntityExtensions.cs" />
|
||||
<Compile Include="Migrations\Upgrade\V_8_0_0\DataTypes\PreValueMigratorBase.cs" />
|
||||
|
||||
@@ -23,6 +23,8 @@ namespace Umbraco.Core
|
||||
handle,
|
||||
(state, timedOut) =>
|
||||
{
|
||||
//TODO: We aren't checking if this is timed out
|
||||
|
||||
tcs.SetResult(null);
|
||||
|
||||
// we take a lock here to make sure the outer method has completed setting the local variable callbackHandle.
|
||||
|
||||
@@ -48,6 +48,31 @@ namespace Umbraco.Examine
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns all index fields that are culture specific (suffixed) or invariant
|
||||
/// </summary>
|
||||
/// <param name="index"></param>
|
||||
/// <param name="culture"></param>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<string> GetCultureAndInvariantFields(this IUmbracoIndex index, string culture)
|
||||
{
|
||||
var allFields = index.GetFields();
|
||||
// ReSharper disable once LoopCanBeConvertedToQuery
|
||||
foreach (var field in allFields)
|
||||
{
|
||||
var match = CultureIsoCodeFieldNameMatchExpression.Match(field);
|
||||
if (match.Success && match.Groups.Count == 3 && culture.InvariantEquals(match.Groups[2].Value))
|
||||
{
|
||||
yield return field; //matches this culture field
|
||||
}
|
||||
else if (!match.Success)
|
||||
{
|
||||
yield return field; //matches no culture field (invariant)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
internal static bool TryParseLuceneQuery(string query)
|
||||
{
|
||||
// TODO: I'd assume there would be a more strict way to parse the query but not that i can find yet, for now we'll
|
||||
@@ -77,7 +102,7 @@ namespace Umbraco.Examine
|
||||
/// <remarks>
|
||||
/// This is not thread safe, use with care
|
||||
/// </remarks>
|
||||
internal static void UnlockLuceneIndexes(this IExamineManager examineManager, ILogger logger)
|
||||
internal static void ConfigureLuceneIndexes(this IExamineManager examineManager, ILogger logger, bool disableExamineIndexing)
|
||||
{
|
||||
foreach (var luceneIndexer in examineManager.Indexes.OfType<LuceneIndex>())
|
||||
{
|
||||
@@ -86,6 +111,8 @@ namespace Umbraco.Examine
|
||||
//that could end up halting shutdown for a very long time causing overlapping appdomains and many other problems.
|
||||
luceneIndexer.WaitForIndexQueueOnShutdown = false;
|
||||
|
||||
if (disableExamineIndexing) continue; //exit if not enabled, we don't need to unlock them if we're not maindom
|
||||
|
||||
//we should check if the index is locked ... it shouldn't be! We are using simple fs lock now and we are also ensuring that
|
||||
//the indexes are not operational unless MainDom is true
|
||||
var dir = luceneIndexer.GetLuceneDirectory();
|
||||
|
||||
@@ -124,7 +124,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
_source = new TestDataSource(kits);
|
||||
|
||||
// at last, create the complete NuCache snapshot service!
|
||||
var options = new PublishedSnapshotService.Options { IgnoreLocalDb = true };
|
||||
var options = new PublishedSnapshotServiceOptions { IgnoreLocalDb = true };
|
||||
_snapshotService = new PublishedSnapshotService(options,
|
||||
null,
|
||||
runtime,
|
||||
@@ -151,117 +151,139 @@ namespace Umbraco.Tests.PublishedContent
|
||||
Mock.Get(factory).Setup(x => x.GetInstance(typeof(IVariationContextAccessor))).Returns(_variationAccesor);
|
||||
}
|
||||
|
||||
private IEnumerable<ContentNodeKit> GetNestedVariantKits()
|
||||
{
|
||||
var paths = new Dictionary<int, string> { { -1, "-1" } };
|
||||
|
||||
//1x variant (root)
|
||||
yield return CreateVariantKit(1, -1, 1, paths);
|
||||
|
||||
//1x invariant under root
|
||||
yield return CreateInvariantKit(4, 1, 1, paths);
|
||||
|
||||
//1x variant under root
|
||||
yield return CreateVariantKit(7, 1, 4, paths);
|
||||
|
||||
//2x mixed under invariant
|
||||
yield return CreateVariantKit(10, 4, 1, paths);
|
||||
yield return CreateInvariantKit(11, 4, 2, paths);
|
||||
|
||||
//2x mixed under variant
|
||||
yield return CreateVariantKit(12, 7, 1, paths);
|
||||
yield return CreateInvariantKit(13, 7, 2, paths);
|
||||
}
|
||||
|
||||
private IEnumerable<ContentNodeKit> GetInvariantKits()
|
||||
{
|
||||
var paths = new Dictionary<int, string> { { -1, "-1" } };
|
||||
|
||||
ContentNodeKit CreateKit(int id, int parentId, int sortOrder)
|
||||
yield return CreateInvariantKit(1, -1, 1, paths);
|
||||
yield return CreateInvariantKit(2, -1, 2, paths);
|
||||
yield return CreateInvariantKit(3, -1, 3, paths);
|
||||
|
||||
yield return CreateInvariantKit(4, 1, 1, paths);
|
||||
yield return CreateInvariantKit(5, 1, 2, paths);
|
||||
yield return CreateInvariantKit(6, 1, 3, paths);
|
||||
|
||||
yield return CreateInvariantKit(7, 2, 3, paths);
|
||||
yield return CreateInvariantKit(8, 2, 2, paths);
|
||||
yield return CreateInvariantKit(9, 2, 1, paths);
|
||||
|
||||
yield return CreateInvariantKit(10, 3, 1, paths);
|
||||
|
||||
yield return CreateInvariantKit(11, 4, 1, paths);
|
||||
yield return CreateInvariantKit(12, 4, 2, paths);
|
||||
}
|
||||
|
||||
private ContentNodeKit CreateInvariantKit(int id, int parentId, int sortOrder, Dictionary<int, string> paths)
|
||||
{
|
||||
if (!paths.TryGetValue(parentId, out var parentPath))
|
||||
throw new Exception("Unknown parent.");
|
||||
|
||||
var path = paths[id] = parentPath + "," + id;
|
||||
var level = path.Count(x => x == ',');
|
||||
var now = DateTime.Now;
|
||||
|
||||
return new ContentNodeKit
|
||||
{
|
||||
if (!paths.TryGetValue(parentId, out var parentPath))
|
||||
throw new Exception("Unknown parent.");
|
||||
|
||||
var path = paths[id] = parentPath + "," + id;
|
||||
var level = path.Count(x => x == ',');
|
||||
var now = DateTime.Now;
|
||||
|
||||
return new ContentNodeKit
|
||||
ContentTypeId = _contentTypeInvariant.Id,
|
||||
Node = new ContentNode(id, Guid.NewGuid(), level, path, sortOrder, parentId, DateTime.Now, 0),
|
||||
DraftData = null,
|
||||
PublishedData = new ContentData
|
||||
{
|
||||
ContentTypeId = _contentTypeInvariant.Id,
|
||||
Node = new ContentNode(id, Guid.NewGuid(), level, path, sortOrder, parentId, DateTime.Now, 0),
|
||||
DraftData = null,
|
||||
PublishedData = new ContentData
|
||||
{
|
||||
Name = "N" + id,
|
||||
Published = true,
|
||||
TemplateId = 0,
|
||||
VersionId = 1,
|
||||
VersionDate = now,
|
||||
WriterId = 0,
|
||||
Properties = new Dictionary<string, PropertyData[]>(),
|
||||
CultureInfos = new Dictionary<string, CultureVariation>()
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
yield return CreateKit(1, -1, 1);
|
||||
yield return CreateKit(2, -1, 2);
|
||||
yield return CreateKit(3, -1, 3);
|
||||
|
||||
yield return CreateKit(4, 1, 1);
|
||||
yield return CreateKit(5, 1, 2);
|
||||
yield return CreateKit(6, 1, 3);
|
||||
|
||||
yield return CreateKit(7, 2, 3);
|
||||
yield return CreateKit(8, 2, 2);
|
||||
yield return CreateKit(9, 2, 1);
|
||||
|
||||
yield return CreateKit(10, 3, 1);
|
||||
|
||||
yield return CreateKit(11, 4, 1);
|
||||
yield return CreateKit(12, 4, 2);
|
||||
Name = "N" + id,
|
||||
Published = true,
|
||||
TemplateId = 0,
|
||||
VersionId = 1,
|
||||
VersionDate = now,
|
||||
WriterId = 0,
|
||||
Properties = new Dictionary<string, PropertyData[]>(),
|
||||
CultureInfos = new Dictionary<string, CultureVariation>()
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private IEnumerable<ContentNodeKit> GetVariantKits()
|
||||
{
|
||||
var paths = new Dictionary<int, string> { { -1, "-1" } };
|
||||
|
||||
Dictionary<string, CultureVariation> GetCultureInfos(int id, DateTime now)
|
||||
yield return CreateVariantKit(1, -1, 1, paths);
|
||||
yield return CreateVariantKit(2, -1, 2, paths);
|
||||
yield return CreateVariantKit(3, -1, 3, paths);
|
||||
|
||||
yield return CreateVariantKit(4, 1, 1, paths);
|
||||
yield return CreateVariantKit(5, 1, 2, paths);
|
||||
yield return CreateVariantKit(6, 1, 3, paths);
|
||||
|
||||
yield return CreateVariantKit(7, 2, 3, paths);
|
||||
yield return CreateVariantKit(8, 2, 2, paths);
|
||||
yield return CreateVariantKit(9, 2, 1, paths);
|
||||
|
||||
yield return CreateVariantKit(10, 3, 1, paths);
|
||||
|
||||
yield return CreateVariantKit(11, 4, 1, paths);
|
||||
yield return CreateVariantKit(12, 4, 2, paths);
|
||||
}
|
||||
|
||||
private static Dictionary<string, CultureVariation> GetCultureInfos(int id, DateTime now)
|
||||
{
|
||||
var en = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
|
||||
var fr = new[] { 1, 3, 4, 6, 7, 9, 10, 12 };
|
||||
|
||||
var infos = new Dictionary<string, CultureVariation>();
|
||||
if (en.Contains(id))
|
||||
infos["en-US"] = new CultureVariation { Name = "N" + id + "-" + "en-US", Date = now, IsDraft = false };
|
||||
if (fr.Contains(id))
|
||||
infos["fr-FR"] = new CultureVariation { Name = "N" + id + "-" + "fr-FR", Date = now, IsDraft = false };
|
||||
return infos;
|
||||
}
|
||||
|
||||
private ContentNodeKit CreateVariantKit(int id, int parentId, int sortOrder, Dictionary<int, string> paths)
|
||||
{
|
||||
if (!paths.TryGetValue(parentId, out var parentPath))
|
||||
throw new Exception("Unknown parent.");
|
||||
|
||||
var path = paths[id] = parentPath + "," + id;
|
||||
var level = path.Count(x => x == ',');
|
||||
var now = DateTime.Now;
|
||||
|
||||
return new ContentNodeKit
|
||||
{
|
||||
var en = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
|
||||
var fr = new[] { 1, 3, 4, 6, 7, 9, 10, 12 };
|
||||
|
||||
var infos = new Dictionary<string, CultureVariation>();
|
||||
if (en.Contains(id))
|
||||
infos["en-US"] = new CultureVariation { Name = "N" + id + "-" + "en-US", Date = now, IsDraft = false };
|
||||
if (fr.Contains(id))
|
||||
infos["fr-FR"] = new CultureVariation { Name = "N" + id + "-" + "fr-FR", Date = now, IsDraft = false };
|
||||
return infos;
|
||||
}
|
||||
|
||||
ContentNodeKit CreateKit(int id, int parentId, int sortOrder)
|
||||
{
|
||||
if (!paths.TryGetValue(parentId, out var parentPath))
|
||||
throw new Exception("Unknown parent.");
|
||||
|
||||
var path = paths[id] = parentPath + "," + id;
|
||||
var level = path.Count(x => x == ',');
|
||||
var now = DateTime.Now;
|
||||
|
||||
return new ContentNodeKit
|
||||
ContentTypeId = _contentTypeVariant.Id,
|
||||
Node = new ContentNode(id, Guid.NewGuid(), level, path, sortOrder, parentId, DateTime.Now, 0),
|
||||
DraftData = null,
|
||||
PublishedData = new ContentData
|
||||
{
|
||||
ContentTypeId = _contentTypeVariant.Id,
|
||||
Node = new ContentNode(id, Guid.NewGuid(), level, path, sortOrder, parentId, DateTime.Now, 0),
|
||||
DraftData = null,
|
||||
PublishedData = new ContentData
|
||||
{
|
||||
Name = "N" + id,
|
||||
Published = true,
|
||||
TemplateId = 0,
|
||||
VersionId = 1,
|
||||
VersionDate = now,
|
||||
WriterId = 0,
|
||||
Properties = new Dictionary<string, PropertyData[]>(),
|
||||
CultureInfos = GetCultureInfos(id, now)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
yield return CreateKit(1, -1, 1);
|
||||
yield return CreateKit(2, -1, 2);
|
||||
yield return CreateKit(3, -1, 3);
|
||||
|
||||
yield return CreateKit(4, 1, 1);
|
||||
yield return CreateKit(5, 1, 2);
|
||||
yield return CreateKit(6, 1, 3);
|
||||
|
||||
yield return CreateKit(7, 2, 3);
|
||||
yield return CreateKit(8, 2, 2);
|
||||
yield return CreateKit(9, 2, 1);
|
||||
|
||||
yield return CreateKit(10, 3, 1);
|
||||
|
||||
yield return CreateKit(11, 4, 1);
|
||||
yield return CreateKit(12, 4, 2);
|
||||
Name = "N" + id,
|
||||
Published = true,
|
||||
TemplateId = 0,
|
||||
VersionId = 1,
|
||||
VersionDate = now,
|
||||
WriterId = 0,
|
||||
Properties = new Dictionary<string, PropertyData[]>(),
|
||||
CultureInfos = GetCultureInfos(id, now)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private IEnumerable<ContentNodeKit> GetVariantWithDraftKits()
|
||||
@@ -660,6 +682,96 @@ namespace Umbraco.Tests.PublishedContent
|
||||
Assert.AreEqual(1, snapshot.Content.GetById(7).Parent?.Id);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void NestedVariationChildrenTest()
|
||||
{
|
||||
var mixedKits = GetNestedVariantKits();
|
||||
Init(mixedKits);
|
||||
|
||||
var snapshot = _snapshotService.CreatePublishedSnapshot(previewToken: null);
|
||||
_snapshotAccessor.PublishedSnapshot = snapshot;
|
||||
|
||||
//TEST with en-us variation context
|
||||
|
||||
_variationAccesor.VariationContext = new VariationContext("en-US");
|
||||
|
||||
var documents = snapshot.Content.GetAtRoot().ToArray();
|
||||
AssertDocuments(documents, "N1-en-US");
|
||||
|
||||
documents = snapshot.Content.GetById(1).Children().ToArray();
|
||||
AssertDocuments(documents, "N4", "N7-en-US");
|
||||
|
||||
//Get the invariant and list children, there's a variation context so it should return invariant AND en-us variants
|
||||
documents = snapshot.Content.GetById(4).Children().ToArray();
|
||||
AssertDocuments(documents, "N10-en-US", "N11");
|
||||
|
||||
//Get the variant and list children, there's a variation context so it should return invariant AND en-us variants
|
||||
documents = snapshot.Content.GetById(7).Children().ToArray();
|
||||
AssertDocuments(documents, "N12-en-US", "N13");
|
||||
|
||||
//TEST with fr-fr variation context
|
||||
|
||||
_variationAccesor.VariationContext = new VariationContext("fr-FR");
|
||||
|
||||
documents = snapshot.Content.GetAtRoot().ToArray();
|
||||
AssertDocuments(documents, "N1-fr-FR");
|
||||
|
||||
documents = snapshot.Content.GetById(1).Children().ToArray();
|
||||
AssertDocuments(documents, "N4", "N7-fr-FR");
|
||||
|
||||
//Get the invariant and list children, there's a variation context so it should return invariant AND en-us variants
|
||||
documents = snapshot.Content.GetById(4).Children().ToArray();
|
||||
AssertDocuments(documents, "N10-fr-FR", "N11");
|
||||
|
||||
//Get the variant and list children, there's a variation context so it should return invariant AND en-us variants
|
||||
documents = snapshot.Content.GetById(7).Children().ToArray();
|
||||
AssertDocuments(documents, "N12-fr-FR", "N13");
|
||||
|
||||
//TEST specific cultures
|
||||
|
||||
documents = snapshot.Content.GetAtRoot("fr-FR").ToArray();
|
||||
AssertDocuments(documents, "N1-fr-FR");
|
||||
|
||||
documents = snapshot.Content.GetById(1).Children("fr-FR").ToArray();
|
||||
AssertDocuments(documents, "N4", "N7-fr-FR"); //NOTE: Returns invariant, this is expected
|
||||
documents = snapshot.Content.GetById(1).Children("").ToArray();
|
||||
AssertDocuments(documents, "N4"); //Only returns invariant since that is what was requested
|
||||
|
||||
documents = snapshot.Content.GetById(4).Children("fr-FR").ToArray();
|
||||
AssertDocuments(documents, "N10-fr-FR", "N11"); //NOTE: Returns invariant, this is expected
|
||||
documents = snapshot.Content.GetById(4).Children("").ToArray();
|
||||
AssertDocuments(documents, "N11"); //Only returns invariant since that is what was requested
|
||||
|
||||
documents = snapshot.Content.GetById(7).Children("fr-FR").ToArray();
|
||||
AssertDocuments(documents, "N12-fr-FR", "N13"); //NOTE: Returns invariant, this is expected
|
||||
documents = snapshot.Content.GetById(7).Children("").ToArray();
|
||||
AssertDocuments(documents, "N13"); //Only returns invariant since that is what was requested
|
||||
|
||||
//TEST without variation context
|
||||
// This will actually convert the culture to "" which will be invariant since that's all it will know how to do
|
||||
// This will return a NULL name for culture specific entities because there is no variation context
|
||||
|
||||
_variationAccesor.VariationContext = null;
|
||||
|
||||
documents = snapshot.Content.GetAtRoot().ToArray();
|
||||
//will return nothing because there's only variant at root
|
||||
Assert.AreEqual(0, documents.Length);
|
||||
//so we'll continue to getting the known variant, do not fully assert this because the Name will NULL
|
||||
documents = snapshot.Content.GetAtRoot("fr-FR").ToArray();
|
||||
Assert.AreEqual(1, documents.Length);
|
||||
|
||||
documents = snapshot.Content.GetById(1).Children().ToArray();
|
||||
AssertDocuments(documents, "N4");
|
||||
|
||||
//Get the invariant and list children
|
||||
documents = snapshot.Content.GetById(4).Children().ToArray();
|
||||
AssertDocuments(documents, "N11");
|
||||
|
||||
//Get the variant and list children
|
||||
documents = snapshot.Content.GetById(7).Children().ToArray();
|
||||
AssertDocuments(documents, "N13");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void VariantChildrenTest()
|
||||
{
|
||||
|
||||
@@ -169,7 +169,7 @@ namespace Umbraco.Tests.PublishedContent
|
||||
_variationAccesor = new TestVariationContextAccessor();
|
||||
|
||||
// at last, create the complete NuCache snapshot service!
|
||||
var options = new PublishedSnapshotService.Options { IgnoreLocalDb = true };
|
||||
var options = new PublishedSnapshotServiceOptions { IgnoreLocalDb = true };
|
||||
_snapshotService = new PublishedSnapshotService(options,
|
||||
null,
|
||||
runtime,
|
||||
|
||||
@@ -72,7 +72,7 @@ namespace Umbraco.Tests.Scoping
|
||||
|
||||
protected override IPublishedSnapshotService CreatePublishedSnapshotService()
|
||||
{
|
||||
var options = new PublishedSnapshotService.Options { IgnoreLocalDb = true };
|
||||
var options = new PublishedSnapshotServiceOptions { IgnoreLocalDb = true };
|
||||
var publishedSnapshotAccessor = new UmbracoContextPublishedSnapshotAccessor(Umbraco.Web.Composing.Current.UmbracoContextAccessor);
|
||||
var runtimeStateMock = new Mock<IRuntimeState>();
|
||||
runtimeStateMock.Setup(x => x.Level).Returns(() => RuntimeLevel.Run);
|
||||
|
||||
@@ -1,157 +0,0 @@
|
||||
using System.Collections.Specialized;
|
||||
using System.Web;
|
||||
using System.Web.Helpers;
|
||||
using Moq;
|
||||
using Newtonsoft.Json;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Tests.TestHelpers;
|
||||
using Umbraco.Web.Mvc;
|
||||
using Umbraco.Web.Security;
|
||||
|
||||
namespace Umbraco.Tests.Security
|
||||
{
|
||||
[TestFixture]
|
||||
public class UmbracoAntiForgeryAdditionalDataProviderTests
|
||||
{
|
||||
[Test]
|
||||
public void Test_Wrapped_Non_BeginUmbracoForm()
|
||||
{
|
||||
var wrapped = Mock.Of<IAntiForgeryAdditionalDataProvider>(x => x.GetAdditionalData(It.IsAny<HttpContextBase>()) == "custom");
|
||||
var provider = new UmbracoAntiForgeryAdditionalDataProvider(wrapped);
|
||||
|
||||
var httpContextFactory = new FakeHttpContextFactory("/hello/world");
|
||||
var data = provider.GetAdditionalData(httpContextFactory.HttpContext);
|
||||
|
||||
Assert.IsTrue(data.DetectIsJson());
|
||||
var json = JsonConvert.DeserializeObject<UmbracoAntiForgeryAdditionalDataProvider.AdditionalData>(data);
|
||||
Assert.AreEqual(null, json.Ufprt);
|
||||
Assert.IsTrue(json.Stamp != default);
|
||||
Assert.AreEqual("custom", json.WrappedValue);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Null_Wrapped_Non_BeginUmbracoForm()
|
||||
{
|
||||
var provider = new UmbracoAntiForgeryAdditionalDataProvider(null);
|
||||
|
||||
var httpContextFactory = new FakeHttpContextFactory("/hello/world");
|
||||
var data = provider.GetAdditionalData(httpContextFactory.HttpContext);
|
||||
|
||||
Assert.IsTrue(data.DetectIsJson());
|
||||
var json = JsonConvert.DeserializeObject<UmbracoAntiForgeryAdditionalDataProvider.AdditionalData>(data);
|
||||
Assert.AreEqual(null, json.Ufprt);
|
||||
Assert.IsTrue(json.Stamp != default);
|
||||
Assert.AreEqual("default", json.WrappedValue);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Validate_Non_Json()
|
||||
{
|
||||
var provider = new UmbracoAntiForgeryAdditionalDataProvider(null);
|
||||
|
||||
var httpContextFactory = new FakeHttpContextFactory("/hello/world");
|
||||
var isValid = provider.ValidateAdditionalData(httpContextFactory.HttpContext, "hello");
|
||||
|
||||
Assert.IsFalse(isValid);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Validate_Invalid_Json()
|
||||
{
|
||||
var provider = new UmbracoAntiForgeryAdditionalDataProvider(null);
|
||||
|
||||
var httpContextFactory = new FakeHttpContextFactory("/hello/world");
|
||||
var isValid = provider.ValidateAdditionalData(httpContextFactory.HttpContext, "{'Stamp': '0'}");
|
||||
Assert.IsFalse(isValid);
|
||||
|
||||
isValid = provider.ValidateAdditionalData(httpContextFactory.HttpContext, "{'Stamp': ''}");
|
||||
Assert.IsFalse(isValid);
|
||||
|
||||
isValid = provider.ValidateAdditionalData(httpContextFactory.HttpContext, "{'hello': 'world'}");
|
||||
Assert.IsFalse(isValid);
|
||||
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Validate_No_Request_Ufprt()
|
||||
{
|
||||
var provider = new UmbracoAntiForgeryAdditionalDataProvider(null);
|
||||
|
||||
var httpContextFactory = new FakeHttpContextFactory("/hello/world");
|
||||
//there is a ufprt in the additional data, but not in the request
|
||||
var isValid = provider.ValidateAdditionalData(httpContextFactory.HttpContext, "{'Stamp': '636970328040070330', 'WrappedValue': 'default', 'Ufprt': 'ASBVDFDFDFDF'}");
|
||||
Assert.IsFalse(isValid);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Validate_No_AdditionalData_Ufprt()
|
||||
{
|
||||
var provider = new UmbracoAntiForgeryAdditionalDataProvider(null);
|
||||
|
||||
var httpContextFactory = new FakeHttpContextFactory("/hello/world");
|
||||
var requestMock = Mock.Get(httpContextFactory.HttpContext.Request);
|
||||
requestMock.SetupGet(x => x["ufprt"]).Returns("ABCDEFG");
|
||||
|
||||
//there is a ufprt in the additional data, but not in the request
|
||||
var isValid = provider.ValidateAdditionalData(httpContextFactory.HttpContext, "{'Stamp': '636970328040070330', 'WrappedValue': 'default', 'Ufprt': ''}");
|
||||
Assert.IsFalse(isValid);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Validate_No_AdditionalData_Or_Request_Ufprt()
|
||||
{
|
||||
var provider = new UmbracoAntiForgeryAdditionalDataProvider(null);
|
||||
|
||||
var httpContextFactory = new FakeHttpContextFactory("/hello/world");
|
||||
|
||||
//there is a ufprt in the additional data, but not in the request
|
||||
var isValid = provider.ValidateAdditionalData(httpContextFactory.HttpContext, "{'Stamp': '636970328040070330', 'WrappedValue': 'default', 'Ufprt': ''}");
|
||||
Assert.IsTrue(isValid);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Validate_Request_And_AdditionalData_Ufprt()
|
||||
{
|
||||
var provider = new UmbracoAntiForgeryAdditionalDataProvider(null);
|
||||
|
||||
var routeParams1 = $"{RenderRouteHandler.ReservedAdditionalKeys.Controller}={HttpUtility.UrlEncode("Test")}&{RenderRouteHandler.ReservedAdditionalKeys.Action}={HttpUtility.UrlEncode("Index")}&{RenderRouteHandler.ReservedAdditionalKeys.Area}=Umbraco";
|
||||
var routeParams2 = $"{RenderRouteHandler.ReservedAdditionalKeys.Controller}={HttpUtility.UrlEncode("Test")}&{RenderRouteHandler.ReservedAdditionalKeys.Action}={HttpUtility.UrlEncode("Index")}&{RenderRouteHandler.ReservedAdditionalKeys.Area}=Umbraco";
|
||||
|
||||
var httpContextFactory = new FakeHttpContextFactory("/hello/world");
|
||||
var requestMock = Mock.Get(httpContextFactory.HttpContext.Request);
|
||||
requestMock.SetupGet(x => x["ufprt"]).Returns(routeParams1.EncryptWithMachineKey());
|
||||
|
||||
var isValid = provider.ValidateAdditionalData(httpContextFactory.HttpContext, "{'Stamp': '636970328040070330', 'WrappedValue': 'default', 'Ufprt': '" + routeParams2.EncryptWithMachineKey() + "'}");
|
||||
Assert.IsTrue(isValid);
|
||||
|
||||
routeParams2 = $"{RenderRouteHandler.ReservedAdditionalKeys.Controller}={HttpUtility.UrlEncode("Invalid")}&{RenderRouteHandler.ReservedAdditionalKeys.Action}={HttpUtility.UrlEncode("Index")}&{RenderRouteHandler.ReservedAdditionalKeys.Area}=Umbraco";
|
||||
isValid = provider.ValidateAdditionalData(httpContextFactory.HttpContext, "{'Stamp': '636970328040070330', 'WrappedValue': 'default', 'Ufprt': '" + routeParams2.EncryptWithMachineKey() + "'}");
|
||||
Assert.IsFalse(isValid);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Validate_Wrapped_Request_And_AdditionalData_Ufprt()
|
||||
{
|
||||
var wrapped = Mock.Of<IAntiForgeryAdditionalDataProvider>(x => x.ValidateAdditionalData(It.IsAny<HttpContextBase>(), "custom") == true);
|
||||
var provider = new UmbracoAntiForgeryAdditionalDataProvider(wrapped);
|
||||
|
||||
var routeParams1 = $"{RenderRouteHandler.ReservedAdditionalKeys.Controller}={HttpUtility.UrlEncode("Test")}&{RenderRouteHandler.ReservedAdditionalKeys.Action}={HttpUtility.UrlEncode("Index")}&{RenderRouteHandler.ReservedAdditionalKeys.Area}=Umbraco";
|
||||
var routeParams2 = $"{RenderRouteHandler.ReservedAdditionalKeys.Controller}={HttpUtility.UrlEncode("Test")}&{RenderRouteHandler.ReservedAdditionalKeys.Action}={HttpUtility.UrlEncode("Index")}&{RenderRouteHandler.ReservedAdditionalKeys.Area}=Umbraco";
|
||||
|
||||
var httpContextFactory = new FakeHttpContextFactory("/hello/world");
|
||||
var requestMock = Mock.Get(httpContextFactory.HttpContext.Request);
|
||||
requestMock.SetupGet(x => x["ufprt"]).Returns(routeParams1.EncryptWithMachineKey());
|
||||
|
||||
var isValid = provider.ValidateAdditionalData(httpContextFactory.HttpContext, "{'Stamp': '636970328040070330', 'WrappedValue': 'default', 'Ufprt': '" + routeParams2.EncryptWithMachineKey() + "'}");
|
||||
Assert.IsFalse(isValid);
|
||||
|
||||
isValid = provider.ValidateAdditionalData(httpContextFactory.HttpContext, "{'Stamp': '636970328040070330', 'WrappedValue': 'custom', 'Ufprt': '" + routeParams2.EncryptWithMachineKey() + "'}");
|
||||
Assert.IsTrue(isValid);
|
||||
|
||||
routeParams2 = $"{RenderRouteHandler.ReservedAdditionalKeys.Controller}={HttpUtility.UrlEncode("Invalid")}&{RenderRouteHandler.ReservedAdditionalKeys.Action}={HttpUtility.UrlEncode("Index")}&{RenderRouteHandler.ReservedAdditionalKeys.Area}=Umbraco";
|
||||
isValid = provider.ValidateAdditionalData(httpContextFactory.HttpContext, "{'Stamp': '636970328040070330', 'WrappedValue': 'default', 'Ufprt': '" + routeParams2.EncryptWithMachineKey() + "'}");
|
||||
Assert.IsFalse(isValid);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -42,7 +42,7 @@ namespace Umbraco.Tests.Services
|
||||
|
||||
protected override IPublishedSnapshotService CreatePublishedSnapshotService()
|
||||
{
|
||||
var options = new PublishedSnapshotService.Options { IgnoreLocalDb = true };
|
||||
var options = new PublishedSnapshotServiceOptions { IgnoreLocalDb = true };
|
||||
var publishedSnapshotAccessor = new UmbracoContextPublishedSnapshotAccessor(Umbraco.Web.Composing.Current.UmbracoContextAccessor);
|
||||
var runtimeStateMock = new Mock<IRuntimeState>();
|
||||
runtimeStateMock.Setup(x => x.Level).Returns(() => RuntimeLevel.Run);
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
using Lucene.Net.Store;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Umbraco.Tests.TestHelpers
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Used for tests with Lucene so that each RAM directory is unique
|
||||
/// </summary>
|
||||
public class RandomIdRAMDirectory : RAMDirectory
|
||||
{
|
||||
private readonly string _lockId = Guid.NewGuid().ToString();
|
||||
public override string GetLockId()
|
||||
{
|
||||
return _lockId;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -147,7 +147,6 @@
|
||||
<Compile Include="Routing\MediaUrlProviderTests.cs" />
|
||||
<Compile Include="Runtimes\StandaloneTests.cs" />
|
||||
<Compile Include="Routing\GetContentUrlsTests.cs" />
|
||||
<Compile Include="Security\UmbracoAntiForgeryAdditionalDataProviderTests.cs" />
|
||||
<Compile Include="Services\AmbiguousEventTests.cs" />
|
||||
<Compile Include="Services\ContentServiceEventTests.cs" />
|
||||
<Compile Include="Services\ContentServicePublishBranchTests.cs" />
|
||||
@@ -158,6 +157,7 @@
|
||||
<Compile Include="Services\MemberGroupServiceTests.cs" />
|
||||
<Compile Include="Services\MediaTypeServiceTests.cs" />
|
||||
<Compile Include="Services\PropertyValidationServiceTests.cs" />
|
||||
<Compile Include="TestHelpers\RandomIdRamDirectory.cs" />
|
||||
<Compile Include="Testing\Objects\TestDataSource.cs" />
|
||||
<Compile Include="Published\PublishedSnapshotTestObjects.cs" />
|
||||
<Compile Include="Published\ModelTypeTests.cs" />
|
||||
@@ -268,6 +268,8 @@
|
||||
<Compile Include="StringNewlineExtensions.cs" />
|
||||
<Compile Include="Strings\StylesheetHelperTests.cs" />
|
||||
<Compile Include="Strings\StringValidationTests.cs" />
|
||||
<Compile Include="Web\Mvc\ValidateUmbracoFormRouteStringAttributeTests.cs" />
|
||||
<Compile Include="Web\PublishedContentQueryTests.cs" />
|
||||
<Compile Include="Web\UmbracoHelperTests.cs" />
|
||||
<Compile Include="Membership\MembershipProviderBaseTests.cs" />
|
||||
<Compile Include="Membership\UmbracoServiceMembershipProviderTests.cs" />
|
||||
|
||||
@@ -4,6 +4,7 @@ using Umbraco.Web;
|
||||
|
||||
namespace Umbraco.Tests.Web.Mvc
|
||||
{
|
||||
|
||||
[TestFixture]
|
||||
public class HtmlHelperExtensionMethodsTests
|
||||
{
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Web;
|
||||
using Umbraco.Web.Mvc;
|
||||
|
||||
namespace Umbraco.Tests.Web.Mvc
|
||||
{
|
||||
[TestFixture]
|
||||
public class ValidateUmbracoFormRouteStringAttributeTests
|
||||
{
|
||||
[Test]
|
||||
public void Validate_Route_String()
|
||||
{
|
||||
var attribute = new ValidateUmbracoFormRouteStringAttribute();
|
||||
|
||||
Assert.Throws<HttpUmbracoFormRouteStringException>(() => attribute.ValidateRouteString(null, null, null, null));
|
||||
|
||||
const string ControllerName = "Test";
|
||||
const string ControllerAction = "Index";
|
||||
const string Area = "MyArea";
|
||||
var validUfprt = UrlHelperRenderExtensions.CreateEncryptedRouteString(ControllerName, ControllerAction, Area);
|
||||
|
||||
var invalidUfprt = validUfprt + "z";
|
||||
Assert.Throws<HttpUmbracoFormRouteStringException>(() => attribute.ValidateRouteString(invalidUfprt, null, null, null));
|
||||
|
||||
Assert.Throws<HttpUmbracoFormRouteStringException>(() => attribute.ValidateRouteString(validUfprt, ControllerName, ControllerAction, "doesntMatch"));
|
||||
Assert.Throws<HttpUmbracoFormRouteStringException>(() => attribute.ValidateRouteString(validUfprt, ControllerName, ControllerAction, null));
|
||||
Assert.Throws<HttpUmbracoFormRouteStringException>(() => attribute.ValidateRouteString(validUfprt, ControllerName, "doesntMatch", Area));
|
||||
Assert.Throws<HttpUmbracoFormRouteStringException>(() => attribute.ValidateRouteString(validUfprt, ControllerName, null, Area));
|
||||
Assert.Throws<HttpUmbracoFormRouteStringException>(() => attribute.ValidateRouteString(validUfprt, "doesntMatch", ControllerAction, Area));
|
||||
Assert.Throws<HttpUmbracoFormRouteStringException>(() => attribute.ValidateRouteString(validUfprt, null, ControllerAction, Area));
|
||||
|
||||
Assert.DoesNotThrow(() => attribute.ValidateRouteString(validUfprt, ControllerName, ControllerAction, Area));
|
||||
Assert.DoesNotThrow(() => attribute.ValidateRouteString(validUfprt, ControllerName.ToLowerInvariant(), ControllerAction.ToLowerInvariant(), Area.ToLowerInvariant()));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Examine;
|
||||
using Examine.LuceneEngine.Providers;
|
||||
using Lucene.Net.Store;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Examine;
|
||||
using Umbraco.Tests.TestHelpers;
|
||||
using Umbraco.Web;
|
||||
using Umbraco.Web.PublishedCache;
|
||||
|
||||
namespace Umbraco.Tests.Web
|
||||
{
|
||||
[TestFixture]
|
||||
public class PublishedContentQueryTests
|
||||
{
|
||||
|
||||
private class TestIndex : LuceneIndex, IUmbracoIndex
|
||||
{
|
||||
private readonly string[] _fieldNames;
|
||||
|
||||
public TestIndex(string name, Directory luceneDirectory, string[] fieldNames)
|
||||
: base(name, luceneDirectory, null, null, null, null)
|
||||
{
|
||||
_fieldNames = fieldNames;
|
||||
}
|
||||
public bool EnableDefaultEventHandler => throw new NotImplementedException();
|
||||
public bool PublishedValuesOnly => throw new NotImplementedException();
|
||||
public IEnumerable<string> GetFields() => _fieldNames;
|
||||
}
|
||||
|
||||
private TestIndex CreateTestIndex(Directory luceneDirectory, string[] fieldNames)
|
||||
{
|
||||
var indexer = new TestIndex("TestIndex", luceneDirectory, fieldNames);
|
||||
|
||||
using (indexer.ProcessNonAsync())
|
||||
{
|
||||
//populate with some test data
|
||||
indexer.IndexItem(new ValueSet("1", "content", new Dictionary<string, object>
|
||||
{
|
||||
[fieldNames[0]] = "Hello world, there are products here",
|
||||
[UmbracoContentIndex.VariesByCultureFieldName] = "n"
|
||||
}));
|
||||
indexer.IndexItem(new ValueSet("2", "content", new Dictionary<string, object>
|
||||
{
|
||||
[fieldNames[1]] = "Hello world, there are products here",
|
||||
[UmbracoContentIndex.VariesByCultureFieldName] = "y"
|
||||
}));
|
||||
indexer.IndexItem(new ValueSet("3", "content", new Dictionary<string, object>
|
||||
{
|
||||
[fieldNames[2]] = "Hello world, there are products here",
|
||||
[UmbracoContentIndex.VariesByCultureFieldName] = "y"
|
||||
}));
|
||||
}
|
||||
|
||||
return indexer;
|
||||
}
|
||||
|
||||
private PublishedContentQuery CreatePublishedContentQuery(IIndex indexer)
|
||||
{
|
||||
var examineManager = new Mock<IExamineManager>();
|
||||
IIndex outarg = indexer;
|
||||
examineManager.Setup(x => x.TryGetIndex("TestIndex", out outarg)).Returns(true);
|
||||
|
||||
var contentCache = new Mock<IPublishedContentCache>();
|
||||
contentCache.Setup(x => x.GetById(It.IsAny<int>())).Returns((int intId) => Mock.Of<IPublishedContent>(x => x.Id == intId));
|
||||
var snapshot = Mock.Of<IPublishedSnapshot>(x => x.Content == contentCache.Object);
|
||||
var variationContext = new VariationContext();
|
||||
var variationContextAccessor = Mock.Of<IVariationContextAccessor>(x => x.VariationContext == variationContext);
|
||||
|
||||
return new PublishedContentQuery(snapshot, variationContextAccessor, examineManager.Object);
|
||||
}
|
||||
|
||||
[TestCase("fr-fr", ExpectedResult = "1, 3", TestName = "Search Culture: fr-fr. Must return both fr-fr and invariant results")]
|
||||
[TestCase("en-us", ExpectedResult = "1, 2", TestName = "Search Culture: en-us. Must return both en-us and invariant results")]
|
||||
[TestCase("*", ExpectedResult = "1, 2, 3", TestName = "Search Culture: *. Must return all cultures and all invariant results")]
|
||||
[TestCase(null, ExpectedResult = "1", TestName = "Search Culture: null. Must return only invariant results")]
|
||||
public string Search(string culture)
|
||||
{
|
||||
using (var luceneDir = new RandomIdRAMDirectory())
|
||||
{
|
||||
var fieldNames = new[] { "title", "title_en-us", "title_fr-fr" };
|
||||
using (var indexer = CreateTestIndex(luceneDir, fieldNames))
|
||||
{
|
||||
var pcq = CreatePublishedContentQuery(indexer);
|
||||
|
||||
var results = pcq.Search("Products", culture, "TestIndex");
|
||||
|
||||
var ids = results.Select(x => x.Content.Id).ToArray();
|
||||
|
||||
return string.Join(", ", ids);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,8 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using Examine.LuceneEngine;
|
||||
using Lucene.Net.Analysis;
|
||||
using Lucene.Net.Analysis.Standard;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core;
|
||||
@@ -13,18 +16,19 @@ using Umbraco.Web;
|
||||
|
||||
namespace Umbraco.Tests.Web
|
||||
{
|
||||
|
||||
[TestFixture]
|
||||
public class UmbracoHelperTests
|
||||
{
|
||||
{
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
Current.Reset();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// ------- Int32 conversion tests
|
||||
[Test]
|
||||
public static void Converting_Boxed_34_To_An_Int_Returns_34()
|
||||
|
||||
+266
-74
File diff suppressed because it is too large
Load Diff
@@ -39,7 +39,7 @@
|
||||
"npm": "^6.4.1",
|
||||
"signalr": "2.4.0",
|
||||
"spectrum-colorpicker": "1.8.0",
|
||||
"tinymce": "4.9.2",
|
||||
"tinymce": "^5.0.12",
|
||||
"typeahead.js": "0.11.1",
|
||||
"underscore": "1.9.1"
|
||||
},
|
||||
|
||||
@@ -94,6 +94,10 @@
|
||||
content.apps[0].active = true;
|
||||
$scope.appChanged(content.apps[0]);
|
||||
}
|
||||
// otherwise make sure the save options are up to date with the current content state
|
||||
else {
|
||||
createButtons($scope.content);
|
||||
}
|
||||
|
||||
editorState.set(content);
|
||||
|
||||
|
||||
+6
-12
@@ -101,14 +101,14 @@ angular.module('umbraco.directives')
|
||||
var eventBindings = [];
|
||||
|
||||
function oneTimeClick(event) {
|
||||
// ignore clicks on button groups toggles (i.e. the save and publish button)
|
||||
var parents = $(event.target).closest("[data-element='button-group-toggle']");
|
||||
if (parents.length > 0) {
|
||||
return;
|
||||
}
|
||||
var el = event.target.nodeName;
|
||||
|
||||
//ignore link and button clicks
|
||||
var els = ["INPUT", "A", "BUTTON"];
|
||||
if (els.indexOf(el) >= 0) { return; }
|
||||
|
||||
// ignore clicks on new overlay
|
||||
parents = $(event.target).parents(".umb-overlay,.umb-tour");
|
||||
var parents = $(event.target).parents("a,button,.umb-overlay,.umb-tour");
|
||||
if (parents.length > 0) {
|
||||
return;
|
||||
}
|
||||
@@ -131,12 +131,6 @@ angular.module('umbraco.directives')
|
||||
return;
|
||||
}
|
||||
|
||||
// ignore clicks on dialog actions
|
||||
var actions = $(event.target).parents(".umb-action");
|
||||
if (actions.length === 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
//ignore clicks inside this element
|
||||
if ($(element).has($(event.target)).length > 0) {
|
||||
return;
|
||||
|
||||
+82
-120
@@ -4,7 +4,7 @@
|
||||
@restrict A
|
||||
|
||||
@description
|
||||
Use this directive make an element sticky and follow the page when scrolling.
|
||||
Use this directive make an element sticky and follow the page when scrolling. `umb-sticky-bar--active` class is applied when the element is stuck
|
||||
|
||||
<h3>Markup example</h3>
|
||||
<pre>
|
||||
@@ -12,140 +12,102 @@ Use this directive make an element sticky and follow the page when scrolling.
|
||||
|
||||
<div
|
||||
class="my-sticky-bar"
|
||||
umb-sticky-bar
|
||||
scrollable-container=".container">
|
||||
umb-sticky-bar>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</pre>
|
||||
|
||||
<h3>CSS example</h3>
|
||||
<pre>
|
||||
.my-sticky-bar {
|
||||
padding: 15px 0;
|
||||
background: #000000;
|
||||
position: relative;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.my-sticky-bar.-umb-sticky-bar {
|
||||
top: 100px;
|
||||
}
|
||||
</pre>
|
||||
|
||||
@param {string} scrollableContainer Set the class (".element") or the id ("#element") of the scrollable container element.
|
||||
**/
|
||||
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
function StickyBarDirective($rootScope) {
|
||||
function StickyBarDirective() {
|
||||
|
||||
/**
|
||||
On initial load, the intersector fires if the grid editor is in the viewport
|
||||
This flag is used to suppress the setClass behaviour on the initial load
|
||||
**/
|
||||
var initial = true;
|
||||
|
||||
/**
|
||||
Toggle `umb-sticky-bar--active` class on the sticky-bar element
|
||||
**/
|
||||
function setClass(addClass, current) {
|
||||
if (!initial) {
|
||||
current.classList.toggle('umb-sticky-bar--active', addClass);
|
||||
} else {
|
||||
initial = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Inserts two elements in the umbStickyBar parent element
|
||||
These are used by the IntersectionObserve to calculate scroll position
|
||||
**/
|
||||
function addSentinels(current) {
|
||||
['-top', '-bottom'].forEach(s => {
|
||||
const sentinel = document.createElement('div');
|
||||
sentinel.classList.add('umb-sticky-sentinel', s);
|
||||
current.parentElement.appendChild(sentinel);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
Calls into setClass when the footer sentinel enters/exits the bottom of the container
|
||||
Container is the parent element of the umbStickyBar element
|
||||
**/
|
||||
function observeFooter(current, container) {
|
||||
const observer = new IntersectionObserver((records, observer) => {
|
||||
let [target, rootBounds, intersected] = [records[0].boundingClientRect, records[0].rootBounds, records[0].intersectionRatio === 1];
|
||||
|
||||
if (target.bottom > rootBounds.top && intersected) {
|
||||
setClass(true, current);
|
||||
}
|
||||
if (target.top < rootBounds.top && target.bottom < rootBounds.bottom) {
|
||||
setClass(false, current);
|
||||
}
|
||||
}, {
|
||||
threshold: [1],
|
||||
root: container
|
||||
});
|
||||
|
||||
observer.observe(current.parentElement.querySelector('.umb-sticky-sentinel.-bottom'));
|
||||
}
|
||||
|
||||
/**
|
||||
Calls into setClass when the header sentinel enters/exits the top of the container
|
||||
Container is the parent element of the umbStickyBar element
|
||||
**/
|
||||
function observeHeader(current, container) {
|
||||
const observer = new IntersectionObserver((records, observer) => {
|
||||
let [target, rootBounds] = [records[0].boundingClientRect, records[0].rootBounds];
|
||||
|
||||
if (target.bottom < rootBounds.top) {
|
||||
setClass(true, current);
|
||||
}
|
||||
|
||||
if (target.bottom >= rootBounds.top && target.bottom < rootBounds.bottom) {
|
||||
setClass(false, current);
|
||||
}
|
||||
}, {
|
||||
threshold: [0],
|
||||
root: container
|
||||
});
|
||||
|
||||
observer.observe(current.parentElement.querySelector('.umb-sticky-sentinel.-top'));
|
||||
}
|
||||
|
||||
function link(scope, el, attr, ctrl) {
|
||||
|
||||
var bar = $(el);
|
||||
var scrollableContainer = null;
|
||||
var clonedBar = null;
|
||||
var cloneIsMade = false;
|
||||
let current = el[0];
|
||||
let container = current.closest('[data-element="editor-container"]');
|
||||
|
||||
function activate() {
|
||||
|
||||
if (bar.parents(".umb-property").length > 1) {
|
||||
bar.addClass("nested");
|
||||
return;
|
||||
}
|
||||
|
||||
if (attr.scrollableContainer) {
|
||||
scrollableContainer = bar.closest(attr.scrollableContainer);
|
||||
} else {
|
||||
scrollableContainer = $(window);
|
||||
}
|
||||
|
||||
scrollableContainer.on('scroll.umbStickyBar', determineVisibility).trigger("scroll");
|
||||
$(window).on('resize.umbStickyBar', determineVisibility);
|
||||
|
||||
scope.$on('$destroy', function () {
|
||||
scrollableContainer.off('.umbStickyBar');
|
||||
$(window).off('.umbStickyBar');
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function determineVisibility() {
|
||||
|
||||
var barTop = bar[0].offsetTop;
|
||||
var scrollTop = scrollableContainer.scrollTop();
|
||||
|
||||
if (scrollTop > barTop) {
|
||||
|
||||
if (!cloneIsMade) {
|
||||
|
||||
createClone();
|
||||
|
||||
clonedBar.css({
|
||||
'visibility': 'visible'
|
||||
});
|
||||
|
||||
} else {
|
||||
|
||||
calculateSize();
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if (cloneIsMade) {
|
||||
|
||||
//remove cloned element (switched places with original on creation)
|
||||
bar.remove();
|
||||
bar = clonedBar;
|
||||
clonedBar = null;
|
||||
|
||||
bar.removeClass('-umb-sticky-bar');
|
||||
bar.css({
|
||||
position: 'relative',
|
||||
'width': 'auto',
|
||||
'height': 'auto',
|
||||
'z-index': 'auto',
|
||||
'visibility': 'visible'
|
||||
});
|
||||
|
||||
cloneIsMade = false;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function calculateSize() {
|
||||
var width = bar.innerWidth();
|
||||
clonedBar.css({
|
||||
width: width + 10 // + 10 (5*2) because we need to add border to avoid seeing the shadow beneath. Look at the CSS.
|
||||
});
|
||||
}
|
||||
|
||||
function createClone() {
|
||||
//switch place with cloned element, to keep binding intact
|
||||
clonedBar = bar;
|
||||
bar = clonedBar.clone();
|
||||
clonedBar.after(bar);
|
||||
clonedBar.addClass('-umb-sticky-bar');
|
||||
clonedBar.css({
|
||||
'position': 'fixed',
|
||||
// if you change this z-index value, make sure the sticky editor sub headers do not
|
||||
// clash with umb-dropdown (e.g. the content actions dropdown in content list view)
|
||||
'z-index': 99,
|
||||
'visibility': 'hidden'
|
||||
});
|
||||
|
||||
cloneIsMade = true;
|
||||
calculateSize();
|
||||
|
||||
}
|
||||
|
||||
activate();
|
||||
addSentinels(current);
|
||||
|
||||
observeHeader(current, container);
|
||||
observeFooter(current, container);
|
||||
}
|
||||
|
||||
var directive = {
|
||||
|
||||
@@ -172,7 +172,7 @@ function entityResource($q, $http, umbRequestHelper) {
|
||||
umbRequestHelper.getApiUrl(
|
||||
"entityApiBaseUrl",
|
||||
"GetUrlAndAnchors",
|
||||
{ id: id })),
|
||||
[{ id: id }])),
|
||||
'Failed to retrieve url and anchors data for id ' + id);
|
||||
},
|
||||
|
||||
@@ -404,7 +404,8 @@ function entityResource($q, $http, umbRequestHelper) {
|
||||
pageNumber: 100,
|
||||
filter: '',
|
||||
orderDirection: "Ascending",
|
||||
orderBy: "SortOrder"
|
||||
orderBy: "SortOrder",
|
||||
dataTypeKey: null
|
||||
};
|
||||
if (options === undefined) {
|
||||
options = {};
|
||||
@@ -421,6 +422,7 @@ function entityResource($q, $http, umbRequestHelper) {
|
||||
options.orderDirection = "Descending";
|
||||
}
|
||||
|
||||
|
||||
return umbRequestHelper.resourcePromise(
|
||||
$http.get(
|
||||
umbRequestHelper.getApiUrl(
|
||||
|
||||
@@ -195,7 +195,8 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
|
||||
//distraction-free = Theme: inlite, inline: true
|
||||
switch (args.mode) {
|
||||
case "classic":
|
||||
modeTheme = "modern";
|
||||
//modeTheme = "modern";
|
||||
modeTheme = "silver";
|
||||
modeInline = false;
|
||||
break;
|
||||
|
||||
@@ -206,7 +207,8 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
|
||||
|
||||
default:
|
||||
//Will default to 'classic'
|
||||
modeTheme = "modern";
|
||||
//modeTheme = "modern";
|
||||
modeTheme = "silver";
|
||||
modeInline = false;
|
||||
break;
|
||||
}
|
||||
@@ -336,10 +338,10 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
|
||||
* @param {Object} editor the TinyMCE editor instance
|
||||
*/
|
||||
createInsertEmbeddedMedia: function (editor, callback) {
|
||||
editor.addButton('umbembeddialog', {
|
||||
editor.ui.registry.addButton('umbembeddialog', {
|
||||
icon: 'custom icon-tv',
|
||||
tooltip: 'Embed',
|
||||
onclick: function () {
|
||||
onAction: function (buttonApi) {
|
||||
if (callback) {
|
||||
angularHelper.safeApply($rootScope, function() {
|
||||
callback();
|
||||
@@ -356,10 +358,10 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
|
||||
|
||||
createAceCodeEditor: function(editor, callback){
|
||||
|
||||
editor.addButton("ace", {
|
||||
editor.ui.registry.addButton("ace", {
|
||||
icon: "code",
|
||||
tooltip: "View Source Code",
|
||||
onclick: function(){
|
||||
onAction: function(buttonApi){
|
||||
if (callback) {
|
||||
angularHelper.safeApply($rootScope, function() {
|
||||
callback();
|
||||
@@ -381,11 +383,11 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
|
||||
* @param {Object} editor the TinyMCE editor instance
|
||||
*/
|
||||
createMediaPicker: function (editor, callback) {
|
||||
editor.addButton('umbmediapicker', {
|
||||
editor.ui.registry.addButton('umbmediapicker', {
|
||||
icon: 'custom icon-picture',
|
||||
tooltip: 'Media Picker',
|
||||
stateSelector: 'img',
|
||||
onclick: function () {
|
||||
onAction: function (buttonApi) {
|
||||
|
||||
|
||||
var selectedElm = editor.selection.getNode(),
|
||||
@@ -428,7 +430,7 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
|
||||
id: '__mcenew',
|
||||
'data-udi': img.udi
|
||||
};
|
||||
|
||||
|
||||
editor.selection.setContent(editor.dom.createHTML('img', data));
|
||||
|
||||
$timeout(function () {
|
||||
@@ -447,9 +449,9 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
|
||||
}
|
||||
}
|
||||
editor.dom.setAttrib(imgElm, 'id', null);
|
||||
|
||||
|
||||
editor.fire('Change');
|
||||
|
||||
|
||||
}, 500);
|
||||
}
|
||||
},
|
||||
@@ -515,13 +517,13 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
|
||||
}
|
||||
|
||||
/** Adds the button instance */
|
||||
editor.addButton('umbmacro', {
|
||||
editor.ui.registry.addButton('umbmacro', {
|
||||
icon: 'custom icon-settings-alt',
|
||||
tooltip: 'Insert macro',
|
||||
onPostRender: function () {
|
||||
|
||||
let ctrl = this;
|
||||
|
||||
|
||||
/**
|
||||
* Check if the macro is currently selected and toggle the menu button
|
||||
*/
|
||||
@@ -543,7 +545,7 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
|
||||
},
|
||||
|
||||
/** The insert macro button click event handler */
|
||||
onclick: function () {
|
||||
onAction: function (buttonApi) {
|
||||
|
||||
var dialogData = {
|
||||
//flag for use in rte so we only show macros flagged for the editor
|
||||
@@ -865,29 +867,29 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
|
||||
});
|
||||
}
|
||||
|
||||
editor.addButton('link', {
|
||||
editor.ui.registry.addButton('link', {
|
||||
icon: 'link',
|
||||
tooltip: 'Insert/edit link',
|
||||
shortcut: 'Ctrl+K',
|
||||
onclick: createLinkList(showDialog),
|
||||
onAction: createLinkList(showDialog),
|
||||
stateSelector: 'a[href]'
|
||||
});
|
||||
|
||||
editor.addButton('unlink', {
|
||||
icon: 'unlink',
|
||||
tooltip: 'Remove link',
|
||||
cmd: 'unlink',
|
||||
stateSelector: 'a[href]'
|
||||
});
|
||||
// editor.ui.registry.addButton('unlink', {
|
||||
// icon: 'unlink',
|
||||
// tooltip: 'Remove link',
|
||||
// cmd: 'unlink',
|
||||
// stateSelector: 'a[href]'
|
||||
// });
|
||||
|
||||
editor.addShortcut('Ctrl+K', '', createLinkList(showDialog));
|
||||
this.showDialog = showDialog;
|
||||
|
||||
editor.addMenuItem('link', {
|
||||
editor.ui.registry.addMenuItem('link', {
|
||||
icon: 'link',
|
||||
text: 'Insert link',
|
||||
shortcut: 'Ctrl+K',
|
||||
onclick: createLinkList(showDialog),
|
||||
onAction: createLinkList(showDialog),
|
||||
stateSelector: 'a[href]',
|
||||
context: 'insert',
|
||||
prependToContext: true
|
||||
@@ -1134,7 +1136,7 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
|
||||
};
|
||||
editorService.linkPicker(linkPicker);
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
//Create the insert media plugin
|
||||
|
||||
+23
-6
@@ -32,15 +32,32 @@
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.umb-editor-sub-header.-umb-sticky-bar {
|
||||
box-shadow: 0 6px 3px -3px rgba(0,0,0,.16);
|
||||
[umb-sticky-bar] {
|
||||
transition: box-shadow 240ms;
|
||||
margin-top: 0;
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
top: calc(@appHeaderHeight + @editorHeaderHeight);
|
||||
position:sticky;
|
||||
z-index: 99;
|
||||
|
||||
.umb-editor--infinityMode & {
|
||||
top: calc(@editorHeaderHeight);
|
||||
&.umb-sticky-bar--active {
|
||||
box-shadow: 0 6px 3px -3px rgba(0,0,0,.16);
|
||||
}
|
||||
}
|
||||
|
||||
.umb-sticky-sentinel {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
pointer-events: none;
|
||||
|
||||
&.-top {
|
||||
top:0px;
|
||||
height:1px;
|
||||
}
|
||||
|
||||
&.-bottom {
|
||||
bottom:50px;
|
||||
height:10px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
// --------------------------------------------------
|
||||
.umb-property-editor {
|
||||
width: 100%;
|
||||
position:relative;
|
||||
}
|
||||
|
||||
.umb-property-editor-tiny {
|
||||
@@ -165,8 +166,6 @@
|
||||
.sp-replacer {
|
||||
display: inline-flex;
|
||||
margin-right: 18px;
|
||||
border: solid 1px @gray-8;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
label {
|
||||
|
||||
+2
-2
@@ -59,10 +59,10 @@ angular.module("umbraco").controller("Umbraco.Editors.LinkPickerController",
|
||||
if (dialogOptions.currentTarget) {
|
||||
// clone the current target so we don't accidentally update the caller's model while manipulating $scope.model.target
|
||||
$scope.model.target = angular.copy(dialogOptions.currentTarget);
|
||||
//if we have a node ID, we fetch the current node to build the form data
|
||||
// if we have a node ID, we fetch the current node to build the form data
|
||||
if ($scope.model.target.id || $scope.model.target.udi) {
|
||||
|
||||
//will be either a udi or an int
|
||||
// will be either a udi or an int
|
||||
var id = $scope.model.target.udi ? $scope.model.target.udi : $scope.model.target.id;
|
||||
|
||||
if ($scope.model.target.udi) {
|
||||
|
||||
+8
-3
@@ -51,13 +51,17 @@ angular.module("umbraco")
|
||||
$scope.acceptedMediatypes = types;
|
||||
});
|
||||
|
||||
var dataTypeKey = null;
|
||||
if($scope.model && $scope.model.dataTypeKey) {
|
||||
dataTypeKey = $scope.model.dataTypeKey;
|
||||
}
|
||||
$scope.searchOptions = {
|
||||
pageNumber: 1,
|
||||
pageSize: 100,
|
||||
totalItems: 0,
|
||||
totalPages: 0,
|
||||
filter: '',
|
||||
dataTypeKey: $scope.model.dataTypeKey
|
||||
dataTypeKey: dataTypeKey
|
||||
};
|
||||
|
||||
//preload selected item
|
||||
@@ -160,7 +164,7 @@ angular.module("umbraco")
|
||||
}
|
||||
|
||||
if (folder.id > 0) {
|
||||
entityResource.getAncestors(folder.id, "media", null, { dataTypeKey: $scope.model.dataTypeKey })
|
||||
entityResource.getAncestors(folder.id, "media", null, { dataTypeKey: dataTypeKey })
|
||||
.then(function (anc) {
|
||||
$scope.path = _.filter(anc,
|
||||
function (f) {
|
||||
@@ -311,6 +315,7 @@ angular.module("umbraco")
|
||||
if ($scope.searchOptions.filter) {
|
||||
searchMedia();
|
||||
} else {
|
||||
|
||||
// reset pagination
|
||||
$scope.searchOptions = {
|
||||
pageNumber: 1,
|
||||
@@ -318,7 +323,7 @@ angular.module("umbraco")
|
||||
totalItems: 0,
|
||||
totalPages: 0,
|
||||
filter: '',
|
||||
dataTypeKey: $scope.model.dataTypeKey
|
||||
dataTypeKey: dataTypeKey
|
||||
};
|
||||
getChildren($scope.currentFolder.id);
|
||||
}
|
||||
|
||||
-1
@@ -1,6 +1,5 @@
|
||||
<div
|
||||
class="umb-editor-sub-header umb-editor-sub-header--{{appearance}}"
|
||||
umb-sticky-bar
|
||||
scrollable-container=".umb-editor-container"
|
||||
ng-transclude>
|
||||
</div>
|
||||
|
||||
@@ -10,11 +10,12 @@
|
||||
vm.numberOfErrors = 0;
|
||||
vm.commonLogMessages = [];
|
||||
vm.commonLogMessagesCount = 10;
|
||||
vm.dateRangeLabel = "";
|
||||
|
||||
// ChartJS Options - for count/overview of log distribution
|
||||
vm.logTypeLabels = ["Info", "Debug", "Warning", "Error", "Critical"];
|
||||
vm.logTypeLabels = ["Debug", "Info", "Warning", "Error", "Fatal"];
|
||||
vm.logTypeData = [0, 0, 0, 0, 0];
|
||||
vm.logTypeColors = [ '#dcdcdc', '#97bbcd', '#46bfbd', '#fdb45c', '#f7464a'];
|
||||
vm.logTypeColors = ['#eaddd5', '#2bc37c', '#3544b1', '#ff9412', '#d42054'];
|
||||
vm.chartOptions = {
|
||||
legend: {
|
||||
display: true,
|
||||
@@ -23,35 +24,42 @@
|
||||
};
|
||||
|
||||
let querystring = $location.search();
|
||||
if(querystring.startDate){
|
||||
if (querystring.startDate) {
|
||||
vm.startDate = querystring.startDate;
|
||||
}else{
|
||||
vm.dateRangeLabel = getDateRangeLabel("Selected Time Period");
|
||||
} else {
|
||||
vm.startDate = new Date(Date.now());
|
||||
vm.startDate.setDate(vm.startDate.getDate()-1);
|
||||
vm.startDate.setDate(vm.startDate.getDate() - 1);
|
||||
vm.startDate = vm.startDate.toIsoDateString();
|
||||
vm.dateRangeLabel = getDateRangeLabel("Today");
|
||||
}
|
||||
|
||||
if(querystring.endDate){
|
||||
if (querystring.endDate) {
|
||||
vm.endDate = querystring.endDate;
|
||||
}else{
|
||||
|
||||
if (querystring.endDate === querystring.startDate) {
|
||||
vm.dateRangeLabel = getDateRangeLabel("Selected Date");
|
||||
}
|
||||
} else {
|
||||
vm.endDate = new Date(Date.now()).toIsoDateString();
|
||||
}
|
||||
vm.period = [vm.startDate, vm.endDate];
|
||||
|
||||
vm.period = [vm.startDate, vm.endDate];
|
||||
|
||||
//functions
|
||||
vm.searchLogQuery = searchLogQuery;
|
||||
vm.findMessageTemplate = findMessageTemplate;
|
||||
|
||||
vm.searchErrors = searchErrors;
|
||||
|
||||
function preFlightCheck(){
|
||||
vm.loading = true;
|
||||
//Do our pre-flight check (to see if we can view logs)
|
||||
//IE the log file is NOT too big such as 1GB & crash the site
|
||||
logViewerResource.canViewLogs(vm.startDate, vm.endDate).then(function(result){
|
||||
logViewerResource.canViewLogs(vm.startDate, vm.endDate).then(function (result) {
|
||||
vm.loading = false;
|
||||
vm.canLoadLogs = result;
|
||||
|
||||
if(result){
|
||||
if (result) {
|
||||
//Can view logs - so initalise
|
||||
init();
|
||||
}
|
||||
@@ -62,39 +70,39 @@
|
||||
function init() {
|
||||
|
||||
vm.loading = true;
|
||||
|
||||
|
||||
var savedSearches = logViewerResource.getSavedSearches().then(function (data) {
|
||||
vm.searches = data;
|
||||
},
|
||||
// fallback to some defaults if error from API response
|
||||
function () {
|
||||
vm.searches = [
|
||||
{
|
||||
"name": "Find all logs where the Level is NOT Verbose and NOT Debug",
|
||||
"query": "Not(@Level='Verbose') and Not(@Level='Debug')"
|
||||
vm.searches = data;
|
||||
},
|
||||
// fallback to some defaults if error from API response
|
||||
function () {
|
||||
vm.searches = [
|
||||
{
|
||||
"name": "Find all logs where the Level is NOT Verbose and NOT Debug",
|
||||
"query": "Not(@Level='Verbose') and Not(@Level='Debug')"
|
||||
},
|
||||
{
|
||||
"name": "Find all logs that has an exception property (Warning, Error & Critical with Exceptions)",
|
||||
"query": "Has(@Exception)"
|
||||
{
|
||||
"name": "Find all logs that has an exception property (Warning, Error & Fatal with Exceptions)",
|
||||
"query": "Has(@Exception)"
|
||||
},
|
||||
{
|
||||
"name": "Find all logs that have the property 'Duration'",
|
||||
"query": "Has(Duration)"
|
||||
{
|
||||
"name": "Find all logs that have the property 'Duration'",
|
||||
"query": "Has(Duration)"
|
||||
},
|
||||
{
|
||||
"name": "Find all logs that have the property 'Duration' and the duration is greater than 1000ms",
|
||||
"query": "Has(Duration) and Duration > 1000"
|
||||
{
|
||||
"name": "Find all logs that have the property 'Duration' and the duration is greater than 1000ms",
|
||||
"query": "Has(Duration) and Duration > 1000"
|
||||
},
|
||||
{
|
||||
"name": "Find all logs that are from the namespace 'Umbraco.Core'",
|
||||
"query": "StartsWith(SourceContext, 'Umbraco.Core')"
|
||||
{
|
||||
"name": "Find all logs that are from the namespace 'Umbraco.Core'",
|
||||
"query": "StartsWith(SourceContext, 'Umbraco.Core')"
|
||||
},
|
||||
{
|
||||
"name": "Find all logs that use a specific log message template",
|
||||
"query": "@MessageTemplate = '[Timing {TimingId}] {EndMessage} ({TimingDuration}ms)'"
|
||||
{
|
||||
"name": "Find all logs that use a specific log message template",
|
||||
"query": "@MessageTemplate = '[Timing {TimingId}] {EndMessage} ({TimingDuration}ms)'"
|
||||
}
|
||||
]
|
||||
});
|
||||
});
|
||||
|
||||
var numOfErrors = logViewerResource.getNumberOfErrors(vm.startDate, vm.endDate).then(function (data) {
|
||||
vm.numberOfErrors = data;
|
||||
@@ -102,41 +110,56 @@
|
||||
|
||||
var logCounts = logViewerResource.getLogLevelCounts(vm.startDate, vm.endDate).then(function (data) {
|
||||
vm.logTypeData = [];
|
||||
vm.logTypeData.push(data.Information);
|
||||
vm.logTypeData.push(data.Debug);
|
||||
vm.logTypeData.push(data.Warning);
|
||||
vm.logTypeData.push(data.Error);
|
||||
vm.logTypeData.push(data.Fatal);
|
||||
|
||||
for (let [key, value] of Object.entries(data)) {
|
||||
const index = vm.logTypeLabels.findIndex(x => key.startsWith(x));
|
||||
if (index > -1) {
|
||||
vm.logTypeData[index] = value;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var commonMsgs = logViewerResource.getMessageTemplates(vm.startDate, vm.endDate).then(function(data){
|
||||
var commonMsgs = logViewerResource.getMessageTemplates(vm.startDate, vm.endDate).then(function (data) {
|
||||
vm.commonLogMessages = data;
|
||||
});
|
||||
|
||||
//Set loading indicatior to false when these 3 queries complete
|
||||
$q.all([savedSearches, numOfErrors, logCounts, commonMsgs]).then(function(data) {
|
||||
//Set loading indicator to false when these 3 queries complete
|
||||
$q.all([savedSearches, numOfErrors, logCounts, commonMsgs]).then(function () {
|
||||
vm.loading = false;
|
||||
});
|
||||
|
||||
$timeout(function () {
|
||||
navigationService.syncTree({ tree: "logViewer", path: "-1" });
|
||||
navigationService.syncTree({
|
||||
tree: "logViewer",
|
||||
path: "-1"
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function searchLogQuery(logQuery){
|
||||
$location.path("/settings/logViewer/search").search({lq: logQuery, startDate: vm.startDate, endDate: vm.endDate});
|
||||
function searchLogQuery(logQuery) {
|
||||
$location.path("/settings/logViewer/search").search({
|
||||
lq: logQuery,
|
||||
startDate: vm.startDate,
|
||||
endDate: vm.endDate
|
||||
});
|
||||
}
|
||||
|
||||
function findMessageTemplate(template){
|
||||
function findMessageTemplate(template) {
|
||||
var logQuery = "@MessageTemplate='" + template.MessageTemplate + "'";
|
||||
searchLogQuery(logQuery);
|
||||
}
|
||||
|
||||
|
||||
|
||||
function getDateRangeLabel(suffix) {
|
||||
return "Log Overview for " + suffix;
|
||||
}
|
||||
|
||||
function searchErrors(){
|
||||
var logQuery = "@Level='Fatal' or @Level='Error' or Has(@Exception)";
|
||||
searchLogQuery(logQuery);
|
||||
}
|
||||
|
||||
preFlightCheck();
|
||||
|
||||
|
||||
/////////////////////
|
||||
|
||||
vm.config = {
|
||||
@@ -147,20 +170,21 @@
|
||||
maxDate: "today",
|
||||
conjunction: " to "
|
||||
};
|
||||
|
||||
vm.dateRangeChange = function(selectedDates, dateStr, instance) {
|
||||
|
||||
if(selectedDates.length > 0){
|
||||
vm.startDate = selectedDates[0].toIsoDateString();
|
||||
vm.endDate = selectedDates[selectedDates.length-1].toIsoDateString(); // Take the last date as end
|
||||
|
||||
if(vm.startDate === vm.endDate){
|
||||
vm.period = [vm.startDate];
|
||||
}else{
|
||||
vm.period = [vm.startDate, vm.endDate];
|
||||
}
|
||||
|
||||
preFlightCheck();
|
||||
vm.dateRangeChange = function (selectedDates, dateStr, instance) {
|
||||
|
||||
if (selectedDates.length > 0) {
|
||||
|
||||
// Update view by re-requesting route with updated querystring.
|
||||
// By doing this we make sure the URL matches the selected time period, aiding sharing the link.
|
||||
// Also resolves a minor layout issue where the " to " conjunction between the selected dates
|
||||
// is collapsed to a comma.
|
||||
const startDate = selectedDates[0].toIsoDateString();
|
||||
const endDate = selectedDates[selectedDates.length - 1].toIsoDateString(); // Take the last date as end
|
||||
$location.path("/settings/logViewer/overview").search({
|
||||
startDate: startDate,
|
||||
endDate: endDate
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<umb-editor-view footer="false">
|
||||
|
||||
<umb-editor-header
|
||||
name="'Log Overview for Today'"
|
||||
name="vm.dateRangeLabel"
|
||||
name-locked="true"
|
||||
hide-icon="true"
|
||||
hide-description="true"
|
||||
@@ -74,17 +74,16 @@
|
||||
<umb-box>
|
||||
<umb-box-header title="Time Period"></umb-box-header>
|
||||
|
||||
<umb-flatpickr
|
||||
class="datepicker"
|
||||
ng-model="vm.period"
|
||||
options="vm.config"
|
||||
on-close="vm.dateRangeChange(selectedDates, dateStr, instance)">
|
||||
<umb-flatpickr class="datepicker"
|
||||
ng-model="vm.period"
|
||||
options="vm.config"
|
||||
on-close="vm.dateRangeChange(selectedDates, dateStr, instance)">
|
||||
</umb-flatpickr>
|
||||
</umb-box>
|
||||
|
||||
<div ng-show=" vm.canLoadLogs">
|
||||
<!-- No of Errors -->
|
||||
<umb-box ng-click="vm.searchLogQuery('Has(@Exception)')" style="cursor:pointer;">
|
||||
<umb-box ng-click="vm.searchErrors()" style="cursor:pointer;">
|
||||
<umb-box-header title="Number of Errors"></umb-box-header>
|
||||
<umb-box-content class="block-form" style="font-size: 40px; font-weight:900; text-align:center; color:#fe6561;">
|
||||
{{ vm.numberOfErrors }}
|
||||
|
||||
@@ -11,26 +11,28 @@
|
||||
vm.showBackButton = true;
|
||||
vm.page = {};
|
||||
|
||||
// this array is also used to map the logTypeColor param onto the log items
|
||||
// in setLogTypeColors()
|
||||
vm.logLevels = [
|
||||
{
|
||||
name: 'Verbose',
|
||||
logTypeColor: 'gray'
|
||||
logTypeColor: ''
|
||||
},
|
||||
{
|
||||
name: 'Debug',
|
||||
logTypeColor: 'secondary'
|
||||
logTypeColor: 'gray'
|
||||
},
|
||||
{
|
||||
name: 'Information',
|
||||
logTypeColor: 'primary'
|
||||
logTypeColor: 'success'
|
||||
},
|
||||
{
|
||||
name: 'Warning',
|
||||
logTypeColor: 'warning'
|
||||
logTypeColor: 'primary'
|
||||
},
|
||||
{
|
||||
name: 'Error',
|
||||
logTypeColor: 'danger'
|
||||
logTypeColor: 'warning'
|
||||
},
|
||||
{
|
||||
name: 'Fatal',
|
||||
@@ -118,7 +120,7 @@
|
||||
"query": "Not(@Level='Verbose') and Not(@Level='Debug')"
|
||||
},
|
||||
{
|
||||
"name": "Find all logs that has an exception property (Warning, Error & Critical with Exceptions)",
|
||||
"name": "Find all logs that has an exception property (Warning, Error & Fatal with Exceptions)",
|
||||
"query": "Has(@Exception)"
|
||||
},
|
||||
{
|
||||
@@ -173,25 +175,8 @@
|
||||
}
|
||||
|
||||
function setLogTypeColor(logItems) {
|
||||
angular.forEach(logItems, function (log) {
|
||||
switch (log.Level) {
|
||||
case "Information":
|
||||
log.logTypeColor = "primary";
|
||||
break;
|
||||
case "Debug":
|
||||
log.logTypeColor = "secondary";
|
||||
break;
|
||||
case "Warning":
|
||||
log.logTypeColor = "warning";
|
||||
break;
|
||||
case "Fatal":
|
||||
case "Error":
|
||||
log.logTypeColor = "danger";
|
||||
break;
|
||||
default:
|
||||
log.logTypeColor = "gray";
|
||||
}
|
||||
});
|
||||
logItems.forEach(logItem =>
|
||||
logItem.logTypeColor = vm.logLevels.find(x => x.name === logItem.Level).logTypeColor);
|
||||
}
|
||||
|
||||
function getFilterName(array) {
|
||||
|
||||
+2
@@ -19,6 +19,7 @@
|
||||
$scope.hasError = false;
|
||||
|
||||
$scope.internal = function ($event) {
|
||||
|
||||
$scope.currentEditLink = null;
|
||||
|
||||
var contentPicker = {
|
||||
@@ -41,6 +42,7 @@
|
||||
};
|
||||
|
||||
$scope.selectInternal = function ($event, link) {
|
||||
|
||||
$scope.currentEditLink = link;
|
||||
|
||||
var contentPicker = {
|
||||
|
||||
@@ -48,18 +48,19 @@ angular.module("umbraco")
|
||||
$q.all(promises).then(function (result) {
|
||||
|
||||
var standardConfig = result[promises.length - 1];
|
||||
|
||||
|
||||
if (height !== null) {
|
||||
standardConfig.plugins.splice(standardConfig.plugins.indexOf("autoresize"), 1);
|
||||
}
|
||||
|
||||
|
||||
//create a baseline Config to extend upon
|
||||
var baseLineConfigObj = {
|
||||
maxImageSize: editorConfig.maxImageSize,
|
||||
width: width,
|
||||
height: height
|
||||
maxImageSize: editorConfig.maxImageSize
|
||||
//width: width,
|
||||
//height: height
|
||||
};
|
||||
|
||||
|
||||
angular.extend(baseLineConfigObj, standardConfig);
|
||||
|
||||
baseLineConfigObj.setup = function (editor) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<div ng-controller="Umbraco.PropertyEditors.RTEController" class="umb-property-editor umb-rte">
|
||||
<umb-load-indicator ng-if="isLoading"></umb-load-indicator>
|
||||
|
||||
<div ng-style="{ visibility : isLoading ? 'hidden' : 'visible', width :containerWidth, height: containerHeight, overflow: containerOverflow}"
|
||||
<div ng-style="{ visibility : isLoading ? 'hidden' : 'visible', overflow: containerOverflow}"
|
||||
id="{{textAreaHtmlId}}" class="umb-rte-editor"></div>
|
||||
</div>
|
||||
|
||||
@@ -345,9 +345,9 @@
|
||||
<WebProjectProperties>
|
||||
<UseIIS>False</UseIIS>
|
||||
<AutoAssignPort>True</AutoAssignPort>
|
||||
<DevelopmentServerPort>8100</DevelopmentServerPort>
|
||||
<DevelopmentServerPort>8200</DevelopmentServerPort>
|
||||
<DevelopmentServerVPath>/</DevelopmentServerVPath>
|
||||
<IISUrl>http://localhost:8100</IISUrl>
|
||||
<IISUrl>http://localhost:8200</IISUrl>
|
||||
<NTLMAuthentication>False</NTLMAuthentication>
|
||||
<UseCustomServer>False</UseCustomServer>
|
||||
<CustomServerUrl>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"query": "Not(@Level='Verbose') and Not(@Level='Debug')"
|
||||
},
|
||||
{
|
||||
"name": "Find all logs that has an exception property (Warning, Error & Critical with Exceptions)",
|
||||
"name": "Find all logs that has an exception property (Warning, Error & Fatal with Exceptions)",
|
||||
"query": "Has(@Exception)"
|
||||
},
|
||||
{
|
||||
|
||||
@@ -26,12 +26,13 @@
|
||||
<add key="serilog:write-to:File.restrictedToMinimumLevel" value="Debug" />
|
||||
<add key="serilog:write-to:File.retainedFileCountLimit" value="32" />--> <!-- Number of log files to keep (or remove value to keep all files) -->
|
||||
<!--<add key="serilog:write-to:File.rollingInterval" value="Day" />--> <!-- Create a new log file every Minute/Hour/Day/Month/Year/infinite -->
|
||||
<!--<add key="serilog:write-to:File.outputTemplate" value="{Timestamp:yyyy-MM-dd HH:mm:ss,fff} [P{ProcessId}/D{AppDomainId}/T{ThreadId}] {Log4NetLevel} {SourceContext} - {Message:lj}{NewLine}{Exception}" /> -->
|
||||
|
||||
<!-- Filters all above sink's to use this expression -->
|
||||
<!-- Common use case is to include SourceType starting with your own namespace -->
|
||||
<!--
|
||||
<add key="serilog:using:FilterExpressions" value="Serilog.Filters.Expressions" />
|
||||
<add key="serilog:filter:ByIncluding.expression" value="StartsWith(SourceContext, 'Umbraco.Core')" />
|
||||
<add key="serilog:filter:ByIncludingOnly.expression" value="StartsWith(SourceContext, 'Umbraco.Core')" />
|
||||
-->
|
||||
|
||||
</appSettings>
|
||||
|
||||
@@ -22,6 +22,7 @@ namespace Umbraco.Web.Controllers
|
||||
|
||||
[HttpPost]
|
||||
[ValidateAntiForgeryToken]
|
||||
[ValidateUmbracoFormRouteString]
|
||||
public ActionResult HandleLogin([Bind(Prefix = "loginModel")]LoginModel model)
|
||||
{
|
||||
if (ModelState.IsValid == false)
|
||||
|
||||
@@ -24,6 +24,7 @@ namespace Umbraco.Web.Controllers
|
||||
|
||||
[HttpPost]
|
||||
[ValidateAntiForgeryToken]
|
||||
[ValidateUmbracoFormRouteString]
|
||||
public ActionResult HandleLogout([Bind(Prefix = "logoutModel")]PostRedirectModel model)
|
||||
{
|
||||
if (ModelState.IsValid == false)
|
||||
|
||||
@@ -23,6 +23,7 @@ namespace Umbraco.Web.Controllers
|
||||
|
||||
[HttpPost]
|
||||
[ValidateAntiForgeryToken]
|
||||
[ValidateUmbracoFormRouteString]
|
||||
public ActionResult HandleUpdateProfile([Bind(Prefix = "profileModel")] ProfileModel model)
|
||||
{
|
||||
var provider = Core.Security.MembershipProviderExtensions.GetMembersMembershipProvider();
|
||||
|
||||
@@ -24,6 +24,7 @@ namespace Umbraco.Web.Controllers
|
||||
|
||||
[HttpPost]
|
||||
[ValidateAntiForgeryToken]
|
||||
[ValidateUmbracoFormRouteString]
|
||||
public ActionResult HandleRegisterMember([Bind(Prefix = "registerModel")]RegisterModel model)
|
||||
{
|
||||
if (ModelState.IsValid == false)
|
||||
|
||||
@@ -74,6 +74,7 @@ namespace Umbraco.Web.Editors
|
||||
//id is passed in eventually we'll probably want to support GUID + Udi too
|
||||
new ParameterSwapControllerActionSelector.ParameterSwapInfo("GetPagedChildren", "id", typeof(int), typeof(string)),
|
||||
new ParameterSwapControllerActionSelector.ParameterSwapInfo("GetPath", "id", typeof(int), typeof(Guid), typeof(Udi)),
|
||||
new ParameterSwapControllerActionSelector.ParameterSwapInfo("GetUrlAndAnchors", "id", typeof(int), typeof(Guid), typeof(Udi)),
|
||||
new ParameterSwapControllerActionSelector.ParameterSwapInfo("GetById", "id", typeof(int), typeof(Guid), typeof(Udi)),
|
||||
new ParameterSwapControllerActionSelector.ParameterSwapInfo("GetByIds", "ids", typeof(int[]), typeof(Guid[]), typeof(Udi[]))));
|
||||
}
|
||||
@@ -288,7 +289,16 @@ namespace Umbraco.Web.Editors
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public UrlAndAnchors GetUrlAndAnchors([FromUri]int id, [FromUri]string culture = "*")
|
||||
public UrlAndAnchors GetUrlAndAnchors(Udi id, string culture = "*")
|
||||
{
|
||||
var intId = Services.EntityService.GetId(id);
|
||||
if (!intId.Success)
|
||||
throw new HttpResponseException(HttpStatusCode.NotFound);
|
||||
|
||||
return GetUrlAndAnchors(intId.Result, culture);
|
||||
}
|
||||
[HttpGet]
|
||||
public UrlAndAnchors GetUrlAndAnchors(int id, string culture = "*")
|
||||
{
|
||||
var url = UmbracoContext.UrlProvider.GetUrl(id);
|
||||
var anchorValues = Services.ContentService.GetAnchorValuesFromRTEs(id, culture);
|
||||
|
||||
@@ -85,7 +85,7 @@ namespace Umbraco.Web.Editors
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Check if the index has been rebuilt
|
||||
@@ -250,7 +250,7 @@ namespace Umbraco.Web.Editors
|
||||
|
||||
private void Indexer_IndexOperationComplete(object sender, EventArgs e)
|
||||
{
|
||||
var indexer = (LuceneIndex)sender;
|
||||
var indexer = (IIndex)sender;
|
||||
|
||||
_logger.Debug<ExamineManagementController>("Logging operation completed for index {IndexName}", indexer.Name);
|
||||
|
||||
@@ -259,7 +259,7 @@ namespace Umbraco.Web.Editors
|
||||
|
||||
_logger
|
||||
.Info<ExamineManagementController
|
||||
>($"Rebuilding index '{indexer.Name}' done, {indexer.CommitCount} items committed (can differ from the number of items in the index)");
|
||||
>($"Rebuilding index '{indexer.Name}' done.");
|
||||
|
||||
var cacheKey = "temp_indexing_op_" + indexer.Name;
|
||||
_runtimeCache.Clear(cacheKey);
|
||||
|
||||
@@ -15,11 +15,11 @@ namespace Umbraco.Web.Editors
|
||||
[PluginController("UmbracoApi")]
|
||||
public class LogViewerController : UmbracoAuthorizedJsonController
|
||||
{
|
||||
private ILogViewer _logViewer;
|
||||
private readonly ILogViewer _logViewer;
|
||||
|
||||
public LogViewerController(ILogViewer logViewer)
|
||||
{
|
||||
_logViewer = logViewer;
|
||||
_logViewer = logViewer ?? throw new ArgumentNullException(nameof(logViewer));
|
||||
}
|
||||
|
||||
private bool CanViewLogs(LogTimePeriod logTimePeriod)
|
||||
@@ -91,8 +91,6 @@ namespace Umbraco.Web.Editors
|
||||
|
||||
var direction = orderDirection == "Descending" ? Direction.Descending : Direction.Ascending;
|
||||
|
||||
|
||||
|
||||
return _logViewer.GetLogs(logTimePeriod, filterExpression: filterExpression, pageNumber: pageNumber, orderDirection: direction, logLevels: logLevels);
|
||||
}
|
||||
|
||||
|
||||
@@ -223,14 +223,6 @@ namespace Umbraco.Web
|
||||
_method = method;
|
||||
_controllerName = controllerName;
|
||||
_encryptedString = UrlHelperRenderExtensions.CreateEncryptedRouteString(controllerName, controllerAction, area, additionalRouteVals);
|
||||
|
||||
//For UmbracoForm's we want to add our routing string to the httpcontext items in the case where anti-forgery tokens are used.
|
||||
//In which case our custom UmbracoAntiForgeryAdditionalDataProvider will kick in and validate the values in the request against
|
||||
//the values that will be appended to the token. This essentially means that when anti-forgery tokens are used with UmbracoForm's forms,
|
||||
//that each token is unique to the controller/action/area instead of the default ASP.Net implementation which is that the token is unique
|
||||
//per user.
|
||||
_viewContext.HttpContext.Items["ufprt"] = _encryptedString;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -39,10 +39,14 @@ namespace Umbraco.Web
|
||||
/// <param name="culture">Optional culture.</param>
|
||||
/// <param name="indexName">Optional index name.</param>
|
||||
/// <remarks>
|
||||
/// <para>When the <paramref name="culture"/> is not specified, all cultures are searched.</para>
|
||||
/// <para>
|
||||
/// When the <paramref name="culture"/> is not specified or is *, all cultures are searched.
|
||||
/// To search for only invariant documents and fields use null.
|
||||
/// When searching on a specific culture, all culture specific fields are searched for the provided culture and all invariant fields for all documents.
|
||||
/// </para>
|
||||
/// <para>While enumerating results, the ambient culture is changed to be the searched culture.</para>
|
||||
/// </remarks>
|
||||
IEnumerable<PublishedSearchResult> Search(string term, string culture = null, string indexName = null);
|
||||
IEnumerable<PublishedSearchResult> Search(string term, string culture = "*", string indexName = null);
|
||||
|
||||
/// <summary>
|
||||
/// Searches content.
|
||||
@@ -54,10 +58,14 @@ namespace Umbraco.Web
|
||||
/// <param name="culture">Optional culture.</param>
|
||||
/// <param name="indexName">Optional index name.</param>
|
||||
/// <remarks>
|
||||
/// <para>When the <paramref name="culture"/> is not specified, all cultures are searched.</para>
|
||||
/// <para>
|
||||
/// When the <paramref name="culture"/> is not specified or is *, all cultures are searched.
|
||||
/// To search for only invariant documents and fields use null.
|
||||
/// When searching on a specific culture, all culture specific fields are searched for the provided culture and all invariant fields for all documents.
|
||||
/// </para>
|
||||
/// <para>While enumerating results, the ambient culture is changed to be the searched culture.</para>
|
||||
/// </remarks>
|
||||
IEnumerable<PublishedSearchResult> Search(string term, int skip, int take, out long totalRecords, string culture = null, string indexName = null);
|
||||
IEnumerable<PublishedSearchResult> Search(string term, int skip, int take, out long totalRecords, string culture = "*", string indexName = null);
|
||||
|
||||
/// <summary>
|
||||
/// Executes the query and converts the results to PublishedSearchResult.
|
||||
|
||||
@@ -106,8 +106,10 @@ namespace Umbraco.Web.JavaScript
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var fullPath = currentHttpContext.Server.MapPath(XmlFileMapper.FileMapDefaultFolder);
|
||||
{
|
||||
var fullPath = XmlFileMapper.FileMapDefaultFolder.StartsWith("~/")
|
||||
? currentHttpContext.Server.MapPath(XmlFileMapper.FileMapDefaultFolder)
|
||||
: XmlFileMapper.FileMapDefaultFolder;
|
||||
if (fullPath != null)
|
||||
{
|
||||
cdfTempDirectories.Add(fullPath);
|
||||
@@ -122,13 +124,12 @@ namespace Umbraco.Web.JavaScript
|
||||
var success = true;
|
||||
foreach (var directory in cdfTempDirectories)
|
||||
{
|
||||
var directoryInfo = new DirectoryInfo(directory);
|
||||
if (directoryInfo.Exists == false)
|
||||
continue;
|
||||
|
||||
try
|
||||
{
|
||||
directoryInfo.Delete(true);
|
||||
if (!Directory.Exists(directory))
|
||||
continue;
|
||||
|
||||
Directory.Delete(directory, true);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Web;
|
||||
|
||||
namespace Umbraco.Web.Mvc
|
||||
{
|
||||
/// <summary>
|
||||
/// Exception that occurs when an Umbraco form route string is invalid
|
||||
/// </summary>
|
||||
/// <seealso cref="System.Web.HttpException" />
|
||||
[Serializable]
|
||||
public sealed class HttpUmbracoFormRouteStringException : HttpException
|
||||
{
|
||||
/// Initializes a new instance of the <see cref="HttpUmbracoFormRouteStringException" /> class.
|
||||
/// </summary>
|
||||
/// <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo" /> that holds the serialized object data about the exception being thrown.</param>
|
||||
/// <param name="context">The <see cref="T:System.Runtime.Serialization.StreamingContext" /> that holds the contextual information about the source or destination.</param>
|
||||
private HttpUmbracoFormRouteStringException(SerializationInfo info, StreamingContext context)
|
||||
: base(info, context)
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="HttpUmbracoFormRouteStringException" /> class.
|
||||
/// </summary>
|
||||
/// <param name="message">The error message displayed to the client when the exception is thrown.</param>
|
||||
public HttpUmbracoFormRouteStringException(string message)
|
||||
: base(message)
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="HttpUmbracoFormRouteStringException" /> class.
|
||||
/// </summary>
|
||||
/// <param name="message">The error message displayed to the client when the exception is thrown.</param>
|
||||
/// <param name="innerException">The <see cref="P:System.Exception.InnerException" />, if any, that threw the current exception.</param>
|
||||
public HttpUmbracoFormRouteStringException(string message, Exception innerException)
|
||||
: base(message, innerException)
|
||||
{ }
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Web.Mvc;
|
||||
using Umbraco.Core;
|
||||
|
||||
namespace Umbraco.Web.Mvc
|
||||
{
|
||||
/// <summary>
|
||||
/// Attribute used to check that the request contains a valid Umbraco form request string.
|
||||
/// </summary>
|
||||
/// <seealso cref="System.Web.Mvc.FilterAttribute" />
|
||||
/// <seealso cref="System.Web.Mvc.IAuthorizationFilter" />
|
||||
/// <remarks>
|
||||
/// Applying this attribute/filter to a <see cref="SurfaceController"/> or SurfaceController Action will ensure that the Action can only be executed
|
||||
/// when it is routed to from within Umbraco, typically when rendering a form with BegingUmbracoForm. It will mean that the natural MVC route for this Action
|
||||
/// will fail with a <see cref="HttpUmbracoFormRouteStringException"/>.
|
||||
/// </remarks>
|
||||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
|
||||
public sealed class ValidateUmbracoFormRouteStringAttribute : FilterAttribute, IAuthorizationFilter
|
||||
{
|
||||
/// <summary>
|
||||
/// Called when authorization is required.
|
||||
/// </summary>
|
||||
/// <param name="filterContext">The filter context.</param>
|
||||
/// <exception cref="ArgumentNullException">filterContext</exception>
|
||||
/// <exception cref="Umbraco.Web.Mvc.HttpUmbracoFormRouteStringException">The required request field \"ufprt\" is not present.
|
||||
/// or
|
||||
/// The Umbraco form request route string could not be decrypted.
|
||||
/// or
|
||||
/// The provided Umbraco form request route string was meant for a different controller and action.</exception>
|
||||
public void OnAuthorization(AuthorizationContext filterContext)
|
||||
{
|
||||
if (filterContext == null)
|
||||
throw new ArgumentNullException(nameof(filterContext));
|
||||
|
||||
var ufprt = filterContext.HttpContext.Request["ufprt"];
|
||||
ValidateRouteString(ufprt, filterContext.ActionDescriptor?.ControllerDescriptor.ControllerName, filterContext.ActionDescriptor?.ActionName, filterContext.RouteData?.DataTokens["area"]?.ToString());
|
||||
}
|
||||
|
||||
public void ValidateRouteString(string ufprt, string currentController, string currentAction, string currentArea)
|
||||
{
|
||||
if (ufprt.IsNullOrWhiteSpace())
|
||||
{
|
||||
throw new HttpUmbracoFormRouteStringException("The required request field \"ufprt\" is not present.");
|
||||
}
|
||||
|
||||
if (!UmbracoHelper.DecryptAndValidateEncryptedRouteString(ufprt, out var additionalDataParts))
|
||||
{
|
||||
throw new HttpUmbracoFormRouteStringException("The Umbraco form request route string could not be decrypted.");
|
||||
}
|
||||
|
||||
if (!additionalDataParts[RenderRouteHandler.ReservedAdditionalKeys.Controller].InvariantEquals(currentController) ||
|
||||
!additionalDataParts[RenderRouteHandler.ReservedAdditionalKeys.Action].InvariantEquals(currentAction) ||
|
||||
(!additionalDataParts[RenderRouteHandler.ReservedAdditionalKeys.Area].IsNullOrWhiteSpace() && !additionalDataParts[RenderRouteHandler.ReservedAdditionalKeys.Area].InvariantEquals(currentArea)))
|
||||
{
|
||||
throw new HttpUmbracoFormRouteStringException("The provided Umbraco form request route string was meant for a different controller and action.");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-11
@@ -12,7 +12,7 @@ namespace Umbraco.Web.Properties {
|
||||
|
||||
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.7.0.0")]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.2.0.0")]
|
||||
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
|
||||
|
||||
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||
@@ -50,15 +50,5 @@ namespace Umbraco.Web.Properties {
|
||||
return ((string)(this["test"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.SpecialSettingAttribute(global::System.Configuration.SpecialSetting.WebServiceUrl)]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("https://our.umbraco.com/umbraco/webservices/api/repository.asmx")]
|
||||
public string umbraco_org_umbraco_our_Repository {
|
||||
get {
|
||||
return ((string)(this["umbraco_org_umbraco_our_Repository"]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,8 +11,5 @@
|
||||
<Setting Name="test" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">Something</Value>
|
||||
</Setting>
|
||||
<Setting Name="umbraco_org_umbraco_our_Repository" Type="(Web Service URL)" Scope="Application">
|
||||
<Value Profile="(Default)">https://our.umbraco.com/umbraco/webservices/api/repository.asmx</Value>
|
||||
</Setting>
|
||||
</Settings>
|
||||
</SettingsFile>
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using Newtonsoft.Json.Linq;
|
||||
@@ -38,9 +39,24 @@ namespace Umbraco.Web.PropertyEditors
|
||||
/// <inheritdoc />
|
||||
public override object FromEditor(ContentPropertyData editorValue, object currentValue)
|
||||
{
|
||||
return editorValue.Value is JArray json
|
||||
? json.Select(x => x.Value<string>())
|
||||
: null;
|
||||
var value = editorValue?.Value?.ToString();
|
||||
|
||||
if (string.IsNullOrEmpty(value))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (editorValue.Value is JArray json)
|
||||
{
|
||||
return json.Select(x => x.Value<string>());
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(value) == false)
|
||||
{
|
||||
return value.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
|
||||
// register the NuCache published snapshot service
|
||||
// must register default options, required in the service ctor
|
||||
composition.Register(factory => new PublishedSnapshotService.Options());
|
||||
composition.Register(factory => new PublishedSnapshotServiceOptions());
|
||||
composition.SetPublishedSnapshotService<PublishedSnapshotService>();
|
||||
|
||||
// add the NuCache health check (hidden from type finder)
|
||||
|
||||
@@ -30,7 +30,8 @@ using File = System.IO.File;
|
||||
|
||||
namespace Umbraco.Web.PublishedCache.NuCache
|
||||
{
|
||||
class PublishedSnapshotService : PublishedSnapshotServiceBase
|
||||
|
||||
internal class PublishedSnapshotService : PublishedSnapshotServiceBase
|
||||
{
|
||||
private readonly ServiceContext _serviceContext;
|
||||
private readonly IPublishedContentTypeFactory _publishedContentTypeFactory;
|
||||
@@ -56,7 +57,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
|
||||
private BPlusTree<int, ContentNodeKit> _localContentDb;
|
||||
private BPlusTree<int, ContentNodeKit> _localMediaDb;
|
||||
private readonly bool _localDbExists;
|
||||
private bool _localDbExists;
|
||||
|
||||
// define constant - determines whether to use cache when previewing
|
||||
// to store eg routes, property converted values, anything - caching
|
||||
@@ -68,7 +69,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
|
||||
//private static int _singletonCheck;
|
||||
|
||||
public PublishedSnapshotService(Options options, IMainDom mainDom, IRuntimeState runtime,
|
||||
public PublishedSnapshotService(PublishedSnapshotServiceOptions options, IMainDom mainDom, IRuntimeState runtime,
|
||||
ServiceContext serviceContext, IPublishedContentTypeFactory publishedContentTypeFactory, IdkMap idkMap,
|
||||
IPublishedSnapshotAccessor publishedSnapshotAccessor, IVariationContextAccessor variationContextAccessor, ILogger logger, IScopeProvider scopeProvider,
|
||||
IDocumentRepository documentRepository, IMediaRepository mediaRepository, IMemberRepository memberRepository,
|
||||
@@ -115,30 +116,36 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
if (options.IgnoreLocalDb == false)
|
||||
{
|
||||
var registered = mainDom.Register(
|
||||
null,
|
||||
() =>
|
||||
{
|
||||
//"install" phase of MainDom
|
||||
//this is inside of a lock in MainDom so this is guaranteed to run if MainDom was acquired and guaranteed
|
||||
//to not run if MainDom wasn't acquired.
|
||||
//If MainDom was not acquired, then _localContentDb and _localMediaDb will remain null which means this appdomain
|
||||
//will load in published content via the DB and in that case this appdomain will probably not exist long enough to
|
||||
//serve more than a page of content.
|
||||
|
||||
var path = GetLocalFilesPath();
|
||||
var localContentDbPath = Path.Combine(path, "NuCache.Content.db");
|
||||
var localMediaDbPath = Path.Combine(path, "NuCache.Media.db");
|
||||
_localDbExists = File.Exists(localContentDbPath) && File.Exists(localMediaDbPath);
|
||||
// if both local databases exist then GetTree will open them, else new databases will be created
|
||||
_localContentDb = BTree.GetTree(localContentDbPath, _localDbExists);
|
||||
_localMediaDb = BTree.GetTree(localMediaDbPath, _localDbExists);
|
||||
},
|
||||
() =>
|
||||
{
|
||||
//"release" phase of MainDom
|
||||
|
||||
lock (_storesLock)
|
||||
{
|
||||
_contentStore.ReleaseLocalDb();
|
||||
_contentStore?.ReleaseLocalDb(); //null check because we could shut down before being assigned
|
||||
_localContentDb = null;
|
||||
_mediaStore.ReleaseLocalDb();
|
||||
_mediaStore?.ReleaseLocalDb(); //null check because we could shut down before being assigned
|
||||
_localMediaDb = null;
|
||||
}
|
||||
});
|
||||
|
||||
if (registered)
|
||||
{
|
||||
var path = GetLocalFilesPath();
|
||||
var localContentDbPath = Path.Combine(path, "NuCache.Content.db");
|
||||
var localMediaDbPath = Path.Combine(path, "NuCache.Media.db");
|
||||
_localDbExists = System.IO.File.Exists(localContentDbPath) && System.IO.File.Exists(localMediaDbPath);
|
||||
|
||||
// if both local databases exist then GetTree will open them, else new databases will be created
|
||||
_localContentDb = BTree.GetTree(localContentDbPath, _localDbExists);
|
||||
_localMediaDb = BTree.GetTree(localMediaDbPath, _localDbExists);
|
||||
}
|
||||
|
||||
// stores are created with a db so they can write to it, but they do not read from it,
|
||||
// stores need to be populated, happens in OnResolutionFrozen which uses _localDbExists to
|
||||
// figure out whether it can read the databases or it should populate them from sql
|
||||
@@ -251,19 +258,6 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
base.Dispose();
|
||||
}
|
||||
|
||||
public class Options
|
||||
{
|
||||
// disabled: prevents the published snapshot from updating and exposing changes
|
||||
// or even creating a new published snapshot to see changes, uses old cache = bad
|
||||
//
|
||||
//// indicates that the snapshot cache should reuse the application request cache
|
||||
//// otherwise a new cache object would be created for the snapshot specifically,
|
||||
//// which is the default - web boot manager uses this to optimize facades
|
||||
//public bool PublishedSnapshotCacheIsApplicationRequestCache;
|
||||
|
||||
public bool IgnoreLocalDb;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Local files
|
||||
@@ -1056,8 +1050,10 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
: _dataSource.GetTypeMediaSources(scope, refreshedIds).ToArray();
|
||||
|
||||
_mediaStore.UpdateContentTypes(removedIds, typesA, kits);
|
||||
_mediaStore.UpdateContentTypes(CreateContentTypes(PublishedItemType.Media, otherIds.ToArray()).ToArray());
|
||||
_mediaStore.NewContentTypes(CreateContentTypes(PublishedItemType.Media, newIds.ToArray()).ToArray());
|
||||
if (!otherIds.IsCollectionEmpty())
|
||||
_mediaStore.UpdateContentTypes(CreateContentTypes(PublishedItemType.Media, otherIds.ToArray()).ToArray());
|
||||
if (!newIds.IsCollectionEmpty())
|
||||
_mediaStore.NewContentTypes(CreateContentTypes(PublishedItemType.Media, newIds.ToArray()).ToArray());
|
||||
scope.Complete();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
namespace Umbraco.Web.PublishedCache.NuCache
|
||||
{
|
||||
/// <summary>
|
||||
/// Options class for configuring the <see cref="IPublishedSnapshotService"/>
|
||||
/// </summary>
|
||||
public class PublishedSnapshotServiceOptions
|
||||
{
|
||||
// disabled: prevents the published snapshot from updating and exposing changes
|
||||
// or even creating a new published snapshot to see changes, uses old cache = bad
|
||||
//
|
||||
//// indicates that the snapshot cache should reuse the application request cache
|
||||
//// otherwise a new cache object would be created for the snapshot specifically,
|
||||
//// which is the default - web boot manager uses this to optimize facades
|
||||
//public bool PublishedSnapshotCacheIsApplicationRequestCache;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// If true this disables the persisted local cache files for content and media
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// By default this is false which means umbraco will use locally persisted cache files for reading in all published content and media on application startup.
|
||||
/// The reason for this is to improve startup times because the alternative to populating the published content and media on application startup is to read
|
||||
/// these values from the database. In scenarios where sites are relatively small (below a few thousand nodes) reading the content/media from the database to populate
|
||||
/// the in memory cache isn't that slow and is only marginally slower than reading from the locally persisted cache files.
|
||||
/// </remarks>
|
||||
public bool IgnoreLocalDb { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -20,14 +20,22 @@ namespace Umbraco.Web
|
||||
{
|
||||
private readonly IPublishedSnapshot _publishedSnapshot;
|
||||
private readonly IVariationContextAccessor _variationContextAccessor;
|
||||
private readonly IExamineManager _examineManager;
|
||||
|
||||
[Obsolete("Use the constructor with all parameters instead")]
|
||||
public PublishedContentQuery(IPublishedSnapshot publishedSnapshot, IVariationContextAccessor variationContextAccessor)
|
||||
: this (publishedSnapshot, variationContextAccessor, ExamineManager.Instance)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PublishedContentQuery"/> class.
|
||||
/// </summary>
|
||||
public PublishedContentQuery(IPublishedSnapshot publishedSnapshot, IVariationContextAccessor variationContextAccessor)
|
||||
public PublishedContentQuery(IPublishedSnapshot publishedSnapshot, IVariationContextAccessor variationContextAccessor, IExamineManager examineManager)
|
||||
{
|
||||
_publishedSnapshot = publishedSnapshot ?? throw new ArgumentNullException(nameof(publishedSnapshot));
|
||||
_variationContextAccessor = variationContextAccessor ?? throw new ArgumentNullException(nameof(variationContextAccessor));
|
||||
_examineManager = examineManager ?? throw new ArgumentNullException(nameof(examineManager));
|
||||
}
|
||||
|
||||
#region Content
|
||||
@@ -175,19 +183,19 @@ namespace Umbraco.Web
|
||||
#region Search
|
||||
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<PublishedSearchResult> Search(string term, string culture = null, string indexName = null)
|
||||
public IEnumerable<PublishedSearchResult> Search(string term, string culture = "*", string indexName = null)
|
||||
{
|
||||
return Search(term, 0, 0, out _, culture, indexName);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<PublishedSearchResult> Search(string term, int skip, int take, out long totalRecords, string culture = null, string indexName = null)
|
||||
public IEnumerable<PublishedSearchResult> Search(string term, int skip, int take, out long totalRecords, string culture = "*", string indexName = null)
|
||||
{
|
||||
indexName = string.IsNullOrEmpty(indexName)
|
||||
? Constants.UmbracoIndexes.ExternalIndexName
|
||||
: indexName;
|
||||
|
||||
if (!ExamineManager.Instance.TryGetIndex(indexName, out var index) || !(index is IUmbracoIndex umbIndex))
|
||||
if (!_examineManager.TryGetIndex(indexName, out var index) || !(index is IUmbracoIndex umbIndex))
|
||||
throw new InvalidOperationException($"No index found by name {indexName} or is not of type {typeof(IUmbracoIndex)}");
|
||||
|
||||
var searcher = umbIndex.GetSearcher();
|
||||
@@ -195,20 +203,28 @@ namespace Umbraco.Web
|
||||
// default to max 500 results
|
||||
var count = skip == 0 && take == 0 ? 500 : skip + take;
|
||||
|
||||
//set this to the specific culture or to the culture in the request
|
||||
culture = culture ?? _variationContextAccessor.VariationContext.Culture;
|
||||
|
||||
ISearchResults results;
|
||||
if (culture.IsNullOrWhiteSpace())
|
||||
if (culture == "*")
|
||||
{
|
||||
//search everything
|
||||
|
||||
results = searcher.Search(term, count);
|
||||
}
|
||||
else if (culture.IsNullOrWhiteSpace())
|
||||
{
|
||||
//only search invariant
|
||||
|
||||
var qry = searcher.CreateQuery().Field(UmbracoContentIndex.VariesByCultureFieldName, "n"); //must not vary by culture
|
||||
qry = qry.And().ManagedQuery(term);
|
||||
results = qry.Execute(count);
|
||||
}
|
||||
else
|
||||
{
|
||||
//search only the specified culture
|
||||
|
||||
//get all index fields suffixed with the culture name supplied
|
||||
var cultureFields = umbIndex.GetCultureFields(culture);
|
||||
var qry = searcher.CreateQuery().Field(UmbracoContentIndex.VariesByCultureFieldName, "y"); //must vary by culture
|
||||
qry = qry.And().ManagedQuery(term, cultureFields.ToArray());
|
||||
var cultureFields = umbIndex.GetCultureAndInvariantFields(culture).ToArray();
|
||||
var qry = searcher.CreateQuery().ManagedQuery(term, cultureFields);
|
||||
results = qry.Execute(count);
|
||||
}
|
||||
|
||||
@@ -304,7 +320,7 @@ namespace Umbraco.Web
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -36,8 +36,6 @@ namespace Umbraco.Web.Runtime
|
||||
|
||||
// ensure WebAPI is initialized, after everything
|
||||
GlobalConfiguration.Configuration.EnsureInitialized();
|
||||
|
||||
AntiForgeryConfig.AdditionalDataProvider = new UmbracoAntiForgeryAdditionalDataProvider(AntiForgeryConfig.AdditionalDataProvider);
|
||||
}
|
||||
|
||||
public void Terminate()
|
||||
|
||||
@@ -64,7 +64,7 @@ namespace Umbraco.Web.Scheduling
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Error<KeepAlive>(ex, "Failed (at '{UmbracoAppUrl}').", umbracoAppUrl);
|
||||
_logger.Error<KeepAlive>(ex, "Keep alive failed (at '{UmbracoAppUrl}').", umbracoAppUrl);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -30,8 +30,9 @@ namespace Umbraco.Web.Search
|
||||
private readonly IValueSetBuilder<IMedia> _mediaValueSetBuilder;
|
||||
private readonly IValueSetBuilder<IMember> _memberValueSetBuilder;
|
||||
private static bool _disableExamineIndexing = false;
|
||||
private static volatile bool _isConfigured = false;
|
||||
private static readonly object IsConfiguredLocker = new object();
|
||||
private static bool _isConfigured = false;
|
||||
private static object _configuredInit = null;
|
||||
private static object _isConfiguredLocker = new object();
|
||||
private readonly IScopeProvider _scopeProvider;
|
||||
private readonly ServiceContext _services;
|
||||
private static BackgroundTaskRunner<IBackgroundTask> _rebuildOnStartupRunner;
|
||||
@@ -91,7 +92,7 @@ namespace Umbraco.Web.Search
|
||||
|
||||
if (!examineShutdownRegistered)
|
||||
{
|
||||
_logger.Debug<ExamineComponent>("Examine shutdown not registered, this AppDomain is not the MainDom, Examine will be disabled");
|
||||
_logger.Info<ExamineComponent>("Examine shutdown not registered, this AppDomain is not the MainDom, Examine will be disabled");
|
||||
|
||||
//if we could not register the shutdown examine ourselves, it means we are not maindom! in this case all of examine should be disabled!
|
||||
Suspendable.ExamineEvents.SuspendIndexers(_logger);
|
||||
@@ -120,7 +121,7 @@ namespace Umbraco.Web.Search
|
||||
MediaCacheRefresher.CacheUpdated += MediaCacheRefresherUpdated;
|
||||
MemberCacheRefresher.CacheUpdated += MemberCacheRefresherUpdated;
|
||||
|
||||
EnsureUnlocked(_logger, _examineManager);
|
||||
ConfigureIndexes(_logger, _examineManager);
|
||||
|
||||
// TODO: Instead of waiting 5000 ms, we could add an event handler on to fulfilling the first request, then start?
|
||||
RebuildIndexes(_indexRebuilder, _logger, true, 5000);
|
||||
@@ -161,25 +162,24 @@ namespace Umbraco.Web.Search
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Must be called to each index is unlocked before any indexing occurs
|
||||
/// Called on startup to configure each index.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Indexing rebuilding can occur on a normal boot if the indexes are empty or on a cold boot by the database server messenger. Before
|
||||
/// either of these happens, we need to configure the indexes.
|
||||
/// Configuring also ensure the indexes are not locked.
|
||||
/// </remarks>
|
||||
private static void EnsureUnlocked(ILogger logger, IExamineManager examineManager)
|
||||
private static void ConfigureIndexes(ILogger logger, IExamineManager examineManager)
|
||||
{
|
||||
if (_disableExamineIndexing) return;
|
||||
if (_isConfigured) return;
|
||||
|
||||
lock (IsConfiguredLocker)
|
||||
{
|
||||
//double check
|
||||
if (_isConfigured) return;
|
||||
|
||||
_isConfigured = true;
|
||||
examineManager.UnlockLuceneIndexes(logger);
|
||||
}
|
||||
LazyInitializer.EnsureInitialized(
|
||||
ref _configuredInit,
|
||||
ref _isConfigured,
|
||||
ref _isConfiguredLocker,
|
||||
() =>
|
||||
{
|
||||
examineManager.ConfigureLuceneIndexes(logger, _disableExamineIndexing);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
#region Cache refresher updated event handlers
|
||||
@@ -737,7 +737,7 @@ namespace Umbraco.Web.Search
|
||||
{
|
||||
var strId = id.ToString(CultureInfo.InvariantCulture);
|
||||
foreach (var index in examineComponent._examineManager.Indexes.OfType<IUmbracoIndex>()
|
||||
.Where(x => (keepIfUnpublished && !x.PublishedValuesOnly) || !keepIfUnpublished)
|
||||
.Where(x => x.PublishedValuesOnly || !keepIfUnpublished)
|
||||
.Where(x => x.EnableDefaultEventHandler))
|
||||
{
|
||||
index.DeleteFromIndex(strId);
|
||||
@@ -800,7 +800,7 @@ namespace Umbraco.Web.Search
|
||||
if (_waitMilliseconds > 0)
|
||||
Thread.Sleep(_waitMilliseconds);
|
||||
|
||||
EnsureUnlocked(_logger, _indexRebuilder.ExamineManager);
|
||||
ConfigureIndexes(_logger, _indexRebuilder.ExamineManager);
|
||||
_indexRebuilder.RebuildIndexes(_onlyEmptyIndexes);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -542,7 +542,7 @@ namespace Umbraco.Web.Security
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the login status model of the currently logged in member, if no member is logged in it returns null;
|
||||
/// Returns the login status model of the currently logged in member.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public virtual LoginStatusModel GetCurrentLoginStatus()
|
||||
|
||||
@@ -4,13 +4,12 @@ using Umbraco.Core;
|
||||
using System.Web.Helpers;
|
||||
using System.Web;
|
||||
using Newtonsoft.Json;
|
||||
using Umbraco.Web.Composing;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace Umbraco.Web.Security
|
||||
{
|
||||
/// <summary>
|
||||
/// A custom <see cref="IAntiForgeryAdditionalDataProvider"/> to create a unique antiforgery token/validator per form created with BeginUmbracoForm
|
||||
/// </summary>
|
||||
[Obsolete("This is no longer used and will be removed from the codebase in future versions")]
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public class UmbracoAntiForgeryAdditionalDataProvider : IAntiForgeryAdditionalDataProvider
|
||||
{
|
||||
private readonly IAntiForgeryAdditionalDataProvider _defaultProvider;
|
||||
|
||||
@@ -219,9 +219,12 @@
|
||||
<Compile Include="Models\Mapping\MapperContextExtensions.cs" />
|
||||
<Compile Include="Models\PublishedContent\HybridVariationContextAccessor.cs" />
|
||||
<Compile Include="Models\TemplateQuery\QueryConditionExtensions.cs" />
|
||||
<Compile Include="Mvc\HttpUmbracoFormRouteStringException.cs" />
|
||||
<Compile Include="Mvc\ModelBindingExceptionFilter.cs" />
|
||||
<Compile Include="Mvc\SurfaceControllerTypeCollectionBuilder.cs" />
|
||||
<Compile Include="Mvc\ValidateUmbracoFormRouteStringAttribute.cs" />
|
||||
<Compile Include="Profiling\WebProfilingController.cs" />
|
||||
<Compile Include="PublishedCache\NuCache\PublishedSnapshotServiceOptions.cs" />
|
||||
<Compile Include="PublishedCache\NuCache\Snap\GenObj.cs" />
|
||||
<Compile Include="PublishedCache\NuCache\Snap\GenRef.cs" />
|
||||
<Compile Include="PublishedCache\NuCache\Snap\LinkedNode.cs" />
|
||||
@@ -230,7 +233,6 @@
|
||||
<Compile Include="Routing\IPublishedRouter.cs" />
|
||||
<Compile Include="Routing\MediaUrlProviderCollection.cs" />
|
||||
<Compile Include="Routing\MediaUrlProviderCollectionBuilder.cs" />
|
||||
<Compile Include="Security\UmbracoAntiForgeryAdditionalDataProvider.cs" />
|
||||
<Compile Include="Services\DashboardService.cs" />
|
||||
<Compile Include="Services\IDashboardService.cs" />
|
||||
<Compile Include="Models\Link.cs" />
|
||||
@@ -340,6 +342,7 @@
|
||||
<Compile Include="Editors\TourController.cs" />
|
||||
<Compile Include="HealthCheck\Checks\Security\XssProtectionCheck.cs" />
|
||||
<Compile Include="HealthCheck\Checks\Security\HstsCheck.cs" />
|
||||
<Compile Include="Security\UmbracoAntiForgeryAdditionalDataProvider.cs" />
|
||||
<Compile Include="Editors\UserEditorAuthorizationHelper.cs" />
|
||||
<Compile Include="Editors\Filters\UserGroupAuthorizationAttribute.cs" />
|
||||
<Compile Include="Editors\Filters\UserGroupEditorAuthorizationHelper.cs" />
|
||||
@@ -903,11 +906,6 @@
|
||||
<Compile Include="JavaScript\CssInitialization.cs" />
|
||||
<Compile Include="JavaScript\DependencyPathRenderer.cs" />
|
||||
<Compile Include="UmbracoComponentRenderer.cs" />
|
||||
<Compile Include="Web References\org.umbraco.our\Reference.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>Reference.map</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="WebApi\AngularJsonMediaTypeFormatter.cs" />
|
||||
<Compile Include="WebApi\AngularJsonOnlyConfigurationAttribute.cs" />
|
||||
<Compile Include="Editors\Binders\MemberBinder.cs" />
|
||||
@@ -1217,12 +1215,6 @@
|
||||
<None Include="..\Umbraco.Web.UI\Views\web.config">
|
||||
<Link>Mvc\web.config</Link>
|
||||
</None>
|
||||
<None Include="Web References\org.umbraco.our\Reference.map">
|
||||
<Generator>MSDiscoCodeGenerator</Generator>
|
||||
<LastGenOutput>Reference.cs</LastGenOutput>
|
||||
</None>
|
||||
<None Include="Web References\org.umbraco.our\repository.disco" />
|
||||
<None Include="Web References\org.umbraco.our\repository.wsdl" />
|
||||
<None Include="Web References\org.umbraco.update\UpgradeResult.datasource">
|
||||
<DependentUpon>Reference.map</DependentUpon>
|
||||
</None>
|
||||
@@ -1235,17 +1227,6 @@
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<WebReferenceUrl Include="http://our.umbraco.org/umbraco/webservices/api/repository.asmx">
|
||||
<UrlBehavior>Dynamic</UrlBehavior>
|
||||
<RelPath>Web References\org.umbraco.our\</RelPath>
|
||||
<UpdateFromURL>http://our.umbraco.org/umbraco/webservices/api/repository.asmx</UpdateFromURL>
|
||||
<ServiceLocationURL>
|
||||
</ServiceLocationURL>
|
||||
<CachedDynamicPropName>
|
||||
</CachedDynamicPropName>
|
||||
<CachedAppSettingsObjectName>Settings</CachedAppSettingsObjectName>
|
||||
<CachedSettingsPropName>umbraco_org_umbraco_our_Repository</CachedSettingsPropName>
|
||||
</WebReferenceUrl>
|
||||
<WebReferenceUrl Include="http://update.umbraco.org/checkforupgrade.asmx">
|
||||
<UrlBehavior>Dynamic</UrlBehavior>
|
||||
<RelPath>Web References\org.umbraco.update\</RelPath>
|
||||
|
||||
@@ -53,7 +53,15 @@ namespace Umbraco.Web
|
||||
{
|
||||
// make sure we have a variation context
|
||||
if (_variationContextAccessor.VariationContext == null)
|
||||
{
|
||||
// TODO: By using _defaultCultureAccessor.DefaultCulture this means that the VariationContext will always return a variant culture, it will never
|
||||
// return an empty string signifying that the culture is invariant. But does this matter? Are we actually expecting this to return an empty string
|
||||
// for invariant routes? From what i can tell throughout the codebase is that whenever we are checking against the VariationContext.Culture we are
|
||||
// also checking if the content type varies by culture or not. This is fine, however the code in the ctor of VariationContext is then misleading
|
||||
// since it's assuming that the Culture can be empty (invariant) when in reality of a website this will never be empty since a real culture is always set here.
|
||||
_variationContextAccessor.VariationContext = new VariationContext(_defaultCultureAccessor.DefaultCulture);
|
||||
}
|
||||
|
||||
|
||||
var webSecurity = new WebSecurity(httpContext, _userService, _globalSettings);
|
||||
|
||||
|
||||
@@ -820,7 +820,7 @@ namespace Umbraco.Web
|
||||
{
|
||||
decryptedString = ufprt.DecryptWithMachineKey();
|
||||
}
|
||||
catch (FormatException)
|
||||
catch (Exception ex) when (ex is FormatException || ex is ArgumentException)
|
||||
{
|
||||
Current.Logger.Warn(typeof(UmbracoHelper), "A value was detected in the ufprt parameter but Umbraco could not decrypt the string");
|
||||
parts = null;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,7 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<DiscoveryClientResultsFile xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
||||
<Results>
|
||||
<DiscoveryClientResult referenceType="System.Web.Services.Discovery.ContractReference" url="https://our.umbraco.com/umbraco/webservices/api/repository.asmx?wsdl" filename="repository.wsdl" />
|
||||
<DiscoveryClientResult referenceType="System.Web.Services.Discovery.DiscoveryDocumentReference" url="https://our.umbraco.com/umbraco/webservices/api/repository.asmx?disco" filename="repository.disco" />
|
||||
</Results>
|
||||
</DiscoveryClientResultsFile>
|
||||
@@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<discovery xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/disco/">
|
||||
<contractRef ref="https://our.umbraco.com/umbraco/webservices/api/repository.asmx?wsdl" docRef="https://our.umbraco.com/umbraco/webservices/api/repository.asmx" xmlns="http://schemas.xmlsoap.org/disco/scl/" />
|
||||
<soap address="https://our.umbraco.com/umbraco/webservices/api/repository.asmx" xmlns:q1="http://packages.umbraco.org/webservices/" binding="q1:RepositorySoap" xmlns="http://schemas.xmlsoap.org/disco/soap/" />
|
||||
<soap address="https://our.umbraco.com/umbraco/webservices/api/repository.asmx" xmlns:q2="http://packages.umbraco.org/webservices/" binding="q2:RepositorySoap12" xmlns="http://schemas.xmlsoap.org/disco/soap/" />
|
||||
</discovery>
|
||||
@@ -1,995 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:tns="http://packages.umbraco.org/webservices/" xmlns:s1="http://microsoft.com/wsdl/types/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:s2="http://packages.umbraco.org/webservices/AbstractTypes" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" targetNamespace="http://packages.umbraco.org/webservices/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
|
||||
<wsdl:types>
|
||||
<s:schema elementFormDefault="qualified" targetNamespace="http://packages.umbraco.org/webservices/">
|
||||
<s:import namespace="http://microsoft.com/wsdl/types/" />
|
||||
<s:element name="Categories">
|
||||
<s:complexType>
|
||||
<s:sequence>
|
||||
<s:element minOccurs="0" maxOccurs="1" name="repositoryGuid" type="s:string" />
|
||||
</s:sequence>
|
||||
</s:complexType>
|
||||
</s:element>
|
||||
<s:element name="CategoriesResponse">
|
||||
<s:complexType>
|
||||
<s:sequence>
|
||||
<s:element minOccurs="0" maxOccurs="1" name="CategoriesResult" type="tns:ArrayOfCategory" />
|
||||
</s:sequence>
|
||||
</s:complexType>
|
||||
</s:element>
|
||||
<s:complexType name="ArrayOfCategory">
|
||||
<s:sequence>
|
||||
<s:element minOccurs="0" maxOccurs="unbounded" name="Category" nillable="true" type="tns:Category" />
|
||||
</s:sequence>
|
||||
</s:complexType>
|
||||
<s:complexType name="Category">
|
||||
<s:sequence>
|
||||
<s:element minOccurs="0" maxOccurs="1" name="Text" type="s:string" />
|
||||
<s:element minOccurs="0" maxOccurs="1" name="Description" type="s:string" />
|
||||
<s:element minOccurs="0" maxOccurs="1" name="Url" type="s:string" />
|
||||
<s:element minOccurs="1" maxOccurs="1" name="Id" type="s:int" />
|
||||
<s:element minOccurs="0" maxOccurs="1" name="Packages" type="tns:ArrayOfPackage" />
|
||||
</s:sequence>
|
||||
</s:complexType>
|
||||
<s:complexType name="ArrayOfPackage">
|
||||
<s:sequence>
|
||||
<s:element minOccurs="0" maxOccurs="unbounded" name="Package" nillable="true" type="tns:Package" />
|
||||
</s:sequence>
|
||||
</s:complexType>
|
||||
<s:complexType name="Package">
|
||||
<s:sequence>
|
||||
<s:element minOccurs="1" maxOccurs="1" name="RepoGuid" type="s1:guid" />
|
||||
<s:element minOccurs="0" maxOccurs="1" name="Text" type="s:string" />
|
||||
<s:element minOccurs="0" maxOccurs="1" name="Description" type="s:string" />
|
||||
<s:element minOccurs="0" maxOccurs="1" name="Icon" type="s:string" />
|
||||
<s:element minOccurs="0" maxOccurs="1" name="Thumbnail" type="s:string" />
|
||||
<s:element minOccurs="0" maxOccurs="1" name="Documentation" type="s:string" />
|
||||
<s:element minOccurs="0" maxOccurs="1" name="Demo" type="s:string" />
|
||||
<s:element minOccurs="1" maxOccurs="1" name="Accepted" type="s:boolean" />
|
||||
<s:element minOccurs="1" maxOccurs="1" name="IsModule" type="s:boolean" />
|
||||
<s:element minOccurs="1" maxOccurs="1" name="EditorsPick" type="s:boolean" />
|
||||
<s:element minOccurs="1" maxOccurs="1" name="Protected" type="s:boolean" />
|
||||
<s:element minOccurs="1" maxOccurs="1" name="HasUpgrade" type="s:boolean" />
|
||||
<s:element minOccurs="0" maxOccurs="1" name="UpgradeVersion" type="s:string" />
|
||||
<s:element minOccurs="0" maxOccurs="1" name="UpgradeReadMe" type="s:string" />
|
||||
<s:element minOccurs="0" maxOccurs="1" name="Url" type="s:string" />
|
||||
</s:sequence>
|
||||
</s:complexType>
|
||||
<s:element name="Modules">
|
||||
<s:complexType />
|
||||
</s:element>
|
||||
<s:element name="ModulesResponse">
|
||||
<s:complexType>
|
||||
<s:sequence>
|
||||
<s:element minOccurs="0" maxOccurs="1" name="ModulesResult" type="tns:ArrayOfPackage" />
|
||||
</s:sequence>
|
||||
</s:complexType>
|
||||
</s:element>
|
||||
<s:element name="ModulesCategorized">
|
||||
<s:complexType />
|
||||
</s:element>
|
||||
<s:element name="ModulesCategorizedResponse">
|
||||
<s:complexType>
|
||||
<s:sequence>
|
||||
<s:element minOccurs="0" maxOccurs="1" name="ModulesCategorizedResult" type="tns:ArrayOfCategory" />
|
||||
</s:sequence>
|
||||
</s:complexType>
|
||||
</s:element>
|
||||
<s:element name="Nitros">
|
||||
<s:complexType />
|
||||
</s:element>
|
||||
<s:element name="NitrosResponse">
|
||||
<s:complexType>
|
||||
<s:sequence>
|
||||
<s:element minOccurs="0" maxOccurs="1" name="NitrosResult" type="tns:ArrayOfPackage" />
|
||||
</s:sequence>
|
||||
</s:complexType>
|
||||
</s:element>
|
||||
<s:element name="NitrosCategorized">
|
||||
<s:complexType />
|
||||
</s:element>
|
||||
<s:element name="NitrosCategorizedResponse">
|
||||
<s:complexType>
|
||||
<s:sequence>
|
||||
<s:element minOccurs="0" maxOccurs="1" name="NitrosCategorizedResult" type="tns:ArrayOfCategory" />
|
||||
</s:sequence>
|
||||
</s:complexType>
|
||||
</s:element>
|
||||
<s:element name="authenticate">
|
||||
<s:complexType>
|
||||
<s:sequence>
|
||||
<s:element minOccurs="0" maxOccurs="1" name="email" type="s:string" />
|
||||
<s:element minOccurs="0" maxOccurs="1" name="md5Password" type="s:string" />
|
||||
</s:sequence>
|
||||
</s:complexType>
|
||||
</s:element>
|
||||
<s:element name="authenticateResponse">
|
||||
<s:complexType>
|
||||
<s:sequence>
|
||||
<s:element minOccurs="0" maxOccurs="1" name="authenticateResult" type="s:string" />
|
||||
</s:sequence>
|
||||
</s:complexType>
|
||||
</s:element>
|
||||
<s:element name="fetchPackage">
|
||||
<s:complexType>
|
||||
<s:sequence>
|
||||
<s:element minOccurs="0" maxOccurs="1" name="packageGuid" type="s:string" />
|
||||
</s:sequence>
|
||||
</s:complexType>
|
||||
</s:element>
|
||||
<s:element name="fetchPackageResponse">
|
||||
<s:complexType>
|
||||
<s:sequence>
|
||||
<s:element minOccurs="0" maxOccurs="1" name="fetchPackageResult" type="s:base64Binary" />
|
||||
</s:sequence>
|
||||
</s:complexType>
|
||||
</s:element>
|
||||
<s:element name="fetchPackageByVersion">
|
||||
<s:complexType>
|
||||
<s:sequence>
|
||||
<s:element minOccurs="0" maxOccurs="1" name="packageGuid" type="s:string" />
|
||||
<s:element minOccurs="0" maxOccurs="1" name="repoVersion" type="s:string" />
|
||||
</s:sequence>
|
||||
</s:complexType>
|
||||
</s:element>
|
||||
<s:element name="fetchPackageByVersionResponse">
|
||||
<s:complexType>
|
||||
<s:sequence>
|
||||
<s:element minOccurs="0" maxOccurs="1" name="fetchPackageByVersionResult" type="s:base64Binary" />
|
||||
</s:sequence>
|
||||
</s:complexType>
|
||||
</s:element>
|
||||
<s:element name="fetchProtectedPackage">
|
||||
<s:complexType>
|
||||
<s:sequence>
|
||||
<s:element minOccurs="0" maxOccurs="1" name="packageGuid" type="s:string" />
|
||||
<s:element minOccurs="0" maxOccurs="1" name="memberKey" type="s:string" />
|
||||
</s:sequence>
|
||||
</s:complexType>
|
||||
</s:element>
|
||||
<s:element name="fetchProtectedPackageResponse">
|
||||
<s:complexType>
|
||||
<s:sequence>
|
||||
<s:element minOccurs="0" maxOccurs="1" name="fetchProtectedPackageResult" type="s:base64Binary" />
|
||||
</s:sequence>
|
||||
</s:complexType>
|
||||
</s:element>
|
||||
<s:element name="SubmitPackage">
|
||||
<s:complexType>
|
||||
<s:sequence>
|
||||
<s:element minOccurs="0" maxOccurs="1" name="repositoryGuid" type="s:string" />
|
||||
<s:element minOccurs="0" maxOccurs="1" name="authorGuid" type="s:string" />
|
||||
<s:element minOccurs="0" maxOccurs="1" name="packageGuid" type="s:string" />
|
||||
<s:element minOccurs="0" maxOccurs="1" name="packageFile" type="s:base64Binary" />
|
||||
<s:element minOccurs="0" maxOccurs="1" name="packageDoc" type="s:base64Binary" />
|
||||
<s:element minOccurs="0" maxOccurs="1" name="packageThumbnail" type="s:base64Binary" />
|
||||
<s:element minOccurs="0" maxOccurs="1" name="name" type="s:string" />
|
||||
<s:element minOccurs="0" maxOccurs="1" name="author" type="s:string" />
|
||||
<s:element minOccurs="0" maxOccurs="1" name="authorUrl" type="s:string" />
|
||||
<s:element minOccurs="0" maxOccurs="1" name="description" type="s:string" />
|
||||
</s:sequence>
|
||||
</s:complexType>
|
||||
</s:element>
|
||||
<s:element name="SubmitPackageResponse">
|
||||
<s:complexType>
|
||||
<s:sequence>
|
||||
<s:element minOccurs="1" maxOccurs="1" name="SubmitPackageResult" type="tns:SubmitStatus" />
|
||||
</s:sequence>
|
||||
</s:complexType>
|
||||
</s:element>
|
||||
<s:simpleType name="SubmitStatus">
|
||||
<s:restriction base="s:string">
|
||||
<s:enumeration value="Complete" />
|
||||
<s:enumeration value="Exists" />
|
||||
<s:enumeration value="NoAccess" />
|
||||
<s:enumeration value="Error" />
|
||||
</s:restriction>
|
||||
</s:simpleType>
|
||||
<s:element name="PackageByGuid">
|
||||
<s:complexType>
|
||||
<s:sequence>
|
||||
<s:element minOccurs="0" maxOccurs="1" name="packageGuid" type="s:string" />
|
||||
</s:sequence>
|
||||
</s:complexType>
|
||||
</s:element>
|
||||
<s:element name="PackageByGuidResponse">
|
||||
<s:complexType>
|
||||
<s:sequence>
|
||||
<s:element minOccurs="0" maxOccurs="1" name="PackageByGuidResult" type="tns:Package" />
|
||||
</s:sequence>
|
||||
</s:complexType>
|
||||
</s:element>
|
||||
<s:element name="ArrayOfCategory" nillable="true" type="tns:ArrayOfCategory" />
|
||||
<s:element name="ArrayOfPackage" nillable="true" type="tns:ArrayOfPackage" />
|
||||
<s:element name="string" nillable="true" type="s:string" />
|
||||
<s:element name="base64Binary" nillable="true" type="s:base64Binary" />
|
||||
<s:element name="SubmitStatus" type="tns:SubmitStatus" />
|
||||
<s:element name="Package" nillable="true" type="tns:Package" />
|
||||
</s:schema>
|
||||
<s:schema elementFormDefault="qualified" targetNamespace="http://microsoft.com/wsdl/types/">
|
||||
<s:simpleType name="guid">
|
||||
<s:restriction base="s:string">
|
||||
<s:pattern value="[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}" />
|
||||
</s:restriction>
|
||||
</s:simpleType>
|
||||
</s:schema>
|
||||
<s:schema targetNamespace="http://packages.umbraco.org/webservices/AbstractTypes">
|
||||
<s:import namespace="http://schemas.xmlsoap.org/soap/encoding/" />
|
||||
<s:complexType name="StringArray">
|
||||
<s:complexContent mixed="false">
|
||||
<s:restriction base="soapenc:Array">
|
||||
<s:sequence>
|
||||
<s:element minOccurs="0" maxOccurs="unbounded" name="String" type="s:string" />
|
||||
</s:sequence>
|
||||
</s:restriction>
|
||||
</s:complexContent>
|
||||
</s:complexType>
|
||||
</s:schema>
|
||||
</wsdl:types>
|
||||
<wsdl:message name="CategoriesSoapIn">
|
||||
<wsdl:part name="parameters" element="tns:Categories" />
|
||||
</wsdl:message>
|
||||
<wsdl:message name="CategoriesSoapOut">
|
||||
<wsdl:part name="parameters" element="tns:CategoriesResponse" />
|
||||
</wsdl:message>
|
||||
<wsdl:message name="ModulesSoapIn">
|
||||
<wsdl:part name="parameters" element="tns:Modules" />
|
||||
</wsdl:message>
|
||||
<wsdl:message name="ModulesSoapOut">
|
||||
<wsdl:part name="parameters" element="tns:ModulesResponse" />
|
||||
</wsdl:message>
|
||||
<wsdl:message name="ModulesCategorizedSoapIn">
|
||||
<wsdl:part name="parameters" element="tns:ModulesCategorized" />
|
||||
</wsdl:message>
|
||||
<wsdl:message name="ModulesCategorizedSoapOut">
|
||||
<wsdl:part name="parameters" element="tns:ModulesCategorizedResponse" />
|
||||
</wsdl:message>
|
||||
<wsdl:message name="NitrosSoapIn">
|
||||
<wsdl:part name="parameters" element="tns:Nitros" />
|
||||
</wsdl:message>
|
||||
<wsdl:message name="NitrosSoapOut">
|
||||
<wsdl:part name="parameters" element="tns:NitrosResponse" />
|
||||
</wsdl:message>
|
||||
<wsdl:message name="NitrosCategorizedSoapIn">
|
||||
<wsdl:part name="parameters" element="tns:NitrosCategorized" />
|
||||
</wsdl:message>
|
||||
<wsdl:message name="NitrosCategorizedSoapOut">
|
||||
<wsdl:part name="parameters" element="tns:NitrosCategorizedResponse" />
|
||||
</wsdl:message>
|
||||
<wsdl:message name="authenticateSoapIn">
|
||||
<wsdl:part name="parameters" element="tns:authenticate" />
|
||||
</wsdl:message>
|
||||
<wsdl:message name="authenticateSoapOut">
|
||||
<wsdl:part name="parameters" element="tns:authenticateResponse" />
|
||||
</wsdl:message>
|
||||
<wsdl:message name="fetchPackageSoapIn">
|
||||
<wsdl:part name="parameters" element="tns:fetchPackage" />
|
||||
</wsdl:message>
|
||||
<wsdl:message name="fetchPackageSoapOut">
|
||||
<wsdl:part name="parameters" element="tns:fetchPackageResponse" />
|
||||
</wsdl:message>
|
||||
<wsdl:message name="fetchPackageByVersionSoapIn">
|
||||
<wsdl:part name="parameters" element="tns:fetchPackageByVersion" />
|
||||
</wsdl:message>
|
||||
<wsdl:message name="fetchPackageByVersionSoapOut">
|
||||
<wsdl:part name="parameters" element="tns:fetchPackageByVersionResponse" />
|
||||
</wsdl:message>
|
||||
<wsdl:message name="fetchProtectedPackageSoapIn">
|
||||
<wsdl:part name="parameters" element="tns:fetchProtectedPackage" />
|
||||
</wsdl:message>
|
||||
<wsdl:message name="fetchProtectedPackageSoapOut">
|
||||
<wsdl:part name="parameters" element="tns:fetchProtectedPackageResponse" />
|
||||
</wsdl:message>
|
||||
<wsdl:message name="SubmitPackageSoapIn">
|
||||
<wsdl:part name="parameters" element="tns:SubmitPackage" />
|
||||
</wsdl:message>
|
||||
<wsdl:message name="SubmitPackageSoapOut">
|
||||
<wsdl:part name="parameters" element="tns:SubmitPackageResponse" />
|
||||
</wsdl:message>
|
||||
<wsdl:message name="PackageByGuidSoapIn">
|
||||
<wsdl:part name="parameters" element="tns:PackageByGuid" />
|
||||
</wsdl:message>
|
||||
<wsdl:message name="PackageByGuidSoapOut">
|
||||
<wsdl:part name="parameters" element="tns:PackageByGuidResponse" />
|
||||
</wsdl:message>
|
||||
<wsdl:message name="CategoriesHttpGetIn">
|
||||
<wsdl:part name="repositoryGuid" type="s:string" />
|
||||
</wsdl:message>
|
||||
<wsdl:message name="CategoriesHttpGetOut">
|
||||
<wsdl:part name="Body" element="tns:ArrayOfCategory" />
|
||||
</wsdl:message>
|
||||
<wsdl:message name="ModulesHttpGetIn" />
|
||||
<wsdl:message name="ModulesHttpGetOut">
|
||||
<wsdl:part name="Body" element="tns:ArrayOfPackage" />
|
||||
</wsdl:message>
|
||||
<wsdl:message name="ModulesCategorizedHttpGetIn" />
|
||||
<wsdl:message name="ModulesCategorizedHttpGetOut">
|
||||
<wsdl:part name="Body" element="tns:ArrayOfCategory" />
|
||||
</wsdl:message>
|
||||
<wsdl:message name="NitrosHttpGetIn" />
|
||||
<wsdl:message name="NitrosHttpGetOut">
|
||||
<wsdl:part name="Body" element="tns:ArrayOfPackage" />
|
||||
</wsdl:message>
|
||||
<wsdl:message name="NitrosCategorizedHttpGetIn" />
|
||||
<wsdl:message name="NitrosCategorizedHttpGetOut">
|
||||
<wsdl:part name="Body" element="tns:ArrayOfCategory" />
|
||||
</wsdl:message>
|
||||
<wsdl:message name="authenticateHttpGetIn">
|
||||
<wsdl:part name="email" type="s:string" />
|
||||
<wsdl:part name="md5Password" type="s:string" />
|
||||
</wsdl:message>
|
||||
<wsdl:message name="authenticateHttpGetOut">
|
||||
<wsdl:part name="Body" element="tns:string" />
|
||||
</wsdl:message>
|
||||
<wsdl:message name="fetchPackageHttpGetIn">
|
||||
<wsdl:part name="packageGuid" type="s:string" />
|
||||
</wsdl:message>
|
||||
<wsdl:message name="fetchPackageHttpGetOut">
|
||||
<wsdl:part name="Body" element="tns:base64Binary" />
|
||||
</wsdl:message>
|
||||
<wsdl:message name="fetchPackageByVersionHttpGetIn">
|
||||
<wsdl:part name="packageGuid" type="s:string" />
|
||||
<wsdl:part name="repoVersion" type="s:string" />
|
||||
</wsdl:message>
|
||||
<wsdl:message name="fetchPackageByVersionHttpGetOut">
|
||||
<wsdl:part name="Body" element="tns:base64Binary" />
|
||||
</wsdl:message>
|
||||
<wsdl:message name="fetchProtectedPackageHttpGetIn">
|
||||
<wsdl:part name="packageGuid" type="s:string" />
|
||||
<wsdl:part name="memberKey" type="s:string" />
|
||||
</wsdl:message>
|
||||
<wsdl:message name="fetchProtectedPackageHttpGetOut">
|
||||
<wsdl:part name="Body" element="tns:base64Binary" />
|
||||
</wsdl:message>
|
||||
<wsdl:message name="SubmitPackageHttpGetIn">
|
||||
<wsdl:part name="repositoryGuid" type="s:string" />
|
||||
<wsdl:part name="authorGuid" type="s:string" />
|
||||
<wsdl:part name="packageGuid" type="s:string" />
|
||||
<wsdl:part name="packageFile" type="s2:StringArray" />
|
||||
<wsdl:part name="packageDoc" type="s2:StringArray" />
|
||||
<wsdl:part name="packageThumbnail" type="s2:StringArray" />
|
||||
<wsdl:part name="name" type="s:string" />
|
||||
<wsdl:part name="author" type="s:string" />
|
||||
<wsdl:part name="authorUrl" type="s:string" />
|
||||
<wsdl:part name="description" type="s:string" />
|
||||
</wsdl:message>
|
||||
<wsdl:message name="SubmitPackageHttpGetOut">
|
||||
<wsdl:part name="Body" element="tns:SubmitStatus" />
|
||||
</wsdl:message>
|
||||
<wsdl:message name="PackageByGuidHttpGetIn">
|
||||
<wsdl:part name="packageGuid" type="s:string" />
|
||||
</wsdl:message>
|
||||
<wsdl:message name="PackageByGuidHttpGetOut">
|
||||
<wsdl:part name="Body" element="tns:Package" />
|
||||
</wsdl:message>
|
||||
<wsdl:message name="CategoriesHttpPostIn">
|
||||
<wsdl:part name="repositoryGuid" type="s:string" />
|
||||
</wsdl:message>
|
||||
<wsdl:message name="CategoriesHttpPostOut">
|
||||
<wsdl:part name="Body" element="tns:ArrayOfCategory" />
|
||||
</wsdl:message>
|
||||
<wsdl:message name="ModulesHttpPostIn" />
|
||||
<wsdl:message name="ModulesHttpPostOut">
|
||||
<wsdl:part name="Body" element="tns:ArrayOfPackage" />
|
||||
</wsdl:message>
|
||||
<wsdl:message name="ModulesCategorizedHttpPostIn" />
|
||||
<wsdl:message name="ModulesCategorizedHttpPostOut">
|
||||
<wsdl:part name="Body" element="tns:ArrayOfCategory" />
|
||||
</wsdl:message>
|
||||
<wsdl:message name="NitrosHttpPostIn" />
|
||||
<wsdl:message name="NitrosHttpPostOut">
|
||||
<wsdl:part name="Body" element="tns:ArrayOfPackage" />
|
||||
</wsdl:message>
|
||||
<wsdl:message name="NitrosCategorizedHttpPostIn" />
|
||||
<wsdl:message name="NitrosCategorizedHttpPostOut">
|
||||
<wsdl:part name="Body" element="tns:ArrayOfCategory" />
|
||||
</wsdl:message>
|
||||
<wsdl:message name="authenticateHttpPostIn">
|
||||
<wsdl:part name="email" type="s:string" />
|
||||
<wsdl:part name="md5Password" type="s:string" />
|
||||
</wsdl:message>
|
||||
<wsdl:message name="authenticateHttpPostOut">
|
||||
<wsdl:part name="Body" element="tns:string" />
|
||||
</wsdl:message>
|
||||
<wsdl:message name="fetchPackageHttpPostIn">
|
||||
<wsdl:part name="packageGuid" type="s:string" />
|
||||
</wsdl:message>
|
||||
<wsdl:message name="fetchPackageHttpPostOut">
|
||||
<wsdl:part name="Body" element="tns:base64Binary" />
|
||||
</wsdl:message>
|
||||
<wsdl:message name="fetchPackageByVersionHttpPostIn">
|
||||
<wsdl:part name="packageGuid" type="s:string" />
|
||||
<wsdl:part name="repoVersion" type="s:string" />
|
||||
</wsdl:message>
|
||||
<wsdl:message name="fetchPackageByVersionHttpPostOut">
|
||||
<wsdl:part name="Body" element="tns:base64Binary" />
|
||||
</wsdl:message>
|
||||
<wsdl:message name="fetchProtectedPackageHttpPostIn">
|
||||
<wsdl:part name="packageGuid" type="s:string" />
|
||||
<wsdl:part name="memberKey" type="s:string" />
|
||||
</wsdl:message>
|
||||
<wsdl:message name="fetchProtectedPackageHttpPostOut">
|
||||
<wsdl:part name="Body" element="tns:base64Binary" />
|
||||
</wsdl:message>
|
||||
<wsdl:message name="SubmitPackageHttpPostIn">
|
||||
<wsdl:part name="repositoryGuid" type="s:string" />
|
||||
<wsdl:part name="authorGuid" type="s:string" />
|
||||
<wsdl:part name="packageGuid" type="s:string" />
|
||||
<wsdl:part name="packageFile" type="s2:StringArray" />
|
||||
<wsdl:part name="packageDoc" type="s2:StringArray" />
|
||||
<wsdl:part name="packageThumbnail" type="s2:StringArray" />
|
||||
<wsdl:part name="name" type="s:string" />
|
||||
<wsdl:part name="author" type="s:string" />
|
||||
<wsdl:part name="authorUrl" type="s:string" />
|
||||
<wsdl:part name="description" type="s:string" />
|
||||
</wsdl:message>
|
||||
<wsdl:message name="SubmitPackageHttpPostOut">
|
||||
<wsdl:part name="Body" element="tns:SubmitStatus" />
|
||||
</wsdl:message>
|
||||
<wsdl:message name="PackageByGuidHttpPostIn">
|
||||
<wsdl:part name="packageGuid" type="s:string" />
|
||||
</wsdl:message>
|
||||
<wsdl:message name="PackageByGuidHttpPostOut">
|
||||
<wsdl:part name="Body" element="tns:Package" />
|
||||
</wsdl:message>
|
||||
<wsdl:portType name="RepositorySoap">
|
||||
<wsdl:operation name="Categories">
|
||||
<wsdl:input message="tns:CategoriesSoapIn" />
|
||||
<wsdl:output message="tns:CategoriesSoapOut" />
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="Modules">
|
||||
<wsdl:input message="tns:ModulesSoapIn" />
|
||||
<wsdl:output message="tns:ModulesSoapOut" />
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="ModulesCategorized">
|
||||
<wsdl:input message="tns:ModulesCategorizedSoapIn" />
|
||||
<wsdl:output message="tns:ModulesCategorizedSoapOut" />
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="Nitros">
|
||||
<wsdl:input message="tns:NitrosSoapIn" />
|
||||
<wsdl:output message="tns:NitrosSoapOut" />
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="NitrosCategorized">
|
||||
<wsdl:input message="tns:NitrosCategorizedSoapIn" />
|
||||
<wsdl:output message="tns:NitrosCategorizedSoapOut" />
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="authenticate">
|
||||
<wsdl:input message="tns:authenticateSoapIn" />
|
||||
<wsdl:output message="tns:authenticateSoapOut" />
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="fetchPackage">
|
||||
<wsdl:input message="tns:fetchPackageSoapIn" />
|
||||
<wsdl:output message="tns:fetchPackageSoapOut" />
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="fetchPackageByVersion">
|
||||
<wsdl:input message="tns:fetchPackageByVersionSoapIn" />
|
||||
<wsdl:output message="tns:fetchPackageByVersionSoapOut" />
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="fetchProtectedPackage">
|
||||
<wsdl:input message="tns:fetchProtectedPackageSoapIn" />
|
||||
<wsdl:output message="tns:fetchProtectedPackageSoapOut" />
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="SubmitPackage">
|
||||
<wsdl:input message="tns:SubmitPackageSoapIn" />
|
||||
<wsdl:output message="tns:SubmitPackageSoapOut" />
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="PackageByGuid">
|
||||
<wsdl:input message="tns:PackageByGuidSoapIn" />
|
||||
<wsdl:output message="tns:PackageByGuidSoapOut" />
|
||||
</wsdl:operation>
|
||||
</wsdl:portType>
|
||||
<wsdl:portType name="RepositoryHttpGet">
|
||||
<wsdl:operation name="Categories">
|
||||
<wsdl:input message="tns:CategoriesHttpGetIn" />
|
||||
<wsdl:output message="tns:CategoriesHttpGetOut" />
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="Modules">
|
||||
<wsdl:input message="tns:ModulesHttpGetIn" />
|
||||
<wsdl:output message="tns:ModulesHttpGetOut" />
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="ModulesCategorized">
|
||||
<wsdl:input message="tns:ModulesCategorizedHttpGetIn" />
|
||||
<wsdl:output message="tns:ModulesCategorizedHttpGetOut" />
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="Nitros">
|
||||
<wsdl:input message="tns:NitrosHttpGetIn" />
|
||||
<wsdl:output message="tns:NitrosHttpGetOut" />
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="NitrosCategorized">
|
||||
<wsdl:input message="tns:NitrosCategorizedHttpGetIn" />
|
||||
<wsdl:output message="tns:NitrosCategorizedHttpGetOut" />
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="authenticate">
|
||||
<wsdl:input message="tns:authenticateHttpGetIn" />
|
||||
<wsdl:output message="tns:authenticateHttpGetOut" />
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="fetchPackage">
|
||||
<wsdl:input message="tns:fetchPackageHttpGetIn" />
|
||||
<wsdl:output message="tns:fetchPackageHttpGetOut" />
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="fetchPackageByVersion">
|
||||
<wsdl:input message="tns:fetchPackageByVersionHttpGetIn" />
|
||||
<wsdl:output message="tns:fetchPackageByVersionHttpGetOut" />
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="fetchProtectedPackage">
|
||||
<wsdl:input message="tns:fetchProtectedPackageHttpGetIn" />
|
||||
<wsdl:output message="tns:fetchProtectedPackageHttpGetOut" />
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="SubmitPackage">
|
||||
<wsdl:input message="tns:SubmitPackageHttpGetIn" />
|
||||
<wsdl:output message="tns:SubmitPackageHttpGetOut" />
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="PackageByGuid">
|
||||
<wsdl:input message="tns:PackageByGuidHttpGetIn" />
|
||||
<wsdl:output message="tns:PackageByGuidHttpGetOut" />
|
||||
</wsdl:operation>
|
||||
</wsdl:portType>
|
||||
<wsdl:portType name="RepositoryHttpPost">
|
||||
<wsdl:operation name="Categories">
|
||||
<wsdl:input message="tns:CategoriesHttpPostIn" />
|
||||
<wsdl:output message="tns:CategoriesHttpPostOut" />
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="Modules">
|
||||
<wsdl:input message="tns:ModulesHttpPostIn" />
|
||||
<wsdl:output message="tns:ModulesHttpPostOut" />
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="ModulesCategorized">
|
||||
<wsdl:input message="tns:ModulesCategorizedHttpPostIn" />
|
||||
<wsdl:output message="tns:ModulesCategorizedHttpPostOut" />
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="Nitros">
|
||||
<wsdl:input message="tns:NitrosHttpPostIn" />
|
||||
<wsdl:output message="tns:NitrosHttpPostOut" />
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="NitrosCategorized">
|
||||
<wsdl:input message="tns:NitrosCategorizedHttpPostIn" />
|
||||
<wsdl:output message="tns:NitrosCategorizedHttpPostOut" />
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="authenticate">
|
||||
<wsdl:input message="tns:authenticateHttpPostIn" />
|
||||
<wsdl:output message="tns:authenticateHttpPostOut" />
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="fetchPackage">
|
||||
<wsdl:input message="tns:fetchPackageHttpPostIn" />
|
||||
<wsdl:output message="tns:fetchPackageHttpPostOut" />
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="fetchPackageByVersion">
|
||||
<wsdl:input message="tns:fetchPackageByVersionHttpPostIn" />
|
||||
<wsdl:output message="tns:fetchPackageByVersionHttpPostOut" />
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="fetchProtectedPackage">
|
||||
<wsdl:input message="tns:fetchProtectedPackageHttpPostIn" />
|
||||
<wsdl:output message="tns:fetchProtectedPackageHttpPostOut" />
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="SubmitPackage">
|
||||
<wsdl:input message="tns:SubmitPackageHttpPostIn" />
|
||||
<wsdl:output message="tns:SubmitPackageHttpPostOut" />
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="PackageByGuid">
|
||||
<wsdl:input message="tns:PackageByGuidHttpPostIn" />
|
||||
<wsdl:output message="tns:PackageByGuidHttpPostOut" />
|
||||
</wsdl:operation>
|
||||
</wsdl:portType>
|
||||
<wsdl:binding name="RepositorySoap" type="tns:RepositorySoap">
|
||||
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" />
|
||||
<wsdl:operation name="Categories">
|
||||
<soap:operation soapAction="http://packages.umbraco.org/webservices/Categories" style="document" />
|
||||
<wsdl:input>
|
||||
<soap:body use="literal" />
|
||||
</wsdl:input>
|
||||
<wsdl:output>
|
||||
<soap:body use="literal" />
|
||||
</wsdl:output>
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="Modules">
|
||||
<soap:operation soapAction="http://packages.umbraco.org/webservices/Modules" style="document" />
|
||||
<wsdl:input>
|
||||
<soap:body use="literal" />
|
||||
</wsdl:input>
|
||||
<wsdl:output>
|
||||
<soap:body use="literal" />
|
||||
</wsdl:output>
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="ModulesCategorized">
|
||||
<soap:operation soapAction="http://packages.umbraco.org/webservices/ModulesCategorized" style="document" />
|
||||
<wsdl:input>
|
||||
<soap:body use="literal" />
|
||||
</wsdl:input>
|
||||
<wsdl:output>
|
||||
<soap:body use="literal" />
|
||||
</wsdl:output>
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="Nitros">
|
||||
<soap:operation soapAction="http://packages.umbraco.org/webservices/Nitros" style="document" />
|
||||
<wsdl:input>
|
||||
<soap:body use="literal" />
|
||||
</wsdl:input>
|
||||
<wsdl:output>
|
||||
<soap:body use="literal" />
|
||||
</wsdl:output>
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="NitrosCategorized">
|
||||
<soap:operation soapAction="http://packages.umbraco.org/webservices/NitrosCategorized" style="document" />
|
||||
<wsdl:input>
|
||||
<soap:body use="literal" />
|
||||
</wsdl:input>
|
||||
<wsdl:output>
|
||||
<soap:body use="literal" />
|
||||
</wsdl:output>
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="authenticate">
|
||||
<soap:operation soapAction="http://packages.umbraco.org/webservices/authenticate" style="document" />
|
||||
<wsdl:input>
|
||||
<soap:body use="literal" />
|
||||
</wsdl:input>
|
||||
<wsdl:output>
|
||||
<soap:body use="literal" />
|
||||
</wsdl:output>
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="fetchPackage">
|
||||
<soap:operation soapAction="http://packages.umbraco.org/webservices/fetchPackage" style="document" />
|
||||
<wsdl:input>
|
||||
<soap:body use="literal" />
|
||||
</wsdl:input>
|
||||
<wsdl:output>
|
||||
<soap:body use="literal" />
|
||||
</wsdl:output>
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="fetchPackageByVersion">
|
||||
<soap:operation soapAction="http://packages.umbraco.org/webservices/fetchPackageByVersion" style="document" />
|
||||
<wsdl:input>
|
||||
<soap:body use="literal" />
|
||||
</wsdl:input>
|
||||
<wsdl:output>
|
||||
<soap:body use="literal" />
|
||||
</wsdl:output>
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="fetchProtectedPackage">
|
||||
<soap:operation soapAction="http://packages.umbraco.org/webservices/fetchProtectedPackage" style="document" />
|
||||
<wsdl:input>
|
||||
<soap:body use="literal" />
|
||||
</wsdl:input>
|
||||
<wsdl:output>
|
||||
<soap:body use="literal" />
|
||||
</wsdl:output>
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="SubmitPackage">
|
||||
<soap:operation soapAction="http://packages.umbraco.org/webservices/SubmitPackage" style="document" />
|
||||
<wsdl:input>
|
||||
<soap:body use="literal" />
|
||||
</wsdl:input>
|
||||
<wsdl:output>
|
||||
<soap:body use="literal" />
|
||||
</wsdl:output>
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="PackageByGuid">
|
||||
<soap:operation soapAction="http://packages.umbraco.org/webservices/PackageByGuid" style="document" />
|
||||
<wsdl:input>
|
||||
<soap:body use="literal" />
|
||||
</wsdl:input>
|
||||
<wsdl:output>
|
||||
<soap:body use="literal" />
|
||||
</wsdl:output>
|
||||
</wsdl:operation>
|
||||
</wsdl:binding>
|
||||
<wsdl:binding name="RepositorySoap12" type="tns:RepositorySoap">
|
||||
<soap12:binding transport="http://schemas.xmlsoap.org/soap/http" />
|
||||
<wsdl:operation name="Categories">
|
||||
<soap12:operation soapAction="http://packages.umbraco.org/webservices/Categories" style="document" />
|
||||
<wsdl:input>
|
||||
<soap12:body use="literal" />
|
||||
</wsdl:input>
|
||||
<wsdl:output>
|
||||
<soap12:body use="literal" />
|
||||
</wsdl:output>
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="Modules">
|
||||
<soap12:operation soapAction="http://packages.umbraco.org/webservices/Modules" style="document" />
|
||||
<wsdl:input>
|
||||
<soap12:body use="literal" />
|
||||
</wsdl:input>
|
||||
<wsdl:output>
|
||||
<soap12:body use="literal" />
|
||||
</wsdl:output>
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="ModulesCategorized">
|
||||
<soap12:operation soapAction="http://packages.umbraco.org/webservices/ModulesCategorized" style="document" />
|
||||
<wsdl:input>
|
||||
<soap12:body use="literal" />
|
||||
</wsdl:input>
|
||||
<wsdl:output>
|
||||
<soap12:body use="literal" />
|
||||
</wsdl:output>
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="Nitros">
|
||||
<soap12:operation soapAction="http://packages.umbraco.org/webservices/Nitros" style="document" />
|
||||
<wsdl:input>
|
||||
<soap12:body use="literal" />
|
||||
</wsdl:input>
|
||||
<wsdl:output>
|
||||
<soap12:body use="literal" />
|
||||
</wsdl:output>
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="NitrosCategorized">
|
||||
<soap12:operation soapAction="http://packages.umbraco.org/webservices/NitrosCategorized" style="document" />
|
||||
<wsdl:input>
|
||||
<soap12:body use="literal" />
|
||||
</wsdl:input>
|
||||
<wsdl:output>
|
||||
<soap12:body use="literal" />
|
||||
</wsdl:output>
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="authenticate">
|
||||
<soap12:operation soapAction="http://packages.umbraco.org/webservices/authenticate" style="document" />
|
||||
<wsdl:input>
|
||||
<soap12:body use="literal" />
|
||||
</wsdl:input>
|
||||
<wsdl:output>
|
||||
<soap12:body use="literal" />
|
||||
</wsdl:output>
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="fetchPackage">
|
||||
<soap12:operation soapAction="http://packages.umbraco.org/webservices/fetchPackage" style="document" />
|
||||
<wsdl:input>
|
||||
<soap12:body use="literal" />
|
||||
</wsdl:input>
|
||||
<wsdl:output>
|
||||
<soap12:body use="literal" />
|
||||
</wsdl:output>
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="fetchPackageByVersion">
|
||||
<soap12:operation soapAction="http://packages.umbraco.org/webservices/fetchPackageByVersion" style="document" />
|
||||
<wsdl:input>
|
||||
<soap12:body use="literal" />
|
||||
</wsdl:input>
|
||||
<wsdl:output>
|
||||
<soap12:body use="literal" />
|
||||
</wsdl:output>
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="fetchProtectedPackage">
|
||||
<soap12:operation soapAction="http://packages.umbraco.org/webservices/fetchProtectedPackage" style="document" />
|
||||
<wsdl:input>
|
||||
<soap12:body use="literal" />
|
||||
</wsdl:input>
|
||||
<wsdl:output>
|
||||
<soap12:body use="literal" />
|
||||
</wsdl:output>
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="SubmitPackage">
|
||||
<soap12:operation soapAction="http://packages.umbraco.org/webservices/SubmitPackage" style="document" />
|
||||
<wsdl:input>
|
||||
<soap12:body use="literal" />
|
||||
</wsdl:input>
|
||||
<wsdl:output>
|
||||
<soap12:body use="literal" />
|
||||
</wsdl:output>
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="PackageByGuid">
|
||||
<soap12:operation soapAction="http://packages.umbraco.org/webservices/PackageByGuid" style="document" />
|
||||
<wsdl:input>
|
||||
<soap12:body use="literal" />
|
||||
</wsdl:input>
|
||||
<wsdl:output>
|
||||
<soap12:body use="literal" />
|
||||
</wsdl:output>
|
||||
</wsdl:operation>
|
||||
</wsdl:binding>
|
||||
<wsdl:binding name="RepositoryHttpGet" type="tns:RepositoryHttpGet">
|
||||
<http:binding verb="GET" />
|
||||
<wsdl:operation name="Categories">
|
||||
<http:operation location="/Categories" />
|
||||
<wsdl:input>
|
||||
<http:urlEncoded />
|
||||
</wsdl:input>
|
||||
<wsdl:output>
|
||||
<mime:mimeXml part="Body" />
|
||||
</wsdl:output>
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="Modules">
|
||||
<http:operation location="/Modules" />
|
||||
<wsdl:input>
|
||||
<http:urlEncoded />
|
||||
</wsdl:input>
|
||||
<wsdl:output>
|
||||
<mime:mimeXml part="Body" />
|
||||
</wsdl:output>
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="ModulesCategorized">
|
||||
<http:operation location="/ModulesCategorized" />
|
||||
<wsdl:input>
|
||||
<http:urlEncoded />
|
||||
</wsdl:input>
|
||||
<wsdl:output>
|
||||
<mime:mimeXml part="Body" />
|
||||
</wsdl:output>
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="Nitros">
|
||||
<http:operation location="/Nitros" />
|
||||
<wsdl:input>
|
||||
<http:urlEncoded />
|
||||
</wsdl:input>
|
||||
<wsdl:output>
|
||||
<mime:mimeXml part="Body" />
|
||||
</wsdl:output>
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="NitrosCategorized">
|
||||
<http:operation location="/NitrosCategorized" />
|
||||
<wsdl:input>
|
||||
<http:urlEncoded />
|
||||
</wsdl:input>
|
||||
<wsdl:output>
|
||||
<mime:mimeXml part="Body" />
|
||||
</wsdl:output>
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="authenticate">
|
||||
<http:operation location="/authenticate" />
|
||||
<wsdl:input>
|
||||
<http:urlEncoded />
|
||||
</wsdl:input>
|
||||
<wsdl:output>
|
||||
<mime:mimeXml part="Body" />
|
||||
</wsdl:output>
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="fetchPackage">
|
||||
<http:operation location="/fetchPackage" />
|
||||
<wsdl:input>
|
||||
<http:urlEncoded />
|
||||
</wsdl:input>
|
||||
<wsdl:output>
|
||||
<mime:mimeXml part="Body" />
|
||||
</wsdl:output>
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="fetchPackageByVersion">
|
||||
<http:operation location="/fetchPackageByVersion" />
|
||||
<wsdl:input>
|
||||
<http:urlEncoded />
|
||||
</wsdl:input>
|
||||
<wsdl:output>
|
||||
<mime:mimeXml part="Body" />
|
||||
</wsdl:output>
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="fetchProtectedPackage">
|
||||
<http:operation location="/fetchProtectedPackage" />
|
||||
<wsdl:input>
|
||||
<http:urlEncoded />
|
||||
</wsdl:input>
|
||||
<wsdl:output>
|
||||
<mime:mimeXml part="Body" />
|
||||
</wsdl:output>
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="SubmitPackage">
|
||||
<http:operation location="/SubmitPackage" />
|
||||
<wsdl:input>
|
||||
<http:urlEncoded />
|
||||
</wsdl:input>
|
||||
<wsdl:output>
|
||||
<mime:mimeXml part="Body" />
|
||||
</wsdl:output>
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="PackageByGuid">
|
||||
<http:operation location="/PackageByGuid" />
|
||||
<wsdl:input>
|
||||
<http:urlEncoded />
|
||||
</wsdl:input>
|
||||
<wsdl:output>
|
||||
<mime:mimeXml part="Body" />
|
||||
</wsdl:output>
|
||||
</wsdl:operation>
|
||||
</wsdl:binding>
|
||||
<wsdl:binding name="RepositoryHttpPost" type="tns:RepositoryHttpPost">
|
||||
<http:binding verb="POST" />
|
||||
<wsdl:operation name="Categories">
|
||||
<http:operation location="/Categories" />
|
||||
<wsdl:input>
|
||||
<mime:content type="application/x-www-form-urlencoded" />
|
||||
</wsdl:input>
|
||||
<wsdl:output>
|
||||
<mime:mimeXml part="Body" />
|
||||
</wsdl:output>
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="Modules">
|
||||
<http:operation location="/Modules" />
|
||||
<wsdl:input>
|
||||
<mime:content type="application/x-www-form-urlencoded" />
|
||||
</wsdl:input>
|
||||
<wsdl:output>
|
||||
<mime:mimeXml part="Body" />
|
||||
</wsdl:output>
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="ModulesCategorized">
|
||||
<http:operation location="/ModulesCategorized" />
|
||||
<wsdl:input>
|
||||
<mime:content type="application/x-www-form-urlencoded" />
|
||||
</wsdl:input>
|
||||
<wsdl:output>
|
||||
<mime:mimeXml part="Body" />
|
||||
</wsdl:output>
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="Nitros">
|
||||
<http:operation location="/Nitros" />
|
||||
<wsdl:input>
|
||||
<mime:content type="application/x-www-form-urlencoded" />
|
||||
</wsdl:input>
|
||||
<wsdl:output>
|
||||
<mime:mimeXml part="Body" />
|
||||
</wsdl:output>
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="NitrosCategorized">
|
||||
<http:operation location="/NitrosCategorized" />
|
||||
<wsdl:input>
|
||||
<mime:content type="application/x-www-form-urlencoded" />
|
||||
</wsdl:input>
|
||||
<wsdl:output>
|
||||
<mime:mimeXml part="Body" />
|
||||
</wsdl:output>
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="authenticate">
|
||||
<http:operation location="/authenticate" />
|
||||
<wsdl:input>
|
||||
<mime:content type="application/x-www-form-urlencoded" />
|
||||
</wsdl:input>
|
||||
<wsdl:output>
|
||||
<mime:mimeXml part="Body" />
|
||||
</wsdl:output>
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="fetchPackage">
|
||||
<http:operation location="/fetchPackage" />
|
||||
<wsdl:input>
|
||||
<mime:content type="application/x-www-form-urlencoded" />
|
||||
</wsdl:input>
|
||||
<wsdl:output>
|
||||
<mime:mimeXml part="Body" />
|
||||
</wsdl:output>
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="fetchPackageByVersion">
|
||||
<http:operation location="/fetchPackageByVersion" />
|
||||
<wsdl:input>
|
||||
<mime:content type="application/x-www-form-urlencoded" />
|
||||
</wsdl:input>
|
||||
<wsdl:output>
|
||||
<mime:mimeXml part="Body" />
|
||||
</wsdl:output>
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="fetchProtectedPackage">
|
||||
<http:operation location="/fetchProtectedPackage" />
|
||||
<wsdl:input>
|
||||
<mime:content type="application/x-www-form-urlencoded" />
|
||||
</wsdl:input>
|
||||
<wsdl:output>
|
||||
<mime:mimeXml part="Body" />
|
||||
</wsdl:output>
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="SubmitPackage">
|
||||
<http:operation location="/SubmitPackage" />
|
||||
<wsdl:input>
|
||||
<mime:content type="application/x-www-form-urlencoded" />
|
||||
</wsdl:input>
|
||||
<wsdl:output>
|
||||
<mime:mimeXml part="Body" />
|
||||
</wsdl:output>
|
||||
</wsdl:operation>
|
||||
<wsdl:operation name="PackageByGuid">
|
||||
<http:operation location="/PackageByGuid" />
|
||||
<wsdl:input>
|
||||
<mime:content type="application/x-www-form-urlencoded" />
|
||||
</wsdl:input>
|
||||
<wsdl:output>
|
||||
<mime:mimeXml part="Body" />
|
||||
</wsdl:output>
|
||||
</wsdl:operation>
|
||||
</wsdl:binding>
|
||||
<wsdl:service name="Repository">
|
||||
<wsdl:port name="RepositorySoap" binding="tns:RepositorySoap">
|
||||
<soap:address location="https://our.umbraco.com/umbraco/webservices/api/repository.asmx" />
|
||||
</wsdl:port>
|
||||
<wsdl:port name="RepositorySoap12" binding="tns:RepositorySoap12">
|
||||
<soap12:address location="https://our.umbraco.com/umbraco/webservices/api/repository.asmx" />
|
||||
</wsdl:port>
|
||||
<wsdl:port name="RepositoryHttpGet" binding="tns:RepositoryHttpGet">
|
||||
<http:address location="https://our.umbraco.com/umbraco/webservices/api/repository.asmx" />
|
||||
</wsdl:port>
|
||||
<wsdl:port name="RepositoryHttpPost" binding="tns:RepositoryHttpPost">
|
||||
<http:address location="https://our.umbraco.com/umbraco/webservices/api/repository.asmx" />
|
||||
</wsdl:port>
|
||||
</wsdl:service>
|
||||
</wsdl:definitions>
|
||||
Reference in New Issue
Block a user