diff --git a/build/NuSpecs/UmbracoCms.nuspec b/build/NuSpecs/UmbracoCms.nuspec index 270d6a08f8..fc8f52d1fa 100644 --- a/build/NuSpecs/UmbracoCms.nuspec +++ b/build/NuSpecs/UmbracoCms.nuspec @@ -17,7 +17,7 @@ - + diff --git a/src/Umbraco.Core/Persistence/Repositories/MemberGroupRepository.cs b/src/Umbraco.Core/Persistence/Repositories/MemberGroupRepository.cs index a760ebb717..c7e8a5c328 100644 --- a/src/Umbraco.Core/Persistence/Repositories/MemberGroupRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/MemberGroupRepository.cs @@ -183,17 +183,17 @@ namespace Umbraco.Core.Persistence.Repositories } public IEnumerable 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(sql) .DistinctBy(dto => dto.NodeId) .Select(x => _modelFactory.BuildEntity(x)); diff --git a/src/Umbraco.Core/Services/ContentService.cs b/src/Umbraco.Core/Services/ContentService.cs index ae2f7a3dc6..9465cf2ad0 100644 --- a/src/Umbraco.Core/Services/ContentService.cs +++ b/src/Umbraco.Core/Services/ContentService.cs @@ -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(sql); return ids.Length == x.Count; } @@ -2007,7 +2006,7 @@ namespace Umbraco.Core.Services } return true; - } + } /// /// Sorts a collection of objects by updating the SortOrder according @@ -2029,7 +2028,7 @@ namespace Umbraco.Core.Services using (new WriteLock(Locker)) { var allContent = GetByIds(ids).ToDictionary(x => x.Id, x => x); - var items = ids.Select(x => allContent[x]); + var items = ids.Select(x => allContent[x]); using (var uow = UowProvider.GetUnitOfWork()) { @@ -2838,4 +2837,4 @@ namespace Umbraco.Core.Services #endregion } -} \ No newline at end of file +} diff --git a/src/Umbraco.Core/Services/UserService.cs b/src/Umbraco.Core/Services/UserService.cs index 1bf847648c..c33a5fa21f 100644 --- a/src/Umbraco.Core/Services/UserService.cs +++ b/src/Umbraco.Core/Services/UserService.cs @@ -228,9 +228,9 @@ namespace Umbraco.Core.Services } /// - /// Deletes an + /// Disables an /// - /// to Delete + /// to disable public void Delete(IUser membershipUser) { //disable @@ -753,7 +753,7 @@ namespace Umbraco.Core.Services /// Id of the User to retrieve /// 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; diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index f522fb467b..c3d655f194 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -333,8 +333,8 @@ umbraco.providers - - ..\packages\Umbraco.ModelsBuilder.3.0.7\lib\Umbraco.ModelsBuilder.dll + + ..\packages\Umbraco.ModelsBuilder.3.0.8\lib\Umbraco.ModelsBuilder.dll diff --git a/src/Umbraco.Web.UI/packages.config b/src/Umbraco.Web.UI/packages.config index eb6e198935..8653059b89 100644 --- a/src/Umbraco.Web.UI/packages.config +++ b/src/Umbraco.Web.UI/packages.config @@ -36,5 +36,5 @@ - + \ No newline at end of file diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/da.xml b/src/Umbraco.Web.UI/umbraco/config/lang/da.xml index 1c1f03f140..29068057b1 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/da.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/da.xml @@ -1485,7 +1485,7 @@ Mange hilsner fra Umbraco robotten Sæt rettigheder for specifikke noder Profil Søg alle 'børn' - Start node + Startnode Aktiv Alle Deaktiveret diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/he.xml b/src/Umbraco.Web.UI/umbraco/config/lang/he.xml index a3a562d152..8561b419f0 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/he.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/he.xml @@ -32,11 +32,6 @@ מיין תרגם עדכן - מחק - בצע - תזמן - ייבא נתונים - צור הגדרות ילדים יומן משימות מתוזמנות diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/pl.xml b/src/Umbraco.Web.UI/umbraco/config/lang/pl.xml index f291aab7ea..49160fc662 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/pl.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/pl.xml @@ -12,9 +12,11 @@ Kopiuj Utwórz Stwórz zbiór + Stwórz grupę Usuń Deaktywuj Opróżnij kosz + Aktywuj Eksportuj typ dokumentu Importuj typ dokumentu Importuj zbiór @@ -27,16 +29,49 @@ Cofnij publikację Odśwież węzeł Opublikuj ponownie całą stronę + Zmień nazwę Przywróć Ustaw uprawnienia dla strony %0% + Wybierz dokąd przenieść + W strukturze drzewa poniżej Uprawnienia Cofnij Wyślij do publikacji Wyślij do tłumaczenia + Ustaw grupę Sortuj Przetłumacz Aktualizuj + Ustaw uprawnienia + Odblokuj + Stwórz Szablon Zawartości + + Zawartość + Administracja + Struktura + Inne + + + Zezwól na dostęp do przydzielenia języka i hostów + Zezwól na dostęp do wglądu w historię logów węzła + Zezwól na dostęp do widoku węzła + Zezwól na dostęp do zmiany typu dokumentu dla węzła + Zezwól na dostęp do skopiowania węzła + Zezwól na dostęp do stworzenia węzłów + Zezwól na dostęp do usunięcia węzłóws + Zezwól na dostęp do przeniesienia węzła + Zezwól na dostęp do ustawienia i zmiany publicznego dostępu węzła + Zezwól na dostęp do publikacji węzła + Zezwól na dostęp do zmiany uprawnień węzła + Zezwól na dostęp do cofnięcia węzła do poprzedniego stanu + Zezwól na dostęp do wysłania węzła do akceptacji przed publikacją + Zezwól na dostęp do wysłania węzła do tłumaczenia + Zezwól na dostęp do zmiany kolejności sortowania węzłów + Zezwól na dostęp do tłumaczenia węzła + Zezwól na dostęp do zapisania węzła + Zezwól na dostęp do utworzenia Szablonu Zawartości + Brak odpowiednich uprawnień Dodaj nową domenę @@ -50,14 +85,18 @@ Domena '%0%' została skasowana Domena '%0%' jest aktualnie przypisana Domena '%0%' została zaktualizowana - - Edycja aktualnych domen + Edytuj Aktualne Domeny + + + Odziedziczona Język - lub wybierz dziedziczenie języka z węzła rodzica. Zostanie to zastosowane
-także do obecnego węzła, o ile poniższa domena również do niego należy.]]>
+ + lub wybierz dziedziczenie języka z węzła rodzica. Zostanie to zastosowane
+ także do obecnego węzła, o ile poniższa domena również do niego należy.]]> +
Domeny @@ -96,6 +135,7 @@ także do obecnego węzła, o ile poniższa domena również do niego należy.]] Pokaż style Wstaw tabelę Wygeneruj modele + Zapisz i wygeneruj modele Cofnij Powtórz @@ -139,6 +179,8 @@ także do obecnego węzła, o ile poniższa domena również do niego należy.]] Opublikowane Nie ma żadnych elementów do wyświetlenia Nie ma żadnych elementów do wyświetlenia w liście. + Nie dodano żadnej zawartości + Nie dodano żadnych członków Typ mediów Link do elementu(ów) mediów Członek grupy @@ -173,16 +215,30 @@ także do obecnego węzła, o ile poniższa domena również do niego należy.]] Cel Oznacza to następującą godzinę na serwerze: Co to oznacza?]]> + Czy na pewno chcesz usunąć ten element? + Właściwość %0% używa edytora %1%, który nie jest wspierany przez Nested Content. Dodaj kolejne pole tekstowe Usuń te pole tekstowe + Korzeń zawartości + + Stwórz nowy Szablon Zawartości z '%0%' + Pusty + Wybierz Szablon Zawartości + Szablon Zawartości został stworzony + Szablon Zawartości został stworzony z '%0%' + Szablon Zawartości o tej samej nazwie już istnieje + Szablon Zawartości to predefiniowana zawartość, którą edytor może wybrać, aby użyć jej jako podstawę do stworzenia nowej zawartości + Kliknij, aby załadować plik Przerzuć swoje pliki tutaj... - Link do mediów + Link do mediów lub kliknij tutaj, aby wybrać pliki Jedyne dozwolone typy plików to + Nie można załadować pliku, typ pliku nie jest akceptowany Maksymalny rozmiar pliku to + Korzeń mediów Stwórz nowego członka @@ -191,6 +247,7 @@ także do obecnego węzła, o ile poniższa domena również do niego należy.]] Gdzie chcesz stworzyć nowy %0%? Utwórz w + Wybierz typ dokumentu, dla którego chcesz stworzyć szablon zawartości Wybierz rodzaj oraz tytuł "typy dokumentów".]]> "typy mediów".]]> @@ -249,6 +306,8 @@ także do obecnego węzła, o ile poniższa domena również do niego należy.]] Skopiowano %0% z %1% elementów + Tytuł linku + Link Nazwa Zarządzaj nazwami hostów Zamknij to okno @@ -276,6 +335,9 @@ także do obecnego węzła, o ile poniższa domena również do niego należy.]] To makro nie posiada żadnych właściwości, które można edytować Wklej Edytuj Uprawnienia dla + Ustaw uprawnienia dla + Ustaw uprawnienia dla %0% dla grupy użytkownika %1% + Wybierz grupy użytkowników, dla których chcesz ustawić uprawnienia Zawartość kosza jest teraz usuwana. Proszę nie zamykać tego okna do momentu zakończenia procesu. Zawartość kosza została usunięta Usunięcie elementów z kosza powoduje ich trwałe i nieodwracalne skasowanie @@ -288,10 +350,14 @@ także do obecnego węzła, o ile poniższa domena również do niego należy.]] Cache strony zostanie odświeżone. Cała zawartość opublikowana będzie aktualna, lecz nieopublikowana zawartość pozostanie niewidoczna Liczba kolumn Liczba wierszy - Ustaw zastępczy ID 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 <asp:treści />]]> - Wybierz zastępczy ID z poniższej listy. Możesz wybierać tylko - spośród ID na szablonie nadrzędnym tego formularza.]]> + + Ustaw zastępczy ID 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 <asp:treści />]]> + + + Wybierz zastępczy ID z poniższej listy. Możesz wybierać tylko + spośród ID na szablonie nadrzędnym tego formularza.]]> + Kliknij na obrazie, aby zobaczyć go w pełnym rozmiarze Wybierz element Podgląd elementów Cache @@ -303,14 +369,19 @@ także do obecnego węzła, o ile poniższa domena również do niego należy.]] Otwórz zlinkowany dokument w nowym oknie lub zakładce Link do mediów Link do plików + Wybierz węzeł początkowy zawartości Wybierz media Wybierz ikonę Wybierz element Wybierz link Wybierz makro Wybierz zawartość + Wybierz węzeł początkowy mediów Wybierz członka Wybierz członka grupy + Wybierz węzeł + Wybierz sekcje + Wybierz użytkowników Nie znaleziono ikon Te makro nie ma żadnych właściwości Brak dostępnych makro do wstawienia @@ -325,9 +396,11 @@ także do obecnego węzła, o ile poniższa domena również do niego należy.]] Wybierz snippet - %0%' poniżej.
-Możesz dodać dodatkowe języki w menu "Języki" po lewej stronie.]]>
+ + %0%' poniżej.
+ Możesz dodać dodatkowe języki w menu "Języki" po lewej stronie.]]> +
Nazwa języka Edytuj klucz elementu słownika. @@ -342,12 +415,15 @@ Możesz dodać dodatkowe języki w menu "Języki" po lewej stronie.]]> Potwierdź hasło Nazwij %0%... Wpisz nazwę... + Wpisz adres e-mail... + Wpisz nazwę użytkownika... Etykieta... Wpisz opis... Wpisz, aby wyszukać... Wpisz, aby filtrować... Wpisz, aby dodać tagi (naciśnij enter po każdym tagu)... Wpisz adres e-mail + Wpisz wiadomość... Twoja nazwa użytkownika to przeważnie Twój adres e-mail diff --git a/src/Umbraco.Web/Editors/ContentController.cs b/src/Umbraco.Web/Editors/ContentController.cs index 6b3a73f5df..a61ca7e249 100644 --- a/src/Umbraco.Web/Editors/ContentController.cs +++ b/src/Umbraco.Web/Editors/ContentController.cs @@ -532,6 +532,7 @@ namespace Umbraco.Web.Editors /// [FileUploadCleanupFilter] [ContentPostValidate] + [OutgoingEditorModelEvent] public ContentItemDisplay PostSave( [ModelBinder(typeof(ContentItemBinder))] ContentItemSave contentItem) @@ -847,6 +848,7 @@ namespace Umbraco.Web.Editors /// /// [EnsureUserPermissionForContent("id", 'U')] + [OutgoingEditorModelEvent] public ContentItemDisplay PostUnPublish(int id) { var foundContent = GetObjectFromRequest(() => Services.ContentService.GetById(id)); diff --git a/src/Umbraco.Web/Editors/MediaController.cs b/src/Umbraco.Web/Editors/MediaController.cs index e8b0550741..72af1c4c70 100644 --- a/src/Umbraco.Web/Editors/MediaController.cs +++ b/src/Umbraco.Web/Editors/MediaController.cs @@ -461,6 +461,7 @@ namespace Umbraco.Web.Editors /// [FileUploadCleanupFilter] [MediaPostValidate] + [OutgoingEditorModelEvent] public MediaItemDisplay PostSave( [ModelBinder(typeof(MediaItemBinder))] MediaItemSave contentItem) diff --git a/src/Umbraco.Web/Editors/MemberController.cs b/src/Umbraco.Web/Editors/MemberController.cs index 5921b9c61c..5aad40aa70 100644 --- a/src/Umbraco.Web/Editors/MemberController.cs +++ b/src/Umbraco.Web/Editors/MemberController.cs @@ -256,6 +256,7 @@ namespace Umbraco.Web.Editors ///
/// [FileUploadCleanupFilter] + [OutgoingEditorModelEvent] public MemberDisplay PostSave( [ModelBinder(typeof(MemberBinder))] MemberSave contentItem) diff --git a/src/Umbraco.Web/ExamineStartup.cs b/src/Umbraco.Web/ExamineStartup.cs index 0a7cab9522..eac3e20d87 100644 --- a/src/Umbraco.Web/ExamineStartup.cs +++ b/src/Umbraco.Web/ExamineStartup.cs @@ -22,6 +22,7 @@ namespace Umbraco.Web private readonly List _indexesToRebuild = new List(); 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 @@ -89,24 +90,7 @@ namespace Umbraco.Web /// public void Complete() { - //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. - foreach (var luceneIndexer in ExamineManager.Instance.IndexProviderCollection.OfType()) - { - 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)) - { - IndexWriter.Unlock(dir); - } - } - } + 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 @@ -131,6 +115,8 @@ namespace Umbraco.Web //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. @@ -168,6 +154,40 @@ namespace Umbraco.Web yield return index; } + /// + /// Must be called to configure each index and ensure it's unlocked before any indexing occurs + /// + /// + /// 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. + /// + private void EnsureUnlockedAndConfigured() + { + if (_isConfigured) return; + + _isConfigured = true; + + foreach (var luceneIndexer in ExamineManager.Instance.IndexProviderCollection.OfType()) + { + //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("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 diff --git a/src/Umbraco.Web/PublishedCache/XmlPublishedCache/PublishedContentCache.cs b/src/Umbraco.Web/PublishedCache/XmlPublishedCache/PublishedContentCache.cs index c8ddd77afd..ae612afe09 100644 --- a/src/Umbraco.Web/PublishedCache/XmlPublishedCache/PublishedContentCache.cs +++ b/src/Umbraco.Web/PublishedCache/XmlPublishedCache/PublishedContentCache.cs @@ -251,7 +251,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache // move to parent node e = (XmlElement) e.ParentNode; - id = int.Parse(e.GetAttribute("id")); + id = int.Parse(e.GetAttribute("id"), CultureInfo.InvariantCulture); hasDomains = id != -1 && domainHelper.NodeHasDomains(id); } diff --git a/src/Umbraco.Web/PublishedContentQuery.cs b/src/Umbraco.Web/PublishedContentQuery.cs index f0f2461ad8..bfe8fb5260 100644 --- a/src/Umbraco.Web/PublishedContentQuery.cs +++ b/src/Umbraco.Web/PublishedContentQuery.cs @@ -230,7 +230,7 @@ namespace Umbraco.Web { // todo: in v8, implement in a more efficient way var legacyXml = UmbracoConfig.For.UmbracoSettings().Content.UseLegacyXmlSchema; - var xpath = legacyXml ? "//node [@key=$guid]" : "//* [@isDoc and @key=$guid]"; + var xpath = legacyXml ? "//node [@key=$guid]" : "//* [@key=$guid]"; var doc = cache.GetSingleByXPath(xpath, new XPathVariable("guid", id.ToString())); return doc; }