Compare commits

..

144 Commits

Author SHA1 Message Date
mikkelhm 67e2c911f7 Re adds the umbraco.presentation.targets for Umbraco.Web.UI as it handles default transormations for confg files 2017-05-09 00:26:40 +02:00
mikkelhm 36e60c774f Bump version to 7.6.1 2017-05-08 14:06:03 +02:00
mikkelhm 745252341f Merge branch 'dev-v7' into dev-v7.6
# Conflicts:
#	src/Umbraco.Core/Persistence/Migrations/MigrationBase.cs
#	src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagegravity.directive.js
2017-05-08 13:58:08 +02:00
Mikkel Holck Madsen a2df4c5232 Merge pull request #1933 from umbraco/temp-U4-9864
U4-9864 Missing import and xss check in other PermissionEditor.aspx
2017-05-08 10:29:03 +02:00
Shannon Deminick d012d8e8b6 Merge pull request #1925 from SaDa1337/dev-v7
fixed console error on media picker
2017-05-08 17:11:28 +10:00
Mikkel Holck Madsen 9318da2883 Merge pull request #1931 from umbraco/temp-U4-9849-2
U4-9849 Query Builder not working in template editor. Always returns …
2017-05-08 09:05:29 +02:00
Shannon Deminick a08849f60a Merge pull request #1935 from jamescoxhead/U4-9869
Fix typo error in upgrade installer
2017-05-08 13:40:36 +10:00
Shannon Deminick 9792d8df25 Merge pull request #1930 from TomSteer/U4-9852
Change Context to be public on MigrationBase
2017-05-08 13:39:06 +10:00
Shannon Deminick 635cfe6b20 Merge pull request #1932 from dawoe/patch-1
Return empty string when e-mail is not filled
2017-05-08 13:37:48 +10:00
James Coxhead 9ccf7bdbab Fix typo error in upgrade installer
Changed "your" to "you're"
2017-05-07 16:22:54 +01:00
Sebastiaan Janssen 0c520f2b43 Merge branch 'dev-v7' into dev-v7.6
# Conflicts:
#	build/Build.bat
2017-05-05 16:19:54 +02:00
Sebastiaan Janssen 85d10014c2 Make new build work when there's spaces in the current path 2017-05-05 16:14:59 +02:00
Claus 3c4b3f44c7 U4-9864 Missing import and xss check in other PermissionEditor.aspx 2017-05-05 14:52:01 +02:00
Sebastiaan Janssen c6956b5e98 Merge branch 'dev-v7' into dev-v7.6
# Conflicts:
#	.gitignore
#	build/Build.bat
2017-05-05 14:30:08 +02:00
Sebastiaan Janssen fcf5ecc166 Uses vswhere to figure out where VS17 is installed (if needed)
Removes targets file that was almost unused, moved the relevant bits to the main csproj
Updates BuildBelle.bat to be completely independent of installed version of node & npm on the machine
2017-05-05 14:14:37 +02:00
Dave Woestenborghs c5c87ff50d Return empty string when e-mail is not filled
Fix for http://issues.umbraco.org/issue/U4-9862
2017-05-05 13:27:32 +02:00
Stephan eb949e2cbc Fix UdiString to escape paths 2017-05-05 12:46:20 +02:00
Claus 8a096cd826 Merge pull request #1794 from TheBekker/fix-U4-9038
[fix-U4-9038] get and set media start node for mediaPickerOverlay in …
2017-05-05 10:51:31 +02:00
Claus 3b236ba724 Merge pull request #1794 from TheBekker/fix-U4-9038
[fix-U4-9038] get and set media start node for mediaPickerOverlay in …
2017-05-05 10:47:52 +02:00
Claus e7eaf6959f U4-9849 Query Builder not working in template editor. Always returns Model.Content.Site().Children()
adding missing nullchecks in the endpoint action.
ensuring promise returns before setting init data - the unresolved promise was being used on the query model instead of the actual text string the promise returns - causing the endpoint to fail to bind the model.
2017-05-04 15:08:37 +02:00
Tom Steer 3e294e290b Change Context to be public on MigrationBase 2017-05-04 09:10:35 +01:00
Shannon Deminick 751dc8df23 Merge pull request #1926 from avatart0ph/dev-v7.6
fix Add basic xss prevention logic
2017-05-04 11:05:49 +10:00
Morten Christensen 91047182fa Merge pull request #1929 from umbraco/temp-U4-9704
U4-9704 Sorting UDI media picker items, makes it store Int's
2017-05-03 13:20:25 +02:00
Claus 1030fd5294 U4-9704 Sorting UDI media picker items, makes it store Int's 2017-05-03 10:21:00 +02:00
Denise Michelle del Bando be2eb3f555 fix Add basic xss prevention logic
missing import on CleanForXss
2017-05-02 23:16:32 -04:00
Maciej Sadowski 0eafa14246 fixed console error on media picker 2017-05-02 15:36:39 +02:00
Shannon c1853e8c51 bumps version to 7.6.0 rtm 2017-05-02 13:42:20 +10:00
Shannon 31c965ae42 Merge remote-tracking branch 'origin/dev-v7' into dev-v7.6 2017-05-02 13:41:03 +10:00
Shannon Deminick d91fc6ce60 Merge pull request #1887 from umbraco/temp-U4-9775
U4-9775 AlreadyClosedException is thrown when retrieving media if the…
2017-05-02 13:40:28 +10:00
Shannon d5124e9739 Ensures that an UmbracoContext exist before emitting the cache handler events 2017-05-01 21:10:22 +10:00
Shannon d9b507c947 bumps version to RC4 so we can build new dependencies against forms/deploy 2017-04-30 23:26:04 +10:00
Shannon d3fcdfb176 updates nuget semver ref in nuspec 2017-04-30 23:24:26 +10:00
Shannon 2479c5a272 updates other nuget refs that shouldnt be there 2017-04-30 23:21:19 +10:00
Shannon fee071db22 Merge branch 'dev-v7.6' of https://github.com/umbraco/Umbraco-CMS into dev-v7.6 2017-04-30 23:20:16 +10:00
Shannon 004e00599d Fixing nuget package issues , semver 2 is only for 452+ which we dont have, we shouldnt be using it and it adds more dependencies that we don't need right now 2017-04-30 23:19:45 +10:00
Morten Christensen 2e2e8b43b0 Merge pull request #1917 from Frozire/patch-1
Edit DA with minor spelling and compound word changes
2017-04-30 14:05:14 +02:00
Morten Christensen e77c5f8667 Keep the Concierge Product name 2017-04-30 14:04:00 +02:00
Shannon Deminick 3509a2c40f Merge pull request #1908 from umbraco/temp-scope-events-stale-entities
POC to normalize all event entities when we track events so that all …
2017-04-30 19:28:19 +10:00
Shannon 378d0f7939 chagnes test params to be slightly less hacky 2017-04-30 19:21:13 +10:00
Shannon d64fa7f92d Fixes tests, ensures we null check when generating hashes for items in a collection 2017-04-30 19:14:36 +10:00
Stephan ea14170272 minor cleanup 2017-04-30 10:14:48 +02:00
Shannon 73209d7e2c Merge branch 'dev-v7' into dev-v7.6 2017-04-30 17:13:14 +10:00
Shannon Deminick cf8ead62ac Merge pull request #1904 from jwoods1/patch-2
Fixed issue on line 216
2017-04-30 17:11:44 +10:00
Shannon Deminick 8461aea7d8 Merge pull request #1907 from wanddy/dev-v7
Improve Chinese translation.
2017-04-30 17:10:58 +10:00
Shannon Deminick 034de1651b Merge pull request #1910 from abryukhov/patch-9
ru.xml - Missing newest area & key from en.xml
2017-04-30 17:09:30 +10:00
Shannon Deminick dcb8aa7e56 Merge pull request #1909 from abryukhov/patch-8
en_us.xml - Missing newest area & key from en.xml
2017-04-30 17:09:15 +10:00
Shannon Deminick e8a52a95da Merge pull request #1914 from dawoe/patch-1
Added dutch translation for usernameHint
2017-04-30 17:08:42 +10:00
Shannon Deminick 42c99e0f07 Merge pull request #1916 from stelim/patch-1
Adding login hint to German language file
2017-04-30 17:08:29 +10:00
Shannon Deminick a31b368b60 Merge pull request #1919 from NathalieLarsson/patch-1
Adding login hint to Swedish language file
2017-04-30 17:05:29 +10:00
Shannon Deminick 77f6d28a74 Merge pull request #1920 from camaya/patch-1
Add Spanish translation for usernameHint
2017-04-30 17:04:56 +10:00
Shannon Deminick 0b8d3ef214 Merge pull request #1921 from mikecp/patch-1
Adding login hint to French language file
2017-04-30 17:04:44 +10:00
Shannon Deminick a4f83f9c00 Merge pull request #1922 from abryukhov/patch-10
Adding 'usernameHint' key to ru.xml lang file
2017-04-30 17:04:30 +10:00
Shannon Deminick 85467976ad Merge pull request #1913 from umbraco/temp-U4-9824-v76
Change username to email in login dialog
2017-04-30 17:04:16 +10:00
Alexander Bryukhov d7e93fe466 Adding 'usernameHint' key to ru.xml lang file 2017-04-30 11:56:47 +07:00
Sebastiaan Janssen 660f048b4f U4-9812 FailedLoginAttempts should be reset to 0 after a successfull login attempt
(cherry picked from commit 3242b31a8a)
2017-04-29 10:22:57 +02:00
Sebastiaan Janssen 9fa76a0133 Merge pull request #1911 from umbraco/temp-U4-9812
U4-9812 FailedLoginAttempts should be reset to 0 after a successfull …
2017-04-29 10:19:26 +02:00
Michael Latouche 444c444f0e Adding login hint to French language file 2017-04-29 00:03:57 +02:00
Cristhian Amaya 383bbbe7e0 Add Spanish translation for usernameHint 2017-04-28 15:19:27 -05:00
Stephan 72eddca3c6 Merge branch 'dev-v7.6' into temp-scope-events-stale-entities 2017-04-28 19:19:36 +02:00
Nicklas Kevin Frank 7c2ddde311 Fixed typo in Dokumenttype 2017-04-28 17:24:43 +02:00
Nathalie Festin c6229e4fcb Adding login hint to Swedish language file
Added usernamehint to placeholders
2017-04-28 15:44:46 +02:00
Nicklas Kevin Frank fbac0aba8b Update da.xml with translation for concierge 2017-04-28 14:56:57 +02:00
Nicklas Kevin Frank f01511c592 Edit DA with minor spelling and compound word changes 2017-04-28 14:48:32 +02:00
Stefan Limbacher 187354f0bd Adding login hint to German language file 2017-04-28 14:29:13 +02:00
Dave Woestenborghs 2f540b1bfa Translated the usually part 2017-04-28 14:25:21 +02:00
Dave Woestenborghs b1f104d1de Changed it to be more consisten
Changed to be more consistent with other dutch translations
2017-04-28 14:24:10 +02:00
Dave Woestenborghs ba5fcad09a Added dutch translation for usernameHint 2017-04-28 14:17:51 +02:00
Niels Hartvig d553eb2978 Change it back to username and then with a hint for email (for backwards compat.) 2017-04-28 13:57:29 +02:00
Niels Hartvig d1e6c0e835 Change username to email in login dialog 2017-04-28 13:37:19 +02:00
Stephan 244977dc95 packages - trace errors 2017-04-28 13:34:35 +02:00
Sebastiaan Janssen 3242b31a8a U4-9812 FailedLoginAttempts should be reset to 0 after a successfull login attempt 2017-04-28 12:46:58 +02:00
Stephan efc3261163 scope - dont break 2017-04-28 11:43:48 +02:00
Stephan 8c6aa9875d scope - dont rename 2017-04-28 11:26:41 +02:00
Stephan f89ce1ff26 scope - cleanup 2017-04-28 10:58:57 +02:00
Shannon 1274fbaefd Fixes up the equality members for the event args types to include Gethash code and sequence equal checking, this is done by a base class used by event args that deal with collections. 2017-04-28 18:14:50 +10:00
Shannon 8140dfdc04 ads notes 2017-04-28 16:57:13 +10:00
Shannon a69eba61c8 Fixes detecting enumerable and ensures that the event is added to the result if we can't cast to IEntity 2017-04-28 14:54:08 +10:00
Alexander Bryukhov 46078a841c Missing newest area & key from en.xml 2017-04-28 11:43:50 +07:00
Alexander Bryukhov 0eb5e5f6e4 Missing newest area & key from en.xml 2017-04-28 11:41:20 +07:00
Shannon ec9020f63e Fixes mappings 2017-04-28 13:34:32 +10:00
Shannon 0b61685fc8 Adds ability to supersede events so we don't have an issue of saved event being raised for an entity after it's been deleted. 2017-04-28 13:26:56 +10:00
Shannon 3779b3c782 Updates base entities to contain a DeletedDate if the entity gets deleted 2017-04-28 11:15:19 +10:00
Shannon 5b0e824301 Merge branch 'dev-v7.6' into temp-scope-events-stale-entities 2017-04-28 10:32:01 +10:00
Shannon d24b0aa9eb oops undeletes a couple files that are still needed for the custom package ascx page 2017-04-28 10:30:47 +10:00
Shannon 9cd7e09986 POC to normalize all event entities when we track events so that all args contain the latest (non stale) entity 2017-04-28 10:04:43 +10:00
Shannon 9f505a7976 bumps to rc3 version 2017-04-28 08:27:31 +10:00
Jason Woods f737004544 Removed space before svalue 2017-04-27 16:13:41 -06:00
Jason Woods 850e354b11 wrapped all values in double quotes
Wrapped image src and crop values in double quotes to keep consistent across all saves and updates.
2017-04-27 16:03:45 -06:00
Shannon 1b27114014 Merge branch 'temp-CON-1267' into dev-v7.6 2017-04-28 07:53:16 +10:00
Shannon Deminick d8b235ad62 Merge pull request #1906 from umbraco/temp-CON-1267
CON-1267 Update Our to not offer v6 to people on < 7.6.0
2017-04-28 07:52:19 +10:00
Shannon 56581478c8 Merge remote-tracking branch 'origin/dev-v7' into temp-CON-1267 2017-04-28 07:48:04 +10:00
Shannon 2be330d237 adds notes, changes to protected 2017-04-28 07:45:01 +10:00
Shannon 4381a700ba Updates UmbracoVirtualNodeRouteHandler to have a new protected GetUmbracoContext method used to get the umb context used in the rest of the code 2017-04-28 07:38:03 +10:00
Shannon 99821954f1 adds notes 2017-04-28 07:31:44 +10:00
Shannon Deminick 10a15be8ad Merge pull request #1901 from tompipe/U4-9384-StaleVariableFix
Quick/simple fix for the stale variable
2017-04-28 07:28:00 +10:00
wanddy 0a2830aece Improve Chinese translation.
Signed-off-by: wanddy <wanddy@163.com>
2017-04-27 22:59:17 +08:00
Stephan d1094eea7a Merge pull request #1905 from umbraco/temp-tasks
Publicize more IBackgroundTask plumbing
2017-04-27 14:46:33 +02:00
Shannon c629a50f39 Fixes entity service and figuring out which GUID to go with which object type 2017-04-27 13:29:31 +10:00
Shannon 430f906ae6 Merge remote-tracking branch 'origin/dev-v7.6' into temp-CON-1267 2017-04-27 13:28:34 +10:00
Shannon 736798c769 Merge remote-tracking branch 'origin/dev-v7' into temp-CON-1267
# Conflicts:
#	src/Umbraco.Core/Exceptions/ConnectionException.cs
#	src/Umbraco.Core/Services/PackagingService.cs
#	src/Umbraco.Web/Editors/PackageInstallController.cs
2017-04-27 13:27:23 +10:00
Shannon e913034d93 Changes PackagingService to not have a different base class since it was not needed 2017-04-27 13:21:56 +10:00
Shannon bed5f8a03b backports updates from 7.6 so that the packages.umbraco.org endpoint is not used for fetching package files any longer 2017-04-27 13:21:07 +10:00
Stephan 0291ab615d Fix shadow wrapper cleanup 2017-04-26 17:38:06 +02:00
Stephan ceeea7827e Fix shadow wrapper cleanup 2017-04-26 14:44:48 +02:00
Shannon 756b4d24c0 Updates endpoint to include hidden package files 2017-04-26 22:10:34 +10:00
Stephan ffe3fc9257 deploy-293 - fix normalization 2017-04-26 13:25:54 +02:00
Shannon 26bd3c7c0b removes unneeded closing of stream since it's disposed 2017-04-26 19:42:58 +10:00
Shannon 944b3dcaac New method for IPackagingService to fetch a package from the repo, removes usages of the old repo endpoint, removes ability to push a package from the back office to Our since that would require a different endpoint. 2017-04-26 19:02:36 +10:00
Stephan ba489afe9a Publicize more IBackgroundTask plumbing 2017-04-26 09:07:48 +02:00
Shannon 968d52e490 Removes old packager files that should absolutely never be used 2017-04-26 15:46:07 +10:00
Shannon ebbe9f6ed0 Removes old packager files that should absolutely never be used 2017-04-26 15:45:37 +10:00
Shannon ba32636fe7 Merge remote-tracking branch 'origin/dev-v7' into temp-CON-1267 2017-04-26 14:18:27 +10:00
Shannon a6f9d14a1b Merge remote-tracking branch 'origin/dev-v7.6' into temp-CON-1267 2017-04-26 14:18:05 +10:00
Shannon 7cd385dd6b disables ssl by default 2017-04-26 14:17:24 +10:00
Shannon 5d4a97591a Cherry picks changes for package fetching for Our to use the new endpoint and passes in the current version 2017-04-26 14:08:37 +10:00
Shannon bfb81f6362 Allows for the umb pckage repo rest api endpoint to be configurable - for testing 2017-04-26 14:04:47 +10:00
Jason Woods 23816665f3 Fixed issue on line 216
Found that when uploading media from the folder browser caused an issue of invalid JSON object being stored in the database.  Added quotes around the property values.
2017-04-25 08:21:02 -06:00
Warren Buckley ca3dc030bc Merge pull request #1893 from umbraco/temp-u4-9764
U4-9764 - add FirstChild with predicate extension
2017-04-25 11:37:37 +01:00
mikkelhm 4775aff749 Bump version to RC2 2017-04-25 11:15:51 +02:00
Warren Buckley 9d20ee293b Merge pull request #1889 from umbraco/temp-U4-9758
U4-9758 New index can't be applied when CmsMember table has very long login names
2017-04-25 10:01:35 +01:00
Warren Buckley a9b820de31 Merge branch 'dev-v7.6' into temp-U4-9758 2017-04-25 09:58:20 +01:00
Stephan 3813653852 deploy-293 - only if not already 7.6 2017-04-25 10:46:37 +02:00
Warren Buckley a4720a2221 Adds null check - So that we still add the index if we don't have any member entries as of yet 2017-04-25 09:13:48 +01:00
Warren Buckley 728b71c4bd Merge pull request #1902 from umbraco/temp-deploy-293
temp-deploy-293
2017-04-24 16:08:01 +01:00
Stephan 9d7975d970 deploy-293 - fix 2017-04-24 16:52:31 +02:00
Emil Wangaa 7505401511 Merge pull request #1896 from umbraco/temp-U4-9760
U4-9760 - Master Templates & Tree Bug
2017-04-24 16:04:00 +02:00
Warren Buckley 7ee0a278f7 Adss null check 2017-04-24 14:57:57 +01:00
Stephan 1adbe9ddcb deploy-293 - normalize template guids on upgrade to 7.6 2017-04-24 15:52:44 +02:00
Tom Pipe 67e3ec2ae0 Quick/simple fix for the stale variable
The umbracoContext variable can hold a null reference to UmbracoContext.Current. 

If a request containing a file extension is passed through an UmbracoVirtualNodeRouteHandler, the UmbracoContext will be null, because a context is never created for urls containing extensions due to https://github.com/umbraco/Umbraco-CMS/blob/5397f2c53acbdeb0805e1fe39fda938f571d295a/src/Umbraco.Core/UriExtensions.cs#L143

A call can be made to EnsureContext in the overridden FindContent method, but the fresh context would never get picked up, instead the variable always contains a null reference, and an exception is then thrown on line 23
2017-04-24 13:23:12 +01:00
Warren Buckley d6272b0cdb Merge branch 'temp-U4-9760' of https://github.com/umbraco/Umbraco-CMS into temp-U4-9760 2017-04-24 13:19:36 +01:00
Warren Buckley ce7dd19a8f Updates the template controller save method - to take into account if the master you are updating to is a sub master that has children that there path's need updating too 2017-04-24 13:19:30 +01:00
Shannon d295174e53 Updates JS to include the current umbraco version when requesting a package's details, updates the c# to use a new endpoint on OUR to ensure that the correct file is downloaded based on the umb version passed in. 2017-04-24 21:31:35 +10:00
Mads Rasmussen 55022e2aaf fix removeNode check to only be for the root node 2017-04-24 12:46:45 +02:00
Warren Buckley 4ffca2e4bf Merge pull request #1900 from umbraco/temp-deploy-103
deploy-103 - fix PublicAccessRepository
2017-04-24 09:53:52 +01:00
Stephan 4a38b8acd1 Fix broken refs to some libs 2017-04-24 10:50:25 +02:00
Stephan d93b8b869e deploy-103 - fix PublicAccessRepository 2017-04-21 16:02:29 +02:00
Shannon Deminick da8c46e426 Merge pull request #1859 from alexxn/dev-v7
Add basic xss prevention logic
2017-04-21 13:05:40 +10:00
Warren Buckley c34a1060f7 When we create a brand new template & set a master template we were removing the entire tree for templates - this adds in a check to not do the remove of the old node if its a brand new template we are creating 2017-04-20 15:49:49 +01:00
Stephan 5880df3859 U4-9764 - add FirstChild with predicate extension 2017-04-19 18:56:12 +02:00
Shannon 13cfb42287 Resizes LoginName column so that it can be indexed but only if the data in the column doesn't exceed a max size 2017-04-19 20:16:43 +10:00
Shannon 13ccd86192 Adds another check for not being able to read the index 2017-04-18 12:35:21 +10:00
Shannon 336266c0eb U4-9775 AlreadyClosedException is thrown when retrieving media if the app domain is currently in a shutdown state and the site is under heavy load 2017-04-18 12:32:44 +10:00
Alex Novgorodov de9739118e Add basic xss prevention logic 2017-04-04 18:11:48 +03:00
TheBekker ab14b65078 [fix-U4-9038] get and set media start node for mediaPickerOverlay in grid 2017-03-13 22:54:20 +01:00
148 changed files with 2686 additions and 3935 deletions
+2 -1
View File
@@ -142,4 +142,5 @@ build/ui-docs.zip
build/csharp-docs.zip
build/msbuild.log
.vs/
src/packages/
src/packages/
build/tools/
+46 -3
View File
@@ -113,18 +113,61 @@ REM This is necessary because SETLOCAL is on in InstallGit.cmd so that one might
REM but the path setting is lost due to SETLOCAL
SET PATH="C:\Program Files (x86)\Git\cmd";"C:\Program Files\Git\cmd";%PATH%
SET toolsFolder=%CD%\tools\
IF NOT EXIST "%toolsFolder%" (
MD tools
)
SET nuGetExecutable=%CD%\tools\nuget.exe
IF NOT EXIST "%nuGetExecutable%" (
ECHO Getting NuGet so we can fetch some tools
ECHO Downloading https://dist.nuget.org/win-x86-commandline/latest/nuget.exe to %nuGetExecutable%
powershell -Command "(New-Object Net.WebClient).DownloadFile('https://dist.nuget.org/win-x86-commandline/latest/nuget.exe', '%nuGetExecutable%')"
)
:: We need 7za.exe for BuildBelle.bat
IF NOT EXIST "%toolsFolder%7za.exe" (
ECHO 7zip not found - fetching now
"%nuGetExecutable%" install 7-Zip.CommandLine -OutputDirectory tools -Verbosity quiet
)
:: We need vswhere.exe for VS2017+
IF NOT EXIST "%toolsFolder%vswhere.exe" (
ECHO vswhere not found - fetching now
"%nuGetExecutable%" install vswhere -OutputDirectory tools -Verbosity quiet
)
:: Put 7za.exe and vswhere.exe in a predictable path (not version specific)
FOR /f "delims=" %%A in ('dir "%toolsFolder%7-Zip.CommandLine.*" /b') DO SET "sevenZipExePath=%toolsFolder%%%A\"
MOVE "%sevenZipExePath%tools\7za.exe" "%toolsFolder%7za.exe"
FOR /f "delims=" %%A in ('dir "%toolsFolder%vswhere.*" /b') DO SET "vswhereExePath=%toolsFolder%%%A\"
MOVE "%vswhereExePath%tools\vswhere.exe" "%toolsFolder%vswhere.exe"
ECHO.
ECHO Making sure we have a web.config
IF NOT EXIST "%CD%\..\src\Umbraco.Web.UI\web.config" COPY "%CD%\..\src\Umbraco.Web.UI\web.Template.config" "%CD%\..\src\Umbraco.Web.UI\web.config"
for /f "usebackq tokens=1* delims=: " %%i in (`"%CD%\tools\vswhere.exe" -latest -requires Microsoft.Component.MSBuild`) do (
if /i "%%i"=="installationPath" set InstallDir=%%j
)
SET VSWherePath="%InstallDir%\MSBuild"
ECHO.
ECHO Visual Studio is installed in: %InstallDir%
SET MSBUILDPATH=C:\Program Files (x86)\MSBuild\14.0\Bin
SET MSBUILD="%MSBUILDPATH%\MsBuild.exe"
ECHO.
ECHO Reporting NuGet version
"%CD%\..\src\.nuget\NuGet.exe" help | findstr "^NuGet Version:"
"%nuGetExecutable%" help | findstr "^NuGet Version:"
ECHO.
ECHO Restoring NuGet packages
ECHO Into %nuGetFolder%
"%CD%\..\src\.nuget\NuGet.exe" restore "%CD%\..\src\umbraco.sln" -Verbosity Quiet -NonInteractive -PackagesDirectory "%nuGetFolder%"
"%nuGetExecutable%" restore "%CD%\..\src\umbraco.sln" -Verbosity Quiet -NonInteractive -PackagesDirectory "%nuGetFolder%"
IF ERRORLEVEL 1 GOTO :error
ECHO.
@@ -134,7 +177,7 @@ ECHO This takes a few minutes and logging is set to report warnings
ECHO and errors only so it might seems like nothing is happening for a while.
ECHO You can check the msbuild.log file for progress.
ECHO.
%MSBUILD% "Build.proj" /p:BUILD_RELEASE=%RELEASE% /p:BUILD_COMMENT=%COMMENT% /p:NugetPackagesDirectory="%nuGetFolder%" /consoleloggerparameters:Summary;ErrorsOnly /fileLogger
%MSBUILD% "Build.proj" /p:BUILD_RELEASE=%RELEASE% /p:BUILD_COMMENT=%COMMENT% /p:NugetPackagesDirectory="%nuGetFolder%" /p:VSWherePath=%VSWherePath% /consoleloggerparameters:Summary;ErrorsOnly /fileLogger
IF ERRORLEVEL 1 GOTO error
ECHO.
+48 -22
View File
@@ -1,33 +1,59 @@
@ECHO OFF
SETLOCAL
:: SETLOCAL is on, so changes to the path not persist to the actual user's path
SET release=%1
ECHO Installing Npm NuGet Package
SET nuGetFolder=%CD%\..\src\packages\
ECHO Configured packages folder: %nuGetFolder%
SET toolsFolder=%CD%\tools\
ECHO Current folder: %CD%
%CD%\..\src\.nuget\NuGet.exe install Npm.js -OutputDirectory %nuGetFolder% -Verbosity quiet
SET nodeFileName=node-v6.9.1-win-x86.7z
SET nodeExtractFolder=%toolsFolder%node.js.691
for /f "delims=" %%A in ('dir %nuGetFolder%node.js.* /b') do set "nodePath=%nuGetFolder%%%A\"
for /f "delims=" %%A in ('dir %nuGetFolder%npm.js.* /b') do set "npmPath=%nuGetFolder%%%A\tools\"
IF NOT EXIST "%nodeExtractFolder%" (
ECHO Downloading http://nodejs.org/dist/v6.9.1/%nodeFileName% to %toolsFolder%%nodeFileName%
powershell -Command "(New-Object Net.WebClient).DownloadFile('http://nodejs.org/dist/v6.9.1/%nodeFileName%', '%toolsFolder%%nodeFileName%')"
ECHO Extracting %nodeFileName% to %nodeExtractFolder%
"%toolsFolder%\7za.exe" x "%toolsFolder%\%nodeFileName%" -o"%nodeExtractFolder%" -aos > nul
)
FOR /f "delims=" %%A in ('dir "%nodeExtractFolder%\node*" /b') DO SET "nodePath=%nodeExtractFolder%\%%A"
ECHO Adding Npm and Node to path
REM SETLOCAL is on, so changes to the path not persist to the actual user's path
PATH=%npmPath%;%nodePath%;%PATH%
SET buildFolder=%CD%
SET nuGetExecutable=%CD%\tools\nuget.exe
IF NOT EXIST "%nuGetExecutable%" (
ECHO Downloading https://dist.nuget.org/win-x86-commandline/latest/nuget.exe to %nuGetExecutable%
powershell -Command "(New-Object Net.WebClient).DownloadFile('https://dist.nuget.org/win-x86-commandline/latest/nuget.exe', '%nuGetExecutable%')"
)
ECHO Change directory to %CD%\..\src\Umbraco.Web.UI.Client\
CD %CD%\..\src\Umbraco.Web.UI.Client\
SET drive=%CD:~0,2%
SET nuGetFolder=%drive%\packages\
FOR /f "delims=" %%A in ('dir "%nuGetFolder%npm.*" /b') DO SET "npmPath=%nuGetFolder%%%A\"
ECHO Do npm install and the grunt build of Belle
call npm cache clean --quiet
call npm install --quiet
call npm install -g grunt-cli --quiet
call npm install -g bower --quiet
call grunt build --buildversion=%release%
IF [%npmPath%] == [] GOTO :installnpm
IF NOT [%npmPath%] == [] GOTO :build
ECHO Move back to the build folder
CD %buildFolder%
:installnpm
ECHO Downloading npm
ECHO Configured packages folder: %nuGetFolder%
ECHO Installing Npm NuGet Package
"%nuGetExecutable%" install Npm -OutputDirectory %nuGetFolder% -Verbosity detailed
REM Ensures that we look for the just downloaded NPM, not whatever the user has installed on their machine
FOR /f "delims=" %%A in ('dir %nuGetFolder%npm.* /b') DO SET "npmPath=%nuGetFolder%%%A\"
GOTO :build
:build
ECHO Adding Npm and Node to path
REM SETLOCAL is on, so changes to the path not persist to the actual user's path
PATH="%npmPath%";"%nodePath%";%PATH%
SET buildFolder=%CD%
ECHO Change directory to %CD%\..\src\Umbraco.Web.UI.Client\
CD %CD%\..\src\Umbraco.Web.UI.Client\
ECHO Do npm install and the grunt build of Belle
call npm cache clean --quiet
call npm install --quiet
call npm install -g grunt-cli --quiet
call npm install -g bower --quiet
call grunt build --buildversion=%release%
ECHO Move back to the build folder
CD "%buildFolder%"
+2 -2
View File
@@ -37,8 +37,8 @@
<dependency id="Examine" version="[0.1.82, 1.0.0)" />
<dependency id="ImageProcessor" version="[2.5.3, 3.0.0)" />
<dependency id="ImageProcessor.Web" version="[4.8.3, 5.0.0)" />
<dependency id="semver" version="[2.0.4, 3.0.0)" />
<!-- Markdown can not be updated due to: https://github.com/hey-red/markdownsharp/issues/71#issuecomment-233585487 -->
<dependency id="semver" version="[1.1.2, 3.0.0)" />
<!-- Markdown can not be updated due to: https://github.com/hey-red/markdownsharp/issues/71#issuecomment-233585487 -->
<dependency id="Markdown" version="[1.14.7, 2.0.0)" />
<dependency id="System.Threading.Tasks.Dataflow" version="[4.7.0, 5.0.0)" />
</dependencies>
+1 -1
View File
@@ -19,7 +19,7 @@
<dependency id="Newtonsoft.Json" version="[10.0.2, 11.0.0)" />
<dependency id="Umbraco.ModelsBuilder" version="[3.0.7, 4.0.0)" />
<dependency id="Microsoft.AspNet.SignalR.Core" version="[2.2.1, 3.0.0)" />
<dependency id="ImageProcessor.Web.Config" version="[2.3.0, 3.0.0)" />
<dependency id="ImageProcessor.Web.Config" version="[2.3.0, 3.0.0)" />
</dependencies>
</metadata>
<files>
+1 -2
View File
@@ -1,3 +1,2 @@
# Usage: on line 2 put the release version, on line 3 put the version comment (example: beta)
7.6.0
RC1
7.6.1
+2 -2
View File
@@ -11,5 +11,5 @@ using System.Resources;
[assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyFileVersion("7.6.0")]
[assembly: AssemblyInformationalVersion("7.6.0-RC1")]
[assembly: AssemblyFileVersion("7.6.1")]
[assembly: AssemblyInformationalVersion("7.6.1")]
@@ -8,6 +8,7 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
Guid Id { get; }
string RepositoryUrl { get; }
string WebServiceUrl { get; }
bool HasCustomWebServiceUrl { get; }
bool HasCustomWebServiceUrl { get; }
string RestApiUrl { get; }
}
}
@@ -0,0 +1,19 @@
using System;
using System.Linq;
namespace Umbraco.Core.Configuration.UmbracoSettings
{
public static class RepositoryConfigExtensions
{
//Our package repo
private static readonly Guid RepoGuid = new Guid("65194810-1f85-11dd-bd0b-0800200c9a66");
public static IRepository GetDefault(this IRepositoriesSection repos)
{
var found = repos.Repositories.FirstOrDefault(x => x.Id == RepoGuid);
if (found == null)
throw new InvalidOperationException("No default package repository found with id " + RepoGuid);
return found;
}
}
}
@@ -38,9 +38,16 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
get
{
var prop = Properties["webserviceurl"];
var repoUrl = this[prop] as ConfigurationElement;
return (repoUrl != null && repoUrl.ElementInformation.IsPresent);
return (string) prop.DefaultValue != (string) this[prop];
}
}
[ConfigurationProperty("restapiurl", DefaultValue = "https://our.umbraco.org/webapi/packages/v1")]
public string RestApiUrl
{
get { return (string)base["restapiurl"]; }
set { base["restapiurl"] = value; }
}
}
}
@@ -6,7 +6,7 @@ namespace Umbraco.Core.Configuration
{
public class UmbracoVersion
{
private static readonly Version Version = new Version("7.6.0");
private static readonly Version Version = new Version("7.6.1");
/// <summary>
/// Gets the current version of Umbraco.
@@ -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 "RC1"; } }
public static string CurrentComment { get { return ""; } }
// 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
@@ -1,85 +1,177 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Security.Permissions;
using Umbraco.Core.Models;
using Umbraco.Core.Models.EntityBase;
namespace Umbraco.Core.Events
{
/// <summary>
/// Event args for a strongly typed object that can support cancellation
/// </summary>
/// <typeparam name="T"></typeparam>
[HostProtection(SecurityAction.LinkDemand, SharedState = true)]
public class CancellableObjectEventArgs<T> : CancellableEventArgs, IEquatable<CancellableObjectEventArgs<T>>
{
public CancellableObjectEventArgs(T eventObject, bool canCancel, EventMessages messages, IDictionary<string, object> additionalData)
/// <summary>
/// Used as a base class for the generic type CancellableObjectEventArgs{T} so that we can get direct 'object' access to the underlying EventObject
/// </summary>
[HostProtection(SecurityAction.LinkDemand, SharedState = true)]
public abstract class CancellableObjectEventArgs : CancellableEventArgs
{
protected CancellableObjectEventArgs(object eventObject, bool canCancel, EventMessages messages, IDictionary<string, object> additionalData)
: base(canCancel, messages, additionalData)
{
{
EventObject = eventObject;
}
public CancellableObjectEventArgs(T eventObject, bool canCancel, EventMessages eventMessages)
protected CancellableObjectEventArgs(object eventObject, bool canCancel, EventMessages eventMessages)
: base(canCancel, eventMessages)
{
EventObject = eventObject;
}
public CancellableObjectEventArgs(T eventObject, EventMessages eventMessages)
protected CancellableObjectEventArgs(object eventObject, EventMessages eventMessages)
: this(eventObject, true, eventMessages)
{
}
protected CancellableObjectEventArgs(object eventObject, bool canCancel)
: base(canCancel)
{
EventObject = eventObject;
}
protected CancellableObjectEventArgs(object eventObject)
: this(eventObject, true)
{
}
/// <summary>
/// Returns the object relating to the event
/// </summary>
/// <remarks>
/// This is protected so that inheritors can expose it with their own name
/// </remarks>
internal object EventObject { get; set; }
}
/// <summary>
/// Event args for a strongly typed object that can support cancellation
/// </summary>
/// <typeparam name="T"></typeparam>
[HostProtection(SecurityAction.LinkDemand, SharedState = true)]
public class CancellableObjectEventArgs<T> : CancellableObjectEventArgs, IEquatable<CancellableObjectEventArgs<T>>
{
public CancellableObjectEventArgs(T eventObject, bool canCancel, EventMessages messages, IDictionary<string, object> additionalData)
: base(eventObject, canCancel, messages, additionalData)
{
}
public CancellableObjectEventArgs(T eventObject, bool canCancel, EventMessages eventMessages)
: base(eventObject, canCancel, eventMessages)
{
}
public CancellableObjectEventArgs(T eventObject, EventMessages eventMessages)
: base(eventObject, eventMessages)
{
}
public CancellableObjectEventArgs(T eventObject, bool canCancel)
: base(canCancel)
{
EventObject = eventObject;
}
: base(eventObject, canCancel)
{
}
public CancellableObjectEventArgs(T eventObject)
: this(eventObject, true)
{
}
public CancellableObjectEventArgs(T eventObject)
: base(eventObject)
{
}
/// <summary>
/// Returns the object relating to the event
/// </summary>
/// <remarks>
/// This is protected so that inheritors can expose it with their own name
/// </remarks>
protected T EventObject { get; set; }
/// <summary>
/// Returns the object relating to the event
/// </summary>
/// <remarks>
/// This is protected so that inheritors can expose it with their own name
/// </remarks>
protected new T EventObject
{
get { return (T) base.EventObject; }
set { base.EventObject = value; }
}
public bool Equals(CancellableObjectEventArgs<T> other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return base.Equals(other) && EqualityComparer<T>.Default.Equals(EventObject, other.EventObject);
}
public bool Equals(CancellableObjectEventArgs<T> other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return base.Equals(other) && EqualityComparer<T>.Default.Equals(EventObject, other.EventObject);
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != this.GetType()) return false;
return Equals((CancellableObjectEventArgs<T>) obj);
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != this.GetType()) return false;
return Equals((CancellableObjectEventArgs<T>)obj);
}
public override int GetHashCode()
{
unchecked
{
return (base.GetHashCode() * 397) ^ EqualityComparer<T>.Default.GetHashCode(EventObject);
}
}
public override int GetHashCode()
{
unchecked
{
return (base.GetHashCode() * 397) ^ EqualityComparer<T>.Default.GetHashCode(EventObject);
}
}
public static bool operator ==(CancellableObjectEventArgs<T> left, CancellableObjectEventArgs<T> right)
{
return Equals(left, right);
}
public static bool operator ==(CancellableObjectEventArgs<T> left, CancellableObjectEventArgs<T> right)
{
return Equals(left, right);
}
public static bool operator !=(CancellableObjectEventArgs<T> left, CancellableObjectEventArgs<T> right)
{
return !Equals(left, right);
}
}
public static bool operator !=(CancellableObjectEventArgs<T> left, CancellableObjectEventArgs<T> right)
{
return !Equals(left, right);
}
}
[HostProtection(SecurityAction.LinkDemand, SharedState = true)]
public class CancellableEnumerableObjectEventArgs<T> : CancellableObjectEventArgs<IEnumerable<T>>, IEquatable<CancellableEnumerableObjectEventArgs<T>>
{
public CancellableEnumerableObjectEventArgs(IEnumerable<T> eventObject, bool canCancel, EventMessages messages, IDictionary<string, object> additionalData)
: base(eventObject, canCancel, messages, additionalData)
{ }
public CancellableEnumerableObjectEventArgs(IEnumerable<T> eventObject, bool canCancel, EventMessages eventMessages)
: base(eventObject, canCancel, eventMessages)
{ }
public CancellableEnumerableObjectEventArgs(IEnumerable<T> eventObject, EventMessages eventMessages)
: base(eventObject, eventMessages)
{ }
public CancellableEnumerableObjectEventArgs(IEnumerable<T> eventObject, bool canCancel)
: base(eventObject, canCancel)
{ }
public CancellableEnumerableObjectEventArgs(IEnumerable<T> eventObject)
: base(eventObject)
{ }
public bool Equals(CancellableEnumerableObjectEventArgs<T> other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return EventObject.SequenceEqual(other.EventObject);
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != this.GetType()) return false;
return Equals((CancellableEnumerableObjectEventArgs<T>)obj);
}
public override int GetHashCode()
{
return HashCodeHelper.GetHashCode(EventObject);
}
}
}
+7 -2
View File
@@ -1,9 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace Umbraco.Core.Events
{
public class DeleteEventArgs<TEntity> : CancellableObjectEventArgs<IEnumerable<TEntity>>, IEquatable<DeleteEventArgs<TEntity>>, IDeletingMediaFilesEventArgs
[SupersedeEvent(typeof(SaveEventArgs<>))]
[SupersedeEvent(typeof(PublishEventArgs<>))]
[SupersedeEvent(typeof(MoveEventArgs<>))]
[SupersedeEvent(typeof(CopyEventArgs<>))]
public class DeleteEventArgs<TEntity> : CancellableEnumerableObjectEventArgs<TEntity>, IEquatable<DeleteEventArgs<TEntity>>, IDeletingMediaFilesEventArgs
{
/// <summary>
/// Constructor accepting multiple entities that are used in the delete operation
@@ -106,7 +111,7 @@ namespace Umbraco.Core.Events
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return base.Equals(other) && MediaFilesToDelete.Equals(other.MediaFilesToDelete);
return base.Equals(other) && MediaFilesToDelete.SequenceEqual(other.MediaFilesToDelete);
}
public override bool Equals(object obj)
+1 -1
View File
@@ -4,7 +4,7 @@ using System.Xml.Linq;
namespace Umbraco.Core.Events
{
public class ImportEventArgs<TEntity> : CancellableObjectEventArgs<IEnumerable<TEntity>>, IEquatable<ImportEventArgs<TEntity>>
public class ImportEventArgs<TEntity> : CancellableEnumerableObjectEventArgs<TEntity>, IEquatable<ImportEventArgs<TEntity>>
{
/// <summary>
/// Constructor accepting an XElement with the xml being imported
@@ -4,7 +4,7 @@ using Umbraco.Core.Packaging.Models;
namespace Umbraco.Core.Events
{
internal class ImportPackageEventArgs<TEntity> : CancellableObjectEventArgs<IEnumerable<TEntity>>, IEquatable<ImportPackageEventArgs<TEntity>>
internal class ImportPackageEventArgs<TEntity> : CancellableEnumerableObjectEventArgs<TEntity>, IEquatable<ImportPackageEventArgs<TEntity>>
{
private readonly MetaData _packageMetaData;
@@ -32,7 +32,8 @@ namespace Umbraco.Core.Events
public bool Equals(ImportPackageEventArgs<TEntity> other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
if (ReferenceEquals(this, other)) return true;
//TODO: MetaData for package metadata has no equality operators :/
return base.Equals(other) && _packageMetaData.Equals(other._packageMetaData);
}
@@ -5,8 +5,10 @@ using System.Linq;
namespace Umbraco.Core.Events
{
/// <summary>
/// This event manager supports event cancellation and will raise the events as soon as they are tracked, it does not store tracked events
/// An IEventDispatcher that immediately raise all events.
/// </summary>
/// <remarks>This means that events will be raised during the scope transaction,
/// whatever happens, and the transaction could roll back in the end.</remarks>
internal class PassThroughEventDispatcher : IEventDispatcher
{
public bool DispatchCancelable(EventHandler eventHandler, object sender, CancellableEventArgs args, string eventName = null)
+1 -1
View File
@@ -3,7 +3,7 @@ using System.Collections.Generic;
namespace Umbraco.Core.Events
{
public class PublishEventArgs<TEntity> : CancellableObjectEventArgs<IEnumerable<TEntity>>, IEquatable<PublishEventArgs<TEntity>>
public class PublishEventArgs<TEntity> : CancellableEnumerableObjectEventArgs<TEntity>, IEquatable<PublishEventArgs<TEntity>>
{
/// <summary>
/// Constructor accepting multiple entities that are used in the publish operation
+2 -3
View File
@@ -1,8 +1,9 @@
using System.Collections.Generic;
using System.Linq;
namespace Umbraco.Core.Events
{
public class SaveEventArgs<TEntity> : CancellableObjectEventArgs<IEnumerable<TEntity>>
public class SaveEventArgs<TEntity> : CancellableEnumerableObjectEventArgs<TEntity>
{
/// <summary>
/// Constructor accepting multiple entities that are used in the saving operation
@@ -116,7 +117,5 @@ namespace Umbraco.Core.Events
{
get { return EventObject; }
}
}
}
@@ -3,11 +3,9 @@ using Umbraco.Core.IO;
namespace Umbraco.Core.Events
{
/// <summary>
/// This event manager is created for each scope and is aware of if it is nested in an outer scope
/// An IEventDispatcher that queues events, and raise them when the scope
/// exits and has been completed.
/// </summary>
/// <remarks>
/// The outer scope is the only scope that can raise events, the inner scope's will defer to the outer scope
/// </remarks>
internal class ScopeEventDispatcher : ScopeEventDispatcherBase
{
public ScopeEventDispatcher()
@@ -1,11 +1,23 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Umbraco.Core.Models.EntityBase;
namespace Umbraco.Core.Events
{
/// <summary>
/// An IEventDispatcher that queues events.
/// </summary>
/// <remarks>
/// <para>Can raise, or ignore, cancelable events, depending on option.</para>
/// <para>Implementations must override ScopeExitCompleted to define what
/// to do with the events when the scope exits and has been completed.</para>
/// <para>If the scope exits without being completed, events are ignored.</para>
/// </remarks>
public abstract class ScopeEventDispatcherBase : IEventDispatcher
{
//events will be enlisted in the order they are raised
private List<IEventDefinition> _events;
private readonly bool _raiseCancelable;
@@ -64,29 +76,263 @@ namespace Umbraco.Core.Events
{
if (_events == null)
return Enumerable.Empty<IEventDefinition>();
switch (filter)
{
case EventDefinitionFilter.All:
return _events;
return FilterSupersededAndUpdateToLatestEntity(_events);
case EventDefinitionFilter.FirstIn:
var l1 = new OrderedHashSet<IEventDefinition>();
foreach (var e in _events)
{
l1.Add(e);
}
return l1;
return FilterSupersededAndUpdateToLatestEntity(l1);
case EventDefinitionFilter.LastIn:
var l2 = new OrderedHashSet<IEventDefinition>(keepOldest: false);
foreach (var e in _events)
{
l2.Add(e);
}
return l2;
return FilterSupersededAndUpdateToLatestEntity(l2);
default:
throw new ArgumentOutOfRangeException("filter", filter, null);
}
}
private class EventDefinitionTypeData
{
public IEventDefinition EventDefinition { get; set; }
public Type EventArgType { get; set; }
public SupersedeEventAttribute[] SupersedeAttributes { get; set; }
}
/// <summary>
/// This will iterate over the events (latest first) and filter out any events or entities in event args that are included
/// in more recent events that Supersede previous ones. For example, If an Entity has been Saved and then Deleted, we don't want
/// to raise the Saved event (well actually we just don't want to include it in the args for that saved event)
/// </summary>
/// <param name="events"></param>
/// <returns></returns>
private static IEnumerable<IEventDefinition> FilterSupersededAndUpdateToLatestEntity(IReadOnlyList<IEventDefinition> events)
{
//used to keep the 'latest' entity and associated event definition data
var allEntities = new List<Tuple<IEntity, EventDefinitionTypeData>>();
//tracks all CancellableObjectEventArgs instances in the events which is the only type of args we can work with
var cancelableArgs = new List<CancellableObjectEventArgs>();
var result = new List<IEventDefinition>();
//This will eagerly load all of the event arg types and their attributes so we don't have to continuously look this data up
var allArgTypesWithAttributes = events.Select(x => x.Args.GetType())
.Distinct()
.ToDictionary(x => x, x => x.GetCustomAttributes<SupersedeEventAttribute>(false).ToArray());
//Iterate all events and collect the actual entities in them and relates them to their corresponding EventDefinitionTypeData
//we'll process the list in reverse because events are added in the order they are raised and we want to filter out
//any entities from event args that are not longer relevant
//(i.e. if an item is Deleted after it's Saved, we won't include the item in the Saved args)
for (var index = events.Count - 1; index >= 0; index--)
{
var eventDefinition = events[index];
var argType = eventDefinition.Args.GetType();
var attributes = allArgTypesWithAttributes[eventDefinition.Args.GetType()];
var meta = new EventDefinitionTypeData
{
EventDefinition = eventDefinition,
EventArgType = argType,
SupersedeAttributes = attributes
};
var args = eventDefinition.Args as CancellableObjectEventArgs;
if (args != null)
{
var list = TypeHelper.CreateGenericEnumerableFromObject(args.EventObject);
if (list == null)
{
//extract the event object
var obj = args.EventObject as IEntity;
if (obj != null)
{
//Now check if this entity already exists in other event args that supersede this current event arg type
if (IsFiltered(obj, meta, allEntities) == false)
{
//if it's not filtered we can adde these args to the response
cancelableArgs.Add(args);
result.Add(eventDefinition);
//track the entity
allEntities.Add(Tuple.Create(obj, meta));
}
}
else
{
//Can't retrieve the entity so cant' filter or inspect, just add to the output
result.Add(eventDefinition);
}
}
else
{
var toRemove = new List<IEntity>();
foreach (var entity in list)
{
//extract the event object
var obj = entity as IEntity;
if (obj != null)
{
//Now check if this entity already exists in other event args that supersede this current event arg type
if (IsFiltered(obj, meta, allEntities))
{
//track it to be removed
toRemove.Add(obj);
}
else
{
//track the entity, it's not filtered
allEntities.Add(Tuple.Create(obj, meta));
}
}
else
{
//we don't need to do anything here, we can't cast to IEntity so we cannot filter, so it will just remain in the list
}
}
//remove anything that has been filtered
foreach (var entity in toRemove)
{
list.Remove(entity);
}
//track the event and include in the response if there's still entities remaining in the list
if (list.Count > 0)
{
if (toRemove.Count > 0)
{
//re-assign if the items have changed
args.EventObject = list;
}
cancelableArgs.Add(args);
result.Add(eventDefinition);
}
}
}
else
{
//it's not a cancelable event arg so we just include it in the result
result.Add(eventDefinition);
}
}
//Now we'll deal with ensuring that only the latest(non stale) entities are used throughout all event args
UpdateToLatestEntities(allEntities, cancelableArgs);
//we need to reverse the result since we've been adding by latest added events first!
result.Reverse();
return result;
}
private static void UpdateToLatestEntities(IEnumerable<Tuple<IEntity, EventDefinitionTypeData>> allEntities, IEnumerable<CancellableObjectEventArgs> cancelableArgs)
{
//Now we'll deal with ensuring that only the latest(non stale) entities are used throughout all event args
var latestEntities = new OrderedHashSet<IEntity>(keepOldest: true);
foreach (var entity in allEntities.OrderByDescending(entity => entity.Item1.UpdateDate))
{
latestEntities.Add(entity.Item1);
}
foreach (var args in cancelableArgs)
{
var list = TypeHelper.CreateGenericEnumerableFromObject(args.EventObject);
if (list == null)
{
//try to find the args entity in the latest entity - based on the equality operators, this will
//match by Id since that is the default equality checker for IEntity. If one is found, than it is
//the most recent entity instance so update the args with that instance so we don't emit a stale instance.
var foundEntity = latestEntities.FirstOrDefault(x => Equals(x, args.EventObject));
if (foundEntity != null)
{
args.EventObject = foundEntity;
}
}
else
{
var updated = false;
for (int i = 0; i < list.Count; i++)
{
//try to find the args entity in the latest entity - based on the equality operators, this will
//match by Id since that is the default equality checker for IEntity. If one is found, than it is
//the most recent entity instance so update the args with that instance so we don't emit a stale instance.
var foundEntity = latestEntities.FirstOrDefault(x => Equals(x, list[i]));
if (foundEntity != null)
{
list[i] = foundEntity;
updated = true;
}
}
if (updated)
{
args.EventObject = list;
}
}
}
}
/// <summary>
/// This will check against all of the processed entity/events (allEntities) to see if this entity already exists in
/// event args that supersede the event args being passed in and if so returns true.
/// </summary>
/// <param name="entity"></param>
/// <param name="eventDef"></param>
/// <param name="allEntities"></param>
/// <returns></returns>
private static bool IsFiltered(
IEntity entity,
EventDefinitionTypeData eventDef,
List<Tuple<IEntity, EventDefinitionTypeData>> allEntities)
{
var argType = eventDef.EventDefinition.Args.GetType();
//check if the entity is found in any processed event data that could possible supersede this one
var foundByEntity = allEntities
.Where(x => x.Item2.SupersedeAttributes.Length > 0
//if it's the same arg type than it cannot supersede
&& x.Item2.EventArgType != argType
&& Equals(x.Item1, entity))
.ToArray();
//no args have been processed with this entity so it should not be filtered
if (foundByEntity.Length == 0)
return false;
if (argType.IsGenericType)
{
var supercededBy = foundByEntity
.FirstOrDefault(x =>
x.Item2.SupersedeAttributes.Any(y =>
//if the attribute type is a generic type def then compare with the generic type def of the event arg
(y.SupersededEventArgsType.IsGenericTypeDefinition && y.SupersededEventArgsType == argType.GetGenericTypeDefinition())
//if the attribute type is not a generic type def then compare with the normal type of the event arg
|| (y.SupersededEventArgsType.IsGenericTypeDefinition == false && y.SupersededEventArgsType == argType)));
return supercededBy != null;
}
else
{
var supercededBy = foundByEntity
.FirstOrDefault(x =>
x.Item2.SupersedeAttributes.Any(y =>
//since the event arg type is not a generic type, then we just compare type 1:1
y.SupersededEventArgsType == argType));
return supercededBy != null;
}
}
public void ScopeExit(bool completed)
{
@@ -0,0 +1,20 @@
using System;
namespace Umbraco.Core.Events
{
/// <summary>
/// This is used to know if the event arg attributed should supersede another event arg type when
/// tracking events for the same entity. If one event args supercedes another then the event args that have been superseded
/// will mean that the event will not be dispatched or the args will be filtered to exclude the entity.
/// </summary>
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
internal class SupersedeEventAttribute : Attribute
{
public Type SupersededEventArgsType { get; private set; }
public SupersedeEventAttribute(Type supersededEventArgsType)
{
SupersededEventArgsType = supersededEventArgsType;
}
}
}
@@ -0,0 +1,12 @@
using System;
namespace Umbraco.Core.Exceptions
{
internal class ConnectionException : Exception
{
public ConnectionException(string message, Exception innerException) : base(message, innerException)
{
}
}
}
@@ -7,7 +7,7 @@ namespace Umbraco.Core.Exceptions
public T Operation { get; private set; }
public DataOperationException(T operation, string message)
:base(message)
: base(message)
{
Operation = operation;
}
+74 -75
View File
@@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
@@ -7,32 +6,32 @@ using System.Text;
namespace Umbraco.Core
{
/// <summary>
/// Used to create a hash code from multiple objects.
/// </summary>
/// <remarks>
/// .Net has a class the same as this: System.Web.Util.HashCodeCombiner and of course it works for all sorts of things
/// which we've not included here as we just need a quick easy class for this in order to create a unique
/// hash of directories/files to see if they have changed.
/// </remarks>
internal class HashCodeCombiner
{
private long _combinedHash = 5381L;
/// <summary>
/// Used to create a hash code from multiple objects.
/// </summary>
/// <remarks>
/// .Net has a class the same as this: System.Web.Util.HashCodeCombiner and of course it works for all sorts of things
/// which we've not included here as we just need a quick easy class for this in order to create a unique
/// hash of directories/files to see if they have changed.
/// </remarks>
internal class HashCodeCombiner
{
private long _combinedHash = 5381L;
internal void AddInt(int i)
{
_combinedHash = ((_combinedHash << 5) + _combinedHash) ^ i;
}
internal void AddInt(int i)
{
_combinedHash = ((_combinedHash << 5) + _combinedHash) ^ i;
}
internal void AddObject(object o)
{
AddInt(o.GetHashCode());
}
internal void AddObject(object o)
{
AddInt(o.GetHashCode());
}
internal void AddDateTime(DateTime d)
{
AddInt(d.GetHashCode());
}
internal void AddDateTime(DateTime d)
{
AddInt(d.GetHashCode());
}
internal void AddString(string s)
{
@@ -40,61 +39,61 @@ namespace Umbraco.Core
AddInt((StringComparer.InvariantCulture).GetHashCode(s));
}
internal void AddCaseInsensitiveString(string s)
{
if (s != null)
AddInt((StringComparer.InvariantCultureIgnoreCase).GetHashCode(s));
}
internal void AddCaseInsensitiveString(string s)
{
if (s != null)
AddInt((StringComparer.InvariantCultureIgnoreCase).GetHashCode(s));
}
internal void AddFileSystemItem(FileSystemInfo f)
{
//if it doesn't exist, don't proceed.
if (!f.Exists)
return;
internal void AddFileSystemItem(FileSystemInfo f)
{
//if it doesn't exist, don't proceed.
if (!f.Exists)
return;
AddCaseInsensitiveString(f.FullName);
AddDateTime(f.CreationTimeUtc);
AddDateTime(f.LastWriteTimeUtc);
//check if it is a file or folder
var fileInfo = f as FileInfo;
if (fileInfo != null)
{
AddInt(fileInfo.Length.GetHashCode());
}
var dirInfo = f as DirectoryInfo;
if (dirInfo != null)
{
foreach (var d in dirInfo.GetFiles())
{
AddFile(d);
}
foreach (var s in dirInfo.GetDirectories())
{
AddFolder(s);
}
}
}
AddCaseInsensitiveString(f.FullName);
AddDateTime(f.CreationTimeUtc);
AddDateTime(f.LastWriteTimeUtc);
internal void AddFile(FileInfo f)
{
AddFileSystemItem(f);
}
//check if it is a file or folder
var fileInfo = f as FileInfo;
if (fileInfo != null)
{
AddInt(fileInfo.Length.GetHashCode());
}
internal void AddFolder(DirectoryInfo d)
{
AddFileSystemItem(d);
}
var dirInfo = f as DirectoryInfo;
if (dirInfo != null)
{
foreach (var d in dirInfo.GetFiles())
{
AddFile(d);
}
foreach (var s in dirInfo.GetDirectories())
{
AddFolder(s);
}
}
}
/// <summary>
/// Returns the hex code of the combined hash code
/// </summary>
/// <returns></returns>
internal string GetCombinedHashCode()
{
return _combinedHash.ToString("x", CultureInfo.InvariantCulture);
}
internal void AddFile(FileInfo f)
{
AddFileSystemItem(f);
}
}
internal void AddFolder(DirectoryInfo d)
{
AddFileSystemItem(d);
}
/// <summary>
/// Returns the hex code of the combined hash code
/// </summary>
/// <returns></returns>
internal string GetCombinedHashCode()
{
return _combinedHash.ToString("x", CultureInfo.InvariantCulture);
}
}
}
+104
View File
@@ -0,0 +1,104 @@
using System.Collections.Generic;
namespace Umbraco.Core
{
/// <summary>
/// Borrowed from http://stackoverflow.com/a/2575444/694494
/// </summary>
internal static class HashCodeHelper
{
public static int GetHashCode<T1, T2>(T1 arg1, T2 arg2)
{
unchecked
{
return 31 * arg1.GetHashCode() + arg2.GetHashCode();
}
}
public static int GetHashCode<T1, T2, T3>(T1 arg1, T2 arg2, T3 arg3)
{
unchecked
{
int hash = arg1.GetHashCode();
hash = 31 * hash + arg2.GetHashCode();
return 31 * hash + arg3.GetHashCode();
}
}
public static int GetHashCode<T1, T2, T3, T4>(T1 arg1, T2 arg2, T3 arg3,
T4 arg4)
{
unchecked
{
int hash = arg1.GetHashCode();
hash = 31 * hash + arg2.GetHashCode();
hash = 31 * hash + arg3.GetHashCode();
return 31 * hash + arg4.GetHashCode();
}
}
public static int GetHashCode<T>(T[] list)
{
unchecked
{
int hash = 0;
foreach (var item in list)
{
if (item == null) continue;
hash = 31 * hash + item.GetHashCode();
}
return hash;
}
}
public static int GetHashCode<T>(IEnumerable<T> list)
{
unchecked
{
int hash = 0;
foreach (var item in list)
{
if (item == null) continue;
hash = 31 * hash + item.GetHashCode();
}
return hash;
}
}
/// <summary>
/// Gets a hashcode for a collection for that the order of items
/// does not matter.
/// So {1, 2, 3} and {3, 2, 1} will get same hash code.
/// </summary>
public static int GetHashCodeForOrderNoMatterCollection<T>(
IEnumerable<T> list)
{
unchecked
{
int hash = 0;
int count = 0;
foreach (var item in list)
{
if (item == null) continue;
hash += item.GetHashCode();
count++;
}
return 31 * hash + count.GetHashCode();
}
}
/// <summary>
/// Alternative way to get a hashcode is to use a fluent
/// interface like this:<br />
/// return 0.CombineHashCode(field1).CombineHashCode(field2).
/// CombineHashCode(field3);
/// </summary>
public static int CombineHashCode<T>(this int hashCode, T arg)
{
unchecked
{
return 31 * hashCode + arg.GetHashCode();
}
}
}
}
+14 -3
View File
@@ -52,9 +52,20 @@ namespace Umbraco.Core.IO
try
{
Directory.Delete(dir, true);
dir = dir.Substring(0, dir.Length - _shadowPath.Length - 1);
if (Directory.EnumerateFileSystemEntries(dir).Any() == false)
Directory.Delete(dir, true);
// shadowPath make be path/to/dir, remove each
dir = dir.Replace("/", "\\");
var min = IOHelper.MapPath("~/App_Data/TEMP/ShadowFs").Length;
var pos = dir.LastIndexOf("\\", StringComparison.OrdinalIgnoreCase);
while (pos > min)
{
dir = dir.Substring(0, pos);
if (Directory.EnumerateFileSystemEntries(dir).Any() == false)
Directory.Delete(dir, true);
else
break;
pos = dir.LastIndexOf("\\", StringComparison.OrdinalIgnoreCase);
}
}
catch
{
@@ -42,6 +42,7 @@ namespace Umbraco.Core.Models
public Guid Key { get; set; }
public DateTime CreateDate { get; set; }
public DateTime UpdateDate { get; set; }
public DateTime? DeletedDate { get; set; }
/// <summary>
/// Special case, always return false, this will cause the repositories managing
@@ -60,5 +61,7 @@ namespace Umbraco.Core.Models
DeepCloneHelper.DeepCloneRefProperties(this, clone);
return clone;
}
}
}
@@ -101,6 +101,9 @@ namespace Umbraco.Core.Models.EntityBase
set { SetPropertyValueAndDetectChanges(value, ref _updateDate, Ps.Value.UpdateDateSelector); }
}
[IgnoreDataMember]
public DateTime? DeletedDate { get; set; }
internal virtual void ResetIdentity()
{
_hasIdentity = false;
@@ -3,7 +3,7 @@
/// <summary>
/// Marker interface for aggregate roots
/// </summary>
public interface IAggregateRoot : IEntity
public interface IAggregateRoot : IDeletableEntity
{
}
@@ -0,0 +1,11 @@
using System;
using System.Runtime.Serialization;
namespace Umbraco.Core.Models.EntityBase
{
public interface IDeletableEntity : IEntity
{
[DataMember]
DateTime? DeletedDate { get; set; }
}
}
@@ -20,7 +20,7 @@ namespace Umbraco.Core.Models.EntityBase
/// <summary>
/// Guid based Id
/// </summary>
/// <remarks>The key is currectly used to store the Unique Id from the
/// <remarks>The key is currectly used to store the Unique Id from the
/// umbracoNode table, which many of the entities are based on.</remarks>
[DataMember]
Guid Key { get; set; }
+1 -1
View File
@@ -11,7 +11,7 @@ namespace Umbraco.Core
{
private readonly bool _keepOldest;
public OrderedHashSet(bool keepOldest = true)
public OrderedHashSet(bool keepOldest = true)
{
_keepOldest = keepOldest;
}
@@ -23,7 +23,7 @@ namespace Umbraco.Core.Persistence.Migrations
Logger = logger;
}
public IMigrationContext Context { get; internal set; }
public IMigrationContext Context;
public abstract void Up();
public abstract void Down();
@@ -1,4 +1,5 @@
using Umbraco.Core.Persistence.Migrations.Syntax.Alter.Column;
using System;
using Umbraco.Core.Persistence.Migrations.Syntax.Alter.Column;
using Umbraco.Core.Persistence.Migrations.Syntax.Alter.Expressions;
using Umbraco.Core.Persistence.Migrations.Syntax.Alter.Table;
using Umbraco.Core.Persistence.SqlSyntax;
@@ -25,6 +26,15 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Alter
return new AlterTableBuilder(_context, _databaseProviders, expression);
}
/// <summary>
/// The problem with this is that only under particular circumstances is the expression added to the context
/// so you wouldn't actually know if you are using it correctly or not and chances are you are not and therefore
/// the statement won't even execute whereas using the IAlterTableSyntax to modify a column is guaranteed to add
/// the expression to the context.
/// </summary>
/// <param name="columnName"></param>
/// <returns></returns>
[Obsolete("Use the IAlterTableSyntax to modify a column instead, this will be removed in future versions")]
public IAlterColumnSyntax Column(string columnName)
{
var expression = new AlterColumnExpression(_context.CurrentDatabaseProvider, _databaseProviders, _sqlSyntax) {Column = {Name = columnName}};
@@ -1,11 +1,22 @@
using Umbraco.Core.Persistence.Migrations.Syntax.Alter.Column;
using System;
using Umbraco.Core.Persistence.Migrations.Syntax.Alter.Column;
using Umbraco.Core.Persistence.Migrations.Syntax.Alter.Table;
namespace Umbraco.Core.Persistence.Migrations.Syntax.Alter
{
public interface IAlterSyntaxBuilder : IFluentSyntax
{
IAlterTableSyntax Table(string tableName);
IAlterTableSyntax Table(string tableName);
/// <summary>
/// The problem with this is that only under particular circumstances is the expression added to the context
/// so you wouldn't actually know if you are using it correctly or not and chances are you are not and therefore
/// the statement won't even execute whereas using the IAlterTableSyntax to modify a column is guaranteed to add
/// the expression to the context.
/// </summary>
/// <param name="columnName"></param>
/// <returns></returns>
[Obsolete("Use the IAlterTableSyntax to modify a column instead, this will be removed in future versions")]
IAlterColumnSyntax Column(string columnName);
}
}
@@ -4,7 +4,7 @@ using Umbraco.Core.Persistence.SqlSyntax;
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenSixZero
{
[Migration("7.6.0", 0, Constants.System.UmbracoMigrationName)]
[Migration("7.6.0", 3, Constants.System.UmbracoMigrationName)]
public class AddIndexToCmsMemberLoginName : MigrationBase
{
public AddIndexToCmsMemberLoginName(ISqlSyntaxProvider sqlSyntax, ILogger logger)
@@ -12,18 +12,43 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenSixZero
{ }
public override void Up()
{
var dbIndexes = SqlSyntax.GetDefinedIndexesDefinitions(Context.Database);
//make sure it doesn't already exist
if (dbIndexes.Any(x => x.IndexName.InvariantEquals("IX_cmsMember_LoginName")) == false)
{
Execute.Code(database =>
{
Create.Index("IX_cmsMember_LoginName").OnTable("cmsMember")
.OnColumn("LoginName")
.Ascending()
.WithOptions()
.NonClustered();
}
//Now we need to check if we can actually d6 this because we won't be able to if there's data in there that is too long
//http://issues.umbraco.org/issue/U4-9758
var colLen = (SqlSyntax is MySqlSyntaxProvider)
? database.ExecuteScalar<int?>("select max(LENGTH(LoginName)) from cmsMember")
: database.ExecuteScalar<int?>("select max(datalength(LoginName)) from cmsMember");
if (colLen < 900 == false && colLen != null)
{
return null;
}
var dbIndexes = SqlSyntax.GetDefinedIndexesDefinitions(Context.Database);
//make sure it doesn't already exist
if (dbIndexes.Any(x => x.IndexName.InvariantEquals("IX_cmsMember_LoginName")) == false)
{
var localContext = new LocalMigrationContext(Context.CurrentDatabaseProvider, database, SqlSyntax, Logger);
//we can apply the index
localContext.Create.Index("IX_cmsMember_LoginName").OnTable("cmsMember")
.OnColumn("LoginName")
.Ascending()
.WithOptions()
.NonClustered();
return localContext.GetSql();
}
return null;
});
}
public override void Down()
@@ -0,0 +1,50 @@
using System;
using System.Linq;
using Umbraco.Core.Logging;
using Umbraco.Core.Persistence.SqlSyntax;
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenSixZero
{
[Migration("7.6.0", 0, Constants.System.UmbracoMigrationName)]
public class NormalizeTemplateGuids : MigrationBase
{
public NormalizeTemplateGuids(ISqlSyntaxProvider sqlSyntax, ILogger logger)
: base(sqlSyntax, logger)
{ }
public override void Up()
{
Execute.Code(UpdateTemplateGuids);
}
private static string UpdateTemplateGuids(Database database)
{
// we need this migration because ppl running pre-7.6 on Cloud and Courier have templates in different
// environments having different GUIDs (Courier does not sync template GUIDs) and we need to normalize
// these GUIDs so templates with the same alias on different environments have the same GUID.
// however, if already running a prerelease version of 7.6, we do NOT want to normalize the GUIDs as quite
// probably, we are already running Deploy and the GUIDs are OK. assuming noone is running a prerelease
// of 7.6 on Courier.
// so... testing if we already have a 7.6.0 version installed. not pretty but...?
//
var version = database.FirstOrDefault<string>("SELECT version FROM umbracoMigration WHERE name=@name ORDER BY version DESC", new { name = Constants.System.UmbracoMigrationName });
if (version != null && version.StartsWith("7.6.0")) return string.Empty;
var updates = database.Query<dynamic>(@"SELECT umbracoNode.id, cmsTemplate.alias FROM umbracoNode
JOIN cmsTemplate ON umbracoNode.id=cmsTemplate.nodeId
WHERE nodeObjectType = @guid", new { guid = Constants.ObjectTypes.TemplateTypeGuid})
.Select(template => Tuple.Create((int) template.id, ("template____" + (string) template.alias).ToGuid()))
.ToList();
foreach (var update in updates)
database.Execute("UPDATE umbracoNode set uniqueId=@guid WHERE id=@id", new { guid = update.Item2, id = update.Item1 });
return string.Empty;
}
public override void Down()
{
throw new NotImplementedException();
}
}
}
@@ -0,0 +1,52 @@
using System.Linq;
using Umbraco.Core.Logging;
using Umbraco.Core.Persistence.SqlSyntax;
namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenSixZero
{
[Migration("7.6.0", 2, Constants.System.UmbracoMigrationName)]
public class ReduceLoginNameColumnsSize : MigrationBase
{
public ReduceLoginNameColumnsSize(ISqlSyntaxProvider sqlSyntax, ILogger logger)
: base(sqlSyntax, logger)
{ }
public override void Up()
{
//Now we need to check if we can actually d6 this because we won't be able to if there's data in there that is too long
//http://issues.umbraco.org/issue/U4-9758
Execute.Code(database =>
{
var dbIndexes = SqlSyntax.GetDefinedIndexesDefinitions(database);
var colLen = (SqlSyntax is MySqlSyntaxProvider)
? database.ExecuteScalar<int?>("select max(LENGTH(LoginName)) from cmsMember")
: database.ExecuteScalar<int?>("select max(datalength(LoginName)) from cmsMember");
if (colLen < 900 == false) return null;
var localContext = new LocalMigrationContext(Context.CurrentDatabaseProvider, database, SqlSyntax, Logger);
//if it exists we need to drop it first
if (dbIndexes.Any(x => x.IndexName.InvariantEquals("IX_cmsMember_LoginName")))
{
localContext.Delete.Index("IX_cmsMember_LoginName").OnTable("cmsMember");
}
//we can apply the col length change
localContext.Alter.Table("cmsMember")
.AlterColumn("LoginName")
.AsString(225)
.NotNullable();
return localContext.GetSql();
});
}
public override void Down()
{
}
}
}
@@ -29,7 +29,7 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenThreeZe
}).ToArray();
//must be non-nullable
Alter.Column("uniqueID").OnTable("umbracoNode").AsGuid().NotNullable();
Alter.Table("umbracoNode").AlterColumn("uniqueID").AsGuid().NotNullable();
//make sure it already exists
if (dbIndexes.Any(x => x.IndexName.InvariantEquals("IX_umbracoNodeUniqueID")))
@@ -70,6 +70,8 @@ namespace Umbraco.Core.Persistence.Repositories
{
//Remove 'published' xml from the cmsContentXml table for the unpublished content
Database.Delete<ContentXmlDto>("WHERE nodeId = @Id", new { Id = entity.Id });
entity.DeletedDate = DateTime.Now;
}
protected override void PersistNewItem(ContentXmlEntity<TContent> entity)
@@ -270,6 +270,8 @@ AND umbracoNode.id <> @id",
//Delete (base) node data
Database.Delete<NodeDto>("WHERE uniqueID = @Id", new { Id = entity.Key });
entity.DeletedDate = DateTime.Now;
}
#endregion
@@ -539,6 +541,8 @@ AND umbracoNode.id <> @id",
Database.Execute(
"DELETE FROM cmsDataTypePreValues WHERE id=@Id",
new { Id = entity.Id });
entity.DeletedDate = DateTime.Now;
}
protected override void PersistNewItem(PreValueEntity entity)
@@ -195,6 +195,8 @@ namespace Umbraco.Core.Persistence.Repositories
//Clear the cache entries that exist by uniqueid/item key
IsolatedCache.ClearCacheItem(GetCacheIdKey<IDictionaryItem>(entity.ItemKey));
IsolatedCache.ClearCacheItem(GetCacheIdKey<IDictionaryItem>(entity.Key));
entity.DeletedDate = DateTime.Now;
}
private void RecursiveDelete(Guid parentId)
@@ -167,6 +167,8 @@ namespace Umbraco.Core.Persistence.Repositories
// delete
Database.Delete(nodeDto);
entity.DeletedDate = DateTime.Now;
}
protected override void PersistNewItem(EntityContainer entity)
@@ -74,6 +74,7 @@ namespace Umbraco.Core.Persistence.Repositories
{
Database.Execute(delete, new { Id = GetEntityId(entity) });
}
entity.DeletedDate = DateTime.Now;
}
}
}
@@ -132,6 +132,11 @@ namespace Umbraco.Core.Persistence.Repositories
Database.Update(dto);
foreach (var removedRule in entity.RemovedRules)
{
Database.Delete<AccessRuleDto>("WHERE id=@Id", new { Id = removedRule });
}
foreach (var rule in entity.Rules)
{
if (rule.HasIdentity)
@@ -157,10 +162,6 @@ namespace Umbraco.Core.Persistence.Repositories
rule.Id = rule.Key.GetHashCode();
}
}
foreach (var removedRule in entity.RemovedRules)
{
Database.Delete<AccessRuleDto>("WHERE id=@Id", new {Id = removedRule});
}
entity.ClearRemovedRules();
@@ -311,6 +311,8 @@ namespace Umbraco.Core.Persistence.Repositories
var masterpageName = string.Concat(entity.Alias, ".master");
_masterpagesFileSystem.DeleteFile(masterpageName);
}
entity.DeletedDate = DateTime.Now;
}
#endregion
@@ -8,5 +8,6 @@ namespace Umbraco.Core.Persistence.UnitOfWork
IScope Scope { get; }
EventMessages Messages { get; }
IEventDispatcher Events { get; }
void Flush();
}
}
@@ -160,7 +160,33 @@ namespace Umbraco.Core.Persistence.UnitOfWork
_key = Guid.NewGuid();
}
public object Key
public void Flush()
{
if (_readOnly)
throw new NotSupportedException("This unit of work is read-only.");
while (_operations.Count > 0)
{
var operation = _operations.Dequeue();
switch (operation.Type)
{
case TransactionType.Insert:
operation.Repository.PersistNewItem(operation.Entity);
break;
case TransactionType.Delete:
operation.Repository.PersistDeletedItem(operation.Entity);
break;
case TransactionType.Update:
operation.Repository.PersistUpdatedItem(operation.Entity);
break;
}
}
_operations.Clear();
_key = Guid.NewGuid();
}
public object Key
{
get { return _key; }
}
@@ -20,6 +20,11 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters
public override object ConvertSourceToObject(PublishedPropertyType propertyType, object source, bool preview)
{
if(source == null)
{
return string.Empty;
}
return source.ToString();
}
+1
View File
@@ -465,6 +465,7 @@ namespace Umbraco.Core.Scoping
}
finally
{
// removes the ambient context (ambient scope already gone)
_scopeProvider.SetAmbient(null);
}
}
+41 -35
View File
@@ -1,16 +1,23 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace Umbraco.Core.Scoping
{
public class ScopeContext : IInstanceIdentifiable
{
private Dictionary<string, IEnlistedObject> _enlisted;
private bool _exiting;
public void ScopeExit(bool completed)
{
if (_enlisted == null)
return;
_exiting = true;
List<Exception> exceptions = null;
foreach (var enlisted in Enlisted.Values)
foreach (var enlisted in _enlisted.Values.OrderBy(x => x.Priority))
{
try
{
@@ -23,6 +30,7 @@ namespace Umbraco.Core.Scoping
exceptions.Add(e);
}
}
if (exceptions != null)
throw new AggregateException("Exceptions were thrown by listed actions.", exceptions);
}
@@ -42,73 +50,71 @@ namespace Umbraco.Core.Scoping
private interface IEnlistedObject
{
void Execute(bool completed);
int Priority { get; }
}
private class EnlistedObject<T> : IEnlistedObject
{
private readonly Action<bool, T> _action;
public EnlistedObject(T item)
{
Item = item;
}
public EnlistedObject(T item, Action<bool, T> action)
public EnlistedObject(T item, Action<bool, T> action, int priority)
{
Item = item;
Priority = priority;
_action = action;
}
public T Item { get; private set; }
public int Priority { get; private set; }
public void Execute(bool completed)
{
_action(completed, Item);
}
}
/// <inheritdoc />
// todo: replace with optional parameters when we can break things
public T Enlist<T>(string key, Func<T> creator)
{
IEnlistedObject enlisted;
if (Enlisted.TryGetValue(key, out enlisted))
{
var enlistedAs = enlisted as EnlistedObject<T>;
if (enlistedAs == null) throw new Exception("An item with a different type has already been enlisted with the same key.");
return enlistedAs.Item;
}
var enlistedOfT = new EnlistedObject<T>(creator());
Enlisted[key] = enlistedOfT;
return enlistedOfT.Item;
return Enlist(key, creator, null, 100);
}
/// <inheritdoc />
// todo: replace with optional parameters when we can break things
public T Enlist<T>(string key, Func<T> creator, Action<bool, T> action)
{
IEnlistedObject enlisted;
if (Enlisted.TryGetValue(key, out enlisted))
{
var enlistedAs = enlisted as EnlistedObject<T>;
if (enlistedAs == null) throw new Exception("An item with a different type has already been enlisted with the same key.");
return enlistedAs.Item;
}
var enlistedOfT = new EnlistedObject<T>(creator(), action);
Enlisted[key] = enlistedOfT;
return enlistedOfT.Item;
return Enlist(key, creator, action, 100);
}
/// <inheritdoc />
// todo: replace with optional parameters when we can break things
public void Enlist(string key, Action<bool> action)
{
Enlist<object>(key, null, (completed, item) => action(completed), 100);
}
public void Enlist(string key, Action<bool> action, int priority)
{
Enlist<object>(key, null, (completed, item) => action(completed), priority);
}
public T Enlist<T>(string key, Func<T> creator, Action<bool, T> action, int priority)
{
if (_exiting)
throw new InvalidOperationException("Cannot enlist now, context is exiting.");
var enlistedObjects = _enlisted ?? (_enlisted = new Dictionary<string, IEnlistedObject>());
IEnlistedObject enlisted;
if (Enlisted.TryGetValue(key, out enlisted))
if (enlistedObjects.TryGetValue(key, out enlisted))
{
var enlistedAs = enlisted as EnlistedObject<object>;
if (enlistedAs == null) throw new Exception("An item with a different type has already been enlisted with the same key.");
return;
var enlistedAs = enlisted as EnlistedObject<T>;
if (enlistedAs == null) throw new InvalidOperationException("An item with the key already exists, but with a different type.");
if (enlistedAs.Priority != priority) throw new InvalidOperationException("An item with the key already exits, but with a different priority.");
return enlistedAs.Item;
}
var enlistedOfT = new EnlistedObject<object>(null, (completed, item) => action(completed));
var enlistedOfT = new EnlistedObject<T>(creator == null ? default(T) : creator(), action, priority);
Enlisted[key] = enlistedOfT;
return enlistedOfT.Item;
}
}
}
@@ -191,6 +191,7 @@ namespace Umbraco.Core.Security
//track the last login date
user.LastLoginDateUtc = DateTime.UtcNow;
user.AccessFailedCount = 0;
await UserManager.UpdateAsync(user);
_logger.WriteCore(TraceEventType.Information, 0,
@@ -231,4 +232,4 @@ namespace Umbraco.Core.Security
return null;
}
}
}
}
+5 -29
View File
@@ -124,35 +124,11 @@ namespace Umbraco.Core.Services
private static Guid GetNodeObjectTypeGuid(UmbracoObjectTypes umbracoObjectType)
{
switch (umbracoObjectType)
{
case UmbracoObjectTypes.Document:
return Constants.ObjectTypes.DocumentGuid;
case UmbracoObjectTypes.MemberType:
return Constants.ObjectTypes.MemberTypeGuid;
case UmbracoObjectTypes.Media:
return Constants.ObjectTypes.MediaGuid;
case UmbracoObjectTypes.Template:
return Constants.ObjectTypes.TemplateTypeGuid;
case UmbracoObjectTypes.MediaType:
return Constants.ObjectTypes.MediaTypeGuid;
case UmbracoObjectTypes.DocumentType:
return Constants.ObjectTypes.DocumentTypeGuid;
case UmbracoObjectTypes.Member:
return Constants.ObjectTypes.MemberGuid;
case UmbracoObjectTypes.DataType:
return Constants.ObjectTypes.DataTypeGuid;
case UmbracoObjectTypes.MemberGroup:
return Constants.ObjectTypes.MemberGroupGuid;
case UmbracoObjectTypes.RecycleBin:
case UmbracoObjectTypes.Stylesheet:
case UmbracoObjectTypes.ContentItem:
case UmbracoObjectTypes.ContentItemType:
case UmbracoObjectTypes.ROOT:
case UmbracoObjectTypes.Unknown:
default:
throw new NotSupportedException("Unsupported object type (" + umbracoObjectType + ").");
}
var guid = umbracoObjectType.GetGuid();
if (guid == Guid.Empty)
throw new NotSupportedException("Unsupported object type (" + umbracoObjectType + ").");
return guid;
}
public IUmbracoEntity GetByKey(Guid key, bool loadBaseType = true)
+11 -1
View File
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Xml.Linq;
using Umbraco.Core.Models;
@@ -6,6 +7,15 @@ namespace Umbraco.Core.Services
{
public interface IPackagingService : IService
{
/// <summary>
/// This will fetch an Umbraco package file from the package repository and return the relative file path to the downloaded package file
/// </summary>
/// <param name="packageId"></param>
/// <param name="umbracoVersion"></param>
/// <param name="userId">The current user id performing the operation</param>
/// <returns></returns>
string FetchPackageFile(Guid packageId, Version umbracoVersion, int userId);
/// <summary>
/// Imports and saves package xml as <see cref="IContent"/>
/// </summary>
@@ -1,15 +1,20 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.UI.WebControls;
using System.Xml.Linq;
using System.Xml.XPath;
using Newtonsoft.Json;
using Umbraco.Core.Auditing;
using Umbraco.Core.Configuration;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.Events;
using Umbraco.Core.Exceptions;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
@@ -75,6 +80,61 @@ namespace Umbraco.Core.Services
_importedContentTypes = new Dictionary<string, IContentType>();
}
/// <summary>
/// This will fetch an Umbraco package file from the package repository and return the relative file path to the downloaded package file
/// </summary>
/// <param name="packageId"></param>
/// <param name="umbracoVersion"></param>
/// /// <param name="userId">The current user id performing the operation</param>
/// <returns></returns>
public string FetchPackageFile(Guid packageId, Version umbracoVersion, int userId)
{
var packageRepo = UmbracoConfig.For.UmbracoSettings().PackageRepositories.GetDefault();
using (var httpClient = new HttpClient())
using (var uow = _uowProvider.GetUnitOfWork())
{
//includeHidden = true because we don't care if it's hidden we want to get the file regardless
var url = string.Format("{0}/{1}?version={2}&includeHidden=true&asFile=true", packageRepo.RestApiUrl, packageId, umbracoVersion.ToString(3));
byte[] bytes;
try
{
bytes = httpClient.GetByteArrayAsync(url).GetAwaiter().GetResult();
}
catch (HttpRequestException ex)
{
throw new ConnectionException("An error occuring downloading the package from " + url, ex);
}
//successfull
if (bytes.Length > 0)
{
var packagePath = IOHelper.MapPath(SystemDirectories.Packages);
// Check for package directory
if (Directory.Exists(packagePath) == false)
Directory.CreateDirectory(packagePath);
var packageFilePath = Path.Combine(packagePath, packageId + ".umb");
using (var fs1 = new FileStream(packageFilePath, FileMode.Create))
{
fs1.Write(bytes, 0, bytes.Length);
return "packages\\" + packageId + ".umb";
}
}
Audit(uow, AuditType.PackagerInstall, string.Format("Package {0} fetched from {1}", packageId, packageRepo.Id), userId, -1);
return null;
}
}
private void Audit(IScopeUnitOfWork uow, AuditType type, string message, int userId, int objectId)
{
var auditRepo = _repositoryFactory.CreateAuditRepository(uow);
auditRepo.AddOrUpdate(new AuditItem(objectId, message, type, userId));
}
#region Content
/// <summary>
+2 -2
View File
@@ -20,7 +20,7 @@ namespace Umbraco.Core
/// <param name="entityType">The entity type part of the udi.</param>
/// <param name="id">The string id part of the udi.</param>
public StringUdi(string entityType, string id)
: base(entityType, "umb://" + entityType + "/" + id)
: base(entityType, "umb://" + entityType + "/" + Uri.EscapeUriString(id))
{
Id = id;
}
@@ -32,7 +32,7 @@ namespace Umbraco.Core
public StringUdi(Uri uriValue)
: base(uriValue)
{
Id = uriValue.AbsolutePath.TrimStart('/');
Id = Uri.UnescapeDataString(uriValue.AbsolutePath.TrimStart('/'));
}
/// <summary>
+2 -2
View File
@@ -166,8 +166,8 @@ namespace Umbraco.Core
return true;
}
return false;
}
}
/// <summary>
/// Determines whether [is of generic type] [the specified type].
/// </summary>
+45 -4
View File
@@ -2,6 +2,7 @@ using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reflection;
@@ -15,11 +16,51 @@ namespace Umbraco.Core
{
private static readonly ConcurrentDictionary<Tuple<Type, bool, bool, bool>, PropertyInfo[]> GetPropertiesCache
= new ConcurrentDictionary<Tuple<Type, bool, bool, bool>, PropertyInfo[]>();
private static readonly ConcurrentDictionary<Type, FieldInfo[]> GetFieldsCache
private static readonly ConcurrentDictionary<Type, FieldInfo[]> GetFieldsCache
= new ConcurrentDictionary<Type, FieldInfo[]>();
private static readonly Assembly[] EmptyAssemblies = new Assembly[0];
/// <summary>
/// Based on a type we'll check if it is IEnumerable{T} (or similar) and if so we'll return a List{T}, this will also deal with array types and return List{T} for those too.
/// If it cannot be done, null is returned.
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
internal static IList CreateGenericEnumerableFromObject(object obj)
{
var type = obj.GetType();
if (type.IsGenericType)
{
var genericTypeDef = type.GetGenericTypeDefinition();
if (genericTypeDef == typeof(IEnumerable<>)
|| genericTypeDef == typeof(ICollection<>)
|| genericTypeDef == typeof(Collection<>)
|| genericTypeDef == typeof(IList<>)
|| genericTypeDef == typeof(List<>)
//this will occur when Linq is used and we get the odd WhereIterator or DistinctIterators since those are special iterator types
|| obj is IEnumerable)
{
//if it is a IEnumerable<>, IList<T> or ICollection<> we'll use a List<>
var genericType = typeof(List<>).MakeGenericType(type.GetGenericArguments());
//pass in obj to fill the list
return (IList)Activator.CreateInstance(genericType, obj);
}
}
if (type.IsArray)
{
//if its an array, we'll use a List<>
var genericType = typeof(List<>).MakeGenericType(type.GetElementType());
//pass in obj to fill the list
return (IList)Activator.CreateInstance(genericType, obj);
}
return null;
}
/// <summary>
/// Checks if the method is actually overriding a base method
/// </summary>
@@ -45,8 +86,8 @@ namespace Umbraco.Core
if (assembly.IsAppCodeAssembly() || assembly.IsGlobalAsaxAssembly())
return EmptyAssemblies;
// find all assembly references that are referencing the current type's assembly since we
// find all assembly references that are referencing the current type's assembly since we
// should only be scanning those assemblies because any other assembly will definitely not
// contain sub type's of the one we're currently looking for
var name = assembly.GetName().Name;
+3 -2
View File
@@ -101,7 +101,8 @@ namespace Umbraco.Core
public override string ToString()
{
// UriValue is created in the ctor and is never null
return UriValue.ToString();
// use AbsoluteUri here and not ToString else it's not encoded!
return UriValue.AbsoluteUri;
}
/// <summary>
@@ -159,7 +160,7 @@ namespace Umbraco.Core
}
if (udiType == UdiType.StringUdi)
{
udi = path == string.Empty ? GetRootUdi(uri.Host) : new StringUdi(uri.Host, path);
udi = path == string.Empty ? GetRootUdi(uri.Host) : new StringUdi(uri.Host, Uri.UnescapeDataString(path));
return true;
}
if (tryParse) return false;
+9 -3
View File
@@ -100,9 +100,8 @@
<HintPath>..\packages\Owin.1.0\lib\net40\Owin.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Semver, Version=2.0.4.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Semver.2.0.4\lib\netstandard1.1\Semver.dll</HintPath>
<Private>True</Private>
<Reference Include="Semver, Version=1.1.2.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\semver.1.1.2\lib\net45\Semver.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.ComponentModel.Composition" />
@@ -292,6 +291,7 @@
<Compile Include="Configuration\UmbracoSettings\RazorStaticMappingElement.cs" />
<Compile Include="Configuration\UmbracoSettings\RepositoriesCollection.cs" />
<Compile Include="Configuration\UmbracoSettings\RepositoriesElement.cs" />
<Compile Include="Configuration\UmbracoSettings\RepositoryConfigExtensions.cs" />
<Compile Include="Configuration\UmbracoSettings\RepositoryElement.cs" />
<Compile Include="Configuration\UmbracoSettings\RequestHandlerElement.cs" />
<Compile Include="Configuration\UmbracoSettings\ScheduledTaskElement.cs" />
@@ -338,7 +338,11 @@
<Compile Include="Events\IDeletingMediaFilesEventArgs.cs" />
<Compile Include="Events\ScopeEventDispatcherBase.cs" />
<Compile Include="Events\ScopeLifespanMessagesFactory.cs" />
<Compile Include="Events\SupersedeEventAttribute.cs" />
<Compile Include="Exceptions\ConnectionException.cs" />
<Compile Include="HashCodeHelper.cs" />
<Compile Include="IHttpContextAccessor.cs" />
<Compile Include="Models\EntityBase\IDeletableEntity.cs" />
<Compile Include="Models\PublishedContent\PublishedContentTypeConverter.cs" />
<Compile Include="OrderedHashSet.cs" />
<Compile Include="Events\UninstallPackageEventArgs.cs" />
@@ -514,6 +518,8 @@
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSevenSixZero\AddIndexToUser2NodePermission.cs" />
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSevenSixZero\AddRelationTypeUniqueIdColumn.cs" />
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSevenSixZero\AddMacroUniqueIdColumn.cs" />
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSevenSixZero\ReduceLoginNameColumnsSize.cs" />
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSevenSixZero\NormalizeTemplateGuids.cs" />
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSevenSixZero\RemovePropertyDataIdIndex.cs" />
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSevenSixZero\RemoveUmbracoDeployTables.cs" />
<Compile Include="Persistence\Migrations\Upgrades\TargetVersionSevenThreeTwo\EnsureMigrationsTableIdentityIsCorrect.cs" />
+1 -5
View File
@@ -15,11 +15,7 @@
<package id="MySql.Data" version="6.9.9" targetFramework="net45" />
<package id="Newtonsoft.Json" version="10.0.2" targetFramework="net45" />
<package id="Owin" version="1.0" targetFramework="net45" />
<package id="Semver" version="2.0.4" targetFramework="net45" />
<package id="semver" version="1.1.2" targetFramework="net45" />
<package id="SharpZipLib" version="0.86.0" targetFramework="net45" />
<package id="SqlServerCE" version="4.0.0.1" targetFramework="net45" />
<package id="System.Runtime" version="4.3.0" targetFramework="net45" />
<package id="System.Runtime.Extensions" version="4.3.0" targetFramework="net45" />
<package id="System.Runtime.InteropServices" version="4.3.0" targetFramework="net45" />
<package id="System.Text.RegularExpressions" version="4.3.0" targetFramework="net45" />
</packages>
@@ -7,6 +7,7 @@ using Umbraco.Core.Models.Membership;
using Umbraco.Core.Services;
using Umbraco.Tests.TestHelpers;
using Umbraco.Web.Cache;
using System.Linq;
namespace Umbraco.Tests.Cache
{
@@ -31,70 +32,70 @@ namespace Umbraco.Tests.Cache
new EventDefinition<ISectionService, EventArgs>(null, ServiceContext.SectionService, new EventArgs(), "Deleted"),
new EventDefinition<ISectionService, EventArgs>(null, ServiceContext.SectionService, new EventArgs(), "New"),
new EventDefinition<IUserService, SaveEventArgs<IUserType>>(null, ServiceContext.UserService, new SaveEventArgs<IUserType>((IUserType) null)),
new EventDefinition<IUserService, DeleteEventArgs<IUserType>>(null, ServiceContext.UserService, new DeleteEventArgs<IUserType>((IUserType) null)),
new EventDefinition<IUserService, SaveEventArgs<IUserType>>(null, ServiceContext.UserService, new SaveEventArgs<IUserType>(Enumerable.Empty<IUserType>())),
new EventDefinition<IUserService, DeleteEventArgs<IUserType>>(null, ServiceContext.UserService, new DeleteEventArgs<IUserType>(Enumerable.Empty<IUserType>())),
new EventDefinition<IUserService, SaveEventArgs<IUser>>(null, ServiceContext.UserService, new SaveEventArgs<IUser>((IUser) null)),
new EventDefinition<IUserService, DeleteEventArgs<IUser>>(null, ServiceContext.UserService, new DeleteEventArgs<IUser>((IUser) null)),
new EventDefinition<IUserService, DeleteEventArgs<IUser>>(null, ServiceContext.UserService, new DeleteEventArgs<IUser>((IUser) null)),
new EventDefinition<IUserService, SaveEventArgs<IUser>>(null, ServiceContext.UserService, new SaveEventArgs<IUser>(Enumerable.Empty<IUser>())),
new EventDefinition<IUserService, DeleteEventArgs<IUser>>(null, ServiceContext.UserService, new DeleteEventArgs<IUser>(Enumerable.Empty<IUser>())),
new EventDefinition<IUserService, DeleteEventArgs<IUser>>(null, ServiceContext.UserService, new DeleteEventArgs<IUser>(Enumerable.Empty<IUser>())),
new EventDefinition<ILocalizationService, SaveEventArgs<IDictionaryItem>>(null, ServiceContext.LocalizationService, new SaveEventArgs<IDictionaryItem>((IDictionaryItem) null)),
new EventDefinition<ILocalizationService, DeleteEventArgs<IDictionaryItem>>(null, ServiceContext.LocalizationService, new DeleteEventArgs<IDictionaryItem>((IDictionaryItem) null)),
new EventDefinition<ILocalizationService, SaveEventArgs<IDictionaryItem>>(null, ServiceContext.LocalizationService, new SaveEventArgs<IDictionaryItem>(Enumerable.Empty<IDictionaryItem>())),
new EventDefinition<ILocalizationService, DeleteEventArgs<IDictionaryItem>>(null, ServiceContext.LocalizationService, new DeleteEventArgs<IDictionaryItem>(Enumerable.Empty<IDictionaryItem>())),
new EventDefinition<IDataTypeService, SaveEventArgs<IDataTypeDefinition>>(null, ServiceContext.DataTypeService, new SaveEventArgs<IDataTypeDefinition>((IDataTypeDefinition) null)),
new EventDefinition<IDataTypeService, DeleteEventArgs<IDataTypeDefinition>>(null, ServiceContext.DataTypeService, new DeleteEventArgs<IDataTypeDefinition>((IDataTypeDefinition) null)),
new EventDefinition<IDataTypeService, SaveEventArgs<IDataTypeDefinition>>(null, ServiceContext.DataTypeService, new SaveEventArgs<IDataTypeDefinition>(Enumerable.Empty<IDataTypeDefinition>())),
new EventDefinition<IDataTypeService, DeleteEventArgs<IDataTypeDefinition>>(null, ServiceContext.DataTypeService, new DeleteEventArgs<IDataTypeDefinition>(Enumerable.Empty<IDataTypeDefinition>())),
new EventDefinition<IFileService, SaveEventArgs<Stylesheet>>(null, ServiceContext.FileService, new SaveEventArgs<Stylesheet>((Stylesheet) null)),
new EventDefinition<IFileService, DeleteEventArgs<Stylesheet>>(null, ServiceContext.FileService, new DeleteEventArgs<Stylesheet>((Stylesheet) null)),
new EventDefinition<IFileService, SaveEventArgs<Stylesheet>>(null, ServiceContext.FileService, new SaveEventArgs<Stylesheet>(Enumerable.Empty<Stylesheet>())),
new EventDefinition<IFileService, DeleteEventArgs<Stylesheet>>(null, ServiceContext.FileService, new DeleteEventArgs<Stylesheet>(Enumerable.Empty<Stylesheet>())),
new EventDefinition<IDomainService, SaveEventArgs<IDomain>>(null, ServiceContext.DomainService, new SaveEventArgs<IDomain>((IDomain) null)),
new EventDefinition<IDomainService, DeleteEventArgs<IDomain>>(null, ServiceContext.DomainService, new DeleteEventArgs<IDomain>((IDomain) null)),
new EventDefinition<IDomainService, SaveEventArgs<IDomain>>(null, ServiceContext.DomainService, new SaveEventArgs<IDomain>(Enumerable.Empty<IDomain>())),
new EventDefinition<IDomainService, DeleteEventArgs<IDomain>>(null, ServiceContext.DomainService, new DeleteEventArgs<IDomain>(Enumerable.Empty<IDomain>())),
new EventDefinition<ILocalizationService, SaveEventArgs<ILanguage>>(null, ServiceContext.LocalizationService, new SaveEventArgs<ILanguage>((ILanguage) null)),
new EventDefinition<ILocalizationService, DeleteEventArgs<ILanguage>>(null, ServiceContext.LocalizationService, new DeleteEventArgs<ILanguage>((ILanguage) null)),
new EventDefinition<ILocalizationService, SaveEventArgs<ILanguage>>(null, ServiceContext.LocalizationService, new SaveEventArgs<ILanguage>(Enumerable.Empty<ILanguage>())),
new EventDefinition<ILocalizationService, DeleteEventArgs<ILanguage>>(null, ServiceContext.LocalizationService, new DeleteEventArgs<ILanguage>(Enumerable.Empty<ILanguage>())),
new EventDefinition<IContentTypeService, SaveEventArgs<IContentType>>(null, ServiceContext.ContentTypeService, new SaveEventArgs<IContentType>((IContentType) null)),
new EventDefinition<IContentTypeService, DeleteEventArgs<IContentType>>(null, ServiceContext.ContentTypeService, new DeleteEventArgs<IContentType>((IContentType) null)),
new EventDefinition<IContentTypeService, SaveEventArgs<IMediaType>>(null, ServiceContext.ContentTypeService, new SaveEventArgs<IMediaType>((IMediaType) null)),
new EventDefinition<IContentTypeService, DeleteEventArgs<IMediaType>>(null, ServiceContext.ContentTypeService, new DeleteEventArgs<IMediaType>((IMediaType) null)),
new EventDefinition<IContentTypeService, SaveEventArgs<IContentType>>(null, ServiceContext.ContentTypeService, new SaveEventArgs<IContentType>(Enumerable.Empty<IContentType>())),
new EventDefinition<IContentTypeService, DeleteEventArgs<IContentType>>(null, ServiceContext.ContentTypeService, new DeleteEventArgs<IContentType>(Enumerable.Empty<IContentType>())),
new EventDefinition<IContentTypeService, SaveEventArgs<IMediaType>>(null, ServiceContext.ContentTypeService, new SaveEventArgs<IMediaType>(Enumerable.Empty<IMediaType>())),
new EventDefinition<IContentTypeService, DeleteEventArgs<IMediaType>>(null, ServiceContext.ContentTypeService, new DeleteEventArgs<IMediaType>(Enumerable.Empty<IMediaType>())),
new EventDefinition<IMemberTypeService, SaveEventArgs<IMemberType>>(null, ServiceContext.MemberTypeService, new SaveEventArgs<IMemberType>((IMemberType) null)),
new EventDefinition<IMemberTypeService, DeleteEventArgs<IMemberType>>(null, ServiceContext.MemberTypeService, new DeleteEventArgs<IMemberType>((IMemberType) null)),
new EventDefinition<IMemberTypeService, SaveEventArgs<IMemberType>>(null, ServiceContext.MemberTypeService, new SaveEventArgs<IMemberType>(Enumerable.Empty<IMemberType>())),
new EventDefinition<IMemberTypeService, DeleteEventArgs<IMemberType>>(null, ServiceContext.MemberTypeService, new DeleteEventArgs<IMemberType>(Enumerable.Empty<IMemberType>())),
new EventDefinition<IFileService, SaveEventArgs<ITemplate>>(null, ServiceContext.FileService, new SaveEventArgs<ITemplate>((ITemplate) null)),
new EventDefinition<IFileService, DeleteEventArgs<ITemplate>>(null, ServiceContext.FileService, new DeleteEventArgs<ITemplate>((ITemplate) null)),
new EventDefinition<IFileService, SaveEventArgs<ITemplate>>(null, ServiceContext.FileService, new SaveEventArgs<ITemplate>(Enumerable.Empty<ITemplate>())),
new EventDefinition<IFileService, DeleteEventArgs<ITemplate>>(null, ServiceContext.FileService, new DeleteEventArgs<ITemplate>(Enumerable.Empty<ITemplate>())),
new EventDefinition<IMacroService, SaveEventArgs<IMacro>>(null, ServiceContext.MacroService, new SaveEventArgs<IMacro>((IMacro) null)),
new EventDefinition<IMacroService, DeleteEventArgs<IMacro>>(null, ServiceContext.MacroService, new DeleteEventArgs<IMacro>((IMacro) null)),
new EventDefinition<IMacroService, SaveEventArgs<IMacro>>(null, ServiceContext.MacroService, new SaveEventArgs<IMacro>(Enumerable.Empty<IMacro>())),
new EventDefinition<IMacroService, DeleteEventArgs<IMacro>>(null, ServiceContext.MacroService, new DeleteEventArgs<IMacro>(Enumerable.Empty<IMacro>())),
new EventDefinition<IMemberService, SaveEventArgs<IMember>>(null, ServiceContext.MemberService, new SaveEventArgs<IMember>((IMember) null)),
new EventDefinition<IMemberService, DeleteEventArgs<IMember>>(null, ServiceContext.MemberService, new DeleteEventArgs<IMember>((IMember) null)),
new EventDefinition<IMemberService, SaveEventArgs<IMember>>(null, ServiceContext.MemberService, new SaveEventArgs<IMember>(Enumerable.Empty<IMember>())),
new EventDefinition<IMemberService, DeleteEventArgs<IMember>>(null, ServiceContext.MemberService, new DeleteEventArgs<IMember>(Enumerable.Empty<IMember>())),
new EventDefinition<IMemberGroupService, SaveEventArgs<IMemberGroup>>(null, ServiceContext.MemberGroupService, new SaveEventArgs<IMemberGroup>((IMemberGroup) null)),
new EventDefinition<IMemberGroupService, DeleteEventArgs<IMemberGroup>>(null, ServiceContext.MemberGroupService, new DeleteEventArgs<IMemberGroup>((IMemberGroup) null)),
new EventDefinition<IMemberGroupService, SaveEventArgs<IMemberGroup>>(null, ServiceContext.MemberGroupService, new SaveEventArgs<IMemberGroup>(Enumerable.Empty<IMemberGroup>())),
new EventDefinition<IMemberGroupService, DeleteEventArgs<IMemberGroup>>(null, ServiceContext.MemberGroupService, new DeleteEventArgs<IMemberGroup>(Enumerable.Empty<IMemberGroup>())),
new EventDefinition<IMediaService, SaveEventArgs<IMedia>>(null, ServiceContext.MediaService, new SaveEventArgs<IMedia>((IMedia) null)),
new EventDefinition<IMediaService, DeleteEventArgs<IMedia>>(null, ServiceContext.MediaService, new DeleteEventArgs<IMedia>((IMedia) null)),
new EventDefinition<IMediaService, SaveEventArgs<IMedia>>(null, ServiceContext.MediaService, new SaveEventArgs<IMedia>(Enumerable.Empty<IMedia>())),
new EventDefinition<IMediaService, DeleteEventArgs<IMedia>>(null, ServiceContext.MediaService, new DeleteEventArgs<IMedia>(Enumerable.Empty<IMedia>())),
new EventDefinition<IMediaService, MoveEventArgs<IMedia>>(null, ServiceContext.MediaService, new MoveEventArgs<IMedia>(new MoveEventInfo<IMedia>(null, "", -1)), "Moved"),
new EventDefinition<IMediaService, MoveEventArgs<IMedia>>(null, ServiceContext.MediaService, new MoveEventArgs<IMedia>(new MoveEventInfo<IMedia>(null, "", -1)), "Trashed"),
new EventDefinition<IMediaService, RecycleBinEventArgs>(null, ServiceContext.MediaService, new RecycleBinEventArgs(Guid.NewGuid(), new Dictionary<int, IEnumerable<Property>>(), true)),
new EventDefinition<IContentService, SaveEventArgs<IContent>>(null, ServiceContext.ContentService, new SaveEventArgs<IContent>((IContent) null)),
new EventDefinition<IContentService, DeleteEventArgs<IContent>>(null, ServiceContext.ContentService, new DeleteEventArgs<IContent>((IContent) null)),
new EventDefinition<IContentService, SaveEventArgs<IContent>>(null, ServiceContext.ContentService, new SaveEventArgs<IContent>(Enumerable.Empty<IContent>())),
new EventDefinition<IContentService, DeleteEventArgs<IContent>>(null, ServiceContext.ContentService, new DeleteEventArgs<IContent>(Enumerable.Empty<IContent>())),
new EventDefinition<IContentService, CopyEventArgs<IContent>>(null, ServiceContext.ContentService, new CopyEventArgs<IContent>(null, null, -1)),
new EventDefinition<IContentService, MoveEventArgs<IContent>>(null, ServiceContext.ContentService, new MoveEventArgs<IContent>(new MoveEventInfo<IContent>(null, "", -1)), "Trashed"),
new EventDefinition<IContentService, RecycleBinEventArgs>(null, ServiceContext.ContentService, new RecycleBinEventArgs(Guid.NewGuid(), new Dictionary<int, IEnumerable<Property>>(), true)),
new EventDefinition<IContentService, PublishEventArgs<IContent>>(null, ServiceContext.ContentService, new PublishEventArgs<IContent>((IContent) null), "Published"),
new EventDefinition<IContentService, PublishEventArgs<IContent>>(null, ServiceContext.ContentService, new PublishEventArgs<IContent>((IContent) null), "UnPublished"),
new EventDefinition<IContentService, PublishEventArgs<IContent>>(null, ServiceContext.ContentService, new PublishEventArgs<IContent>(Enumerable.Empty<IContent>()), "Published"),
new EventDefinition<IContentService, PublishEventArgs<IContent>>(null, ServiceContext.ContentService, new PublishEventArgs<IContent>(Enumerable.Empty<IContent>()), "UnPublished"),
new EventDefinition<IPublicAccessService, SaveEventArgs<PublicAccessEntry>>(null, ServiceContext.PublicAccessService, new SaveEventArgs<PublicAccessEntry>((PublicAccessEntry) null)),
new EventDefinition<IPublicAccessService, DeleteEventArgs<PublicAccessEntry>>(null, ServiceContext.PublicAccessService, new DeleteEventArgs<PublicAccessEntry>((PublicAccessEntry) null)),
new EventDefinition<IPublicAccessService, SaveEventArgs<PublicAccessEntry>>(null, ServiceContext.PublicAccessService, new SaveEventArgs<PublicAccessEntry>(Enumerable.Empty<PublicAccessEntry>())),
new EventDefinition<IPublicAccessService, DeleteEventArgs<PublicAccessEntry>>(null, ServiceContext.PublicAccessService, new DeleteEventArgs<PublicAccessEntry>(Enumerable.Empty<PublicAccessEntry>())),
new EventDefinition<IRelationService, SaveEventArgs<IRelationType>>(null, ServiceContext.RelationService, new SaveEventArgs<IRelationType>((IRelationType) null)),
new EventDefinition<IRelationService, DeleteEventArgs<IRelationType>>(null, ServiceContext.RelationService, new DeleteEventArgs<IRelationType>((IRelationType) null)),
new EventDefinition<IRelationService, SaveEventArgs<IRelationType>>(null, ServiceContext.RelationService, new SaveEventArgs<IRelationType>(Enumerable.Empty<IRelationType>())),
new EventDefinition<IRelationService, DeleteEventArgs<IRelationType>>(null, ServiceContext.RelationService, new DeleteEventArgs<IRelationType>(Enumerable.Empty<IRelationType>())),
new EventDefinition<IRelationService, SaveEventArgs<IRelationType>>(null, ServiceContext.RelationService, new SaveEventArgs<IRelationType>((IRelationType) null)),
new EventDefinition<IRelationService, DeleteEventArgs<IRelationType>>(null, ServiceContext.RelationService, new DeleteEventArgs<IRelationType>((IRelationType) null)),
new EventDefinition<IRelationService, SaveEventArgs<IRelationType>>(null, ServiceContext.RelationService, new SaveEventArgs<IRelationType>(Enumerable.Empty<IRelationType>())),
new EventDefinition<IRelationService, DeleteEventArgs<IRelationType>>(null, ServiceContext.RelationService, new DeleteEventArgs<IRelationType>(Enumerable.Empty<IRelationType>())),
};
foreach (var definition in definitions)
@@ -4,13 +4,16 @@ using System.Linq;
using Moq;
using NUnit.Framework;
using Umbraco.Core.Events;
using Umbraco.Core.Models;
using Umbraco.Core.Persistence;
using Umbraco.Core.Scoping;
using Umbraco.Tests.TestHelpers;
using Umbraco.Tests.TestHelpers.Entities;
namespace Umbraco.Tests.Scoping
{
[TestFixture]
public class ScopeEventDispatcherTests
public class ScopeEventDispatcherTests : BaseUmbracoConfigurationTest
{
[SetUp]
public void Setup()
@@ -79,7 +82,7 @@ namespace Umbraco.Tests.Scoping
var events = scope.Events.GetEvents(EventDefinitionFilter.All).ToArray();
var knownNames = new[] { "DoThing1", "DoThing2", "DoThing3" };
var knownArgTypes = new[] { typeof (SaveEventArgs<string>), typeof (SaveEventArgs<int>), typeof (SaveEventArgs<decimal>) };
var knownArgTypes = new[] { typeof(SaveEventArgs<string>), typeof(SaveEventArgs<int>), typeof(SaveEventArgs<decimal>) };
for (var i = 0; i < events.Length; i++)
{
@@ -89,6 +92,166 @@ namespace Umbraco.Tests.Scoping
}
}
[Test]
public void SupersededEvents()
{
DoSaveForContent += OnDoThingFail;
DoDeleteForContent += OnDoThingFail;
DoForTestArgs += OnDoThingFail;
DoForTestArgs2 += OnDoThingFail;
var contentType = MockedContentTypes.CreateBasicContentType();
var content1 = MockedContent.CreateBasicContent(contentType);
content1.Id = 123;
var content2 = MockedContent.CreateBasicContent(contentType);
content2.Id = 456;
var content3 = MockedContent.CreateBasicContent(contentType);
content3.Id = 789;
var scopeProvider = new ScopeProvider(Mock.Of<IDatabaseFactory2>());
using (var scope = scopeProvider.CreateScope(eventDispatcher: new PassiveEventDispatcher()))
{
//content1 will be filtered from the args
scope.Events.Dispatch(DoSaveForContent, this, new SaveEventArgs<IContent>(new[]{ content1 , content3}));
scope.Events.Dispatch(DoDeleteForContent, this, new DeleteEventArgs<IContent>(content1));
scope.Events.Dispatch(DoSaveForContent, this, new SaveEventArgs<IContent>(content2));
//this entire event will be filtered
scope.Events.Dispatch(DoForTestArgs, this, new TestEventArgs(content1));
scope.Events.Dispatch(DoForTestArgs2, this, new TestEventArgs2(content1));
// events have been queued
var events = scope.Events.GetEvents(EventDefinitionFilter.All).ToArray();
Assert.AreEqual(4, events.Length);
Assert.AreEqual(typeof(SaveEventArgs<IContent>), events[0].Args.GetType());
Assert.AreEqual(1, ((SaveEventArgs<IContent>)events[0].Args).SavedEntities.Count());
Assert.AreEqual(content3.Id, ((SaveEventArgs<IContent>)events[0].Args).SavedEntities.First().Id);
Assert.AreEqual(typeof(DeleteEventArgs<IContent>), events[1].Args.GetType());
Assert.AreEqual(content1.Id, ((DeleteEventArgs<IContent>) events[1].Args).DeletedEntities.First().Id);
Assert.AreEqual(typeof(SaveEventArgs<IContent>), events[2].Args.GetType());
Assert.AreEqual(content2.Id, ((SaveEventArgs<IContent>)events[2].Args).SavedEntities.First().Id);
Assert.AreEqual(typeof(TestEventArgs2), events[3].Args.GetType());
}
}
/// <summary>
/// This will test that when we track events that before we Get the events we normalize all of the
/// event entities to be the latest one (most current) found amongst the event so that there is
/// no 'stale' entities in any of the args
/// </summary>
[Test]
public void LatestEntities()
{
DoSaveForContent += OnDoThingFail;
var now = DateTime.Now;
var contentType = MockedContentTypes.CreateBasicContentType();
var content1 = MockedContent.CreateBasicContent(contentType);
content1.Id = 123;
content1.UpdateDate = now.AddMinutes(1);
var content2 = MockedContent.CreateBasicContent(contentType);
content2.Id = 123;
content2.UpdateDate = now.AddMinutes(2);
var content3 = MockedContent.CreateBasicContent(contentType);
content3.Id = 123;
content3.UpdateDate = now.AddMinutes(3);
var scopeProvider = new ScopeProvider(Mock.Of<IDatabaseFactory2>());
using (var scope = scopeProvider.CreateScope(eventDispatcher: new PassiveEventDispatcher()))
{
scope.Events.Dispatch(DoSaveForContent, this, new SaveEventArgs<IContent>(content1));
scope.Events.Dispatch(DoSaveForContent, this, new SaveEventArgs<IContent>(content2));
scope.Events.Dispatch(DoSaveForContent, this, new SaveEventArgs<IContent>(content3));
// events have been queued
var events = scope.Events.GetEvents(EventDefinitionFilter.All).ToArray();
Assert.AreEqual(3, events.Length);
foreach (var t in events)
{
var args = (SaveEventArgs<IContent>)t.Args;
foreach (var entity in args.SavedEntities)
{
Assert.AreEqual(content3, entity);
Assert.IsTrue(object.ReferenceEquals(content3, entity));
}
}
}
}
[Test]
public void FirstIn()
{
DoSaveForContent += OnDoThingFail;
var now = DateTime.Now;
var contentType = MockedContentTypes.CreateBasicContentType();
var content1 = MockedContent.CreateBasicContent(contentType);
content1.Id = 123;
content1.UpdateDate = now.AddMinutes(1);
var content2 = MockedContent.CreateBasicContent(contentType);
content2.Id = 123;
content1.UpdateDate = now.AddMinutes(2);
var content3 = MockedContent.CreateBasicContent(contentType);
content3.Id = 123;
content1.UpdateDate = now.AddMinutes(3);
var scopeProvider = new ScopeProvider(Mock.Of<IDatabaseFactory2>());
using (var scope = scopeProvider.CreateScope(eventDispatcher: new PassiveEventDispatcher()))
{
scope.Events.Dispatch(DoSaveForContent, this, new SaveEventArgs<IContent>(content1));
scope.Events.Dispatch(DoSaveForContent, this, new SaveEventArgs<IContent>(content2));
scope.Events.Dispatch(DoSaveForContent, this, new SaveEventArgs<IContent>(content3));
// events have been queued
var events = scope.Events.GetEvents(EventDefinitionFilter.FirstIn).ToArray();
Assert.AreEqual(1, events.Length);
Assert.AreEqual(content1, ((SaveEventArgs<IContent>) events[0].Args).SavedEntities.First());
Assert.IsTrue(object.ReferenceEquals(content1, ((SaveEventArgs<IContent>)events[0].Args).SavedEntities.First()));
Assert.AreEqual(content1.UpdateDate, ((SaveEventArgs<IContent>) events[0].Args).SavedEntities.First().UpdateDate);
}
}
[Test]
public void LastIn()
{
DoSaveForContent += OnDoThingFail;
var now = DateTime.Now;
var contentType = MockedContentTypes.CreateBasicContentType();
var content1 = MockedContent.CreateBasicContent(contentType);
content1.Id = 123;
content1.UpdateDate = now.AddMinutes(1);
var content2 = MockedContent.CreateBasicContent(contentType);
content2.Id = 123;
content2.UpdateDate = now.AddMinutes(2);
var content3 = MockedContent.CreateBasicContent(contentType);
content3.Id = 123;
content3.UpdateDate = now.AddMinutes(3);
var scopeProvider = new ScopeProvider(Mock.Of<IDatabaseFactory2>());
using (var scope = scopeProvider.CreateScope(eventDispatcher: new PassiveEventDispatcher()))
{
scope.Events.Dispatch(DoSaveForContent, this, new SaveEventArgs<IContent>(content1));
scope.Events.Dispatch(DoSaveForContent, this, new SaveEventArgs<IContent>(content2));
scope.Events.Dispatch(DoSaveForContent, this, new SaveEventArgs<IContent>(content3));
// events have been queued
var events = scope.Events.GetEvents(EventDefinitionFilter.LastIn).ToArray();
Assert.AreEqual(1, events.Length);
Assert.AreEqual(content3, ((SaveEventArgs<IContent>)events[0].Args).SavedEntities.First());
Assert.IsTrue(object.ReferenceEquals(content3, ((SaveEventArgs<IContent>)events[0].Args).SavedEntities.First()));
Assert.AreEqual(content3.UpdateDate, ((SaveEventArgs<IContent>)events[0].Args).SavedEntities.First().UpdateDate);
}
}
[TestCase(true)]
[TestCase(false)]
public void EventsDispatching_Passive(bool complete)
@@ -177,12 +340,41 @@ namespace Umbraco.Tests.Scoping
Assert.Fail();
}
public static event EventHandler<SaveEventArgs<IContent>> DoSaveForContent;
public static event EventHandler<DeleteEventArgs<IContent>> DoDeleteForContent;
public static event EventHandler<TestEventArgs> DoForTestArgs;
public static event EventHandler<TestEventArgs2> DoForTestArgs2;
public static event EventHandler<SaveEventArgs<string>> DoThing1;
public static event EventHandler<SaveEventArgs<int>> DoThing2;
public static event TypedEventHandler<ScopeEventDispatcherTests, SaveEventArgs<decimal>> DoThing3;
public class TestEventArgs : CancellableObjectEventArgs
{
public TestEventArgs(object eventObject) : base(eventObject)
{
}
public object MyEventObject
{
get { return EventObject; }
}
}
[SupersedeEvent(typeof(TestEventArgs))]
public class TestEventArgs2 : CancellableObjectEventArgs
{
public TestEventArgs2(object eventObject) : base(eventObject)
{
}
public object MyEventObject
{
get { return EventObject; }
}
}
public class PassiveEventDispatcher : ScopeEventDispatcherBase
{
public PassiveEventDispatcher()
+39 -1
View File
@@ -591,7 +591,7 @@ namespace Umbraco.Tests.Scoping
Assert.IsNull(scopeProvider.AmbientContext);
// back to original thread
ScopeProvider.HttpContextItemsGetter = () => httpContextItems;
ScopeProvider.HttpContextItemsGetter = () => httpContextItems;
}
Assert.IsNotNull(scopeProvider.AmbientScope);
Assert.AreSame(scope, scopeProvider.AmbientScope);
@@ -656,6 +656,44 @@ namespace Umbraco.Tests.Scoping
Assert.IsNotNull(ambientContext); // the context is still there
}
[TestCase(true)]
[TestCase(false)]
public void ScopeContextEnlistAgain(bool complete)
{
var scopeProvider = DatabaseContext.ScopeProvider;
bool? completed = null;
Exception exception = null;
Assert.IsNull(scopeProvider.AmbientScope);
using (var scope = scopeProvider.CreateScope())
{
scopeProvider.Context.Enlist("name", c =>
{
completed = c;
// at that point the scope is gone, but the context is still there
var ambientContext = scopeProvider.AmbientContext;
try
{
ambientContext.Enlist("another", c2 => { });
}
catch (Exception e)
{
exception = e;
}
});
if (complete)
scope.Complete();
}
Assert.IsNull(scopeProvider.AmbientScope);
Assert.IsNull(scopeProvider.AmbientContext);
Assert.IsNotNull(completed);
Assert.IsNotNull(exception);
Assert.IsInstanceOf<InvalidOperationException>(exception);
}
[Test]
public void ScopeContextException()
{
+3 -1
View File
@@ -179,7 +179,9 @@ namespace Umbraco.Tests.Scoping
scope.Complete();
}
Assert.AreEqual(complete ? 2 : 0, evented);
//The reason why there is only 1 event occuring is because we are publishing twice for the same event for the same
//object and the scope deduplicates the events (uses the latest)
Assert.AreEqual(complete ? 1 : 0, evented);
// this should never change
Assert.AreEqual(beforeOuterXml, beforeXml.OuterXml);
+28
View File
@@ -31,6 +31,34 @@ namespace Umbraco.Tests
Assert.AreEqual("umb://" + Constants.UdiEntityType.AnyString + "/test-id", udi.ToString());
}
[Test]
public void StringEncodingTest()
{
// absolute path is unescaped
var uri = new Uri("umb://" + Constants.UdiEntityType.AnyString + "/this%20is%20a%20test");
Assert.AreEqual("umb://" + Constants.UdiEntityType.AnyString + "/this is a test", uri.ToString());
Assert.AreEqual("umb://" + Constants.UdiEntityType.AnyString + "/this%20is%20a%20test", uri.AbsoluteUri);
Assert.AreEqual("/this%20is%20a%20test", uri.AbsolutePath);
Assert.AreEqual("/this is a test", Uri.UnescapeDataString(uri.AbsolutePath));
Assert.AreEqual("%2Fthis%20is%20a%20test", Uri.EscapeDataString("/this is a test"));
Assert.AreEqual("/this%20is%20a%20test", Uri.EscapeUriString("/this is a test"));
var udi = Udi.Parse("umb://" + Constants.UdiEntityType.AnyString + "/this%20is%20a%20test");
Assert.AreEqual(Constants.UdiEntityType.AnyString, udi.EntityType);
Assert.IsInstanceOf<StringUdi>(udi);
var stringEntityId = udi as StringUdi;
Assert.IsNotNull(stringEntityId);
Assert.AreEqual("this is a test", stringEntityId.Id);
Assert.AreEqual("umb://" + Constants.UdiEntityType.AnyString + "/this%20is%20a%20test", udi.ToString());
var udi2 = new StringUdi(Constants.UdiEntityType.AnyString, "this is a test");
Assert.AreEqual(udi, udi2);
var udi3 = new StringUdi(Constants.UdiEntityType.AnyString, "path to/this is a test.xyz");
Assert.AreEqual("umb://" + Constants.UdiEntityType.AnyString + "/path%20to/this%20is%20a%20test.xyz", udi3.ToString());
}
[Test]
public void GuidEntityCtorTest()
{
+2 -3
View File
@@ -97,9 +97,8 @@
<Reference Include="Owin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f0ebd12fd5e55cc5, processorArchitecture=MSIL">
<HintPath>..\packages\Owin.1.0\lib\net40\Owin.dll</HintPath>
</Reference>
<Reference Include="Semver, Version=2.0.4.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Semver.2.0.4\lib\netstandard1.1\Semver.dll</HintPath>
<Private>True</Private>
<Reference Include="Semver, Version=1.1.2.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\semver.1.1.2\lib\net45\Semver.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.ComponentModel.Composition" />
+1 -1
View File
@@ -23,7 +23,7 @@
<package id="NUnit" version="2.6.2" targetFramework="net45" />
<package id="Owin" version="1.0" targetFramework="net45" />
<package id="Selenium.WebDriver" version="2.32.0" targetFramework="net45" />
<package id="Semver" version="2.0.4" targetFramework="net45" />
<package id="semver" version="1.1.2" targetFramework="net45" />
<package id="SharpZipLib" version="0.86.0" targetFramework="net45" />
<package id="SqlServerCE" version="4.0.0.1" targetFramework="net45" />
<package id="System.Runtime" version="4.3.0" targetFramework="net45" />
@@ -105,14 +105,14 @@ angular.module("umbraco.directives")
});
//// INIT /////
$image.load(function(){
$timeout(function(){
setDimensions();
scope.loaded = true;
if (scope.onImageLoaded) {
scope.onImageLoaded();
}
});
$image.load(function() {
$timeout(function() {
setDimensions();
scope.loaded = true;
if (angular.isFunction(scope.onImageLoaded)) {
scope.onImageLoaded();
}
});
});
$(window).on('resize.umbImageGravity', function(){
@@ -5,15 +5,14 @@
**/
function ourPackageRepositoryResource($q, $http, umbDataFormatter, umbRequestHelper) {
//var baseurl = "http://localhost:24292/webapi/packages/v1";
var baseurl = "https://our.umbraco.org/webapi/packages/v1";
var baseurl = Umbraco.Sys.ServerVariables.umbracoUrls.packagesRestApiBaseUrl;
return {
getDetails: function (packageId) {
return umbRequestHelper.resourcePromise(
$http.get(baseurl + "/" + packageId),
$http.get(baseurl + "/" + packageId + "?version=" + Umbraco.Sys.ServerVariables.application.version),
'Failed to get package details');
},
@@ -5,7 +5,7 @@
</p>
<p>
To read a report of changes between your current version <strong>{{installer.current.model.currentVersion}}</strong> and this version your upgrading to <strong>{{installer.current.model.newVersion}}</strong>
To read a report of changes between your current version <strong>{{installer.current.model.currentVersion}}</strong> and this version you're upgrading to <strong>{{installer.current.model.newVersion}}</strong>
</p>
<p>
<a ng-href="{{installer.current.model.reportUrl}}" target="_blank" class="btn btn-info">View Report</a>
@@ -50,7 +50,7 @@
<div class="control-group" ng-class="{error: loginForm.username.$invalid}">
<label><localize key="general_username">Username</localize></label>
<input type="text" ng-model="login" name="username" class="-full-width-input" localize="placeholder" placeholder="@placeholders_username" />
<input type="text" ng-model="login" name="username" class="-full-width-input" localize="placeholder" placeholder="@placeholders_usernameHint" />
</div>
<div class="control-group" ng-class="{error: loginForm.password.$invalid}">
@@ -1,14 +1,13 @@
(function () {
(function() {
"use strict";
function QueryBuilderOverlayController($scope, templateQueryResource, localizationService) {
var everything = localizationService.localize("template_allContent");
var myWebsite = localizationService.localize("template_websiteRoot");
var everything = "";
var myWebsite = "";
var ascendingTranslation = "";
var descendingTranslation = "";
var ascendingTranslation = localizationService.localize("template_ascending");
var descendingTranslation = localizationService.localize("template_descending");
var vm = this;
vm.properties = [];
@@ -21,34 +20,6 @@
format: "YYYY-MM-DD"
};
vm.query = {
contentType: {
name: everything
},
source: {
name: myWebsite
},
filters: [
{
property: undefined,
operator: undefined
}
],
sort: {
property: {
alias: "",
name: "",
},
direction: "ascending", //This is the value for sorting sent to server
translation: {
currentLabel: ascendingTranslation, //This is the localized UI value in the the dialog
ascending: ascendingTranslation,
descending: descendingTranslation
}
}
};
vm.chooseSource = chooseSource;
vm.getPropertyOperators = getPropertyOperators;
vm.addFilter = addFilter;
@@ -63,21 +34,48 @@
function onInit() {
vm.query = {
contentType: {
name: everything
},
source: {
name: myWebsite
},
filters: [
{
property: undefined,
operator: undefined
}
],
sort: {
property: {
alias: "",
name: "",
},
direction: "ascending", //This is the value for sorting sent to server
translation: {
currentLabel: ascendingTranslation, //This is the localized UI value in the the dialog
ascending: ascendingTranslation,
descending: descendingTranslation
}
}
};
templateQueryResource.getAllowedProperties()
.then(function (properties) {
.then(function(properties) {
vm.properties = properties;
});
templateQueryResource.getContentTypes()
.then(function (contentTypes) {
.then(function(contentTypes) {
vm.contentTypes = contentTypes;
});
templateQueryResource.getFilterConditions()
.then(function (conditions) {
.then(function(conditions) {
vm.conditions = conditions;
});
throttledFunc();
}
@@ -111,10 +109,11 @@
}
function getPropertyOperators(property) {
var conditions = _.filter(vm.conditions, function (condition) {
var index = condition.appliesTo.indexOf(property.type);
return index >= 0;
});
var conditions = _.filter(vm.conditions,
function(condition) {
var index = condition.appliesTo.indexOf(property.type);
return index >= 0;
});
return conditions;
}
@@ -123,10 +122,8 @@
}
function trashFilter(query, filter) {
for (var i = 0; i < query.filters.length; i++)
{
if (query.filters[i] == filter)
{
for (var i = 0; i < query.filters.length; i++) {
if (query.filters[i] == filter) {
query.filters.splice(i, 1);
}
}
@@ -173,7 +170,7 @@
function setFilterTerm(filter, term) {
filter.term = term;
if(filter.constraintValue) {
if (filter.constraintValue) {
throttledFunc();
}
}
@@ -183,22 +180,32 @@
}
function datePickerChange(event, filter) {
if(event.date && event.date.isValid()) {
if (event.date && event.date.isValid()) {
filter.constraintValue = event.date.format(vm.datePickerConfig.format);
throttledFunc();
}
}
var throttledFunc = _.throttle(function () {
templateQueryResource.postTemplateQuery(vm.query)
.then(function (response) {
$scope.model.result = response;
});
var throttledFunc = _.throttle(function() {
}, 200);
templateQueryResource.postTemplateQuery(vm.query)
.then(function(response) {
$scope.model.result = response;
});
onInit();
},
200);
localizationService.localizeMany([
"template_allContent", "template_websiteRoot", "template_ascending", "template_descending"
])
.then(function(res) {
everything = res[0];
myWebsite = res[1];
ascendingTranslation = res[2];
descendingTranslation = res[3];
onInit();
});
}
angular.module("umbraco").controller("Umbraco.Overlays.QueryBuilderController", QueryBuilderOverlayController);
@@ -1,10 +1,17 @@
angular.module("umbraco")
.controller("Umbraco.PropertyEditors.Grid.MediaController",
function ($scope, $rootScope, $timeout) {
function ($scope, $rootScope, $timeout, userService) {
if (!$scope.model.config.startNodeId) {
userService.getCurrentUser().then(function (userData) {
$scope.model.config.startNodeId = userData.startMediaId;
});
}
$scope.setImage = function(){
$scope.mediaPickerOverlay = {};
$scope.mediaPickerOverlay.view = "mediapicker";
$scope.mediaPickerOverlay.startNodeId = $scope.model.config && $scope.model.config.startNodeId ? $scope.model.config.startNodeId : undefined;
$scope.mediaPickerOverlay.cropSize = $scope.control.editor.config && $scope.control.editor.config.size ? $scope.control.editor.config.size : undefined;
$scope.mediaPickerOverlay.showDetails = true;
$scope.mediaPickerOverlay.disableFolderSelect = true;
@@ -112,10 +112,9 @@ angular.module('umbraco').controller("Umbraco.PropertyEditors.MediaPickerControl
// content picker. THen we don't have to worry about setting ids, render models, models, we just set one and let the
// watch do all the rest.
$timeout(function(){
angular.forEach($scope.images, function(value, key){
r.push(value.id);
angular.forEach($scope.images, function(value, key) {
r.push($scope.model.config.idType === "udi" ? value.udi : value.id);
});
$scope.ids = r;
$scope.sync();
}, 500, false);
@@ -60,10 +60,13 @@
// sync tree
// if master template alias has changed move the node to it's new location
if(oldMasterTemplateAlias !== vm.template.masterTemplateAlias) {
// move node to new location in tree
//first we need to remove the node that we're working on
treeService.removeNode(vm.page.menu.currentNode);
// When creating a new template the id is -1. Make sure We don't remove the root node.
if (vm.page.menu.currentNode.id !== "-1") {
// move node to new location in tree
//first we need to remove the node that we're working on
treeService.removeNode(vm.page.menu.currentNode);
}
// update stored alias to the new one so the node won't move again unless the alias is changed again
oldMasterTemplateAlias = vm.template.masterTemplateAlias;
+28 -29
View File
@@ -40,7 +40,8 @@
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<TargetFrameworkProfile />
<UseIISExpress>true</UseIISExpress>
<IISExpressSSLPort>44319</IISExpressSSLPort>
<IISExpressSSLPort>
</IISExpressSSLPort>
<IISExpressAnonymousAuthentication>enabled</IISExpressAnonymousAuthentication>
<IISExpressWindowsAuthentication>disabled</IISExpressWindowsAuthentication>
<IISExpressUseClassicPipelineMode>false</IISExpressUseClassicPipelineMode>
@@ -206,8 +207,8 @@
<Reference Include="System">
<Name>System</Name>
</Reference>
<Reference Include="System.Collections.Immutable, Version=1.2.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Collections.Immutable.1.3.1\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll</HintPath>
<Reference Include="System.Collections.Immutable, Version=1.1.36.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Collections.Immutable.1.1.36\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll</HintPath>
</Reference>
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="System.configuration" />
@@ -239,8 +240,8 @@
<SpecificVersion>False</SpecificVersion>
<Private>False</Private>
</Reference>
<Reference Include="System.Reflection.Metadata, Version=1.4.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Reflection.Metadata.1.4.2\lib\portable-net45+win8\System.Reflection.Metadata.dll</HintPath>
<Reference Include="System.Reflection.Metadata, Version=1.0.21.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Reflection.Metadata.1.0.21\lib\portable-net45+win8\System.Reflection.Metadata.dll</HintPath>
</Reference>
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.ServiceModel" />
@@ -348,13 +349,6 @@
<Compile Include="..\SolutionInfo.cs">
<Link>Properties\SolutionInfo.cs</Link>
</Compile>
<Compile Include="Umbraco\Install\Legacy\LoadStarterKits.ascx.cs">
<DependentUpon>loadStarterKits.ascx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="Umbraco\Install\Legacy\LoadStarterKits.ascx.designer.cs">
<DependentUpon>loadStarterKits.ascx</DependentUpon>
</Compile>
<Compile Include="Config\splashes\NoNodes.aspx.cs">
<DependentUpon>noNodes.aspx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
@@ -453,13 +447,6 @@
<Compile Include="Umbraco\Developer\Packages\DirectoryBrowser.aspx.designer.cs">
<DependentUpon>directoryBrowser.aspx</DependentUpon>
</Compile>
<Compile Include="Umbraco\Developer\Packages\StarterKits.aspx.cs">
<DependentUpon>StarterKits.aspx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
</Compile>
<Compile Include="Umbraco\Developer\Packages\StarterKits.aspx.designer.cs">
<DependentUpon>StarterKits.aspx</DependentUpon>
</Compile>
<Compile Include="Umbraco\Developer\Python\EditPython.aspx.cs">
<DependentUpon>editPython.aspx</DependentUpon>
<SubType>ASPXCodeBehind</SubType>
@@ -579,9 +566,9 @@
<Content Include="Config\Lang\sv-SE.user.xml" />
<Content Include="Config\Lang\zh-CN.user.xml" />
<Content Include="Umbraco\Config\Lang\cs.xml" />
<Content Include="Umbraco\Install\Legacy\loadStarterKits.ascx" />
<Content Include="Umbraco\ClientRedirect.aspx" />
<Content Include="Umbraco\create.aspx" />
<Content Include="Umbraco\Developer\Packages\installer.aspx" />
<Content Include="Umbraco\Logout.aspx" />
<Content Include="Umbraco\umbraco.aspx" />
<Content Include="Umbraco_Client\Application\JQuery\jquery.unobtrusive-ajax.min.js" />
@@ -1546,7 +1533,6 @@
<Content Include="Umbraco_Client\Installer\Js\jquery.ui.selectmenu.js" />
<Content Include="Umbraco\Config\Lang\ko.xml" />
<Content Include="Umbraco\Dashboard\FeedProxy.aspx" />
<Content Include="Umbraco\Developer\Packages\StarterKits.aspx" />
<Content Include="Umbraco\helpRedirect.aspx" />
<Content Include="Umbraco\Images\aboutNew.png" />
<Content Include="Umbraco\Images\Editor\skin.gif" />
@@ -1716,7 +1702,6 @@
<Content Include="Umbraco_Client\Tree\Themes\Umbraco\li.gif" />
<Content Include="Umbraco_Client\Tree\Themes\Umbraco\style.css" />
<Content Include="Umbraco_Client\Tree\Themes\Umbraco\throbber.gif" />
<Content Include="Umbraco\Developer\Packages\proxy.htm" />
<Content Include="Umbraco\Developer\Xslt\xsltVisualize.aspx" />
<Content Include="Umbraco\Dialogs\empty.htm" />
<Content Include="Umbraco\Dialogs\insertMasterpageContent.aspx" />
@@ -1783,12 +1768,8 @@
<Content Include="Umbraco\Images\Umbraco\repository.gif" />
<Content Include="Umbraco\Images\Umbraco\uploadpackage.gif" />
<Content Include="Umbraco_Client\Application\JQuery\jquery.autocomplete.js" />
<Content Include="Umbraco\Developer\Packages\BrowseRepository.aspx" />
<Content Include="Umbraco\Developer\Packages\directoryBrowser.aspx" />
<Content Include="Umbraco\Developer\Packages\editPackage.aspx" />
<Content Include="Umbraco\Developer\Packages\installedPackage.aspx" />
<Content Include="Umbraco\Developer\Packages\LoadNitros.ascx" />
<Content Include="Umbraco\Developer\Packages\SubmitPackage.aspx" />
<Content Include="Umbraco\Dialogs\about.aspx" />
<Content Include="Umbraco\Dialogs\AssignDomain.aspx" />
<Content Include="Umbraco\Dialogs\create.aspx" />
@@ -1801,7 +1782,6 @@
<Content Include="Umbraco\Dialogs\insertTable.aspx" />
<Content Include="Umbraco\Dialogs\moveOrCopy.aspx" />
<Content Include="Umbraco\Dialogs\notifications.aspx" />
<Content Include="Umbraco\Developer\Packages\installer.aspx" />
<Content Include="Umbraco\Dialogs\protectPage.aspx" />
<Content Include="Umbraco\Dialogs\publish.aspx" />
<Content Include="Umbraco\Dialogs\RegexWs.aspx" />
@@ -2396,9 +2376,9 @@ xcopy "$(ProjectDir)"..\packages\SqlServerCE.4.0.0.1\x86\*.* "$(TargetDir)x86\"
<WebProjectProperties>
<UseIIS>True</UseIIS>
<AutoAssignPort>True</AutoAssignPort>
<DevelopmentServerPort>7600</DevelopmentServerPort>
<DevelopmentServerPort>7610</DevelopmentServerPort>
<DevelopmentServerVPath>/</DevelopmentServerVPath>
<IISUrl>http://localhost:7600</IISUrl>
<IISUrl>http://localhost:7610</IISUrl>
<NTLMAuthentication>False</NTLMAuthentication>
<UseCustomServer>False</UseCustomServer>
<CustomServerUrl>
@@ -2415,7 +2395,26 @@ xcopy "$(ProjectDir)"..\packages\SqlServerCE.4.0.0.1\x86\*.* "$(TargetDir)x86\"
</PostBuildEvent>
</PropertyGroup>
<Import Project="$(SolutionDir)\.nuget\nuget.targets" />
<PropertyGroup Condition="Exists('$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.Tasks.dll')">
<WebPublishingTasks>$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.Tasks.dll</WebPublishingTasks>
</PropertyGroup>
<PropertyGroup Condition="Exists('$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v11.0\Web\Microsoft.Web.Publishing.Tasks.dll')">
<WebPublishingTasks>$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v11.0\Web\Microsoft.Web.Publishing.Tasks.dll</WebPublishingTasks>
</PropertyGroup>
<PropertyGroup Condition="Exists('$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v12.0\Web\Microsoft.Web.Publishing.Tasks.dll')">
<WebPublishingTasks>$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v12.0\Web\Microsoft.Web.Publishing.Tasks.dll</WebPublishingTasks>
</PropertyGroup>
<PropertyGroup Condition="Exists('$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v14.0\Web\Microsoft.Web.Publishing.Tasks.dll')">
<WebPublishingTasks>$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v14.0\Web\Microsoft.Web.Publishing.Tasks.dll</WebPublishingTasks>
</PropertyGroup>
<PropertyGroup Condition="Exists('$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v15.0\Web\Microsoft.Web.Publishing.Tasks.dll')">
<WebPublishingTasks>$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v15.0\Web\Microsoft.Web.Publishing.Tasks.dll</WebPublishingTasks>
</PropertyGroup>
<UsingTask TaskName="TransformXml" AssemblyFile="$(WebPublishingTasks)" Condition="'$(WebPublishingTasks)' != ''" />
<UsingTask TaskName="TransformXml" AssemblyFile="$(VSWherePath)\Microsoft\VisualStudio\v15.0\Web\Microsoft.Web.Publishing.Tasks.dll" Condition="'$(VSWherePath)' != ''" />
<Target Name="BeforeBuild">
<Message Text="WebPublishingTasks: $(WebPublishingTasks)" Importance="high" />
<Message Text="VSWherePath: $(VSWherePath)" Importance="high" />
<!-- Create web.config file from Template if it doesn't exist -->
<Copy SourceFiles="$(ProjectDir)web.Template.config" DestinationFiles="$(ProjectDir)Web.config" OverwriteReadOnlyFiles="true" SkipUnchangedFiles="false" Condition="!Exists('$(ProjectDir)Web.config')" />
<!-- Transform the local Web.config file in Visual Studio -->
+2 -2
View File
@@ -35,7 +35,7 @@
<package id="Owin" version="1.0" targetFramework="net45" />
<package id="SharpZipLib" version="0.86.0" targetFramework="net45" />
<package id="SqlServerCE" version="4.0.0.1" targetFramework="net45" />
<package id="System.Collections.Immutable" version="1.3.1" targetFramework="net45" />
<package id="System.Reflection.Metadata" version="1.4.2" targetFramework="net45" />
<package id="System.Collections.Immutable" version="1.1.36" targetFramework="net45" />
<package id="System.Reflection.Metadata" version="1.0.21" targetFramework="net45" />
<package id="Umbraco.ModelsBuilder" version="3.0.7" targetFramework="net45" />
</packages>
@@ -1,106 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using System.Web.UI;
using Umbraco.Core.Logging;
using Umbraco.Web.Install;
namespace Umbraco.Web.UI.Install.Steps.Skinning
{
public delegate void StarterKitInstalledEventHandler();
public partial class LoadStarterKits : UserControl
{
/// <summary>
/// Returns the string for the package installer web service base url
/// </summary>
protected string PackageInstallServiceBaseUrl { get; private set; }
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
//Get the URL for the package install service base url
var umbracoPath = Core.Configuration.GlobalSettings.UmbracoMvcArea;
var urlHelper = new UrlHelper(Context.Request.RequestContext);
//PackageInstallServiceBaseUrl = urlHelper.Action("Index", "InstallPackage", new { area = "UmbracoInstall" });
PackageInstallServiceBaseUrl = urlHelper.GetUmbracoApiService("Index", "InstallPackage", "UmbracoInstall");
}
/// <summary>
/// Flag to show if we can connect to the repo or not
/// </summary>
protected bool CannotConnect { get; private set; }
public event StarterKitInstalledEventHandler StarterKitInstalled;
protected virtual void OnStarterKitInstalled()
{
StarterKitInstalled();
}
private readonly global::umbraco.cms.businesslogic.packager.repositories.Repository _repo;
private const string RepoGuid = "65194810-1f85-11dd-bd0b-0800200c9a66";
public LoadStarterKits()
{
_repo = global::umbraco.cms.businesslogic.packager.repositories.Repository.getByGuid(RepoGuid);
}
protected void Page_Load(object sender, EventArgs e)
{
}
//protected void NextStep(object sender, EventArgs e)
//{
// var p = (Default)this.Page;
// //InstallHelper.RedirectToNextStep(Page, Request.GetItemAsString("installStep"));
//}
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
if (_repo == null)
{
throw new InvalidOperationException("Could not find repository with id " + RepoGuid);
}
//clear progressbar cache
//InstallHelper.ClearProgress();
if (_repo.HasConnection())
{
try
{
var r = new org.umbraco.our.Repository();
rep_starterKits.DataSource = r.Modules();
rep_starterKits.DataBind();
}
catch (Exception ex)
{
LogHelper.Error<LoadStarterKits>("Cannot connect to package repository", ex);
CannotConnect = true;
}
}
else
{
CannotConnect = true;
}
}
protected void GotoLastStep(object sender, EventArgs e)
{
//InstallHelper.RedirectToLastStep(Page);
}
}
}
@@ -1,60 +0,0 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Umbraco.Web.UI.Install.Steps.Skinning {
public partial class LoadStarterKits {
/// <summary>
/// pl_loadStarterKits control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.PlaceHolder pl_loadStarterKits;
/// <summary>
/// JsInclude1 control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::ClientDependency.Core.Controls.JsInclude JsInclude1;
/// <summary>
/// rep_starterKits control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Repeater rep_starterKits;
/// <summary>
/// LinkButton1 control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.LinkButton LinkButton1;
/// <summary>
/// LinkButton2 control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.LinkButton LinkButton2;
}
}
@@ -1,98 +0,0 @@
<%@ Control Language="C#" AutoEventWireup="True" CodeBehind="LoadStarterKits.ascx.cs" Inherits="Umbraco.Web.UI.Install.Steps.Skinning.LoadStarterKits" %>
<%@ Import Namespace="Umbraco.Web.org.umbraco.our" %>
<%@ Register TagPrefix="umb" Namespace="ClientDependency.Core.Controls" Assembly="ClientDependency.Core" %>
<asp:PlaceHolder ID="pl_loadStarterKits" runat="server">
<umb:JsInclude ID="JsInclude1" runat="server" FilePath="installer/js/PackageInstaller.js" PathNameAlias="UmbracoClient" />
<% if (!CannotConnect) { %>
<script type="text/javascript">
(function ($) {
$(document).ready(function () {
var installer = new Umbraco.Installer.PackageInstaller({
starterKits: $("a.selectStarterKit"),
baseUrl: "<%= PackageInstallServiceBaseUrl %>",
serverError: $("#serverError"),
connectionError: $("#connectionError"),
setProgress: updateProgressBar,
setStatusMessage: updateStatusMessage
});
installer.init();
});
})(jQuery);
</script>
<% } %>
<div id="starter-kit-progress" style="display: none;">
<h2>Installation in progress...</h2>
<div class="loader">
<div class="hold">
<div class="progress-bar">
</div>
<span class="progress-bar-value">0%</span>
</div>
<strong></strong>
</div>
</div>
<asp:Repeater ID="rep_starterKits" runat="server">
<headertemplate>
<ul class="thumbnails">
</headertemplate>
<itemtemplate>
<li class="span4 add-<%# ((Package)Container.DataItem).Text.Replace(" ","").ToLower() %>">
<div class="thumbnail" style="margin-right: 10px; height: 260px">
<img src="http://our.umbraco.org<%# ((Package)Container.DataItem).Thumbnail %>?width=170" alt="<%# ((Package)Container.DataItem).Text %>">
<h4><%# ((Package)Container.DataItem).Text %></h4>
<%# ((Package)Container.DataItem).Description %>
<a href="#" class="btn btn-success single-tab selectStarterKit" data-name="<%# ((Package)Container.DataItem).Text %>" title="Install <%# ((Package)Container.DataItem).Text %>" data-repoid="<%# ((Package)Container.DataItem).RepoGuid %>">
Install
</a>
</div>
</li>
</itemtemplate>
<footertemplate>
</ul>
<%--<asp:LinkButton runat="server" ID="declineStarterKits" CssClass="declineKit" OnClientClick="return confirm('Are you sure you do not want to install a starter kit?');" OnClick="NextStep">
No thanks, do not install a starterkit!
</asp:LinkButton>--%>
</footertemplate>
</asp:Repeater>
</asp:PlaceHolder>
<div id="connectionError" style="<%= CannotConnect ? "" : "display:none;" %>">
<div style="padding: 0 100px 13px 5px;">
<h2>Oops...the installer can't connect to the repository</h2>
Starter Kits could not be fetched from the repository as there was no connection - which can occur if you are using a proxy server or firewall with certain configurations,
or if you are not currently connected to the internet.
<br />
Click <strong>Continue</strong> to complete the installation then navigate to the Developer section of your Umbraco installation
where you will find the Starter Kits listed in the Packages tree.
</div>
<!-- btn box -->
<footer class="btn-box">
<div class="t">&nbsp;</div>
<asp:LinkButton ID="LinkButton1" class="btn-step btn btn-continue" runat="server" OnClick="GotoLastStep"><span>Continue</span></asp:LinkButton>
</footer>
</div>
<div id="serverError" style="display:none;">
<div style="padding: 0 100px 13px 5px;">
<h2>Oops...the installer encountered an error</h2>
<div class="error-message"></div>
</div>
<!-- btn box -->
<footer class="btn-box">
<div class="t">&nbsp;</div>
<asp:LinkButton ID="LinkButton2" class="btn-step btn btn-continue" runat="server" OnClick="GotoLastStep"><span>Continue</span></asp:LinkButton>
</footer>
</div>
+12 -11
View File
@@ -150,7 +150,7 @@
<key alias="releaseDate">Udgivelsesdato</key>
<key alias="unpublishDate">Dato for Fortryd udgivelse</key>
<key alias="removeDate">Fjern dato</key>
<key alias="sortDone">Sorteringrækkefølgen er opdateret</key>
<key alias="sortDone">Sorteringsrækkefølgen er opdateret</key>
<key alias="sortHelp">For at sortere, træk siderne eller klik på en af kolonnehovederne. Du kan vælge flere sider ved at holde "shift" eller "control" nede mens du vælger.</key>
<key alias="statistics">Statistik</key>
<key alias="titleOptional">Titel (valgfri)</key>
@@ -184,7 +184,7 @@
<key alias="updateData">Vælg en type og skriv en titel</key>
<key alias="noDocumentTypes" version="7.0"><![CDATA[Der kunne ikke findes nogen tilladte dokument typer. Du skal tillade disse i indstillinger under <strong>"dokument typer"</strong>.]]></key>
<key alias="noMediaTypes" version="7.0"><![CDATA[Der kunne ikke findes nogen tilladte media typer. Du skal tillade disse i indstillinger under <strong>"media typer"</strong>.]]></key>
<key alias="documentTypeWithoutTemplate">Dokument type uden skabelon</key>
<key alias="documentTypeWithoutTemplate">Dokumenttype uden skabelon</key>
<key alias="newFolder">Ny mappe</key>
<key alias="newDataType">Ny datatype</key>
</area>
@@ -321,6 +321,7 @@
<key alias="search">Søg...</key>
<key alias="filter">Filtrer...</key>
<key alias="enterTags">Indtast nøgleord (tryk på Enter efter hvert nøgleord)...</key>
<key alias="usernameHint">Dit brugernavn er typisk din e-mail adresse</key>
</area>
<area alias="editcontenttype">
<key alias="allowAtRoot" version="7.2">Tillad på rodniveau</key>
@@ -579,13 +580,13 @@
<key alias="permissionsAffectedFolders">Berørte filer og foldere</key>
<key alias="permissionsAffectedFoldersMoreInfo">Flere informationer om at opsætte rettigheder for Umbraco her</key>
<key alias="permissionsAffectedFoldersText">Du er nødt til at give ASP.NET 'modify' rettigheder på følgende filer/foldere</key>
<key alias="permissionsAlmostPerfect"><![CDATA[<strong>Dine rettighedsinstillinger er næsten perfekte!</strong><br/><br/>Du kan køre Umbraco uden problemer, men du vil ikke være i stand til at installere pakker, som er anbefalet for at få fuldt udbytte af Umbraco.]]></key>
<key alias="permissionsAlmostPerfect"><![CDATA[<strong>Dine rettighedsindstillinger er næsten perfekte!</strong><br/><br/>Du kan køre Umbraco uden problemer, men du vil ikke være i stand til at installere pakker, som er anbefalet for at få fuldt udbytte af Umbraco.]]></key>
<key alias="permissionsHowtoResolve">Hvorledes besluttes</key>
<key alias="permissionsHowtoResolveLink">Klik her for at læse tekstversionen</key>
<key alias="permissionsHowtoResolveText"><![CDATA[Se vores <strong>video tutorials</strong> om at opsætte folderrettigheder for Umbraco eller læs tekstversionen.]]></key>
<key alias="permissionsMaybeAnIssue"><![CDATA[<strong>Dine rettighedsinstillinger kan være et problem!</strong><br/><br/>Du kan afvikle Umbraco uden problemer, men du vil ikke være i stand til at oprette foldere eller installere pakker, hvilket er anbefalet for at få fuldt udbytte af Umbraco.]]></key>
<key alias="permissionsNotReady"><![CDATA[<strong>Dine rettighedsinstillinger er ikke klar til Umbraco!</strong><br/><br/>For at afvikle Umbraco er du nødt til at opdatere dine rettighedsinstillinger.]]></key>
<key alias="permissionsPerfect"><![CDATA[<strong>Dine rettighedsinstillinger er perfekte!</strong><br/><br/>Du er nu parat til at afvikle Umbraco og installere pakker!]]></key>
<key alias="permissionsMaybeAnIssue"><![CDATA[<strong>Dine rettighedsindstillinger kan være et problem!</strong><br/><br/>Du kan afvikle Umbraco uden problemer, men du vil ikke være i stand til at oprette foldere eller installere pakker, hvilket er anbefalet for at få fuldt udbytte af Umbraco.]]></key>
<key alias="permissionsNotReady"><![CDATA[<strong>Dine rettighedsindstillinger er ikke klar til Umbraco!</strong><br/><br/>For at afvikle Umbraco er du nødt til at opdatere dine rettighedsindstillinger.]]></key>
<key alias="permissionsPerfect"><![CDATA[<strong>Dine rettighedsindstillinger er perfekte!</strong><br/><br/>Du er nu parat til at afvikle Umbraco og installere pakker!]]></key>
<key alias="permissionsResolveFolderIssues">Løser folder problem</key>
<key alias="permissionsResolveFolderIssuesLink">Følg dette link for mere information om udfordringer med ASP.NET og oprettelse af foldere</key>
<key alias="permissionsSettingUpPermissions">Sætter folderrettigheder op</key>
@@ -597,7 +598,7 @@
<key alias="runwayInstalledText"><![CDATA[Du har fundamentet på plads. Vælg hvilke moduler du ønsker at installere ovenpå det.<br/>Dette er vores liste over anbefalede moduler. Kryds dem af du ønsker at installere eller se den <a href="#" onclick="toggleModules(); return false;" id="toggleModuleList">fulde liste af moduler</a> ]]></key>
<key alias="runwayOnlyProUsers">Kun anbefalet for erfarne brugere</key>
<key alias="runwaySimpleSite">Jeg ønsker at begynder med et simpelt website</key>
<key alias="runwaySimpleSiteText"><![CDATA[<p>"Runway" er et simpelt website som stiller nogle basale dokumenttyper og skabeloner til rådighed. Instaleringsprogrammet kan automatisk opsætte Runway for dig, men du kan nemt redigere, udvide eller fjerne det. Det er ikke nødvendigt og du kan sagtens bruge Umbraco uden. Men Runway tilbyder et fundament, som er baseret på 'Best Practices', som får dig igang hurtigere end nogensinde før. Hvis du vælger at installere Runway, kan du efter eget valg vælge de grundlæggende byggesten kaldet 'Runway Modules' til at forbedre dine Runway-sider.</p><p><small><em>Inkluderet med Runway:</em>Home Page, Getting Started page, Installing Modules page.<br /> <em>Valgfri Moduler:</em> Top Navigation, Sitemap, Contact, Gallery. </small></p>]]></key>
<key alias="runwaySimpleSiteText"><![CDATA[<p>"Runway" er et simpelt website som stiller nogle basale dokumenttyper og skabeloner til rådighed. Installeringsprogrammet kan automatisk opsætte Runway for dig, men du kan nemt redigere, udvide eller fjerne det. Det er ikke nødvendigt og du kan sagtens bruge Umbraco uden. Men Runway tilbyder et fundament, som er baseret på 'Best Practices', som får dig igang hurtigere end nogensinde før. Hvis du vælger at installere Runway, kan du efter eget valg vælge de grundlæggende byggesten kaldet 'Runway Modules' til at forbedre dine Runway-sider.</p><p><small><em>Inkluderet med Runway:</em>Home Page, Getting Started page, Installing Modules page.<br /> <em>Valgfri Moduler:</em> Top Navigation, Sitemap, Contact, Gallery. </small></p>]]></key>
<key alias="runwayWhatIsRunway">Hvad er Runway</key>
<key alias="step1">Skridt 1/5: Acceptér licens</key>
<key alias="step2">Skridt 2/5: Database-konfiguration</key>
@@ -714,7 +715,7 @@ Mange hilsner fra Umbraco robotten
<key alias="packageRepository">Pakke opbevaringsbase</key>
<key alias="packageUninstallConfirm">Bekræft af-installering</key>
<key alias="packageUninstalledHeader">Pakken blev fjernet</key>
<key alias="packageUninstalledText">Pakken er på succefuld vis blevet fjernet</key>
<key alias="packageUninstalledText">Pakken er på succesfuld vis blevet fjernet</key>
<key alias="packageUninstallHeader">Afinstallér pakke</key>
<key alias="packageUninstallText">
<![CDATA[Du kan fjerne markeringen på elementer du ikke ønsker at fjerne, på dette tidspunkt, nedenfor. Når du klikker 'bekræft' vil alle afkrydsede elemenet blive fjernet <br/>
@@ -795,7 +796,7 @@ Mange hilsner fra Umbraco robotten
<key alias="addRows">Tilføj række</key>
<key alias="addElement">Tilføj indhold</key>
<key alias="dropElement">Slip indhold</key>
<key alias="settingsApplied">Instillinger tilføjet</key>
<key alias="settingsApplied">Indstillinger tilføjet</key>
<key alias="contentNotAllowed">Indholdet er ikke tilladt her</key>
<key alias="contentAllowed">Indholdet er tilladt her</key>
@@ -940,7 +941,7 @@ Mange hilsner fra Umbraco robotten
<key alias="tab">Faneblad</key>
<key alias="tabname">Titel på faneblad</key>
<key alias="tabs">Faneblade</key>
<key alias="masterDocumentType">Master Dokument Type</key>
<key alias="masterDocumentType">Master Dokumenttype</key>
<key alias="createMatchingTemplate">Opret matchende skabelon</key>
</area>
<area alias="sort">
@@ -1024,7 +1025,7 @@ Mange hilsner fra Umbraco robotten
<key alias="insertContentAreaPlaceHolder">Indsæt pladsholder for indholdsområde</key>
<key alias="insert">Indsæt</key>
<key alias="insertDesc">Hvad vil du indsætte ?</key>
<key alias="insertDesc">Hvad vil du indsætte?</key>
<key alias="insertDictionaryItem">Oversættelse</key>
<key alias="insertDictionaryItemDesc">Indsætter en oversætbar tekst, som skifter efter det sprog, som websitet vises i.</key>
@@ -278,6 +278,7 @@
<key alias="search">Durchsuchen ...</key>
<key alias="filter">Filtern ...</key>
<key alias="enterTags">Tippen, um Tags hinzuzufügen (nach jedem Tag die Eingabetaste drücken) ...</key>
<key alias="usernameHint">Der Benutzername ist normalerweise Ihre E-Mail-Adresse</key>
</area>
<area alias="editcontenttype">
<key alias="allowAtRoot" version="7.2">Auf oberster Ebene erlauben</key>
@@ -348,6 +348,7 @@
<key alias="filter">Type to filter...</key>
<key alias="enterTags">Type to add tags (press enter after each tag)...</key>
<key alias="email">Enter your email</key>
<key alias="usernameHint">Your username is usually your email</key>
</area>
<area alias="editcontenttype">
<key alias="allowAtRoot" version="7.2">Allow at root</key>
@@ -1547,4 +1547,7 @@ To manage your website, simply open the Umbraco back office and start adding con
<key alias="enabledConfirm">URL tracker has now been enabled.</key>
<key alias="enableError">Error enabling the URL tracker, more information can be found in your log file.</key>
</area>
<area alias="emptyStates">
<key alias="emptyDictionaryTree">No Dictionary items to choose from</key>
</area>
</language>
@@ -277,6 +277,7 @@
<key alias="entername">Escribe un nombre...</key>
<key alias="search">Escribe tu búsqueda...</key>
<key alias="filter">Escribe para filtrar resultados...</key>
<key alias="usernameHint">Tu nombre de usuario normalmente es tu e-mail</key>
</area>
<area alias="editcontenttype">
<key alias="allowAtRoot" version="7.2">Permitir en nodo raíz</key>
@@ -329,6 +329,7 @@
<key alias="filter">Filtrer...</key>
<key alias="enterTags">Ajouter des tags (appuyer sur enter entre chaque tag)...</key>
<key alias="email">Entrez votre email</key>
<key alias="usernameHint">Votre nom d'utilisateur est généralement votre adresse email</key>
</area>
<area alias="editcontenttype">
@@ -339,6 +339,7 @@
<key alias="filter">Typ om te filteren...</key>
<key alias="enterTags">Typ om tags toe te voegen (druk op enter na elke tag)...</key>
<key alias="email">Voer jouw email in</key>
<key alias="usernameHint">Jouw gebruikersnaam is meestal jouw email</key>
</area>
<area alias="editcontenttype">
@@ -416,6 +416,9 @@
<key alias="rteShowLabel">Показать метку</key>
<key alias="rteWidthAndHeight">Ширина и высота</key>
</area>
<area alias="emptyStates">
<key alias="emptyDictionaryTree">Нет доступных элементов словаря</key>
</area>
<area alias="errorHandling">
<key alias="errorButDataWasSaved">Ваши данные сохранены, но для того, чтобы опубликовать этот документ, Вы должны сначала исправить следующие ошибки:</key>
<key alias="errorChangingProviderPassword">Текущий провайдер ролей пользователей не поддерживает изменение пароля (необходимо свойству EnablePasswordRetrieval в файле web.config присвоить значение true)</key>
@@ -1019,6 +1022,7 @@
<key alias="password">Укажите пароль</key>
<key alias="search">Что искать...</key>
<key alias="username">Укажите имя пользователя</key>
<key alias="usernameHint">Имя пользователя (часто это Ваш email-адрес)</key>
</area>
<area alias="prompt">
<key alias="stay">Остаться</key>
@@ -594,6 +594,7 @@
<key alias="search">Skriv för att söka...</key>
<key alias="username">Fyll i ditt lösenord</key>
<key alias="enterTags">Skriv för att lägga till taggar (och tryck enter efter varje tagg)...</key>
<key alias="usernamehint">Ditt användarnamn är vanligtvis din e-postadress</key>
</area>
<area alias="publicAccess">
<key alias="paAdvanced">Rollbaserat lösenordsskydd</key>
File diff suppressed because it is too large Load Diff
@@ -1,20 +0,0 @@
<%@ Page Language="C#" AutoEventWireup="true" MasterPageFile="../../masterpages/umbracoPage.Master" Title="Browse Repository" CodeBehind="BrowseRepository.aspx.cs" Inherits="umbraco.presentation.developer.packages.BrowseRepository" %>
<%@ Register TagPrefix="cc1" Namespace="umbraco.uicontrols" Assembly="controls" %>
<asp:Content ContentPlaceHolderID="body" runat="server">
<cc1:UmbracoPanel id="Panel1" Text="Browse package repository" runat="server" Width="612px" Height="600px" hasMenu="false">
<cc1:Feedback ID="fb" runat="server" />
<asp:Literal runat="server" ID="iframeGen" />
</cc1:UmbracoPanel>
</asp:Content>
<asp:Content ContentPlaceHolderID="footer" runat="server">
<script type="text/javascript">
jQuery(document).ready(function() {
var frame = jQuery("#repoFrame");
var win = jQuery(window);
frame.height(win.height() - frame.offset().top - 40);
frame.width(win.width() - 35);
});
</script>
</asp:Content>
@@ -1,32 +0,0 @@
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="LoadNitros.ascx.cs" Inherits="umbraco.presentation.developer.packages.LoadNitros" %>
<asp:Panel id="loadNitros" runat="server">
<div id="list1a">
<span id="editorCategories">
<a class="accordianOpener">
Editors picks
<small>Recommended by the umbraco core team</small>
</a>
<div style="display: block;" class="accordianContainer">
<asp:PlaceHolder ID="ph_recommendedHolder" runat="server" />
</div>
</span>
<span id="generatedCategories">
<asp:Repeater ID="rep_nitros" runat="server" OnItemDataBound="onCategoryDataBound">
<ItemTemplate>
<a class="accordianOpener generated">
<asp:Literal ID="lit_name" runat="server" />
<small><asp:Literal ID="lit_desc" runat="server"/></small>
</a>
<div class="accordianContainer generated">
<asp:PlaceHolder ID="ph_nitroHolder" runat="server" />
</div>
</ItemTemplate>
</asp:Repeater>
</span>
</div>
<asp:Button runat="server" CssClass="loadNitrosButton" id="bt_install" OnClick="installNitros" OnClientClick="InstallPackages(this,'loadingBar'); return true;" Text="Install selected modules" />
</asp:Panel>
@@ -1,86 +0,0 @@
<%@ Page Language="C#" AutoEventWireup="True" MasterPageFile="../../masterpages/umbracoPage.Master" Title="Install starter kit" CodeBehind="StarterKits.aspx.cs" Inherits="Umbraco.Web.UI.Umbraco.Developer.Packages.StarterKits" %>
<%@ Register TagPrefix="cc1" Namespace="umbraco.uicontrols" Assembly="controls" %>
<%@ Register TagPrefix="umb" Namespace="ClientDependency.Core.Controls" Assembly="ClientDependency.Core" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
<umb:JsInclude ID="JsInclude1" runat="server" FilePath="ui/jqueryui.js" PathNameAlias="UmbracoClient" />
<script type="text/javascript">
var percentComplete = 0;
jQuery(document).ready(function() {
//bind to button click events
jQuery("a.selectStarterKit").click(function() {
jQuery(".progress-status").siblings(".install-dialog").hide();
jQuery(".progress-status").show();
});
});
function updateProgressBar(percent) {
percentComplete = percent;
}
function updateStatusMessage(message, error) {
if (message != null && message != undefined) {
jQuery(".progress-status").text(message + " (" + percentComplete + "%)");
}
}
</script>
<style type="text/css">
.progress-status {
display: none;
}
.add-thanks
{
position:absolute;
left:-2500;
display:none !important;
}
.zoom-list li {float: left; margin: 15px; display: block; width: 180px;}
.btn-prev, .btn-next, .paging, .btn-preview, .faik-mask , .faik-mask-ie6
{
display:none;
}
.image {float: left; margin: 15px; display: block; width: 140px;}
.image .gal-drop{padding-top:10px;}
ul{list-style-type: none;}
</style>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="body" runat="server">
<cc1:UmbracoPanel id="Panel1" Text="Starter kit" runat="server" Width="612px" Height="600px" hasMenu="false">
<cc1:Feedback ID="fb" runat="server" />
<cc1:Pane id="StarterKitNotInstalled" Text="Install starter kit" runat="server">
<h3>Available starter kits</h3>
<p>You can choose from the following starter kits, each having specific functionality.</p>
<div class="progress-status">Please wait...</div>
<div id="connectionError"></div>
<div id="serverError"></div>
<div class="install-dialog">
<asp:PlaceHolder ID="ph_starterkits" runat="server"></asp:PlaceHolder>
</div>
</cc1:Pane>
<cc1:Pane id="installationCompleted" Text="Installation completed" runat="server" Visible="false">
<p>Installation completed succesfully</p>
</cc1:Pane>
<cc1:Pane id="InstallationDirectoryNotAvailable" Text="Unable to install" runat="server" Visible="false">
<p>We can not install starterkits when the install directory or package repository is not present.</p>
</cc1:Pane>
</cc1:UmbracoPanel>
</asp:Content>
@@ -1,85 +0,0 @@
using System;
using System.Linq;
using Umbraco.Core;
using Umbraco.Core.Configuration;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
using Umbraco.Web.UI.Install.Steps.Skinning;
using Umbraco.Web.UI.Pages;
using System.IO;
using umbraco.cms.businesslogic.packager;
namespace Umbraco.Web.UI.Umbraco.Developer.Packages
{
public partial class StarterKits : UmbracoEnsuredPage
{
private const string RepoGuid = "65194810-1f85-11dd-bd0b-0800200c9a66";
protected void Page_Load(object sender, EventArgs e)
{
//check if a starter kit is already isntalled
var installed = InstalledPackage.GetAllInstalledPackages();
if (installed.Count == 0)
{
ShowStarterKits();
return;
}
var repo = global::umbraco.cms.businesslogic.packager.repositories.Repository.getByGuid(RepoGuid);
if (repo.HasConnection())
{
try
{
var kits = repo.Webservice.StarterKits();
var kitIds = kits.Select(x => x.RepoGuid).ToArray();
//if a starter kit is already installed show finish
if (installed.Any(x => kitIds.Contains(Guid.Parse(x.Data.PackageGuid))))
{
StarterKitNotInstalled.Visible = false;
installationCompleted.Visible = true;
}
else
{
ShowStarterKits();
}
}
catch (Exception ex)
{
LogHelper.Error<StarterKits>("Cannot connect to package repository", ex);
InstallationDirectoryNotAvailable.Visible = true;
StarterKitNotInstalled.Visible = false;
}
}
else
{
InstallationDirectoryNotAvailable.Visible = true;
StarterKitNotInstalled.Visible = false;
}
}
private void ShowStarterKits()
{
if (Directory.Exists(Server.MapPath(GlobalSettings.Path.EnsureEndsWith('/') + "install/Legacy")) == false)
{
InstallationDirectoryNotAvailable.Visible = true;
StarterKitNotInstalled.Visible = false;
return;
}
var starterkitsctrl = (LoadStarterKits)LoadControl(GlobalSettings.Path.EnsureEndsWith('/') + "install/Legacy/loadStarterKits.ascx");
ph_starterkits.Controls.Add(starterkitsctrl);
StarterKitNotInstalled.Visible = true;
}
}
}
@@ -1,78 +0,0 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Umbraco.Web.UI.Umbraco.Developer.Packages {
public partial class StarterKits {
/// <summary>
/// JsInclude1 control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::ClientDependency.Core.Controls.JsInclude JsInclude1;
/// <summary>
/// Panel1 control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::umbraco.uicontrols.UmbracoPanel Panel1;
/// <summary>
/// fb control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::umbraco.uicontrols.Feedback fb;
/// <summary>
/// StarterKitNotInstalled control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::umbraco.uicontrols.Pane StarterKitNotInstalled;
/// <summary>
/// ph_starterkits control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.PlaceHolder ph_starterkits;
/// <summary>
/// installationCompleted control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::umbraco.uicontrols.Pane installationCompleted;
/// <summary>
/// InstallationDirectoryNotAvailable control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::umbraco.uicontrols.Pane InstallationDirectoryNotAvailable;
}
}
@@ -1,113 +0,0 @@
<%@ Page Language="C#" Title="Submit package" MasterPageFile="../../masterpages/umbracoPage.Master" AutoEventWireup="true" CodeBehind="SubmitPackage.aspx.cs" Inherits="umbraco.presentation.developer.packages.SubmitPackage" %>
<%@ Register TagPrefix="cc2" Namespace="umbraco.uicontrols" Assembly="controls" %>
<asp:Content ContentPlaceHolderID="footer" runat="server">
<script type="text/javascript">
var tb_email = document.getElementById('<%= tb_email.ClientID %>');
if (tb_email.value != "") {
onRepoChange();
}
</script>
</asp:Content>
<asp:Content ContentPlaceHolderID="head" runat="server">
<script type="text/javascript">
function onRepoChange() {
var dropdown = document.getElementById('<%= dd_repositories.ClientID %>');
var myindex = dropdown.selectedIndex
var SelValue = dropdown.options[myindex].value
var repoLogin = document.getElementById('<%= pl_repoLogin.ClientID %>');
if (SelValue != "") {
var publicRepoHelp = document.getElementById('<%= publicRepoHelp.ClientID %>');
var privateRepoHelp = document.getElementById('<%= privateRepoHelp.ClientID %>');
publicRepoHelp.style.display = 'none';
privateRepoHelp.style.display = 'none';
if (SelValue == "65194810-1f85-11dd-bd0b-0800200c9a66") {
publicRepoHelp.style.display = 'block';
} else {
privateRepoHelp.style.display = 'block';
}
repoLogin.style.display = 'block';
} else {
repoLogin.style.display = 'none';
}
}
</script>
</asp:Content>
<asp:Content ContentPlaceHolderID="body" runat="server">
<cc2:UmbracoPanel ID="Panel1" Text="Submit package to repository" runat="server" Width="496px" Height="584px">
<br />
<cc2:Feedback ID="fb_feedback" runat="server" />
<asp:PlaceHolder ID="feedbackControls" runat="server" Visible="false">
<br />
<p>
<button onclick="window.location.href = 'editpackage.aspx?id=<%= Request.QueryString["id"] %>'; return false;">Ok</button>
</p>
</asp:PlaceHolder>
<cc2:Pane ID="Pane2" runat="server" Text="Repository">
<asp:Panel ID="pl_repoChoose" runat="server">
<cc2:PropertyPanel runat="server">
<p>Choose the repository you want to submit the package to</p>
</cc2:PropertyPanel>
<cc2:PropertyPanel Text="Repository" runat="server">
<asp:DropDownList ID="dd_repositories" runat="server" />
</cc2:PropertyPanel>
</asp:Panel>
<asp:Panel id="pl_repoLogin" style="display: none;" runat="server">
<cc2:PropertyPanel ID="PropertyPanel1" runat="server">
<h3 style="margin-left: 0px; padding-top: 15px;">Please enter your credentials to authenticate your user.</h3>
<p runat="server" id="publicRepoHelp" style="display: none">If you do not have a user on the umbraco package repository, you can create one <a href="http://packages.umbraco.org/create-user" target="_blank">here</a>.</p>
<p runat="server" id="privateRepoHelp" style="display: none">If you do not have a user on this private repository, contact your repository administrator to gain access</p>
</cc2:PropertyPanel>
<cc2:PropertyPanel ID="PropertyPanel2" runat="server" Text="Email">
<asp:TextBox ID="tb_email" runat="server" /> <asp:RequiredFieldValidator ID="RequiredFieldValidator1" ControlToValidate="tb_email" runat="server" ErrorMessage="*" />
</cc2:PropertyPanel>
<cc2:PropertyPanel ID="PropertyPanel3" runat="server" Text="Password">
<asp:TextBox TextMode="Password" ID="tb_password" runat="server" /> <asp:RequiredFieldValidator ControlToValidate="tb_password" runat="server" ErrorMessage="*" />
</cc2:PropertyPanel>
</asp:Panel>
</cc2:Pane>
<cc2:Pane ID="Pane1" runat="server" Text="Documentation (.pdf only)">
<cc2:PropertyPanel ID="PropertyPanel4" runat="server">
<p>Upload additional documentation for your package to help new users getting started with your package</p>
</cc2:PropertyPanel>
<cc2:PropertyPanel ID="PropertyPanel5" runat="server" Text="Documentation file">
<asp:FileUpload ID="fu_doc" runat="server" />
<asp:RegularExpressionValidator ID="doc_regex" runat="server" ControlToValidate="fu_doc" ValidationExpression="(.*?)\.(pdf|PDF)$" ErrorMessage="Only .pdf files are accepted" />
</cc2:PropertyPanel>
</cc2:Pane>
<asp:PlaceHolder runat="server" ID="submitControls">
<br />
<div class="notice">
<p>By clicking "submit package" below you understand that your package will be submitted to a package repository and will in some cases be publicly available to download.</p>
<p><strong>Please notice: </strong> only packages with complete read-me, author information and install information gets considered for inclusion.</p>
<p>The package administrators group reservers the right to decline packages based on lack of documentation, poorly written readme and missing author information</p>
</div>
<p>
<asp:Button ID="bt_submit" runat="server" Text="Submit package" OnClick="submitPackage" /> &nbsp;<em><%= umbraco.ui.Text("or") %></em> &nbsp;<a href="editpackage.aspx?id=<%= Request.QueryString["id"] %>"><%= umbraco.ui.Text("cancel") %></a>
</p>
</asp:PlaceHolder>
</cc2:UmbracoPanel>
</asp:Content>
@@ -39,7 +39,6 @@
<asp:TextBox ID="iconUrl" runat="server" Width="230px" CssClass="guiInputText"></asp:TextBox>
</cc2:PropertyPanel>
<cc2:PropertyPanel runat="server" ID="pp_file" Text="Package file (.zip):">
<asp:Button ID="bt_submitButton" runat="server" Text="Submit to repository" Visible="false" />
<asp:Literal ID="packageUmbFile" runat="server" />
</cc2:PropertyPanel>
@@ -1,184 +0,0 @@
<%@ Page Language="C#" MasterPageFile="../../masterpages/umbracoPage.Master" AutoEventWireup="true" CodeBehind="installedPackage.aspx.cs" Inherits="umbraco.presentation.developer.packages.installedPackage" %>
<%@ Register TagPrefix="cc2" Namespace="umbraco.uicontrols" Assembly="controls" %>
<asp:Content ContentPlaceHolderID="head" runat="server">
<script type="text/javascript">
function toggleDiv(id, gotoDiv) {
var div = document.getElementById(id);
if (div.style.display == "none")
div.style.display = "block";
else
div.style.display = "none";
}
function openDemo(link, id) {
UmbClientMgr.openModalWindow("http://packages.umbraco.org/viewPackageData.aspx?id=" + id, link.innerHTML, true, 750, 550)
}
</script>
<style type="text/css">
.propertyItemheader {
width: 250px;
}
</style>
</asp:Content>
<asp:Content ContentPlaceHolderID="body" runat="server">
<cc2:Tabview ID="Panel1" Text="Installed package" runat="server" Width="496px" Height="584px">
<cc2:Pane ID="pane_meta" runat="server" Text="Package meta data">
<cc2:PropertyPanel ID="pp_name" runat="server">
<asp:Literal ID="lt_packagename" runat="server" />
</cc2:PropertyPanel>
<cc2:PropertyPanel ID="pp_version" runat="server">
<asp:Literal ID="lt_packageVersion" runat="server" />
</cc2:PropertyPanel>
<cc2:PropertyPanel ID="pp_author" runat="server">
<asp:Literal ID="lt_packageAuthor" runat="server" />
</cc2:PropertyPanel>
<cc2:PropertyPanel ID="pp_documentation" Visible="false" runat="server">
<asp:HyperLink id="hl_docLink" Target="_blank" runat="server" />
<asp:LinkButton id="lb_demoLink" OnClientClick="" runat="server" />
</cc2:PropertyPanel>
<cc2:PropertyPanel ID="pp_repository" Visible="false" runat="server">
<asp:HyperLink id="hl_packageRepo" runat="server" />
</cc2:PropertyPanel>
<cc2:PropertyPanel ID="pp_readme" runat="server">
<div style="position: relative; background: #fff; padding: 3px; border: 1px solid #ccc; width: 400px; white-space: normal !Important; overflow: auto;">
<asp:Literal ID="lt_readme" runat="server" /></div>
</cc2:PropertyPanel>
</cc2:Pane>
<cc2:Pane ID="pane_versions" runat="server" Text="Package version history" Visible="false">
<cc2:PropertyPanel ID="pp_versions" runat="server">
<asp:Repeater ID="rptr_versions" runat="server">
<headertemplate><ul></headertemplate>
<itemtemplate><li><a href="#"><%# ((umbraco.cms.businesslogic.packager.InstalledPackage)Container.DataItem).Data.Name %></a></li></itemtemplate>
<footertemplate></ul></footertemplate>
</asp:Repeater>
</cc2:PropertyPanel>
</cc2:Pane>
<cc2:Pane ID="pane_upgrade" runat="server" Text="Upgrade package" Visible="false">
<cc2:PropertyPanel runat="server">
<p>
<%= umbraco.ui.Text("packager", "packageUpgradeText") %>
</p>
</cc2:PropertyPanel>
<cc2:PropertyPanel ID="pp_upgradeInstruction" Text="Upgrade instructions" runat="server">
<p>
<asp:Literal ID="lt_upgradeReadme" runat="server" />
</p>
<p>
<asp:Button ID="bt_gotoUpgrade" Text="Download update from the repository" runat="server" UseSubmitBehavior="false" />
</p>
</cc2:PropertyPanel>
</cc2:Pane>
<cc2:Pane ID="pane_noItems" Visible="false" runat="server" Text="Uninstaller doesn't contain any items">
<div class="guiDialogNormal" style="margin: 10px">
<%= umbraco.ui.Text("packager", "packageNoItemsText") %>
<p>
<asp:Button ID="bt_deletePackage" OnClick="delPack" runat="server" Text="Remove uninstaller" />
</p>
</div>
</cc2:Pane>
<cc2:Pane ID="pane_uninstall" runat="server" Text="Uninstall items installed by this package">
<p>
<%= umbraco.ui.Text("packager", "packageUninstallText") %>
</p>
<cc2:PropertyPanel runat="server" Text="Document Types" ID="pp_docTypes">
<asp:CheckBoxList ID="documentTypes" runat="server" />
</cc2:PropertyPanel>
<cc2:PropertyPanel runat="server" Text="Templates" ID="pp_templates">
<asp:CheckBoxList ID="templates" runat="server" />
</cc2:PropertyPanel>
<cc2:PropertyPanel runat="server" Text="Stylesheets" ID="pp_css">
<asp:CheckBoxList ID="stylesheets" runat="server" />
</cc2:PropertyPanel>
<cc2:PropertyPanel runat="server" Text="Macros" ID="pp_macros">
<asp:CheckBoxList ID="macros" runat="server" />
</cc2:PropertyPanel>
<cc2:PropertyPanel ID="pp_files" runat="server" Text="Files">
<asp:CheckBoxList ID="files" runat="server" />
</cc2:PropertyPanel>
<cc2:PropertyPanel ID="pp_di" runat="server" Text="Dictionary Items">
<asp:CheckBoxList ID="dictionaryItems" runat="server" />
</cc2:PropertyPanel>
<cc2:PropertyPanel ID="pp_dt" runat="server" Text="Data types">
<asp:CheckBoxList ID="dataTypes" runat="server" />
</cc2:PropertyPanel>
<cc2:PropertyPanel ID="pp_confirm" runat="server" Text="&nbsp;">
<asp:Button ID="bt_confirmUninstall" OnClick="confirmUnInstall" OnClientClick="$('#loadingbar').show()" Text="Confirm uninstall" CssClass="btn btn-primary" runat="server" />
<div id="loadingbar" style="display: none">
<div class="umb-loader-wrapper">
<cc2:ProgressBar ID="progbar" runat="server" Title="Please wait..." />
</div>
</div>
</cc2:PropertyPanel>
</cc2:Pane>
<cc2:Pane id="pane_uninstalled" runat="server" Visible="false">
<div class="alert alert-block">
Package uninstall in progress, please wait while the browser is reloaded...
</div>
<script type="text/javascript">
//This is all a bit zany with double encoding because we have a URL in a hash (#) url part
// but it works and maintains query strings
var umbPath = "<%=umbraco.GlobalSettings.Path%>";
setTimeout(function () {
var mainWindow = UmbClientMgr.mainWindow();
//kill the tree and template cache
if (mainWindow.UmbClientMgr) {
mainWindow.UmbClientMgr._packageInstalled();
}
var baseUrl = mainWindow.location.href.substr(0, mainWindow.location.href.indexOf("#/developer/framed/"));
var framedUrl = baseUrl + "#/developer/framed/";
var refreshUrl = framedUrl + encodeURIComponent(encodeURIComponent(umbPath + "/developer/packages/installer.aspx?installing=uninstalled"));
var redirectUrl = umbPath + "/ClientRedirect.aspx?redirectUrl=" + refreshUrl;
mainWindow.location.href = redirectUrl;
}, 2000);
</script>
</cc2:Pane>
</cc2:Tabview>
</asp:Content>
@@ -1,67 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>Repo proxy</title>
</head>
<body>
<script type="text/javascript">
//This is a stupid way of parsing a uri
//https://gist.github.com/jlong/2428561
try {
var parser = document.createElement('a');
parser.href = window.location.search.substring(1);
// This next line may seem redundant but is required to get around a bug in IE
// that doesn't set the parser.hostname or parser.protocol correctly for relative URLs.
// see https://gist.github.com/jlong/2428561#gistcomment-1461205
parser.href = parser.href;
// => "http:"
if (parser.protocol && (parser.protocol.toLowerCase() != "http:" && parser.protocol.toLowerCase() != "https:")) {
throw "invalid protocol";
};
// => "example.com"
if (!parser.hostname || parser.hostname == "") {
throw "invalid hostname";
}
//parser.port; // => "3000"
// => "/pathname/"
if (!parser.pathname || ((parser.pathname.length - parser.pathname.toLowerCase().indexOf("/developer/packages/installer.aspx")) != "/developer/packages/installer.aspx".length))
{
throw "invalid pathname";
}
// => "?search=test"
if (!parser.search || parser.search.toLowerCase().indexOf("?repoguid") != 0) {
throw "invalid search";
}
// => "#hash"
if (parser.hash && parser.hash != "") {
throw "invalid hash";
}
//parser.host; // => "example.com:3000"
if (!top.right) {
throw "invalid document";
}
top.right.document.location = window.location.search.substring(1);
} catch (e) {
alert(e);
}
</script>
</body>
</html>

Some files were not shown because too many files have changed in this diff Show More