Compare commits

..

220 Commits

Author SHA1 Message Date
Sebastiaan Jansssen 3e8fb11abd Update to latest modelsbuilder 2018-01-08 08:39:01 +01:00
Shannon 5181988a41 forgot to set the flag 2018-01-08 18:10:27 +11:00
Shannon 5169310258 Makes sure we check for index locking on both a normal boot with empty indexes and a cold boot when that is being forced 2018-01-08 17:57:15 +11:00
Shannon Deminick f987640462 Merge pull request #2370 from abjerner/patch-30
Fixed the xmldoc for UserService.Delete
2018-01-08 14:34:53 +11:00
Anders Bjerner 55e97dad74 Fixed the xmldoc for UserService.Delete 2018-01-06 20:24:02 +01:00
Sebastiaan Jansssen d2f3e162f1 Bump version to 7.7.8 2018-01-04 16:45:00 +01:00
Claus 7404e20a19 Merge pull request #2331 from JackPenney/JackPenney-patch-1
Removed CMS Import keys from hebrew translation
2018-01-04 14:05:43 +01:00
Claus 744ff0cf33 Merge pull request #2328 from akierczynska/patch-3
Update pl.xml
2018-01-04 14:04:47 +01:00
Claus afd0018dd6 Merge pull request #2349 from dallastaylor/remove-console-writeline
Remove Console.Writeline() from IsPublishable().
2018-01-04 13:56:43 +01:00
Shannon Deminick c36aec624b Merge pull request #2367 from umbraco/temp-U4-10756-performance-fix
Doesn't fix the issue but improves performance by ~30%
2018-01-04 23:43:25 +11:00
Claus 1ba86f361a Merge pull request #2368 from umbraco/temp-U4-9268
U4-9268 Hidden preview button reappears after 'save' or 'save and pub…
2018-01-04 12:29:00 +01:00
Shannon e5a21625ea U4-9268 Hidden preview button reappears after 'save' or 'save and publish'. 2018-01-04 21:53:55 +11:00
Sebastiaan Janssen efd3d6937a Merge pull request #2365 from umbraco/temp-U4-10701
U4-10701 Umbraco.MemberHasAccess generates slow query after upgrading…
2018-01-03 15:36:51 +01:00
Niels Hartvig 6d46c2204d Doesn't fix the issue but improves performance by ~30% 2018-01-03 12:54:25 +01:00
Warren Buckley 27b9385df5 Update client build NPM dependancy for gulp-connect to use 5.0.0 as next/latest version required you to use CoffeeScript to compile their src code to use the module/component 2018-01-03 11:08:55 +00:00
Shannon ea6d81f7ac U4-10701 Umbraco.MemberHasAccess generates slow query after upgrading to 7.7.6 2018-01-03 11:47:26 +11:00
Mads Rasmussen f56bd731b7 Merge pull request #2227 from abryukhov/U4-10481
U4-10481 - v7.7.x - RU localization of the last added keys
2017-12-27 13:24:42 +01:00
Mads Rasmussen bee0642417 Merge pull request #2263 from krighi/U4-10323
U4-10323 - FIX - Grid stuck at 12 columns (percentage calculation incorrect)
2017-12-27 13:04:31 +01:00
Mads Rasmussen 43abb08e59 Merge pull request #2305 from marcemarc/temp-u4-10637
Fixes U4-10637 - textarea Macro Parameters hidden in niche circumstances
2017-12-27 11:05:12 +01:00
Mads Rasmussen 17db5709f1 Merge pull request #2339 from bjarnef/dev-v7-U4-10720
U4-10720 - Add documentation to umb-table component
2017-12-27 10:38:43 +01:00
Mads Rasmussen 2fc6d9b7df Merge pull request #2327 from bjarnef/dev-v7-U4-10703
Wrap text in umb-node-preview component
2017-12-27 10:19:23 +01:00
Shannon e4561851a4 modifies some code changes to null check and not to use extension methods that require singleton access. 2017-12-21 17:30:37 +11:00
Shannon Deminick c6daf2e111 Merge pull request #2353 from mitutee/temp-U4-10770
U4-10770
2017-12-21 17:20:19 +11:00
Sebastiaan Janssen 883366f741 Merge pull request #2295 from JacekJMMJ/temp-u4-10626
Temp u4 10626
2017-12-20 16:07:14 +01:00
Claus cac331adbc U4-10640 Multiple Media Picker duplicate image Angular issue in Umbraco 7.7.4 2017-12-20 13:38:07 +01:00
Shannon Deminick 18318ecabf Merge pull request #2354 from umbraco/temp-u4-10764
U4-10764 - workaround broken events
2017-12-20 17:27:42 +11:00
Shannon 6b9ef6df7a fix tests 2017-12-20 17:02:52 +11:00
Shannon Deminick fcaf78ef29 Merge pull request #2355 from umbraco/temp-u4-10774
U4-10774 - leak in CacheRefresherEventHandler
2017-12-20 16:06:41 +11:00
Sebastiaan Janssen 833b4c552c Merge pull request #2350 from umbraco/temp-U4-10686
U4-10686 TypedMediaAtRoot().Descendants() calls SQL
2017-12-19 18:25:23 +01:00
Mads Rasmussen c678b7f6d9 Merge branch 'bjarnef-dev-v7-U4-10639' into dev-v7 2017-12-19 10:40:59 +01:00
Mads Rasmussen e320840a29 fix position of add button in media picker 2017-12-19 10:39:52 +01:00
Stephan b664fc5e94 U4-10774 - leak in CacheRefresherEventHandler 2017-12-19 10:04:33 +01:00
Stephan b87346bee5 U4-10764 - minor fix 2017-12-19 10:01:51 +01:00
Mads Rasmussen 6029306fe9 Merge branch 'dev-v7-U4-10639' of git://github.com/bjarnef/Umbraco-CMS into bjarnef-dev-v7-U4-10639 2017-12-19 09:53:52 +01:00
Stephan f979792290 U4-10764 - workaround broken events 2017-12-18 16:53:58 +01:00
m.kilianovskyi 5f82fc6e20 Merge branch 'dev-v7' into HEAD 2017-12-18 17:51:27 +02:00
m.kilianovskyi b1a0ca98ea U4-10770 Get all permissions for entity instead of explicit only 2017-12-18 17:50:53 +02:00
Ilham Boulghallat f4f99c2922 Merge pull request #2336 from MrCosmo/temp-U4-10722
U4-10722 fix in Dutch localization
2017-12-18 10:32:33 +00:00
Shannon c1b3da869d U4-10686 TypedMediaAtRoot().Descendants() calls SQL 2017-12-15 16:01:20 +11:00
Dallas Taylor e39158d5e5 Remove Console.Writeline() from IsPublishable(). 2017-12-14 22:18:49 -05:00
Shannon ddd9c8ef7d Do a lock check on the index on startup and unlock it if it is, this is a safety check since we are now using the simplefs dir 2017-12-14 19:25:01 +11:00
Shannon 44db4e7a48 updates nuspec and references to use latest Examine 2017-12-14 18:34:48 +11:00
Shannon f44b158c15 When we disable examine indexing on startup with MainDom, also suspend all indexing 2017-12-14 16:19:54 +11:00
Robert 1ff66d0c3a Merge pull request #2345 from umbraco/temp-U4-10735
U4-10735 Examine update to better manage appdomain shutdowns
2017-12-13 10:52:56 +01:00
Robert aba2c2a79e Merge pull request #2346 from umbraco/temp-U4-10738
U4-10738 Deleting a media type folder causes an exception
2017-12-12 16:02:21 +01:00
Robert 9f62dfc087 Merge pull request #2348 from umbraco/temp-U4-10588
U4-10588 Indexed member data is missing fields
2017-12-12 13:40:48 +01:00
Shannon Deminick a21912dc41 Merge pull request #2337 from skttl/U4-10549-rte-memory-usage
Fix for U4-10549 RTE memory usage
2017-12-12 11:53:42 +01:00
Robert 733b4a770f Merge pull request #2347 from umbraco/temp-U4-10587
U4-10587 Email field in InternalMemberIndex seems to be attempted to …
2017-12-12 11:29:10 +01:00
Shannon 2e097b7e46 U4-10588 Indexed member data is missing fields 2017-12-12 11:25:53 +01:00
Shannon e1b6997ef7 U4-10587 Email field in InternalMemberIndex seems to be attempted to being added to the index twice 2017-12-11 15:50:27 +01:00
Sebastiaan Jansssen b6b7b9f433 Bump version to 7.7.7 2017-12-11 13:57:31 +01:00
Shannon 8181f88cb0 Do not keep looking up data to index if the app is shutting down 2017-12-08 09:09:14 +01:00
Claus 3a4865ef7d U4-10738 Deleting a media type folder causes an exception 2017-12-07 13:45:49 +01:00
Shannon 37f6dbfa6b more logging 2017-12-06 15:46:35 +01:00
Shannon 131fea3ba4 updates some proj refs 2017-12-06 15:38:00 +01:00
Shannon b0661218a0 U4-10735 Examine update to better manage appdomain shutdowns 2017-12-06 15:21:38 +01:00
Mikkel Holck Madsen fb99b101d8 Merge pull request #2340 from umbraco/temp-U4-10610
U4-10610 Cannot restore content templates
2017-12-05 13:47:11 +01:00
Claus 0ce7efc978 U4-10610 Cannot restore content templates 2017-12-05 10:19:12 +01:00
Bjarne Fyrstenborg 3b8a2d7d65 Add basic documentation to umbPasswordToggle 2017-11-30 23:48:41 +01:00
Bjarne Fyrstenborg 61b9ab5c7b Fix typo 2017-11-30 23:47:55 +01:00
Bjarne Fyrstenborg cfda04b6ed Add documentation of umb-table component 2017-11-30 23:47:23 +01:00
Mikkel Holck Madsen 11bdfbba19 Merge pull request #2338 from umbraco/temp-u4-10715
U4-10715 - scheduled publishing and LB issue
2017-11-30 10:57:12 +01:00
Stephan 9694831638 U4-10715 - scheduled publishing and LB issue 2017-11-30 08:54:16 +01:00
Søren Kottal a20844b55b Destroy tineMceEditors on $destroy 2017-11-29 12:16:12 +01:00
Marco 158e40d7f6 U4-10722 fix in Dutch localization 2017-11-29 08:25:04 +01:00
Jack Penney 1c4e1db054 Removed CMS Import keys from hebrew translation 2017-11-23 12:28:17 +00:00
Bjarne Fyrstenborg 3c98d9d2e1 Wrap text in umb-node-preview component 2017-11-20 19:18:57 +01:00
bjarnef 8d14a3ef2c added number validation in embed overlay 2017-11-20 12:36:12 +01:00
bjarnef 2f3d9c9509 localize texts 2017-11-20 12:32:09 +01:00
Robert 6e8f3b6e13 Merge pull request #2324 from umbraco/temp-UAASSSCRUM-1254
Added custom RollingFileAppender and changed rollingStyle to "size"
2017-11-17 13:03:48 +01:00
mikkelhm b9cbdbd9a7 Add rename of Appender to csproj 2017-11-17 12:01:32 +01:00
mikkelhm ebf35356a8 Updates the CustomRollingFileAppender to read config settings to control it 2017-11-17 12:00:42 +01:00
akierczynska f3ba1fa7ed Update pl.xml
Adding translations and adjusting pl.xml to en.xml format.
2017-11-15 18:07:31 +00:00
Sebastiaan Janssen 7eca99e249 Bump version to 7.7.6 2017-11-15 15:21:25 +01:00
Sebastiaan Janssen 837bb83d48 Merge remote-tracking branch 'origin/dev-v7.6' into dev-v7 2017-11-15 14:40:19 +01:00
Sebastiaan Janssen 054ac78970 Revert "Position changed from "target" to "center""
This reverts commit c1769aa299.
2017-11-15 14:39:09 +01:00
Robert 5982a868ea Added custom RollingFileAppender and changed rollingStyle to "size"
OpenFile method has been overiden, this means that everytime a log will be opened, it will check the last access time of all existing logs, and delete the ones that haven't been accessed in more than 1 month.

Changing the rollingStyle to "size" will make sure that logs will roll once the maximumFileSize reaches its set limit.
2017-11-14 12:01:11 +01:00
Sebastiaan Janssen 69a42e26a9 Merge remote-tracking branch 'origin/dev-v7.6' into dev-v7 2017-11-14 11:42:00 +01:00
Sebastiaan Janssen d9ed420ed4 U4-10492 Users failing to list with MySQL 2017-11-14 11:38:45 +01:00
Sebastiaan Janssen 2b3397120f Disambiguate events by explicitly naming them 2017-11-14 11:23:48 +01:00
Sebastiaan Janssen 1f41aa7d81 Merge branch 'dev-v7.6' into dev-v7
# Conflicts:
#	src/SolutionInfo.cs
#	src/Umbraco.Core/Configuration/UmbracoVersion.cs
#	src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
#	src/Umbraco.Web.UI/packages.config
2017-11-14 07:19:08 +01:00
Sebastiaan Janssen dad77fc506 Bump version to 7.7.5 2017-11-14 07:17:19 +01:00
Sebastiaan Janssen 350f5c88c7 Bump version to 7.6.12 2017-11-14 07:16:14 +01:00
Stephan 928c0dc535 Merge pull request #2314 from umbraco/temp-U4-10646
U4-10646 Sorting nodes in edge cases can lead to blanking out of property data
2017-11-13 17:33:27 +01:00
Sebastiaan Janssen cc7a28db65 Update to latest ImageProcessor 2017-11-13 15:39:29 +01:00
Sebastiaan Janssen 065e764957 Update to latest Examine 2017-11-13 15:39:28 +01:00
Sebastiaan Janssen 000ba73887 Merge branch 'dev-v7.6' into dev-v7
# Conflicts:
#	build/NuSpecs/UmbracoCms.Core.nuspec
#	src/Umbraco.Tests/Umbraco.Tests.csproj
#	src/Umbraco.Tests/packages.config
#	src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
#	src/Umbraco.Web.UI/packages.config
#	src/Umbraco.Web/Umbraco.Web.csproj
#	src/Umbraco.Web/packages.config
#	src/UmbracoExamine/UmbracoExamine.csproj
#	src/UmbracoExamine/packages.config
#	src/umbraco.MacroEngines/packages.config
#	src/umbraco.MacroEngines/umbraco.MacroEngines.csproj
2017-11-13 15:38:59 +01:00
Sebastiaan Janssen 08b81d991b Update to latest ImageProcessor 2017-11-13 15:33:54 +01:00
Sebastiaan Janssen 4937f87c0d Update to latest Examine 2017-11-13 15:27:15 +01:00
Claus dc67d82671 adding trim. 2017-11-08 12:08:30 +01:00
Claus c7d9683fc4 Merge pull request #2277 from umbraco/temp-U4-10589
U4-10589 Login should be sanitized and/or cause validation errors if trying to save with
2017-11-08 12:07:34 +01:00
Mads Rasmussen ed7675bdcd Merge pull request #1584 from readingdancer/U4-9144
Style changes to the developer dashboard area.
2017-11-08 11:49:48 +01:00
Mads Rasmussen 3c7c6b4ad7 Update thumbnails.less
Use new color variables
2017-11-08 11:38:32 +01:00
Mads Rasmussen 838d7975c9 Update healthcheck.less
prevent UI from "jumping" on hover
2017-11-08 11:36:23 +01:00
Mads Rasmussen 5af9712d51 Merge branch 'dev-v7' into U4-9144 2017-11-08 10:43:58 +01:00
Shannon e2c2b8534f Merge branch 'dev-v7' of https://github.com/umbraco/Umbraco-CMS into dev-v7 2017-11-08 19:48:02 +11:00
Shannon cfd3cc5187 OK... maybe that is now required 2017-11-08 19:47:47 +11:00
Sebastiaan Janssen 1f29418ea5 Revert "Adds overloads so you can do paging with the TypedSearch methods."
This reverts commit 089f488c15.
2017-11-08 09:23:58 +01:00
Shannon 977b30c51a Revert "more test hacks" which in theory shouldn't be required for 7.7+ 2017-11-08 19:23:34 +11:00
Shannon 66a849dd12 Merge branch 'dev-v7.6' into dev-v7 2017-11-08 19:20:28 +11:00
Shannon 637abc384b more test hacks 2017-11-08 18:46:08 +11:00
Shannon 8959b81f6a another test fix attempt (this is only for 7.6, this is already fixed in 7.7) 2017-11-08 18:16:17 +11:00
Shannon 32bb8ac5a4 Merge branch 'dev-v7.6' of https://github.com/umbraco/Umbraco-CMS into dev-v7.6 2017-11-08 17:47:32 +11:00
Shannon 016caba35f attempt to fix tests 2017-11-08 17:47:18 +11:00
Shannon 9290f61f94 Merge branch 'dev-v7.6' into dev-v7
# Conflicts:
#	src/Umbraco.Core/Security/MembershipProviderExtensions.cs
#	src/Umbraco.Web.UI/umbraco/config/lang/en.xml
#	src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml
2017-11-08 17:36:27 +11:00
Shannon Deminick d522dd7a31 Merge pull request #2313 from umbraco/temp-U4-10620
U4-10620 Umbraco 2FA implementation issues
2017-11-08 17:18:31 +11:00
Shannon 95f632e1ea Adds notes and overrides SendTwoFactorCodeAsync and checks for -1 instead of null 2017-11-08 17:16:11 +11:00
Shannon Deminick e72ec171f7 Merge pull request #2312 from umbraco/temp-U4-9857
Temp u4 9857
2017-11-08 16:06:53 +11:00
Shannon 2538e2e9c9 additional null check 2017-11-08 16:06:23 +11:00
Daniël Knippers b1ceeb23b3 Only show characters left is a number of characters is configured on the datatype, hide otherwise 2017-11-07 23:13:59 +01:00
Sebastiaan Janssen 46d0807fa4 Merge pull request #2287 from PerplexDaniel/U4-6985
Switching between sections - select last node
2017-11-07 20:26:25 +01:00
Sebastiaan Janssen 579c572dd8 Oops, missed that I was passing a string array into the int array param 2017-11-07 18:36:37 +01:00
Sebastiaan Janssen bbf4c18825 U4-10646 Sorting nodes in edge cases can lead to blanking out of property data 2017-11-07 17:12:04 +01:00
Sebastiaan Janssen 9a94ac5317 Implement TwoFactorSignInAsync from Identity repo to make sure our custom GetVerifiedUserIdAsync fires
U4-10620 Umbraco 2FA implementation issues
2017-11-07 16:51:40 +01:00
Sebastiaan Janssen 0b904e82b5 Get user by id instead of loginname
U4-9857 Umbraco 7.6 - Exception after changing user login name
2017-11-07 16:36:15 +01:00
Claus c816558936 cleanup. 2017-11-07 15:14:45 +01:00
Sebastiaan Janssen 51fec0c7d3 Remove misleading text, nothing bad will happen when you close the sort panel, sorting is a background task. 2017-11-07 14:03:17 +01:00
Sebastiaan Janssen 87ace12a4f Prevent double clicks of the Save button
U4-10646 Sorting nodes in edge cases can lead to blanking out of property data
2017-11-07 13:49:02 +01:00
Sebastiaan Janssen 632f84904f Merge branch 'dev-v7.6' into dev-v7 2017-11-07 10:32:12 +01:00
Daniël Knippers a1fd73cdb0 Feature Request: Double Click Content Node to Expand
Doube-clicking a tree item now expands or collapses a node. It basically does the exact same as clicking the triangle left of the node.

(cherry picked from commit bd2a794b59)
2017-11-07 10:30:08 +01:00
Sebastiaan Janssen a53866953e Merge pull request #2296 from PerplexDaniel/U4-6259
Feature Request: Double Click Content Node to Expand
2017-11-07 10:29:10 +01:00
Bjarne Fyrstenborg e72758e04a Ensure box is square when picker is multiple picker 2017-11-06 22:01:35 +01:00
Bjarne Fyrstenborg 9d373c194d Show thumbnails if any images/files has been selected 2017-11-06 21:42:01 +01:00
Bjarne Fyrstenborg 856e123ec2 Oops - remove duplicated disableFolderSelect 2017-11-06 19:23:41 +01:00
Bjarne Fyrstenborg 0b2af6b48f Fix square image in imagepicker prevalue editor. Cleanup and consistency 2017-11-06 19:12:27 +01:00
Sebastiaan Janssen ff996b05f0 Merge branch 'dev-v7.6' into dev-v7 2017-11-06 17:30:00 +01:00
Sebastiaan Janssen 403502ef1b Merge pull request #2294 from ja0b/U4-854
U4-854 Add MaxLength to Textstring fields --> Fixed

(cherry picked from commit ee4ad36e70)
2017-11-06 17:11:12 +01:00
Sebastiaan Janssen ee4ad36e70 Merge pull request #2294 from ja0b/U4-854
U4-854 Add MaxLength to Textstring fields --> Fixed
2017-11-06 17:08:46 +01:00
Sebastiaan Janssen 4f2650277a Don't need showcharacterslefttext if we're always showing number of chars left 2017-11-06 17:07:14 +01:00
Sebastiaan Janssen 0231a6037e Always show number of characters left
Makes it less magical as to why you can't type any more characters.
2017-11-06 17:03:23 +01:00
Sebastiaan Janssen db51a5bb44 Update TextboxPropertyEditor.cs 2017-11-06 17:02:34 +01:00
Sebastiaan Janssen d1b7063e44 Rename textstringnumber.html to textstringlimited.html 2017-11-06 17:02:08 +01:00
Sebastiaan Janssen 364d4b11e8 Merge branch 'dev-v7.6' into dev-v7 2017-11-06 15:00:05 +01:00
Craig c1769aa299 Position changed from "target" to "center"
Prevents modal jumping position on HIDPI screens

(cherry picked from commit 422be31c4e)
2017-11-06 14:58:31 +01:00
Sebastiaan Janssen a571eee945 Merge pull request #2292 from craigs100/U4-10628
U4-10628
2017-11-06 14:57:46 +01:00
prjseal 143d127fb9 Format date in backoffice based on Users language
We have formatted the Created Date and Updated Date using the Current
Culture of the application.

(cherry picked from commit 10ca1239b6)
2017-11-06 14:03:54 +01:00
Lewis Smith 01cf2e240a U4-10627 - Updated stats / facts when installing.
U4-10627 Update some of the Umbraco Installer facts. Updated the facts you get when installing umbraco. All facts that were changed were taken from the Umbraco page.

https://umbraco.com/blog/codegarden-2017-the-aftermath/
https://umbraco.com/blog/codegarden-2017/
(cherry picked from commit 69258fee7b)
2017-11-06 13:51:43 +01:00
Tim 49689d5057 Fixes missing content type check.
(cherry picked from commit 80d605beac)
2017-11-06 13:48:09 +01:00
Andy Felton f722d7731d Fixed URL Tracker button colour
(cherry picked from commit bb9a0258df)
2017-11-06 13:47:05 +01:00
Sebastiaan Janssen 74ba3261ff Merge branch 'dev-v7.6' into dev-v7 2017-11-06 12:33:48 +01:00
Sebastiaan Janssen ac42f335c2 Fix U4-4889 checkbox in template 2017-11-06 12:33:12 +01:00
Sebastiaan Janssen f0eefbd5af U4-10636 Removed '#' from 'value' when generating alias 2017-11-06 12:31:06 +01:00
Sebastiaan Janssen ed48f29e3a Merge pull request #2300 from dernafees/dev-v7
Fix U4-4889 checkbox in template.
2017-11-06 12:28:32 +01:00
Sebastiaan Janssen 03c5d5197b Updates a few more fields to make sure clicking on labels focuses the field 2017-11-06 12:28:14 +01:00
Sebastiaan Janssen 7f0921bd96 Delete web.config.temp-build.0 2017-11-06 12:09:15 +01:00
Sebastiaan Janssen c38b49b1cf Delete vwd.webinfo 2017-11-06 12:08:45 +01:00
Sebastiaan Janssen c4dfbd4a1c Merge pull request #2304 from pbres/dev-v7
U4-10636 Unable to generate alias for localized name
2017-11-06 12:04:16 +01:00
Sebastiaan Janssen 9b1e5d7649 Update entity.resource.js 2017-11-06 12:03:53 +01:00
Marc Goodson 360665c082 Fixes accidental hiding of textarea parameters when inserting a Macro(with those parameters) via the Rich Text Editor Macro button within a grid cell - U4-10637 2017-11-05 10:36:14 +00:00
Pawel Bres c07b96ade7 Merge pull request #1 from pbres/pbres-patch-1
Removed '#' from 'value' when generating alias
2017-11-04 15:09:00 +01:00
Pawel Bres 576a790e2f Removed '#' from 'value' when generating alias
When '#' is presented in the 'value' everything in the GET URL after '#' gets removed because it's being treated as "hash" part of the URL and it's not being sent to the server at all.
2017-11-04 15:07:47 +01:00
Alejandro Ocampo 29f93160b7 removing unnecessary if statement 2017-11-03 11:51:39 +01:00
Warren Buckley 827e79c705 Merge pull request #2280 from umbraco/temp-U4-10625
U4-10625 HealthCheckController non-empty constructor fails to initial…
2017-11-03 09:29:14 +00:00
Alexander Bryukhov ff98b5f321 U4-10481 - v7.7.x - RU localization of the last added keys (grid editor U4-5722) 2017-11-03 12:18:24 +07:00
Stephan f6ea317dd1 Merge pull request #2299 from PerplexDaniel/U4-10582
Make a shiny template for the emails that are sent from Umbraco
2017-11-02 18:19:32 +01:00
Stephan 68e8ca8d8e Merge pull request #2289 from LewisS303/U4-10627
U4-10627 - Updated stats / facts when installing.
2017-11-02 18:03:25 +01:00
Stephan bcae131545 Merge pull request #2067 from Xiaohao112/patch-1
Created a link to composition doctype
2017-11-02 17:55:30 +01:00
Haider Naji c6d686eabd Fix U4-4889 checkbox in template. 2017-11-02 16:50:19 +00:00
Sebastiaan Janssen a8b660bfbf Check for itemMinHeight on scope before trying to set it 2017-11-02 17:46:01 +01:00
Sebastiaan Janssen 1f60486df8 Merge pull request #2232 from marcemarc/temp-U4-10510
Check for itemMinHeight on scope before trying to set it
2017-11-02 16:45:23 +00:00
Daniël Knippers c066280990 Make a shiny template for the emails that are sent from Umbraco
Make a shiny template for the emails that are sent from Umbraco (only for EN and EN-US).
2017-11-02 16:44:08 +00:00
Sebastiaan Janssen ba747ea579 Merge pull request #2293 from LottePitcher/ReadmeUpdate
Update README.md with correct location of build.bat
2017-11-02 16:42:43 +00:00
Stephan 6f857b16ee Merge pull request #2286 from Attackmonkey/U4-9291
Adds overloads so you can do paging with the TypedSearch methods.
2017-11-02 17:25:26 +01:00
Alejandro Ocampo 27115e5794 U4-854 Add MaxLength to Textstring fields --> Fixed 2017-11-02 17:14:13 +01:00
Jacek Malinowski 92378095a2 U4 10-626. Detecting new Application Url and _umbracoApplicationUrl refresh. 2017-11-02 09:08:46 -07:00
Stephan 13e6a81bbe Merge pull request #2291 from Attackmonkey/U4-9613
Fixes missing content type check.
2017-11-02 17:03:58 +01:00
Daniël Knippers bd2a794b59 Feature Request: Double Click Content Node to Expand
Doube-clicking a tree item now expands or collapses a node. It basically does the exact same as clicking the triangle left of the node.
2017-11-02 16:01:24 +00:00
Stephan 576ffce9aa Merge pull request #2290 from AndyFelton/U4-9932
Fixed URL Tracker button colour
2017-11-02 16:56:57 +01:00
Lotte Pitcher 3bfdaa7e10 Update README.md with correct location of build.bat
With a link to the build markdown page
2017-11-02 15:39:57 +00:00
Sebastiaan Janssen dc7b5bae9b Fix U4-10618 - AbstractConfigCheck SuccessMessages are missing CurrentValue 2017-11-02 16:28:58 +01:00
Craig 422be31c4e Position changed from "target" to "center"
Prevents modal jumping position on HIDPI screens
2017-11-02 15:26:20 +00:00
Sebastiaan Janssen 8d8fb76694 Merge pull request #2279 from Jeavon/temp-U4-10618
Fix U4-10618 - AbstractConfigCheck
2017-11-02 15:25:24 +00:00
Tim 80d605beac Fixes missing content type check. 2017-11-02 15:17:35 +00:00
Andy Felton bb9a0258df Fixed URL Tracker button colour 2017-11-02 15:06:13 +00:00
Jacek Malinowski daa0741802 U4-10626 Detecting deplayoment Id change 2017-11-02 07:40:53 -07:00
Lewis Smith 69258fee7b U4-10627 - Updated stats / facts when installing.
U4-10627 Update some of the Umbraco Installer facts. Updated the facts you get when installing umbraco. All facts that were changed were taken from the Umbraco page.

https://umbraco.com/blog/codegarden-2017-the-aftermath/ 
https://umbraco.com/blog/codegarden-2017/
2017-11-02 14:31:19 +00:00
Stephan 1fd7569c6e Merge pull request #2285 from prjseal/U4-6152
Format date in backoffice based on Users language
2017-11-02 15:20:40 +01:00
Robert 3a1f19ee0a Merge pull request #2283 from jchurchley/U4-9142
U4-9142 - Multiple Related Links pickers on same Document Type not working
2017-11-02 15:09:50 +01:00
Daniël Knippers 90bc7f5829 Switching between sections - select last node
When returning to a previously visited section, will open the last selected node within that section immediately again, if any.
2017-11-02 15:06:35 +01:00
Claus 30b391f3fb Merge pull request #2281 from umbraco/temp-U4-10622
U4-10622 Corrupted id/key map
2017-11-02 14:56:35 +01:00
Tim 089f488c15 Adds overloads so you can do paging with the TypedSearch methods. 2017-11-02 13:55:19 +00:00
Stephan 99b99ce3cd Merge branch 'tompipe-U4-8982-AddIsPublishedtoExamine' into dev-v7 2017-11-02 14:44:39 +01:00
prjseal 10ca1239b6 Format date in backoffice based on Users language
We have formatted the Created Date and Updated Date using the Current
Culture of the application.
2017-11-02 13:44:05 +00:00
Stephan f4fc3c4db4 Merge branch 'U4-8982-AddIsPublishedtoExamine' of https://github.com/tompipe/Umbraco-CMS into tompipe-U4-8982-AddIsPublishedtoExamine 2017-11-02 14:44:03 +01:00
Stephan eaa8ca5fdc U4-10626 - support resetting UmbracoApplicationUrl 2017-11-02 13:30:45 +01:00
DESKTOP-6DNOQH9\John 234c0680d8 Checking if $scope.model.value is an array on the add method. 2017-11-02 12:15:04 +00:00
Stephan ea8c6af028 Document common PowerShell issues when building 2017-11-02 13:07:45 +01:00
Shannon Deminick 5f31c70cbe stats 2017-11-02 18:39:47 +11:00
Shannon Deminick 579a04d179 updates stats 2017-11-02 18:37:56 +11:00
Shannon ff3b7963b1 U4-10622 Corrupted id/key map 2017-11-02 15:35:47 +11:00
Shannon e85d212891 U4-10625 HealthCheckController non-empty constructor fails to initialize the correct variables 2017-11-02 15:18:58 +11:00
Jeavon ef40ecfefd Fix U4-10618 - AbstractConfigCheck SuccessMessages are missing CurrentValue 2017-11-01 12:34:24 +00:00
Robert 73b2d31298 Moved username trimming to service level, also added email trimming 2017-11-01 13:08:17 +01:00
Robert 8676a99b3a Trimming login input on the server-side as well 2017-11-01 09:00:05 +01:00
Sebastiaan Janssen 84b380028c Fixes U4-9401 Double slashes in some Umbraco generated urls causes broken links 2017-10-31 23:21:41 +01:00
Robert 0b2cfe956d Triming login field to avoid validation errors 2017-10-31 15:19:06 +01:00
Shannon Deminick 006deb22db Merge pull request #2271 from richarth/patch-1
Updated grammar
2017-10-31 11:22:52 +11:00
Shannon Deminick 40624255ca Merge pull request #2272 from bjarnef/dev-v7-U4-10609
U4-10609 - Fix missing end closing <div> in login screen
2017-10-31 11:22:04 +11:00
Bjarne Fyrstenborg 24900fb9f8 Fix missing end closing <div> 2017-10-30 18:39:21 +01:00
Richard Thompson 594c473134 Updated grammar
Updated the grammar of the email validation messages
2017-10-30 15:00:08 +00:00
Shannon Deminick 49d54f8ca5 Merge pull request #2266 from ProNotion/issues/U4-9401
Fixes  U4-9401 Double slashes in some Umbraco generated urls causes broken links
2017-10-27 14:32:04 +11:00
Simon Dingley 731e380445 Fixes U4-9401 Double slashes in some Umbraco generated urls causes broken links 2017-10-26 14:27:23 +01:00
Shannon Deminick bd0edb322d Merge pull request #2262 from umbraco/temp-U4-10564
U4-10564 - Update ImageProcessor dependencies
2017-10-26 15:06:36 +11:00
Kaue Righi e0e9823a03 U4-10323 - Grid stuck at 12 columns (percentage calculation incorrect) - fix 2017-10-25 11:40:46 -02:00
Sebastiaan Janssen f766057e50 Merge branch 'dev-v7.6' into dev-v7
# Conflicts:
#	src/Umbraco.Core/PluginManager.cs
#	src/Umbraco.Tests/TestHelpers/BaseUmbracoApplicationTest.cs
2017-10-25 14:13:38 +02:00
Sebastiaan Janssen f0b5c831f1 Manually applied all changes for U4-10503 Umbraco plugins cache files should be stored in the same local temp location as the umbraco xml cache file 2017-10-25 14:05:56 +02:00
Shannon d3232a09fb U4-10503 Umbraco plugins cache files should be stored in the same local temp location as the umbraco xml cache file
(cherry picked from commit 7b3f7f4ad4)
2017-10-25 13:42:10 +02:00
Sebastiaan Janssen 586c59949a Merge branch 'dev-v7.6' into dev-v7
# Conflicts:
#	src/SolutionInfo.cs
#	src/Umbraco.Core/Configuration/UmbracoVersion.cs
#	src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
2017-10-25 13:05:11 +02:00
Shannon 7cbaecc53a U4-10538 Disable Ping on front-end nodes when load balancing
(cherry picked from commit fd8daa398f)
2017-10-25 13:03:31 +02:00
Stephan e84a963d66 U4-10121 - Scheduled Publishing as background task
(cherry picked from commit 79df75c415)
2017-10-25 11:51:42 +02:00
Sebastiaan Janssen 58c180d6cc Merge pull request #2242 from umbraco/temp-U4-10538
U4-10538 Disable Ping on front-end nodes when load balancing
2017-10-24 17:21:13 +02:00
Sebastiaan Janssen 18e377f159 U4-10564 - Update ImageProcessor dependencies 2017-10-24 13:20:33 +02:00
Sebastiaan Janssen a36184a261 Bump version to 7.6.11 2017-10-23 14:14:59 +02:00
Shannon fd8daa398f U4-10538 Disable Ping on front-end nodes when load balancing 2017-10-16 16:22:10 +11:00
Marc Goodson 4e6d60b755 Check for itemMinHeight on scope before trying to set it - Issue U4-10510 2017-10-07 15:07:28 +01:00
Alexander Bryukhov 3a98d63bf1 U4-10481v7.7.2 - RU localization of the last added keys (user section filters & sort) 2017-09-29 15:15:28 +07:00
Alexander Bryukhov ac65af772a U4-10481 - v7.7.2 - RU localization of the last added keys 2017-09-29 13:27:45 +07:00
Xiaohao112 ed480e1e6e Created a link to composition doctype
Related to this issue; http://issues.umbraco.org/issue/U4-10192. Made a link to a composition from the current doctype.
2017-07-24 14:12:59 +02:00
Chris Houston a4f83e0125 Style changes to the developer dashboard area. 2016-11-03 14:41:41 +00:00
Tom Pipe 7b08c0dde6 Adding isPublished value to the index 2016-11-03 11:48:49 +00:00
133 changed files with 5472 additions and 4036 deletions
+37
View File
@@ -14,6 +14,43 @@ By default, this builds the current version. It is possible to specify a differe
Valid version strings are defined in the `Set-UmbracoVersion` documentation below.
## PowerShell Quirks
There is a good chance that running `build.ps1` ends up in error, with messages such as
>The file ...\build\build.ps1 is not digitally signed. You cannot run this script on the current system. For more information about running scripts and setting execution policy, see about_Execution_Policies.
PowerShell has *Execution Policies* that may prevent the script from running. You can check the current policies with:
PS> Get-ExecutionPolicy -List
Scope ExecutionPolicy
----- ---------------
MachinePolicy Undefined
UserPolicy Undefined
Process Undefined
CurrentUser Undefined
LocalMachine RemoteSigned
Policies can be `Restricted`, `AllSigned`, `RemoteSigned`, `Unrestricted` and `Bypass`. Scopes can be `MachinePolicy`, `UserPolicy`, `Process`, `CurrentUser`, `LocalMachine`. You need the current policy to be `RemoteSigned`&mdash;as long as it is `Undefined`, the script cannot run. You can change the current user policy with:
PS> Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned
Alternatively, you can do it at machine level, from within an elevated PowerShell session:
PS> Set-ExecutionPolicy -Scope LocalMachine -ExecutionPolicy RemoteSigned
And *then* the script should run. It *might* however still complain about executing scripts, with messages such as:
>Security warning - Run only scripts that you trust. While scripts from the internet can be useful, this script can potentially harm your computer. If you trust this script, use the Unblock-File cmdlet to allow the script to run without this warning message. Do you want to run ...\build\build.ps1?
[D] Do not run [R] Run once [S] Suspend [?] Help (default is "D"):
This is usually caused by the scripts being *blocked*. And that usually happens when the source code has been downloaded as a Zip file. When Windows downloads Zip files, they are marked as *blocked* (technically, they have a Zone.Identifier alternate data stream, with a value of "3" to indicate that they were downloaded from the Internet). And when such a Zip file is un-zipped, each and every single file is also marked as blocked.
The best solution is to unblock the Zip file before un-zipping: right-click the files, open *Properties*, and there should be a *Unblock* checkbox at the bottom of the dialog. If, however, the Zip file has already been un-zipped, it is possible to recursively unblock all files from PowerShell with:
PS> Get-ChildItem -Recurse *.* | Unblock-File
## Notes
Git might have issues dealing with long file paths during build. You may want/need to enable `core.longpaths` support (see [this page](https://github.com/msysgit/msysgit/wiki/Git-cannot-create-a-file-or-directory-with-a-long-path) for details).
+3 -3
View File
@@ -2,7 +2,7 @@
Umbraco CMS
===========
The friendliest, most flexible and fastest growing ASP.NET CMS used by more than 390,000 websites worldwide: [https://umbraco.com](https://umbraco.com)
The friendliest, most flexible and fastest growing ASP.NET CMS used by more than 443,000 websites worldwide: [https://umbraco.com](https://umbraco.com)
[![ScreenShot](vimeo.png)](https://vimeo.com/172382998/)
@@ -12,7 +12,7 @@ Umbraco is a free open source Content Management System built on the ASP.NET pla
## Building Umbraco from source ##
The easiest way to get started is to run `build/build.bat` which will build both the backoffice (also known as "Belle") and the Umbraco core. You can then easily start debugging from Visual Studio, or if you need to debug Belle you can run `gulp dev` in `src\Umbraco.Web.UI.Client`.
The easiest way to get started is to run `build.bat` which will build both the backoffice (also known as "Belle") and the Umbraco core. You can then easily start debugging from Visual Studio, or if you need to debug Belle you can run `gulp dev` in `src\Umbraco.Web.UI.Client`. See [this page](BUILD.md) for more details.
Note that you can always [download a nightly build](http://nightly.umbraco.org/?container=umbraco-750) so you don't have to build the code yourself.
@@ -26,7 +26,7 @@ For the first time on the Microsoft platform, there is a free user and developer
Umbraco is not only loved by developers, but is a content editors dream. Enjoy intuitive editing tools, media management, responsive views and approval workflows to send your content live.
Used by more than 350,000 active websites including Carlsberg, Segway, Amazon and Heinz and **The Official ASP.NET and IIS.NET website from Microsoft** ([https://asp.net](https://asp.net) / [https://iis.net](https://iis.net)), you can be sure that the technology is proven, stable and scales. Backed by the team at Umbraco HQ, and supported by a dedicated community of over 200,000 craftspeople globally, you can trust that Umbraco is a safe choice and is here to stay.
Used by more than 443,000 active websites including Carlsberg, Segway, Amazon and Heinz and **The Official ASP.NET and IIS.NET website from Microsoft** ([https://asp.net](https://asp.net) / [https://iis.net](https://iis.net)), you can be sure that the technology is proven, stable and scales. Backed by the team at Umbraco HQ, and supported by a dedicated community of over 220,000 craftspeople globally, you can trust that Umbraco is a safe choice and is here to stay.
To view more examples, please visit [https://umbraco.com/why-umbraco/#caseStudies](https://umbraco.com/why-umbraco/#caseStudies)
+1 -2
View File
@@ -10,6 +10,5 @@ IF ERRORLEVEL 1 (
:error
ECHO.
ECHO Can not run build\build.ps1.
ECHO If this is due to a SecurityError then make sure to run the following command from an administrator command prompt:
ECHO If this is due to a SecurityError then please refer to BUILD.md for help!
ECHO.
ECHO powershell Set-ExecutionPolicy -ExecutionPolicy RemoteSigned
+4 -4
View File
@@ -33,13 +33,13 @@
<dependency id="ClientDependency-Mvc5" version="[1.8.0.0, 2.0.0)" />
<dependency id="AutoMapper" version="[3.3.1, 4.0.0)" />
<dependency id="Newtonsoft.Json" version="[10.0.2, 11.0.0)" />
<dependency id="Examine" version="[0.1.85, 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="Examine" version="[0.1.89, 1.0.0)" />
<dependency id="ImageProcessor" version="[2.5.6, 3.0.0)" />
<dependency id="ImageProcessor.Web" version="[4.8.7, 5.0.0)" />
<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)" />
<dependency id="System.Threading.Tasks.Dataflow" version="[4.7.0, 5.0.0)" />
</dependencies>
</metadata>
<files>
+2 -2
View File
@@ -17,9 +17,9 @@
<dependencies>
<dependency id="UmbracoCms.Core" version="[$version$]" />
<dependency id="Newtonsoft.Json" version="[10.0.2, 11.0.0)" />
<dependency id="Umbraco.ModelsBuilder" version="[3.0.7, 4.0.0)" />
<dependency id="Umbraco.ModelsBuilder" version="[3.0.8, 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.1, 3.0.0)" />
</dependencies>
</metadata>
<files>
-2
View File
@@ -49,11 +49,9 @@
<Reference Include="System.Core" />
<Reference Include="System.Data.SqlServerCe, Version=4.0.0.1, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL">
<HintPath>..\packages\SqlServerCE.4.0.0.1\lib\System.Data.SqlServerCe.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Data.SqlServerCe.Entity, Version=4.0.0.1, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL">
<HintPath>..\packages\SqlServerCE.4.0.0.1\lib\System.Data.SqlServerCe.Entity.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
+2 -2
View File
@@ -11,5 +11,5 @@ using System.Resources;
[assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyFileVersion("7.7.4")]
[assembly: AssemblyInformationalVersion("7.7.4")]
[assembly: AssemblyFileVersion("7.7.8")]
[assembly: AssemblyInformationalVersion("7.7.8")]
+15 -2
View File
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Threading;
using Umbraco.Core.Configuration;
@@ -260,7 +261,7 @@ namespace Umbraco.Core
/// - http://issues.umbraco.org/issue/U4-5728
/// - http://issues.umbraco.org/issue/U4-5391
/// </remarks>
internal string UmbracoApplicationUrl
public string UmbracoApplicationUrl
{
get
{
@@ -268,9 +269,21 @@ namespace Umbraco.Core
return _umbracoApplicationUrl;
}
}
/// <summary>
/// Resets the url.
/// </summary>
public void ResetUmbracoApplicationUrl()
{
_umbracoApplicationUrl = null;
}
// ReSharper disable once InconsistentNaming
internal string _umbracoApplicationUrl;
internal string _umbracoApplicationUrl;
internal List<string> _umbracoApplicationDomains = new List<string>();
internal string _umbracoApplicationDeploymentId;
private Lazy<bool> _configured;
internal MainDom MainDom { get; private set; }
@@ -6,7 +6,7 @@ namespace Umbraco.Core.Configuration
{
public class UmbracoVersion
{
private static readonly Version Version = new Version("7.7.4");
private static readonly Version Version = new Version("7.7.8");
/// <summary>
/// Gets the current version of Umbraco.
@@ -76,260 +76,257 @@ namespace Umbraco.Core.Events
{
if (_events == null)
return Enumerable.Empty<IEventDefinition>();
IReadOnlyList<IEventDefinition> events;
switch (filter)
{
case EventDefinitionFilter.All:
return FilterSupersededAndUpdateToLatestEntity(_events);
events = _events;
break;
case EventDefinitionFilter.FirstIn:
var l1 = new OrderedHashSet<IEventDefinition>();
foreach (var e in _events)
{
l1.Add(e);
}
return FilterSupersededAndUpdateToLatestEntity(l1);
events = l1;
break;
case EventDefinitionFilter.LastIn:
var l2 = new OrderedHashSet<IEventDefinition>(keepOldest: false);
foreach (var e in _events)
{
l2.Add(e);
}
return FilterSupersededAndUpdateToLatestEntity(l2);
events = l2;
break;
default:
throw new ArgumentOutOfRangeException("filter", filter, null);
}
return FilterSupersededAndUpdateToLatestEntity(events);
}
private class EventDefinitionTypeData
private class EventDefinitionInfos
{
public IEventDefinition EventDefinition { get; set; }
public Type EventArgType { get; set; }
public SupersedeEventAttribute[] SupersedeAttributes { get; set; }
public Type[] SupersedeTypes { 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)
// fixme
// this is way too convoluted, the superceede attribute is used only on DeleteEventargs to specify
// that it superceeds save, publish, move and copy - BUT - publish event args is also used for
// unpublishing and should NOT be superceeded - so really it should not be managed at event args
// level but at event level
//
// what we want is:
// if an entity is deleted, then all Saved, Moved, Copied, Published events prior to this should
// not trigger for the entity - and even though, does it make any sense? making a copy of an entity
// should ... trigger?
//
// not going to refactor it all - we probably want to *always* trigger event but tell people that
// due to scopes, they should not expected eg a saved entity to still be around - however, now,
// going to write a ugly condition to deal with U4-10764
// iterates 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)
internal 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>();
// keeps the 'latest' entity and associated event data
var entities = new List<Tuple<IEntity, EventDefinitionInfos>>();
// collects the event definitions
// collects the arguments in result, that require their entities to be updated
var result = new List<IEventDefinition>();
var resultArgs = new List<CancellableObjectEventArgs>();
//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())
// eagerly fetch superceeded arg types for each arg type
var argTypeSuperceeding = 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)
.ToDictionary(x => x, x => x.GetCustomAttributes<SupersedeEventAttribute>(false).Select(y => y.SupersededEventArgsType).ToArray());
// iterate over all events and filter
//
// process the list in reverse, because events are added in the order they are raised and we want to keep
// the latest (most recent) entities and filter out what is not relevant anymore (too old), eg if an entity
// is Deleted after being Saved, we want to filter out the Saved event
for (var index = events.Count - 1; index >= 0; index--)
{
var eventDefinition = events[index];
var def = events[index];
var argType = eventDefinition.Args.GetType();
var attributes = allArgTypesWithAttributes[eventDefinition.Args.GetType()];
var meta = new EventDefinitionTypeData
var infos = new EventDefinitionInfos
{
EventDefinition = eventDefinition,
EventArgType = argType,
SupersedeAttributes = attributes
EventDefinition = def,
SupersedeTypes = argTypeSuperceeding[def.Args.GetType()]
};
var args = eventDefinition.Args as CancellableObjectEventArgs;
if (args != null)
var args = def.Args as CancellableObjectEventArgs;
if (args == null)
{
var list = TypeHelper.CreateGenericEnumerableFromObject(args.EventObject);
if (list == null)
// not a cancellable event arg, include event definition in result
result.Add(def);
}
else
{
// event object can either be a single object or an enumerable of objects
// try to get as an enumerable, get null if it's not
var eventObjects = TypeHelper.CreateGenericEnumerableFromObject(args.EventObject);
if (eventObjects == null)
{
//extract the event object
var obj = args.EventObject as IEntity;
if (obj != null)
// single object, cast as an IEntity
// if cannot cast, cannot filter, nothing - just include event definition in result
var eventEntity = args.EventObject as IEntity;
if (eventEntity == 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));
}
result.Add(def);
continue;
}
else
// look for this entity in superceding event args
// found = must be removed (ie not added), else track
if (IsSuperceeded(eventEntity, infos, entities) == false)
{
//Can't retrieve the entity so cant' filter or inspect, just add to the output
result.Add(eventDefinition);
// track
entities.Add(Tuple.Create(eventEntity, infos));
// track result arguments
// include event definition in result
resultArgs.Add(args);
result.Add(def);
}
}
else
{
// enumerable of objects
var toRemove = new List<IEntity>();
foreach (var entity in list)
foreach (var eventObject in eventObjects)
{
//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));
}
}
// extract the event object, cast as an IEntity
// if cannot cast, cannot filter, nothing to do - just leave it in the list & continue
var eventEntity = eventObject as IEntity;
if (eventEntity == null)
continue;
// look for this entity in superceding event args
// found = must be removed, else track
if (IsSuperceeded(eventEntity, infos, entities))
toRemove.Add(eventEntity);
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
}
entities.Add(Tuple.Create(eventEntity, infos));
}
//remove anything that has been filtered
// remove superceded entities
foreach (var entity in toRemove)
{
list.Remove(entity);
}
eventObjects.Remove(entity);
//track the event and include in the response if there's still entities remaining in the list
if (list.Count > 0)
// if there are still entities in the list, keep the event definition
if (eventObjects.Count > 0)
{
if (toRemove.Count > 0)
{
//re-assign if the items have changed
args.EventObject = list;
// re-assign if changed
args.EventObject = eventObjects;
}
cancelableArgs.Add(args);
result.Add(eventDefinition);
// track result arguments
// include event definition in result
resultArgs.Add(args);
result.Add(def);
}
}
}
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);
// go over all args in result, and update them with the latest instanceof each entity
UpdateToLatestEntities(entities, resultArgs);
//we need to reverse the result since we've been adding by latest added events first!
// reverse, since we processed the list in reverse
result.Reverse();
return result;
}
private static void UpdateToLatestEntities(IEnumerable<Tuple<IEntity, EventDefinitionTypeData>> allEntities, IEnumerable<CancellableObjectEventArgs> cancelableArgs)
// edits event args to use the latest instance of each entity
private static void UpdateToLatestEntities(IEnumerable<Tuple<IEntity, EventDefinitionInfos>> entities, IEnumerable<CancellableObjectEventArgs> args)
{
//Now we'll deal with ensuring that only the latest(non stale) entities are used throughout all event args
// get the latest entities
// ordered hash set + keepOldest will keep the latest inserted entity (in case of duplicates)
var latestEntities = new OrderedHashSet<IEntity>(keepOldest: true);
foreach (var entity in allEntities.OrderByDescending(entity => entity.Item1.UpdateDate))
{
foreach (var entity in entities.OrderByDescending(entity => entity.Item1.UpdateDate))
latestEntities.Add(entity.Item1);
}
foreach (var args in cancelableArgs)
foreach (var arg in args)
{
var list = TypeHelper.CreateGenericEnumerableFromObject(args.EventObject);
if (list == null)
// event object can either be a single object or an enumerable of objects
// try to get as an enumerable, get null if it's not
var eventObjects = TypeHelper.CreateGenericEnumerableFromObject(arg.EventObject);
if (eventObjects == 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));
// single object
// look for a more recent entity for that object, and replace if any
// works by "equalling" entities ie the more recent one "equals" this one (though different object)
var foundEntity = latestEntities.FirstOrDefault(x => Equals(x, arg.EventObject));
if (foundEntity != null)
{
args.EventObject = foundEntity;
}
arg.EventObject = foundEntity;
}
else
{
// enumerable of objects
// same as above but for each object
var updated = false;
for (int i = 0; i < list.Count; i++)
for (var i = 0; i < eventObjects.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;
}
var foundEntity = latestEntities.FirstOrDefault(x => Equals(x, eventObjects[i]));
if (foundEntity == null) continue;
eventObjects[i] = foundEntity;
updated = true;
}
if (updated)
{
args.EventObject = list;
}
arg.EventObject = eventObjects;
}
}
}
/// <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)
// determines if a given entity, appearing in a given event definition, should be filtered out,
// considering the entities that have already been visited - an entity is filtered out if it
// appears in another even definition, which superceedes this event definition.
private static bool IsSuperceeded(IEntity entity, EventDefinitionInfos infos, List<Tuple<IEntity, EventDefinitionInfos>> entities)
{
var argType = eventDef.EventDefinition.Args.GetType();
//var argType = meta.EventArgsType;
var argType = infos.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))
// look for other instances of the same entity, coming from an event args that supercedes other event args,
// ie is marked with the attribute, and is not this event args (cannot supersede itself)
var superceeding = entities
.Where(x => x.Item2.SupersedeTypes.Length > 0 // has the attribute
&& x.Item2.EventDefinition.Args.GetType() != argType // is not the same
&& Equals(x.Item1, entity)) // same entity
.ToArray();
//no args have been processed with this entity so it should not be filtered
if (foundByEntity.Length == 0)
// first time we see this entity = not filtered
if (superceeding.Length == 0)
return false;
// fixme see notes above
// delete event args does NOT superceedes 'unpublished' event
if (argType.IsGenericType && argType.GetGenericTypeDefinition() == typeof(PublishEventArgs<>) && infos.EventDefinition.EventName == "UnPublished")
return false;
// found occurences, need to determine if this event args is superceded
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)));
// generic, must compare type arguments
var supercededBy = superceeding.FirstOrDefault(x =>
x.Item2.SupersedeTypes.Any(y =>
// superceeding a generic type which has the same generic type definition
// fixme no matter the generic type parameters? could be different?
y.IsGenericTypeDefinition && y == argType.GetGenericTypeDefinition()
// or superceeding a non-generic type which is ... fixme how is this ever possible? argType *is* generic?
|| y.IsGenericTypeDefinition == false && y == 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));
// non-generic, can compare types 1:1
var supercededBy = superceeding.FirstOrDefault(x =>
x.Item2.SupersedeTypes.Any(y => y == argType));
return supercededBy != null;
}
}
@@ -0,0 +1,95 @@
using System;
using System.IO;
using log4net.Appender;
using log4net.Util;
namespace Umbraco.Core.Logging
{
/// <summary>
/// This class will do the exact same thing as the RollingFileAppender that comes from log4net
/// With the extension, that it is able to do automatic cleanup of the logfiles in the directory where logging happens
///
/// By specifying the properties MaxLogFileDays and BaseFilePattern, the files will automaticly get deleted when
/// the logger is configured(typically when the app starts). To utilize this appender swap out the type of the rollingFile appender
/// that ships with Umbraco, to be Umbraco.Core.Logging.RollingFileCleanupAppender, and add the maxLogFileDays and baseFilePattern elements
/// to the configuration i.e.:
///
/// <example>
/// <appender name="rollingFile" type="Log4netAwesomeness.CustomRollingFileAppender, Log4netAwesomeness">
/// <file type="log4net.Util.PatternString" value="App_Data\Logs\UmbracoTraceLog.%property{log4net:HostName}.txt" />
/// <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
/// <appendToFile value="true" />
/// <rollingStyle value="Date" />
/// <maximumFileSize value="5MB" />
/// <maxLogFileDays value="5"/>
/// <basefilePattern value="UmbracoTraceLog.*.txt.*"/>
/// <layout type="log4net.Layout.PatternLayout">
/// <conversionPattern value=" %date [P%property{processId}/D%property{appDomainId}/T%thread] %-5level %logger - %message%newline" />
/// </layout>
/// <layout type="log4net.Layout.PatternLayout">
/// <conversionPattern value=" %date [P%property{processId}/D%property{appDomainId}/T%thread] %-5level %logger - %message%newline" />
/// </layout>
/// <encoding value="utf-8" />
/// </appender>
/// </example>
/// </summary>
public class RollingFileCleanupAppender : RollingFileAppender
{
public int MaxLogFileDays { get; set; }
public string BaseFilePattern { get; set; }
/// <summary>
/// This override will delete logs older than the specified amount of days
/// </summary>
/// <param name="fileName"></param>
/// <param name="append"></param>
protected override void OpenFile(string fileName, bool append)
{
bool cleanup = true;
// Validate settings and input
if (MaxLogFileDays <= 0)
{
LogLog.Warn(typeof(RollingFileCleanupAppender), "Parameter 'MaxLogFileDays' needs to be a positive integer, aborting cleanup");
cleanup = false;
}
if (string.IsNullOrWhiteSpace(BaseFilePattern))
{
LogLog.Warn(typeof(RollingFileCleanupAppender), "Parameter 'BaseFilePattern' is empty, aborting cleanup");
cleanup = false;
}
// grab the directory we are logging to, as this is were we will search for older logfiles
var logFolder = Path.GetDirectoryName(fileName);
if (Directory.Exists(logFolder) == false)
{
LogLog.Warn(typeof(RollingFileCleanupAppender), string.Format("Directory '{0}' for logfiles does not exist, aborting cleanup", logFolder));
cleanup = false;
}
// If everything is validated, we can do the actual cleanup
if (cleanup)
{
Cleanup(logFolder);
}
base.OpenFile(fileName, append);
}
private void Cleanup(string directoryPath)
{
// only take files that matches the pattern we are using i.e. UmbracoTraceLog.*.txt.*
string[] logFiles = Directory.GetFiles(directoryPath, BaseFilePattern);
LogLog.Debug(typeof(RollingFileCleanupAppender), string.Format("Found {0} files that matches the baseFilePattern: '{1}'", logFiles.Length, BaseFilePattern));
foreach (var logFile in logFiles)
{
DateTime lastAccessTime = System.IO.File.GetLastWriteTimeUtc(logFile);
// take the value from the config file
if (lastAccessTime < DateTime.Now.AddDays(-MaxLogFileDays))
{
LogLog.Debug(typeof(RollingFileCleanupAppender), string.Format("Deleting file {0} as its lastAccessTime is older than {1} days speficied by MaxLogFileDays", logFile, MaxLogFileDays));
base.DeleteFile(logFile);
}
}
}
}
}
@@ -188,7 +188,7 @@ namespace Umbraco.Core.Models
Language,
/// <summary>
/// Document
/// Document Blueprint
/// </summary>
[UmbracoObjectType(Constants.ObjectTypes.DocumentBlueprint, typeof(IContent))]
[FriendlyName("DocumentBlueprint")]
@@ -134,7 +134,9 @@ namespace Umbraco.Core.Persistence.Repositories
.InnerJoin<ContentDto>(SqlSyntax)
.On<ContentVersionDto, ContentDto>(SqlSyntax, left => left.NodeId, right => right.NodeId)
.InnerJoin<NodeDto>(SqlSyntax)
.On<ContentDto, NodeDto>(SqlSyntax, left => left.NodeId, right => right.NodeId);
.On<ContentDto, NodeDto>(SqlSyntax, left => left.NodeId, right => right.NodeId)
.InnerJoin<ContentTypeDto>()
.On<ContentTypeDto, ContentDto>(left => left.NodeId, right => right.ContentTypeId);
//TODO: IF we want to enable querying on content type information this will need to be joined
//.InnerJoin<ContentTypeDto>(SqlSyntax)
//.On<ContentDto, ContentTypeDto>(SqlSyntax, left => left.ContentTypeId, right => right.NodeId, SqlSyntax);
@@ -833,11 +835,21 @@ order by umbracoNode.{2}, umbracoNode.parentID, umbracoNode.sortOrder",
}
public int CountPublished()
{
var sql = GetBaseQuery(true).Where<NodeDto>(x => x.Trashed == false)
.Where<DocumentDto>(x => x.Published == true);
return Database.ExecuteScalar<int>(sql);
public int CountPublished(string contentTypeAlias = null)
{
if (contentTypeAlias.IsNullOrWhiteSpace())
{
var sql = GetBaseQuery(true).Where<NodeDto>(x => x.Trashed == false)
.Where<DocumentDto>(x => x.Published == true);
return Database.ExecuteScalar<int>(sql);
}
else
{
var sql = GetBaseQuery(true).Where<NodeDto>(x => x.Trashed == false)
.Where<DocumentDto>(x => x.Published == true)
.Where<ContentTypeDto>(x => x.Alias == contentTypeAlias);
return Database.ExecuteScalar<int>(sql);
}
}
public void ReplaceContentPermissions(EntityPermissionSet permissionSet)
@@ -26,7 +26,7 @@ namespace Umbraco.Core.Persistence.Repositories
/// <remarks>
/// We require this on the repo because the IQuery{IContent} cannot supply the 'newest' parameter
/// </remarks>
int CountPublished();
int CountPublished(string contentTypeAlias = null);
/// <summary>
/// Used to bulk update the permissions set for a content item. This will replace all permissions
@@ -183,17 +183,17 @@ namespace Umbraco.Core.Persistence.Repositories
}
public IEnumerable<IMemberGroup> GetMemberGroupsForMember(string username)
{
var sql = new Sql()
{
var sql = new Sql()
.Select("un.*")
.From("umbracoNode AS un")
.InnerJoin("cmsMember2MemberGroup")
.On("un.id = cmsMember2MemberGroup.MemberGroup")
.LeftJoin("(SELECT umbracoNode.id, cmsMember.LoginName FROM umbracoNode INNER JOIN cmsMember ON umbracoNode.id = cmsMember.nodeId) AS member")
.On("member.id = cmsMember2MemberGroup.Member")
.Where("un.nodeObjectType=@objectType", new {objectType = NodeObjectTypeId })
.Where("member.LoginName=@loginName", new {loginName = username});
.On("cmsMember2MemberGroup.MemberGroup = un.id")
.InnerJoin("cmsMember")
.On("cmsMember.nodeId = cmsMember2MemberGroup.Member")
.Where("un.nodeObjectType=@objectType", new { objectType = NodeObjectTypeId })
.Where("cmsMember.LoginName=@loginName", new { loginName = username });
return Database.Fetch<NodeDto>(sql)
.DistinctBy(dto => dto.NodeId)
.Select(x => _modelFactory.BuildEntity(x));
@@ -191,11 +191,11 @@ ORDER BY colName";
return new Dictionary<UserState, int>
{
{UserState.All, result[0].num},
{UserState.Active, result[1].num},
{UserState.Disabled, result[2].num},
{UserState.LockedOut, result[3].num},
{UserState.Invited, result[4].num}
{UserState.All, (int)result[0].num},
{UserState.Active, (int)result[1].num},
{UserState.Disabled, (int)result[2].num},
{UserState.LockedOut, (int)result[3].num},
{UserState.Invited, (int)result[4].num}
};
}
+22 -22
View File
@@ -207,7 +207,7 @@ namespace Umbraco.Core
return _currentAssembliesHash;
_currentAssembliesHash = GetFileHash(new List<Tuple<FileSystemInfo, bool>>
{
{
// the bin folder and everything in it
new Tuple<FileSystemInfo, bool>(new DirectoryInfo(IOHelper.MapPath(SystemDirectories.Bin)), false),
// the app code folder and everything in it
@@ -216,7 +216,7 @@ namespace Umbraco.Core
new Tuple<FileSystemInfo, bool>(new FileInfo(IOHelper.MapPath("~/global.asax")), false),
// trees.config - use the contents to create the hash since this gets resaved on every app startup!
new Tuple<FileSystemInfo, bool>(new FileInfo(IOHelper.MapPath(SystemDirectories.Config + "/trees.config")), true)
}, _logger);
}, _logger);
return _currentAssembliesHash;
}
@@ -601,7 +601,7 @@ namespace Umbraco.Core
if (cache == false || typeof(IDiscoverable).IsAssignableFrom(typeof(T)) == false)
{
return ResolveTypesInternal(
typeof (T), null,
typeof(T), null,
() => TypeFinder.FindClassesOfType<T>(specificAssemblies ?? AssembliesToScan),
cache);
}
@@ -610,14 +610,14 @@ namespace Umbraco.Core
// filter the cached discovered types (and cache the result)
var discovered = ResolveTypesInternal(
typeof (IDiscoverable), null,
typeof(IDiscoverable), null,
() => TypeFinder.FindClassesOfType<IDiscoverable>(AssembliesToScan),
true);
return ResolveTypesInternal(
typeof (T), null,
typeof(T), null,
() => discovered
.Where(x => typeof (T).IsAssignableFrom(x)),
.Where(x => typeof(T).IsAssignableFrom(x)),
true);
}
@@ -640,7 +640,7 @@ namespace Umbraco.Core
if (cache == false || typeof(IDiscoverable).IsAssignableFrom(typeof(T)) == false)
{
return ResolveTypesInternal(
typeof (T), typeof (TAttribute),
typeof(T), typeof(TAttribute),
() => TypeFinder.FindClassesOfTypeWithAttribute<T, TAttribute>(specificAssemblies ?? AssembliesToScan),
cache);
}
@@ -649,12 +649,12 @@ namespace Umbraco.Core
// filter the cached discovered types (and cache the result)
var discovered = ResolveTypesInternal(
typeof (IDiscoverable), null,
typeof(IDiscoverable), null,
() => TypeFinder.FindClassesOfType<IDiscoverable>(AssembliesToScan),
true);
return ResolveTypesInternal(
typeof (T), typeof (TAttribute),
typeof(T), typeof(TAttribute),
() => discovered
.Where(x => typeof(T).IsAssignableFrom(x))
.Where(x => x.GetCustomAttributes<TAttribute>(false).Any()),
@@ -676,7 +676,7 @@ namespace Umbraco.Core
cache &= specificAssemblies == null;
return ResolveTypesInternal(
typeof (object), typeof (TAttribute),
typeof(object), typeof(TAttribute),
() => TypeFinder.FindClassesWithAttribute<TAttribute>(specificAssemblies ?? AssembliesToScan),
cache);
}
@@ -694,13 +694,13 @@ namespace Umbraco.Core
var name = ResolvedName(baseType, attributeType);
lock (_typesLock)
using (_logger.TraceDuration<PluginManager>(
"Resolving " + name,
"Resolved " + name)) // cannot contain typesFound.Count as it's evaluated before the find
{
// resolve within a lock & timer
return ResolveTypesInternalLocked(baseType, attributeType, finder, cache);
}
using (_logger.TraceDuration<PluginManager>(
"Resolving " + name,
"Resolved " + name)) // cannot contain typesFound.Count as it's evaluated before the find
{
// resolve within a lock & timer
return ResolveTypesInternalLocked(baseType, attributeType, finder, cache);
}
}
private static string ResolvedName(Type baseType, Type attributeType)
@@ -836,7 +836,7 @@ namespace Umbraco.Core
public TypeListKey(Type baseType, Type attributeType)
{
BaseType = baseType ?? typeof (object);
BaseType = baseType ?? typeof(object);
AttributeType = attributeType;
}
@@ -854,7 +854,7 @@ namespace Umbraco.Core
var hash = 5381;
hash = ((hash << 5) + hash) ^ BaseType.GetHashCode();
hash = ((hash << 5) + hash) ^ (AttributeType ?? typeof (TypeListKey)).GetHashCode();
hash = ((hash << 5) + hash) ^ (AttributeType ?? typeof(TypeListKey)).GetHashCode();
return hash;
}
}
@@ -917,7 +917,7 @@ namespace Umbraco.Core
{
// look for IParameterEditor (fast, IDiscoverable) then filter
var propertyEditor = typeof (PropertyEditor);
var propertyEditor = typeof(PropertyEditor);
return mgr.ResolveTypes<IParameterEditor>()
.Where(x => propertyEditor.IsAssignableFrom(x) && x != propertyEditor);
@@ -932,8 +932,8 @@ namespace Umbraco.Core
/// </remarks>
public static IEnumerable<Type> ResolveParameterEditors(this PluginManager mgr)
{
var propertyEditor = typeof (PropertyEditor);
var parameterEditor = typeof (ParameterEditor);
var propertyEditor = typeof(PropertyEditor);
var parameterEditor = typeof(ParameterEditor);
return mgr.ResolveTypes<IParameterEditor>()
.Where(x => x != propertyEditor && x != parameterEditor);
@@ -12,6 +12,7 @@ using Umbraco.Core.Models.Identity;
namespace Umbraco.Core.Security
{
//TODO: In v8 we need to change this to use an int? nullable TKey instead, see notes against overridden TwoFactorSignInAsync
public class BackOfficeSignInManager : SignInManager<BackOfficeIdentityUser, int>
{
private readonly ILogger _logger;
@@ -259,5 +260,67 @@ namespace Umbraco.Core.Security
}
return null;
}
/// <summary>
/// Two factor verification step
/// </summary>
/// <param name="provider"></param>
/// <param name="code"></param>
/// <param name="isPersistent"></param>
/// <param name="rememberBrowser"></param>
/// <returns></returns>
/// <remarks>
/// This is implemented because we cannot override GetVerifiedUserIdAsync and instead we have to shadow it
/// so due to this and because we are using an INT as the TKey and not an object, it can never be null. Adding to that
/// the default(int) value returned by the base class is always a valid user (i.e. the admin) so we just have to duplicate
/// all of this code to check for -1 instead.
/// </remarks>
public override async Task<SignInStatus> TwoFactorSignInAsync(string provider, string code, bool isPersistent, bool rememberBrowser)
{
var userId = await GetVerifiedUserIdAsync();
if (userId == -1)
{
return SignInStatus.Failure;
}
var user = await UserManager.FindByIdAsync(userId);
if (user == null)
{
return SignInStatus.Failure;
}
if (await UserManager.IsLockedOutAsync(user.Id))
{
return SignInStatus.LockedOut;
}
if (await UserManager.VerifyTwoFactorTokenAsync(user.Id, provider, code))
{
// When token is verified correctly, clear the access failed count used for lockout
await UserManager.ResetAccessFailedCountAsync(user.Id);
await SignInAsync(user, isPersistent, rememberBrowser);
return SignInStatus.Success;
}
// If the token is incorrect, record the failure which also may cause the user to be locked out
await UserManager.AccessFailedAsync(user.Id);
return SignInStatus.Failure;
}
/// <summary>Send a two factor code to a user</summary>
/// <param name="provider"></param>
/// <returns></returns>
/// <remarks>
/// This is implemented because we cannot override GetVerifiedUserIdAsync and instead we have to shadow it
/// so due to this and because we are using an INT as the TKey and not an object, it can never be null. Adding to that
/// the default(int) value returned by the base class is always a valid user (i.e. the admin) so we just have to duplicate
/// all of this code to check for -1 instead.
/// </remarks>
public override async Task<bool> SendTwoFactorCodeAsync(string provider)
{
var userId = await GetVerifiedUserIdAsync();
if (userId == -1)
return false;
var token = await UserManager.GenerateTwoFactorTokenAsync(userId, provider);
var identityResult = await UserManager.NotifyTwoFactorTokenAsync(userId, provider, token);
return identityResult.Succeeded;
}
}
}
+93 -4
View File
@@ -62,7 +62,7 @@ namespace Umbraco.Core.Services
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateContentRepository(uow);
return repository.CountPublished();
return repository.CountPublished(contentTypeAlias);
}
}
@@ -993,8 +993,7 @@ namespace Umbraco.Core.Services
FROM umbracoNode
JOIN cmsDocument ON umbracoNode.id=cmsDocument.nodeId AND cmsDocument.published=@0
WHERE umbracoNode.trashed=@1 AND umbracoNode.id IN (@2)",
true, false, ids);
Console.WriteLine(sql.SQL);
true, false, ids);
var x = uow.Database.Fetch<int>(sql);
return ids.Length == x.Count;
}
@@ -2009,6 +2008,96 @@ namespace Umbraco.Core.Services
return true;
}
/// <summary>
/// Sorts a collection of <see cref="IContent"/> objects by updating the SortOrder according
/// to the ordering of node Ids passed in.
/// </summary>
/// <remarks>
/// Using this method will ensure that the Published-state is maintained upon sorting
/// so the cache is updated accordingly - as needed.
/// </remarks>
/// <param name="ids"></param>
/// <param name="userId"></param>
/// <param name="raiseEvents"></param>
/// <returns>True if sorting succeeded, otherwise False</returns>
public bool Sort(int[] ids, int userId = 0, bool raiseEvents = true)
{
var shouldBePublished = new List<IContent>();
var shouldBeSaved = new List<IContent>();
using (new WriteLock(Locker))
{
var allContent = GetByIds(ids).ToDictionary(x => x.Id, x => x);
var items = ids.Select(x => allContent[x]);
using (var uow = UowProvider.GetUnitOfWork())
{
var asArray = items.ToArray();
var saveEventArgs = new SaveEventArgs<IContent>(asArray);
if (raiseEvents && uow.Events.DispatchCancelable(Saving, this, saveEventArgs, "Saving"))
{
uow.Commit();
return false;
}
var repository = RepositoryFactory.CreateContentRepository(uow);
var i = 0;
foreach (var content in asArray)
{
//If the current sort order equals that of the content
//we don't need to update it, so just increment the sort order
//and continue.
if (content.SortOrder == i)
{
i++;
continue;
}
content.SortOrder = i;
content.WriterId = userId;
i++;
if (content.Published)
{
//TODO: This should not be an inner operation, but if we do this, it cannot raise events and cannot be cancellable!
var published = _publishingStrategy.Publish(uow, content, userId).Success;
shouldBePublished.Add(content);
}
else
shouldBeSaved.Add(content);
repository.AddOrUpdate(content);
//add or update a preview
repository.AddOrUpdatePreviewXml(content, c => _entitySerializer.Serialize(this, _dataTypeService, _userService, c));
}
foreach (var content in shouldBePublished)
{
//Create and Save ContentXml DTO
repository.AddOrUpdateContentXml(content, c => _entitySerializer.Serialize(this, _dataTypeService, _userService, c));
}
if (raiseEvents)
{
saveEventArgs.CanCancel = false;
uow.Events.Dispatch(Saved, this, saveEventArgs, "Saved");
}
if (shouldBePublished.Any())
{
//TODO: This should not be an inner operation, but if we do this, it cannot raise events and cannot be cancellable!
_publishingStrategy.PublishingFinalized(uow, shouldBePublished, false);
}
Audit(uow, AuditType.Sort, "Sorting content performed by user", userId, 0);
uow.Commit();
}
}
return true;
}
public IEnumerable<IContent> GetBlueprintsForContentTypes(params int[] documentTypeIds)
{
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
@@ -2749,4 +2838,4 @@ namespace Umbraco.Core.Services
#endregion
}
}
}
@@ -377,7 +377,7 @@ namespace Umbraco.Core.Services
repo.Delete(container);
uow.Commit();
deleteEventArgs.CanCancel = false;
uow.Events.Dispatch(DeletedMediaTypeContainer, this, deleteEventArgs);
uow.Events.Dispatch(DeletedMediaTypeContainer, this, deleteEventArgs, "DeletedMediaTypeContainer");
return OperationStatus.Success(evtMsgs);
//TODO: Audit trail ?
@@ -42,6 +42,7 @@ namespace Umbraco.Core.Services
xml.Add(new XAttribute("writerID", content.WriterId));
xml.Add(new XAttribute("template", content.Template == null ? "0" : content.Template.Id.ToString(CultureInfo.InvariantCulture)));
xml.Add(new XAttribute("nodeTypeAlias", content.ContentType.Alias));
xml.Add(new XAttribute("isPublished", content.Published));
if (deep)
{
+15 -1
View File
@@ -642,7 +642,21 @@ namespace Umbraco.Core.Services
/// <param name="userId"></param>
/// <param name="raiseEvents"></param>
/// <returns>True if sorting succeeded, otherwise False</returns>
bool Sort(IEnumerable<IContent> items, int userId = 0, bool raiseEvents = true);
bool Sort(IEnumerable<IContent> items, int userId = 0, bool raiseEvents = true);
/// <summary>
/// Sorts a collection of <see cref="IContent"/> objects by updating the SortOrder according
/// to the ordering of node Ids passed in.
/// </summary>
/// <remarks>
/// Using this method will ensure that the Published-state is maintained upon sorting
/// so the cache is updated accordingly - as needed.
/// </remarks>
/// <param name="ids"></param>
/// <param name="userId"></param>
/// <param name="raiseEvents"></param>
/// <returns>True if sorting succeeded, otherwise False</returns>
bool Sort(int[] ids, int userId = 0, bool raiseEvents = true);
/// <summary>
/// Gets the parent of the current content as an <see cref="IContent"/> item.
+2 -2
View File
@@ -106,8 +106,8 @@ namespace Umbraco.Core.Services
try
{
_locker.EnterWriteLock();
_id2Key[id] = new TypedId<Guid>(val.Value, umbracoObjectType); ;
_key2Id[val.Value] = new TypedId<int>();
_id2Key[id] = new TypedId<Guid>(val.Value, umbracoObjectType);
_key2Id[val.Value] = new TypedId<int>(id, umbracoObjectType);
}
finally
{
+5 -1
View File
@@ -986,7 +986,11 @@ namespace Umbraco.Core.Services
/// <param name="raiseEvents">Optional parameter to raise events.
/// Default is <c>True</c> otherwise set to <c>False</c> to not raise events</param>
public void Save(IMember entity, bool raiseEvents = true)
{
{
//trimming username and email to make sure we have no trailing space
entity.Username = entity.Username.Trim();
entity.Email = entity.Email.Trim();
using (var uow = UowProvider.GetUnitOfWork())
{
var saveEventArgs = new SaveEventArgs<IMember>(entity);
+3 -3
View File
@@ -228,9 +228,9 @@ namespace Umbraco.Core.Services
}
/// <summary>
/// Deletes an <see cref="IUser"/>
/// Disables an <see cref="IUser"/>
/// </summary>
/// <param name="membershipUser"><see cref="IUser"/> to Delete</param>
/// <param name="membershipUser"><see cref="IUser"/> to disable</param>
public void Delete(IUser membershipUser)
{
//disable
@@ -712,7 +712,7 @@ namespace Umbraco.Core.Services
/// <param name="id">Id of the User to retrieve</param>
/// <returns><see cref="IProfile"/></returns>
public IProfile GetProfileById(int id)
{
{
//This is called a TON. Go get the full user from cache which should already be IProfile
var fullUser = GetUserById(id);
var asProfile = fullUser as IProfile;
+21 -3
View File
@@ -3,6 +3,7 @@ using System.Web;
using Umbraco.Core.Configuration;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
using Umbraco.Core.ObjectResolution;
namespace Umbraco.Core.Sync
@@ -46,8 +47,20 @@ namespace Umbraco.Core.Sync
// settings: for unit tests only
internal static void EnsureApplicationUrl(ApplicationContext appContext, HttpRequestBase request = null, IUmbracoSettingsSection settings = null)
{
bool newApplicationUrl = false;
if (request != null)
{
var applicationUrl = GetApplicationUrlFromRequest(request);
newApplicationUrl = !appContext._umbracoApplicationDomains.Contains(applicationUrl);
if (newApplicationUrl)
{
appContext._umbracoApplicationDomains.Add(applicationUrl);
LogHelper.Info(typeof(ApplicationUrlHelper), $"New ApplicationUrl detected: {applicationUrl}");
}
}
// if initialized, return
if (appContext._umbracoApplicationUrl != null) return;
if (appContext._umbracoApplicationUrl != null && !newApplicationUrl) return;
var logger = appContext.ProfilingLogger.Logger;
@@ -132,6 +145,12 @@ namespace Umbraco.Core.Sync
{
var logger = appContext.ProfilingLogger.Logger;
appContext._umbracoApplicationUrl = GetApplicationUrlFromRequest(request);
logger.Info(TypeOfApplicationUrlHelper, "ApplicationUrl: " + appContext.UmbracoApplicationUrl + " (UmbracoModule request)");
}
private static string GetApplicationUrlFromRequest(HttpRequestBase request)
{
// if (HTTP and SSL not required) or (HTTPS and SSL required),
// use ports from request
// otherwise,
@@ -147,8 +166,7 @@ namespace Umbraco.Core.Sync
var ssl = useSsl ? "s" : ""; // force, whatever the first request
var url = "http" + ssl + "://" + request.ServerVariables["SERVER_NAME"] + port + IOHelper.ResolveUrl(SystemDirectories.Umbraco);
appContext._umbracoApplicationUrl = url.TrimEnd('/');
logger.Info(TypeOfApplicationUrlHelper, "ApplicationUrl: " + appContext.UmbracoApplicationUrl + " (UmbracoModule request)");
return url.TrimEnd('/');
}
}
}
+4
View File
@@ -117,6 +117,8 @@ namespace Umbraco.Core
{
case UmbracoObjectTypes.Document:
return Document;
case UmbracoObjectTypes.DocumentBlueprint:
return DocumentBluePrint;
case UmbracoObjectTypes.Media:
return Media;
case UmbracoObjectTypes.Member:
@@ -161,6 +163,8 @@ namespace Umbraco.Core
{
case Document:
return UmbracoObjectTypes.Document;
case DocumentBluePrint:
return UmbracoObjectTypes.DocumentBlueprint;
case Media:
return UmbracoObjectTypes.Media;
case Member:
+4 -12
View File
@@ -39,25 +39,21 @@
<ItemGroup>
<Reference Include="AutoMapper, Version=3.3.1.0, Culture=neutral, PublicKeyToken=be96cd2c38ef1005, processorArchitecture=MSIL">
<HintPath>..\packages\AutoMapper.3.3.1\lib\net40\AutoMapper.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="AutoMapper.Net4, Version=3.3.1.0, Culture=neutral, PublicKeyToken=be96cd2c38ef1005, processorArchitecture=MSIL">
<HintPath>..\packages\AutoMapper.3.3.1\lib\net40\AutoMapper.Net4.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="ClientDependency.Core, Version=1.9.2.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\ClientDependency.1.9.2\lib\net45\ClientDependency.Core.dll</HintPath>
</Reference>
<Reference Include="HtmlAgilityPack, Version=1.4.9.5, Culture=neutral, PublicKeyToken=bd319b19eaf3b43a, processorArchitecture=MSIL">
<HintPath>..\packages\HtmlAgilityPack.1.4.9.5\lib\Net45\HtmlAgilityPack.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="ICSharpCode.SharpZipLib, Version=0.86.0.518, Culture=neutral, PublicKeyToken=1b03e6acf1164f73, processorArchitecture=MSIL">
<HintPath>..\packages\SharpZipLib.0.86.0\lib\20\ICSharpCode.SharpZipLib.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="ImageProcessor, Version=2.5.3.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\ImageProcessor.2.5.3\lib\net45\ImageProcessor.dll</HintPath>
<Reference Include="ImageProcessor, Version=2.5.6.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\ImageProcessor.2.5.6\lib\net45\ImageProcessor.dll</HintPath>
</Reference>
<Reference Include="log4net, Version=2.0.8.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
<HintPath>..\packages\log4net.2.0.8\lib\net45-full\log4net.dll</HintPath>
@@ -67,11 +63,9 @@
</Reference>
<Reference Include="Microsoft.AspNet.Identity.Core, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.Identity.Core.2.2.1\lib\net45\Microsoft.AspNet.Identity.Core.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.AspNet.Identity.Owin, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.AspNet.Identity.Owin.2.2.1\lib\net45\Microsoft.AspNet.Identity.Owin.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Owin, Version=3.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Owin.3.1.0\lib\net45\Microsoft.Owin.dll</HintPath>
@@ -87,17 +81,16 @@
</Reference>
<Reference Include="MiniProfiler, Version=2.1.0.0, Culture=neutral, PublicKeyToken=b44f9351044011a3, processorArchitecture=MSIL">
<HintPath>..\packages\MiniProfiler.2.1.0\lib\net40\MiniProfiler.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="MySql.Data, Version=6.9.9.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d, processorArchitecture=MSIL">
<HintPath>..\packages\MySql.Data.6.9.9\lib\net45\MySql.Data.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.10.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="Owin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f0ebd12fd5e55cc5, processorArchitecture=MSIL">
<HintPath>..\packages\Owin.1.0\lib\net40\Owin.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Semver, Version=1.1.2.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\semver.1.1.2\lib\net45\Semver.dll</HintPath>
@@ -109,11 +102,9 @@
<Reference Include="System.Data.Entity" />
<Reference Include="System.Data.SqlServerCe, Version=4.0.0.1, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL">
<HintPath>..\packages\SqlServerCE.4.0.0.1\lib\System.Data.SqlServerCe.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Data.SqlServerCe.Entity, Version=4.0.0.1, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL">
<HintPath>..\packages\SqlServerCE.4.0.0.1\lib\System.Data.SqlServerCe.Entity.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.DirectoryServices.AccountManagement" />
<Reference Include="System.Drawing" />
@@ -366,6 +357,7 @@
<Compile Include="HashGenerator.cs" />
<Compile Include="IEmailSender.cs" />
<Compile Include="IHttpContextAccessor.cs" />
<Compile Include="Logging\RollingFileCleanupAppender.cs" />
<Compile Include="Models\EntityBase\EntityPath.cs" />
<Compile Include="Models\EntityBase\IDeletableEntity.cs" />
<Compile Include="Models\IUserControl.cs" />
+1 -1
View File
@@ -3,7 +3,7 @@
<package id="AutoMapper" version="3.3.1" targetFramework="net45" />
<package id="ClientDependency" version="1.9.2" targetFramework="net45" />
<package id="HtmlAgilityPack" version="1.4.9.5" targetFramework="net45" />
<package id="ImageProcessor" version="2.5.3" targetFramework="net45" />
<package id="ImageProcessor" version="2.5.6" targetFramework="net45" />
<package id="log4net" version="2.0.8" targetFramework="net45" />
<package id="Log4Net.Async" version="2.0.4" targetFramework="net45" />
<package id="Microsoft.AspNet.Identity.Core" version="2.2.1" targetFramework="net45" />
@@ -40,34 +40,27 @@
<ItemGroup>
<Reference Include="BenchmarkDotNet, Version=0.9.9.0, Culture=neutral, PublicKeyToken=aa0ca2f9092cefc4, processorArchitecture=MSIL">
<HintPath>..\packages\BenchmarkDotNet.0.9.9\lib\net45\BenchmarkDotNet.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="BenchmarkDotNet.Core, Version=0.9.9.0, Culture=neutral, PublicKeyToken=aa0ca2f9092cefc4, processorArchitecture=MSIL">
<HintPath>..\packages\BenchmarkDotNet.Core.0.9.9\lib\net45\BenchmarkDotNet.Core.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="BenchmarkDotNet.Diagnostics.Windows, Version=0.9.9.0, Culture=neutral, PublicKeyToken=aa0ca2f9092cefc4, processorArchitecture=MSIL">
<HintPath>..\packages\BenchmarkDotNet.Diagnostics.Windows.0.9.9\lib\net45\BenchmarkDotNet.Diagnostics.Windows.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="BenchmarkDotNet.Toolchains.Roslyn, Version=0.9.9.0, Culture=neutral, PublicKeyToken=aa0ca2f9092cefc4, processorArchitecture=MSIL">
<HintPath>..\packages\BenchmarkDotNet.Toolchains.Roslyn.0.9.9\lib\net45\BenchmarkDotNet.Toolchains.Roslyn.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Castle.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
<HintPath>..\packages\Castle.Core.4.0.0\lib\net45\Castle.Core.dll</HintPath>
</Reference>
<Reference Include="Microsoft.CodeAnalysis, Version=1.3.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.CodeAnalysis.Common.1.3.2\lib\net45\Microsoft.CodeAnalysis.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.CodeAnalysis.CSharp, Version=1.3.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.CodeAnalysis.CSharp.1.3.2\lib\net45\Microsoft.CodeAnalysis.CSharp.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Diagnostics.Tracing.TraceEvent, Version=1.0.41.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Diagnostics.Tracing.TraceEvent.1.0.41\lib\net40\Microsoft.Diagnostics.Tracing.TraceEvent.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Moq, Version=4.1.1309.919, Culture=neutral, PublicKeyToken=69f491c39445e920, processorArchitecture=MSIL">
<HintPath>..\packages\Moq.4.1.1309.0919\lib\net40\Moq.dll</HintPath>
@@ -75,27 +68,22 @@
<Reference Include="System" />
<Reference Include="System.Collections.Immutable, Version=1.2.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Collections.Immutable.1.2.0\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.ComponentModel.Composition" />
<Reference Include="System.Core" />
<Reference Include="System.Data.SqlServerCe, Version=4.0.0.1, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL">
<HintPath>..\packages\SqlServerCE.4.0.0.1\lib\System.Data.SqlServerCe.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Data.SqlServerCe.Entity, Version=4.0.0.1, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL">
<HintPath>..\packages\SqlServerCE.4.0.0.1\lib\System.Data.SqlServerCe.Entity.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Management" />
<Reference Include="System.Numerics" />
<Reference Include="System.Reflection.Metadata, Version=1.3.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Reflection.Metadata.1.3.0\lib\portable-net45+win8\System.Reflection.Metadata.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Threading.Tasks.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Threading.Tasks.Extensions.4.0.0\lib\portable-net45+win8+wp8+wpa81\System.Threading.Tasks.Extensions.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
@@ -116,6 +104,7 @@
<ItemGroup>
<None Include="App.config" />
<None Include="packages.config" />
<None Include="_TraceEventProgrammersGuide.docx" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Umbraco.Core\Umbraco.Core.csproj">
@@ -132,8 +121,8 @@
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Analyzer Include="..\packages\Microsoft.CodeAnalysis.Analyzers.1.1.0\analyzers\dotnet\cs\Microsoft.CodeAnalysis.Analyzers.dll" />
<Analyzer Include="..\packages\Microsoft.CodeAnalysis.Analyzers.1.1.0\analyzers\dotnet\cs\Microsoft.CodeAnalysis.CSharp.Analyzers.dll" />
<Content Include="TraceEvent.ReadMe.txt" />
<Content Include="TraceEvent.ReleaseNotes.txt" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
@@ -3,10 +3,13 @@ using System.Collections.Generic;
using System.Linq;
using Moq;
using NUnit.Framework;
using umbraco.cms.businesslogic;
using Umbraco.Core;
using Umbraco.Core.Events;
using Umbraco.Core.Models;
using Umbraco.Core.Persistence;
using Umbraco.Core.Scoping;
using Umbraco.Core.Services;
using Umbraco.Tests.TestHelpers;
using Umbraco.Tests.TestHelpers.Entities;
@@ -99,7 +102,7 @@ namespace Umbraco.Tests.Scoping
DoDeleteForContent += OnDoThingFail;
DoForTestArgs += OnDoThingFail;
DoForTestArgs2 += OnDoThingFail;
var contentType = MockedContentTypes.CreateBasicContentType();
var content1 = MockedContent.CreateBasicContent(contentType);
@@ -114,10 +117,10 @@ namespace Umbraco.Tests.Scoping
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(DoDeleteForContent, this, new DeleteEventArgs<IContent>(content1), "DoDeleteForContent");
scope.Events.Dispatch(DoSaveForContent, this, new SaveEventArgs<IContent>(content2));
//this entire event will be filtered
scope.Events.Dispatch(DoForTestArgs, this, new TestEventArgs(content1));
@@ -141,15 +144,36 @@ namespace Umbraco.Tests.Scoping
}
}
[Test]
public void SupersededEvents2()
{
var contentService = Mock.Of<IContentService>();
var content = Mock.Of<IContent>();
var l1 = new List<IEventDefinition>
{
new EventDefinition<IContentService, PublishEventArgs<IContent>>(Test_UnPublished, contentService, new PublishEventArgs<IContent>(new [] { content }), "UnPublished"),
new EventDefinition<IContentService, DeleteEventArgs<IContent>>(Test_Deleted, contentService, new DeleteEventArgs<IContent>(new [] { content }), "Deleted")
};
var l2 = new OrderedHashSet<IEventDefinition>(keepOldest: false);
foreach (var e in l1)
l2.Add(e);
var l3 = ScopeEventDispatcherBase.FilterSupersededAndUpdateToLatestEntity(l2);
// see U4-10764
Assert.AreEqual(2, l3.Count());
}
/// <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
/// 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;
DoSaveForContent += OnDoThingFail;
var now = DateTime.Now;
var contentType = MockedContentTypes.CreateBasicContentType();
@@ -165,7 +189,7 @@ namespace Umbraco.Tests.Scoping
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));
@@ -173,7 +197,7 @@ namespace Umbraco.Tests.Scoping
// 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;
@@ -212,7 +236,7 @@ namespace Umbraco.Tests.Scoping
// events have been queued
var events = scope.Events.GetEvents(EventDefinitionFilter.FirstIn).ToArray();
Assert.AreEqual(1, events.Length);
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);
@@ -350,6 +374,9 @@ namespace Umbraco.Tests.Scoping
public static event TypedEventHandler<ScopeEventDispatcherTests, SaveEventArgs<decimal>> DoThing3;
public static event TypedEventHandler<IContentService, PublishEventArgs<IContent>> Test_UnPublished;
public static event TypedEventHandler<IContentService, DeleteEventArgs<IContent>> Test_Deleted;
public class TestEventArgs : CancellableObjectEventArgs
{
public TestEventArgs(object eventObject) : base(eventObject)
@@ -124,7 +124,7 @@ namespace Umbraco.Tests.TestHelpers
protected virtual void ResetPluginManager()
{
PluginManager.Current = null;
}
}
protected virtual CacheHelper CreateCacheHelper()
{
+6
View File
@@ -14,6 +14,12 @@ namespace Umbraco.Tests
[TestFixture]
public class UdiTests : BaseUmbracoApplicationTest
{
[SetUp]
public void Setup()
{
Udi.ResetUdiTypes();
}
[Test]
public void StringUdiCtorTest()
{
+2 -2
View File
@@ -62,8 +62,8 @@
<Reference Include="Castle.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
<HintPath>..\packages\Castle.Core.4.0.0\lib\net45\Castle.Core.dll</HintPath>
</Reference>
<Reference Include="Examine, Version=0.1.85.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Examine.0.1.85\lib\net45\Examine.dll</HintPath>
<Reference Include="Examine, Version=0.1.89.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Examine.0.1.89\lib\net45\Examine.dll</HintPath>
</Reference>
<Reference Include="ICSharpCode.SharpZipLib, Version=0.86.0.518, Culture=neutral, PublicKeyToken=1b03e6acf1164f73, processorArchitecture=MSIL">
<HintPath>..\packages\SharpZipLib.0.86.0\lib\20\ICSharpCode.SharpZipLib.dll</HintPath>
@@ -20,8 +20,14 @@ using Umbraco.Web.Templates;
namespace Umbraco.Tests.Web
{
[TestFixture]
public class TemplateUtilitiesTests
public class TemplateUtilitiesTests : BaseUmbracoApplicationTest
{
[SetUp]
public void Setup()
{
Udi.ResetUdiTypes();
}
[TestCase("", "")]
[TestCase("hello href=\"{localLink:1234}\" world ", "hello href=\"/my-test-url\" world ")]
[TestCase("hello href=\"{localLink:umb://document-type/9931BDE0-AAC3-4BAB-B838-909A7B47570E}\" world ", "hello href=\"/my-test-url\" world ")]
+1 -1
View File
@@ -2,7 +2,7 @@
<packages>
<package id="AutoMapper" version="3.3.1" targetFramework="net45" />
<package id="Castle.Core" version="4.0.0" targetFramework="net45" />
<package id="Examine" version="0.1.85" targetFramework="net45" />
<package id="Examine" version="0.1.89" targetFramework="net45" />
<package id="log4net" version="2.0.8" targetFramework="net45" />
<package id="Log4Net.Async" version="2.0.4" targetFramework="net45" />
<package id="Lucene.Net" version="2.9.4.1" targetFramework="net45" />
@@ -31,15 +31,17 @@
display: block;
padding: 4px;
line-height: @baseLineHeight;
border: 1px solid #ddd;
border: 1px solid @gray-8;
.border-radius(@baseBorderRadius);
.box-shadow(0 1px 3px rgba(0,0,0,.055));
.transition(all .2s ease-in-out);
}
// Add a hover/focus state for linked versions only
a.thumbnail:hover,
a.thumbnail:focus {
border-color: @linkColor;
// Add a hover/focus state for linked versions only.
a.thumbnail:hover,
a.thumbnail:focus,
a div.thumbnail:hover,
a div.thumbnail:focus {
border-color: @turquoise;
.box-shadow(0 1px 4px rgba(0,105,214,.25));
}
+1 -1
View File
@@ -26,7 +26,7 @@
"cssnano": "^3.7.6",
"gulp": "^3.9.1",
"gulp-concat": "^2.6.0",
"gulp-connect": "^5.0.0",
"gulp-connect": "5.0.0",
"gulp-less": "^3.1.0",
"gulp-ngdocs": "^0.3.0",
"gulp-open": "^2.0.0",
@@ -3,7 +3,7 @@
* @name umbraco.directives.directive:umbSections
* @restrict E
**/
function sectionsDirective($timeout, $window, navigationService, treeService, sectionService, appState, eventsService, $location) {
function sectionsDirective($timeout, $window, navigationService, treeService, sectionService, appState, eventsService, $location, historyService) {
return {
restrict: "E", // restrict to an element
replace: true, // replace the html element with the template
@@ -161,7 +161,9 @@ function sectionsDirective($timeout, $window, navigationService, treeService, se
$location.path(section.routePath);
}
else {
$location.path(section.alias).search('');
var lastAccessed = historyService.getLastAccessedItemForSection(section.alias);
var path = lastAccessed != null ? lastAccessed.link : section.alias;
$location.path(path).search('');
}
};
@@ -366,6 +366,9 @@ angular.module("umbraco.directives")
// element might still be there even after the modal has been hidden.
scope.$on('$destroy', function () {
unsubscribe();
if (tinyMceEditor !== undefined && tinyMceEditor != null) {
tinyMceEditor.destroy()
}
});
});
@@ -36,7 +36,7 @@ angular.module("umbraco.directives")
// this will greatly improve performance since there's potentially a lot of nodes being rendered = a LOT of watches!
template: '<li ng-class="{\'current\': (node == currentNode), \'has-children\': node.hasChildren}" on-right-click="altSelect(node, $event)">' +
'<div ng-class="getNodeCssClass(node)" ng-swipe-right="options(node, $event)" >' +
'<div ng-class="getNodeCssClass(node)" ng-swipe-right="options(node, $event)" ng-dblclick="load(node)" >' +
//NOTE: This ins element is used to display the search icon if the node is a container/listview and the tree is currently in dialog
//'<ins ng-if="tree.enablelistviewsearch && node.metaData.isContainer" class="umb-tree-node-search icon-search" ng-click="searchNode(node, $event)" alt="searchAltText"></ins>' +
'<ins ng-class="{\'icon-navigation-right\': !node.expanded || node.metaData.isContainer, \'icon-navigation-down\': node.expanded && !node.metaData.isContainer}" ng-click="load(node)">&nbsp;</ins>' +
@@ -110,7 +110,7 @@ Use this directive to generate a thumbnail grid of media items.
itemMinWidth = scope.itemMinWidth;
}
if (scope.itemMinWidth) {
if (scope.itemMinHeight) {
itemMinHeight = scope.itemMinHeight;
}
@@ -77,7 +77,7 @@
@param {string} icon (<code>binding</code>): The node icon.
@param {string} name (<code>binding</code>): The node name.
@param {boolean} published (<code>binding</code>): The node pusblished state.
@param {boolean} published (<code>binding</code>): The node published state.
@param {string} description (<code>binding</code>): A short description.
@param {boolean} sortable (<code>binding</code>): Will add a move cursor on the node preview. Can used in combination with ui-sortable.
@param {boolean} allowRemove (<code>binding</code>): Show/Hide the remove button.
@@ -1,4 +1,15 @@
(function () {
/**
@ngdoc directive
@name umbraco.directives.directive:umbPasswordToggle
@restrict E
@scope
@description
<strong>Added in Umbraco v. 7.7.4:</strong> Use this directive to render a password toggle.
**/
(function () {
'use strict';
// comes from https://codepen.io/jakob-e/pen/eNBQaP
@@ -1,3 +1,114 @@
/**
@ngdoc directive
@name umbraco.directives.directive:umbTable
@restrict E
@scope
@description
<strong>Added in Umbraco v. 7.4:</strong> Use this directive to render a data table.
<h3>Markup example</h3>
<pre>
<div ng-controller="My.TableController as vm">
<umb-table
ng-if="items"
items="vm.items"
item-properties="vm.options.includeProperties"
allow-select-all="vm.allowSelectAll"
on-select="vm.selectItem"
on-click="vm.clickItem"
on-select-all="vm.selectAll"
on-selected-all="vm.isSelectedAll"
on-sorting-direction="vm.isSortDirection"
on-sort="vm.sort">
</umb-table>
</div>
</pre>
<h3>Controller example</h3>
<pre>
(function () {
"use strict";
function Controller() {
var vm = this;
vm.items = [
{
"icon": "icon-document",
"name": "My node 1",
"published": true,
"description": "A short description of my node",
"author": "Author 1"
},
{
"icon": "icon-document",
"name": "My node 2",
"published": true,
"description": "A short description of my node",
"author": "Author 2"
}
];
vm.options = {
includeProperties: [
{ alias: "description", header: "Description" },
{ alias: "author", header: "Author" }
]
};
vm.selectItem = selectItem;
vm.clickItem = clickItem;
vm.selectAll = selectAll;
vm.isSelectedAll = isSelectedAll;
vm.isSortDirection = isSortDirection;
vm.sort = sort;
function selectAll($event) {
alert("select all");
}
function isSelectedAll() {
}
function clickItem(item) {
alert("click node");
}
function selectItem(selectedItem, $index, $event) {
alert("select node");
}
function isSortDirection(col, direction) {
}
function sort(field, allow, isSystem) {
}
}
angular.module("umbraco").controller("My.TableController", Controller);
})();
</pre>
@param {string} icon (<code>binding</code>): The node icon.
@param {string} name (<code>binding</code>): The node name.
@param {string} published (<code>binding</code>): The node published state.
@param {function} onSelect (<code>expression</code>): Callback function when the row is selected.
@param {function} onClick (<code>expression</code>): Callback function when the "Name" column link is clicked.
@param {function} onSelectAll (<code>expression</code>): Callback function when selecting all items.
@param {function} onSelectedAll (<code>expression</code>): Callback function when all items are selected.
@param {function} onSortingDirection (<code>expression</code>): Callback function when sorting direction is changed.
@param {function} onSort (<code>expression</code>): Callback function when sorting items.
**/
(function () {
'use strict';
@@ -41,7 +41,7 @@ function entityResource($q, $http, umbRequestHelper) {
if (!value) {
return "";
}
value = value.replace("#", "");
return umbRequestHelper.resourcePromise(
$http.get(
umbRequestHelper.getApiUrl(
@@ -115,6 +115,27 @@ angular.module('umbraco.services')
*/
getCurrent: function(){
return nArray;
}
},
/**
* @ngdoc method
* @name umbraco.services.historyService#getLastAccessedItemForSection
* @methodOf umbraco.services.historyService
*
* @description
* Method to return the item that was last accessed in the given section
*
* @param {string} sectionAlias Alias of the section to return the last accessed item for.
*/
getLastAccessedItemForSection: function (sectionAlias) {
for (var i = 0, len = nArray.length; i < len; i++) {
var item = nArray[i];
if (item.link.indexOf(sectionAlias + "/") === 0) {
return item;
}
}
return null;
}
};
});
@@ -242,8 +242,8 @@
var propGroups = _.find(genericTab.properties, function (item) {
return item.alias === "_umb_membergroup";
});
saveModel.email = propEmail.value;
saveModel.username = propLogin.value;
saveModel.email = propEmail.value.trim();
saveModel.username = propLogin.value.trim();
saveModel.password = this.formatChangePasswordModel(propPass.value);
@@ -17,7 +17,7 @@ angular.module("umbraco.install").factory('installerService', function($rootScop
//add to umbraco installer facts here
var facts = ['Umbraco helped millions of people watch a man jump from the edge of space',
'Over 420 000 websites are currently powered by Umbraco',
'Over 440 000 websites are currently powered by Umbraco',
"At least 2 people have named their cat 'Umbraco'",
'On an average day, more than 1000 people download Umbraco',
'<a target="_blank" href="https://umbraco.tv">umbraco.tv</a> is the premier source of Umbraco video tutorials to get you started',
@@ -31,10 +31,10 @@ angular.module("umbraco.install").factory('installerService', function($rootScop
"At least 4 people have the Umbraco logo tattooed on them",
"'Umbraco' is the danish name for an allen key",
"Umbraco has been around since 2005, that's a looong time in IT",
"More than 550 people from all over the world meet each year in Denmark in June for our annual conference <a target='_blank' href='https://umbra.co/codegarden'>CodeGarden</a>",
"More than 600 people from all over the world meet each year in Denmark in June for our annual conference <a target='_blank' href='https://umbra.co/codegarden'>CodeGarden</a>",
"While you are installing Umbraco someone else on the other side of the planet is probably doing it too",
"You can extend Umbraco without modifying the source code using either JavaScript or C#",
"Umbraco was installed in more than 165 countries in 2015"
"Umbraco has been installed in more than 198 countries"
];
/**
@@ -535,7 +535,7 @@
color: @gray-3;
}
.umb-grid .umb-cell-rte textarea {
.umb-grid .umb-cell-rte textarea.mceNoEditor {
display: none !important;
}
@@ -37,6 +37,7 @@
.umb-node-preview__content {
flex: 1 1 auto;
margin-right: 25px;
overflow: hidden;
}
.umb-node-preview__name {
@@ -50,6 +51,13 @@
color: @gray-3;
}
.umb-node-preview__name,
.umb-node-preview__description {
/*text-overflow: ellipsis;
overflow: hidden;*/
word-wrap: break-word;
}
.umb-node-preview__actions {
flex: 0 0 auto;
display: flex;
@@ -29,12 +29,12 @@
padding: 15px 10px;
box-sizing: border-box;
text-align: center;
border: 2px solid transparent;
border: 1px solid @gray-8;
height: 100%;
}
.umb-healthcheck-group:hover {
border: 2px solid @turquoise;
border: 1px solid @turquoise;
cursor: pointer;
}
@@ -281,6 +281,12 @@ ul.color-picker li a {
display: block;
}
.umb-sortable-thumbnails .umb-sortable-thumbnails__wrapper {
width: 120px;
height: 114px;
overflow: hidden;
}
.umb-sortable-thumbnails .umb-sortable-thumbnails__actions {
position: absolute;
bottom: 10px;
@@ -308,6 +314,7 @@ ul.color-picker li a {
justify-content: center;
align-items: center;
margin-left: 5px;
text-decoration: none;
}
.umb-sortable-thumbnails .umb-sortable-thumbnails__action.-red {
@@ -151,7 +151,8 @@
<label><localize key="general_password">Password</localize></label>
<div class="password-toggle">
<input type="password" ng-model="password" name="password" class="-full-width-input" localize="placeholder" placeholder="@placeholders_password" autocomplete="off" /><a ng-click="togglePassword()">Toggle</a>
</div>
</div>
</div>
<div class="flex justify-between items-center">
<button type="submit" class="btn btn-success" val-trigger-change="#login .form input"><localize key="general_login">Login</localize></button>
@@ -2,7 +2,7 @@
<umb-control-group label="@general_url">
<input id="url" class="umb-editor input-block-level" type="text" style="margin-bottom: 10px;" ng-model="model.embed.url" ng-keyup="$event.keyCode == 13 ? vm.showPreview() : null" required />
<input type="button" ng-click="vm.showPreview()" class="btn" localize="value" value="@general_retrieve" />
<input type="button" ng-click="vm.showPreview()" class="btn" value="@general_retrieve" localize="value" />
</umb-control-group>
<umb-control-group>
@@ -12,15 +12,15 @@
<div ng-show="model.embed.supportsDimensions">
<umb-control-group label="@general_width">
<input type="text" ng-model="model.embed.width" on-blur="vm.changeSize('width')" />
<input type="number" pattern="[0-9]*" min="0" ng-model="model.embed.width" on-blur="vm.changeSize('width')" />
</umb-control-group>
<umb-control-group label="@general_height">
<input type="text" ng-model="model.embed.height" on-blur="vm.changeSize('height')" />
<input type="number" pattern="[0-9]*" min="0" ng-model="model.embed.height" on-blur="vm.changeSize('height')" />
</umb-control-group>
<umb-control-group label="@general_constrain">
<input id="constrain" type="checkbox" ng-model="model.embed.constrain" />
<input id="constrain" type="checkbox" ng-model="model.embed.constrain" />
</umb-control-group>
</div>
@@ -31,7 +31,7 @@
<div class="umb-el-wrap">
<label class="control-label" for="altField"><localize key="templateEditor_fallbackField">Fallback field</localize></label>
<div class="controls">
<select ng-model="vm.altField" >
<select ng-model="vm.altField" id="altField">
<optgroup localize="label" label="@templateEditor_customFields">
<option ng-repeat="(key, value) in vm.properties" value="{{value}}">{{value}}</option>
</optgroup>
@@ -43,6 +43,7 @@
</div>
</div>
</div>
</div>
<!-- Default value -->
<div>
@@ -55,7 +56,7 @@
<div class="umb-el-wrap">
<label class="control-label" for="altText"><localize key="templateEditor_defaultValue">Default value</localize></label>
<div class="controls">
<input type="text" name="altText" ng-model="vm.altText" umb-auto-focus>
<input type="text" id="altText" name="altText" ng-model="vm.altText" umb-auto-focus>
</div>
</div>
</div>
@@ -65,11 +66,13 @@
<div class="control-group umb-control-group">
<div class="umb-el-wrap">
<div class="controls">
<label class="control-label" for="recursive">
<label class="control-label" >
<localize key="templateEditor_recursive">Recursive</localize>
</label>
<input type="checkbox" name="recursive" ng-model="vm.recursive">
<localize key="templateEditor_recursiveDescr">Yes, make it recursive</localize>
<label for="recursive">
<input id="recursive" type="checkbox" name="recursive" ng-model="vm.recursive">
<localize key="templateEditor_recursiveDescr">Yes, make it recursive</localize>
</label>
</div>
</div>
</div>
@@ -134,7 +137,7 @@
<small><localize key="templateEditor_insertedBefore">Will be inserted before the field value</localize></small>
</label>
<div class="controls">
<input type="text" name="insertBefore" class="-full-width-input" ng-model="vm.insertBefore">
<input type="text" id="insertBefore" name="insertBefore" class="-full-width-input" ng-model="vm.insertBefore">
</div>
</div>
</div>
@@ -147,7 +150,7 @@
<small><localize key="templateEditor_insertedAfter">Will be inserted after the field value</localize></small>
</label>
<div class="controls">
<input type="text" name="insertAfter" class="-full-width-input" ng-model="vm.insertAfter">
<input type="text" id="insertAfter" name="insertAfter" class="-full-width-input" ng-model="vm.insertAfter">
</div>
</div>
</div>
@@ -162,8 +165,10 @@
<small><localize key="templateEditor_convertLineBreaksHelp">Replaces line breaks with break html tag</localize></small>
</label>
</div>
<input type="checkbox" name="linebreaks" ng-model="vm.convertLinebreaks">
<localize key="templateEditor_convertLineBreaksDescription">Yes, convert line breaks</localize>
<label for="linebreaks">
<input type="checkbox" id="linebreaks" name="linebreaks" ng-model="vm.convertLinebreaks">
<localize key="templateEditor_convertLineBreaksDescription">Yes, convert line breaks</localize>
</label>
</div>
</div>
</div>
@@ -98,7 +98,7 @@
<localize key="contentTypeEditor_inheritedFrom"></localize> {{ tab.inheritedFromName }}
<span ng-repeat="contentTypeName in tab.parentTabContentTypeNames">
{{ contentTypeName }}
<a href="#/settings/documentTypes/edit/{{tab.contentTypeId}}">{{ contentTypeName }}</a>
<span ng-if="!$last">, </span>
</span>
</div>
@@ -1,5 +1,5 @@
<h3>Hours of Umbraco training videos are only a click away</h3>
<p>Want to master Umbraco? Spend a couple of minutes learning some best practices by watching one of these videos about using Umbraco. And visit <a class="btn-link -underline" href="http://umbraco.tv" target="_blank">umbraco.tv</a> for even more Umbraco videos</p>
<p>Want to master Umbraco? Spend a couple of minutes learning some best practices by watching one of these videos about using Umbraco, then visit <a class="btn-link -underline" href="http://umbraco.tv" target="_blank">umbraco.tv</a> for even more Umbraco videos.</p>
<div class="row-fluid"
ng-init="init('http://umbraco.tv/videos/developer/chapterrss?sort=no')"
@@ -7,14 +7,12 @@
<ul class="thumbnails" >
<li class="span2" ng-repeat="video in videos">
<div class="thumbnail" style="margin-right: 20px; padding: 20px;">
<a class="btn-link -underline" target="_blank" href="{{video.link}}" title="{{video.title}}">
<img ng-src="{{video.thumbnail}}" alt="{{video.title}}">
</a>
<a target="_blank" href="{{video.link}}" title="{{video.title}}">
<div style="font-weight: bold; text-align: center; margin: 20px 0 0;">{{video.title}}</div>
</a>
</div>
<a class="btn-link" target="_blank" href="{{video.link}}" title="{{video.title}}">
<div class="thumbnail" style="margin-right: 20px; padding: 20px;">
<img ng-src="{{video.thumbnail}}" alt="{{video.title}}">
<div style="font-weight: bold; text-align: center; margin: 20px 0 0;">{{video.title}}</div>
</div>
</a>
</li>
</ul>
</div>
@@ -19,7 +19,7 @@
<button
ng-if="vm.dashboard.urlTrackerDisabled === true"
type="button"
class="umb-era-button umb-button--s -blue"
class="umb-era-button umb-button--s -green"
ng-click="vm.enableUrlTracker()">
<span><localize key="redirectUrls_enableUrlTracker">Enable URL Tracker</localize></span>
</button>
@@ -172,9 +172,7 @@
notificationsService.error(value);
});
});
});
}
}];
}
@@ -185,34 +183,24 @@
//we are creating so get an empty data type item
contentTypeResource.getScaffold($routeParams.id)
.then(function (dt) {
init(dt);
vm.page.loading = false;
});
.then(function(dt) {
init(dt);
vm.page.loading = false;
});
}
else {
loadDocumentType();
}
function loadDocumentType() {
vm.page.loading = true;
contentTypeResource.getById($routeParams.id).then(function (dt) {
init(dt);
syncTreeNode(vm.contentType, dt.path, true);
vm.page.loading = false;
});
}
/* ---------- SAVE ---------- */
function save() {
@@ -241,7 +229,6 @@
vm.contentType.id = savedContentType.id;
vm.contentType.groups.forEach(function(group) {
if (!group.name) return;
var k = 0;
while (k < savedContentType.groups.length && savedContentType.groups[k].name != group.name)
k++;
@@ -249,13 +236,11 @@
group.id = 0;
return;
}
var savedGroup = savedContentType.groups[k];
if (!group.id) group.id = savedGroup.id;
group.properties.forEach(function (property) {
if (property.id || !property.alias) return;
k = 0;
while (k < savedGroup.properties.length && savedGroup.properties[k].alias != property.alias)
k++;
@@ -263,7 +248,6 @@
property.id = 0;
return;
}
var savedProperty = savedGroup.properties[k];
property.id = savedProperty.id;
});
@@ -289,13 +273,10 @@
});
}
vm.page.saveButtonState = "error";
deferred.reject(err);
});
return deferred.promise;
}
}
function init(contentType) {
@@ -343,12 +324,11 @@
function getDataTypeDetails(property) {
if (property.propertyState !== "init") {
dataTypeResource.getById(property.dataTypeId)
.then(function (dataType) {
property.dataTypeIcon = dataType.icon;
property.dataTypeName = dataType.name;
});
.then(function(dataType) {
property.dataTypeIcon = dataType.icon;
property.dataTypeName = dataType.name;
});
}
}
@@ -369,7 +349,6 @@
eventsService.unsubscribe(evts[e]);
}
});
}
angular.module("umbraco").controller("Umbraco.Editors.DocumentTypes.EditController", DocumentTypesEditController);
@@ -1,20 +1,25 @@
function imageFilePickerController($scope) {
$scope.pick = function() {
$scope.mediaPickerDialog = {};
$scope.mediaPickerDialog.view = "mediapicker";
$scope.mediaPickerDialog.show = true;
$scope.mediaPickerDialog.submit = function(model) {
$scope.model.value = model.selectedImages[0].image;
$scope.mediaPickerDialog.show = false;
$scope.mediaPickerDialog = null;
$scope.add = function() {
$scope.mediaPickerOverlay = {
view: "mediapicker",
disableFolderSelect: true,
onlyImages: true,
show: true,
submit: function (model) {
$scope.model.value = model.selectedImages[0].image;
$scope.mediaPickerOverlay.show = false;
$scope.mediaPickerOverlay = null;
},
close: function () {
$scope.mediaPickerOverlay.show = false;
$scope.mediaPickerOverlay = null;
}
};
};
$scope.mediaPickerDialog.close = function(oldModel) {
$scope.mediaPickerDialog.show = false;
$scope.mediaPickerDialog = null;
};
$scope.remove = function () {
$scope.model.value = null;
};
}
@@ -1,19 +1,28 @@
<div ng-controller="Umbraco.PrevalueEditors.ImageFilePickerController" class="umb-editor umb-mediapicker">
<ul class="umb-sortable-thumbnails">
<li>
<img ng-src="{{model.value}}" alt="" ng-show="model.value">
<a href class="picked-image" ng-click="model.value = null" ng-show="model.value"><i class="icon icon-delete"></i></a>
<ul class="umb-sortable-thumbnails" ng-if="model.value">
<li class="umb-sortable-thumbnails__wrapper">
<img ng-src="{{model.value}}" alt="">
<div class="umb-sortable-thumbnails__actions">
<!--<a class="umb-sortable-thumbnails__action" href="" ng-click="goToItem(image)">
<i class="icon icon-edit"></i>
</a>-->
<a class="umb-sortable-thumbnails__action -red" href="" ng-click="remove()">
<i class="icon icon-delete"></i>
</a>
</div>
</li>
</ul>
<a href ng-click="pick()" class="umb-mediapicker add-link" ng-hide="model.value">
<a href="#" class="add-link" ng-click="add()" ng-class="{'add-link-square': !model.value }" ng-hide="model.value" prevent-default>
<i class="icon icon-add large"></i>
</a>
<umb-overlay
ng-if="mediaPickerDialog.show"
model="mediaPickerDialog"
view="mediaPickerDialog.view"
ng-if="mediaPickerOverlay.show"
model="mediaPickerOverlay"
view="mediaPickerOverlay.view"
position="right">
</umb-overlay>
@@ -0,0 +1,12 @@
<div>
<input name="numberField" class="umb-editor umb-number"
type="number"
ng-model="model.value"
val-server="value"
min="0"
max="500"
fix-number />
<span class="help-inline" val-msg-for="numberField" val-toggle-msg="number">Not a number</span>
<span class="help-inline" val-msg-for="numberField" val-toggle-msg="valServer">{{propertyForm.requiredField.errorMsg}}</span>
</div>
@@ -640,16 +640,16 @@ angular.module("umbraco")
var clear = true;
//settings indicator shortcut
if ( ($scope.model.config.items.config && $scope.model.config.items.config.length > 0) || ($scope.model.config.items.styles && $scope.model.config.items.styles.length > 0)) {
if (($scope.model.config.items.config && $scope.model.config.items.config.length > 0) || ($scope.model.config.items.styles && $scope.model.config.items.styles.length > 0)) {
$scope.hasSettings = true;
}
//ensure the grid has a column value set,
//if nothing is found, set it to 12
if ($scope.model.config.items.columns && angular.isString($scope.model.config.items.columns)) {
$scope.model.config.items.columns = parseInt($scope.model.config.items.columns);
} else {
if (!$scope.model.config.items.columns){
$scope.model.config.items.columns = 12;
} else if (angular.isString($scope.model.config.items.columns)) {
$scope.model.config.items.columns = parseInt($scope.model.config.items.columns);
}
if ($scope.model.value && $scope.model.value.sections && $scope.model.value.sections.length > 0 && $scope.model.value.sections[0].rows && $scope.model.value.sections[0].rows.length > 0) {
@@ -19,6 +19,8 @@ angular.module('umbraco').controller("Umbraco.PropertyEditors.MediaPickerControl
$scope.images = [];
$scope.ids = [];
$scope.isMultiPicker = multiPicker;
if ($scope.model.value) {
var ids = $scope.model.value.split(',');
@@ -2,10 +2,10 @@
<p ng-if="(images|filter:{trashed:true}).length == 1"><localize key="mediaPicker_pickedTrashedItem"></localize></p>
<p ng-if="(images|filter:{trashed:true}).length > 1"><localize key="mediaPicker_pickedTrashedItems"></localize></p>
<div class="flex error">
<ul ui-sortable="sortableOptions" ng-model="images" class="umb-sortable-thumbnails">
<li style="width: 120px; height: 100px; overflow: hidden;" ng-repeat="image in images">
<li class="umb-sortable-thumbnails__wrapper" ng-repeat="image in images track by $index">
<!-- IMAGE -->
<img ng-class="{'trashed': image.trashed}" ng-src="{{image.thumbnail}}" alt="" ng-show="image.thumbnail" title="{{image.trashed ? 'Trashed: ' + image.name : image.name}}" />
@@ -30,11 +30,12 @@
</div>
</li>
<li style="border: none;">
<a href="#" class="add-link" ng-click="add()" ng-class="{'add-link-square': (images.length === 0 || isMultiPicker)}" ng-if="showAdd()" prevent-default>
<i class="icon icon-add large"></i>
</a>
</li>
</ul>
<a href="#" class="add-link" ng-click="add()" ng-class="{'add-link-square': images.length === 0}" ng-if="showAdd()" prevent-default>
<i class="icon icon-add large"></i>
</a>
</div>
<umb-overlay
@@ -86,6 +86,10 @@
};
$scope.add = function ($event) {
if (!angular.isArray($scope.model.value)) {
$scope.model.value = [];
}
if ($scope.newCaption == "") {
$scope.hasError = true;
} else {
@@ -374,6 +374,9 @@ angular.module("umbraco")
// element might still be there even after the modal has been hidden.
$scope.$on('$destroy', function () {
unsubscribe();
if (tinyMceEditor !== undefined && tinyMceEditor != null) {
tinyMceEditor.destroy()
}
});
});
});
@@ -1,37 +1,42 @@
function textboxController($scope) {
// macro parameter editor doesn't contains a config object,
// so we create a new one to hold any properties
// so we create a new one to hold any properties
if (!$scope.model.config) {
$scope.model.config = {};
}
if (!$scope.model.config.maxChars) {
$scope.model.config.maxChars = false;
}
$scope.model.maxlength = false;
if ($scope.model.config && $scope.model.config.maxChars) {
$scope.model.maxlength = true;
if($scope.model.value == undefined) {
}
if (!$scope.model.config.maxChars) {
// 500 is the maximum number that can be stored
// in the database, so set it to the max, even
// if no max is specified in the config
$scope.model.config.maxChars = 500;
}
if ($scope.model.maxlength) {
if ($scope.model.value === undefined) {
$scope.model.count = ($scope.model.config.maxChars * 1);
} else {
$scope.model.count = ($scope.model.config.maxChars * 1) - $scope.model.value.length;
}
}
$scope.model.change = function() {
$scope.model.change = function () {
if ($scope.model.config && $scope.model.config.maxChars) {
if($scope.model.value == undefined) {
if ($scope.model.value === undefined) {
$scope.model.count = ($scope.model.config.maxChars * 1);
} else {
$scope.model.count = ($scope.model.config.maxChars * 1) - $scope.model.value.length;
}
if($scope.model.count < 0) {
if ($scope.model.count < 0) {
$scope.model.value = $scope.model.value.substring(0, ($scope.model.config.maxChars * 1));
$scope.model.count = 0;
}
}
}
}
angular.module('umbraco').controller("Umbraco.PropertyEditors.textboxController", textboxController);
angular.module('umbraco').controller("Umbraco.PropertyEditors.textboxController", textboxController);
@@ -4,11 +4,11 @@
val-server="value"
ng-required="model.validation.mandatory"
ng-trim="false"
ng-keyup="model.change()" />
ng-keyup="model.change()" />
<span class="help-inline" val-msg-for="textbox" val-toggle-msg="valServer"></span>
<span class="help-inline" val-msg-for="textbox" val-toggle-msg="required"><localize key="general_required">Required</localize></span>
<div class="help" ng-if="model.maxlength">
<strong>{{model.count}}</strong>
<localize key="textbox_characters_left">characters left</localize>
</div>
</div>
<div class="help" ng-if="model.maxlength">
<strong>{{model.count}}</strong>
<localize key="textbox_characters_left">characters left</localize>
</div>
</div>
+12 -15
View File
@@ -127,24 +127,22 @@
<Reference Include="dotless.Core, Version=1.5.2.0, Culture=neutral, PublicKeyToken=96b446c9e63eae34, processorArchitecture=MSIL">
<HintPath>..\packages\dotless.1.5.2\lib\dotless.Core.dll</HintPath>
</Reference>
<Reference Include="Examine, Version=0.1.85.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Examine.0.1.85\lib\net45\Examine.dll</HintPath>
<Reference Include="Examine, Version=0.1.89.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Examine.0.1.89\lib\net45\Examine.dll</HintPath>
</Reference>
<Reference Include="ICSharpCode.SharpZipLib, Version=0.86.0.518, Culture=neutral, PublicKeyToken=1b03e6acf1164f73, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\SharpZipLib.0.86.0\lib\20\ICSharpCode.SharpZipLib.dll</HintPath>
</Reference>
<Reference Include="ImageProcessor, Version=2.5.3.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\ImageProcessor.2.5.3\lib\net45\ImageProcessor.dll</HintPath>
<Reference Include="ImageProcessor, Version=2.5.6.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\ImageProcessor.2.5.6\lib\net45\ImageProcessor.dll</HintPath>
</Reference>
<Reference Include="ImageProcessor.Web, Version=4.8.3.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\ImageProcessor.Web.4.8.3\lib\net45\ImageProcessor.Web.dll</HintPath>
<Reference Include="ImageProcessor.Web, Version=4.8.7.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\ImageProcessor.Web.4.8.7\lib\net45\ImageProcessor.Web.dll</HintPath>
</Reference>
<Reference Include="log4net, Version=2.0.8.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
<HintPath>..\packages\log4net.2.0.8\lib\net45-full\log4net.dll</HintPath>
</Reference>
<Reference Include="Lucene.Net, Version=2.9.4.1, Culture=neutral, PublicKeyToken=85089178b9ac3181, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Lucene.Net.2.9.4.1\lib\net40\Lucene.Net.dll</HintPath>
</Reference>
<Reference Include="Microsoft.AspNet.Identity.Core">
@@ -162,9 +160,8 @@
<HintPath>..\packages\Microsoft.CodeAnalysis.CSharp.1.0.0\lib\net45\Microsoft.CodeAnalysis.CSharp.dll</HintPath>
</Reference>
<Reference Include="Microsoft.CSharp" />
<Reference Include="Microsoft.IO.RecyclableMemoryStream, Version=1.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.IO.RecyclableMemoryStream.1.2.1\lib\net45\Microsoft.IO.RecyclableMemoryStream.dll</HintPath>
<Private>True</Private>
<Reference Include="Microsoft.IO.RecyclableMemoryStream, Version=1.2.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.IO.RecyclableMemoryStream.1.2.2\lib\net45\Microsoft.IO.RecyclableMemoryStream.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Owin, Version=3.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Owin.3.1.0\lib\net45\Microsoft.Owin.dll</HintPath>
@@ -336,8 +333,8 @@
<Name>umbraco.providers</Name>
</ProjectReference>
<Reference Include="System.Xml.Linq" />
<Reference Include="Umbraco.ModelsBuilder, Version=3.0.7.99, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Umbraco.ModelsBuilder.3.0.7\lib\Umbraco.ModelsBuilder.dll</HintPath>
<Reference Include="Umbraco.ModelsBuilder, Version=3.0.8.100, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Umbraco.ModelsBuilder.3.0.8\lib\Umbraco.ModelsBuilder.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
@@ -1027,9 +1024,9 @@ xcopy "$(ProjectDir)"..\packages\SqlServerCE.4.0.0.1\x86\*.* "$(TargetDir)x86\"
<WebProjectProperties>
<UseIIS>True</UseIIS>
<AutoAssignPort>True</AutoAssignPort>
<DevelopmentServerPort>7740</DevelopmentServerPort>
<DevelopmentServerPort>7780</DevelopmentServerPort>
<DevelopmentServerVPath>/</DevelopmentServerVPath>
<IISUrl>http://localhost:7740</IISUrl>
<IISUrl>http://localhost:7780</IISUrl>
<NTLMAuthentication>False</NTLMAuthentication>
<UseCustomServer>False</UseCustomServer>
<CustomServerUrl>
@@ -771,7 +771,7 @@
<key alias="sortCreationDate">Creation date</key>
<key alias="sortDone">Třídění bylo ukončeno.</key>
<key alias="sortHelp">Abyste nastavili, jak mají být položky seřazeny, přetáhněte jednotlivé z nich nahoru či dolů. Anebo klikněte na hlavičku sloupce pro setřídění celé kolekce</key>
<key alias="sortPleaseWait"><![CDATA[ Čekejte, prosím. Položky jsou tříděny a může to chvíli trvat.<br/> <br/> Během třídění nezavírejte toto okno]]></key>
<key alias="sortPleaseWait"><![CDATA[ Čekejte, prosím. Položky jsou tříděny a může to chvíli trvat.]]></key>
</area>
<area alias="speechBubbles">
<key alias="contentPublishedFailedByEvent">Publikování bylo zrušeno doplňkem třetí strany</key>
+13 -2
View File
@@ -422,7 +422,7 @@
<key alias="showPageOnSend">Hvilken side skal vises etter at skjemaet er sendt</key>
<key alias="size">Størrelse</key>
<key alias="sort">Sorter</key>
<key alias="submit">Submit</key> <!-- TODO: Translate this -->
<key alias="submit">Send</key>
<key alias="type">Type</key>
<key alias="typeToSearch">Søk...</key>
<key alias="up">Opp</key>
@@ -439,6 +439,17 @@
<key alias="yes">Ja</key>
<key alias="folder">Mappe</key>
<key alias="searchResults">Søkeresultater</key>
<key alias="reorder">Sorter</key>
<key alias="reorderDone">Avslutt sortering</key>
<key alias="preview">Eksempel</key>
<key alias="changePassword">Bytt passord</key>
<key alias="to">til</key>
<key alias="listView">Listevisning</key>
<key alias="saving">Lagrer...</key>
<key alias="current">nåværende</key>
<key alias="embed">Innbygging</key>
<key alias="retrieve">Hent</key>
<key alias="selected">valgt</key>
</area>
<area alias="graphicheadline">
<key alias="backgroundcolor">Bakgrunnsfarge</key>
@@ -733,7 +744,7 @@ Vennlig hilsen Umbraco roboten
<key alias="sortCreationDate">Creation date</key>
<key alias="sortDone">Sortering ferdig.</key>
<key alias="sortHelp">Dra elementene opp eller ned for å arrangere dem. Du kan også klikke kolonneoverskriftene for å sortere alt på en gang.</key>
<key alias="sortPleaseWait"><![CDATA[Vennligst vent. Elementene blir sortert, dette kan ta litt tid.<br/> <br/> Ikke lukk dette vinduet under sortering]]></key>
<key alias="sortPleaseWait"><![CDATA[Vennligst vent. Elementene blir sortert, dette kan ta litt tid.]]></key>
</area>
<area alias="speechBubbles">
<key alias="operationFailedHeader">En feil oppsto</key>
@@ -905,7 +905,7 @@
<key alias="sortCreationDate">增添時間</key>
<key alias="sortDone">排序完成。</key>
<key alias="sortHelp">上下拖拽項目或按一下列頭進行排序</key>
<key alias="sortPleaseWait"><![CDATA[ 請稍後。項目正在排序,這需要一點時間。<br/> <br/>排序中請不要關閉視窗。]]></key>
<key alias="sortPleaseWait"><![CDATA[ 請稍後。項目正在排序,這需要一點時間。]]></key>
</area>
<area alias="speechBubbles">
<key alias="validationFailedHeader">驗證</key>
@@ -14,6 +14,7 @@
<plugin name="Filter" type="ImageProcessor.Web.Processors.Filter, ImageProcessor.Web" />
<plugin name="Flip" type="ImageProcessor.Web.Processors.Flip, ImageProcessor.Web" />
<plugin name="Format" type="ImageProcessor.Web.Processors.Format, ImageProcessor.Web" enabled="true" />
<plugin name="Gamma" type="ImageProcessor.Web.Processors.Gamma, ImageProcessor.Web" />
<plugin name="GaussianBlur" type="ImageProcessor.Web.Processors.GaussianBlur, ImageProcessor.Web">
<settings>
<setting key="MaxSize" value="22" />
+6 -6
View File
@@ -4,10 +4,10 @@
<package id="ClientDependency" version="1.9.2" targetFramework="net45" />
<package id="ClientDependency-Mvc5" version="1.8.0.0" targetFramework="net45" />
<package id="dotless" version="1.5.2" targetFramework="net45" />
<package id="Examine" version="0.1.85" targetFramework="net45" />
<package id="ImageProcessor" version="2.5.3" targetFramework="net45" />
<package id="ImageProcessor.Web" version="4.8.3" targetFramework="net45" />
<package id="ImageProcessor.Web.Config" version="2.3.0" targetFramework="net45" />
<package id="Examine" version="0.1.89" targetFramework="net45" />
<package id="ImageProcessor" version="2.5.6" targetFramework="net45" />
<package id="ImageProcessor.Web" version="4.8.7" targetFramework="net45" />
<package id="ImageProcessor.Web.Config" version="2.3.1" targetFramework="net45" />
<package id="log4net" version="2.0.8" targetFramework="net45" />
<package id="Lucene.Net" version="2.9.4.1" targetFramework="net45" />
<package id="Microsoft.AspNet.Identity.Core" version="2.2.1" targetFramework="net45" />
@@ -22,7 +22,7 @@
<package id="Microsoft.CodeAnalysis.Analyzers" version="1.0.0" targetFramework="net45" />
<package id="Microsoft.CodeAnalysis.Common" version="1.0.0" targetFramework="net45" />
<package id="Microsoft.CodeAnalysis.CSharp" version="1.0.0" targetFramework="net45" />
<package id="Microsoft.IO.RecyclableMemoryStream" version="1.2.1" targetFramework="net45" />
<package id="Microsoft.IO.RecyclableMemoryStream" version="1.2.2" targetFramework="net45" />
<package id="Microsoft.Owin" version="3.1.0" targetFramework="net45" />
<package id="Microsoft.Owin.Host.SystemWeb" version="3.1.0" targetFramework="net45" />
<package id="Microsoft.Owin.Security" version="3.1.0" targetFramework="net45" />
@@ -37,5 +37,5 @@
<package id="SqlServerCE" version="4.0.0.1" 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" />
<package id="Umbraco.ModelsBuilder" version="3.0.8" targetFramework="net45" />
</packages>
@@ -586,7 +586,6 @@
<key alias="sort">Sortér</key>
<key alias="status">Status</key>
<key alias="submit">Indsend</key>
<!-- TODO: Translate this -->
<key alias="type">Type</key>
<key alias="typeToSearch">Skriv for at søge...</key>
<key alias="up">Op</key>
@@ -612,6 +611,7 @@
<key alias="saving">Gemmer...</key>
<key alias="current">nuværende</key>
<key alias="embed">Indlejring</key>
<key alias="retrieve">Hent</key>
<key alias="selected">valgt</key>
</area>
@@ -1014,7 +1014,7 @@ Mange hilsner fra Umbraco robotten
<key alias="sortCreationDate">Oprettelsesdato</key>
<key alias="sortDone">Sortering udført</key>
<key alias="sortHelp">Træk de forskellige sider op eller ned for at indstille hvordan de skal arrangeres, eller klik på kolonnehovederne for at sortere hele rækken af sider</key>
<key alias="sortPleaseWait"><![CDATA[Vent venligst mens siderne sorteres. Det kan tage et stykke tid<br/><br/>Luk ikke dette vindue imens]]></key>
<key alias="sortPleaseWait"><![CDATA[Vent venligst mens siderne sorteres. Det kan tage et stykke tid.]]></key>
</area>
<area alias="speechBubbles">
<key alias="operationCancelledHeader">Annulleret</key>
@@ -764,7 +764,7 @@ Wenn Sie sich für Runway entscheiden, können Sie optional Blöcke nutzen, die
<key alias="sortCreationDate">Erstellungsdatum</key>
<key alias="sortDone">Sortierung abgeschlossen.</key>
<key alias="sortHelp">Ziehen Sie die Elemente an ihre gewünschte neue Position.</key>
<key alias="sortPleaseWait">Bitte warten, die Seiten werden sortiert. Das kann einen Moment dauern. Bitte schließen Sie dieses Fenster nicht, bis der Sortiervorgang abgeschlossen ist.</key>
<key alias="sortPleaseWait">Bitte warten, die Seiten werden sortiert. Das kann einen Moment dauern.</key>
</area>
<area alias="speechBubbles">
<key alias="operationFailedHeader">Fehlgeschlagen</key>
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -685,8 +685,7 @@
<key alias="sortCreationDate">Creation date</key>
<key alias="sortDone">Ordenación completa.</key>
<key alias="sortHelp">Arrastra las diferentes páginas debajo para colocarlas como deberían estar. O haz click en las cabeceras de las columnas para ordenar todas las páginas</key>
<key alias="sortPleaseWait"><![CDATA[Espere por favor, las páginas están siendo ordenadas. El proceso puede durar un poco.<br/>
<br/> No cierre esta ventana mientras se está ordenando ]]></key>
<key alias="sortPleaseWait"><![CDATA[Espere por favor, las páginas están siendo ordenadas. El proceso puede durar un poco.]]></key>
</area>
<area alias="speechBubbles">
<key alias="contentPublishedFailedByEvent">La publicación fue cancelada por un complemento de terceros</key>
@@ -1015,7 +1015,7 @@ Pour gérer votre site, ouvrez simplement le backoffice Umbraco et commencez à
<key alias="sortCreationDate">Date de création</key>
<key alias="sortDone">Tri achevé.</key>
<key alias="sortHelp">Faites glisser les différents éléments vers le haut ou vers le bas pour définir la manière dont ils doivent être organisés. Ou cliquez sur les entêtes de colonnes pour trier la collection complète d'éléments</key>
<key alias="sortPleaseWait"><![CDATA[Veuillez patienter. Les éléments sont en cours de tri, cela peut prendre un moment.<br/> <br/> Ne fermez pas cette fenêtre durant le tri.]]></key>
<key alias="sortPleaseWait"><![CDATA[Veuillez patienter. Les éléments sont en cours de tri, cela peut prendre un moment.]]></key>
</area>
<area alias="speechBubbles">
<key alias="validationFailedHeader">Validation</key>
@@ -32,11 +32,6 @@
<key alias="sort">מיין</key>
<key alias="translate">תרגם</key>
<key alias="update">עדכן</key>
<key alias="DeleteCMSImportAction">מחק</key>
<key alias="ExecuteCMSImportWizardAction">בצע</key>
<key alias="ScheduleCMSImportWizardAction">תזמן</key>
<key alias="StartCMSImportWizardAction">ייבא נתונים</key>
<key alias="StartCMSImportChildDefinitionAction">צור הגדרות ילדים</key>
<key alias="LastRunInfoAction">יומן משימות מתוזמנות</key>
</area>
<area alias="assignDomain">
@@ -681,7 +676,7 @@ To manage your website, simply open the Umbraco back office and start adding con
<key alias="sortCreationDate">Creation date</key>
<key alias="sortDone">המיון הושלם.</key>
<key alias="sortHelp">יש לגרור את הפריטים מעלה או מטה כדי להגדיר את סדר התוכן. או לחץ על כותרת העמודה כדי למיין את כל פריטי התוכן</key>
<key alias="sortPleaseWait"><![CDATA[פריטי התוכן ממיונים ברגע זה, תהליך זה לוקח זמן מה.<br/> <br/> נא לא לסגור את החלון בזמן המיון]]></key>
<key alias="sortPleaseWait"><![CDATA[פריטי התוכן ממיונים ברגע זה, תהליך זה לוקח זמן מה.]]></key>
</area>
<area alias="speechBubbles">
<key alias="contentPublishedFailedByEvent">הפירסום בוטל על ידי תוסף צד שלישי</key>
@@ -657,7 +657,7 @@ Per gestire il tuo sito web, è sufficiente aprire il back office di Umbraco e i
<key alias="sortCreationDate">Creation date</key>
<key alias="sortDone"><![CDATA[Ordinamento completato.]]></key>
<key alias="sortHelp"><![CDATA[Sposta su o giù le pagine trascinandole per determinarne l'ordinamento. Oppure clicca la testata della colonna per ordinare l'intero gruppo di pagine]]></key>
<key alias="sortPleaseWait"><![CDATA[Si prega di attendere. Gli elementi sono in fase di ordinamento, questo può richiedere del tempo.<br/> <br/>Non chiudere questa finestra durante l'operazione]]></key>
<key alias="sortPleaseWait"><![CDATA[Si prega di attendere. Gli elementi sono in fase di ordinamento, questo può richiedere del tempo.]]></key>
</area>
<area alias="speechBubbles">
<key alias="contentPublishedFailedByEvent"><![CDATA[La pubblicazione è stata cancellata da un add-in di terze parti.]]></key>
@@ -887,7 +887,7 @@ Runwayをインストールして作られた新しいウェブサイトがど
<key alias="sortCreationDate">Creation date</key>
<key alias="sortDone">ソートが完了しました。</key>
<key alias="sortHelp">上下にアイテムをドラッグするなどして適当に配置したり、列のヘッダーをクリックしてコレクション全体をソートできます</key>
<key alias="sortPleaseWait"><![CDATA[ 項目の並べ替えには少し時間がかかります。しばらくお待ちください。<br/> <br/> 並び替え中はウィンドウを閉じないでください。]]></key>
<key alias="sortPleaseWait"><![CDATA[ 項目の並べ替えには少し時間がかかります。しばらくお待ちください。]]></key>
</area>
<area alias="speechBubbles">
<key alias="validationFailedHeader">検証</key>
@@ -658,7 +658,7 @@
<key alias="sortCreationDate">Creation date</key>
<key alias="sortDone">정렬 완료</key>
<key alias="sortHelp">다른 아이템을 마우스로 위,아래로 드래그 하여 이동하거나 열의 헤더를 클릭하여 아이템을 정렬할 수 있습니다</key>
<key alias="sortPleaseWait"><![CDATA[잠시 기다리십시오. 아이템을 정렬 하는데 잠시 시간이 소요될 수 있습니다<br/><br/>정렬하는 동안 이 창을 닫지 마십시오]]></key>
<key alias="sortPleaseWait"><![CDATA[잠시 기다리십시오. 아이템을 정렬 하는데 잠시 시간이 소요될 수 있습니다]]></key>
</area>
<area alias="speechBubbles">
<key alias="contentPublishedFailedByEvent">3rd party add-in 때문에 발행이 취소되었습니다.</key>
@@ -452,7 +452,7 @@
<key alias="email">Email</key>
<key alias="error">Fout</key>
<key alias="findDocument">Vind</key>
<key alias="height">Hogte</key>
<key alias="height">Hoogte</key>
<key alias="help">Help</key>
<key alias="icon">Icoon</key>
<key alias="import">Import</key>
@@ -949,7 +949,7 @@ Echter, Runway biedt een gemakkelijke basis om je snel op weg te helpen. Als je
<key alias="sortCreationDate">Creation date</key>
<key alias="sortDone">Sorteren gereed.</key>
<key alias="sortHelp">Sleep de pagina's omhoog of omlaag om de volgorde te veranderen. Of klik op de kolom-header om alle pagina's daarop te sorteren.</key>
<key alias="sortPleaseWait"><![CDATA[Een ogenblik geduld. Paginas worden gesorteerd, dit kan even duren.<br/> <br/> Sluit dit venster niet tijdens het sorteren]]></key>
<key alias="sortPleaseWait"><![CDATA[Een ogenblik geduld. Paginas worden gesorteerd, dit kan even duren.]]></key>
</area>
<area alias="speechBubbles">
<key alias="validationFailedHeader">Validatie</key>
+91 -15
View File
@@ -12,9 +12,11 @@
<key alias="copy">Kopiuj</key>
<key alias="create">Utwórz</key>
<key alias="createPackage">Stwórz zbiór</key>
<key alias="createGroup">Stwórz grupę</key>
<key alias="delete">Usuń</key>
<key alias="disable">Deaktywuj</key>
<key alias="emptyTrashcan">Opróżnij kosz</key>
<key alias="enable">Aktywuj</key>
<key alias="exportDocumentType">Eksportuj typ dokumentu</key>
<key alias="importDocumentType">Importuj typ dokumentu</key>
<key alias="importPackage">Importuj zbiór</key>
@@ -27,16 +29,49 @@
<key alias="unpublish">Cofnij publikację</key>
<key alias="refreshNode">Odśwież węzeł</key>
<key alias="republish">Opublikuj ponownie całą stronę</key>
<key alias="rename" version="7.3.0">Zmień nazwę</key>
<key alias="restore" version="7.3.0">Przywróć</key>
<key alias="SetPermissionsForThePage">Ustaw uprawnienia dla strony %0%</key>
<key alias="chooseWhereToMove">Wybierz dokąd przenieść</key>
<key alias="toInTheTreeStructureBelow">W strukturze drzewa poniżej</key>
<key alias="rights">Uprawnienia</key>
<key alias="rollback">Cofnij</key>
<key alias="sendtopublish">Wyślij do publikacji</key>
<key alias="sendToTranslate">Wyślij do tłumaczenia</key>
<key alias="setGroup">Ustaw grupę</key>
<key alias="sort">Sortuj</key>
<key alias="translate">Przetłumacz</key>
<key alias="update">Aktualizuj</key>
<key alias="setPermissions">Ustaw uprawnienia</key>
<key alias="unlock">Odblokuj</key>
<key alias="createblueprint">Stwórz Szablon Zawartości</key>
</area>
<area alias="actionCategories">
<key alias="content">Zawartość</key>
<key alias="administration">Administracja</key>
<key alias="structure">Struktura</key>
<key alias="other">Inne</key>
</area>
<area alias="actionDescriptions">
<key alias="assignDomain">Zezwól na dostęp do przydzielenia języka i hostów</key>
<key alias="auditTrail">Zezwól na dostęp do wglądu w historię logów węzła</key>
<key alias="browse">Zezwól na dostęp do widoku węzła</key>
<key alias="changeDocType">Zezwól na dostęp do zmiany typu dokumentu dla węzła</key>
<key alias="copy">Zezwól na dostęp do skopiowania węzła</key>
<key alias="create">Zezwól na dostęp do stworzenia węzłów</key>
<key alias="delete">Zezwól na dostęp do usunięcia węzłóws</key>
<key alias="move">Zezwól na dostęp do przeniesienia węzła</key>
<key alias="protect">Zezwól na dostęp do ustawienia i zmiany publicznego dostępu węzła</key>
<key alias="publish">Zezwól na dostęp do publikacji węzła</key>
<key alias="rights">Zezwól na dostęp do zmiany uprawnień węzła</key>
<key alias="rollback">Zezwól na dostęp do cofnięcia węzła do poprzedniego stanu</key>
<key alias="sendtopublish">Zezwól na dostęp do wysłania węzła do akceptacji przed publikacją</key>
<key alias="sendToTranslate">Zezwól na dostęp do wysłania węzła do tłumaczenia</key>
<key alias="sort">Zezwól na dostęp do zmiany kolejności sortowania węzłów</key>
<key alias="translate">Zezwól na dostęp do tłumaczenia węzła</key>
<key alias="update">Zezwól na dostęp do zapisania węzła</key>
<key alias="createblueprint">Zezwól na dostęp do utworzenia Szablonu Zawartości</key>
</area>
<area alias="assignDomain">
<key alias="permissionDenied">Brak odpowiednich uprawnień</key>
<key alias="addNew">Dodaj nową domenę</key>
@@ -50,14 +85,18 @@
<key alias="domainDeleted">Domena '%0%' została skasowana</key>
<key alias="domainExists">Domena '%0%' jest aktualnie przypisana</key>
<key alias="domainUpdated">Domena '%0%' została zaktualizowana</key>
<key alias="domainHelp"><![CDATA[Poprawne domeny to: "example.com", "www.example.com", "example.com:8080" lub
"https://www.example.com/". Wspierane są jednopoziomowe ścieżki domen, np. "example.com/en" jednakże powinno się ich unikać.
Preferowane jest użycie powyższych ustawień języka.]]></key>
<key alias="orEdit">Edycja aktualnych domen</key>
<key alias="orEdit">Edytuj Aktualne Domeny</key>
<key alias="domainHelp">
<![CDATA[Poprawne domeny to: "example.com", "www.example.com", "example.com:8080" lub
"https://www.example.com/". Wspierane są jednopoziomowe ścieżki domen, np. "example.com/en" jednakże powinno się ich unikać.
Preferowane jest użycie powyższych ustawień języka.]]>
</key>
<key alias="inherit">Odziedziczona</key>
<key alias="setLanguage">Język</key>
<key alias="setLanguageHelp"><![CDATA[Wybierz język dla węzła,<br /> lub wybierz dziedziczenie języka z węzła rodzica. Zostanie to zastosowane<br />
także do obecnego węzła, o ile poniższa domena również do niego należy.]]></key>
<key alias="setLanguageHelp">
<![CDATA[Wybierz język dla węzła,<br /> lub wybierz dziedziczenie języka z węzła rodzica. Zostanie to zastosowane<br />
także do obecnego węzła, o ile poniższa domena również do niego należy.]]>
</key>
<key alias="setDomains">Domeny</key>
</area>
<area alias="auditTrails">
@@ -96,6 +135,7 @@ także do obecnego węzła, o ile poniższa domena również do niego należy.]]
<key alias="styleShow">Pokaż style</key>
<key alias="tableInsert">Wstaw tabelę</key>
<key alias="generateModels">Wygeneruj modele</key>
<key alias="saveAndGenerateModels">Zapisz i wygeneruj modele</key>
<key alias="undo">Cofnij</key>
<key alias="redo">Powtórz</key>
</area>
@@ -139,6 +179,8 @@ także do obecnego węzła, o ile poniższa domena również do niego należy.]]
<key alias="lastPublished">Opublikowane</key>
<key alias="noItemsToShow">Nie ma żadnych elementów do wyświetlenia</key>
<key alias="listViewNoItems" version="7.1.5">Nie ma żadnych elementów do wyświetlenia w liście.</key>
<key alias="listViewNoContent">Nie dodano żadnej zawartości</key>
<key alias="listViewNoMembers">Nie dodano żadnych członków</key>
<key alias="mediatype">Typ mediów</key>
<key alias="mediaLinks">Link do elementu(ów) mediów</key>
<key alias="membergroup">Członek grupy</key>
@@ -173,16 +215,30 @@ także do obecnego węzła, o ile poniższa domena również do niego należy.]]
<key alias="target" version="7.0">Cel</key>
<key alias="scheduledPublishServerTime">Oznacza to następującą godzinę na serwerze:</key>
<key alias="scheduledPublishDocumentation"><![CDATA[<a href="https://our.umbraco.org/documentation/Getting-Started/Data/Scheduled-Publishing/#timezones" target="_blank">Co to oznacza?</a>]]></key>
<key alias="nestedContentDeleteItem">Czy na pewno chcesz usunąć ten element?</key>
<key alias="nestedContentEditorNotSupported">Właściwość %0% używa edytora %1%, który nie jest wspierany przez Nested Content.</key>
<key alias="addTextBox">Dodaj kolejne pole tekstowe</key>
<key alias="removeTextBox">Usuń te pole tekstowe</key>
<key alias="contentRoot">Korzeń zawartości</key>
</area>
<area alias="blueprints">
<key alias="createBlueprintFrom">Stwórz nowy Szablon Zawartości z '%0%'</key>
<key alias="blankBlueprint">Pusty</key>
<key alias="selectBlueprint">Wybierz Szablon Zawartości</key>
<key alias="createdBlueprintHeading">Szablon Zawartości został stworzony</key>
<key alias="createdBlueprintMessage">Szablon Zawartości został stworzony z '%0%'</key>
<key alias="duplicateBlueprintMessage">Szablon Zawartości o tej samej nazwie już istnieje</key>
<key alias="blueprintDescription">Szablon Zawartości to predefiniowana zawartość, którą edytor może wybrać, aby użyć jej jako podstawę do stworzenia nowej zawartości</key>
</area>
<area alias="media">
<key alias="clickToUpload">Kliknij, aby załadować plik</key>
<key alias="dropFilesHere">Przerzuć swoje pliki tutaj...</key>
<key alias="urls">Link do mediów</key>
<key alias="urls">Link do mediów</key>
<key alias="orClickHereToUpload">lub kliknij tutaj, aby wybrać pliki</key>
<key alias="onlyAllowedFiles">Jedyne dozwolone typy plików to</key>
<key alias="disallowedFileType">Nie można załadować pliku, typ pliku nie jest akceptowany</key>
<key alias="maxFileSize">Maksymalny rozmiar pliku to</key>
<key alias="mediaRoot">Korzeń mediów</key>
</area>
<area alias="member">
<key alias="createNewMember">Stwórz nowego członka</key>
@@ -191,6 +247,7 @@ także do obecnego węzła, o ile poniższa domena również do niego należy.]]
<area alias="create">
<key alias="chooseNode">Gdzie chcesz stworzyć nowy %0%?</key>
<key alias="createUnder">Utwórz w</key>
<key alias="createContentBlueprint">Wybierz typ dokumentu, dla którego chcesz stworzyć szablon zawartości</key>
<key alias="updateData">Wybierz rodzaj oraz tytuł</key>
<key alias="noDocumentTypes" version="7.0"><![CDATA[Brak dostępnych dozwolonych typów dokumentów. Należy włączyć je w ustawieniach sekcji pod <strong>"typy dokumentów"</strong>.]]></key>
<key alias="noMediaTypes" version="7.0"><![CDATA[Brak dostępnych dozwolonych typów mediów. Należy włączyć je w ustawieniach sekcji pod <strong>"typy mediów"</strong>.]]></key>
@@ -249,6 +306,8 @@ także do obecnego węzła, o ile poniższa domena również do niego należy.]]
<key alias="copiedItemOfItems">Skopiowano %0% z %1% elementów</key>
</area>
<area alias="defaultdialogs">
<key alias="nodeNameLinkPicker">Tytuł linku</key>
<key alias="urlLinkPicker">Link</key>
<key alias="anchorInsert">Nazwa</key>
<key alias="assignDomain">Zarządzaj nazwami hostów</key>
<key alias="closeThisWindow">Zamknij to okno</key>
@@ -276,6 +335,9 @@ także do obecnego węzła, o ile poniższa domena również do niego należy.]]
<key alias="macroDoesNotHaveProperties">To makro nie posiada żadnych właściwości, które można edytować</key>
<key alias="paste">Wklej</key>
<key alias="permissionsEdit">Edytuj Uprawnienia dla</key>
<key alias="permissionsSet">Ustaw uprawnienia dla</key>
<key alias="permissionsSetForGroup">Ustaw uprawnienia dla %0% dla grupy użytkownika %1%</key>
<key alias="permissionsHelp">Wybierz grupy użytkowników, dla których chcesz ustawić uprawnienia</key>
<key alias="recycleBinDeleting">Zawartość kosza jest teraz usuwana. Proszę nie zamykać tego okna do momentu zakończenia procesu.</key>
<key alias="recycleBinIsEmpty">Zawartość kosza została usunięta</key>
<key alias="recycleBinWarning">Usunięcie elementów z kosza powoduje ich trwałe i nieodwracalne skasowanie</key>
@@ -288,10 +350,14 @@ także do obecnego węzła, o ile poniższa domena również do niego należy.]]
<key alias="siterepublishHelp">Cache strony zostanie odświeżone. Cała zawartość opublikowana będzie aktualna, lecz nieopublikowana zawartość pozostanie niewidoczna</key>
<key alias="tableColumns">Liczba kolumn</key>
<key alias="tableRows">Liczba wierszy</key>
<key alias="templateContentAreaHelp"><![CDATA[<strong>Ustaw zastępczy ID</strong> Ustawiając ID na tym elemencie możesz później łączyć treść z podrzędnych szablonów,
ustawiając dowiązanie do tego ID na elemencie <code>&lt;asp:treści /&gt;</code>]]></key>
<key alias="templateContentPlaceHolderHelp"><![CDATA[<strong>Wybierz zastępczy ID</strong> z poniższej listy. Możesz wybierać tylko
spośród ID na szablonie nadrzędnym tego formularza.]]></key>
<key alias="templateContentAreaHelp">
<![CDATA[<strong>Ustaw zastępczy ID</strong> Ustawiając ID na tym elemencie możesz później łączyć treść z podrzędnych szablonów,
ustawiając dowiązanie do tego ID na elemencie <code>&lt;asp:treści /&gt;</code>]]>
</key>
<key alias="templateContentPlaceHolderHelp">
<![CDATA[<strong>Wybierz zastępczy ID</strong> z poniższej listy. Możesz wybierać tylko
spośród ID na szablonie nadrzędnym tego formularza.]]>
</key>
<key alias="thumbnailimageclickfororiginal">Kliknij na obrazie, aby zobaczyć go w pełnym rozmiarze</key>
<key alias="treepicker">Wybierz element</key>
<key alias="viewCacheItem">Podgląd elementów Cache</key>
@@ -303,14 +369,19 @@ także do obecnego węzła, o ile poniższa domena również do niego należy.]]
<key alias="openInNewWindow">Otwórz zlinkowany dokument w nowym oknie lub zakładce</key>
<key alias="linkToMedia">Link do mediów</key>
<key alias="linkToFile">Link do plików</key>
<key alias="selectContentStartNode">Wybierz węzeł początkowy zawartości</key>
<key alias="selectMedia">Wybierz media</key>
<key alias="selectIcon">Wybierz ikonę</key>
<key alias="selectItem">Wybierz element</key>
<key alias="selectLink">Wybierz link</key>
<key alias="selectMacro">Wybierz makro</key>
<key alias="selectContent">Wybierz zawartość</key>
<key alias="selectMediaStartNode">Wybierz węzeł początkowy mediów</key>
<key alias="selectMember">Wybierz członka</key>
<key alias="selectMemberGroup">Wybierz członka grupy</key>
<key alias="selectNode">Wybierz węzeł</key>
<key alias="selectSections">Wybierz sekcje</key>
<key alias="selectUsers">Wybierz użytkowników</key>
<key alias="noIconsFound">Nie znaleziono ikon</key>
<key alias="noMacroParams">Te makro nie ma żadnych właściwości</key>
<key alias="noMacros">Brak dostępnych makro do wstawienia</key>
@@ -325,9 +396,11 @@ także do obecnego węzła, o ile poniższa domena również do niego należy.]]
<key alias="selectSnippet">Wybierz snippet</key>
</area>
<area alias="dictionaryItem">
<key alias="description"><![CDATA[
Edytuj różne wersje językowe dla elementu słownika '<em>%0%</em>' poniżej.<br/>
Możesz dodać dodatkowe języki w menu "Języki" po lewej stronie.]]></key>
<key alias="description">
<![CDATA[
Edytuj różne wersje językowe dla elementu słownika '<em>%0%</em>' poniżej.<br/>
Możesz dodać dodatkowe języki w menu "Języki" po lewej stronie.]]>
</key>
<key alias="displayName">Nazwa języka</key>
<key alias="changeKey">Edytuj klucz elementu słownika.</key>
<key alias="changeKeyError">
@@ -342,12 +415,15 @@ Możesz dodać dodatkowe języki w menu "Języki" po lewej stronie.]]></key>
<key alias="confirmPassword">Potwierdź hasło</key>
<key alias="nameentity">Nazwij %0%...</key>
<key alias="entername">Wpisz nazwę...</key>
<key alias="enteremail">Wpisz adres e-mail...</key>
<key alias="enterusername">Wpisz nazwę użytkownika...</key>
<key alias="label">Etykieta...</key>
<key alias="enterDescription">Wpisz opis...</key>
<key alias="search">Wpisz, aby wyszukać...</key>
<key alias="filter">Wpisz, aby filtrować...</key>
<key alias="enterTags">Wpisz, aby dodać tagi (naciśnij enter po każdym tagu)...</key>
<key alias="email">Wpisz adres e-mail</key>
<key alias="enterMessage">Wpisz wiadomość...</key>
<key alias="usernameHint">Twoja nazwa użytkownika to przeważnie Twój adres e-mail</key>
</area>
<area alias="editcontenttype">
@@ -1012,7 +1088,7 @@ Naciśnij przycisk <strong>instaluj</strong>, aby zainstalować bazę danych Umb
<key alias="sortCreationDate">Data utworzenia</key>
<key alias="sortDone">Sortowanie zakończone.</key>
<key alias="sortHelp">Przesuń poszczególne elementy w górę oraz w dół aż będą w odpowiedniej kolejności lub kliknij na nagłówku kolumny, aby posortować całą kolekcję elementów</key>
<key alias="sortPleaseWait"><![CDATA[Proszę czekać. Trwa sortowanie elementów.<br/><br/>Nie zamykaj tego okna podczas sortowania]]></key>
<key alias="sortPleaseWait"><![CDATA[Proszę czekać. Trwa sortowanie elementów.]]></key>
</area>
<area alias="speechBubbles">
<key alias="validationFailedHeader">Walidacja</key>
@@ -646,7 +646,7 @@ Você pode publicar esta página e todas suas sub-páginas ao selecionar <em>pub
<key alias="sortCreationDate">Creation date</key>
<key alias="sortDone">Classificação concluída.</key>
<key alias="sortHelp">Arraste os diferentes itens para cima ou para baixo para definir como os mesmos serão arranjados. Ou clique no título da coluna para classificar a coleção completa de itens</key>
<key alias="sortPleaseWait"><![CDATA[Favor esperar. Itens estão sendo classificados, isto pode demorar um tempo. <br /><br /> Não feche esta janela durante a classificação]]></key>
<key alias="sortPleaseWait"><![CDATA[Favor esperar. Itens estão sendo classificados, isto pode demorar um tempo.]]></key>
</area>
<area alias="speechBubbles">
<key alias="contentPublishedFailedByEvent">Publicação foi cancelada por add-in de terceiros</key>
+24 -8
View File
@@ -153,6 +153,7 @@
<key alias="listNumeric">Нумерованный список</key>
<key alias="macroInsert">Вставить макрос</key>
<key alias="pictureInsert">Вставить изображение</key>
<key alias="redo">Повторить</key>
<key alias="relations">Править связи</key>
<key alias="returnToList">Вернуться к списку</key>
<key alias="save">Сохранить</key>
@@ -168,6 +169,7 @@
<key alias="styleChoose">Выбрать стиль</key>
<key alias="styleShow">Показать стили</key>
<key alias="tableInsert">Вставить таблицу</key>
<key alias="undo">Отменить</key>
</area>
<area alias="changeDocType">
<key alias="changeDocTypeInstruction">Чтобы сменить тип документа для выбранного узла, сначала выберите тип из списка разрешенных для данного расположения.</key>
@@ -375,6 +377,7 @@
<key alias="macroContainerSettings">Свойства макроса</key>
<key alias="macroDoesNotHaveProperties">Этот макрос не имеет редактируемых свойств</key>
<key alias="nodeNameLinkPicker">Заголовок ссылки</key>
<key alias="noIconsFound">Ни одной пиктограммы не найдено</key>
<key alias="paste">Вставить</key>
<key alias="permissionsEdit">Изменить разрешения для</key>
<key alias="permissionsSet">Установить разрешения для</key>
@@ -596,6 +599,7 @@
<key alias="new">Новый</key>
<key alias="next">След</key>
<key alias="no">Нет</key>
<key alias="noItemsInList">Здесь пока нет элементов</key>
<key alias="of">из</key>
<key alias="off">Выкл</key>
<key alias="ok">Ok</key>
@@ -696,6 +700,8 @@
<key alias="chooseExtra">Выбрать дополнительно</key>
<key alias="chooseDefault">Выбрать по-умолчанию</key>
<key alias="areAdded">добавлены</key>
<key alias="maxItemsDescription">Оставьте пустым или задайте 0 для снятия лимита</key>
<key alias="maxItems">Максимальное количество</key>
</area>
<area alias="headers">
<key alias="page">Страница</key>
@@ -1049,7 +1055,7 @@
<area alias="packager">
<key alias="chooseLocalPackageText"><![CDATA[
Выберите файл пакета на своем компьютере, нажав на кнопку 'Обзор'<br />
и указав на нужный файл. Пакеты Umbraco обычно являются архивами с расширением ".umb" или ".zip".
и указав на нужный файл. Пакеты Umbraco обычно являются архивами с расширением '.zip'.
]]></key>
<key alias="dropHere">Перетащите сюда</key>
<key alias="orClickHereToUpload">или нажмите здесь для выбора файла пакета</key>
@@ -1215,12 +1221,12 @@
</area>
<area alias="relatedlinks">
<key alias="caption">Заголовок</key>
<key alias="captionPlaceholder">Укажите заголовок</key>
<key alias="captionPlaceholder">Укажите заголовок ссылки</key>
<key alias="chooseInternal">выбрать страницу сайта</key>
<key alias="enterExternal">указать внешнюю ссылку</key>
<key alias="externalLinkPlaceholder">Укажите ссылку</key>
<key alias="link">Ссылка</key>
<key alias="newWindow">В новом окне</key>
<key alias="newWindow">Открыть в новом окне</key>
</area>
<area alias="renamecontainer">
<key alias="renamed">Переименована</key>
@@ -1310,7 +1316,7 @@
<key alias="sortCreationDate">Дата создания</key>
<key alias="sortDone">Сортировка завершена</key>
<key alias="sortHelp">Перетаскивайте элементы на нужное место вверх или вниз для определения необходимого Вам порядка сортировки. Также можно использовать заголовки столбцов, чтобы отсортировать все элементы сразу.</key>
<key alias="sortPleaseWait"><![CDATA[Пожалуйста, подождите... Страницы сортируются, это может занять некоторое время.<br/> <br/> Не закрывайте это окно до окончания процесса сортировки.]]></key>
<key alias="sortPleaseWait"><![CDATA[Пожалуйста, подождите... Страницы сортируются, это может занять некоторое время.]]></key>
</area>
<area alias="speechBubbles">
<key alias="contentPublishedFailedByEvent">Процесс публикации был отменен установленным пакетом дополнений.</key>
@@ -1393,8 +1399,6 @@
<key alias="disableUserSuccess">'%0%' сейчас заблокирован</key>
<key alias="disableUserError">При блокировке пользователя произошла ошибка</key>
<key alias="setUserGroupOnUsersSuccess">Группы пользователей установлены</key>
<key alias="deleteUserGroupsSuccess">Удалено %0% групп пользователей</key>
<key alias="deleteUserGroupSuccess">'%0%' была удалена</key>
<key alias="unlockUsersSuccess">Разблокировано %0% пользователей</key>
<key alias="unlockUsersError">При разблокировке пользователей произошла ошибка</key>
<key alias="unlockUserSuccess">'%0%' сейчас разблокирован</key>
@@ -1517,8 +1521,8 @@
<key alias="fallbackField">Поле замены</key>
<key alias="addDefaultValue">Добавить значение по-умолчанию</key>
<key alias="defaultValue">Значение по-умолчанию</key>
<key alias="alternativeField">Альтернативное поле</key>
<key alias="alternativeText">Текст по-умолчанию</key>
<key alias="alternativeField">Поле замены</key>
<key alias="alternativeText">Значение по-умолчанию</key>
<key alias="casing">Регистр</key>
<key alias="chooseField">Выбрать поле</key>
<key alias="convertLineBreaks">Преобразовать переводы строк</key>
@@ -1715,11 +1719,22 @@
<key alias="profile">Профиль</key>
<key alias="resetPassword">Сбросить пароль</key>
<key alias="searchAllChildren">Поиск всех дочерних документов</key>
<key alias="selectUserGroups">Выбрать группы пользователей</key>
<key alias="sendInvite">Отправить приглашение</key>
<key alias="sessionExpires" version="7.0">Сессия истекает через</key>
<key alias="sectionsHelp">Разделы, доступные пользователю</key>
<key alias="noStartNode">Начальный узел не задан</key>
<key alias="noStartNodes">Начальные узлы не заданы</key>
<key alias="sortNameAscending">Имя (А-Я)</key>
<key alias="sortNameDescending">Имя (Я-А)</key>
<key alias="sortCreateDateDescending">Сначала новые</key>
<key alias="sortCreateDateAscending">Сначала старые</key>
<key alias="sortLastLoginDateDescending">Недавно зашедшие</key>
<key alias="stateActive">Активные</key>
<key alias="stateAll">Все</key>
<key alias="stateDisabled">Отключенные</key>
<key alias="stateLockedOut">Заблокированные</key>
<key alias="stateInvited">Приглашенные</key>
<key alias="startnode">Начальный узел содержимого</key>
<key alias="startnodehelp">Можно ограничить доступ к дереву содержимого (какой-либо его части), задав начальный узел</key>
<key alias="startnodes">Начальные узлы содержимого</key>
@@ -1736,6 +1751,7 @@
<key alias="userInvitedSuccessHelp">Новому пользователю было отправлено приглашение, в котором содержатся инструкции для входа в панель Umbraco.</key>
<key alias="userinviteWelcomeMessage">Здравствуйте и добро пожаловать в Umbraco! Все будет готово в течении пары минут, нам лишь нужно задать Ваш пароль для входа и добавить аватар.</key>
<key alias="userinviteAvatarMessage">Загрузите изображение, это поможет другим пользователям идентифицировать Вас.</key>
<key alias="userManagement">Управление пользователями</key>
<key alias="userPermissions">Разрешения для пользователя</key>
<key alias="writer">Автор</key>
<key alias="yourHistory" version="7.0">Ваша недавняя история</key>
+13 -4
View File
@@ -411,7 +411,7 @@
<key alias="showPageOnSend">Vilken sida skall visas när formuläret är skickat</key>
<key alias="size">Storlek</key>
<key alias="sort">Sortera</key>
<key alias="submit">Submit</key> <!-- TODO: Translate this -->
<key alias="submit">Skicka</key>
<key alias="type">Skriv</key>
<key alias="typeToSearch">Skriv för att söka...</key>
<key alias="up">Upp</key>
@@ -426,8 +426,17 @@
<key alias="width">Bredd</key>
<key alias="view">Titta på</key>
<key alias="yes">Ja</key>
<key alias="reorder">Reorder</key>
<key alias="reorderDone">I am done reordering</key>
<key alias="reorder">Sortera</key>
<key alias="reorderDone">Avsluta sortering</key>
<key alias="preview">Förhandsvisning</key>
<key alias="changePassword">Ändra lösenord</key>
<key alias="to">till</key>
<key alias="listView">Listvy</key>
<key alias="saving">Sparar...</key>
<key alias="current">nuvarande</key>
<key alias="embed">Inbäddning</key>
<key alias="retrieve">Hämta</key>
<key alias="selected">valgt</key>
</area>
<area alias="graphicheadline">
<key alias="backgroundcolor">Bakgrundsfärg</key>
@@ -694,7 +703,7 @@
<key alias="sortCreationDate">Creation date</key>
<key alias="sortDone">Sortering klar</key>
<key alias="sortHelp">Välj i vilken ordning du vill ha sidorna genom att dra dem upp eller ner i listan. Du kan också klicka på kolumnrubrikerna för att sortera grupper av sidor</key>
<key alias="sortPleaseWait"><![CDATA[Vänta medan sidorna sorteras. Det kan ta en stund.<br/><br/>Stäng inte fönstret under tiden sidorna sorteras.]]></key>
<key alias="sortPleaseWait"><![CDATA[Vänta medan sidorna sorteras. Det kan ta en stund.]]></key>
</area>
<area alias="speechBubbles">
<key alias="contentPublishedFailedByEvent">Publiceringen avbröts av ett tredjepartstillägg</key>
@@ -844,7 +844,7 @@ To manage your website, simply open the Umbraco back office and start adding con
<area alias="sort">
<key alias="sortDone">Sorting complete.</key>
<key alias="sortHelp">Drag the different items up or down below to set how they should be arranged. Or click the column headers to sort the entire collection of items</key>
<key alias="sortPleaseWait"><![CDATA[ Please wait. Items are being sorted, this can take a while.<br/> <br/> Do not close this window during sorting]]></key>
<key alias="sortPleaseWait"><![CDATA[ Please wait. Items are being sorted, this can take a while.]]></key>
</area>
<area alias="speechBubbles">
<key alias="operationFailedHeader">Hata</key>
@@ -1065,7 +1065,7 @@
<key alias="sortCreationDate">创建日期</key>
<key alias="sortDone">排序完成。</key>
<key alias="sortHelp">上下拖拽项目或单击列头进行排序</key>
<key alias="sortPleaseWait"><![CDATA[正在排序请稍候…<br/><br/>请不要关闭窗口]]></key>
<key alias="sortPleaseWait"><![CDATA[正在排序请稍候…]]></key>
</area>
<area alias="speechBubbles">
<key alias="validationFailedHeader">验证</key>
@@ -105,6 +105,7 @@
//wire up the submit button
self._opts.submitButton.click(function() {
this.disabled = true;
self._saveSort();
});
@@ -805,13 +805,13 @@ namespace Umbraco.Web.Cache
/// <summary>
/// Used to cache all found event handlers
/// </summary>
private static readonly ConcurrentDictionary<IEventDefinition, MethodInfo> FoundHandlers = new ConcurrentDictionary<IEventDefinition, MethodInfo>();
private static readonly ConcurrentDictionary<string, MethodInfo> FoundHandlers = new ConcurrentDictionary<string, MethodInfo>();
internal static MethodInfo FindHandler(IEventDefinition eventDefinition)
{
var name = eventDefinition.Sender.GetType().Name + "_" + eventDefinition.EventName;
return FoundHandlers.GetOrAdd(eventDefinition, _ => CandidateHandlers.Value.FirstOrDefault(x => x.Name == name));
return FoundHandlers.GetOrAdd(name, n => CandidateHandlers.Value.FirstOrDefault(x => x.Name == n));
}
}
}
+3 -4
View File
@@ -532,6 +532,7 @@ namespace Umbraco.Web.Editors
/// <returns></returns>
[FileUploadCleanupFilter]
[ContentPostValidate]
[OutgoingEditorModelEvent]
public ContentItemDisplay PostSave(
[ModelBinder(typeof(ContentItemBinder))]
ContentItemSave contentItem)
@@ -792,11 +793,8 @@ namespace Umbraco.Web.Editors
{
var contentService = Services.ContentService;
// content service GetByIds does order the content items based on the order of Ids passed in
var content = contentService.GetByIds(sorted.IdSortOrder);
// Save content with new sort order and update content xml in db accordingly
if (contentService.Sort(content) == false)
if (contentService.Sort(sorted.IdSortOrder) == false)
{
LogHelper.Warn<ContentController>("Content sorting failed, this was probably caused by an event being cancelled");
return Request.CreateValidationErrorResponse("Content sorting failed, this was probably caused by an event being cancelled");
@@ -850,6 +848,7 @@ namespace Umbraco.Web.Editors
/// <param name="id"></param>
/// <returns></returns>
[EnsureUserPermissionForContent("id", 'U')]
[OutgoingEditorModelEvent]
public ContentItemDisplay PostUnPublish(int id)
{
var foundContent = GetObjectFromRequest(() => Services.ContentService.GetById(id));
@@ -464,6 +464,7 @@ namespace Umbraco.Web.Editors
/// <returns></returns>
[FileUploadCleanupFilter]
[MediaPostValidate]
[OutgoingEditorModelEvent]
public MediaItemDisplay PostSave(
[ModelBinder(typeof(MediaItemBinder))]
MediaItemSave contentItem)
+3 -2
View File
@@ -256,6 +256,7 @@ namespace Umbraco.Web.Editors
/// </summary>
/// <returns></returns>
[FileUploadCleanupFilter]
[OutgoingEditorModelEvent]
public MemberDisplay PostSave(
[ModelBinder(typeof(MemberBinder))]
MemberSave contentItem)
@@ -393,7 +394,7 @@ namespace Umbraco.Web.Editors
UpdateName(contentItem);
//map the custom properties - this will already be set for new entities in our member binder
contentItem.PersistedContent.Email = contentItem.Email;
contentItem.PersistedContent.Email = contentItem.Email;
contentItem.PersistedContent.Username = contentItem.Username;
//use the base method to map the rest of the properties
@@ -555,7 +556,7 @@ namespace Umbraco.Web.Editors
var builtInAliases = Constants.Conventions.Member.GetStandardPropertyTypeStubs().Select(x => x.Key).ToArray();
foreach (var p in contentItem.PersistedContent.Properties)
{
var valueMapped = currProps.SingleOrDefault(x => x.Alias == p.Alias);
var valueMapped = currProps.FirstOrDefault(x => x.Alias == p.Alias);
if (builtInAliases.Contains(p.Alias) == false && valueMapped != null)
{
p.Value = valueMapped.Value;
+208
View File
@@ -0,0 +1,208 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Examine;
using Examine.Config;
using Examine.LuceneEngine;
using Examine.LuceneEngine.Providers;
using Examine.Providers;
using Lucene.Net.Index;
using Lucene.Net.Store;
using Umbraco.Core;
using Umbraco.Core.Logging;
using UmbracoExamine;
namespace Umbraco.Web
{
/// <summary>
/// Used to configure Examine during startup for the web application
/// </summary>
internal class ExamineStartup
{
private readonly List<BaseIndexProvider> _indexesToRebuild = new List<BaseIndexProvider>();
private readonly ApplicationContext _appCtx;
private readonly ProfilingLogger _profilingLogger;
private static bool _isConfigured = false;
//this is used if we are not the MainDom, in which case we need to ensure that if indexes need rebuilding that this
//doesn't occur since that should only occur when we are MainDom
private bool _disableExamineIndexing = false;
public ExamineStartup(ApplicationContext appCtx)
{
_appCtx = appCtx;
_profilingLogger = appCtx.ProfilingLogger;
}
/// <summary>
/// Called during the initialize operation of the boot manager process
/// </summary>
public void Initialize()
{
//We want to manage Examine's appdomain shutdown sequence ourselves so first we'll disable Examine's default behavior
//and then we'll use MainDom to control Examine's shutdown
ExamineManager.DisableDefaultHostingEnvironmentRegistration();
//we want to tell examine to use a different fs lock instead of the default NativeFSFileLock which could cause problems if the appdomain
//terminates and in some rare cases would only allow unlocking of the file if IIS is forcefully terminated. Instead we'll rely on the simplefslock
//which simply checks the existence of the lock file
DirectoryTracker.DefaultLockFactory = d =>
{
var simpleFsLockFactory = new NoPrefixSimpleFsLockFactory(d);
return simpleFsLockFactory;
};
//This is basically a hack for this item: http://issues.umbraco.org/issue/U4-5976
// when Examine initializes it will try to rebuild if the indexes are empty, however in many cases not all of Examine's
// event handlers will be assigned during bootup when the rebuilding starts which is a problem. So with the examine 0.1.58.2941 build
// it has an event we can subscribe to in order to cancel this rebuilding process, but what we'll do is cancel it and postpone the rebuilding until the
// boot process has completed. It's a hack but it works.
ExamineManager.Instance.BuildingEmptyIndexOnStartup += OnInstanceOnBuildingEmptyIndexOnStartup;
//let's deal with shutting down Examine with MainDom
var examineShutdownRegistered = _appCtx.MainDom.Register(() =>
{
using (_profilingLogger.TraceDuration<ExamineStartup>("Examine shutting down"))
{
//Due to the way Examine's own IRegisteredObject works, we'll first run it with immediate=false and then true so that
//it's correct subroutines are executed (otherwise we'd have to run this logic manually ourselves)
ExamineManager.Instance.Stop(false);
ExamineManager.Instance.Stop(true);
}
});
if (examineShutdownRegistered)
{
_profilingLogger.Logger.Debug<ExamineStartup>("Examine shutdown registered with MainDom");
}
else
{
_profilingLogger.Logger.Debug<ExamineStartup>("Examine shutdown not registered, this appdomain is not the MainDom");
//if we could not register the shutdown examine ourselves, it means we are not maindom! in this case all of examine should be disabled
//from indexing anything on startup!!
_disableExamineIndexing = true;
Suspendable.ExamineEvents.SuspendIndexers();
}
}
/// <summary>
/// Called during the Complete operation of the boot manager process
/// </summary>
public void Complete()
{
EnsureUnlockedAndConfigured();
//Ok, now that everything is complete we'll check if we've stored any references to index that need rebuilding and run them
// (see the initialize method for notes) - we'll ensure we remove the event handler too in case examine manager doesn't actually
// initialize during startup, in which case we want it to rebuild the indexes itself.
ExamineManager.Instance.BuildingEmptyIndexOnStartup -= OnInstanceOnBuildingEmptyIndexOnStartup;
//don't do anything if we have disabled this
if (_disableExamineIndexing == false)
{
foreach (var indexer in _indexesToRebuild)
{
indexer.RebuildIndex();
}
}
}
/// <summary>
/// Called to perform the rebuilding indexes on startup if the indexes don't exist
/// </summary>
public void RebuildIndexes()
{
//don't do anything if we have disabled this
if (_disableExamineIndexing) return;
EnsureUnlockedAndConfigured();
//If the developer has explicitly opted out of rebuilding indexes on startup then we
// should adhere to that and not do it, this means that if they are load balancing things will be
// out of sync if they are auto-scaling but there's not much we can do about that.
if (ExamineSettings.Instance.RebuildOnAppStart == false) return;
foreach (var indexer in GetIndexesForColdBoot())
{
indexer.RebuildIndex();
}
}
/// <summary>
/// The method used to create indexes on a cold boot
/// </summary>
/// <remarks>
/// A cold boot is when the server determines it will not (or cannot) process instructions in the cache table and
/// will rebuild it's own caches itself.
/// </remarks>
public IEnumerable<BaseIndexProvider> GetIndexesForColdBoot()
{
// NOTE: This is IMPORTANT! ... we don't want to rebuild any index that is already flagged to be re-indexed
// on startup based on our _indexesToRebuild variable and how Examine auto-rebuilds when indexes are empty.
// This callback is used above for the DatabaseServerMessenger startup options.
// all indexes
IEnumerable<BaseIndexProvider> indexes = ExamineManager.Instance.IndexProviderCollection;
// except those that are already flagged
// and are processed in Complete()
if (_indexesToRebuild.Any())
indexes = indexes.Except(_indexesToRebuild);
// return
foreach (var index in indexes)
yield return index;
}
/// <summary>
/// Must be called to configure each index and ensure it's unlocked before any indexing occurs
/// </summary>
/// <remarks>
/// Indexing rebuilding can occur on a normal boot if the indexes are empty or on a cold boot by the database server messenger. Before
/// either of these happens, we need to configure the indexes.
/// </remarks>
private void EnsureUnlockedAndConfigured()
{
if (_isConfigured) return;
_isConfigured = true;
foreach (var luceneIndexer in ExamineManager.Instance.IndexProviderCollection.OfType<LuceneIndexer>())
{
//We now need to disable waiting for indexing for Examine so that the appdomain is shutdown immediately and doesn't wait for pending
//indexing operations. We used to wait for indexing operations to complete but this can cause more problems than that is worth because
//that could end up halting shutdown for a very long time causing overlapping appdomains and many other problems.
luceneIndexer.WaitForIndexQueueOnShutdown = false;
//we should check if the index is locked ... it shouldn't be! We are using simple fs lock now and we are also ensuring that
//the indexes are not operational unless MainDom is true so if _disableExamineIndexing is false then we should be in charge
if (_disableExamineIndexing == false)
{
var dir = luceneIndexer.GetLuceneDirectory();
if (IndexWriter.IsLocked(dir))
{
_profilingLogger.Logger.Info<ExamineStartup>("Forcing index " + luceneIndexer.IndexSetName + " to be unlocked since it was left in a locked state");
IndexWriter.Unlock(dir);
}
}
}
}
private void OnInstanceOnBuildingEmptyIndexOnStartup(object sender, BuildingEmptyIndexOnStartupEventArgs args)
{
//store the indexer that needs rebuilding because it's empty for when the boot process
// is complete and cancel this current event so the rebuild process doesn't start right now.
args.Cancel = true;
_indexesToRebuild.Add((BaseIndexProvider)args.Indexer);
//check if the index is rebuilding due to an error and log it
if (args.IsHealthy == false)
{
var baseIndex = args.Indexer as BaseIndexProvider;
var name = baseIndex != null ? baseIndex.Name : "[UKNOWN]";
_profilingLogger.Logger.Error<ExamineStartup>(string.Format("The index {0} is rebuilding due to being unreadable/corrupt", name), args.UnhealthyException);
}
}
}
}
@@ -139,7 +139,7 @@ namespace Umbraco.Web.HealthCheck.Checks.Config
public override IEnumerable<HealthCheckStatus> GetStatus()
{
var successMessage = string.Format(CheckSuccessMessage, FileName, XPath, Values, CurrentValue);
var successMessage = string.Format(CheckSuccessMessage, FileName, XPath, Values);
var configValue = _configurationService.GetConfigurationValue();
if (configValue.Success == false)
@@ -155,6 +155,9 @@ namespace Umbraco.Web.HealthCheck.Checks.Config
CurrentValue = configValue.Result;
// need to update the successMessage with the CurrentValue
successMessage = string.Format(CheckSuccessMessage, FileName, XPath, Values, CurrentValue);
var valueFound = Values.Any(value => string.Equals(CurrentValue, value.Value, StringComparison.InvariantCultureIgnoreCase));
if (ValueComparisonType == ValueComparisonType.ShouldEqual && valueFound || ValueComparisonType == ValueComparisonType.ShouldNotEqual && valueFound == false)
{

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