Compare commits

...

33 Commits

Author SHA1 Message Date
Sebastiaan Janssen 5fdd7d8bd6 Merge branch 'bjarnef-dev-v7-U4-6898' into dev-v7 2015-07-31 11:29:58 +02:00
Sebastiaan Janssen b5c87ccfb7 Merge branch 'dev-v7-U4-6898' of https://github.com/bjarnef/Umbraco-CMS into bjarnef-dev-v7-U4-6898 2015-07-31 11:29:51 +02:00
Sebastiaan Janssen 2efe6ae7a4 Merge pull request #754 from bjarnef/dev-v7-U4-6179
Highlight recycle bin tree node
2015-07-31 11:20:44 +02:00
Sebastiaan Janssen cbab70fd7c Should finally fix this test that apparently relies on super strict timings 2015-07-30 19:28:33 +02:00
bjarnef 09a3b0d155 Highlight recycle bin tree node
Ensure recycle bin tree node is highlighted when chosen.
2015-07-30 18:36:22 +02:00
Sebastiaan Janssen ca9cd77ded Fix log type 2015-07-30 18:14:29 +02:00
Sebastiaan Janssen 812601217a Merge branch 'pete2' into dev-v7 2015-07-30 18:03:09 +02:00
Pete Duncanson 3a6ec5ef0c Add a log message to stop database start up code from swallowing exception messages, now stash them in the logs to give developers a chance ;) 2015-07-30 18:01:24 +02:00
Rasmus Eeg Møller 4197a7654f U4-6902 - Changed from internal to public
Just like the ContentFinderResolver.cs
2015-07-30 17:59:18 +02:00
Sebastiaan Janssen 3133014650 Removes more references to FixedDisplayModes 2015-07-30 17:39:07 +02:00
Sebastiaan Janssen 4bce945946 Remove stray FixedDisplayModes reference 2015-07-30 17:19:43 +02:00
Sebastiaan Janssen 2d15c9c01c Use the new views config transform 2015-07-30 17:08:40 +02:00
Sebastiaan Janssen 58e648828b Fix web.config and adds a transform for NuGet 2015-07-30 17:08:40 +02:00
Sebastiaan Janssen d87b268a40 Update to MVC5 2015-07-30 17:08:39 +02:00
bjarnef 5174645059 Make tree nodes consistent
Make tree nodes have same position from the left regardless of the arrow
to expand the children.
2015-07-30 16:04:54 +02:00
Shannon e4286bc35b Merge branch 'dev-v7' of https://github.com/umbraco/Umbraco-CMS into dev-v7 2015-07-30 15:13:51 +02:00
Shannon cf4d13da31 fixes backward compat issue 2015-07-30 15:13:39 +02:00
Shannon Deminick a89b064e29 Merge pull request #751 from rasmuseeg/patch-1
U4-6902 - Changed from internal to public
2015-07-30 15:04:23 +02:00
Rasmus Eeg Møller 1e41973eb5 U4-6902 - Changed from internal to public
Just like the ContentFinderResolver.cs
2015-07-30 14:54:10 +02:00
Shannon b4e496fceb Fixes backwards compat issue in 7.3 with TagQuery property on UmbracoHelper. see: http://issues.umbraco.org/issue/U4-6899 2015-07-30 14:03:17 +02:00
Shannon bb94fc7d71 Ensures notifications are shown for drag/drop uploads 2015-07-30 11:35:00 +02:00
Shannon 959378c456 Fixes file cleanup with blue imp uploads 2015-07-29 16:14:09 +02:00
Shannon 787e128d5c wires up event messages for media editor and tree (haven't done the drag/drop media upload though) 2015-07-29 16:00:06 +02:00
Shannon b7912a7be7 fixes build 2015-07-29 15:22:22 +02:00
Shannon 0bc7aa6ba7 Merge branch 'dev-v7' of https://github.com/umbraco/Umbraco-CMS into dev-v7 2015-07-29 15:18:34 +02:00
Shannon 367da39bbb wires up UI to show notifications for delete cancellation 2015-07-29 15:18:23 +02:00
Shannon 6d8ffb903f Ensures events for deleting, trashing and unpublishing are done using the event messages, updates UI to support showing these messages in the list view, Since we cannot change the
method results on a service, we've created a new temporary service that we will explicitly implement with an extension method to get it. This is temporary until v8 where we will just replace
the original methods on the service with these methods and then remove this class.
2015-07-29 15:12:12 +02:00
Shannon 0e992f897f Removes standalone classes, we can replace these with what we've got in the LinqPad provider 2015-07-29 15:07:55 +02:00
Shannon 3f19878c18 changes member controller to use long overload 2015-07-29 15:07:32 +02:00
Stephan 308f64a7e2 doc BatchedDatabaseServerMessenger startup 2015-07-29 11:22:12 +02:00
Shannon 1eab92b299 updates prog bars in examine mgt dashboard to be like other umb prog bars 2015-07-27 18:58:14 +02:00
Shannon 7a8b8f138f Fixes list view search debounce and adds a ui indication that search is in progress. 2015-07-27 18:48:41 +02:00
Shannon 926ea54c39 Developers can cancel an event with the CancelOperation method of the event with a custom message which will be used in place of the normal default cancellation message 2015-07-27 18:04:20 +02:00
99 changed files with 1497 additions and 1783 deletions
+4 -3
View File
@@ -15,9 +15,8 @@
<language>en-US</language>
<tags>umbraco</tags>
<dependencies>
<dependency id="Microsoft.AspNet.Mvc" version="[4.0.40804.0,6.0.0)" />
<dependency id="Microsoft.AspNet.Mvc" version="[5.2.3,6.0.0)" />
<dependency id="Microsoft.AspNet.WebApi" version="[5.2.3,6.0.0)" />
<dependency id="Microsoft.AspNet.Mvc.FixedDisplayModes" version="1.0.1" />
<dependency id="Microsoft.Net.Http" version="[2.2.29, 3.0.0)" />
<dependency id="Microsoft.AspNet.Identity.Owin" version="[2.2.1, 3.0.0)" />
<dependency id="Microsoft.Owin.Security.Cookies" version="[3.0.1, 4.0.0)" />
@@ -30,13 +29,15 @@
<dependency id="MySql.Data" version="[6.9.7, 7.0.0)" />
<dependency id="xmlrpcnet" version="[2.5.0, 3.0.0)" />
<dependency id="ClientDependency" version="[1.8.4, 2.0.0)" />
<dependency id="ClientDependency-Mvc" version="[1.8.0, 2.0.0)" />
<dependency id="ClientDependency-Mvc5" version="[1.8.0, 2.0.0)" />
<dependency id="AutoMapper" version="[3.3.1, 4.0.0)" />
<dependency id="Newtonsoft.Json" version="[6.0.8, 7.0.0)" />
<dependency id="Examine" version="[0.1.66, 1.0.0)" />
<dependency id="ImageProcessor" version="[1.9.5, 3.0.0)" />
<dependency id="ImageProcessor.Web" version="[3.3.1, 5.0.0)" />
<dependency id="semver" version="[1.1.2, 2.0.0)" />
<dependency id="Microsoft.AspNet.WebHelpers" version="[3.2.3, 4.0.0)" />
<dependency id="Microsoft.AspNet.WebPages.Data" version="[3.2.3, 4.0.0)" />
</dependencies>
</metadata>
<files>
+1
View File
@@ -40,6 +40,7 @@
<file src="tools\Dashboard.config.install.xdt" target="Content\config\Dashboard.config.install.xdt" />
<file src="tools\trees.config.install.xdt" target="Content\config\trees.config.install.xdt" />
<file src="tools\umbracoSettings.config.install.xdt" target="Content\config\umbracoSettings.config.install.xdt" />
<file src="tools\Views.Web.config.install.xdt" target="Views\Web.config.install.xdt" />
<file src="build\**" target="build" />
</files>
</package>
@@ -0,0 +1,37 @@
<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<configSections>
<sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
xdt:Locator="Match(name)"
xdt:Transform="SetAttributes(type)">
<section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
xdt:Locator="Match(name)"
xdt:Transform="SetAttributes(type)" />
<section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
xdt:Locator="Match(name)"
xdt:Transform="SetAttributes(type)" />
</sectionGroup>
</configSections>
<system.web.webPages.razor>
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
xdt:Locator="Match(factoryType)"
xdt:Transform="SetAttributes(factoryType)" />
</system.web.webPages.razor>
<system.web>
<pages
pageParserFilterType="System.Web.Mvc.ViewTypeParserFilter, System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
pageBaseType="System.Web.Mvc.ViewPage, System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
userControlBaseType="System.Web.Mvc.ViewUserControl, System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
xdt:Locator="Match(pageParserFilterType,pageBaseType,userControlBaseType)"
xdt:Transform="SetAttributes(pageParserFilterType,pageBaseType,userControlBaseType)">
<controls>
<add assembly="System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" namespace="System.Web.Mvc"
xdt:Locator="Match(namespace)"
xdt:Transform="SetAttributes(assembly)" />
</controls>
</pages>
</system.web>
</configuration>
+1
View File
@@ -58,6 +58,7 @@ if ($project) {
if(Test-Path $umbracoBinFolder\ImageProcessor.Web.dll) { Remove-Item $umbracoBinFolder\ImageProcessor.Web.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\Lucene.Net.dll) { Remove-Item $umbracoBinFolder\Lucene.Net.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\Microsoft.Web.Infrastructure.dll) { Remove-Item $umbracoBinFolder\Microsoft.Web.Infrastructure.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\Microsoft.Web.Helpers.dll) { Remove-Item $umbracoBinFolder\Microsoft.Web.Helpers.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\Microsoft.Web.Mvc.FixedDisplayModes.dll) { Remove-Item $umbracoBinFolder\Microsoft.Web.Mvc.FixedDisplayModes.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\MiniProfiler.dll) { Remove-Item $umbracoBinFolder\MiniProfiler.dll -Force -Confirm:$false }
if(Test-Path $umbracoBinFolder\MySql.Data.dll) { Remove-Item $umbracoBinFolder\MySql.Data.dll -Force -Confirm:$false }
+1 -1
View File
@@ -1,3 +1,3 @@
# Usage: on line 2 put the release version, on line 3 put the version comment (example: beta)
7.3.0
beta2
beta3
+1 -1
View File
@@ -12,4 +12,4 @@ using System.Resources;
[assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyFileVersion("7.3.0")]
[assembly: AssemblyInformationalVersion("7.3.0-beta2")]
[assembly: AssemblyInformationalVersion("7.3.0-beta3")]
@@ -24,7 +24,7 @@ namespace Umbraco.Core.Configuration
/// Gets the version comment (like beta or RC).
/// </summary>
/// <value>The version comment.</value>
public static string CurrentComment { get { return "beta2"; } }
public static string CurrentComment { get { return "beta3"; } }
// Get the version of the umbraco.dll by looking at a class in that dll
// Had to do it like this due to medium trust issues, see: http://haacked.com/archive/2010/11/04/assembly-location-and-medium-trust.aspx
+4 -3
View File
@@ -159,15 +159,16 @@ namespace Umbraco.Core
/// <returns></returns>
protected virtual ServiceContext CreateServiceContext(DatabaseContext dbContext, IDatabaseFactory dbFactory)
{
//default transient factory
var msgFactory = new TransientMessagesFactory();
return new ServiceContext(
new RepositoryFactory(ApplicationCache, ProfilingLogger.Logger, dbContext.SqlSyntax, UmbracoConfig.For.UmbracoSettings()),
new PetaPocoUnitOfWorkProvider(dbFactory),
new FileUnitOfWorkProvider(),
new PublishingStrategy(),
new PublishingStrategy(msgFactory, ProfilingLogger.Logger),
ApplicationCache,
ProfilingLogger.Logger,
//default transient factory
new TransientMessagesFactory());
msgFactory);
}
/// <summary>
@@ -63,6 +63,17 @@ namespace Umbraco.Core.Events
}
}
/// <summary>
/// if this instance supports cancellation, this will set Cancel to true with an affiliated cancellation message
/// </summary>
/// <param name="cancelationMessage"></param>
public void CancelOperation(EventMessage cancelationMessage)
{
Cancel = true;
cancelationMessage.IsDefaultEventMessage = true;
Messages.Add(cancelationMessage);
}
/// <summary>
/// Returns the EventMessages object which is used to add messages to the message collection for this event
/// </summary>
+57 -7
View File
@@ -4,12 +4,56 @@ namespace Umbraco.Core.Events
{
public class DeleteEventArgs<TEntity> : CancellableObjectEventArgs<IEnumerable<TEntity>>
{
/// <summary>
/// Constructor accepting multiple entities that are used in the delete operation
/// </summary>
/// <param name="eventObject"></param>
/// <param name="canCancel"></param>
public DeleteEventArgs(IEnumerable<TEntity> eventObject, bool canCancel) : base(eventObject, canCancel)
/// <summary>
/// Constructor accepting multiple entities that are used in the delete operation
/// </summary>
/// <param name="eventObject"></param>
/// <param name="canCancel"></param>
/// <param name="eventMessages"></param>
public DeleteEventArgs(IEnumerable<TEntity> eventObject, bool canCancel, EventMessages eventMessages) : base(eventObject, canCancel, eventMessages)
{
MediaFilesToDelete = new List<string>();
}
/// <summary>
/// Constructor accepting multiple entities that are used in the delete operation
/// </summary>
/// <param name="eventObject"></param>
/// <param name="eventMessages"></param>
public DeleteEventArgs(IEnumerable<TEntity> eventObject, EventMessages eventMessages) : base(eventObject, eventMessages)
{
MediaFilesToDelete = new List<string>();
}
/// <summary>
/// Constructor accepting a single entity instance
/// </summary>
/// <param name="eventObject"></param>
/// <param name="eventMessages"></param>
public DeleteEventArgs(TEntity eventObject, EventMessages eventMessages)
: base(new List<TEntity> { eventObject }, eventMessages)
{
MediaFilesToDelete = new List<string>();
}
/// <summary>
/// Constructor accepting a single entity instance
/// </summary>
/// <param name="eventObject"></param>
/// <param name="canCancel"></param>
/// <param name="eventMessages"></param>
public DeleteEventArgs(TEntity eventObject, bool canCancel, EventMessages eventMessages)
: base(new List<TEntity> { eventObject }, canCancel, eventMessages)
{
MediaFilesToDelete = new List<string>();
}
/// <summary>
/// Constructor accepting multiple entities that are used in the delete operation
/// </summary>
/// <param name="eventObject"></param>
/// <param name="canCancel"></param>
public DeleteEventArgs(IEnumerable<TEntity> eventObject, bool canCancel) : base(eventObject, canCancel)
{
MediaFilesToDelete = new List<string>();
}
@@ -60,7 +104,13 @@ namespace Umbraco.Core.Events
public class DeleteEventArgs : CancellableEventArgs
{
public DeleteEventArgs(int id, bool canCancel)
public DeleteEventArgs(int id, bool canCancel, EventMessages eventMessages)
: base(canCancel, eventMessages)
{
Id = id;
}
public DeleteEventArgs(int id, bool canCancel)
: base(canCancel)
{
Id = id;
+5
View File
@@ -18,5 +18,10 @@ namespace Umbraco.Core.Events
public string Category { get; private set; }
public string Message { get; private set; }
public EventMessageType MessageType { get; private set; }
/// <summary>
/// This is used to track if this message should be used as a default message so that Umbraco doesn't also append it's own default messages
/// </summary>
internal bool IsDefaultEventMessage { get; set; }
}
}
+43
View File
@@ -6,6 +6,49 @@ namespace Umbraco.Core.Events
{
public class MoveEventArgs<TEntity> : CancellableObjectEventArgs<TEntity>
{
/// <summary>
/// Constructor accepting a collection of MoveEventInfo objects
/// </summary>
/// <param name="canCancel"></param>
/// <param name="eventMessages"></param>
/// <param name="moveInfo">
/// A colleciton of MoveEventInfo objects that exposes all entities that have been moved during a single move operation
/// </param>
public MoveEventArgs(bool canCancel, EventMessages eventMessages, params MoveEventInfo<TEntity>[] moveInfo)
: base(default(TEntity), canCancel, eventMessages)
{
if (moveInfo.FirstOrDefault() == null)
{
throw new ArgumentException("moveInfo argument must contain at least one item");
}
MoveInfoCollection = moveInfo;
//assign the legacy props
EventObject = moveInfo.First().Entity;
ParentId = moveInfo.First().NewParentId;
}
/// <summary>
/// Constructor accepting a collection of MoveEventInfo objects
/// </summary>
/// <param name="eventMessages"></param>
/// <param name="moveInfo">
/// A colleciton of MoveEventInfo objects that exposes all entities that have been moved during a single move operation
/// </param>
public MoveEventArgs(EventMessages eventMessages, params MoveEventInfo<TEntity>[] moveInfo)
: base(default(TEntity), eventMessages)
{
if (moveInfo.FirstOrDefault() == null)
{
throw new ArgumentException("moveInfo argument must contain at least one item");
}
MoveInfoCollection = moveInfo;
//assign the legacy props
EventObject = moveInfo.First().Entity;
ParentId = moveInfo.First().NewParentId;
}
/// <summary>
/// Constructor accepting a collection of MoveEventInfo objects
/// </summary>
@@ -4,6 +4,52 @@ namespace Umbraco.Core.Events
{
public class PublishEventArgs<TEntity> : CancellableObjectEventArgs<IEnumerable<TEntity>>
{
/// <summary>
/// Constructor accepting multiple entities that are used in the publish operation
/// </summary>
/// <param name="eventObject"></param>
/// <param name="canCancel"></param>
/// <param name="isAllPublished"></param>
/// <param name="eventMessages"></param>
public PublishEventArgs(IEnumerable<TEntity> eventObject, bool canCancel, bool isAllPublished, EventMessages eventMessages)
: base(eventObject, canCancel, eventMessages)
{
IsAllRepublished = isAllPublished;
}
/// <summary>
/// Constructor accepting multiple entities that are used in the publish operation
/// </summary>
/// <param name="eventObject"></param>
/// <param name="eventMessages"></param>
public PublishEventArgs(IEnumerable<TEntity> eventObject, EventMessages eventMessages)
: base(eventObject, eventMessages)
{
}
/// <summary>
/// Constructor accepting a single entity instance
/// </summary>
/// <param name="eventObject"></param>
/// <param name="eventMessages"></param>
public PublishEventArgs(TEntity eventObject, EventMessages eventMessages)
: base(new List<TEntity> { eventObject }, eventMessages)
{
}
/// <summary>
/// Constructor accepting a single entity instance
/// </summary>
/// <param name="eventObject"></param>
/// <param name="canCancel"></param>
/// <param name="isAllPublished"></param>
/// <param name="eventMessages"></param>
public PublishEventArgs(TEntity eventObject, bool canCancel, bool isAllPublished, EventMessages eventMessages)
: base(new List<TEntity> { eventObject }, canCancel, eventMessages)
{
IsAllRepublished = isAllPublished;
}
/// <summary>
/// Constructor accepting multiple entities that are used in the publish operation
/// </summary>
@@ -7,6 +7,7 @@ using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Umbraco.Core.Logging;
namespace Umbraco.Core.Persistence
{
@@ -75,8 +76,10 @@ namespace Umbraco.Core.Persistence
connection.Open();
connection.Close();
}
catch (DbException)
catch (DbException exc)
{
// Don't swallow this error, the exception is super handy for knowing "why" its not available
LogHelper.WarnWithException<IDbConnection>("Configured database is reporting as not being available!", exc);
return false;
}
+8 -13
View File
@@ -1,24 +1,17 @@
using System.Collections.Generic;
using Umbraco.Core.Models;
using Umbraco.Core.Services;
namespace Umbraco.Core.Publishing
{
/// <summary>
/// The result of publishing a content item
/// </summary>
public class PublishStatus
public class PublishStatus : OperationStatus<IContent, PublishStatusType>
{
public PublishStatus()
{
//initialize
InvalidProperties = new List<Property>();
}
public PublishStatus(IContent content, PublishStatusType statusType)
: this()
{
ContentItem = content;
StatusType = statusType;
: base(content, statusType)
{
}
/// <summary>
@@ -29,8 +22,10 @@ namespace Umbraco.Core.Publishing
{
}
public IContent ContentItem { get; private set; }
public PublishStatusType StatusType { get; internal set; }
public IContent ContentItem
{
get { return Entity; }
}
/// <summary>
/// Gets sets the invalid properties if the status failed due to validation.
@@ -5,6 +5,7 @@ using Umbraco.Core.Events;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core;
using Umbraco.Core.Services;
namespace Umbraco.Core.Publishing
{
@@ -14,6 +15,16 @@ namespace Umbraco.Core.Publishing
/// </summary>
public class PublishingStrategy : BasePublishingStrategy
{
private readonly IEventMessagesFactory _eventMessagesFactory;
private readonly ILogger _logger;
public PublishingStrategy(IEventMessagesFactory eventMessagesFactory, ILogger logger)
{
if (eventMessagesFactory == null) throw new ArgumentNullException("eventMessagesFactory");
if (logger == null) throw new ArgumentNullException("logger");
_eventMessagesFactory = eventMessagesFactory;
_logger = logger;
}
/// <summary>
/// Publishes a single piece of Content
@@ -22,18 +33,20 @@ namespace Umbraco.Core.Publishing
/// <param name="userId">Id of the User issueing the publish operation</param>
internal Attempt<PublishStatus> PublishInternal(IContent content, int userId)
{
if (Publishing.IsRaisedEventCancelled(new PublishEventArgs<IContent>(content), this))
if (Publishing.IsRaisedEventCancelled(
_eventMessagesFactory.Get(),
messages => new PublishEventArgs<IContent>(content), this))
{
LogHelper.Info<PublishingStrategy>(
_logger.Info<PublishingStrategy>(
string.Format("Content '{0}' with Id '{1}' will not be published, the event was cancelled.", content.Name, content.Id));
return Attempt<PublishStatus>.Fail(new PublishStatus(content, PublishStatusType.FailedCancelledByEvent));
}
//Check if the Content is Expired to verify that it can in fact be published
if (content.Status == ContentStatus.Expired)
{
LogHelper.Info<PublishingStrategy>(
_logger.Info<PublishingStrategy>(
string.Format("Content '{0}' with Id '{1}' has expired and could not be published.",
content.Name, content.Id));
return Attempt<PublishStatus>.Fail(new PublishStatus(content, PublishStatusType.FailedHasExpired));
@@ -42,7 +55,7 @@ namespace Umbraco.Core.Publishing
//Check if the Content is Awaiting Release to verify that it can in fact be published
if (content.Status == ContentStatus.AwaitingRelease)
{
LogHelper.Info<PublishingStrategy>(
_logger.Info<PublishingStrategy>(
string.Format("Content '{0}' with Id '{1}' is awaiting release and could not be published.",
content.Name, content.Id));
return Attempt<PublishStatus>.Fail(new PublishStatus(content, PublishStatusType.FailedAwaitingRelease));
@@ -51,7 +64,7 @@ namespace Umbraco.Core.Publishing
//Check if the Content is Trashed to verify that it can in fact be published
if (content.Status == ContentStatus.Trashed)
{
LogHelper.Info<PublishingStrategy>(
_logger.Info<PublishingStrategy>(
string.Format("Content '{0}' with Id '{1}' is trashed and could not be published.",
content.Name, content.Id));
return Attempt<PublishStatus>.Fail(new PublishStatus(content, PublishStatusType.FailedIsTrashed));
@@ -59,7 +72,7 @@ namespace Umbraco.Core.Publishing
content.ChangePublishedState(PublishedState.Published);
LogHelper.Info<PublishingStrategy>(
_logger.Info<PublishingStrategy>(
string.Format("Content '{0}' with Id '{1}' has been published.",
content.Name, content.Id));
@@ -122,7 +135,7 @@ namespace Umbraco.Core.Publishing
// much difference because we iterate over them all anyways?? Morten?
// Because we're grouping I think this will execute all the queries anyways so need to fetch it all first.
var fetchedContent = content.ToArray();
//We're going to populate the statuses with all content that is already published because below we are only going to iterate over
// content that is not published. We'll set the status to "AlreadyPublished"
statuses.AddRange(fetchedContent.Where(x => x.Published)
@@ -138,7 +151,7 @@ namespace Umbraco.Core.Publishing
//be published regardless of the rules mentioned in the remarks.
if (!firstLevel.HasValue)
{
firstLevel = level.Key;
firstLevel = level.Key;
}
/* Only update content thats not already been published - we want to loop through
@@ -149,7 +162,7 @@ namespace Umbraco.Core.Publishing
//Check if this item should be excluded because it's parent's publishing has failed/cancelled
if (parentsIdsCancelled.Contains(item.ParentId))
{
LogHelper.Info<PublishingStrategy>(
_logger.Info<PublishingStrategy>(
string.Format("Content '{0}' with Id '{1}' will not be published because it's parent's publishing action failed or was cancelled.", item.Name, item.Id));
//if this cannot be published, ensure that it's children can definitely not either!
parentsIdsCancelled.Add(item.Id);
@@ -165,23 +178,25 @@ namespace Umbraco.Core.Publishing
}
//Fire Publishing event
if (Publishing.IsRaisedEventCancelled(new PublishEventArgs<IContent>(item), this))
if (Publishing.IsRaisedEventCancelled(
_eventMessagesFactory.Get(),
messages => new PublishEventArgs<IContent>(item, messages), this))
{
//the publishing has been cancelled.
LogHelper.Info<PublishingStrategy>(
_logger.Info<PublishingStrategy>(
string.Format("Content '{0}' with Id '{1}' will not be published, the event was cancelled.", item.Name, item.Id));
statuses.Add(Attempt.Fail(new PublishStatus(item, PublishStatusType.FailedCancelledByEvent)));
//Does this document apply to our rule to cancel it's children being published?
CheckCancellingOfChildPublishing(item, parentsIdsCancelled, includeUnpublishedDocuments);
continue;
}
//Check if the content is valid if the flag is set to check
if (!item.IsValid())
{
LogHelper.Info<PublishingStrategy>(
_logger.Info<PublishingStrategy>(
string.Format("Content '{0}' with Id '{1}' will not be published because some of it's content is not passing validation rules.",
item.Name, item.Id));
statuses.Add(Attempt.Fail(new PublishStatus(item, PublishStatusType.FailedContentInvalid)));
@@ -195,21 +210,21 @@ namespace Umbraco.Core.Publishing
//Check if the Content is Expired to verify that it can in fact be published
if (item.Status == ContentStatus.Expired)
{
LogHelper.Info<PublishingStrategy>(
_logger.Info<PublishingStrategy>(
string.Format("Content '{0}' with Id '{1}' has expired and could not be published.",
item.Name, item.Id));
statuses.Add(Attempt.Fail(new PublishStatus(item, PublishStatusType.FailedHasExpired)));
//Does this document apply to our rule to cancel it's children being published?
CheckCancellingOfChildPublishing(item, parentsIdsCancelled, includeUnpublishedDocuments);
continue;
}
//Check if the Content is Awaiting Release to verify that it can in fact be published
if (item.Status == ContentStatus.AwaitingRelease)
{
LogHelper.Info<PublishingStrategy>(
_logger.Info<PublishingStrategy>(
string.Format("Content '{0}' with Id '{1}' is awaiting release and could not be published.",
item.Name, item.Id));
statuses.Add(Attempt.Fail(new PublishStatus(item, PublishStatusType.FailedAwaitingRelease)));
@@ -223,7 +238,7 @@ namespace Umbraco.Core.Publishing
//Check if the Content is Trashed to verify that it can in fact be published
if (item.Status == ContentStatus.Trashed)
{
LogHelper.Info<PublishingStrategy>(
_logger.Info<PublishingStrategy>(
string.Format("Content '{0}' with Id '{1}' is trashed and could not be published.",
item.Name, item.Id));
statuses.Add(Attempt.Fail(new PublishStatus(item, PublishStatusType.FailedIsTrashed)));
@@ -236,13 +251,13 @@ namespace Umbraco.Core.Publishing
item.ChangePublishedState(PublishedState.Published);
LogHelper.Info<PublishingStrategy>(
_logger.Info<PublishingStrategy>(
string.Format("Content '{0}' with Id '{1}' has been published.",
item.Name, item.Id));
statuses.Add(Attempt.Succeed(new PublishStatus(item)));
}
}
return statuses;
@@ -263,7 +278,7 @@ namespace Umbraco.Core.Publishing
//TODO: We're going back to the service layer here... not sure how to avoid this? And this will add extra overhead to
// any document that fails to publish...
var hasPublishedVersion = ApplicationContext.Current.Services.ContentService.HasPublishedVersion(content.Id);
if (hasPublishedVersion && !includeUnpublishedDocuments)
{
//it has a published version but our flag tells us to not include un-published documents and therefore we should
@@ -273,7 +288,7 @@ namespace Umbraco.Core.Publishing
else if (!hasPublishedVersion)
{
//it doesn't have a published version so we certainly cannot publish it's children.
parentsIdsCancelled.Add(content.Id);
parentsIdsCancelled.Add(content.Id);
}
}
@@ -327,9 +342,11 @@ namespace Umbraco.Core.Publishing
// at the moment it's done by the content service
//Fire UnPublishing event
if (UnPublishing.IsRaisedEventCancelled(new PublishEventArgs<IContent>(content), this))
if (UnPublishing.IsRaisedEventCancelled(
_eventMessagesFactory.Get(),
messages => new PublishEventArgs<IContent>(content, messages), this))
{
LogHelper.Info<PublishingStrategy>(
_logger.Info<PublishingStrategy>(
string.Format("Content '{0}' with Id '{1}' will not be unpublished, the event was cancelled.", content.Name, content.Id));
return Attempt.Fail(new PublishStatus(content, PublishStatusType.FailedCancelledByEvent));
}
@@ -340,7 +357,7 @@ namespace Umbraco.Core.Publishing
{
content.ReleaseDate = null;
LogHelper.Info<PublishingStrategy>(
_logger.Info<PublishingStrategy>(
string.Format("Content '{0}' with Id '{1}' had its release date removed, because it was unpublished.",
content.Name, content.Id));
}
@@ -349,7 +366,7 @@ namespace Umbraco.Core.Publishing
if (content.Published)
content.ChangePublishedState(PublishedState.Unpublished);
LogHelper.Info<PublishingStrategy>(
_logger.Info<PublishingStrategy>(
string.Format("Content '{0}' with Id '{1}' has been unpublished.",
content.Name, content.Id));
@@ -385,7 +402,9 @@ namespace Umbraco.Core.Publishing
/// <param name="content"><see cref="IContent"/> thats being published</param>
public override void PublishingFinalized(IContent content)
{
Published.RaiseEvent(new PublishEventArgs<IContent>(content, false, false), this);
Published.RaiseEvent(
_eventMessagesFactory.Get(),
messages => new PublishEventArgs<IContent>(content, false, false, messages), this);
}
/// <summary>
@@ -395,7 +414,9 @@ namespace Umbraco.Core.Publishing
/// <param name="isAllRepublished">Boolean indicating whether its all content that is republished</param>
public override void PublishingFinalized(IEnumerable<IContent> content, bool isAllRepublished)
{
Published.RaiseEvent(new PublishEventArgs<IContent>(content, false, isAllRepublished), this);
Published.RaiseEvent(
_eventMessagesFactory.Get(),
messages => new PublishEventArgs<IContent>(content, false, isAllRepublished, messages), this);
}
@@ -405,7 +426,9 @@ namespace Umbraco.Core.Publishing
/// <param name="content"><see cref="IContent"/> thats being unpublished</param>
public override void UnPublishingFinalized(IContent content)
{
UnPublished.RaiseEvent(new PublishEventArgs<IContent>(content, false, false), this);
UnPublished.RaiseEvent(
_eventMessagesFactory.Get(),
messages => new PublishEventArgs<IContent>(content, false, false, messages), this);
}
/// <summary>
@@ -414,7 +437,9 @@ namespace Umbraco.Core.Publishing
/// <param name="content">An enumerable list of <see cref="IContent"/> thats being unpublished</param>
public override void UnPublishingFinalized(IEnumerable<IContent> content)
{
UnPublished.RaiseEvent(new PublishEventArgs<IContent>(content, false, false), this);
UnPublished.RaiseEvent(
_eventMessagesFactory.Get(),
messages => new PublishEventArgs<IContent>(content, false, false, messages), this);
}
/// <summary>
@@ -0,0 +1,29 @@
using Umbraco.Core.Models;
using Umbraco.Core.Services;
namespace Umbraco.Core.Publishing
{
/// <summary>
/// The result of unpublishing a content item
/// </summary>
public class UnPublishStatus : OperationStatus<IContent, UnPublishedStatusType>
{
public UnPublishStatus(IContent content, UnPublishedStatusType statusType)
: base(content, statusType)
{
}
/// <summary>
/// Creates a successful unpublish status
/// </summary>
public UnPublishStatus(IContent content)
: this(content, UnPublishedStatusType.Success)
{
}
public IContent ContentItem
{
get { return Entity; }
}
}
}
@@ -0,0 +1,26 @@
namespace Umbraco.Core.Publishing
{
/// <summary>
/// A status type of the result of unpublishing a content item
/// </summary>
/// <remarks>
/// Anything less than 10 = Success!
/// </remarks>
public enum UnPublishedStatusType
{
/// <summary>
/// The unpublishing was successful.
/// </summary>
Success = 0,
/// <summary>
/// The item was already unpublished
/// </summary>
SuccessAlreadyUnPublished = 1,
/// <summary>
/// The publish action has been cancelled by an event handler
/// </summary>
FailedCancelledByEvent = 14,
}
}
+226 -136
View File
@@ -26,7 +26,7 @@ namespace Umbraco.Core.Services
/// <summary>
/// Represents the Content Service, which is an easy access to operations involving <see cref="IContent"/>
/// </summary>
public class ContentService : RepositoryService, IContentService
public class ContentService : RepositoryService, IContentService, IContentServiceOperations
{
private readonly IPublishingStrategy _publishingStrategy;
private readonly EntityXmlSerializer _entitySerializer = new EntityXmlSerializer();
@@ -38,18 +38,18 @@ namespace Umbraco.Core.Services
private static readonly ReaderWriterLockSlim Locker = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
public ContentService(
IDatabaseUnitOfWorkProvider provider,
RepositoryFactory repositoryFactory,
IDatabaseUnitOfWorkProvider provider,
RepositoryFactory repositoryFactory,
ILogger logger,
IEventMessagesFactory eventMessagesFactory,
IPublishingStrategy publishingStrategy,
IDataTypeService dataTypeService,
IPublishingStrategy publishingStrategy,
IDataTypeService dataTypeService,
IUserService userService)
: base(provider, repositoryFactory, logger, eventMessagesFactory)
{
if (publishingStrategy == null) throw new ArgumentNullException("publishingStrategy");
if (dataTypeService == null) throw new ArgumentNullException("dataTypeService");
if (userService == null) throw new ArgumentNullException("userService");
if (userService == null) throw new ArgumentNullException("userService");
_publishingStrategy = publishingStrategy;
_dataTypeService = dataTypeService;
_userService = userService;
@@ -747,7 +747,7 @@ namespace Umbraco.Core.Services
}
}
/// <summary>
/// Checks whether an <see cref="IContent"/> item has any children
@@ -857,6 +857,109 @@ namespace Umbraco.Core.Services
return result.Success;
}
/// <summary>
/// Publishes a <see cref="IContent"/> object and all its children
/// </summary>
/// <param name="content">The <see cref="IContent"/> to publish along with its children</param>
/// <param name="userId">Optional Id of the User issueing the publishing</param>
/// <param name="includeUnpublished"></param>
/// <returns>The list of statuses for all published items</returns>
IEnumerable<Attempt<PublishStatus>> IContentServiceOperations.PublishWithChildren(IContent content, int userId, bool includeUnpublished)
{
return PublishWithChildrenDo(content, userId, includeUnpublished);
}
/// <summary>
/// Saves and Publishes a single <see cref="IContent"/> object
/// </summary>
/// <param name="content">The <see cref="IContent"/> to save and publish</param>
/// <param name="userId">Optional Id of the User issueing the publishing</param>
/// <param name="raiseEvents">Optional boolean indicating whether or not to raise save events.</param>
/// <returns>True if publishing succeeded, otherwise False</returns>
Attempt<PublishStatus> IContentServiceOperations.SaveAndPublish(IContent content, int userId, bool raiseEvents)
{
return SaveAndPublishDo(content, userId, raiseEvents);
}
/// <summary>
/// Deletes an <see cref="IContent"/> object by moving it to the Recycle Bin
/// </summary>
/// <remarks>Move an item to the Recycle Bin will result in the item being unpublished</remarks>
/// <param name="content">The <see cref="IContent"/> to delete</param>
/// <param name="userId">Optional Id of the User deleting the Content</param>
Attempt<OperationStatus> IContentServiceOperations.MoveToRecycleBin(IContent content, int userId)
{
using (new WriteLock(Locker))
{
var originalPath = content.Path;
if (Trashing.IsRaisedEventCancelled(
EventMessagesFactory.Get(),
messages => new MoveEventArgs<IContent>(messages, new MoveEventInfo<IContent>(content, originalPath, Constants.System.RecycleBinContent)),
this))
{
return Attempt.Fail(OperationStatus.Cancelled);
}
var moveInfo = new List<MoveEventInfo<IContent>>
{
new MoveEventInfo<IContent>(content, originalPath, Constants.System.RecycleBinContent)
};
//Make sure that published content is unpublished before being moved to the Recycle Bin
if (HasPublishedVersion(content.Id))
{
//TODO: this shouldn't be a 'sub operation', and if it needs to be it cannot raise events and cannot be cancelled!
UnPublish(content, userId);
}
//Unpublish descendents of the content item that is being moved to trash
var descendants = GetDescendants(content).OrderBy(x => x.Level).ToList();
foreach (var descendant in descendants)
{
//TODO: this shouldn't be a 'sub operation', and if it needs to be it cannot raise events and cannot be cancelled!
UnPublish(descendant, userId);
}
var uow = UowProvider.GetUnitOfWork();
using (var repository = RepositoryFactory.CreateContentRepository(uow))
{
content.WriterId = userId;
content.ChangeTrashedState(true);
repository.AddOrUpdate(content);
//Loop through descendants to update their trash state, but ensuring structure by keeping the ParentId
foreach (var descendant in descendants)
{
moveInfo.Add(new MoveEventInfo<IContent>(descendant, descendant.Path, descendant.ParentId));
descendant.WriterId = userId;
descendant.ChangeTrashedState(true, descendant.ParentId);
repository.AddOrUpdate(descendant);
}
uow.Commit();
}
Trashed.RaiseEvent(EventMessagesFactory.Get(), messages => new MoveEventArgs<IContent>(false, messages, moveInfo.ToArray()), this);
Audit(AuditType.Move, "Move Content to Recycle Bin performed by user", userId, content.Id);
return Attempt.Succeed(OperationStatus.Success);
}
}
/// <summary>
/// UnPublishes a single <see cref="IContent"/> object
/// </summary>
/// <param name="content">The <see cref="IContent"/> to publish</param>
/// <param name="userId">Optional Id of the User issueing the publishing</param>
/// <returns>True if unpublishing succeeded, otherwise False</returns>
Attempt<UnPublishStatus> IContentServiceOperations.UnPublish(IContent content, int userId)
{
return UnPublishDo(content, false, userId);
}
/// <summary>
/// Publishes a single <see cref="IContent"/> object
/// </summary>
@@ -865,7 +968,7 @@ namespace Umbraco.Core.Services
/// <returns>True if publishing succeeded, otherwise False</returns>
public Attempt<PublishStatus> PublishWithStatus(IContent content, int userId = 0)
{
return SaveAndPublishDo(content, userId);
return ((IContentServiceOperations)this).Publish(content, userId);
}
/// <summary>
@@ -881,7 +984,7 @@ namespace Umbraco.Core.Services
//This used to just return false only when the parent content failed, otherwise would always return true so we'll
// do the same thing for the moment
if (!result.Any(x => x.Result.ContentItem.Id == content.Id))
if (result.All(x => x.Result.ContentItem.Id != content.Id))
return false;
return result.Single(x => x.Result.ContentItem.Id == content.Id).Success;
@@ -896,7 +999,7 @@ namespace Umbraco.Core.Services
/// <returns>True if publishing succeeded, otherwise False</returns>
public IEnumerable<Attempt<PublishStatus>> PublishWithChildrenWithStatus(IContent content, int userId = 0, bool includeUnpublished = false)
{
return PublishWithChildrenDo(content, userId, includeUnpublished);
return ((IContentServiceOperations)this).PublishWithChildren(content, userId, includeUnpublished);
}
/// <summary>
@@ -907,7 +1010,7 @@ namespace Umbraco.Core.Services
/// <returns>True if unpublishing succeeded, otherwise False</returns>
public bool UnPublish(IContent content, int userId = 0)
{
return UnPublishDo(content, false, userId);
return ((IContentServiceOperations) this).UnPublish(content, userId).Success;
}
/// <summary>
@@ -933,7 +1036,7 @@ namespace Umbraco.Core.Services
/// <returns>True if publishing succeeded, otherwise False</returns>
public Attempt<PublishStatus> SaveAndPublishWithStatus(IContent content, int userId = 0, bool raiseEvents = true)
{
return SaveAndPublishDo(content, userId, raiseEvents);
return ((IContentServiceOperations)this).SaveAndPublish(content, userId, raiseEvents);
}
/// <summary>
@@ -942,9 +1045,9 @@ namespace Umbraco.Core.Services
/// <param name="content">The <see cref="IContent"/> to save</param>
/// <param name="userId">Optional Id of the User saving the Content</param>
/// <param name="raiseEvents">Optional boolean indicating whether or not to raise events.</param>
public Attempt<OperationStatus> SaveWithStatus(IContent content, int userId = 0, bool raiseEvents = true)
public void Save(IContent content, int userId = 0, bool raiseEvents = true)
{
return Save(content, true, userId, raiseEvents);
((IContentServiceOperations)this).Save(content, userId, raiseEvents);
}
/// <summary>
@@ -953,7 +1056,7 @@ namespace Umbraco.Core.Services
/// <param name="contents">Collection of <see cref="IContent"/> to save</param>
/// <param name="userId">Optional Id of the User saving the Content</param>
/// <param name="raiseEvents">Optional boolean indicating whether or not to raise events.</param>
public Attempt<OperationStatus> SaveWithStatus(IEnumerable<IContent> contents, int userId = 0, bool raiseEvents = true)
Attempt<OperationStatus> IContentServiceOperations.Save(IEnumerable<IContent> contents, int userId, bool raiseEvents)
{
var asArray = contents.ToArray();
@@ -1012,15 +1115,80 @@ namespace Umbraco.Core.Services
}
}
/// <summary>
/// Permanently deletes an <see cref="IContent"/> object.
/// </summary>
/// <remarks>
/// This method will also delete associated media files, child content and possibly associated domains.
/// </remarks>
/// <remarks>Please note that this method will completely remove the Content from the database</remarks>
/// <param name="content">The <see cref="IContent"/> to delete</param>
/// <param name="userId">Optional Id of the User deleting the Content</param>
Attempt<OperationStatus> IContentServiceOperations.Delete(IContent content, int userId)
{
using (new WriteLock(Locker))
{
if (Deleting.IsRaisedEventCancelled(
EventMessagesFactory.Get(),
messages => new DeleteEventArgs<IContent>(content, messages),
this))
{
return Attempt.Fail(OperationStatus.Cancelled);
}
//Make sure that published content is unpublished before being deleted
if (HasPublishedVersion(content.Id))
{
UnPublish(content, userId);
}
//Delete children before deleting the 'possible parent'
var children = GetChildren(content.Id);
foreach (var child in children)
{
Delete(child, userId);
}
var uow = UowProvider.GetUnitOfWork();
using (var repository = RepositoryFactory.CreateContentRepository(uow))
{
repository.Delete(content);
uow.Commit();
var evtMsgs = EventMessagesFactory.Get();
var args = new DeleteEventArgs<IContent>(content, false, evtMsgs);
Deleted.RaiseEvent(evtMsgs, messages => args, this);
//remove any flagged media files
repository.DeleteMediaFiles(args.MediaFilesToDelete);
}
Audit(AuditType.Delete, "Delete Content performed by user", userId, content.Id);
return Attempt.Succeed(OperationStatus.Success);
}
}
/// <summary>
/// Publishes a single <see cref="IContent"/> object
/// </summary>
/// <param name="content">The <see cref="IContent"/> to publish</param>
/// <param name="userId">Optional Id of the User issueing the publishing</param>
/// <returns>The published status attempt</returns>
Attempt<PublishStatus> IContentServiceOperations.Publish(IContent content, int userId)
{
return SaveAndPublishDo(content, userId);
}
/// <summary>
/// Saves a single <see cref="IContent"/> object
/// </summary>
/// <param name="content">The <see cref="IContent"/> to save</param>
/// <param name="userId">Optional Id of the User saving the Content</param>
/// <param name="raiseEvents">Optional boolean indicating whether or not to raise events.</param>
public void Save(IContent content, int userId = 0, bool raiseEvents = true)
Attempt<OperationStatus> IContentServiceOperations.Save(IContent content, int userId, bool raiseEvents)
{
SaveWithStatus(content, userId, raiseEvents);
return Save(content, true, userId, raiseEvents);
}
/// <summary>
@@ -1035,7 +1203,7 @@ namespace Umbraco.Core.Services
/// <param name="raiseEvents">Optional boolean indicating whether or not to raise events.</param>
public void Save(IEnumerable<IContent> contents, int userId = 0, bool raiseEvents = true)
{
SaveWithStatus(contents, userId, raiseEvents);
((IContentServiceOperations)this).Save(contents, userId, raiseEvents);
}
/// <summary>
@@ -1093,39 +1261,7 @@ namespace Umbraco.Core.Services
/// <param name="userId">Optional Id of the User deleting the Content</param>
public void Delete(IContent content, int userId = 0)
{
using (new WriteLock(Locker))
{
if (Deleting.IsRaisedEventCancelled(new DeleteEventArgs<IContent>(content), this))
return;
//Make sure that published content is unpublished before being deleted
if (HasPublishedVersion(content.Id))
{
UnPublish(content, userId);
}
//Delete children before deleting the 'possible parent'
var children = GetChildren(content.Id);
foreach (var child in children)
{
Delete(child, userId);
}
var uow = UowProvider.GetUnitOfWork();
using (var repository = RepositoryFactory.CreateContentRepository(uow))
{
repository.Delete(content);
uow.Commit();
var args = new DeleteEventArgs<IContent>(content, false);
Deleted.RaiseEvent(args, this);
//remove any flagged media files
repository.DeleteMediaFiles(args.MediaFilesToDelete);
}
Audit(AuditType.Delete, "Delete Content performed by user", userId, content.Id);
}
((IContentServiceOperations)this).Delete(content, userId);
}
/// <summary>
@@ -1194,59 +1330,7 @@ namespace Umbraco.Core.Services
/// <param name="userId">Optional Id of the User deleting the Content</param>
public void MoveToRecycleBin(IContent content, int userId = 0)
{
using (new WriteLock(Locker))
{
var originalPath = content.Path;
if (Trashing.IsRaisedEventCancelled(
new MoveEventArgs<IContent>(
new MoveEventInfo<IContent>(content, originalPath, Constants.System.RecycleBinContent)), this))
{
return;
}
var moveInfo = new List<MoveEventInfo<IContent>>
{
new MoveEventInfo<IContent>(content, originalPath, Constants.System.RecycleBinContent)
};
//Make sure that published content is unpublished before being moved to the Recycle Bin
if (HasPublishedVersion(content.Id))
{
UnPublish(content, userId);
}
//Unpublish descendents of the content item that is being moved to trash
var descendants = GetDescendants(content).OrderBy(x => x.Level).ToList();
foreach (var descendant in descendants)
{
UnPublish(descendant, userId);
}
var uow = UowProvider.GetUnitOfWork();
using (var repository = RepositoryFactory.CreateContentRepository(uow))
{
content.WriterId = userId;
content.ChangeTrashedState(true);
repository.AddOrUpdate(content);
//Loop through descendants to update their trash state, but ensuring structure by keeping the ParentId
foreach (var descendant in descendants)
{
moveInfo.Add(new MoveEventInfo<IContent>(descendant, descendant.Path, descendant.ParentId));
descendant.WriterId = userId;
descendant.ChangeTrashedState(true, descendant.ParentId);
repository.AddOrUpdate(descendant);
}
uow.Commit();
}
Trashed.RaiseEvent(new MoveEventArgs<IContent>(false, moveInfo.ToArray()), this);
Audit(AuditType.Move, "Move Content to Recycle Bin performed by user", userId, content.Id);
}
((IContentServiceOperations) this).MoveToRecycleBin(content, userId);
}
/// <summary>
@@ -1414,7 +1498,7 @@ namespace Umbraco.Core.Services
SentToPublish.RaiseEvent(new SendToPublishEventArgs<IContent>(content, false), this);
Audit(AuditType.SendToPublish, "Send to Publish performed by user", content.WriterId, content.Id);
return true;
}
@@ -1504,6 +1588,7 @@ namespace Umbraco.Core.Services
if (content.Published)
{
//TODO: This should not be an inner operation, but if we do this, it cannot raise events and cannot be cancellable!
var published = _publishingStrategy.Publish(content, userId);
shouldBePublished.Add(content);
}
@@ -1529,7 +1614,11 @@ namespace Umbraco.Core.Services
Saved.RaiseEvent(new SaveEventArgs<IContent>(asArray, false), this);
if (shouldBePublished.Any())
{
//TODO: This should not be an inner operation, but if we do this, it cannot raise events and cannot be cancellable!
_publishingStrategy.PublishingFinalized(shouldBePublished, false);
}
Audit(AuditType.Sort, "Sorting content performed by user", userId, 0);
@@ -1707,9 +1796,9 @@ namespace Umbraco.Core.Services
result.Add(
Attempt.Fail(
new PublishStatus(content, PublishStatusType.FailedContentInvalid)
{
InvalidProperties = ((ContentBase)content).LastInvalidProperties
}));
{
InvalidProperties = ((ContentBase)content).LastInvalidProperties
}));
return result;
}
@@ -1763,38 +1852,39 @@ namespace Umbraco.Core.Services
/// <param name="omitCacheRefresh">Optional boolean to avoid having the cache refreshed when calling this Unpublish method. By default this method will update the cache.</param>
/// <param name="userId">Optional Id of the User issueing the publishing</param>
/// <returns>True if unpublishing succeeded, otherwise False</returns>
private bool UnPublishDo(IContent content, bool omitCacheRefresh = false, int userId = 0)
private Attempt<UnPublishStatus> UnPublishDo(IContent content, bool omitCacheRefresh = false, int userId = 0)
{
var newest = GetById(content.Id); // ensure we have the newest version
if (content.Version != newest.Version) // but use the original object if it's already the newest version
content = newest;
var published = content.Published ? content : GetPublishedVersion(content.Id); // get the published version
if (published == null)
return false; // already unpublished
var unpublished = _publishingStrategy.UnPublish(content, userId);
if (unpublished)
{
var uow = UowProvider.GetUnitOfWork();
using (var repository = RepositoryFactory.CreateContentRepository(uow))
{
content.WriterId = userId;
repository.AddOrUpdate(content);
// is published is not newest, reset the published flag on published version
if (published.Version != content.Version)
repository.ClearPublished(published);
repository.DeleteContentXml(content);
uow.Commit();
}
//Delete xml from db? and call following method to fire event through PublishingStrategy to update cache
if (omitCacheRefresh == false)
_publishingStrategy.UnPublishingFinalized(content);
Audit(AuditType.UnPublish, "UnPublish performed by user", userId, content.Id);
return Attempt.Succeed(new UnPublishStatus(content, UnPublishedStatusType.SuccessAlreadyUnPublished)); // already unpublished
}
var unpublished = _publishingStrategy.UnPublish(content, userId);
if (unpublished == false) return Attempt.Fail(new UnPublishStatus(content, UnPublishedStatusType.FailedCancelledByEvent));
return unpublished;
var uow = UowProvider.GetUnitOfWork();
using (var repository = RepositoryFactory.CreateContentRepository(uow))
{
content.WriterId = userId;
repository.AddOrUpdate(content);
// is published is not newest, reset the published flag on published version
if (published.Version != content.Version)
repository.ClearPublished(published);
repository.DeleteContentXml(content);
uow.Commit();
}
//Delete xml from db? and call following method to fire event through PublishingStrategy to update cache
if (omitCacheRefresh == false)
_publishingStrategy.UnPublishingFinalized(content);
Audit(AuditType.UnPublish, "UnPublish performed by user", userId, content.Id);
return Attempt.Succeed(new UnPublishStatus(content, UnPublishedStatusType.Success));
}
/// <summary>
@@ -1903,13 +1993,13 @@ namespace Umbraco.Core.Services
{
if (raiseEvents)
{
if (Saving.IsRaisedEventCancelled(
EventMessagesFactory.Get(),
messages => new SaveEventArgs<IContent>(content, messages),
this))
if (Saving.IsRaisedEventCancelled(
EventMessagesFactory.Get(),
messages => new SaveEventArgs<IContent>(content, messages),
this))
{
return Attempt.Fail(OperationStatus.Cancelled);
}
}
}
using (new WriteLock(Locker))
+83 -23
View File
@@ -8,6 +8,86 @@ using Umbraco.Core.Publishing;
namespace Umbraco.Core.Services
{
/// <summary>
/// A temporary interface until we are in v8, this is used to return a different result for the same method and this interface gets implemented
/// explicitly. These methods will replace the normal ones in IContentService in v8 and this will be removed.
/// </summary>
public interface IContentServiceOperations
{
//TODO: Remove this class in v8
//TODO: There's probably more that needs to be added like the EmptyRecycleBin, etc...
/// <summary>
/// Saves a single <see cref="IContent"/> object
/// </summary>
/// <param name="content">The <see cref="IContent"/> to save</param>
/// <param name="userId">Optional Id of the User saving the Content</param>
/// <param name="raiseEvents">Optional boolean indicating whether or not to raise events.</param>
Attempt<OperationStatus> Save(IContent content, int userId = 0, bool raiseEvents = true);
/// <summary>
/// Saves a collection of <see cref="IContent"/> objects.
/// </summary>
/// <param name="contents">Collection of <see cref="IContent"/> to save</param>
/// <param name="userId">Optional Id of the User saving the Content</param>
/// <param name="raiseEvents">Optional boolean indicating whether or not to raise events.</param>
Attempt<OperationStatus> Save(IEnumerable<IContent> contents, int userId = 0, bool raiseEvents = true);
/// <summary>
/// Permanently deletes an <see cref="IContent"/> object.
/// </summary>
/// <remarks>
/// This method will also delete associated media files, child content and possibly associated domains.
/// </remarks>
/// <remarks>Please note that this method will completely remove the Content from the database</remarks>
/// <param name="content">The <see cref="IContent"/> to delete</param>
/// <param name="userId">Optional Id of the User deleting the Content</param>
Attempt<OperationStatus> Delete(IContent content, int userId = 0);
/// <summary>
/// Publishes a single <see cref="IContent"/> object
/// </summary>
/// <param name="content">The <see cref="IContent"/> to publish</param>
/// <param name="userId">Optional Id of the User issueing the publishing</param>
/// <returns>The published status attempt</returns>
Attempt<PublishStatus> Publish(IContent content, int userId = 0);
/// <summary>
/// Publishes a <see cref="IContent"/> object and all its children
/// </summary>
/// <param name="content">The <see cref="IContent"/> to publish along with its children</param>
/// <param name="userId">Optional Id of the User issueing the publishing</param>
/// <param name="includeUnpublished"></param>
/// <returns>The list of statuses for all published items</returns>
IEnumerable<Attempt<PublishStatus>> PublishWithChildren(IContent content, int userId = 0, bool includeUnpublished = false);
/// <summary>
/// Saves and Publishes a single <see cref="IContent"/> object
/// </summary>
/// <param name="content">The <see cref="IContent"/> to save and publish</param>
/// <param name="userId">Optional Id of the User issueing the publishing</param>
/// <param name="raiseEvents">Optional boolean indicating whether or not to raise save events.</param>
/// <returns>True if publishing succeeded, otherwise False</returns>
Attempt<PublishStatus> SaveAndPublish(IContent content, int userId = 0, bool raiseEvents = true);
/// <summary>
/// Deletes an <see cref="IContent"/> object by moving it to the Recycle Bin
/// </summary>
/// <remarks>Move an item to the Recycle Bin will result in the item being unpublished</remarks>
/// <param name="content">The <see cref="IContent"/> to delete</param>
/// <param name="userId">Optional Id of the User deleting the Content</param>
Attempt<OperationStatus> MoveToRecycleBin(IContent content, int userId = 0);
/// <summary>
/// UnPublishes a single <see cref="IContent"/> object
/// </summary>
/// <param name="content">The <see cref="IContent"/> to publish</param>
/// <param name="userId">Optional Id of the User issueing the publishing</param>
/// <returns>True if unpublishing succeeded, otherwise False</returns>
Attempt<UnPublishStatus> UnPublish(IContent content, int userId = 0);
}
/// <summary>
/// Defines the ContentService, which is an easy access to operations involving <see cref="IContent"/>
/// </summary>
@@ -188,31 +268,13 @@ namespace Umbraco.Core.Services
/// </summary>
/// <returns>An Enumerable list of <see cref="IContent"/> objects</returns>
IEnumerable<IContent> GetContentInRecycleBin();
/// <summary>
/// Saves a single <see cref="IContent"/> object
/// </summary>
/// <param name="content">The <see cref="IContent"/> to save</param>
/// <param name="userId">Optional Id of the User saving the Content</param>
/// <param name="raiseEvents">Optional boolean indicating whether or not to raise events.</param>
Attempt<OperationStatus> SaveWithStatus(IContent content, int userId = 0, bool raiseEvents = true);
/// <summary>
/// Saves a collection of <see cref="IContent"/> objects.
/// </summary>
/// <param name="contents">Collection of <see cref="IContent"/> to save</param>
/// <param name="userId">Optional Id of the User saving the Content</param>
/// <param name="raiseEvents">Optional boolean indicating whether or not to raise events.</param>
Attempt<OperationStatus> SaveWithStatus(IEnumerable<IContent> contents, int userId = 0, bool raiseEvents = true);
/// <summary>
/// Saves a single <see cref="IContent"/> object
/// </summary>
/// <param name="content">The <see cref="IContent"/> to save</param>
/// <param name="userId">Optional Id of the User saving the Content</param>
/// <param name="raiseEvents">Optional boolean indicating whether or not to raise events.</param>
[EditorBrowsable(EditorBrowsableState.Never)]
[Obsolete("Use SaveWithStatus instead, that method will provide more detailed information on the outcome")]
void Save(IContent content, int userId = 0, bool raiseEvents = true);
/// <summary>
@@ -221,8 +283,6 @@ namespace Umbraco.Core.Services
/// <param name="contents">Collection of <see cref="IContent"/> to save</param>
/// <param name="userId">Optional Id of the User saving the Content</param>
/// <param name="raiseEvents">Optional boolean indicating whether or not to raise events.</param>
[EditorBrowsable(EditorBrowsableState.Never)]
[Obsolete("Use SaveWithStatus instead, that method will provide more detailed information on the outcome")]
void Save(IEnumerable<IContent> contents, int userId = 0, bool raiseEvents = true);
/// <summary>
@@ -407,7 +467,7 @@ namespace Umbraco.Core.Services
/// <param name="raiseEvents">Optional boolean indicating whether or not to raise save events.</param>
/// <returns>True if publishing succeeded, otherwise False</returns>
Attempt<PublishStatus> SaveAndPublishWithStatus(IContent content, int userId = 0, bool raiseEvents = true);
/// <summary>
/// Permanently deletes an <see cref="IContent"/> object.
/// </summary>
@@ -416,7 +476,7 @@ namespace Umbraco.Core.Services
/// </remarks>
/// <remarks>Please note that this method will completely remove the Content from the database</remarks>
/// <param name="content">The <see cref="IContent"/> to delete</param>
/// <param name="userId">Optional Id of the User deleting the Content</param>
/// <param name="userId">Optional Id of the User deleting the Content</param>
void Delete(IContent content, int userId = 0);
/// <summary>
+46 -21
View File
@@ -6,6 +6,51 @@ using Umbraco.Core.Persistence.DatabaseModelDefinitions;
namespace Umbraco.Core.Services
{
/// <summary>
/// A temporary interface until we are in v8, this is used to return a different result for the same method and this interface gets implemented
/// explicitly. These methods will replace the normal ones in IContentService in v8 and this will be removed.
/// </summary>
public interface IMediaServiceOperations
{
//TODO: Remove this class in v8
//TODO: There's probably more that needs to be added like the EmptyRecycleBin, etc...
/// <summary>
/// Deletes an <see cref="IMedia"/> object by moving it to the Recycle Bin
/// </summary>
/// <param name="media">The <see cref="IMedia"/> to delete</param>
/// <param name="userId">Id of the User deleting the Media</param>
Attempt<OperationStatus> MoveToRecycleBin(IMedia media, int userId = 0);
/// <summary>
/// Permanently deletes an <see cref="IMedia"/> object
/// </summary>
/// <remarks>
/// Please note that this method will completely remove the Media from the database,
/// but current not from the file system.
/// </remarks>
/// <param name="media">The <see cref="IMedia"/> to delete</param>
/// <param name="userId">Id of the User deleting the Media</param>
Attempt<OperationStatus> Delete(IMedia media, int userId = 0);
/// <summary>
/// Saves a single <see cref="IMedia"/> object
/// </summary>
/// <param name="media">The <see cref="IMedia"/> to save</param>
/// <param name="userId">Id of the User saving the Media</param>
/// <param name="raiseEvents">Optional boolean indicating whether or not to raise events.</param>
Attempt<OperationStatus> Save(IMedia media, int userId = 0, bool raiseEvents = true);
/// <summary>
/// Saves a collection of <see cref="IMedia"/> objects
/// </summary>
/// <param name="medias">Collection of <see cref="IMedia"/> to save</param>
/// <param name="userId">Id of the User saving the Media</param>
/// <param name="raiseEvents">Optional boolean indicating whether or not to raise events.</param>
Attempt<OperationStatus> Save(IEnumerable<IMedia> medias, int userId = 0, bool raiseEvents = true);
}
/// <summary>
/// Defines the Media Service, which is an easy access to operations involving <see cref="IMedia"/>
/// </summary>
@@ -174,31 +219,13 @@ namespace Umbraco.Core.Services
/// <param name="media">The <see cref="IMedia"/> to delete</param>
/// <param name="userId">Id of the User deleting the Media</param>
void Delete(IMedia media, int userId = 0);
/// <summary>
/// Saves a single <see cref="IMedia"/> object
/// </summary>
/// <param name="media">The <see cref="IMedia"/> to save</param>
/// <param name="userId">Id of the User saving the Media</param>
/// <param name="raiseEvents">Optional boolean indicating whether or not to raise events.</param>
Attempt<OperationStatus> SaveWithStatus(IMedia media, int userId = 0, bool raiseEvents = true);
/// <summary>
/// Saves a collection of <see cref="IMedia"/> objects
/// </summary>
/// <param name="medias">Collection of <see cref="IMedia"/> to save</param>
/// <param name="userId">Id of the User saving the Media</param>
/// <param name="raiseEvents">Optional boolean indicating whether or not to raise events.</param>
Attempt<OperationStatus> SaveWithStatus(IEnumerable<IMedia> medias, int userId = 0, bool raiseEvents = true);
/// <summary>
/// Saves a single <see cref="IMedia"/> object
/// </summary>
/// <param name="media">The <see cref="IMedia"/> to save</param>
/// <param name="userId">Id of the User saving the Media</param>
/// <param name="raiseEvents">Optional boolean indicating whether or not to raise events.</param>
[EditorBrowsable(EditorBrowsableState.Never)]
[Obsolete("Use SaveWithStatus instead, that method will provide more detailed information on the outcome")]
void Save(IMedia media, int userId = 0, bool raiseEvents = true);
/// <summary>
@@ -207,8 +234,6 @@ namespace Umbraco.Core.Services
/// <param name="medias">Collection of <see cref="IMedia"/> to save</param>
/// <param name="userId">Id of the User saving the Media</param>
/// <param name="raiseEvents">Optional boolean indicating whether or not to raise events.</param>
[EditorBrowsable(EditorBrowsableState.Never)]
[Obsolete("Use SaveWithStatus instead, that method will provide more detailed information on the outcome")]
void Save(IEnumerable<IMedia> medias, int userId = 0, bool raiseEvents = true);
/// <summary>
+182 -147
View File
@@ -25,7 +25,7 @@ namespace Umbraco.Core.Services
/// <summary>
/// Represents the Media Service, which is an easy access to operations involving <see cref="IMedia"/>
/// </summary>
public class MediaService : RepositoryService, IMediaService
public class MediaService : RepositoryService, IMediaService, IMediaServiceOperations
{
//Support recursive locks because some of the methods that require locking call other methods that require locking.
@@ -726,54 +726,144 @@ namespace Umbraco.Core.Services
/// <param name="userId">Id of the User deleting the Media</param>
public void MoveToRecycleBin(IMedia media, int userId = 0)
{
if (media == null) throw new ArgumentNullException("media");
((IMediaServiceOperations) this).MoveToRecycleBin(media, userId);
}
var originalPath = media.Path;
/// <summary>
/// Permanently deletes an <see cref="IMedia"/> object
/// </summary>
/// <remarks>
/// Please note that this method will completely remove the Media from the database,
/// but current not from the file system.
/// </remarks>
/// <param name="media">The <see cref="IMedia"/> to delete</param>
/// <param name="userId">Id of the User deleting the Media</param>
Attempt<OperationStatus> IMediaServiceOperations.Delete(IMedia media, int userId)
{
//TODO: IT would be much nicer to mass delete all in one trans in the repo level!
if (Trashing.IsRaisedEventCancelled(
new MoveEventArgs<IMedia>(
new MoveEventInfo<IMedia>(media, originalPath, Constants.System.RecycleBinMedia)), this))
if (Deleting.IsRaisedEventCancelled(
EventMessagesFactory.Get(),
messages => new DeleteEventArgs<IMedia>(media, messages), this))
{
return;
return Attempt.Fail(OperationStatus.Cancelled);
}
var moveInfo = new List<MoveEventInfo<IMedia>>
//Delete children before deleting the 'possible parent'
var children = GetChildren(media.Id);
foreach (var child in children)
{
new MoveEventInfo<IMedia>(media, originalPath, Constants.System.RecycleBinMedia)
};
//Find Descendants, which will be moved to the recycle bin along with the parent/grandparent.
var descendants = GetDescendants(media).OrderBy(x => x.Level).ToList();
Delete(child, userId);
}
var uow = UowProvider.GetUnitOfWork();
using (var repository = RepositoryFactory.CreateMediaRepository(uow))
{
//TODO: This should be part of the repo!
repository.Delete(media);
uow.Commit();
//Remove 'published' xml from the cmsContentXml table for the unpublished media
uow.Database.Delete<ContentXmlDto>("WHERE nodeId = @Id", new { Id = media.Id });
var msgs = EventMessagesFactory.Get();
var args = new DeleteEventArgs<IMedia>(media, false, msgs);
Deleted.RaiseEvent(msgs, messages => args, this);
media.ChangeTrashedState(true, Constants.System.RecycleBinMedia);
repository.AddOrUpdate(media);
//remove any flagged media files
repository.DeleteMediaFiles(args.MediaFilesToDelete);
}
//Loop through descendants to update their trash state, but ensuring structure by keeping the ParentId
foreach (var descendant in descendants)
Audit(AuditType.Delete, "Delete Media performed by user", userId, media.Id);
return Attempt.Succeed(OperationStatus.Success);
}
/// <summary>
/// Saves a single <see cref="IMedia"/> object
/// </summary>
/// <param name="media">The <see cref="IMedia"/> to save</param>
/// <param name="userId">Id of the User saving the Media</param>
/// <param name="raiseEvents">Optional boolean indicating whether or not to raise events.</param>
Attempt<OperationStatus> IMediaServiceOperations.Save(IMedia media, int userId, bool raiseEvents)
{
if (raiseEvents)
{
if (Saving.IsRaisedEventCancelled(
EventMessagesFactory.Get(),
messages => new SaveEventArgs<IMedia>(media, messages),
this))
{
//Remove 'published' xml from the cmsContentXml table for the unpublished media
uow.Database.Delete<ContentXmlDto>("WHERE nodeId = @Id", new { Id = descendant.Id });
return Attempt.Fail(OperationStatus.Cancelled);
}
descendant.ChangeTrashedState(true, descendant.ParentId);
repository.AddOrUpdate(descendant);
}
moveInfo.Add(new MoveEventInfo<IMedia>(descendant, descendant.Path, descendant.ParentId));
var uow = UowProvider.GetUnitOfWork();
using (var repository = RepositoryFactory.CreateMediaRepository(uow))
{
media.CreatorId = userId;
repository.AddOrUpdate(media);
repository.AddOrUpdateContentXml(media, m => _entitySerializer.Serialize(this, _dataTypeService, _userService, m));
// generate preview for blame history?
if (UmbracoConfig.For.UmbracoSettings().Content.GlobalPreviewStorageEnabled)
{
repository.AddOrUpdatePreviewXml(media, m => _entitySerializer.Serialize(this, _dataTypeService, _userService, m));
}
uow.Commit();
}
Trashed.RaiseEvent(new MoveEventArgs<IMedia>(false, moveInfo.ToArray()), this);
if (raiseEvents)
Saved.RaiseEvent(EventMessagesFactory.Get(), messages => new SaveEventArgs<IMedia>(media, false, messages), this);
Audit(AuditType.Move, "Move Media to Recycle Bin performed by user", userId, media.Id);
Audit(AuditType.Save, "Save Media performed by user", userId, media.Id);
return Attempt.Succeed(OperationStatus.Success);
}
/// <summary>
/// Saves a collection of <see cref="IMedia"/> objects
/// </summary>
/// <param name="medias">Collection of <see cref="IMedia"/> to save</param>
/// <param name="userId">Id of the User saving the Media</param>
/// <param name="raiseEvents">Optional boolean indicating whether or not to raise events.</param>
Attempt<OperationStatus> IMediaServiceOperations.Save(IEnumerable<IMedia> medias, int userId, bool raiseEvents)
{
var asArray = medias.ToArray();
if (raiseEvents)
{
if (Saving.IsRaisedEventCancelled(
EventMessagesFactory.Get(),
messages => new SaveEventArgs<IMedia>(asArray, messages),
this))
{
return Attempt.Fail(OperationStatus.Cancelled);
}
}
var uow = UowProvider.GetUnitOfWork();
using (var repository = RepositoryFactory.CreateMediaRepository(uow))
{
foreach (var media in asArray)
{
media.CreatorId = userId;
repository.AddOrUpdate(media);
repository.AddOrUpdateContentXml(media, m => _entitySerializer.Serialize(this, _dataTypeService, _userService, m));
// generate preview for blame history?
if (UmbracoConfig.For.UmbracoSettings().Content.GlobalPreviewStorageEnabled)
{
repository.AddOrUpdatePreviewXml(media, m => _entitySerializer.Serialize(this, _dataTypeService, _userService, m));
}
}
//commit the whole lot in one go
uow.Commit();
}
if (raiseEvents)
Saved.RaiseEvent(EventMessagesFactory.Get(), messages => new SaveEventArgs<IMedia>(asArray, false, messages), this);
Audit(AuditType.Save, "Save Media items performed by user", userId, -1);
return Attempt.Succeed(OperationStatus.Success);
}
/// <summary>
@@ -859,6 +949,67 @@ namespace Umbraco.Core.Services
}
}
/// <summary>
/// Deletes an <see cref="IMedia"/> object by moving it to the Recycle Bin
/// </summary>
/// <param name="media">The <see cref="IMedia"/> to delete</param>
/// <param name="userId">Id of the User deleting the Media</param>
Attempt<OperationStatus> IMediaServiceOperations.MoveToRecycleBin(IMedia media, int userId)
{
if (media == null) throw new ArgumentNullException("media");
var originalPath = media.Path;
if (Trashing.IsRaisedEventCancelled(
EventMessagesFactory.Get(),
messages => new MoveEventArgs<IMedia>(messages, new MoveEventInfo<IMedia>(media, originalPath, Constants.System.RecycleBinMedia)), this))
{
return Attempt.Fail(OperationStatus.Cancelled);
}
var moveInfo = new List<MoveEventInfo<IMedia>>
{
new MoveEventInfo<IMedia>(media, originalPath, Constants.System.RecycleBinMedia)
};
//Find Descendants, which will be moved to the recycle bin along with the parent/grandparent.
var descendants = GetDescendants(media).OrderBy(x => x.Level).ToList();
var uow = UowProvider.GetUnitOfWork();
using (var repository = RepositoryFactory.CreateMediaRepository(uow))
{
//TODO: This should be part of the repo!
//Remove 'published' xml from the cmsContentXml table for the unpublished media
uow.Database.Delete<ContentXmlDto>("WHERE nodeId = @Id", new { Id = media.Id });
media.ChangeTrashedState(true, Constants.System.RecycleBinMedia);
repository.AddOrUpdate(media);
//Loop through descendants to update their trash state, but ensuring structure by keeping the ParentId
foreach (var descendant in descendants)
{
//Remove 'published' xml from the cmsContentXml table for the unpublished media
uow.Database.Delete<ContentXmlDto>("WHERE nodeId = @Id", new { Id = descendant.Id });
descendant.ChangeTrashedState(true, descendant.ParentId);
repository.AddOrUpdate(descendant);
moveInfo.Add(new MoveEventInfo<IMedia>(descendant, descendant.Path, descendant.ParentId));
}
uow.Commit();
}
Trashed.RaiseEvent(
EventMessagesFactory.Get(),
messages => new MoveEventArgs<IMedia>(false, messages, moveInfo.ToArray()), this);
Audit(AuditType.Move, "Move Media to Recycle Bin performed by user", userId, media.Id);
return Attempt.Succeed(OperationStatus.Success);
}
/// <summary>
/// Permanently deletes an <see cref="IMedia"/> object as well as all of its Children.
/// </summary>
@@ -870,32 +1021,7 @@ namespace Umbraco.Core.Services
/// <param name="userId">Id of the User deleting the Media</param>
public void Delete(IMedia media, int userId = 0)
{
//TODO: IT would be much nicer to mass delete all in one trans in the repo level!
if (Deleting.IsRaisedEventCancelled(new DeleteEventArgs<IMedia>(media), this))
return;
//Delete children before deleting the 'possible parent'
var children = GetChildren(media.Id);
foreach (var child in children)
{
Delete(child, userId);
}
var uow = UowProvider.GetUnitOfWork();
using (var repository = RepositoryFactory.CreateMediaRepository(uow))
{
repository.Delete(media);
uow.Commit();
var args = new DeleteEventArgs<IMedia>(media, false);
Deleted.RaiseEvent(args, this);
//remove any flagged media files
repository.DeleteMediaFiles(args.MediaFilesToDelete);
}
Audit(AuditType.Delete, "Delete Media performed by user", userId, media.Id);
}
@@ -954,98 +1080,7 @@ namespace Umbraco.Core.Services
Audit(AuditType.Delete, "Delete Media by version performed by user", userId, -1);
}
/// <summary>
/// Saves a single <see cref="IMedia"/> object
/// </summary>
/// <param name="media">The <see cref="IMedia"/> to save</param>
/// <param name="userId">Id of the User saving the Media</param>
/// <param name="raiseEvents">Optional boolean indicating whether or not to raise events.</param>
public Attempt<OperationStatus> SaveWithStatus(IMedia media, int userId = 0, bool raiseEvents = true)
{
if (raiseEvents)
{
if (Saving.IsRaisedEventCancelled(
EventMessagesFactory.Get(),
messages => new SaveEventArgs<IMedia>(media, messages),
this))
{
return Attempt.Fail(OperationStatus.Cancelled);
}
}
var uow = UowProvider.GetUnitOfWork();
using (var repository = RepositoryFactory.CreateMediaRepository(uow))
{
media.CreatorId = userId;
repository.AddOrUpdate(media);
repository.AddOrUpdateContentXml(media, m => _entitySerializer.Serialize(this, _dataTypeService, _userService, m));
// generate preview for blame history?
if (UmbracoConfig.For.UmbracoSettings().Content.GlobalPreviewStorageEnabled)
{
repository.AddOrUpdatePreviewXml(media, m => _entitySerializer.Serialize(this, _dataTypeService, _userService, m));
}
uow.Commit();
}
if (raiseEvents)
Saved.RaiseEvent(EventMessagesFactory.Get(), messages => new SaveEventArgs<IMedia>(media, false, messages), this);
Audit(AuditType.Save, "Save Media performed by user", userId, media.Id);
return Attempt.Succeed(OperationStatus.Success);
}
/// <summary>
/// Saves a collection of <see cref="IMedia"/> objects
/// </summary>
/// <param name="medias">Collection of <see cref="IMedia"/> to save</param>
/// <param name="userId">Id of the User saving the Media</param>
/// <param name="raiseEvents">Optional boolean indicating whether or not to raise events.</param>
public Attempt<OperationStatus> SaveWithStatus(IEnumerable<IMedia> medias, int userId = 0, bool raiseEvents = true)
{
var asArray = medias.ToArray();
if (raiseEvents)
{
if (Saving.IsRaisedEventCancelled(
EventMessagesFactory.Get(),
messages => new SaveEventArgs<IMedia>(asArray, messages),
this))
{
return Attempt.Fail(OperationStatus.Cancelled);
}
}
var uow = UowProvider.GetUnitOfWork();
using (var repository = RepositoryFactory.CreateMediaRepository(uow))
{
foreach (var media in asArray)
{
media.CreatorId = userId;
repository.AddOrUpdate(media);
repository.AddOrUpdateContentXml(media, m => _entitySerializer.Serialize(this, _dataTypeService, _userService, m));
// generate preview for blame history?
if (UmbracoConfig.For.UmbracoSettings().Content.GlobalPreviewStorageEnabled)
{
repository.AddOrUpdatePreviewXml(media, m => _entitySerializer.Serialize(this, _dataTypeService, _userService, m));
}
}
//commit the whole lot in one go
uow.Commit();
}
if (raiseEvents)
Saved.RaiseEvent(EventMessagesFactory.Get(), messages => new SaveEventArgs<IMedia>(asArray, false, messages), this);
Audit(AuditType.Save, "Save Media items performed by user", userId, -1);
return Attempt.Succeed(OperationStatus.Success);
}
/// <summary>
/// Saves a single <see cref="IMedia"/> object
/// </summary>
@@ -1054,7 +1089,7 @@ namespace Umbraco.Core.Services
/// <param name="raiseEvents">Optional boolean indicating whether or not to raise events.</param>
public void Save(IMedia media, int userId = 0, bool raiseEvents = true)
{
SaveWithStatus(media, userId, raiseEvents);
((IMediaServiceOperations)this).Save (media, userId, raiseEvents);
}
/// <summary>
@@ -1065,7 +1100,7 @@ namespace Umbraco.Core.Services
/// <param name="raiseEvents">Optional boolean indicating whether or not to raise events.</param>
public void Save(IEnumerable<IMedia> medias, int userId = 0, bool raiseEvents = true)
{
SaveWithStatus(medias, userId, raiseEvents);
((IMediaServiceOperations)this).Save(medias, userId, raiseEvents);
}
/// <summary>
+38 -10
View File
@@ -1,26 +1,54 @@
using Umbraco.Core.Models;
namespace Umbraco.Core.Services
{
/// <summary>
/// The status returned by many of the service methods
/// </summary>
public class OperationStatus
public class OperationStatus<TEntity, TStatus> : OperationStatus<TStatus>
where TStatus : struct
{
//TODO: This is a pretty simple class atm, but is 'future' proofed in case we need to add more detail here
public OperationStatus(TEntity entity, TStatus statusType) : base(statusType)
{
Entity = entity;
}
public TEntity Entity { get; private set; }
}
public class OperationStatus<TStatus>
where TStatus : struct
{
public OperationStatus(TStatus statusType)
{
StatusType = statusType;
}
public TStatus StatusType { get; internal set; }
}
/// <summary>
/// The default operation status
/// </summary>
public class OperationStatus : OperationStatus<OperationStatusType>
{
public OperationStatus(OperationStatusType statusType) : base(statusType)
{
}
#region Static Helper methods
internal static OperationStatus Cancelled
{
get { return new OperationStatus(OperationStatusType.FailedCancelledByEvent);}
get { return new OperationStatus(OperationStatusType.FailedCancelledByEvent); }
}
internal static OperationStatus Success
{
get { return new OperationStatus(OperationStatusType.Success); }
}
public OperationStatus(OperationStatusType statusType)
{
StatusType = statusType;
}
public OperationStatusType StatusType { get; internal set; }
}
#endregion
}
}
@@ -17,5 +17,7 @@ namespace Umbraco.Core.Services
/// The saving has been cancelled by a 3rd party add-in
/// </summary>
FailedCancelledByEvent = 14
//TODO: In the future, we might need to add more operations statuses, potentially like 'FailedByPermissions', etc...
}
}
@@ -12,6 +12,25 @@ using Umbraco.Core.Events;
namespace Umbraco.Core.Services
{
/// <summary>
/// These are used currently to return the temporary 'operation' interfaces for services
/// which are used to return a status from operational methods so we can determine if things are
/// cancelled, etc...
///
/// These will be obsoleted in v8 since all real services methods will be changed to have the correct result.
/// </summary>
public static class ServiceWithResultExtensions
{
public static IContentServiceOperations WithResult(this IContentService contentService)
{
return (IContentServiceOperations)contentService;
}
public static IMediaServiceOperations WithResult(this IMediaService mediaService)
{
return (IMediaServiceOperations)mediaService;
}
}
/// <summary>
/// The Umbraco ServiceContext, which provides access to the following services:
/// <see cref="IContentService"/>, <see cref="IContentTypeService"/>, <see cref="IDataTypeService"/>,
@@ -1,89 +0,0 @@
using System;
using System.Diagnostics;
using Umbraco.Core.Cache;
using Umbraco.Core.Configuration;
using Umbraco.Core.Events;
using Umbraco.Core.Logging;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.Mappers;
using Umbraco.Core.Persistence.SqlSyntax;
using Umbraco.Core.Persistence.UnitOfWork;
using Umbraco.Core.Publishing;
using Umbraco.Core.Services;
namespace Umbraco.Core.Standalone
{
internal class ServiceContextManager : IDisposable
{
private readonly string _connectionString;
private readonly string _providerName;
private readonly ILogger _logger;
private readonly ISqlSyntaxProvider _syntaxProvider;
private ServiceContext _serviceContext;
private readonly StandaloneCoreApplication _application;
public ServiceContextManager(string connectionString, string providerName, string baseDirectory, ILogger logger, ISqlSyntaxProvider syntaxProvider)
{
_connectionString = connectionString;
_providerName = providerName;
_logger = logger;
_syntaxProvider = syntaxProvider;
Trace.WriteLine("ServiceContextManager-Current AppDomain: " + AppDomain.CurrentDomain.FriendlyName);
Trace.WriteLine("ServiceContextManager-Current AppDomain: " + AppDomain.CurrentDomain.BaseDirectory);
//var webAssembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(x => x.FullName.StartsWith("umbraco"));
//if (webAssembly != null && examineEventHandlerToRemove == null)
//{
// var examineEventType = webAssembly.GetType("Umbraco.Web.Search.ExamineEvents");
// examineEventHandlerToRemove = examineEventType;
//}
_application = StandaloneCoreApplication.GetApplication(baseDirectory);
var examineEventHandlerToRemove = Type.GetType("Umbraco.Web.Search.ExamineEvents, umbraco");
if (examineEventHandlerToRemove != null)
_application.WithoutApplicationEventHandler(examineEventHandlerToRemove);
_application.Start();
}
public ServiceContext Services
{
get
{
if (_serviceContext == null)
{
var cacheHelper = new CacheHelper(
new ObjectCacheRuntimeCacheProvider(),
new StaticCacheProvider(),
//we have no request based cache when running standalone
new NullCacheProvider());
var dbFactory = new DefaultDatabaseFactory(_connectionString, _providerName, _logger);
var dbContext = new DatabaseContext(dbFactory, _logger, _syntaxProvider, _providerName);
Database.Mapper = new PetaPocoMapper();
_serviceContext = new ServiceContext(
new RepositoryFactory(cacheHelper, _logger, dbContext.SqlSyntax, UmbracoConfig.For.UmbracoSettings()),
new PetaPocoUnitOfWorkProvider(dbFactory),
new FileUnitOfWorkProvider(),
new PublishingStrategy(),
cacheHelper,
new DebugDiagnosticsLogger(),
new TransientMessagesFactory());
//initialize the DatabaseContext
dbContext.Initialize(_providerName);
}
return _serviceContext;
}
}
public void Dispose()
{
((IDisposable)ApplicationContext.Current).Dispose();
_application.Dispose();
}
}
}
@@ -1,122 +0,0 @@
using System;
using System.Collections.Generic;
namespace Umbraco.Core.Standalone
{
internal class StandaloneCoreApplication : UmbracoApplicationBase
{
/// <summary>
/// Initializes a new instance of the <see cref="StandaloneCoreApplication"/> class.
/// </summary>
protected StandaloneCoreApplication(string baseDirectory)
{
_baseDirectory = baseDirectory;
}
/// <summary>
/// Provides the application boot manager.
/// </summary>
/// <returns>An application boot manager.</returns>
protected override IBootManager GetBootManager()
{
return new StandaloneCoreBootManager(this, _handlersToAdd, _handlersToRemove, _baseDirectory);
}
#region Application
private readonly string _baseDirectory;
private static StandaloneCoreApplication _application;
private static bool _started;
private static readonly object AppLock = new object();
/// <summary>
/// Gets the instance of the standalone Umbraco application.
/// </summary>
public static StandaloneCoreApplication GetApplication(string baseDirectory)
{
lock (AppLock)
{
return _application ?? (_application = new StandaloneCoreApplication(baseDirectory));
}
}
/// <summary>
/// Starts the application.
/// </summary>
public void Start()
{
lock (AppLock)
{
if (_started)
throw new InvalidOperationException("Application has already started.");
Application_Start(this, EventArgs.Empty);
_started = true;
}
}
#endregion
#region IApplicationEventHandler management
private readonly List<Type> _handlersToAdd = new List<Type>();
private readonly List<Type> _handlersToRemove = new List<Type>();
/// <summary>
/// Associates an <see cref="IApplicationEventHandler"/> type with the application.
/// </summary>
/// <typeparam name="T">The type to associate.</typeparam>
/// <returns>The application.</returns>
/// <remarks>Types implementing <see cref="IApplicationEventHandler"/> from within
/// an executable are not automatically discovered by Umbraco and have to be
/// explicitely associated with the application using this method.</remarks>
public StandaloneCoreApplication WithApplicationEventHandler<T>()
where T : IApplicationEventHandler
{
_handlersToAdd.Add(typeof(T));
return this;
}
/// <summary>
/// Dissociates an <see cref="IApplicationEventHandler"/> type from the application.
/// </summary>
/// <typeparam name="T">The type to dissociate.</typeparam>
/// <returns>The application.</returns>
public StandaloneCoreApplication WithoutApplicationEventHandler<T>()
where T : IApplicationEventHandler
{
_handlersToRemove.Add(typeof(T));
return this;
}
/// <summary>
/// Associates an <see cref="IApplicationEventHandler"/> type with the application.
/// </summary>
/// <param name="type">The type to associate.</param>
/// <returns>The application.</returns>
/// <remarks>Types implementing <see cref="IApplicationEventHandler"/> from within
/// an executable are not automatically discovered by Umbraco and have to be
/// explicitely associated with the application using this method.</remarks>
public StandaloneCoreApplication WithApplicationEventHandler(Type type)
{
if (type.Implements<IApplicationEventHandler>() == false)
throw new ArgumentException("Type does not implement IApplicationEventHandler.", "type");
_handlersToAdd.Add(type);
return this;
}
/// <summary>
/// Dissociates an <see cref="IApplicationEventHandler"/> type from the application.
/// </summary>
/// <param name="type">The type to dissociate.</param>
/// <returns>The application.</returns>
public StandaloneCoreApplication WithoutApplicationEventHandler(Type type)
{
if (type.Implements<IApplicationEventHandler>() == false)
throw new ArgumentException("Type does not implement IApplicationEventHandler.", "type");
_handlersToRemove.Add(type);
return this;
}
#endregion
}
}
@@ -1,59 +0,0 @@
using System;
using System.Collections.Generic;
using Umbraco.Core.ObjectResolution;
using Umbraco.Core.Persistence.Mappers;
using umbraco.interfaces;
namespace Umbraco.Core.Standalone
{
internal class StandaloneCoreBootManager : CoreBootManager
{
private readonly IEnumerable<Type> _handlersToAdd;
private readonly IEnumerable<Type> _handlersToRemove;
private readonly string _baseDirectory;
public StandaloneCoreBootManager(UmbracoApplicationBase umbracoApplication, IEnumerable<Type> handlersToAdd, IEnumerable<Type> handlersToRemove, string baseDirectory)
: base(umbracoApplication)
{
_handlersToAdd = handlersToAdd;
_handlersToRemove = handlersToRemove;
_baseDirectory = baseDirectory;
base.InitializeApplicationRootPath(_baseDirectory);
// this is only here to ensure references to the assemblies needed for
// the DataTypesResolver otherwise they won't be loaded into the AppDomain.
var interfacesAssemblyName = typeof(IDataType).Assembly.FullName;
}
protected override void InitializeApplicationEventsResolver()
{
base.InitializeApplicationEventsResolver();
foreach (var type in _handlersToAdd)
ApplicationEventsResolver.Current.AddType(type);
foreach (var type in _handlersToRemove)
ApplicationEventsResolver.Current.RemoveType(type);
}
protected override void InitializeResolvers()
{
base.InitializeResolvers();
//Mappers are not resolved, which could be because of a known TypeMapper issue
/*MappingResolver.Reset();
MappingResolver.Current = new MappingResolver(
() =>
new List<Type>
{
typeof (ContentMapper),
typeof (ContentTypeMapper),
typeof (MediaMapper),
typeof (MediaTypeMapper),
typeof (DataTypeDefinitionMapper),
typeof (UmbracoEntityMapper)
});*/
}
}
}
@@ -100,7 +100,7 @@ namespace Umbraco.Core.Sync
/// Thread safety: this is NOT thread safe. Because it is NOT meant to run multi-threaded.
/// Callers MUST ensure thread-safety.
/// </remarks>
internal protected void Boot()
protected void Boot()
{
// weight:10, must release *before* the facade service, because once released
// the service will *not* be able to properly handle our notifications anymore
+2 -3
View File
@@ -445,6 +445,8 @@
<Compile Include="Persistence\Repositories\TaskRepository.cs" />
<Compile Include="Persistence\Repositories\TaskTypeRepository.cs" />
<Compile Include="PropertyEditors\ValueConverters\GridValueConverter.cs" />
<Compile Include="Publishing\UnPublishedStatusType.cs" />
<Compile Include="Publishing\UnPublishStatus.cs" />
<Compile Include="Security\BackOfficeClaimsIdentityFactory.cs" />
<Compile Include="Security\BackOfficeSignInManager.cs" />
<Compile Include="Security\BackOfficeUserManager.cs" />
@@ -1246,9 +1248,6 @@
<Compile Include="Services\UserService.cs" />
<Compile Include="Services\UserServiceExtensions.cs" />
<Compile Include="IO\ViewHelper.cs" />
<Compile Include="Standalone\ServiceContextManager.cs" />
<Compile Include="Standalone\StandaloneCoreApplication.cs" />
<Compile Include="Standalone\StandaloneCoreBootManager.cs" />
<Compile Include="Strategies\RelateOnCopyHandler.cs" />
<Compile Include="Strategies\RelateOnTrashHandler.cs" />
<Compile Include="Strings\ContentBaseExtensions.cs" />
+2 -2
View File
@@ -100,7 +100,7 @@
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.0.1" newVersion="4.0.0.1" />
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
</dependentAssembly>
@@ -108,7 +108,7 @@
<assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
@@ -1,6 +1,5 @@
using System.Collections.Generic;
using System.Web.Mvc;
using Microsoft.Web.Mvc;
using NUnit.Framework;
using Umbraco.Core.Profiling;
using Umbraco.Web;
@@ -16,46 +15,38 @@ namespace Umbraco.Tests.BootManagers
{
IList<IViewEngine> engines = new List<IViewEngine>
{
new FixedWebFormViewEngine(),
new FixedRazorViewEngine(),
new RenderViewEngine(),
new PluginViewEngine()
};
WebBootManager.WrapViewEngines(engines);
Assert.That(engines.Count, Is.EqualTo(4));
Assert.That(engines.Count, Is.EqualTo(2));
Assert.That(engines[0], Is.InstanceOf<ProfilingViewEngine>());
Assert.That(engines[1], Is.InstanceOf<ProfilingViewEngine>());
Assert.That(engines[2], Is.InstanceOf<ProfilingViewEngine>());
Assert.That(engines[3], Is.InstanceOf<ProfilingViewEngine>());
}
[Test]
public void WrapViewEngines_HasEngines_KeepsSortOrder()
{
IList<IViewEngine> engines = new List<IViewEngine>
IList<IViewEngine> engines = new List<IViewEngine>
{
new FixedWebFormViewEngine(),
new FixedRazorViewEngine(),
new RenderViewEngine(),
new PluginViewEngine()
};
WebBootManager.WrapViewEngines(engines);
Assert.That(engines.Count, Is.EqualTo(4));
Assert.That(((ProfilingViewEngine)engines[0]).Inner, Is.InstanceOf<FixedWebFormViewEngine>());
Assert.That(((ProfilingViewEngine)engines[1]).Inner, Is.InstanceOf<FixedRazorViewEngine>());
Assert.That(((ProfilingViewEngine)engines[2]).Inner, Is.InstanceOf<RenderViewEngine>());
Assert.That(((ProfilingViewEngine)engines[3]).Inner, Is.InstanceOf<PluginViewEngine>());
Assert.That(engines.Count, Is.EqualTo(2));
Assert.That(((ProfilingViewEngine)engines[0]).Inner, Is.InstanceOf<RenderViewEngine>());
Assert.That(((ProfilingViewEngine)engines[1]).Inner, Is.InstanceOf<PluginViewEngine>());
}
[Test]
public void WrapViewEngines_HasProfiledEngine_AddsSameInstance()
{
var profiledEngine = new ProfilingViewEngine(new FixedRazorViewEngine());
var profiledEngine = new ProfilingViewEngine(new PluginViewEngine());
IList<IViewEngine> engines = new List<IViewEngine>
{
profiledEngine
@@ -56,11 +56,12 @@ namespace Umbraco.Tests.Persistence
var repositoryFactory = new RepositoryFactory(cacheHelper, _logger, SqlSyntaxProvider, SettingsForTests.GenerateMockSettings());
var evtMsgs = new TransientMessagesFactory();
ApplicationContext.Current = new ApplicationContext(
//assign the db context
dbContext,
//assign the service context
new ServiceContext(repositoryFactory, new PetaPocoUnitOfWorkProvider(_logger), new FileUnitOfWorkProvider(), new PublishingStrategy(), cacheHelper, _logger, new TransientMessagesFactory()),
new ServiceContext(repositoryFactory, new PetaPocoUnitOfWorkProvider(_logger), new FileUnitOfWorkProvider(), new PublishingStrategy(evtMsgs, _logger), cacheHelper, _logger, evtMsgs),
cacheHelper,
new ProfilingLogger(_logger, Mock.Of<IProfiler>()))
{
@@ -1,6 +1,7 @@
using System;
using System.Linq;
using NUnit.Framework;
using Umbraco.Core;
using Umbraco.Core.Models;
using Umbraco.Core.Persistence.Repositories;
using Umbraco.Core.Persistence.UnitOfWork;
@@ -63,7 +64,7 @@ namespace Umbraco.Tests.Persistence.Repositories
Assert.AreEqual(0, found.First().AssigneeUserId);
Assert.AreEqual(false, found.First().Closed);
Assert.AreEqual("hello world", found.First().Comment);
Assert.GreaterOrEqual(found.First().CreateDate, created);
Assert.GreaterOrEqual(found.First().CreateDate.TruncateTo(DateTimeExtensions.DateTruncate.Second), created.TruncateTo(DateTimeExtensions.DateTruncate.Second));
Assert.AreEqual(-1, found.First().EntityId);
Assert.AreEqual(0, found.First().OwnerUserId);
Assert.AreEqual(true, found.First().HasIdentity);
@@ -64,7 +64,7 @@ namespace Umbraco.Tests.Publishing
ServiceContext.ContentTypeService.GetContentType("umbTextpage"), "Sub Sub Sub", mandatorContent.Id);
ServiceContext.ContentService.Save(subContent, 0);
var strategy = new PublishingStrategy();
var strategy = new PublishingStrategy(new TransientMessagesFactory(), Logger);
//publish root and nodes at it's children level
var listToPublish = ServiceContext.ContentService.GetDescendants(_homePage.Id).Concat(new[] { _homePage });
@@ -91,8 +91,8 @@ namespace Umbraco.Tests.Publishing
{
CreateTestData();
var strategy = new PublishingStrategy();
var strategy = new PublishingStrategy(new TransientMessagesFactory(), Logger);
PublishingStrategy.Publishing +=PublishingStrategyPublishing;
@@ -118,8 +118,8 @@ namespace Umbraco.Tests.Publishing
{
CreateTestData();
var strategy = new PublishingStrategy();
var strategy = new PublishingStrategy(new TransientMessagesFactory(), Logger);
//publish root and nodes at it's children level
var result1 = strategy.Publish(_homePage, 0);
Assert.IsTrue(result1);
@@ -145,7 +145,7 @@ namespace Umbraco.Tests.Publishing
{
CreateTestData();
var strategy = new PublishingStrategy();
var strategy = new PublishingStrategy(new TransientMessagesFactory(), Logger);
//publish root and nodes at it's children level
var result1 = strategy.Publish(_homePage, 0);
@@ -50,14 +50,15 @@ namespace Umbraco.Tests.Services
//we need a new Database object for each thread.
var repositoryFactory = new RepositoryFactory(cacheHelper, Logger, SqlSyntax, SettingsForTests.GenerateMockSettings());
_uowProvider = new PerThreadPetaPocoUnitOfWorkProvider(_dbFactory);
ApplicationContext.Services = new ServiceContext(
var evtMsgs = new TransientMessagesFactory();
ApplicationContext.Services = new ServiceContext(
repositoryFactory,
_uowProvider,
new FileUnitOfWorkProvider(),
new PublishingStrategy(),
new PublishingStrategy(evtMsgs, Logger),
cacheHelper,
Logger,
new TransientMessagesFactory());
evtMsgs);
CreateTestData();
}
@@ -76,11 +76,12 @@ namespace Umbraco.Tests.TestHelpers
var repositoryFactory = new RepositoryFactory(cacheHelper, Logger, SqlSyntax, SettingsForTests.GenerateMockSettings());
var evtMsgs = new TransientMessagesFactory();
_appContext = new ApplicationContext(
//assign the db context
new DatabaseContext(dbFactory, Logger, SqlSyntax, "System.Data.SqlServerCe.4.0"),
//assign the service context
new ServiceContext(repositoryFactory, new PetaPocoUnitOfWorkProvider(dbFactory), new FileUnitOfWorkProvider(), new PublishingStrategy(), cacheHelper, Logger, new TransientMessagesFactory()),
new ServiceContext(repositoryFactory, new PetaPocoUnitOfWorkProvider(dbFactory), new FileUnitOfWorkProvider(), new PublishingStrategy(evtMsgs, Logger), cacheHelper, Logger, evtMsgs),
cacheHelper,
ProfilingLogger)
{
@@ -153,12 +153,13 @@ namespace Umbraco.Tests.TestHelpers
var sqlSyntax = new SqlCeSyntaxProvider();
var repoFactory = new RepositoryFactory(CacheHelper.CreateDisabledCacheHelper(), Logger, sqlSyntax, SettingsForTests.GenerateMockSettings());
var evtMsgs = new TransientMessagesFactory();
ApplicationContext.Current = new ApplicationContext(
//assign the db context
new DatabaseContext(new DefaultDatabaseFactory(Core.Configuration.GlobalSettings.UmbracoConnectionName, Logger),
Logger, sqlSyntax, "System.Data.SqlServerCe.4.0"),
//assign the service context
new ServiceContext(repoFactory, new PetaPocoUnitOfWorkProvider(Logger), new FileUnitOfWorkProvider(), new PublishingStrategy(), CacheHelper, Logger, new TransientMessagesFactory()),
new ServiceContext(repoFactory, new PetaPocoUnitOfWorkProvider(Logger), new FileUnitOfWorkProvider(), new PublishingStrategy(evtMsgs, Logger), CacheHelper, Logger, evtMsgs),
CacheHelper,
ProfilingLogger)
{
+12 -14
View File
@@ -79,9 +79,6 @@
<Private>True</Private>
<HintPath>..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Web.Mvc.FixedDisplayModes">
<HintPath>..\packages\Microsoft.AspNet.Mvc.FixedDisplayModes.1.0.1\lib\net40\Microsoft.Web.Mvc.FixedDisplayModes.dll</HintPath>
</Reference>
<Reference Include="MiniProfiler, Version=2.1.0.0, Culture=neutral, PublicKeyToken=b44f9351044011a3, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\MiniProfiler.2.1.0\lib\net40\MiniProfiler.dll</HintPath>
@@ -124,9 +121,9 @@
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.Web" />
<Reference Include="System.Web.ApplicationServices" />
<Reference Include="System.Web.Helpers, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<Reference Include="System.Web.Helpers, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.Helpers.dll</HintPath>
<Private>True</Private>
<HintPath>..\packages\Microsoft.AspNet.WebPages.2.0.30506.0\lib\net40\System.Web.Helpers.dll</HintPath>
</Reference>
<Reference Include="System.Web.Http, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
@@ -139,25 +136,26 @@
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Microsoft.AspNet.WebApi.WebHost.5.2.3\lib\net45\System.Web.Http.WebHost.dll</HintPath>
</Reference>
<Reference Include="System.Web.Mvc, Version=4.0.0.1, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<Reference Include="System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.Mvc.5.2.3\lib\net45\System.Web.Mvc.dll</HintPath>
<Private>True</Private>
<HintPath>..\packages\Microsoft.AspNet.Mvc.4.0.40804.0\lib\net40\System.Web.Mvc.dll</HintPath>
</Reference>
<Reference Include="System.Web.Razor, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<Reference Include="System.Web.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.Razor.3.2.3\lib\net45\System.Web.Razor.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Web.Services" />
<Reference Include="System.Web.WebPages, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<Reference Include="System.Web.WebPages, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.dll</HintPath>
<Private>True</Private>
<HintPath>..\packages\Microsoft.AspNet.WebPages.2.0.30506.0\lib\net40\System.Web.WebPages.dll</HintPath>
</Reference>
<Reference Include="System.Web.WebPages.Deployment, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<Reference Include="System.Web.WebPages.Deployment, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.Deployment.dll</HintPath>
<Private>True</Private>
<HintPath>..\packages\Microsoft.AspNet.WebPages.2.0.30506.0\lib\net40\System.Web.WebPages.Deployment.dll</HintPath>
</Reference>
<Reference Include="System.Web.WebPages.Razor, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<Reference Include="System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.Razor.dll</HintPath>
<Private>True</Private>
<HintPath>..\packages\Microsoft.AspNet.WebPages.2.0.30506.0\lib\net40\System.Web.WebPages.Razor.dll</HintPath>
</Reference>
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
+3 -4
View File
@@ -5,15 +5,14 @@
<package id="Examine" version="0.1.66.0" targetFramework="net45" />
<package id="log4net-mediumtrust" version="2.0.0" targetFramework="net45" />
<package id="Lucene.Net" version="2.9.4.1" targetFramework="net45" />
<package id="Microsoft.AspNet.Mvc" version="4.0.40804.0" targetFramework="net45" />
<package id="Microsoft.AspNet.Mvc.FixedDisplayModes" version="1.0.1" />
<package id="Microsoft.AspNet.Razor" version="2.0.30506.0" targetFramework="net45" />
<package id="Microsoft.AspNet.Mvc" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.Razor" version="3.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Core" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.SelfHost" version="4.0.30506.0" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.WebHost" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebPages" version="2.0.30506.0" targetFramework="net45" />
<package id="Microsoft.AspNet.WebPages" version="3.2.3" targetFramework="net45" />
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net45" />
<package id="MiniProfiler" version="2.1.0" targetFramework="net45" />
<package id="Moq" version="4.1.1309.0919" targetFramework="net45" />
@@ -64,6 +64,13 @@ function umbImageFolder($rootScope, assetsService, $timeout, $log, umbRequestHel
found.completed = true;
}
//Show notifications!!!!
if (data.result && data.result.notifications && angular.isArray(data.result.notifications)) {
for (var n = 0; n < data.result.notifications.length; n++) {
notificationsService.showNotification(data.result.notifications[n]);
}
}
//when none are left resync everything
var remaining = _.filter(scope.files, function (file) { return file.completed !== true; });
if (remaining.length === 0) {
@@ -37,8 +37,7 @@ angular.module("umbraco.directives")
template: '<li ng-class="{\'current\': (node == currentNode)}" on-right-click="altSelect(node, $event)">' +
'<div ng-class="getNodeCssClass(node)" ng-swipe-right="options(node, $event)" >' +
//NOTE: This ins element is used to display the search icon if the node is a container/listview and the tree is currently in dialog
//'<ins ng-if="tree.enablelistviewsearch && node.metaData.isContainer" class="umb-tree-node-search icon-search" ng-click="searchNode(node, $event)" alt="searchAltText"></ins>' +
'<ins style="width:18px;"></ins>' +
//'<ins ng-if="tree.enablelistviewsearch && node.metaData.isContainer" class="umb-tree-node-search icon-search" ng-click="searchNode(node, $event)" alt="searchAltText"></ins>' +
'<ins ng-class="{\'icon-navigation-right\': !node.expanded, \'icon-navigation-down\': node.expanded}" ng-click="load(node)"></ins>' +
'<i class="icon umb-tree-icon sprTree"></i>' +
'<a ng-click="select(node, $event)"></a>' +
+9 -12
View File
@@ -3,14 +3,13 @@
.umb-item-list {
margin: 0px;
margin: 0;
width: auto;
display: block
}
.umb-item-list li {
display: block;
width: auto;
display: block
}
@@ -20,7 +19,7 @@
// -------------------------
.umb-tree {
margin: 0px;
margin: 0;
min-width: 100%;
width: auto;
}
@@ -29,17 +28,17 @@
display: block;
min-width: 100%;
width: auto;
display: block
}
.umb-tree li.current > div, .umb-tree div.selected {
background: @blue;
}
.umb-tree li.current > div a.umb-options i, .umb-tree div.selected i{
.umb-tree li.current > div a.umb-options i, .umb-tree div.selected i {
background: #fff;
border-color: @blue;
}
.umb-tree li.current > div a,
.umb-tree li.current > div i.icon{
.umb-tree li.current > div i.icon,
.umb-tree li.current > div ins {
color: white !important;
background: @blue;
border-color: @blue;
@@ -57,8 +56,8 @@
white-space: nowrap
}
.umb-tree ul {
padding: 0px;
margin: 0px;
padding: 0;
margin: 0;
min-width: 100%;
width: 100%;
//display: table
@@ -111,16 +110,14 @@
display: inline-block;
visibility: hidden;
text-decoration: none;
font-size: 12px;
}
.umb-tree li:hover ins {
visibility: visible;
cursor: pointer
}
.umb-tree ins {
font-size: 12px;
}
.umb-tree .icon {
vertical-align: middle;
margin: 1px 13px 1px 0px;
@@ -1,7 +1,7 @@
//used for the media picker dialog
angular.module("umbraco")
.controller("Umbraco.Dialogs.MediaPickerController",
function ($scope, mediaResource, umbRequestHelper, entityResource, $log, mediaHelper, eventsService, treeService, $cookies, $element, $timeout) {
function ($scope, mediaResource, umbRequestHelper, entityResource, $log, mediaHelper, eventsService, treeService, $cookies, $element, $timeout, notificationsService) {
var dialogOptions = $scope.dialogOptions;
@@ -98,6 +98,12 @@ angular.module("umbraco")
$scope.gotoFolder($scope.currentFolder);
});
}
//Show notifications!!!!
if (data.result && data.result.notifications && angular.isArray(data.result.notifications)) {
for (var n = 0; n < data.result.notifications.length; n++) {
notificationsService.showNotification(data.result.notifications[n]);
}
}
});
// All these sit-ups are to add dropzone area and make sure it gets removed if dragging is aborted!
@@ -6,7 +6,7 @@
* @description
* The controller for deleting content
*/
function ContentDeleteController($scope, contentResource, treeService, navigationService, editorState, $location) {
function ContentDeleteController($scope, contentResource, treeService, navigationService, editorState, $location, dialogService, notificationsService) {
$scope.performDelete = function() {
@@ -41,6 +41,20 @@ function ContentDeleteController($scope, contentResource, treeService, navigatio
}
navigationService.hideMenu();
}, function(err) {
$scope.currentNode.loading = false;
//check if response is ysod
if (err.status && err.status >= 500) {
dialogService.ysodDialog(err);
}
if (err.data && angular.isArray(err.data.notifications)) {
for (var i = 0; i < err.data.notifications.length; i++) {
notificationsService.showNotification(err.data.notifications[i]);
}
}
});
};
@@ -8,7 +8,7 @@
*
*/
function ContentRecycleBinController($scope, $routeParams, dataTypeResource) {
function ContentRecycleBinController($scope, $routeParams, dataTypeResource, navigationService) {
//ensures the list view doesn't actually load until we query for the list view config
// for the section
@@ -24,6 +24,8 @@ function ContentRecycleBinController($scope, $routeParams, dataTypeResource) {
$scope.model = { config: { entityType: $routeParams.section } };
// sync tree node
navigationService.syncTree({ tree: "content", path: ["-1", $routeParams.id], forceReload: false });
}
angular.module('umbraco').controller("Umbraco.Editors.Content.RecycleBinController", ContentRecycleBinController);
@@ -29,9 +29,11 @@
<button class="btn btn-warning" ng-click="rebuildIndex(indexer)">Rebuild index</button>
<button class="btn btn-warning" ng-click="optimizeIndex(indexer)" ng-show="indexer.documentCount > 0">Optimize index</button>
</div>
<div ng-show="indexer.isProcessing" class="progress progress-striped active">
<div class="bar" style="width: 100%;"></div>
<div ng-show="indexer.isProcessing" class="umb-loader-wrapper" ng-show="actionInProgress">
<div class="umb-loader"></div>
</div>
<div class="error" ng-show="indexer.processingAttempts >= 100">
The process is taking longer than expected, check the umbraco log to see if there have been any errors during this operation
</div>
@@ -183,10 +185,11 @@
</form>
<div class="search-results" ng-show="searcher.isSearching">
<div ng-show="indexer.isProcessing" class="progress progress-striped active">
<div class="bar" style="width: 100%;"></div>
<div ng-show="indexer.isProcessing" class="umb-loader-wrapper" ng-show="indexer.isProcessing">
<div class="umb-loader"></div>
</div>
<table ng-hide="searcher.isProcessing" class="table table-bordered table-condensed">
<thead>
<tr>
@@ -6,7 +6,7 @@
* @description
* The controller for deleting content
*/
function MediaDeleteController($scope, mediaResource, treeService, navigationService, editorState, $location) {
function MediaDeleteController($scope, mediaResource, treeService, navigationService, editorState, $location, dialogService, notificationsService) {
$scope.performDelete = function() {
@@ -42,8 +42,20 @@ function MediaDeleteController($scope, mediaResource, treeService, navigationSer
navigationService.hideMenu();
},function() {
}, function (err) {
$scope.currentNode.loading = false;
//check if response is ysod
if (err.status && err.status >= 500) {
dialogService.ysodDialog(err);
}
if (err.data && angular.isArray(err.data.notifications)) {
for (var i = 0; i < err.data.notifications.length; i++) {
notificationsService.showNotification(err.data.notifications[i]);
}
}
});
};
@@ -8,7 +8,7 @@
*
*/
function MediaRecycleBinController($scope, $routeParams, dataTypeResource) {
function MediaRecycleBinController($scope, $routeParams, dataTypeResource, navigationService) {
//ensures the list view doesn't actually load until we query for the list view config
// for the section
@@ -24,6 +24,8 @@ function MediaRecycleBinController($scope, $routeParams, dataTypeResource) {
$scope.model = { config: { entityType: $routeParams.section } };
// sync tree node
navigationService.syncTree({ tree: "media", path: ["-1", $routeParams.id], forceReload: false });
}
angular.module('umbraco').controller("Umbraco.Editors.Media.RecycleBinController", MediaRecycleBinController);
@@ -91,6 +91,27 @@ function listViewController($rootScope, $scope, $routeParams, $injector, notific
}
});
function showNotificationsAndReset(err, reload) {
//check if response is ysod
if(err.status && err.status >= 500) {
dialogService.ysodDialog(err);
}
$scope.bulkStatus = "";
$scope.actionInProgress = false;
if (reload === true) {
$scope.reloadView($scope.contentId);
}
if (err.data && angular.isArray(err.data.notifications)) {
for (var i = 0; i < err.data.notifications.length; i++) {
notificationsService.showNotification(err.data.notifications[i]);
}
}
}
$scope.isSortDirection = function (col, direction) {
return $scope.options.orderBy.toUpperCase() == col.toUpperCase() && $scope.options.orderDirection == direction;
}
@@ -140,8 +161,12 @@ function listViewController($rootScope, $scope, $routeParams, $injector, notific
/*Pagination is done by an array of objects, due angularJS's funky way of monitoring state
with simple values */
$scope.reloadView = function(id) {
$scope.reloadView = function (id) {
getListResultsCallback(id, $scope.options).then(function (data) {
$scope.actionInProgress = false;
$scope.listViewResultSet = data;
//update all values for display
@@ -203,11 +228,17 @@ function listViewController($rootScope, $scope, $routeParams, $injector, notific
});
};
//assign debounce method to the search to limit the queries
$scope.search = _.debounce(function() {
$scope.options.pageNumber = 1;
$scope.reloadView($scope.contentId);
}, 100);
$scope.$watch(function() {
return $scope.options.filter;
}, _.debounce(function(newVal, oldVal) {
$scope.$apply(function() {
if (newVal !== null && newVal !== undefined && newVal !== oldVal) {
$scope.options.pageNumber = 1;
$scope.actionInProgress = true;
$scope.reloadView($scope.contentId);
}
});
}, 200));
$scope.enterSearch = function($event) {
$($event.target).next().focus();
@@ -266,12 +297,13 @@ function listViewController($rootScope, $scope, $routeParams, $injector, notific
$scope.bulkStatus = "Deleted item " + current + " out of " + total + " item" + pluralSuffix;
deleteItemCallback(getIdCallback(selected[i])).then(function (data) {
if (current === total) {
//TODO: Should probably add notifications on the server side
notificationsService.success("Bulk action", "Deleted " + total + " item" + pluralSuffix);
$scope.bulkStatus = "";
$scope.reloadView($scope.contentId);
$scope.actionInProgress = false;
showNotificationsAndReset(data, true);
}
current++;
}, function (err) {
showNotificationsAndReset(err, false);
});
}
}
@@ -300,26 +332,12 @@ function listViewController($rootScope, $scope, $routeParams, $injector, notific
.then(function(content) {
if (current == total) {
notificationsService.success("Bulk action", "Published " + total + " document" + pluralSuffix);
$scope.bulkStatus = "";
$scope.reloadView($scope.contentId);
$scope.actionInProgress = false;
showNotificationsAndReset(content, true);
}
current++;
}, function(err) {
$scope.bulkStatus = "";
$scope.reloadView($scope.contentId);
$scope.actionInProgress = false;
//if there are validation errors for publishing then we need to show them
if (err.status === 400 && err.data && err.data.Message) {
notificationsService.error("Publish error", err.data.Message);
}
else {
dialogService.ysodDialog(err);
}
showNotificationsAndReset(err, false);
});
}
};
@@ -346,12 +364,12 @@ function listViewController($rootScope, $scope, $routeParams, $injector, notific
if (current == total) {
notificationsService.success("Bulk action", "Unpublished " + total + " document" + pluralSuffix);
$scope.bulkStatus = "";
$scope.reloadView($scope.contentId);
$scope.actionInProgress = false;
showNotificationsAndReset(content, true);
}
current++;
}, function(err) {
showNotificationsAndReset(err, false);
});
}
};
@@ -39,11 +39,15 @@
</a>
</div>
<span ng-bind="bulkStatus" ng-show="isAnythingSelected()"></span>
<div class="umb-loader-wrapper" ng-show="actionInProgress">
<div class="umb-loader"></div>
</div>
<form class="form-search pull-right" novalidate>
<div class="inner-addon left-addon">
<i class="icon icon-search" ng-click="enterSearch($event)"></i>
<input type="text" class="form-control" localize="placeholder" placeholder="@general_typeToSearch" ng-model="options.filter" on-keyup="search()" prevent-enter-submit no-dirty-check>
<input type="text" class="form-control" localize="placeholder" placeholder="@general_typeToSearch" ng-model="options.filter" prevent-enter-submit no-dirty-check>
</div>
</form>
</div>
+14 -18
View File
@@ -120,8 +120,8 @@
<Private>True</Private>
</Reference>
<Reference Include="ClientDependency.Core.Mvc, Version=1.8.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\ClientDependency-Mvc.1.8.0.0\lib\net45\ClientDependency.Core.Mvc.dll</HintPath>
<HintPath>..\packages\ClientDependency-Mvc5.1.8.0.0\lib\net45\ClientDependency.Core.Mvc.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="dotless.Core, Version=1.4.1.0, Culture=neutral, PublicKeyToken=96b446c9e63eae34, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
@@ -184,10 +184,6 @@
<Private>True</Private>
<HintPath>..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Web.Mvc.FixedDisplayModes, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Microsoft.AspNet.Mvc.FixedDisplayModes.1.0.1\lib\net40\Microsoft.Web.Mvc.FixedDisplayModes.dll</HintPath>
</Reference>
<Reference Include="MiniProfiler, Version=2.1.0.0, Culture=neutral, PublicKeyToken=b44f9351044011a3, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\MiniProfiler.2.1.0\lib\net40\MiniProfiler.dll</HintPath>
@@ -252,9 +248,9 @@
<Reference Include="System.Web.Entity" />
<Reference Include="System.Web.Extensions" />
<Reference Include="System.Web.Extensions.Design" />
<Reference Include="System.Web.Helpers, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<Reference Include="System.Web.Helpers, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.Helpers.dll</HintPath>
<Private>True</Private>
<HintPath>..\packages\Microsoft.AspNet.WebPages.2.0.30506.0\lib\net40\System.Web.Helpers.dll</HintPath>
</Reference>
<Reference Include="System.Web.Http, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
@@ -264,28 +260,28 @@
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Microsoft.AspNet.WebApi.WebHost.5.2.3\lib\net45\System.Web.Http.WebHost.dll</HintPath>
</Reference>
<Reference Include="System.Web.Mvc, Version=4.0.0.1, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<Reference Include="System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.Mvc.5.2.3\lib\net45\System.Web.Mvc.dll</HintPath>
<Private>True</Private>
<HintPath>..\packages\Microsoft.AspNet.Mvc.4.0.40804.0\lib\net40\System.Web.Mvc.dll</HintPath>
</Reference>
<Reference Include="System.Web.Razor, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<Reference Include="System.Web.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.Razor.3.2.3\lib\net45\System.Web.Razor.dll</HintPath>
<Private>True</Private>
<HintPath>..\packages\Microsoft.AspNet.Razor.2.0.30506.0\lib\net40\System.Web.Razor.dll</HintPath>
</Reference>
<Reference Include="System.Web.Services">
<Name>System.Web.Services</Name>
</Reference>
<Reference Include="System.Web.WebPages, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<Reference Include="System.Web.WebPages, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.dll</HintPath>
<Private>True</Private>
<HintPath>..\packages\Microsoft.AspNet.WebPages.2.0.30506.0\lib\net40\System.Web.WebPages.dll</HintPath>
</Reference>
<Reference Include="System.Web.WebPages.Deployment, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<Reference Include="System.Web.WebPages.Deployment, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.Deployment.dll</HintPath>
<Private>True</Private>
<HintPath>..\packages\Microsoft.AspNet.WebPages.2.0.30506.0\lib\net40\System.Web.WebPages.Deployment.dll</HintPath>
</Reference>
<Reference Include="System.Web.WebPages.Razor, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<Reference Include="System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.Razor.dll</HintPath>
<Private>True</Private>
<HintPath>..\packages\Microsoft.AspNet.WebPages.2.0.30506.0\lib\net40\System.Web.WebPages.Razor.dll</HintPath>
</Reference>
<Reference Include="System.Xml">
<Name>System.XML</Name>
+8 -8
View File
@@ -2,14 +2,14 @@
<configuration>
<configSections>
<sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
<section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
<section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
<sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
<section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
<section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
</sectionGroup>
</configSections>
<system.web.webPages.razor>
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<pages pageBaseType="System.Web.Mvc.WebViewPage">
<namespaces>
<add namespace="System.Web.Mvc" />
@@ -44,11 +44,11 @@
-->
<pages
validateRequest="false"
pageParserFilterType="System.Web.Mvc.ViewTypeParserFilter, System.Web.Mvc, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
pageBaseType="System.Web.Mvc.ViewPage, System.Web.Mvc, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
userControlBaseType="System.Web.Mvc.ViewUserControl, System.Web.Mvc, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
pageParserFilterType="System.Web.Mvc.ViewTypeParserFilter, System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
pageBaseType="System.Web.Mvc.ViewPage, System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
userControlBaseType="System.Web.Mvc.ViewUserControl, System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
<controls>
<add assembly="System.Web.Mvc, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" namespace="System.Web.Mvc" tagPrefix="mvc" />
<add assembly="System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" namespace="System.Web.Mvc" tagPrefix="mvc" />
</controls>
</pages>
</system.web>
+4 -5
View File
@@ -2,7 +2,7 @@
<packages>
<package id="AutoMapper" version="3.3.1" targetFramework="net45" />
<package id="ClientDependency" version="1.8.4" targetFramework="net45" />
<package id="ClientDependency-Mvc" version="1.8.0.0" targetFramework="net45" />
<package id="ClientDependency-Mvc5" version="1.8.0.0" targetFramework="net45" />
<package id="dotless" version="1.4.1.0" targetFramework="net45" />
<package id="Examine" version="0.1.66.0" targetFramework="net45" />
<package id="ImageProcessor" version="1.9.5.0" targetFramework="net45" />
@@ -11,14 +11,13 @@
<package id="Lucene.Net" version="2.9.4.1" targetFramework="net45" />
<package id="Microsoft.AspNet.Identity.Core" version="2.2.1" targetFramework="net45" />
<package id="Microsoft.AspNet.Identity.Owin" version="2.2.1" targetFramework="net45" />
<package id="Microsoft.AspNet.Mvc" version="4.0.40804.0" targetFramework="net45" />
<package id="Microsoft.AspNet.Mvc.FixedDisplayModes" version="1.0.1" />
<package id="Microsoft.AspNet.Razor" version="2.0.30506.0" targetFramework="net45" />
<package id="Microsoft.AspNet.Mvc" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.Razor" version="3.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Core" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.WebHost" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebPages" version="2.0.30506.0" targetFramework="net45" />
<package id="Microsoft.AspNet.WebPages" version="3.2.3" targetFramework="net45" />
<package id="Microsoft.Bcl" version="1.1.9" targetFramework="net45" />
<package id="Microsoft.Bcl.Build" version="1.0.14" targetFramework="net45" />
<package id="Microsoft.Owin" version="3.0.1" targetFramework="net45" />
@@ -2,14 +2,14 @@
<configuration>
<configSections>
<sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
<section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
<section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
<sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
<section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
<section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
</sectionGroup>
</configSections>
<system.web.webPages.razor>
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<pages pageBaseType="System.Web.Mvc.WebViewPage">
<namespaces>
<add namespace="System.Web.Mvc" />
@@ -38,11 +38,11 @@
-->
<pages
validateRequest="false"
pageParserFilterType="System.Web.Mvc.ViewTypeParserFilter, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
pageBaseType="System.Web.Mvc.ViewPage, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
userControlBaseType="System.Web.Mvc.ViewUserControl, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
pageParserFilterType="System.Web.Mvc.ViewTypeParserFilter, System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
pageBaseType="System.Web.Mvc.ViewPage, System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
userControlBaseType="System.Web.Mvc.ViewUserControl, System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
<controls>
<add assembly="System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" namespace="System.Web.Mvc" tagPrefix="mvc" />
<add assembly="System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" namespace="System.Web.Mvc" tagPrefix="mvc" />
</controls>
</pages>
</system.web>
@@ -774,6 +774,8 @@ To manage your website, simply open the Umbraco back office and start adding con
<key alias="sortPleaseWait"><![CDATA[ Please wait. Items are being sorted, this can take a while.<br/> <br/> Do not close this window during sorting]]></key>
</area>
<area alias="speechBubbles">
<key alias="operationFailedHeader">Failed</key>
<key alias="invalidUserPermissionsText">Insufficient user permissions, could not complete the operation</key>
<key alias="operationCancelledHeader">Cancelled</key>
<key alias="operationCancelledText">Operation was cancelled by a 3rd party add-in</key>
<key alias="contentPublishedFailedByEvent">Publishing was cancelled by a 3rd party add-in</key>
@@ -775,6 +775,8 @@ To manage your website, simply open the Umbraco back office and start adding con
<key alias="sortPleaseWait"><![CDATA[ Please wait. Items are being sorted, this can take a while.<br/> <br/> Do not close this window during sorting]]></key>
</area>
<area alias="speechBubbles">
<key alias="operationFailedHeader">Failed</key>
<key alias="invalidUserPermissionsText">Insufficient user permissions, could not complete the operation</key>
<key alias="operationCancelledHeader">Cancelled</key>
<key alias="operationCancelledText">Operation was cancelled by a 3rd party add-in</key>
<key alias="contentPublishedFailedByEvent">Publishing was cancelled by a 3rd party add-in</key>
+4 -4
View File
@@ -126,14 +126,14 @@
xdt:Locator="Condition(_defaultNamespace:assemblyIdentity[@name='System.Web.Helpers']])" />
<dependentAssembly xdt:Transform="Insert">
<assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly xdt:Transform="Remove"
xdt:Locator="Condition(_defaultNamespace:assemblyIdentity[@name='System.Web.Mvc']])" />
<dependentAssembly xdt:Transform="Insert">
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-4.0.0.1" newVersion="4.0.0.1" />
<bindingRedirect oldVersion="1.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
</dependentAssembly>
<dependentAssembly xdt:Transform="Remove"
@@ -154,14 +154,14 @@
xdt:Locator="Condition(_defaultNamespace:assemblyIdentity[@name='System.Web.WebPages']])" />
<dependentAssembly xdt:Transform="Insert">
<assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly xdt:Transform="Remove"
xdt:Locator="Condition(_defaultNamespace:assemblyIdentity[@name='System.Web.WebPages.Razor']])" />
<dependentAssembly xdt:Transform="Insert">
<assemblyIdentity name="System.Web.WebPages.Razor" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
+4 -4
View File
@@ -236,15 +236,15 @@
<!-- Ensure correct version of MVC -->
<dependentAssembly>
<assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.WebPages.Razor" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<!-- Ensure correct version of HtmlAgilityPack -->
@@ -265,7 +265,7 @@
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.0.1" newVersion="4.0.0.1" />
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Http" publicKeyToken="31bf3856ad364e35" culture="neutral" />
@@ -8,6 +8,7 @@ using Umbraco.Core;
using Umbraco.Core.Models.Rdbms;
using Umbraco.Core.Sync;
using Umbraco.Web.Routing;
using Umbraco.Core.Logging;
namespace Umbraco.Web
{
@@ -21,10 +22,28 @@ namespace Umbraco.Web
{
public BatchedDatabaseServerMessenger(ApplicationContext appContext, bool enableDistCalls, DatabaseServerMessengerOptions options)
: base(appContext, enableDistCalls, options)
{
{ }
// invoked by BatchedDatabaseServerMessengerStartup which is an ApplicationEventHandler
// with default "ShouldExecute", so that method will run if app IsConfigured and database
// context IsDatabaseConfigured - we still want to check CanConnect though to be safe
internal void Startup()
{
UmbracoModule.EndRequest += UmbracoModule_EndRequest;
UmbracoModule.RouteAttempt += UmbracoModule_RouteAttempt;
if (ApplicationContext.DatabaseContext.CanConnect == false)
{
ApplicationContext.ProfilingLogger.Logger.Warn<BatchedDatabaseServerMessenger>(
"Cannot connect to the database, distributed calls will not be enabled for this server.");
}
else
{
Boot();
}
}
internal void UmbracoModule_RouteAttempt(object sender, RoutableAttemptEventArgs e)
private void UmbracoModule_RouteAttempt(object sender, RoutableAttemptEventArgs e)
{
switch (e.Outcome)
{
@@ -47,7 +66,7 @@ namespace Umbraco.Web
}
}
internal void UmbracoModule_EndRequest(object sender, EventArgs e)
private void UmbracoModule_EndRequest(object sender, EventArgs e)
{
// will clear the batch - will remain in HttpContext though - that's ok
FlushBatch();
@@ -116,8 +135,6 @@ namespace Umbraco.Web
batch.Add(new RefreshInstructionEnvelope(servers, refresher,
RefreshInstruction.GetInstructions(refresher, messageType, ids, idType, json)));
}
}
}
}
@@ -11,23 +11,12 @@ namespace Umbraco.Web
{
protected override void ApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
{
var msgr = ServerMessengerResolver.HasCurrent ? ServerMessengerResolver.Current.Messenger as BatchedDatabaseServerMessenger : null;
var messenger = ServerMessengerResolver.HasCurrent
? ServerMessengerResolver.Current.Messenger as BatchedDatabaseServerMessenger
: null;
if (msgr == null) return;
UmbracoModule.EndRequest += msgr.UmbracoModule_EndRequest;
UmbracoModule.RouteAttempt += msgr.UmbracoModule_RouteAttempt;
if (applicationContext.DatabaseContext.IsDatabaseConfigured == false || applicationContext.DatabaseContext.CanConnect == false)
{
applicationContext.ProfilingLogger.Logger.Warn<BatchedDatabaseServerMessenger>(
"The app cannot connect to the database, this server cannot be initialized with "
+ typeof(BatchedDatabaseServerMessenger) + ", distributed calls will not be enabled for this server");
}
else
{
msgr.Boot();
}
if (messenger != null)
messenger.Startup();
}
}
}
+90 -89
View File
@@ -30,7 +30,9 @@ using Umbraco.Core.Dynamics;
using umbraco.BusinessLogic.Actions;
using umbraco.cms.businesslogic.web;
using umbraco.presentation.preview;
using Umbraco.Web.UI;
using Constants = Umbraco.Core.Constants;
using Notification = Umbraco.Web.Models.ContentEditing.Notification;
namespace Umbraco.Web.Editors
{
@@ -255,7 +257,8 @@ namespace Umbraco.Web.Editors
if (contentItem.Action == ContentSaveAction.Save || contentItem.Action == ContentSaveAction.SaveNew)
{
//save the item
var saveResult = Services.ContentService.SaveWithStatus(contentItem.PersistedContent, Security.CurrentUser.Id);
var saveResult = Services.ContentService.WithResult().Save(contentItem.PersistedContent, Security.CurrentUser.Id);
wasCancelled = saveResult.Success == false && saveResult.Result.StatusType == OperationStatusType.FailedCancelledByEvent;
}
else if (contentItem.Action == ContentSaveAction.SendPublish || contentItem.Action == ContentSaveAction.SendPublishNew)
@@ -288,9 +291,7 @@ namespace Umbraco.Web.Editors
}
else
{
display.AddWarningNotification(
Services.TextService.Localize("speechBubbles/operationCancelledHeader"),
Services.TextService.Localize("speechBubbles/operationCancelledText"));
AddCancelMessage(display);
}
break;
case ContentSaveAction.SendPublish:
@@ -303,9 +304,7 @@ namespace Umbraco.Web.Editors
}
else
{
display.AddWarningNotification(
Services.TextService.Localize("speechBubbles/operationCancelledHeader"),
Services.TextService.Localize("speechBubbles/operationCancelledText"));
AddCancelMessage(display);
}
break;
case ContentSaveAction.Publish:
@@ -319,57 +318,7 @@ namespace Umbraco.Web.Editors
return display;
}
/// <summary>
/// Checks if the user is currently in preview mode and if so will update the preview content for this item
/// </summary>
/// <param name="contentId"></param>
private void UpdatePreviewContext(int contentId)
{
var previewId = Request.GetPreviewCookieValue();
if (previewId.IsNullOrWhiteSpace()) return;
Guid id;
if (Guid.TryParse(previewId, out id))
{
var d = new Document(contentId);
var pc = new PreviewContent(UmbracoUser, id, false);
pc.PrepareDocument(UmbracoUser, d, true);
pc.SavePreviewSet();
}
}
/// <summary>
/// Maps the dto property values to the persisted model
/// </summary>
/// <param name="contentItem"></param>
private void MapPropertyValues(ContentItemSave contentItem)
{
UpdateName(contentItem);
//TODO: We need to support 'send to publish'
contentItem.PersistedContent.ExpireDate = contentItem.ExpireDate;
contentItem.PersistedContent.ReleaseDate = contentItem.ReleaseDate;
//only set the template if it didn't change
var templateChanged = (contentItem.PersistedContent.Template == null && contentItem.TemplateAlias.IsNullOrWhiteSpace() == false)
|| (contentItem.PersistedContent.Template != null && contentItem.PersistedContent.Template.Alias != contentItem.TemplateAlias)
|| (contentItem.PersistedContent.Template != null && contentItem.TemplateAlias.IsNullOrWhiteSpace());
if (templateChanged)
{
var template = Services.FileService.GetTemplate(contentItem.TemplateAlias);
if (template == null && contentItem.TemplateAlias.IsNullOrWhiteSpace() == false)
{
//ModelState.AddModelError("Template", "No template exists with the specified alias: " + contentItem.TemplateAlias);
LogHelper.Warn<ContentController>("No template exists with the specified alias: " + contentItem.TemplateAlias);
}
else
{
//NOTE: this could be null if there was a template and the posted template is null, this should remove the assigned template
contentItem.PersistedContent.Template = template;
}
}
base.MapPropertyValues(contentItem);
}
/// <summary>
/// Publishes a document with a given ID
@@ -391,30 +340,12 @@ namespace Umbraco.Web.Editors
return HandleContentNotFound(id, false);
}
var publishResult = Services.ContentService.PublishWithStatus(foundContent, UmbracoUser.Id);
var publishResult = Services.ContentService.PublishWithStatus(foundContent, Security.GetUserId());
if (publishResult.Success == false)
{
switch (publishResult.Result.StatusType)
{
case PublishStatusType.FailedPathNotPublished:
return Request.CreateValidationErrorResponse(
Services.TextService.Localize("publish/contentPublishedFailedByParent",
new[] {string.Format("{0} ({1})", publishResult.Result.ContentItem.Name, publishResult.Result.ContentItem.Id)}).Trim());
case PublishStatusType.FailedCancelledByEvent:
return Request.CreateValidationErrorResponse(
Services.TextService.Localize("speechBubbles/contentPublishedFailedByEvent"));
case PublishStatusType.FailedHasExpired:
case PublishStatusType.FailedAwaitingRelease:
case PublishStatusType.FailedIsTrashed:
case PublishStatusType.FailedContentInvalid:
return Request.CreateValidationErrorResponse(
Services.TextService.Localize("publish/contentPublishedFailedInvalid",
new[]
{
string.Format("{0} ({1})", publishResult.Result.ContentItem.Name, publishResult.Result.ContentItem.Id),
string.Join(",", publishResult.Result.InvalidProperties.Select(x => x.Alias))
}));
}
var notificationModel = new SimpleNotificationModel();
ShowMessageForPublishStatus(publishResult.Result, notificationModel);
return Request.CreateValidationErrorResponse(notificationModel);
}
//return ok
@@ -446,11 +377,23 @@ namespace Umbraco.Web.Editors
//if the current item is in the recycle bin
if (foundContent.IsInRecycleBin() == false)
{
Services.ContentService.MoveToRecycleBin(foundContent, UmbracoUser.Id);
var moveResult = Services.ContentService.WithResult().MoveToRecycleBin(foundContent, Security.GetUserId());
if (moveResult == false)
{
//returning an object of INotificationModel will ensure that any pending
// notification messages are added to the response.
return Request.CreateValidationErrorResponse(new SimpleNotificationModel());
}
}
else
{
Services.ContentService.Delete(foundContent, UmbracoUser.Id);
var deleteResult = Services.ContentService.WithResult().Delete(foundContent, Security.GetUserId());
if (deleteResult == false)
{
//returning an object of INotificationModel will ensure that any pending
// notification messages are added to the response.
return Request.CreateValidationErrorResponse(new SimpleNotificationModel());
}
}
return Request.CreateResponse(HttpStatusCode.OK);
@@ -559,12 +502,72 @@ namespace Umbraco.Web.Editors
if (foundContent == null)
HandleContentNotFound(id);
Services.ContentService.UnPublish(foundContent, Security.CurrentUser.Id);
var unpublishResult = Services.ContentService.WithResult().UnPublish(foundContent, Security.CurrentUser.Id);
var content = Mapper.Map<IContent, ContentItemDisplay>(foundContent);
content.AddSuccessNotification(Services.TextService.Localize("content/unPublish"), Services.TextService.Localize("speechBubbles/contentUnpublished"));
if (unpublishResult == false)
{
AddCancelMessage(content);
throw new HttpResponseException(Request.CreateValidationErrorResponse(content));
}
else
{
content.AddSuccessNotification(Services.TextService.Localize("content/unPublish"), Services.TextService.Localize("speechBubbles/contentUnpublished"));
return content;
}
}
return content;
/// <summary>
/// Checks if the user is currently in preview mode and if so will update the preview content for this item
/// </summary>
/// <param name="contentId"></param>
private void UpdatePreviewContext(int contentId)
{
var previewId = Request.GetPreviewCookieValue();
if (previewId.IsNullOrWhiteSpace()) return;
Guid id;
if (Guid.TryParse(previewId, out id))
{
var d = new Document(contentId);
var pc = new PreviewContent(UmbracoUser, id, false);
pc.PrepareDocument(UmbracoUser, d, true);
pc.SavePreviewSet();
}
}
/// <summary>
/// Maps the dto property values to the persisted model
/// </summary>
/// <param name="contentItem"></param>
private void MapPropertyValues(ContentItemSave contentItem)
{
UpdateName(contentItem);
//TODO: We need to support 'send to publish'
contentItem.PersistedContent.ExpireDate = contentItem.ExpireDate;
contentItem.PersistedContent.ReleaseDate = contentItem.ReleaseDate;
//only set the template if it didn't change
var templateChanged = (contentItem.PersistedContent.Template == null && contentItem.TemplateAlias.IsNullOrWhiteSpace() == false)
|| (contentItem.PersistedContent.Template != null && contentItem.PersistedContent.Template.Alias != contentItem.TemplateAlias)
|| (contentItem.PersistedContent.Template != null && contentItem.TemplateAlias.IsNullOrWhiteSpace());
if (templateChanged)
{
var template = Services.FileService.GetTemplate(contentItem.TemplateAlias);
if (template == null && contentItem.TemplateAlias.IsNullOrWhiteSpace() == false)
{
//ModelState.AddModelError("Template", "No template exists with the specified alias: " + contentItem.TemplateAlias);
LogHelper.Warn<ContentController>("No template exists with the specified alias: " + contentItem.TemplateAlias);
}
else
{
//NOTE: this could be null if there was a template and the posted template is null, this should remove the assigned template
contentItem.PersistedContent.Template = template;
}
}
base.MapPropertyValues(contentItem);
}
/// <summary>
@@ -621,7 +624,7 @@ namespace Umbraco.Web.Editors
return toMove;
}
private void ShowMessageForPublishStatus(PublishStatus status, ContentItemDisplay display)
private void ShowMessageForPublishStatus(PublishStatus status, INotificationModel display)
{
switch (status.StatusType)
{
@@ -638,9 +641,7 @@ namespace Umbraco.Web.Editors
new[] {string.Format("{0} ({1})", status.ContentItem.Name, status.ContentItem.Id)}).Trim());
break;
case PublishStatusType.FailedCancelledByEvent:
display.AddWarningNotification(
Services.TextService.Localize("publish"),
Services.TextService.Localize("speechBubbles/contentPublishedFailedByEvent"));
AddCancelMessage(display, "publish", "speechBubbles/contentPublishedFailedByEvent");
break;
case PublishStatusType.FailedAwaitingRelease:
display.AddWarningNotification(
@@ -172,5 +172,19 @@ namespace Umbraco.Web.Editors
return (action.ToString().EndsWith("New"));
}
protected void AddCancelMessage(INotificationModel display,
string header = "speechBubbles/operationCancelledHeader",
string message = "speechBubbles/operationCancelledText",
bool localizeHeader = true,
bool localizeMessage = true)
{
//if there's already a default event message, don't add our default one
var msgs = UmbracoContext.GetCurrentEventMessages();
if (msgs != null && msgs.GetAll().Any(x => x.IsDefaultEventMessage)) return;
display.AddWarningNotification(
localizeHeader ? Services.TextService.Localize(header) : header,
localizeMessage ? Services.TextService.Localize(message): message);
}
}
}
+55 -29
View File
@@ -26,6 +26,7 @@ using Umbraco.Web.Models.Mapping;
using Umbraco.Web.Mvc;
using Umbraco.Web.WebApi;
using System.Linq;
using System.Runtime.Serialization;
using Umbraco.Web.WebApi.Binders;
using Umbraco.Web.WebApi.Filters;
using umbraco;
@@ -33,6 +34,8 @@ using umbraco.BusinessLogic.Actions;
using Constants = Umbraco.Core.Constants;
using Umbraco.Core.Configuration;
using Umbraco.Core.Persistence.FaultHandling;
using Umbraco.Web.UI;
using Notification = Umbraco.Web.Models.ContentEditing.Notification;
namespace Umbraco.Web.Editors
{
@@ -182,11 +185,23 @@ namespace Umbraco.Web.Editors
//if the current item is in the recycle bin
if (foundMedia.IsInRecycleBin() == false)
{
Services.MediaService.MoveToRecycleBin(foundMedia, (int)Security.CurrentUser.Id);
var moveResult = Services.MediaService.WithResult().MoveToRecycleBin(foundMedia, (int)Security.CurrentUser.Id);
if (moveResult == false)
{
//returning an object of INotificationModel will ensure that any pending
// notification messages are added to the response.
return Request.CreateValidationErrorResponse(new SimpleNotificationModel());
}
}
else
{
Services.MediaService.Delete(foundMedia, (int)Security.CurrentUser.Id);
var deleteResult = Services.MediaService.WithResult().Delete(foundMedia, (int)Security.CurrentUser.Id);
if (deleteResult == false)
{
//returning an object of INotificationModel will ensure that any pending
// notification messages are added to the response.
return Request.CreateValidationErrorResponse(new SimpleNotificationModel());
}
}
return Request.CreateResponse(HttpStatusCode.OK);
@@ -234,7 +249,7 @@ namespace Umbraco.Web.Editors
// then we cannot continue saving, we can only display errors
// * If there are validation errors and they were attempting to publish, we can only save, NOT publish and display
// a message indicating this
if (!ModelState.IsValid)
if (ModelState.IsValid == false)
{
if (ValidationHelper.ModelHasRequiredForPersistenceErrors(contentItem)
&& (contentItem.Action == ContentSaveAction.SaveNew))
@@ -248,7 +263,7 @@ namespace Umbraco.Web.Editors
}
//save the item
var saveStatus = Services.MediaService.SaveWithStatus(contentItem.PersistedContent, (int)Security.CurrentUser.Id);
var saveStatus = Services.MediaService.WithResult().Save(contentItem.PersistedContent, (int)Security.CurrentUser.Id);
//return the updated model
var display = Mapper.Map<IMedia, MediaItemDisplay>(contentItem.PersistedContent);
@@ -269,9 +284,7 @@ namespace Umbraco.Web.Editors
}
else
{
display.AddWarningNotification(
Services.TextService.Localize("speechBubbles/operationCancelledHeader"),
Services.TextService.Localize("speechBubbles/operationCancelledText"));
AddCancelMessage(display);
}
break;
@@ -386,9 +399,7 @@ namespace Umbraco.Web.Editors
int parentId;
if (int.TryParse(result.FormData["currentFolder"], out parentId) == false)
{
var response = Request.CreateResponse(HttpStatusCode.BadRequest);
response.ReasonPhrase = "The request was not formatted correctly, the currentFolder is not an integer";
throw new HttpResponseException(response);
return Request.CreateValidationErrorResponse("The request was not formatted correctly, the currentFolder is not an integer");
}
//ensure the user has access to this folder by parent id!
@@ -397,7 +408,12 @@ namespace Umbraco.Web.Editors
Security.CurrentUser,
Services.MediaService, parentId) == false)
{
return Request.CreateResponse(HttpStatusCode.Unauthorized);
return Request.CreateResponse(
HttpStatusCode.Unauthorized,
new SimpleNotificationModel(new Notification(
Services.TextService.Localize("speechBubbles/operationFailedHeader"),
Services.TextService.Localize("speechBubbles/invalidUserPermissionsText"),
SpeechBubbleIcon.Warning)));
}
var tempFiles = new PostedFiles();
@@ -408,7 +424,7 @@ namespace Umbraco.Web.Editors
var fileName = file.Headers.ContentDisposition.FileName.Trim(new[] { '\"' });
var ext = fileName.Substring(fileName.LastIndexOf('.')+1).ToLower();
if (!UmbracoConfig.For.UmbracoSettings().Content.DisallowedUploadFiles.Contains(ext))
if (UmbracoConfig.For.UmbracoSettings().Content.DisallowedUploadFiles.Contains(ext) == false)
{
var mediaType = Constants.Conventions.MediaTypes.File;
@@ -426,19 +442,30 @@ namespace Umbraco.Web.Editors
f.SetValue(Constants.Conventions.Media.File, fileName, fs);
}
mediaService.Save(f, Security.CurrentUser.Id);
var saveResult = mediaService.WithResult().Save(f, Security.CurrentUser.Id);
if (saveResult == false)
{
AddCancelMessage(tempFiles,
message: Services.TextService.Localize("speechBubbles/operationCancelledText") + " -- " + fileName,
localizeMessage: false);
}
else
{
tempFiles.UploadedFiles.Add(new ContentItemFile
{
FileName = fileName,
PropertyAlias = Constants.Conventions.Media.File,
TempFilePath = file.LocalFileName
});
}
}
else
{
LogHelper.Warn<MediaController>("Cannot upload file " + file + ", it is not an approved file type");
tempFiles.Notifications.Add(new Notification(
Services.TextService.Localize("speechBubbles/operationFailedHeader"),
"Cannot upload file " + file + ", it is not an approved file type",
SpeechBubbleIcon.Warning));
}
tempFiles.UploadedFiles.Add(new ContentItemFile
{
FileName = fileName,
PropertyAlias = Constants.Conventions.Media.File,
TempFilePath = file.LocalFileName
});
}
//Different response if this is a 'blueimp' request
@@ -448,13 +475,7 @@ namespace Umbraco.Web.Editors
if (origin.Value == "blueimp")
{
return Request.CreateResponse(HttpStatusCode.OK,
tempFiles.UploadedFiles.Select(x => new
{
name = x.FileName,
size = "",
url = "",
thumbnailUrl = ""
}),
tempFiles,
//Don't output the angular xsrf stuff, blue imp doesn't like that
new JsonMediaTypeFormatter());
}
@@ -467,13 +488,18 @@ namespace Umbraco.Web.Editors
/// This is used for the response of PostAddFile so that we can analyze the response in a filter and remove the
/// temporary files that were created.
/// </summary>
private class PostedFiles : IHaveUploadedFiles
[DataContract]
private class PostedFiles : IHaveUploadedFiles, INotificationModel
{
public PostedFiles()
{
UploadedFiles = new List<ContentItemFile>();
Notifications = new List<Notification>();
}
public List<ContentItemFile> UploadedFiles { get; private set; }
[DataMember(Name = "notifications")]
public List<Notification> Notifications { get; private set; }
}
/// <summary>
+3 -1
View File
@@ -80,7 +80,7 @@ namespace Umbraco.Web.Editors
string filter = "",
string memberTypeAlias = null)
{
int totalRecords;
if (pageNumber <= 0 || pageSize <= 0)
{
throw new NotSupportedException("Both pageNumber and pageSize must be greater than zero");
@@ -88,6 +88,7 @@ namespace Umbraco.Web.Editors
if (MembershipScenario == MembershipScenario.NativeUmbraco)
{
long totalRecords;
var members = Services.MemberService.GetAll((pageNumber - 1), pageSize, out totalRecords, orderBy, orderDirection, memberTypeAlias, filter).ToArray();
if (totalRecords == 0)
{
@@ -100,6 +101,7 @@ namespace Umbraco.Web.Editors
}
else
{
int totalRecords;
var members = _provider.GetAllUsers((pageNumber - 1), pageSize, out totalRecords);
if (totalRecords == 0)
{
@@ -83,6 +83,8 @@ namespace Umbraco.Web.Editors
{
var targetNode = umbraco.TypedContent(model.Source.Id);
//TODO: Null check!!!!!!!!!!!!
var aliases = this.GetChildContentTypeAliases(targetNode, currentPage).Reverse();
foreach (var contentTypeAlias in aliases)
@@ -3,7 +3,6 @@ using System.Linq;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Routing;
using Microsoft.Web.Mvc;
using Umbraco.Core;
using Umbraco.Core.Configuration;
using Umbraco.Web.Editors;
@@ -12,7 +12,7 @@ using umbraco.BusinessLogic.Utils;
namespace Umbraco.Web.Media.ThumbnailProviders
{
internal sealed class ThumbnailProvidersResolver : ManyObjectsResolverBase<ThumbnailProvidersResolver, IThumbnailProvider>
public sealed class ThumbnailProvidersResolver : ManyObjectsResolverBase<ThumbnailProvidersResolver, IThumbnailProvider>
{
/// <summary>
/// Constructor
@@ -6,6 +6,18 @@ namespace Umbraco.Web.Models.ContentEditing
[DataContract(Name = "notification", Namespace = "")]
public class Notification
{
public Notification()
{
}
public Notification(string header, string message, SpeechBubbleIcon notificationType)
{
Header = header;
Message = message;
NotificationType = notificationType;
}
[DataMember(Name = "header")]
public string Header { get; set; }
[DataMember(Name = "message")]
@@ -0,0 +1,25 @@
using System.Collections.Generic;
using System.Runtime.Serialization;
namespace Umbraco.Web.Models.ContentEditing
{
[DataContract(Name = "notificationModel", Namespace = "")]
public class SimpleNotificationModel : INotificationModel
{
public SimpleNotificationModel()
{
Notifications = new List<Notification>();
}
public SimpleNotificationModel(params Notification[] notifications)
{
Notifications = new List<Notification>(notifications);
}
/// <summary>
/// This is used to add custom localized messages/strings to the response for the app to use for localized UI purposes.
/// </summary>
[DataMember(Name = "notifications")]
public List<Notification> Notifications { get; private set; }
}
}
+1 -2
View File
@@ -2,7 +2,6 @@ using System.IO;
using System.Linq;
using System.Web.Mvc;
using Lucene.Net.Util;
using Microsoft.Web.Mvc;
using Umbraco.Core.IO;
namespace Umbraco.Web.Mvc
@@ -10,7 +9,7 @@ namespace Umbraco.Web.Mvc
/// <summary>
/// A view engine to look into the App_Plugins folder for views for packaged controllers
/// </summary>
public class PluginViewEngine : ReflectedFixedRazorViewEngine
public class PluginViewEngine : RazorViewEngine
{
/// <summary>
@@ -7,6 +7,7 @@ namespace Umbraco.Web.Mvc
/// <summary>
/// This is here to support compatibility with both MVC4 and MVC5
/// </summary>
[Obsolete("MVC5 does not have a 'fixed' viewengine so there's no reason to use this any more", false)]
public abstract class ReflectedFixedRazorViewEngine : IViewEngine
{
protected ReflectedFixedRazorViewEngine()
-1
View File
@@ -2,7 +2,6 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web.Mvc;
using Microsoft.Web.Mvc;
using Umbraco.Core;
using Umbraco.Core.IO;
using Umbraco.Web.Models;
@@ -1,41 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
namespace Umbraco.Web.Standalone
{
internal static class PowershellAssemblyResolver
{
private static readonly Dictionary<string, string> Assemblies;
private static readonly object Locko = new object();
static PowershellAssemblyResolver()
{
var comparer = StringComparer.CurrentCultureIgnoreCase;
Assemblies = new Dictionary<string,string>(comparer);
AppDomain.CurrentDomain.AssemblyResolve += ResolveHandler;
}
public static void AddAssemblyLocation(string path)
{
if (string.IsNullOrWhiteSpace(path))
throw new ArgumentException("Arg is null or empty.", "path");
lock (Locko)
{
var name = Path.GetFileNameWithoutExtension(path);
Assemblies.Add(name, path);
}
}
private static Assembly ResolveHandler(object sender, ResolveEventArgs args)
{
var assemblyName = new AssemblyName(args.Name);
string assemblyFile;
return Assemblies.TryGetValue(assemblyName.Name, out assemblyFile)
? Assembly.LoadFrom(assemblyFile)
: null;
}
}
}
@@ -1,83 +0,0 @@
using System;
using System.Diagnostics;
using Umbraco.Core;
using Umbraco.Core.Cache;
using Umbraco.Core.Configuration;
using Umbraco.Core.Events;
using Umbraco.Core.Logging;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.Mappers;
using Umbraco.Core.Persistence.SqlSyntax;
using Umbraco.Core.Persistence.UnitOfWork;
using Umbraco.Core.Publishing;
using Umbraco.Core.Services;
namespace Umbraco.Web.Standalone
{
//TODO: Why does this exist? there's the same thing in the Core proj
internal class ServiceContextManager : IDisposable
{
private readonly string _connectionString;
private readonly string _providerName;
private readonly ILogger _logger;
private readonly ISqlSyntaxProvider _syntaxProvider;
private ServiceContext _serviceContext;
private readonly StandaloneApplication _application;
public ServiceContextManager(string connectionString, string providerName, string baseDirectory, ILogger logger, ISqlSyntaxProvider syntaxProvider)
{
_connectionString = connectionString;
_providerName = providerName;
_logger = logger;
_syntaxProvider = syntaxProvider;
Trace.WriteLine("Current AppDomain: " + AppDomain.CurrentDomain.FriendlyName);
Trace.WriteLine("Current AppDomain: " + AppDomain.CurrentDomain.BaseDirectory);
_application = StandaloneApplication.GetApplication(baseDirectory);
_application.Start();
}
public ServiceContext Services
{
get
{
if (_serviceContext == null)
{
var cacheHelper = new CacheHelper(
//SD: Not sure if this is correct? Should we be using HttpRuntime.Cache here since this is for 'Web' ?
// just not quite sure what this standalone stuff is.
new ObjectCacheRuntimeCacheProvider(),
new StaticCacheProvider(),
//SD: Not sure if this is correct? Should we be using request cache here since this is for 'Web' ?
// just not quite sure what this standalone stuff is.
new NullCacheProvider());
var dbFactory = new DefaultDatabaseFactory(_connectionString, _providerName, _logger);
var dbContext = new DatabaseContext(dbFactory, _logger, _syntaxProvider, _providerName);
Database.Mapper = new PetaPocoMapper();
_serviceContext = new ServiceContext(
new RepositoryFactory(cacheHelper, _logger, dbContext.SqlSyntax, UmbracoConfig.For.UmbracoSettings()),
new PetaPocoUnitOfWorkProvider(dbFactory),
new FileUnitOfWorkProvider(),
new PublishingStrategy(),
cacheHelper,
new DebugDiagnosticsLogger(),
new TransientMessagesFactory());
//initialize the DatabaseContext
dbContext.Initialize(_providerName);
}
return _serviceContext;
}
}
public void Dispose()
{
((IDisposable)ApplicationContext.Current).Dispose();
_application.Dispose();
}
}
}
@@ -1,186 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Umbraco.Core;
using Umbraco.Core.ObjectResolution;
namespace Umbraco.Web.Standalone
{
/// <summary>
/// An application standalone applications.
/// </summary>
internal class StandaloneApplication : UmbracoApplicationBase
{
/// <summary>
/// Initializes a new instance of the <see cref="StandaloneApplication"/> class.
/// </summary>
protected StandaloneApplication(string baseDirectory)
{
_baseDirectory = baseDirectory;
}
/// <summary>
/// Provides the application boot manager.
/// </summary>
/// <returns>An application boot manager.</returns>
protected override IBootManager GetBootManager()
{
return new StandaloneBootManager(this, _handlersToAdd, _handlersToRemove, _baseDirectory);
}
#region Application
private static StandaloneApplication _application;
private readonly string _baseDirectory;
private static bool _started;
private static readonly object AppLock = new object();
/// <summary>
/// Gets the instance of the standalone Umbraco application.
/// </summary>
public static StandaloneApplication GetApplication(string baseDirectory)
{
lock (AppLock)
{
return _application ?? (_application = new StandaloneApplication(baseDirectory));
}
}
/// <summary>
/// Starts the application.
/// </summary>
public void Start(bool noerr = false)
{
lock (AppLock)
{
if (_started)
{
if (noerr) return;
throw new InvalidOperationException("Application has already started.");
}
try
{
Application_Start(this, EventArgs.Empty);
}
catch
{
TerminateInternal();
throw;
}
_started = true;
}
}
public void Terminate(bool noerr = false)
{
lock (AppLock)
{
if (_started == false)
{
if (noerr) return;
throw new InvalidOperationException("Application has already been terminated.");
}
TerminateInternal();
}
}
private void TerminateInternal()
{
if (ApplicationContext.Current != null)
{
ApplicationContext.Current.DisposeIfDisposable(); // should reset resolution, clear caches & resolvers...
ApplicationContext.Current = null;
}
if (UmbracoContext.Current != null)
{
UmbracoContext.Current.DisposeIfDisposable(); // dunno
UmbracoContext.Current = null;
}
_started = false;
_application = null;
}
#endregion
#region IApplicationEventHandler management
private readonly List<Type> _handlersToAdd = new List<Type>();
private readonly List<Type> _handlersToRemove = new List<Type>();
/// <summary>
/// Associates an <see cref="IApplicationEventHandler"/> type with the application.
/// </summary>
/// <typeparam name="T">The type to associate.</typeparam>
/// <returns>The application.</returns>
/// <remarks>Types implementing <see cref="IApplicationEventHandler"/> from within
/// an executable are not automatically discovered by Umbraco and have to be
/// explicitely associated with the application using this method.</remarks>
public StandaloneApplication WithApplicationEventHandler<T>()
where T : IApplicationEventHandler
{
_handlersToAdd.Add(typeof(T));
return this;
}
/// <summary>
/// Dissociates an <see cref="IApplicationEventHandler"/> type from the application.
/// </summary>
/// <typeparam name="T">The type to dissociate.</typeparam>
/// <returns>The application.</returns>
public StandaloneApplication WithoutApplicationEventHandler<T>()
where T : IApplicationEventHandler
{
_handlersToRemove.Add(typeof(T));
return this;
}
/// <summary>
/// Associates an <see cref="IApplicationEventHandler"/> type with the application.
/// </summary>
/// <param name="type">The type to associate.</param>
/// <returns>The application.</returns>
/// <remarks>Types implementing <see cref="IApplicationEventHandler"/> from within
/// an executable are not automatically discovered by Umbraco and have to be
/// explicitely associated with the application using this method.</remarks>
public StandaloneApplication WithApplicationEventHandler(Type type)
{
if (type.Implements<IApplicationEventHandler>() == false)
throw new ArgumentException("Type does not implement IApplicationEventHandler.", "type");
_handlersToAdd.Add(type);
return this;
}
/// <summary>
/// Dissociates an <see cref="IApplicationEventHandler"/> type from the application.
/// </summary>
/// <param name="type">The type to dissociate.</param>
/// <returns>The application.</returns>
public StandaloneApplication WithoutApplicationEventHandler(Type type)
{
if (type.Implements<IApplicationEventHandler>() == false)
throw new ArgumentException("Type does not implement IApplicationEventHandler.", "type");
_handlersToRemove.Add(type);
return this;
}
#endregion
#region Shortcuts to contexts
/// <summary>
/// Gets the current <see cref="ApplicationContext"/>.
/// </summary>
/// <remarks>This is a shortcut for scripts to be able to do <c>$app.ApplicationContext</c>.</remarks>
public ApplicationContext ApplicationContext { get { return ApplicationContext.Current; } }
/// <summary>
/// Gets the current <see cref="UmbracoContext"/>.
/// </summary>
/// <remarks>This is a shortcut for scripts to be able to do <c>$app.UmbracoContext</c>.</remarks>
public UmbracoContext UmbracoContext { get { return UmbracoContext.Current; } }
#endregion
}
}
@@ -1,89 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Umbraco.Core;
using Umbraco.Core.Logging;
using Umbraco.Core.ObjectResolution;
using Umbraco.Web.PublishedCache;
using Umbraco.Web.Routing;
using Umbraco.Web.Security;
using umbraco.interfaces;
namespace Umbraco.Web.Standalone
{
/// <summary>
/// A boot manager for use in standalone applications.
/// </summary>
internal class StandaloneBootManager : CoreBootManager
{
// TODO
// this is highly experimental and probably not complete - not for production usage!
// also, could we inherit from WebBootManager?
private readonly IEnumerable<Type> _handlersToAdd;
private readonly IEnumerable<Type> _handlersToRemove;
private readonly string _baseDirectory;
public StandaloneBootManager(UmbracoApplicationBase umbracoApplication, IEnumerable<Type> handlersToAdd, IEnumerable<Type> handlersToRemove, string baseDirectory)
: base(umbracoApplication)
{
_handlersToAdd = handlersToAdd;
_handlersToRemove = handlersToRemove;
_baseDirectory = baseDirectory;
base.InitializeApplicationRootPath(_baseDirectory);
// this is only here to ensure references to the assemblies needed for
// the DataTypesResolver otherwise they won't be loaded into the AppDomain.
var interfacesAssemblyName = typeof(IDataType).Assembly.FullName;
// TODO there's also that one... but we don't use it in standalone?
//using umbraco.editorControls;
//var editorControlsAssemblyName = typeof(uploadField).Assembly.FullName;
}
protected override void InitializeApplicationEventsResolver()
{
base.InitializeApplicationEventsResolver();
foreach (var type in _handlersToAdd)
ApplicationEventsResolver.Current.AddType(type);
foreach (var type in _handlersToRemove)
ApplicationEventsResolver.Current.RemoveType(type);
}
protected override void InitializeResolvers()
{
base.InitializeResolvers();
var caches = new PublishedCaches(
new PublishedCache.XmlPublishedCache.PublishedContentCache(),
new PublishedCache.XmlPublishedCache.PublishedMediaCache(ApplicationContext.Current));
PublishedCachesResolver.Current = new PublishedCachesResolver(caches);
UrlProviderResolver.Current = new UrlProviderResolver(ServiceProvider, LoggerResolver.Current.Logger, typeof(DefaultUrlProvider));
SiteDomainHelperResolver.Current = new SiteDomainHelperResolver(new SiteDomainHelper());
ContentLastChanceFinderResolver.Current = new ContentLastChanceFinderResolver();
ContentFinderResolver.Current = new ContentFinderResolver(
ServiceProvider, LoggerResolver.Current.Logger,
typeof (ContentFinderByPageIdQuery),
typeof (ContentFinderByNiceUrl),
typeof (ContentFinderByIdPath),
typeof (ContentFinderByNotFoundHandlers)
);
// TODO what else?
}
// can't create context before resolution is frozen!
protected override void FreezeResolution()
{
base.FreezeResolution();
var httpContext = new StandaloneHttpContext();
UmbracoContext.EnsureContext(httpContext, ApplicationContext.Current, new WebSecurity(httpContext, ApplicationContext.Current), false, false);
}
}
}
@@ -1,73 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Web;
namespace Umbraco.Web.Standalone
{
/// <summary>
/// An Http context for use in standalone applications.
/// </summary>
internal class StandaloneHttpContext : HttpContextBase
{
private readonly string _url;
private readonly HttpSessionStateBase _session = new StandaloneHttpSessionState();
private readonly HttpResponseBase _response;
private readonly HttpRequestBase _request = new StandaloneHttpRequest();
private readonly TextWriter _writer = new StringWriter();
private readonly IDictionary _items = new Dictionary<string, object>();
public StandaloneHttpContext()
{
_response = new HttpResponseWrapper(new HttpResponse(_writer));
}
public StandaloneHttpContext(string url)
: this()
{
if (url == null) throw new ArgumentNullException("url");
_url = url;
_request = new HttpRequestWrapper(new HttpRequest("", _url, ""));
}
// what else should we implement here?
public override IDictionary Items
{
get { return _items; }
}
public override HttpSessionStateBase Session
{
get { return _session; }
}
public override HttpRequestBase Request
{
get { return _request; }
}
public override HttpResponseBase Response
{
get { return _response; }
}
}
internal class StandaloneHttpSessionState : HttpSessionStateBase
{
}
internal class StandaloneHttpRequest : HttpRequestBase
{
public override Uri Url
{
get { return new Uri("http://localhost"); }
}
}
}
@@ -1,262 +0,0 @@
using System;
using System.Collections.Specialized;
using System.Configuration;
using System.Configuration.Internal;
using System.Reflection;
using System.Threading;
namespace Umbraco.Web.Standalone
{
// see http://stackoverflow.com/questions/15653621/how-to-update-add-modify-delete-keys-in-appsettings-section-of-web-config-at-r
// see http://www.codeproject.com/Articles/69364/Override-Configuration-Manager
internal sealed class WriteableConfigSystem : IInternalConfigSystem
{
private static readonly ReaderWriterLockSlim RwLock = new ReaderWriterLockSlim();
private static WriteableConfigSystem _installed;
private static IInternalConfigSystem _clientConfigSystem;
private object _appsettings;
private object _connectionStrings;
private static object _sInitStateOrig;
private static object _sConfigSystemOrig;
public static bool Installed
{
get
{
try
{
RwLock.EnterReadLock();
return _installed != null;
}
finally
{
RwLock.ExitReadLock();
}
}
}
/// <summary>
/// Re-initializes the ConfigurationManager, allowing us to merge in the settings from Core.Config
/// </summary>
public static void Install()
{
try
{
RwLock.EnterWriteLock();
if (_installed != null)
throw new InvalidOperationException("ConfigSystem is already installed.");
FieldInfo[] fiStateValues = null;
var tInitState = typeof(ConfigurationManager).GetNestedType("InitState", BindingFlags.NonPublic);
if (tInitState != null)
fiStateValues = tInitState.GetFields();
// 0: NotStarted
// 1: Started
// 2: Usable
// 3: Completed
var fiInit = typeof(ConfigurationManager).GetField("s_initState", BindingFlags.NonPublic | BindingFlags.Static);
var fiSystem = typeof(ConfigurationManager).GetField("s_configSystem", BindingFlags.NonPublic | BindingFlags.Static);
if (fiInit != null && fiSystem != null && fiStateValues != null)
{
_sInitStateOrig = fiInit.GetValue(null);
_sConfigSystemOrig = fiSystem.GetValue(null);
fiInit.SetValue(null, fiStateValues[1].GetValue(null)); // set to Started
fiSystem.SetValue(null, null); // clear current config system
}
_installed = new WriteableConfigSystem();
var configFactoryType = Type.GetType("System.Configuration.Internal.InternalConfigSettingsFactory, System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", true);
var configSettingsFactory = (IInternalConfigSettingsFactory)Activator.CreateInstance(configFactoryType, true);
// just does ConfigurationManager.SetConfigurationSystem(_installed, false);
// 'false' turns initState to 2 ie usable (vs 3 ie completed)
configSettingsFactory.SetConfigurationSystem(_installed, false);
// note: prob. don't need the factory... see how we uninstall...
var clientConfigSystemType = Type.GetType("System.Configuration.ClientConfigurationSystem, System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", true);
_clientConfigSystem = (IInternalConfigSystem)Activator.CreateInstance(clientConfigSystemType, true);
}
finally
{
RwLock.ExitWriteLock();
}
}
public static void Uninstall()
{
try
{
RwLock.EnterWriteLock();
if (_installed == null)
throw new InvalidOperationException("ConfigSystem is not installed.");
FieldInfo[] fiStateValues = null;
var tInitState = typeof(ConfigurationManager).GetNestedType("InitState", BindingFlags.NonPublic);
if (tInitState != null)
fiStateValues = tInitState.GetFields();
var fiInit = typeof(ConfigurationManager).GetField("s_initState", BindingFlags.NonPublic | BindingFlags.Static);
var fiSystem = typeof(ConfigurationManager).GetField("s_configSystem", BindingFlags.NonPublic | BindingFlags.Static);
if (fiInit != null && fiSystem != null && fiStateValues != null)
{
// reset - the hard way
fiInit.SetValue(null, _sInitStateOrig);
fiSystem.SetValue(null, _sConfigSystemOrig);
}
_installed = null;
_clientConfigSystem = null;
}
finally
{
RwLock.ExitWriteLock();
}
}
public static void Reset()
{
try
{
RwLock.EnterWriteLock();
if (_installed == null)
throw new InvalidOperationException("ConfigSystem is not installed.");
_installed._appsettings = null;
_installed._connectionStrings = null;
}
finally
{
RwLock.ExitWriteLock();
}
}
#region IInternalConfigSystem Members
public object GetSection(string configKey)
{
// get the section from the default location (web.config or app.config)
var section = _clientConfigSystem.GetSection(configKey);
try
{
RwLock.EnterReadLock();
switch (configKey)
{
case "appSettings":
// Return cached version if exists
if (_appsettings != null)
return _appsettings;
// create a new collection because the underlying collection is read-only
var cfg = new NameValueCollection();
// If an AppSettings section exists in Web.config, read and add values from it
var nvSection = section as NameValueCollection;
if (nvSection != null)
{
var localSettings = nvSection;
foreach (string key in localSettings)
cfg.Add(key, localSettings[key]);
}
//// --------------------------------------------------------------------
//// Here I read and decrypt keys and add them to secureConfig dictionary
//// To test assume the following line is a key stored in secure sotrage.
////secureConfig = SecureConfig.LoadConfig();
//secureConfig.Add("ACriticalKey", "VeryCriticalValue");
//// --------------------------------------------------------------------
//foreach (KeyValuePair<string, string> item in secureConfig)
//{
// if (cfg.AllKeys.Contains(item.Key))
// {
// cfg[item.Key] = item.Value;
// }
// else
// {
// cfg.Add(item.Key, item.Value);
// }
//}
//// --------------------------------------------------------------------
// Cach the settings for future use
_appsettings = cfg;
// return the merged version of the items from secure storage and appsettings
section = _appsettings;
break;
case "connectionStrings":
// Return cached version if exists
if (_connectionStrings != null)
return _connectionStrings;
// create a new collection because the underlying collection is read-only
var connectionStringsSection = new ConnectionStringsSection();
// copy the existing connection strings into the new collection
foreach (
ConnectionStringSettings connectionStringSetting in
((ConnectionStringsSection)section).ConnectionStrings)
connectionStringsSection.ConnectionStrings.Add(connectionStringSetting);
// --------------------------------------------------------------------
// Again Load connection strings from secure storage and merge like below
// connectionStringsSection.ConnectionStrings.Add(connectionStringSetting);
// --------------------------------------------------------------------
// Cach the settings for future use
_connectionStrings = connectionStringsSection;
// return the merged version of the items from secure storage and appsettings
section = _connectionStrings;
break;
}
}
finally
{
RwLock.ExitReadLock();
}
return section;
}
public void RefreshConfig(string sectionName)
{
try
{
RwLock.EnterWriteLock();
if (sectionName == "appSettings")
{
_appsettings = null;
}
if (sectionName == "connectionStrings")
{
_connectionStrings = null;
}
}
finally
{
RwLock.ExitWriteLock();
}
_clientConfigSystem.RefreshConfig(sectionName);
}
public bool SupportsUserConfig { get { return _clientConfigSystem.SupportsUserConfig; } }
#endregion
}
}
+46 -1
View File
@@ -13,6 +13,11 @@ namespace Umbraco.Web
/// </summary>
public class TagQuery : ITagQuery
{
//TODO: This class also acts as a wrapper for ITagQuery due to breaking changes, need to fix in
// version 8: http://issues.umbraco.org/issue/U4-6899
private readonly ITagQuery _wrappedQuery;
private readonly ITagService _tagService;
private readonly ITypedPublishedContentQuery _typedContentQuery;
@@ -22,7 +27,7 @@ namespace Umbraco.Web
{
}
[Obsolete("Use the alternate constructor specifying the ITypedPublishedContentQuery instead")]
[Obsolete("Use the alternate constructor specifying the ITypedPublishedContentQuery instead")]
public TagQuery(ITagService tagService, PublishedContentQuery contentQuery)
{
if (tagService == null) throw new ArgumentNullException("tagService");
@@ -31,6 +36,16 @@ namespace Umbraco.Web
_typedContentQuery = contentQuery;
}
/// <summary>
/// Constructor for wrapping ITagQuery, see http://issues.umbraco.org/issue/U4-6899
/// </summary>
/// <param name="wrappedQuery"></param>
internal TagQuery(ITagQuery wrappedQuery)
{
if (wrappedQuery == null) throw new ArgumentNullException("wrappedQuery");
_wrappedQuery = wrappedQuery;
}
/// <summary>
/// Constructor
/// </summary>
@@ -52,6 +67,9 @@ namespace Umbraco.Web
/// <returns></returns>
public IEnumerable<IPublishedContent> GetContentByTag(string tag, string tagGroup = null)
{
//TODO: http://issues.umbraco.org/issue/U4-6899
if (_wrappedQuery != null) return _wrappedQuery.GetContentByTag(tag, tagGroup);
var ids = _tagService.GetTaggedContentByTag(tag, tagGroup)
.Select(x => x.EntityId);
return _typedContentQuery.TypedContent(ids)
@@ -65,6 +83,9 @@ namespace Umbraco.Web
/// <returns></returns>
public IEnumerable<IPublishedContent> GetContentByTagGroup(string tagGroup)
{
//TODO: http://issues.umbraco.org/issue/U4-6899
if (_wrappedQuery != null) return _wrappedQuery.GetContentByTagGroup(tagGroup);
var ids = _tagService.GetTaggedContentByTagGroup(tagGroup)
.Select(x => x.EntityId);
return _typedContentQuery.TypedContent(ids)
@@ -79,6 +100,9 @@ namespace Umbraco.Web
/// <returns></returns>
public IEnumerable<IPublishedContent> GetMediaByTag(string tag, string tagGroup = null)
{
//TODO: http://issues.umbraco.org/issue/U4-6899
if (_wrappedQuery != null) return _wrappedQuery.GetMediaByTag(tag, tagGroup);
var ids = _tagService.GetTaggedMediaByTag(tag, tagGroup)
.Select(x => x.EntityId);
return _typedContentQuery.TypedMedia(ids)
@@ -92,6 +116,9 @@ namespace Umbraco.Web
/// <returns></returns>
public IEnumerable<IPublishedContent> GetMediaByTagGroup(string tagGroup)
{
//TODO: http://issues.umbraco.org/issue/U4-6899
if (_wrappedQuery != null) return _wrappedQuery.GetMediaByTagGroup(tagGroup);
var ids = _tagService.GetTaggedMediaByTagGroup(tagGroup)
.Select(x => x.EntityId);
return _typedContentQuery.TypedMedia(ids)
@@ -113,6 +140,9 @@ namespace Umbraco.Web
/// </summary>
public IEnumerable<TagModel> GetAllTags(string group = null)
{
//TODO: http://issues.umbraco.org/issue/U4-6899
if (_wrappedQuery != null) return _wrappedQuery.GetAllTags(group);
return Mapper.Map<IEnumerable<TagModel>>(_tagService.GetAllTags(group));
}
@@ -123,6 +153,9 @@ namespace Umbraco.Web
/// <returns></returns>
public IEnumerable<TagModel> GetAllContentTags(string group = null)
{
//TODO: http://issues.umbraco.org/issue/U4-6899
if (_wrappedQuery != null) return _wrappedQuery.GetAllContentTags(group);
return Mapper.Map<IEnumerable<TagModel>>(_tagService.GetAllContentTags(group));
}
@@ -133,6 +166,9 @@ namespace Umbraco.Web
/// <returns></returns>
public IEnumerable<TagModel> GetAllMediaTags(string group = null)
{
//TODO: http://issues.umbraco.org/issue/U4-6899
if (_wrappedQuery != null) return _wrappedQuery.GetAllMediaTags(group);
return Mapper.Map<IEnumerable<TagModel>>(_tagService.GetAllMediaTags(group));
}
@@ -143,6 +179,9 @@ namespace Umbraco.Web
/// <returns></returns>
public IEnumerable<TagModel> GetAllMemberTags(string group = null)
{
//TODO: http://issues.umbraco.org/issue/U4-6899
if (_wrappedQuery != null) return _wrappedQuery.GetAllMemberTags(group);
return Mapper.Map<IEnumerable<TagModel>>(_tagService.GetAllMemberTags(group));
}
@@ -155,6 +194,9 @@ namespace Umbraco.Web
/// <returns></returns>
public IEnumerable<TagModel> GetTagsForProperty(int contentId, string propertyTypeAlias, string tagGroup = null)
{
//TODO: http://issues.umbraco.org/issue/U4-6899
if (_wrappedQuery != null) return _wrappedQuery.GetTagsForProperty(contentId, propertyTypeAlias, tagGroup);
return Mapper.Map<IEnumerable<TagModel>>(_tagService.GetTagsForProperty(contentId, propertyTypeAlias, tagGroup));
}
@@ -166,6 +208,9 @@ namespace Umbraco.Web
/// <returns></returns>
public IEnumerable<TagModel> GetTagsForEntity(int contentId, string tagGroup = null)
{
//TODO: http://issues.umbraco.org/issue/U4-6899
if (_wrappedQuery != null) return _wrappedQuery.GetTagsForEntity(contentId, tagGroup);
return Mapper.Map<IEnumerable<TagModel>>(_tagService.GetTagsForEntity(contentId, tagGroup));
}
}
+13 -22
View File
@@ -165,10 +165,6 @@
<Private>True</Private>
<HintPath>..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Web.Mvc.FixedDisplayModes, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Microsoft.AspNet.Mvc.FixedDisplayModes.1.0.1\lib\net40\Microsoft.Web.Mvc.FixedDisplayModes.dll</HintPath>
</Reference>
<Reference Include="MiniProfiler, Version=2.1.0.0, Culture=neutral, PublicKeyToken=b44f9351044011a3, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\MiniProfiler.2.1.0\lib\net40\MiniProfiler.dll</HintPath>
@@ -216,9 +212,9 @@
<Reference Include="System.Web.Entity" />
<Reference Include="System.Web.Extensions" />
<Reference Include="System.Web.Extensions.Design" />
<Reference Include="System.Web.Helpers, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<Reference Include="System.Web.Helpers, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.Helpers.dll</HintPath>
<Private>True</Private>
<HintPath>..\packages\Microsoft.AspNet.WebPages.2.0.30506.0\lib\net40\System.Web.Helpers.dll</HintPath>
</Reference>
<Reference Include="System.Web.Http">
<HintPath>..\packages\Microsoft.AspNet.WebApi.Core.5.2.3\lib\net45\System.Web.Http.dll</HintPath>
@@ -228,28 +224,28 @@
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Microsoft.AspNet.WebApi.WebHost.5.2.3\lib\net45\System.Web.Http.WebHost.dll</HintPath>
</Reference>
<Reference Include="System.Web.Mvc, Version=4.0.0.1, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<Reference Include="System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.Mvc.5.2.3\lib\net45\System.Web.Mvc.dll</HintPath>
<Private>True</Private>
<HintPath>..\packages\Microsoft.AspNet.Mvc.4.0.40804.0\lib\net40\System.Web.Mvc.dll</HintPath>
</Reference>
<Reference Include="System.Web.Razor, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<Reference Include="System.Web.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.Razor.3.2.3\lib\net45\System.Web.Razor.dll</HintPath>
<Private>True</Private>
<HintPath>..\packages\Microsoft.AspNet.Razor.2.0.30506.0\lib\net40\System.Web.Razor.dll</HintPath>
</Reference>
<Reference Include="System.Web.Services">
<Name>System.Web.Services</Name>
</Reference>
<Reference Include="System.Web.WebPages, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<Reference Include="System.Web.WebPages, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.dll</HintPath>
<Private>True</Private>
<HintPath>..\packages\Microsoft.AspNet.WebPages.2.0.30506.0\lib\net40\System.Web.WebPages.dll</HintPath>
</Reference>
<Reference Include="System.Web.WebPages.Deployment, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<Reference Include="System.Web.WebPages.Deployment, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.Deployment.dll</HintPath>
<Private>True</Private>
<HintPath>..\packages\Microsoft.AspNet.WebPages.2.0.30506.0\lib\net40\System.Web.WebPages.Deployment.dll</HintPath>
</Reference>
<Reference Include="System.Web.WebPages.Razor, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<Reference Include="System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.Razor.dll</HintPath>
<Private>True</Private>
<HintPath>..\packages\Microsoft.AspNet.WebPages.2.0.30506.0\lib\net40\System.Web.WebPages.Razor.dll</HintPath>
</Reference>
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml">
@@ -305,6 +301,7 @@
<Compile Include="Editors\BackOfficeNotificationsController.cs" />
<Compile Include="HtmlHelperBackOfficeExtensions.cs" />
<Compile Include="Media\EmbedProviders\Flickr.cs" />
<Compile Include="Models\ContentEditing\SimpleNotificationModel.cs" />
<Compile Include="PropertyEditors\DatePreValueEditor.cs" />
<Compile Include="RequestLifespanMessagesFactory.cs" />
<Compile Include="Scheduling\LatchedBackgroundTaskBase.cs" />
@@ -743,7 +740,6 @@
<Compile Include="Security\Providers\UmbracoMembershipProvider.cs" />
<Compile Include="Security\Providers\UsersMembershipProvider.cs" />
<Compile Include="Trees\ContentTreeController.cs" />
<Compile Include="Standalone\PowershellAssemblyResolver.cs" />
<Compile Include="Trees\TreeRenderingEventArgs.cs" />
<Compile Include="Trees\UrlHelperExtensions.cs" />
<Compile Include="UI\JavaScript\JsInitialization.cs" />
@@ -755,10 +751,6 @@
<Compile Include="Models\ContentEditing\ContentPropertyBasic.cs" />
<Compile Include="Models\ContentEditing\ContentPropertyDisplay.cs" />
<Compile Include="Models\ContentEditing\ContentPropertyDto.cs" />
<Compile Include="Standalone\ServiceContextManager.cs" />
<Compile Include="Standalone\StandaloneApplication.cs" />
<Compile Include="Standalone\StandaloneBootManager.cs" />
<Compile Include="Standalone\StandaloneHttpContext.cs" />
<Compile Include="Dynamics\DynamicExpression.cs" />
<Compile Include="Dynamics\DynamicGrouping.cs" />
<Compile Include="Dynamics\DynamicPublishedContentIdEqualityComparer.cs" />
@@ -813,7 +805,6 @@
<Compile Include="Search\LuceneIndexerExtensions.cs" />
<Compile Include="Security\ValidateRequestAttempt.cs" />
<Compile Include="Security\WebSecurity.cs" />
<Compile Include="Standalone\WriteableConfigSystem.cs" />
<Compile Include="UI\JavaScript\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
+7 -3
View File
@@ -32,7 +32,7 @@ namespace Umbraco.Web
private IUmbracoComponentRenderer _componentRenderer;
private PublishedContentQuery _query;
private MembershipHelper _membershipHelper;
private ITagQuery _tag;
private TagQuery _tag;
private IDataTypeService _dataTypeService;
private UrlProvider _urlProvider;
private ICultureDictionary _cultureDictionary;
@@ -40,8 +40,12 @@ namespace Umbraco.Web
/// <summary>
/// Lazy instantiates the tag context
/// </summary>
public ITagQuery TagQuery
public TagQuery TagQuery
{
//TODO: Unfortunately we cannot change this return value to be ITagQuery
// since it's a breaking change, need to fix it for v8
// http://issues.umbraco.org/issue/U4-6899
get
{
return _tag ??
@@ -159,7 +163,7 @@ namespace Umbraco.Web
if (membershipHelper == null) throw new ArgumentNullException("membershipHelper");
_umbracoContext = umbracoContext;
_tag = tagQuery;
_tag = new TagQuery(tagQuery);
_dataTypeService = dataTypeService;
_urlProvider = urlProvider;
_cultureDictionary = cultureDictionary;
@@ -17,7 +17,6 @@ namespace Umbraco.Web.WebApi.Filters
public override void OnActionExecuted(HttpActionExecutedContext context)
{
if (context.Response == null) return;
if (context.Response.IsSuccessStatusCode == false) return;
if (context.Request.Method == HttpMethod.Get) return;
if (UmbracoContext.Current == null) return;
@@ -35,7 +35,7 @@ namespace Umbraco.Web.WebApi
/// <summary>
/// Returns the currently logged in Umbraco User
/// </summary>
[Obsolete("This should no longer be used since it returns the legacy user object, use The Security.CurrentUser instead to return the proper user object")]
[Obsolete("This should no longer be used since it returns the legacy user object, use The Security.CurrentUser instead to return the proper user object, or Security.GetUserId() if you want to just get the user id")]
protected User UmbracoUser
{
get
+4 -3
View File
@@ -84,15 +84,16 @@ namespace Umbraco.Web
/// <returns></returns>
protected override ServiceContext CreateServiceContext(DatabaseContext dbContext, IDatabaseFactory dbFactory)
{
//use a request based messaging factory
var evtMsgs = new RequestLifespanMessagesFactory(new SingletonUmbracoContextAccessor());
return new ServiceContext(
new RepositoryFactory(ApplicationCache, ProfilingLogger.Logger, dbContext.SqlSyntax, UmbracoConfig.For.UmbracoSettings()),
new PetaPocoUnitOfWorkProvider(dbFactory),
new FileUnitOfWorkProvider(),
new PublishingStrategy(),
new PublishingStrategy(evtMsgs, ProfilingLogger.Logger),
ApplicationCache,
ProfilingLogger.Logger,
//use a request based messaging factory
new RequestLifespanMessagesFactory(new SingletonUmbracoContextAccessor()));
evtMsgs);
}
/// <summary>
+2 -2
View File
@@ -29,11 +29,11 @@
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.0.1" newVersion="4.0.0.1" />
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" culture="neutral" />
+3 -4
View File
@@ -8,14 +8,13 @@
<package id="Lucene.Net" version="2.9.4.1" targetFramework="net45" />
<package id="Microsoft.AspNet.Identity.Core" version="2.2.1" targetFramework="net45" />
<package id="Microsoft.AspNet.Identity.Owin" version="2.2.1" targetFramework="net45" />
<package id="Microsoft.AspNet.Mvc" version="4.0.40804.0" targetFramework="net45" />
<package id="Microsoft.AspNet.Mvc.FixedDisplayModes" version="1.0.1" targetFramework="net45" />
<package id="Microsoft.AspNet.Razor" version="2.0.30506.0" targetFramework="net45" />
<package id="Microsoft.AspNet.Mvc" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.Razor" version="3.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Core" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.WebHost" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebPages" version="2.0.30506.0" targetFramework="net45" />
<package id="Microsoft.AspNet.WebPages" version="3.2.3" targetFramework="net45" />
<package id="Microsoft.Owin" version="3.0.1" targetFramework="net45" />
<package id="Microsoft.Owin.Host.SystemWeb" version="3.0.1" targetFramework="net45" />
<package id="Microsoft.Owin.Security" version="3.0.1" targetFramework="net45" />
@@ -93,6 +93,11 @@ namespace umbraco.presentation.webservices
throw new ArgumentException("User not logged in");
}
public void UpdateSortOrder(int ParentId, string SortOrder)
{
UpdateSortOrder(ParentId.ToString(), SortOrder);
}
[WebMethod]
public void UpdateSortOrder(string ParentId, string SortOrder)
{
+2 -2
View File
@@ -4,11 +4,11 @@
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.0.1" newVersion="4.0.0.1" />
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
+2 -2
View File
@@ -8,7 +8,7 @@
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" culture="neutral" />
@@ -16,7 +16,7 @@
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.0.1" newVersion="4.0.0.1" />
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="MiniProfiler" publicKeyToken="b44f9351044011a3" culture="neutral" />
+3 -3
View File
@@ -3,13 +3,13 @@
<package id="Examine" version="0.1.66.0" targetFramework="net45" />
<package id="HtmlAgilityPack" version="1.4.9" targetFramework="net45" />
<package id="Lucene.Net" version="2.9.4.1" targetFramework="net45" />
<package id="Microsoft.AspNet.Mvc" version="4.0.40804.0" targetFramework="net45" />
<package id="Microsoft.AspNet.Razor" version="2.0.30506.0" targetFramework="net45" />
<package id="Microsoft.AspNet.Mvc" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.Razor" version="3.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Core" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.WebHost" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebPages" version="2.0.30506.0" targetFramework="net45" />
<package id="Microsoft.AspNet.WebPages" version="3.2.3" targetFramework="net45" />
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net45" />
<package id="Newtonsoft.Json" version="6.0.8" targetFramework="net45" />
<package id="SharpZipLib" version="0.86.0" targetFramework="net45" />
@@ -80,9 +80,9 @@
</Reference>
<Reference Include="System.Net.Http.WebRequest" />
<Reference Include="System.Web" />
<Reference Include="System.Web.Helpers, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<Reference Include="System.Web.Helpers, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.Helpers.dll</HintPath>
<Private>True</Private>
<HintPath>..\packages\Microsoft.AspNet.WebPages.2.0.30506.0\lib\net40\System.Web.Helpers.dll</HintPath>
</Reference>
<Reference Include="System.Web.Http, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
@@ -92,25 +92,25 @@
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Microsoft.AspNet.WebApi.WebHost.5.2.3\lib\net45\System.Web.Http.WebHost.dll</HintPath>
</Reference>
<Reference Include="System.Web.Mvc, Version=4.0.0.1, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<Reference Include="System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.Mvc.5.2.3\lib\net45\System.Web.Mvc.dll</HintPath>
<Private>True</Private>
<HintPath>..\packages\Microsoft.AspNet.Mvc.4.0.40804.0\lib\net40\System.Web.Mvc.dll</HintPath>
</Reference>
<Reference Include="System.Web.Razor, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<Reference Include="System.Web.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.Razor.3.2.3\lib\net45\System.Web.Razor.dll</HintPath>
<Private>True</Private>
<HintPath>..\packages\Microsoft.AspNet.Razor.2.0.30506.0\lib\net40\System.Web.Razor.dll</HintPath>
</Reference>
<Reference Include="System.Web.WebPages, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<Reference Include="System.Web.WebPages, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.dll</HintPath>
<Private>True</Private>
<HintPath>..\packages\Microsoft.AspNet.WebPages.2.0.30506.0\lib\net40\System.Web.WebPages.dll</HintPath>
</Reference>
<Reference Include="System.Web.WebPages.Deployment, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<Reference Include="System.Web.WebPages.Deployment, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.Deployment.dll</HintPath>
<Private>True</Private>
<HintPath>..\packages\Microsoft.AspNet.WebPages.2.0.30506.0\lib\net40\System.Web.WebPages.Deployment.dll</HintPath>
</Reference>
<Reference Include="System.Web.WebPages.Razor, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<Reference Include="System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.Razor.dll</HintPath>
<Private>True</Private>
<HintPath>..\packages\Microsoft.AspNet.WebPages.2.0.30506.0\lib\net40\System.Web.WebPages.Razor.dll</HintPath>
</Reference>
<Reference Include="System.Xml.Linq" />
<Reference Include="Microsoft.CSharp" />
+2 -2
View File
@@ -4,11 +4,11 @@
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.0.1" newVersion="4.0.0.1" />
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
+4 -4
View File
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="AutoMapper" version="3.3.1" targetFramework="net45" />
<package id="Microsoft.AspNet.Mvc" version="4.0.40804.0" targetFramework="net45" />
<package id="Microsoft.AspNet.Razor" version="2.0.30506.0" targetFramework="net40" />
<package id="Microsoft.AspNet.WebPages" version="2.0.30506.0" targetFramework="net40" />
<package id="Microsoft.AspNet.Mvc" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.Razor" version="3.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebPages" version="3.2.3" targetFramework="net45" />
<package id="Microsoft.Owin" version="3.0.1" targetFramework="net45" />
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net40" />
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net4" />
<package id="Owin" version="1.0" targetFramework="net45" />
</packages>
@@ -140,29 +140,29 @@
<Reference Include="System.Web.Extensions">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Web.Helpers, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<Reference Include="System.Web.Helpers, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.Helpers.dll</HintPath>
<Private>True</Private>
<HintPath>..\packages\Microsoft.AspNet.WebPages.2.0.30506.0\lib\net40\System.Web.Helpers.dll</HintPath>
</Reference>
<Reference Include="System.Web.Mvc, Version=4.0.0.1, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<Reference Include="System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.Mvc.5.2.3\lib\net45\System.Web.Mvc.dll</HintPath>
<Private>True</Private>
<HintPath>..\packages\Microsoft.AspNet.Mvc.4.0.40804.0\lib\net40\System.Web.Mvc.dll</HintPath>
</Reference>
<Reference Include="System.Web.Razor, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<Reference Include="System.Web.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.Razor.3.2.3\lib\net45\System.Web.Razor.dll</HintPath>
<Private>True</Private>
<HintPath>..\packages\Microsoft.AspNet.Razor.2.0.30506.0\lib\net40\System.Web.Razor.dll</HintPath>
</Reference>
<Reference Include="System.Web.WebPages, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<Reference Include="System.Web.WebPages, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.dll</HintPath>
<Private>True</Private>
<HintPath>..\packages\Microsoft.AspNet.WebPages.2.0.30506.0\lib\net40\System.Web.WebPages.dll</HintPath>
</Reference>
<Reference Include="System.Web.WebPages.Deployment, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<Reference Include="System.Web.WebPages.Deployment, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.Deployment.dll</HintPath>
<Private>True</Private>
<HintPath>..\packages\Microsoft.AspNet.WebPages.2.0.30506.0\lib\net40\System.Web.WebPages.Deployment.dll</HintPath>
</Reference>
<Reference Include="System.Web.WebPages.Razor, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<Reference Include="System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.Razor.dll</HintPath>
<Private>True</Private>
<HintPath>..\packages\Microsoft.AspNet.WebPages.2.0.30506.0\lib\net40\System.Web.WebPages.Razor.dll</HintPath>
</Reference>
<Reference Include="System.Xml">
<Name>System.XML</Name>
+2 -2
View File
@@ -4,11 +4,11 @@
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.0.1" newVersion="4.0.0.1" />
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
+2 -2
View File
@@ -4,11 +4,11 @@
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.0.1" newVersion="4.0.0.1" />
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
+2 -2
View File
@@ -4,11 +4,11 @@
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.0.1" newVersion="4.0.0.1" />
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" culture="neutral" />
+2 -2
View File
@@ -4,11 +4,11 @@
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.0.1" newVersion="4.0.0.1" />
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />