Compare commits

...

30 Commits

Author SHA1 Message Date
Sebastiaan Janssen 389b29599b U4-9495 ImageProcessor high CPU usage when trimCache=true 2017-02-07 10:29:11 +01:00
Shannon f816a63b54 Ok, reverting the correct commit this time: Revert "Fixes database context issue during startup when there is no db configured" 2017-02-07 12:49:26 +11:00
Shannon fa8f3985b8 Fixes database context issue during startup when there is no db configured 2017-02-07 12:33:37 +11:00
Mikkel Holck Madsen 175c785705 Merge pull request #1722 from umbraco/temp-U4-9458
Changes IndexFieldPolicies to be a StaticFieldCollection which is a k…
2017-02-06 21:45:54 +01:00
Mikkel Holck Madsen 72aebd3ecf Merge branch 'dev-v7' into temp-U4-9458 2017-02-06 21:44:26 +01:00
Mikkel Holck Madsen 802cbb82c4 Merge pull request #1723 from umbraco/temp-U4-9448
U4-9448 Slave Front End server requires write access to database when…
2017-02-06 15:01:30 +01:00
Mikkel Holck Madsen 42f5507fe8 Merge pull request #1734 from umbraco/temp-U4-9492
U4-9492 Update to latest ImageProcessor
2017-02-06 14:39:01 +01:00
Sebastiaan Janssen 5a8e37f5b4 U4-9492 Update to latest ImageProcessor 2017-02-06 13:46:10 +01:00
Shannon Deminick 3c7d3b2f63 Merge pull request #1724 from umbraco/temp-installer-url-update
Update NewInstallStep.cs
2017-02-06 19:42:23 +11:00
Shannon d598fdce54 Updates to latest Examine release 2017-02-03 12:03:56 +11:00
hartvig 32892cf5e0 Update NewInstallStep.cs 2017-02-02 10:05:14 +01:00
Shannon 882d5ec7f5 missing null check 2017-02-02 16:02:29 +11:00
Shannon ce69497a68 Update code to have zero breaking changes for old public APIs 2017-02-02 14:16:39 +11:00
Shannon 1d43cf491b U4-9448 Slave Front End server requires write access to database when master performs unpublish 2017-02-02 14:09:49 +11:00
Shannon 27283754c0 Changes IndexFieldPolicies to be a StaticFieldCollection which is a keyed collection instead of using Linq and iterating to find the values in critical code 2017-02-01 16:48:09 +11:00
Shannon 5b2212829c Small performance change which makes a fairly large impact when rebuilding very large indexes. 2017-02-01 13:02:22 +11:00
Morten Christensen 546209ddb5 Merge pull request #1716 from umbraco/temp-U4-9451
U4-9451 Package installation custom user control is not displayed aft…
2017-01-31 12:24:52 +01:00
Shannon 54bda6f12a U4-9451 Package installation custom user control is not displayed after a package is installed 2017-01-31 15:40:02 +11:00
Sebastiaan Janssen 690af8e494 Merge pull request #1711 from umbraco/temp-U4-9444
U4-9444 SessionState is not available when rendering macro contents i…
2017-01-30 10:00:40 +01:00
Shannon 9d06ce53a4 U4-9444 SessionState is not available when rendering macro contents in the Rich Text Editor 2017-01-30 13:22:47 +11:00
Claus daa80a7bf6 Merge pull request #1709 from umbraco/temp-U4-9435-2
U4-9435 Fix breaking change made in U4-9312
2017-01-27 09:05:47 +01:00
Shannon 8152e7cb92 Doh, forgot a file change for tests - fixes build 2017-01-27 16:55:29 +11:00
Shannon Deminick adccb4161e Merge pull request #1707 from umbraco/temp-u4-9438
U4-9438 - fix nasty issue with reading properties in VersionableRepos…
2017-01-27 16:52:10 +11:00
Shannon 72a0187295 Writes unit test to confirm the correct property data iteration in GetPropertyCollection 2017-01-27 16:50:44 +11:00
Shannon 24d6287918 Adds string overloads just in case 2017-01-27 16:21:01 +11:00
Shannon 55900a3464 Updates MediaController and MediaTypeController to have the same method signature supporting both INT and GUID with a custom action selector to handle the ambiguity 2017-01-27 16:09:35 +11:00
Sebastiaan Janssen 36e9bb4d78 Merge pull request #1705 from umbraco/temp-v758-recyclebin-fix
Fixes U4-9437
2017-01-26 17:31:31 +01:00
Sebastiaan Janssen 639d04381e Bump version 2017-01-26 14:48:19 +01:00
Stephan 7f905bce0e U4-9438 - fix nasty issue with reading properties in VersionableRepositoryBase 2017-01-26 11:49:52 +01:00
Niels Hartvig 205ea22daa Fixes U4-9437 2017-01-25 17:34:34 +01:00
42 changed files with 527 additions and 191 deletions
+2 -2
View File
@@ -33,8 +33,8 @@
<dependency id="AutoMapper" version="[3.3.1, 4.0.0)" />
<dependency id="Newtonsoft.Json" version="[6.0.8, 10.0.0)" />
<dependency id="Examine" version="[0.1.80, 1.0.0)" />
<dependency id="ImageProcessor" version="[2.5.1, 3.0.0)" />
<dependency id="ImageProcessor.Web" version="[4.8.0, 5.0.0)" />
<dependency id="ImageProcessor" version="[2.5.2, 3.0.0)" />
<dependency id="ImageProcessor.Web" version="[4.8.2, 5.0.0)" />
<dependency id="semver" version="[1.1.2, 2.0.0)" />
<dependency id="UrlRewritingNet" version="[2.0.7, 3.0.0)" />
<!-- Markdown can not be updated due to: https://github.com/hey-red/markdownsharp/issues/71#issuecomment-233585487 -->
+1
View File
@@ -45,6 +45,7 @@
<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="tools\processing.config.install.xdt" target="Content\Config\imageprocessor\processing.config.install.xdt" />
<file src="tools\cache.config.install.xdt" target="Content\Config\imageprocessor\cache.config.install.xdt" />
<file src="build\**" target="build" />
</files>
</package>
@@ -0,0 +1,6 @@
<?xml version="1.0"?>
<caching xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<caches>
<cache name="DiskCache" trimCache="false" xdt:Transform="SetAttributes(trimCache)" xdt:Locator="Match(name)" />
</caches>
</caching>
+1 -1
View File
@@ -1,2 +1,2 @@
# Usage: on line 2 put the release version, on line 3 put the version comment (example: beta)
7.5.8
7.5.9
+2 -2
View File
@@ -11,5 +11,5 @@ using System.Resources;
[assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyFileVersion("7.5.8")]
[assembly: AssemblyInformationalVersion("7.5.8")]
[assembly: AssemblyFileVersion("7.5.9")]
[assembly: AssemblyInformationalVersion("7.5.9")]
@@ -6,7 +6,7 @@ namespace Umbraco.Core.Configuration
{
public class UmbracoVersion
{
private static readonly Version Version = new Version("7.5.8");
private static readonly Version Version = new Version("7.5.9");
/// <summary>
/// Gets the current version of Umbraco.
@@ -163,7 +163,7 @@ namespace Umbraco.Core.Persistence.Repositories
//each order by param needs to be in a bracket! see: https://github.com/toptensoftware/PetaPoco/issues/177
query.OrderBy(orderBy == null
? "(umbracoNode.id)"
? "(umbracoNode.id)"
: string.Join(",", orderBy.Select(x => string.Format("({0})", SqlSyntax.GetQuotedColumnName(x)))));
var pagedResult = Database.Page<ContentXmlDto>(pageIndex + 1, pageSize, query);
@@ -461,14 +461,14 @@ namespace Umbraco.Core.Persistence.Repositories
totalRecords = Convert.ToInt32(pagedResult.TotalItems);
//NOTE: We need to check the actual items returned, not the 'totalRecords', that is because if you request a page number
// that doesn't actually have any data on it, the totalRecords will still indicate there are records but there are none in
// that doesn't actually have any data on it, the totalRecords will still indicate there are records but there are none in
// the pageResult, then the GetAll will actually return ALL records in the db.
if (pagedResult.Items.Any())
{
//Crete the inner paged query that was used above to get the paged result, we'll use that as the inner sub query
var args = sqlNodeIdsWithSort.Arguments;
string sqlStringCount, sqlStringPage;
Database.BuildPageQueries<TDto>(pageIndex * pageSize, pageSize, sqlNodeIdsWithSort.SQL, ref args, out sqlStringCount, out sqlStringPage);
Database.BuildPageQueries<TDto>(pageIndex * pageSize, pageSize, sqlNodeIdsWithSort.SQL, ref args, out sqlStringCount, out sqlStringPage);
//We need to make this FULL query an inner join on the paged ID query
var splitQuery = sqlQueryFull.SQL.Split(new[] { "WHERE " }, StringSplitOptions.None);
@@ -502,7 +502,7 @@ namespace Umbraco.Core.Persistence.Repositories
{
if (documentDefs.Count == 0) return new Dictionary<int, PropertyCollection>();
//we need to parse the original SQL statement and reduce the columns to just cmsContent.nodeId, cmsContentVersion.VersionId so that we can use
//we need to parse the original SQL statement and reduce the columns to just cmsContent.nodeId, cmsContentVersion.VersionId so that we can use
// the statement to go get the property data for all of the items by using an inner join
var parsedOriginalSql = "SELECT {0} " + docSql.SQL.Substring(docSql.SQL.IndexOf("FROM", StringComparison.Ordinal));
//now remove everything from an Orderby clause and beyond
@@ -513,7 +513,7 @@ namespace Umbraco.Core.Persistence.Repositories
//This retrieves all pre-values for all data types that are referenced for all property types
// that exist in the data set.
//Benchmarks show that eagerly loading these so that we can lazily read the property data
//Benchmarks show that eagerly loading these so that we can lazily read the property data
// below (with the use of Query intead of Fetch) go about 30% faster, so we'll eagerly load
// this now since we cannot execute another reader inside of reading the property data.
var preValsSql = new Sql(@"SELECT a.id, a.value, a.sortorder, a.alias, a.datatypeNodeId
@@ -532,11 +532,11 @@ WHERE EXISTS(
//It's Important with the sort order here! We require this to be sorted by node id,
// this is required because this data set can be huge depending on the page size. Due
// to it's size we need to be smart about iterating over the property values to build
// the document. Before we used to use Linq to get the property data for a given content node
// to it's size we need to be smart about iterating over the property values to build
// the document. Before we used to use Linq to get the property data for a given content node
// and perform a Distinct() call. This kills performance because that would mean if we had 7000 nodes
// and on each iteration we will perform a lookup on potentially 100,000 property rows against the node
// id which turns out to be a crazy amount of iterations. Instead we know it's sorted by this value we'll
// id which turns out to be a crazy amount of iterations. Instead we know it's sorted by this value we'll
// keep an index stored of the rows being read so we never have to re-iterate the entire data set
// on each document iteration.
var propSql = new Sql(@"SELECT cmsPropertyData.*
@@ -562,6 +562,7 @@ ORDER BY contentNodeId, propertytypeid
//keep track of the current property data item being enumerated
var propertyDataSetEnumerator = allPropertyData.GetEnumerator();
var hasCurrent = false; // initially there is no enumerator.Current
try
{
@@ -569,7 +570,7 @@ ORDER BY contentNodeId, propertytypeid
// which allows us to more efficiently iterate over the large data set of property values
foreach (var def in documentDefs.OrderBy(x => x.Id))
{
//get the resolved proeprties from our local cache, or resolve them and put them in cache
// get the resolved properties from our local cache, or resolve them and put them in cache
PropertyType[] compositionProperties;
if (resolvedCompositionProperties.ContainsKey(def.Composition.Id))
{
@@ -581,28 +582,20 @@ ORDER BY contentNodeId, propertytypeid
resolvedCompositionProperties[def.Composition.Id] = compositionProperties;
}
// assemble the dtos for this def
// use the available enumerator.Current if any else move to next
var propertyDataDtos = new List<PropertyDataDto>();
//Check if there is a current enumerated item and check if we match and add it
if (propertyDataSetEnumerator.Current != null)
{
if (propertyDataSetEnumerator.Current.NodeId == def.Id)
{
propertyDataDtos.Add(propertyDataSetEnumerator.Current);
}
}
//Move to the next position, see if we match and add it, if not exit
while (propertyDataSetEnumerator.MoveNext())
while (hasCurrent || propertyDataSetEnumerator.MoveNext())
{
if (propertyDataSetEnumerator.Current.NodeId == def.Id)
{
hasCurrent = false; // enumerator.Current is not available
propertyDataDtos.Add(propertyDataSetEnumerator.Current);
}
else
{
//the node id has changed so we need to exit the loop,
//the enumerator position will be maintained
break;
hasCurrent = true; // enumerator.Current is available for another def
break; // no more propertyDataDto for this def
}
}
+3 -2
View File
@@ -49,8 +49,9 @@
<Reference Include="ICSharpCode.SharpZipLib, Version=0.86.0.518, Culture=neutral, PublicKeyToken=1b03e6acf1164f73, processorArchitecture=MSIL">
<HintPath>..\packages\SharpZipLib.0.86.0\lib\20\ICSharpCode.SharpZipLib.dll</HintPath>
</Reference>
<Reference Include="ImageProcessor, Version=2.5.1.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\ImageProcessor.2.5.1\lib\net45\ImageProcessor.dll</HintPath>
<Reference Include="ImageProcessor, Version=2.5.2.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\ImageProcessor.2.5.2\lib\net45\ImageProcessor.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="log4net, Version=1.2.11.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\log4net-mediumtrust.2.0.0\lib\log4net.dll</HintPath>
+1 -1
View File
@@ -2,7 +2,7 @@
<packages>
<package id="AutoMapper" version="3.3.1" targetFramework="net45" />
<package id="HtmlAgilityPack" version="1.4.9" targetFramework="net45" />
<package id="ImageProcessor" version="2.5.1" targetFramework="net45" />
<package id="ImageProcessor" version="2.5.2" targetFramework="net45" />
<package id="log4net-mediumtrust" version="2.0.0" 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" />
@@ -67,6 +67,66 @@ namespace Umbraco.Tests.Persistence.Repositories
return repository;
}
/// <summary>
/// This tests the regression issue of U4-9438
/// </summary>
/// <remarks>
/// The problem was the iteration of the property data in VersionableRepositoryBase when a content item
/// in the list actually doesn't have any property types, it would still skip over a property row.
/// To test, we have 3 content items, the first has properties, the second doesn't and the third does.
/// </remarks>
[Test]
public void Property_Data_Assigned_Correctly()
{
// Arrange
var provider = new PetaPocoUnitOfWorkProvider(Logger);
var unitOfWork = provider.GetUnitOfWork();
ContentTypeRepository contentTypeRepository;
var allContent = new List<IContent>();
using (var repository = CreateRepository(unitOfWork, out contentTypeRepository))
{
var emptyContentType = MockedContentTypes.CreateBasicContentType();
var hasPropertiesContentType = MockedContentTypes.CreateSimpleContentType("umbTextpage1", "Textpage");
var content1 = MockedContent.CreateSimpleContent(hasPropertiesContentType);
var content2 = MockedContent.CreateBasicContent(emptyContentType);
var content3 = MockedContent.CreateSimpleContent(hasPropertiesContentType);
// Act
contentTypeRepository.AddOrUpdate(emptyContentType);
contentTypeRepository.AddOrUpdate(hasPropertiesContentType);
repository.AddOrUpdate(content1);
repository.AddOrUpdate(content2);
repository.AddOrUpdate(content3);
unitOfWork.Commit();
allContent.Add(content1);
allContent.Add(content2);
allContent.Add(content3);
}
// Assert
using (var repository = CreateRepository(unitOfWork, out contentTypeRepository))
{
//this will cause the GetPropertyCollection to execute and we need to ensure that
// all of the properties and property types are all correct
var result = repository.GetAll(allContent.Select(x => x.Id).ToArray()).ToArray();
foreach (var content in result)
{
foreach (var contentProperty in content.Properties)
{
//prior to the fix, the 2nd document iteration in the GetPropertyCollection would have caused
//the enumerator to move forward past the first property of the 3rd document which would have
//ended up not assiging a property to the 3rd document. This would have ended up with the 3rd
//document still having 3 properties but the last one would not have been assigned an identity
//because the property data would not have been assigned.
Assert.IsTrue(contentProperty.HasIdentity);
}
}
}
}
[Test]
public void Rebuild_Xml_Structures_With_Non_Latest_Version()
{
@@ -6,9 +6,18 @@ namespace Umbraco.Tests.TestHelpers.Entities
{
public class MockedContent
{
public static Content CreateBasicContent(IContentType contentType)
{
var content = new Content("Home", -1, contentType) { Level = 1, SortOrder = 1, CreatorId = 0, WriterId = 0 };
content.ResetDirtyProperties(false);
return content;
}
public static Content CreateSimpleContent(IContentType contentType)
{
var content = new Content("Home", -1, contentType) { Language = "en-US", Level = 1, SortOrder = 1, CreatorId = 0, WriterId = 0 };
var content = new Content("Home", -1, contentType) { Level = 1, SortOrder = 1, CreatorId = 0, WriterId = 0 };
object obj =
new
{
@@ -26,7 +35,7 @@ namespace Umbraco.Tests.TestHelpers.Entities
public static Content CreateSimpleContent(IContentType contentType, string name, int parentId)
{
var content = new Content(name, parentId, contentType) { Language = "en-US", CreatorId = 0, WriterId = 0 };
var content = new Content(name, parentId, contentType) { CreatorId = 0, WriterId = 0 };
object obj =
new
{
@@ -44,7 +53,7 @@ namespace Umbraco.Tests.TestHelpers.Entities
public static Content CreateSimpleContent(IContentType contentType, string name, IContent parent)
{
var content = new Content(name, parent, contentType) { Language = "en-US", CreatorId = 0, WriterId = 0 };
var content = new Content(name, parent, contentType) { CreatorId = 0, WriterId = 0 };
object obj =
new
{
@@ -62,7 +71,7 @@ namespace Umbraco.Tests.TestHelpers.Entities
public static Content CreateTextpageContent(IContentType contentType, string name, int parentId)
{
var content = new Content(name, parentId, contentType) { Language = "en-US", CreatorId = 0, WriterId = 0};
var content = new Content(name, parentId, contentType) { CreatorId = 0, WriterId = 0};
object obj =
new
{
@@ -81,7 +90,7 @@ namespace Umbraco.Tests.TestHelpers.Entities
public static Content CreateSimpleContentWithSpecialDatabaseTypes(IContentType contentType, string name, int parentId, string decimalValue, string intValue, DateTime datetimeValue)
{
var content = new Content(name, parentId, contentType) { Language = "en-US", CreatorId = 0, WriterId = 0 };
var content = new Content(name, parentId, contentType) { CreatorId = 0, WriterId = 0 };
object obj = new
{
decimalProperty = decimalValue,
@@ -96,7 +105,7 @@ namespace Umbraco.Tests.TestHelpers.Entities
public static Content CreateAllTypesContent(IContentType contentType, string name, int parentId)
{
var content = new Content("Random Content Name", parentId, contentType) { Language = "en-US", Level = 1, SortOrder = 1, CreatorId = 0, WriterId = 0 };
var content = new Content("Random Content Name", parentId, contentType) { Level = 1, SortOrder = 1, CreatorId = 0, WriterId = 0 };
content.SetValue("isTrue", true);
content.SetValue("number", 42);
@@ -130,7 +139,7 @@ namespace Umbraco.Tests.TestHelpers.Entities
for (int i = 0; i < amount; i++)
{
var name = "Textpage No-" + i;
var content = new Content(name, parentId, contentType) { Language = "en-US", CreatorId = 0, WriterId = 0 };
var content = new Content(name, parentId, contentType) { CreatorId = 0, WriterId = 0 };
object obj =
new
{
@@ -7,6 +7,13 @@ namespace Umbraco.Tests.TestHelpers.Entities
{
public class MockedContentTypes
{
/// <summary>
/// Creates a content type without any properties
/// </summary>
/// <param name="alias"></param>
/// <param name="name"></param>
/// <param name="parent"></param>
/// <returns></returns>
public static ContentType CreateBasicContentType(string alias = "basePage", string name = "Base Page",
ContentType parent = null)
{
+2 -3
View File
@@ -57,9 +57,8 @@
<Reference Include="AutoMapper.Net4, Version=3.3.1.0, Culture=neutral, PublicKeyToken=be96cd2c38ef1005, processorArchitecture=MSIL">
<HintPath>..\packages\AutoMapper.3.3.1\lib\net40\AutoMapper.Net4.dll</HintPath>
</Reference>
<Reference Include="Examine, Version=0.1.80.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Examine.0.1.80\lib\net45\Examine.dll</HintPath>
<Private>True</Private>
<Reference Include="Examine, Version=0.1.81.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Examine.0.1.81\lib\net45\Examine.dll</HintPath>
</Reference>
<Reference Include="ICSharpCode.SharpZipLib, Version=0.86.0.518, Culture=neutral, PublicKeyToken=1b03e6acf1164f73, processorArchitecture=MSIL">
<HintPath>..\packages\SharpZipLib.0.86.0\lib\20\ICSharpCode.SharpZipLib.dll</HintPath>
+1 -1
View File
@@ -2,7 +2,7 @@
<packages>
<package id="AspNetWebApi.SelfHost" version="4.0.20710.0" targetFramework="net45" />
<package id="AutoMapper" version="3.3.1" targetFramework="net45" />
<package id="Examine" version="0.1.80" targetFramework="net45" />
<package id="Examine" version="0.1.81" 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="5.2.3" targetFramework="net45" />
@@ -204,7 +204,7 @@ angular.module('umbraco.services')
//when it's successful, return the user data
setCurrentUser(data);
var result = { user: data, authenticated: true, lastUserId: lastUserId };
var result = { user: data, authenticated: true, lastUserId: lastUserId, loginType: "credentials" };
//broadcast a global event
eventsService.emit("app.authenticated", result);
@@ -232,7 +232,7 @@ angular.module('umbraco.services')
authResource.getCurrentUser()
.then(function (data) {
var result = { user: data, authenticated: true, lastUserId: lastUserId };
var result = { user: data, authenticated: true, lastUserId: lastUserId, loginType: "implicit" };
//TODO: This is a mega backwards compatibility hack... These variables SHOULD NOT exist in the server variables
// since they are not supposed to be dynamic but I accidentally added them there in 7.1.5 IIRC so some people might
@@ -8,7 +8,7 @@
* The main application controller
*
*/
function MainController($scope, $rootScope, $location, $routeParams, $timeout, $http, $log, appState, treeService, notificationsService, userService, navigationService, historyService, updateChecker, assetsService, eventsService, umbRequestHelper, tmhDynamicLocale) {
function MainController($scope, $rootScope, $location, $routeParams, $timeout, $http, $log, appState, treeService, notificationsService, userService, navigationService, historyService, updateChecker, assetsService, eventsService, umbRequestHelper, tmhDynamicLocale, localStorageService) {
//the null is important because we do an explicit bool check on this in the view
//the avatar is by default the umbraco logo
@@ -81,6 +81,14 @@ function MainController($scope, $rootScope, $location, $routeParams, $timeout, $
$location.path("/").search("");
historyService.removeAll();
treeService.clearCache();
//if the user changed, clearout local storage too - could contain sensitive data
localStorageService.clearAll();
}
//if this is a new login (i.e. the user entered credentials), then clear out local storage - could contain sensitive data
if (data.loginType === "credentials") {
localStorageService.clearAll();
}
//Load locale file
+1 -5
View File
@@ -13,11 +13,7 @@ app.run(['userService', '$log', '$rootScope', '$location', 'navigationService',
/** Listens for authentication and checks if our required assets are loaded, if/once they are we'll broadcast a ready event */
eventsService.on("app.authenticated", function(evt, data) {
//Removes all stored LocalStorage browser items - that may contain sensitive data
//So if a machine or computer is shared and a new user logs in, we clear out the previous persons localStorage items
localStorageService.clearAll();
assetsService._loadInitAssets().then(function() {
appState.setGlobalState("isReady", true);
+11 -10
View File
@@ -127,19 +127,19 @@
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\dotless.1.4.1.0\lib\dotless.Core.dll</HintPath>
</Reference>
<Reference Include="Examine, Version=0.1.80.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Examine.0.1.80\lib\net45\Examine.dll</HintPath>
<Private>True</Private>
<Reference Include="Examine, Version=0.1.81.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Examine.0.1.81\lib\net45\Examine.dll</HintPath>
</Reference>
<Reference Include="ICSharpCode.SharpZipLib, Version=0.86.0.518, Culture=neutral, PublicKeyToken=1b03e6acf1164f73, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\SharpZipLib.0.86.0\lib\20\ICSharpCode.SharpZipLib.dll</HintPath>
</Reference>
<Reference Include="ImageProcessor, Version=2.5.1.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\ImageProcessor.2.5.1\lib\net45\ImageProcessor.dll</HintPath>
<Reference Include="ImageProcessor, Version=2.5.2.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\ImageProcessor.2.5.2\lib\net45\ImageProcessor.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="ImageProcessor.Web, Version=4.8.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\ImageProcessor.Web.4.8.0\lib\net45\ImageProcessor.Web.dll</HintPath>
<Reference Include="ImageProcessor.Web, Version=4.8.2.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\ImageProcessor.Web.4.8.2\lib\net45\ImageProcessor.Web.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="log4net, Version=1.2.11.0, Culture=neutral, processorArchitecture=MSIL">
@@ -168,7 +168,8 @@
</Reference>
<Reference Include="Microsoft.CSharp" />
<Reference Include="Microsoft.IO.RecyclableMemoryStream, Version=1.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.IO.RecyclableMemoryStream.1.2.0\lib\net45\Microsoft.IO.RecyclableMemoryStream.dll</HintPath>
<HintPath>..\packages\Microsoft.IO.RecyclableMemoryStream.1.2.1\lib\net45\Microsoft.IO.RecyclableMemoryStream.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Owin">
<HintPath>..\packages\Microsoft.Owin.3.0.1\lib\net45\Microsoft.Owin.dll</HintPath>
@@ -2422,9 +2423,9 @@ xcopy "$(ProjectDir)"..\packages\SqlServerCE.4.0.0.1\x86\*.* "$(TargetDir)x86\"
<WebProjectProperties>
<UseIIS>True</UseIIS>
<AutoAssignPort>True</AutoAssignPort>
<DevelopmentServerPort>7580</DevelopmentServerPort>
<DevelopmentServerPort>7590</DevelopmentServerPort>
<DevelopmentServerVPath>/</DevelopmentServerVPath>
<IISUrl>http://localhost:7580</IISUrl>
<IISUrl>http://localhost:7590</IISUrl>
<NTLMAuthentication>False</NTLMAuthentication>
<UseCustomServer>False</UseCustomServer>
<CustomServerUrl>
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<caching currentCache="DiskCache">
<caches>
<cache name="DiskCache" type="ImageProcessor.Web.Caching.DiskCache, ImageProcessor.Web" maxDays="365" browserMaxDays="7">
<cache name="DiskCache" type="ImageProcessor.Web.Caching.DiskCache, ImageProcessor.Web" maxDays="365" browserMaxDays="7" trimCache="false">
<settings>
<setting key="VirtualCachePath" value="~/app_data/cache" />
</settings>
+4 -4
View File
@@ -4,9 +4,9 @@
<package id="ClientDependency" version="1.9.2" 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.80" targetFramework="net45" />
<package id="ImageProcessor" version="2.5.1" targetFramework="net45" />
<package id="ImageProcessor.Web" version="4.8.0" targetFramework="net45" />
<package id="Examine" version="0.1.81" targetFramework="net45" />
<package id="ImageProcessor" version="2.5.2" targetFramework="net45" />
<package id="ImageProcessor.Web" version="4.8.2" targetFramework="net45" />
<package id="ImageProcessor.Web.Config" version="2.3.0" targetFramework="net45" />
<package id="log4net-mediumtrust" version="2.0.0" targetFramework="net45" />
<package id="Lucene.Net" version="2.9.4.1" targetFramework="net45" />
@@ -22,7 +22,7 @@
<package id="Microsoft.CodeAnalysis.Analyzers" version="1.0.0" targetFramework="net45" />
<package id="Microsoft.CodeAnalysis.Common" version="1.0.0" targetFramework="net45" />
<package id="Microsoft.CodeAnalysis.CSharp" version="1.0.0" targetFramework="net45" />
<package id="Microsoft.IO.RecyclableMemoryStream" version="1.2.0" targetFramework="net45" />
<package id="Microsoft.IO.RecyclableMemoryStream" version="1.2.1" 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" />
+2 -2
View File
@@ -74,7 +74,7 @@ namespace Umbraco.Web.Cache
public override void Remove(int id)
{
ApplicationContext.Current.ApplicationCache.ClearPartialViewCache();
content.Instance.ClearDocumentCache(id);
content.Instance.ClearDocumentCache(id, false);
DistributedCache.Instance.ClearAllMacroCacheOnCurrentServer();
DistributedCache.Instance.ClearXsltCacheOnCurrentServer();
ClearAllIsolatedCacheByEntityType<PublicAccessEntry>();
@@ -95,7 +95,7 @@ namespace Umbraco.Web.Cache
public override void Remove(IContent instance)
{
ApplicationContext.Current.ApplicationCache.ClearPartialViewCache();
content.Instance.ClearDocumentCache(new Document(instance));
content.Instance.ClearDocumentCache(new Document(instance), false);
XmlPublishedContent.ClearRequest();
DistributedCache.Instance.ClearAllMacroCacheOnCurrentServer();
DistributedCache.Instance.ClearXsltCacheOnCurrentServer();
@@ -262,7 +262,7 @@ namespace Umbraco.Web.Editors
},
{
"mediaTypeApiBaseUrl", Url.GetUmbracoApiServiceBaseUrl<MediaTypeController>(
controller => controller.GetAllowedChildren("0"))
controller => controller.GetAllowedChildren(0))
},
{
"macroApiBaseUrl", Url.GetUmbracoApiServiceBaseUrl<MacroController>(
+9 -4
View File
@@ -4,21 +4,26 @@ using System.Net;
using System.Net.Http;
using System.Text;
using System.Web.Http;
using System.Web.SessionState;
using AutoMapper;
using Umbraco.Web.Models.ContentEditing;
using Umbraco.Web.Mvc;
using umbraco;
using Umbraco.Core;
namespace Umbraco.Web.Editors
{
/// <summary>
/// API controller to deal with Macro data
/// </summary>
/// <remarks>
/// Note that this implements IRequiresSessionState which will enable HttpContext.Session - generally speaking we don't normally
/// enable this for webapi controllers, however since this controller is used to render macro content and macros can access
/// Session, we don't want it to throw null reference exceptions.
/// </remarks>
[PluginController("UmbracoApi")]
public class MacroController : UmbracoAuthorizedJsonController
public class MacroController : UmbracoAuthorizedJsonController, IRequiresSessionState
{
/// <summary>
/// Gets the macro parameters to be filled in for a particular macro
/// </summary>
@@ -124,6 +129,6 @@ namespace Umbraco.Web.Editors
"text/html");
return result;
}
}
}
+70 -33
View File
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Net;
using System.Net.Http;
@@ -27,6 +28,7 @@ using Umbraco.Web.Mvc;
using Umbraco.Web.WebApi;
using System.Linq;
using System.Runtime.Serialization;
using System.Web.Http.Controllers;
using Umbraco.Web.WebApi.Binders;
using Umbraco.Web.WebApi.Filters;
using umbraco;
@@ -45,9 +47,22 @@ namespace Umbraco.Web.Editors
/// access to ALL of the methods on this controller will need access to the media application.
/// </remarks>
[PluginController("UmbracoApi")]
[UmbracoApplicationAuthorizeAttribute(Constants.Applications.Media)]
[UmbracoApplicationAuthorize(Constants.Applications.Media)]
[MediaControllerControllerConfiguration]
public class MediaController : ContentControllerBase
{
/// <summary>
/// Configures this controller with a custom action selector
/// </summary>
private class MediaControllerControllerConfigurationAttribute : Attribute, IControllerConfiguration
{
public void Initialize(HttpControllerSettings controllerSettings, HttpControllerDescriptor controllerDescriptor)
{
controllerSettings.Services.Replace(typeof(IHttpActionSelector), new ParameterSwapControllerActionSelector(
new ParameterSwapControllerActionSelector.ParameterSwapInfo("GetChildren", "id", typeof(int), typeof(Guid), typeof(string))));
}
}
/// <summary>
/// Constructor
/// </summary>
@@ -173,40 +188,10 @@ namespace Umbraco.Web.Editors
}
/// <summary>
/// Returns the child media objects
/// Returns the child media objects - using the entity INT id
/// </summary>
[FilterAllowedOutgoingMedia(typeof(IEnumerable<ContentItemBasic<ContentPropertyBasic, IMedia>>), "Items")]
public PagedResult<ContentItemBasic<ContentPropertyBasic, IMedia>> GetChildren(string id,
int pageNumber = 0,
int pageSize = 0,
string orderBy = "SortOrder",
Direction orderDirection = Direction.Ascending,
bool orderBySystemField = true,
string filter = "")
{
int idInt; Guid idGuid;
if (Guid.TryParse(id, out idGuid))
{
var entity = Services.EntityService.GetByKey(idGuid);
if (entity != null)
{
return GetChildren(entity.Id, pageNumber, pageSize, orderBy, orderDirection, orderBySystemField, filter);
}
else
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
}
else if (int.TryParse(id, out idInt))
{
return GetChildren(idInt, pageNumber, pageSize, orderBy, orderDirection, orderBySystemField, filter);
}
throw new HttpResponseException(HttpStatusCode.NotFound);
}
private PagedResult<ContentItemBasic<ContentPropertyBasic, IMedia>> GetChildren(int id,
public PagedResult<ContentItemBasic<ContentPropertyBasic, IMedia>> GetChildren(int id,
int pageNumber = 0,
int pageSize = 0,
string orderBy = "SortOrder",
@@ -240,6 +225,58 @@ namespace Umbraco.Web.Editors
return pagedResult;
}
/// <summary>
/// Returns the child media objects - using the entity GUID id
/// </summary>
/// <param name="id"></param>
/// <param name="pageNumber"></param>
/// <param name="pageSize"></param>
/// <param name="orderBy"></param>
/// <param name="orderDirection"></param>
/// <param name="orderBySystemField"></param>
/// <param name="filter"></param>
/// <returns></returns>
[FilterAllowedOutgoingMedia(typeof(IEnumerable<ContentItemBasic<ContentPropertyBasic, IMedia>>), "Items")]
public PagedResult<ContentItemBasic<ContentPropertyBasic, IMedia>> GetChildren(Guid id,
int pageNumber = 0,
int pageSize = 0,
string orderBy = "SortOrder",
Direction orderDirection = Direction.Ascending,
bool orderBySystemField = true,
string filter = "")
{
var entity = Services.EntityService.GetByKey(id);
if (entity != null)
{
return GetChildren(entity.Id, pageNumber, pageSize, orderBy, orderDirection, orderBySystemField, filter);
}
throw new HttpResponseException(HttpStatusCode.NotFound);
}
[Obsolete("Do not use this method, use either the overload with INT or GUID instead, this will be removed in future versions")]
[EditorBrowsable(EditorBrowsableState.Never)]
[UmbracoTreeAuthorize(Constants.Trees.MediaTypes, Constants.Trees.Media)]
public PagedResult<ContentItemBasic<ContentPropertyBasic, IMedia>> GetChildren(string id,
int pageNumber = 0,
int pageSize = 0,
string orderBy = "SortOrder",
Direction orderDirection = Direction.Ascending,
bool orderBySystemField = true,
string filter = "")
{
foreach (var type in new[] { typeof(int), typeof(Guid) })
{
var parsed = id.TryConvertTo(type);
if (parsed)
{
//oooh magic! will auto select the right overload
return GetChildren((dynamic)parsed.Result);
}
}
throw new HttpResponseException(HttpStatusCode.NotFound);
}
/// <summary>
/// Moves an item to the recycle bin, if it is already there then it will permanently delete it
/// </summary>
+52 -17
View File
@@ -13,6 +13,9 @@ using Umbraco.Web.WebApi;
using Umbraco.Core.Services;
using Umbraco.Core.Models.EntityBase;
using System;
using System.ComponentModel;
using System.Web.Http.Controllers;
using Umbraco.Core;
namespace Umbraco.Web.Editors
{
@@ -26,8 +29,21 @@ namespace Umbraco.Web.Editors
[PluginController("UmbracoApi")]
[UmbracoTreeAuthorize(Constants.Trees.MediaTypes)]
[EnableOverrideAuthorization]
[MediaTypeControllerControllerConfigurationAttribute]
public class MediaTypeController : ContentTypeControllerBase
{
/// <summary>
/// Configures this controller with a custom action selector
/// </summary>
private class MediaTypeControllerControllerConfigurationAttribute : Attribute, IControllerConfiguration
{
public void Initialize(HttpControllerSettings controllerSettings, HttpControllerDescriptor controllerDescriptor)
{
controllerSettings.Services.Replace(typeof(IHttpActionSelector), new ParameterSwapControllerActionSelector(
new ParameterSwapControllerActionSelector.ParameterSwapInfo("GetAllowedChildren", "contentId", typeof(int), typeof(Guid), typeof(string))));
}
}
/// <summary>
/// Constructor
/// </summary>
@@ -172,26 +188,11 @@ namespace Umbraco.Web.Editors
/// <summary>
/// Returns the allowed child content type objects for the content item id passed in
/// Returns the allowed child content type objects for the content item id passed in - based on an INT id
/// </summary>
/// <param name="contentId"></param>
[UmbracoTreeAuthorize(Constants.Trees.MediaTypes, Constants.Trees.Media)]
public IEnumerable<ContentTypeBasic> GetAllowedChildren(string contentId)
{
Guid idGuid = Guid.Empty;
int idInt;
if (Guid.TryParse(contentId, out idGuid)) {
var entity = ApplicationContext.Services.EntityService.GetByKey(idGuid);
return GetAllowedChildrenInternal(entity.Id);
} else if (int.TryParse(contentId, out idInt))
{
return GetAllowedChildrenInternal(idInt);
}
throw new HttpResponseException(HttpStatusCode.NotFound);
}
private IEnumerable<ContentTypeBasic> GetAllowedChildrenInternal(int contentId)
public IEnumerable<ContentTypeBasic> GetAllowedChildren(int contentId)
{
if (contentId == Constants.System.RecycleBinContent)
return Enumerable.Empty<ContentTypeBasic>();
@@ -231,6 +232,40 @@ namespace Umbraco.Web.Editors
return basics;
}
/// <summary>
/// Returns the allowed child content type objects for the content item id passed in - based on a GUID id
/// </summary>
/// <param name="contentId"></param>
[UmbracoTreeAuthorize(Constants.Trees.MediaTypes, Constants.Trees.Media)]
public IEnumerable<ContentTypeBasic> GetAllowedChildren(Guid contentId)
{
var entity = ApplicationContext.Services.EntityService.GetByKey(contentId);
if (entity != null)
{
return GetAllowedChildren(entity.Id);
}
throw new HttpResponseException(HttpStatusCode.NotFound);
}
[Obsolete("Do not use this method, use either the overload with INT or GUID instead, this will be removed in future versions")]
[EditorBrowsable(EditorBrowsableState.Never)]
[UmbracoTreeAuthorize(Constants.Trees.MediaTypes, Constants.Trees.Media)]
public IEnumerable<ContentTypeBasic> GetAllowedChildren(string contentId)
{
foreach (var type in new[] { typeof(int), typeof(Guid) })
{
var parsed = contentId.TryConvertTo(type);
if (parsed)
{
//oooh magic! will auto select the right overload
return GetAllowedChildren((dynamic)parsed.Result);
}
}
throw new HttpResponseException(HttpStatusCode.NotFound);
}
/// <summary>
/// Move the media type
/// </summary>
@@ -0,0 +1,84 @@
using System;
using System.Linq;
using System.Web;
using System.Web.Http.Controllers;
using Umbraco.Core;
namespace Umbraco.Web.Editors
{
/// <summary>
/// This is used to auto-select specific actions on controllers that would otherwise be ambiguous based on a single parameter type
/// </summary>
/// <remarks>
/// As an example, lets say we have 2 methods: GetChildren(int id) and GetChildren(Guid id), by default Web Api won't allow this since
/// it won't know what to select, but if this Tuple is passed in new Tuple{string, string}("GetChildren", "id")
/// </remarks>
internal class ParameterSwapControllerActionSelector : ApiControllerActionSelector
{
private readonly ParameterSwapInfo[] _actions;
/// <summary>
/// Constructor accepting a list of action name + parameter name
/// </summary>
/// <param name="actions"></param>
public ParameterSwapControllerActionSelector(params ParameterSwapInfo[] actions)
{
_actions = actions;
}
public override HttpActionDescriptor SelectAction(HttpControllerContext controllerContext)
{
var found = _actions.FirstOrDefault(x => controllerContext.Request.RequestUri.GetLeftPart(UriPartial.Path).InvariantEndsWith(x.ActionName));
if (found != null)
{
var id = HttpUtility.ParseQueryString(controllerContext.Request.RequestUri.Query).Get(found.ParamName);
if (id != null)
{
var idTypes = found.SupportedTypes;
foreach (var idType in idTypes)
{
var converted = id.TryConvertTo(idType);
if (converted)
{
var method = MatchByType(idType, controllerContext, found);
if (method != null)
return method;
}
}
}
}
return base.SelectAction(controllerContext);
}
private static ReflectedHttpActionDescriptor MatchByType(Type idType, HttpControllerContext controllerContext, ParameterSwapInfo found)
{
var controllerType = controllerContext.Controller.GetType();
var methods = controllerType.GetMethods().Where(info => info.Name == found.ActionName).ToArray();
if (methods.Length > 1)
{
//choose the one that has the parameter with the T type
var method = methods.FirstOrDefault(x => x.GetParameters().FirstOrDefault(p => p.Name == found.ParamName && p.ParameterType == idType) != null);
return new ReflectedHttpActionDescriptor(controllerContext.ControllerDescriptor, method);
}
return null;
}
internal class ParameterSwapInfo
{
public string ActionName { get; private set; }
public string ParamName { get; private set; }
public Type[] SupportedTypes { get; private set; }
public ParameterSwapInfo(string actionName, string paramName, params Type[] supportedTypes)
{
ActionName = actionName;
ParamName = paramName;
SupportedTypes = supportedTypes;
}
}
}
}
@@ -81,7 +81,7 @@ namespace Umbraco.Web.Install.InstallSteps
{
var client = new System.Net.WebClient();
var values = new NameValueCollection { { "name", admin.Name }, { "email", admin.Email} };
client.UploadValues("https://umbraco.com/base/Ecom/SubmitEmail/installer.aspx", values);
client.UploadValues("https://shop.umbraco.com/base/Ecom/SubmitEmail/installer.aspx", values);
}
catch { /* fail in silence */ }
}
@@ -147,4 +147,4 @@ namespace Umbraco.Web.Install.InstallSteps
}
}
}
}
}
@@ -3,8 +3,10 @@ using System.Collections.Generic;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Routing;
using System.Web.SessionState;
using Umbraco.Core;
using Umbraco.Core.Configuration;
using Umbraco.Web.WebApi;
namespace Umbraco.Web.Mvc
{
@@ -93,6 +95,13 @@ namespace Umbraco.Web.Mvc
}
//look in this namespace to create the controller
controllerPluginRoute.DataTokens.Add("Namespaces", new[] {controllerType.Namespace});
//Special case! Check if the controller type implements IRequiresSessionState and if so use our
//custom webapi session handler
if (typeof(IRequiresSessionState).IsAssignableFrom(controllerType))
{
controllerPluginRoute.RouteHandler = new SessionHttpControllerRouteHandler();
}
}
//Don't look anywhere else except this namespace!
@@ -100,9 +109,9 @@ namespace Umbraco.Web.Mvc
//constraints: only match controllers ending with 'controllerSuffixName' and only match this controller's ID for this route
if (controllerSuffixName.IsNullOrWhiteSpace() == false)
{
controllerPluginRoute.Constraints = new RouteValueDictionary(
new Dictionary<string, object>
{
controllerPluginRoute.Constraints = new RouteValueDictionary(
new Dictionary<string, object>
{
{"controller", @"(\w+)" + controllerSuffixName}
});
@@ -125,9 +125,10 @@ namespace Umbraco.Web.Trees
// use helper method to ensure we support both integer and guid lookups
int iid;
// if it's the root node, we won't use the look up
if (id != "-1")
// look up from GUID if it's not an integer
if (int.TryParse(id, out iid) == false)
{
var idEntity = GetEntityFromId(id);
if (idEntity == null)
{
@@ -135,10 +136,6 @@ namespace Umbraco.Web.Trees
}
iid = idEntity.Id;
}
else
{
iid = int.Parse(id);
}
//if a request is made for the root node data but the user's start node is not the default, then
+4 -3
View File
@@ -112,9 +112,8 @@
<Reference Include="dotless.Core, Version=1.4.1.0, Culture=neutral, PublicKeyToken=96b446c9e63eae34, processorArchitecture=MSIL">
<HintPath>..\packages\dotless.1.4.1.0\lib\dotless.Core.dll</HintPath>
</Reference>
<Reference Include="Examine, Version=0.1.80.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Examine.0.1.80\lib\net45\Examine.dll</HintPath>
<Private>True</Private>
<Reference Include="Examine, Version=0.1.81.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Examine.0.1.81\lib\net45\Examine.dll</HintPath>
</Reference>
<Reference Include="HtmlAgilityPack, Version=1.4.9.0, Culture=neutral, PublicKeyToken=bd319b19eaf3b43a, processorArchitecture=MSIL">
<HintPath>..\packages\HtmlAgilityPack.1.4.9\lib\Net45\HtmlAgilityPack.dll</HintPath>
@@ -278,6 +277,7 @@
<Compile Include="Editors\EditorValidationResolver.cs" />
<Compile Include="Editors\EditorValidator.cs" />
<Compile Include="Editors\GravatarController.cs" />
<Compile Include="Editors\ParameterSwapControllerActionSelector.cs" />
<Compile Include="HealthCheck\Checks\Config\AbstractConfigCheck.cs" />
<Compile Include="HealthCheck\Checks\Config\AcceptableConfiguration.cs" />
<Compile Include="HealthCheck\Checks\Config\ConfigurationService.cs" />
@@ -956,6 +956,7 @@
<Compile Include="WebApi\NamespaceHttpControllerSelector.cs" />
<Compile Include="WebApi\PrefixlessBodyModelValidator.cs" />
<Compile Include="WebApi\PrefixlessBodyModelValidatorAttribute.cs" />
<Compile Include="WebApi\SessionHttpControllerRouteHandler.cs" />
<Compile Include="WebApi\UmbracoApiController.cs" />
<Compile Include="WebApi\UmbracoApiControllerBase.cs" />
<Compile Include="WebApi\UmbracoApiControllerResolver.cs" />
@@ -0,0 +1,31 @@
using System.Web;
using System.Web.Http.WebHost;
using System.Web.Routing;
using System.Web.SessionState;
namespace Umbraco.Web.WebApi
{
/// <summary>
/// A custom WebApi route handler that enables session on the HttpContext - use with caution!
/// </summary>
/// <remarks>
/// WebApi controllers (and REST in general) shouldn't have session state enabled since it's stateless,
/// enabling session state puts additional locks on requests so only use this when absolutley needed
/// </remarks>
internal class SessionHttpControllerRouteHandler : HttpControllerRouteHandler
{
protected override IHttpHandler GetHttpHandler(RequestContext requestContext)
{
return new SessionHttpControllerHandler(requestContext.RouteData);
}
/// <summary>
/// A custom WebApi handler that enables session on the HttpContext
/// </summary>
private class SessionHttpControllerHandler : HttpControllerHandler, IRequiresSessionState
{
public SessionHttpControllerHandler(RouteData routeData) : base(routeData)
{ }
}
}
}
+1 -1
View File
@@ -3,7 +3,7 @@
<package id="AutoMapper" version="3.3.1" targetFramework="net45" />
<package id="ClientDependency" version="1.9.2" targetFramework="net45" />
<package id="dotless" version="1.4.1.0" targetFramework="net45" />
<package id="Examine" version="0.1.80" targetFramework="net45" />
<package id="Examine" version="0.1.81" targetFramework="net45" />
<package id="HtmlAgilityPack" version="1.4.9" targetFramework="net45" />
<package id="Lucene.Net" version="2.9.4.1" targetFramework="net45" />
<package id="Markdown" version="1.14.7" targetFramework="net45" />
@@ -394,6 +394,11 @@ namespace umbraco
}
public virtual void ClearDocumentCache(int documentId)
{
ClearDocumentCache(documentId, true);
}
internal virtual void ClearDocumentCache(int documentId, bool removeDbXmlEntry)
{
// Get the document
Document d;
@@ -408,7 +413,7 @@ namespace umbraco
ClearDocumentXmlCache(documentId);
return;
}
ClearDocumentCache(d);
ClearDocumentCache(d, removeDbXmlEntry);
}
/// <summary>
@@ -416,7 +421,8 @@ namespace umbraco
/// This means the node gets unpublished from the website.
/// </summary>
/// <param name="doc">The document</param>
internal void ClearDocumentCache(Document doc)
/// <param name="removeDbXmlEntry"></param>
internal void ClearDocumentCache(Document doc, bool removeDbXmlEntry)
{
var e = new DocumentCacheEventArgs();
FireBeforeClearDocumentCache(doc, e);
@@ -425,8 +431,13 @@ namespace umbraco
{
XmlNode x;
// remove from xml db cache
doc.XmlRemoveFromDB();
//Hack: this is here purely for backwards compat if someone for some reason is using the
// ClearDocumentCache(int documentId) method and expecting it to remove the xml
if (removeDbXmlEntry)
{
// remove from xml db cache
doc.XmlRemoveFromDB();
}
// clear xml cache
ClearDocumentXmlCache(doc.Id);
@@ -14,7 +14,7 @@ namespace UmbracoExamine.Config
public static class IndexSetExtensions
{
internal static IIndexCriteria ToIndexCriteria(this IndexSet set, IDataService svc,
IEnumerable<StaticField> indexFieldPolicies)
StaticFieldCollection indexFieldPolicies)
{
return new LazyIndexCriteria(set, svc, indexFieldPolicies);
}
@@ -29,7 +29,7 @@ namespace UmbracoExamine.Config
/// <returns></returns>
public static IIndexCriteria ToIndexCriteria(this IndexSet set, IDataService svc)
{
return set.ToIndexCriteria(svc, Enumerable.Empty<StaticField>());
return set.ToIndexCriteria(svc, new StaticFieldCollection());
}
}
@@ -12,7 +12,7 @@ namespace UmbracoExamine.Config
public LazyIndexCriteria(
IndexSet set,
IDataService svc,
IEnumerable<StaticField> indexFieldPolicies)
StaticFieldCollection indexFieldPolicies)
{
if (set == null) throw new ArgumentNullException("set");
if (indexFieldPolicies == null) throw new ArgumentNullException("indexFieldPolicies");
@@ -35,8 +35,9 @@ namespace UmbracoExamine.Config
foreach (var u in userProps)
{
var field = new IndexField() { Name = u };
var policy = indexFieldPolicies.FirstOrDefault(x => x.Name == u);
if (policy != null)
StaticField policy;
if (indexFieldPolicies.TryGetValue(u, out policy))
{
field.Type = policy.Type;
field.EnableSorting = policy.EnableSorting;
@@ -55,8 +56,9 @@ namespace UmbracoExamine.Config
foreach (var s in sysProps)
{
var field = new IndexField() { Name = s };
var policy = indexFieldPolicies.FirstOrDefault(x => x.Name == s);
if (policy != null)
StaticField policy;
if (indexFieldPolicies.TryGetValue(s, out policy))
{
field.Type = policy.Type;
field.EnableSorting = policy.EnableSorting;
@@ -0,0 +1,28 @@
using System.Collections.ObjectModel;
namespace UmbracoExamine
{
internal class StaticFieldCollection : KeyedCollection<string, StaticField>
{
protected override string GetKeyForItem(StaticField item)
{
return item.Name;
}
/// <summary>
/// Implements TryGetValue using the underlying dictionary
/// </summary>
/// <param name="key"></param>
/// <param name="field"></param>
/// <returns></returns>
public bool TryGetValue(string key, out StaticField field)
{
if (Dictionary == null)
{
field = null;
return false;
}
return Dictionary.TryGetValue(key, out field);
}
}
}
+39 -30
View File
@@ -196,27 +196,27 @@ namespace UmbracoExamine
/// Alot of standard umbraco fields shouldn't be tokenized or even indexed, just stored into lucene
/// for retreival after searching.
/// </summary>
internal static readonly List<StaticField> IndexFieldPolicies
= new List<StaticField>
internal static readonly StaticFieldCollection IndexFieldPolicies
= new StaticFieldCollection
{
new StaticField("id", FieldIndexTypes.NOT_ANALYZED, false, string.Empty),
new StaticField("key", FieldIndexTypes.NOT_ANALYZED, false, string.Empty),
new StaticField( "version", FieldIndexTypes.NOT_ANALYZED, false, string.Empty),
new StaticField( "parentID", FieldIndexTypes.NOT_ANALYZED, false, string.Empty),
new StaticField( "level", FieldIndexTypes.NOT_ANALYZED, true, "NUMBER"),
new StaticField( "writerID", FieldIndexTypes.NOT_ANALYZED, false, string.Empty),
new StaticField( "creatorID", FieldIndexTypes.NOT_ANALYZED, false, string.Empty),
new StaticField( "nodeType", FieldIndexTypes.NOT_ANALYZED, false, string.Empty),
new StaticField( "template", FieldIndexTypes.NOT_ANALYZED, false, string.Empty),
new StaticField( "sortOrder", FieldIndexTypes.NOT_ANALYZED, true, "NUMBER"),
new StaticField( "createDate", FieldIndexTypes.NOT_ANALYZED, false, "DATETIME"),
new StaticField( "updateDate", FieldIndexTypes.NOT_ANALYZED, false, "DATETIME"),
new StaticField( "nodeName", FieldIndexTypes.ANALYZED, false, string.Empty),
new StaticField( "urlName", FieldIndexTypes.NOT_ANALYZED, false, string.Empty),
new StaticField( "writerName", FieldIndexTypes.ANALYZED, false, string.Empty),
new StaticField( "creatorName", FieldIndexTypes.ANALYZED, false, string.Empty),
new StaticField( "nodeTypeAlias", FieldIndexTypes.ANALYZED, false, string.Empty),
new StaticField( "path", FieldIndexTypes.NOT_ANALYZED, false, string.Empty)
new StaticField("version", FieldIndexTypes.NOT_ANALYZED, false, string.Empty),
new StaticField("parentID", FieldIndexTypes.NOT_ANALYZED, false, string.Empty),
new StaticField("level", FieldIndexTypes.NOT_ANALYZED, true, "NUMBER"),
new StaticField("writerID", FieldIndexTypes.NOT_ANALYZED, false, string.Empty),
new StaticField("creatorID", FieldIndexTypes.NOT_ANALYZED, false, string.Empty),
new StaticField("nodeType", FieldIndexTypes.NOT_ANALYZED, false, string.Empty),
new StaticField("template", FieldIndexTypes.NOT_ANALYZED, false, string.Empty),
new StaticField("sortOrder", FieldIndexTypes.NOT_ANALYZED, true, "NUMBER"),
new StaticField("createDate", FieldIndexTypes.NOT_ANALYZED, false, "DATETIME"),
new StaticField("updateDate", FieldIndexTypes.NOT_ANALYZED, false, "DATETIME"),
new StaticField("nodeName", FieldIndexTypes.ANALYZED, false, string.Empty),
new StaticField("urlName", FieldIndexTypes.NOT_ANALYZED, false, string.Empty),
new StaticField("writerName", FieldIndexTypes.ANALYZED, false, string.Empty),
new StaticField("creatorName", FieldIndexTypes.ANALYZED, false, string.Empty),
new StaticField("nodeTypeAlias", FieldIndexTypes.ANALYZED, false, string.Empty),
new StaticField("path", FieldIndexTypes.NOT_ANALYZED, false, string.Empty)
};
#endregion
@@ -709,15 +709,16 @@ namespace UmbracoExamine
// Get all user data that we want to index and store into a dictionary
foreach (var field in IndexerData.UserFields)
{
if (e.Fields.ContainsKey(field.Name))
string fieldVal;
if (e.Fields.TryGetValue(field.Name, out fieldVal))
{
//check if the field value has html
if (XmlHelper.CouldItBeXml(e.Fields[field.Name]))
if (XmlHelper.CouldItBeXml(fieldVal))
{
//First save the raw value to a raw field, we will change the policy of this field by detecting the prefix later
e.Fields[RawFieldPrefix + field.Name] = e.Fields[field.Name];
e.Fields[RawFieldPrefix + field.Name] = fieldVal;
//now replace the original value with the stripped html
e.Fields[field.Name] = DataService.ContentService.StripHtml(e.Fields[field.Name]);
e.Fields[field.Name] = DataService.ContentService.StripHtml(fieldVal);
}
}
}
@@ -803,9 +804,13 @@ namespace UmbracoExamine
/// <param name="fieldName"></param>
/// <returns></returns>
protected override FieldIndexTypes GetPolicy(string fieldName)
{
var def = IndexFieldPolicies.Where(x => x.Name == fieldName).ToArray();
return (def.Any() == false ? FieldIndexTypes.ANALYZED : def.Single().IndexType);
{
StaticField def;
if (IndexFieldPolicies.TryGetValue(fieldName, out def))
{
return def.IndexType;
}
return FieldIndexTypes.ANALYZED;
}
/// <summary>
@@ -815,14 +820,18 @@ namespace UmbracoExamine
/// </summary>
protected override bool ValidateDocument(XElement node)
{
var nodeId = int.Parse(node.Attribute("id").Value);
// Test for access if we're only indexing published content
// return nothing if we're not supporting protected content and it is protected, and we're not supporting unpublished content
if (!SupportUnpublishedContent
&& (!SupportProtectedContent
&& DataService.ContentService.IsProtected(nodeId, node.Attribute("path").Value)))
if (SupportUnpublishedContent == false
&& SupportProtectedContent == false)
{
return false;
var nodeId = int.Parse(node.Attribute("id").Value);
if (DataService.ContentService.IsProtected(nodeId, node.Attribute("path").Value))
{
return false;
}
}
return base.ValidateDocument(node);
}
+3 -3
View File
@@ -82,9 +82,8 @@
<AssemblyOriginatorKeyFile>..\Solution Items\TheFARM-Public.snk</AssemblyOriginatorKeyFile>
</PropertyGroup>
<ItemGroup>
<Reference Include="Examine, Version=0.1.80.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Examine.0.1.80\lib\net45\Examine.dll</HintPath>
<Private>True</Private>
<Reference Include="Examine, Version=0.1.81.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Examine.0.1.81\lib\net45\Examine.dll</HintPath>
</Reference>
<Reference Include="ICSharpCode.SharpZipLib, Version=0.86.0.518, Culture=neutral, PublicKeyToken=1b03e6acf1164f73, processorArchitecture=MSIL">
<HintPath>..\packages\SharpZipLib.0.86.0\lib\20\ICSharpCode.SharpZipLib.dll</HintPath>
@@ -134,6 +133,7 @@
<Compile Include="LocalStorage\MultiIndexOutput.cs" />
<Compile Include="LoggingLevel.cs" />
<Compile Include="StaticField.cs" />
<Compile Include="StaticFieldCollection.cs" />
<Compile Include="UmbracoMemberIndexer.cs" />
<Compile Include="ContentExtensions.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
+11 -4
View File
@@ -117,8 +117,9 @@ namespace UmbracoExamine
if (indexerData.UserFields.Any(x => x.Name == "_searchEmail") == false)
{
var field = new IndexField { Name = "_searchEmail" };
var policy = IndexFieldPolicies.FirstOrDefault(x => x.Name == "_searchEmail");
if (policy != null)
StaticField policy;
if (IndexFieldPolicies.TryGetValue("_searchEmail", out policy))
{
field.Type = policy.Type;
field.EnableSorting = policy.EnableSorting;
@@ -237,10 +238,16 @@ namespace UmbracoExamine
{
var fields = base.GetSpecialFieldsToIndex(allValuesForIndexing);
//adds the special path property to the index
//adds the special key property to the index
string valuesForIndexing;
if (allValuesForIndexing.TryGetValue("__key", out valuesForIndexing))
fields.Add("__key", valuesForIndexing);
{
if (fields.ContainsKey("__key") == false)
{
fields.Add("__key", valuesForIndexing);
}
}
return fields;
+1 -1
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Examine" version="0.1.80" targetFramework="net45" />
<package id="Examine" version="0.1.81" targetFramework="net45" />
<package id="Lucene.Net" version="2.9.4.1" targetFramework="net45" />
<package id="SharpZipLib" version="0.86.0" targetFramework="net45" />
</packages>
+1 -1
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Examine" version="0.1.80" targetFramework="net45" />
<package id="Examine" version="0.1.81" 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="5.2.3" targetFramework="net45" />
@@ -45,9 +45,8 @@
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Reference Include="Examine, Version=0.1.80.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Examine.0.1.80\lib\net45\Examine.dll</HintPath>
<Private>True</Private>
<Reference Include="Examine, Version=0.1.81.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Examine.0.1.81\lib\net45\Examine.dll</HintPath>
</Reference>
<Reference Include="HtmlAgilityPack, Version=1.4.9.0, Culture=neutral, PublicKeyToken=bd319b19eaf3b43a, processorArchitecture=MSIL">
<HintPath>..\packages\HtmlAgilityPack.1.4.9\lib\Net45\HtmlAgilityPack.dll</HintPath>