Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#8791: Merge 1.10.x into dev #8792

Merged
merged 5 commits into from
Apr 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ public class AzureFileSystem {
return newPath;
}

private static string GetFolderName(string path) => path.Substring(path.LastIndexOf('/') + 1);

public string Combine(string path1, string path2) {
if (path1 == null) {
throw new ArgumentNullException("path1");
Expand Down Expand Up @@ -148,10 +150,10 @@ public class AzureFileSystem {
}

return BlobClient.ListBlobs(prefix)
.OfType<CloudBlockBlob>()
.Where(blobItem => !blobItem.Uri.AbsoluteUri.EndsWith(FolderEntry))
.Select(blobItem => new AzureBlobFileStorage(blobItem, _absoluteRoot))
.ToArray();
.OfType<CloudBlockBlob>()
.Where(blobItem => !blobItem.Uri.AbsoluteUri.EndsWith(FolderEntry))
.Select(blobItem => new AzureBlobFileStorage(blobItem, _absoluteRoot))
.ToArray();
}

public IEnumerable<IStorageFolder> ListFolders(string path) {
Expand Down Expand Up @@ -201,6 +203,11 @@ public class AzureFileSystem {

public void CreateFolder(string path) {
path = ConvertToRelativeUriPath(path);

if (FileSystemStorageProvider.FolderNameContainsInvalidCharacters(GetFolderName(path))) {
throw new InvalidNameCharacterException("The directory name contains invalid character(s)");
}

Container.EnsureDirectoryDoesNotExist(String.Concat(_root, path));

// Creating a virtually hidden file to make the directory an existing concept
Expand Down Expand Up @@ -232,7 +239,11 @@ public class AzureFileSystem {
path = ConvertToRelativeUriPath(path);
newPath = ConvertToRelativeUriPath(newPath);

// Workaround for https://github.com/Azure/azure-storage-net/issues/892
if (FileSystemStorageProvider.FolderNameContainsInvalidCharacters(GetFolderName(newPath))) {
throw new InvalidNameCharacterException("The new directory name contains invalid character(s)");
}

// Workaround for https://github.com/Azure/azure-storage-net/issues/892.
// Renaming a folder by only changing the casing corrupts all the files in the folder.
if (path.Equals(newPath, StringComparison.OrdinalIgnoreCase)) {
var tempPath = Guid.NewGuid().ToString() + "/";
Expand Down Expand Up @@ -277,6 +288,10 @@ public class AzureFileSystem {
path = ConvertToRelativeUriPath(path);
newPath = ConvertToRelativeUriPath(newPath);

if (FileSystemStorageProvider.FileNameContainsInvalidCharacters(Path.GetFileName(newPath))) {
throw new InvalidNameCharacterException("The new file name contains invalid character(s)");
}

Container.EnsureBlobExists(String.Concat(_root, path));
Container.EnsureBlobDoesNotExist(String.Concat(_root, newPath));

Expand All @@ -301,6 +316,10 @@ public class AzureFileSystem {
public IStorageFile CreateFile(string path) {
path = ConvertToRelativeUriPath(path);

if (FileSystemStorageProvider.FileNameContainsInvalidCharacters(Path.GetFileName(path))) {
throw new InvalidNameCharacterException("The file name contains invalid character(s)");
}

if (Container.BlobExists(String.Concat(_root, path))) {
throw new ArgumentException("File " + path + " already exists");
}
Expand Down Expand Up @@ -388,10 +407,7 @@ private class AzureBlobFolderStorage : IStorageFolder {
_rootPath = rootPath;
}

public string GetName() {
var path = GetPath();
return path.Substring(path.LastIndexOf('/') + 1);
}
public string GetName() => GetFolderName(GetPath());

public string GetPath() {
return _blob.Uri.ToString().Substring(_rootPath.Length).Trim('/');
Expand All @@ -416,11 +432,12 @@ private class AzureBlobFolderStorage : IStorageFolder {
long size = 0;

foreach (var blobItem in directoryBlob.ListBlobs()) {
if (blobItem is CloudBlockBlob)
size += ((CloudBlockBlob)blobItem).Properties.Length;

if (blobItem is CloudBlobDirectory)
size += GetDirectorySize((CloudBlobDirectory)blobItem);
if (blobItem is CloudBlockBlob blob) {
size += blob.Properties.Length;
}
else if (blobItem is CloudBlobDirectory directory) {
size += GetDirectorySize(directory);
}
}

return size;
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,6 @@
<Compile Include="Migrations.cs" />
<Compile Include="Handlers\ReadFormValuesHandler.cs" />
<Compile Include="Services\FormElementEventHandlerBase.cs" />
<Compile Include="Helpers\NameValueCollectionExtensions.cs" />
<Compile Include="Models\Submission.cs" />
<Compile Include="Permissions.cs" />
<Compile Include="Services\FormService.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -467,4 +467,4 @@ public class FormService : IFormService {
return validatorElementType == elementType || validatorElementType.IsAssignableFrom(elementType);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,46 +4,41 @@
using Orchard.Fields.Fields;
using Orchard.Fields.Settings;
using Orchard.Localization;
using System;
using System.Collections.Generic;
using System.Linq;

namespace Orchard.Fields.Drivers {
public class EnumerationFieldDriver : ContentFieldDriver<EnumerationField> {
public IOrchardServices Services { get; set; }

private const string TemplateName = "Fields/Enumeration.Edit";

public EnumerationFieldDriver(IOrchardServices services) {
Services = services;

T = NullLocalizer.Instance;
}

public Localizer T { get; set; }

private static string GetPrefix(ContentField field, ContentPart part) {
return part.PartDefinition.Name + "." + field.Name;
}
private static string GetPrefix(ContentField field, ContentPart part) =>
part.PartDefinition.Name + "." + field.Name;

private static string GetDifferentiator(EnumerationField field, ContentPart part) {
return field.Name;
}
private static string GetDifferentiator(EnumerationField field) => field.Name;

protected override DriverResult Display(ContentPart part, EnumerationField field, string displayType, dynamic shapeHelper) {
return ContentShape("Fields_Enumeration", GetDifferentiator(field, part),
() => shapeHelper.Fields_Enumeration());
return ContentShape("Fields_Enumeration", GetDifferentiator(field), () => shapeHelper.Fields_Enumeration());
}

protected override DriverResult Editor(ContentPart part, EnumerationField field, dynamic shapeHelper) {
return ContentShape("Fields_Enumeration_Edit", GetDifferentiator(field, part),
() => {
if (part.IsNew() && String.IsNullOrEmpty(field.Value)) {
var settings = field.PartFieldDefinition.Settings.GetModel<EnumerationFieldSettings>();
if (!String.IsNullOrWhiteSpace(settings.DefaultValue)) {
field.Value = settings.DefaultValue;
}
return ContentShape("Fields_Enumeration_Edit", GetDifferentiator(field), () => {
if (part.IsNew() && string.IsNullOrEmpty(field.Value)) {
var settings = field.PartFieldDefinition.Settings.GetModel<EnumerationFieldSettings>();
if (!string.IsNullOrWhiteSpace(settings.DefaultValue)) {
field.SelectedValues = new string[] { settings.DefaultValue };
}
return shapeHelper.EditorTemplate(TemplateName: TemplateName, Model: field, Prefix: GetPrefix(field, part));
});
}

return shapeHelper.EditorTemplate(TemplateName: TemplateName, Model: field, Prefix: GetPrefix(field, part));
});
}

protected override DriverResult Editor(ContentPart part, EnumerationField field, IUpdateModel updater, dynamic shapeHelper) {
Expand Down
26 changes: 7 additions & 19 deletions src/Orchard.Web/Modules/Orchard.Fields/Fields/EnumerationField.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,28 +7,16 @@ public class EnumerationField : ContentField {
private const char Separator = ';';

public string Value {
get { return Storage.Get<string>(); }
set { Storage.Set(value ?? String.Empty); }
get => Storage.Get<string>()?.Trim(Separator) ?? "";
set => Storage.Set(string.IsNullOrWhiteSpace(value)
? string.Empty
// It is now the responsibility of this field to (re-)add the separators.
: Separator + value.Trim(Separator) + Separator);
}

public string[] SelectedValues {
get {
var value = Value;
if(string.IsNullOrWhiteSpace(value)) {
return new string[0];
}

return value.Split(new [] { Separator }, StringSplitOptions.RemoveEmptyEntries);
}

set {
if (value == null || value.Length == 0) {
Value = String.Empty;
}
else {
Value = Separator + string.Join(Separator.ToString(), value) + Separator;
}
}
get => Value?.Split(new[] { Separator }, StringSplitOptions.RemoveEmptyEntries) ?? new string[0];
set => Value = value?.Length > 0 ? string.Join(Separator.ToString(), value) : "";
}
}
}
Original file line number Diff line number Diff line change
@@ -1,22 +1,27 @@
@model Orchard.Fields.Fields.EnumerationField

@using Orchard.Fields.Settings;

@{
var settings = Model.PartFieldDefinition.Settings.GetModel<EnumerationFieldSettings>();
string[] options = (!String.IsNullOrWhiteSpace(settings.Options)) ? settings.Options.Split(new string[] { System.Environment.NewLine }, StringSplitOptions.None) : new string[] { T("Select an option").ToString() };
}

<fieldset>
<label for="@Html.FieldIdFor(m => m.Value)" @if (settings.Required) { <text> class="required" </text> }>@Model.DisplayName</label>
<label for="@Html.FieldIdFor(m => m.Value)" @if (settings.Required) { <text> class="required" </text> }>@Model.DisplayName</label>
@switch (settings.ListMode) {
case ListMode.Dropdown:
@Html.DropDownListFor(m => m.Value, new SelectList(options, Model.Value), settings.Required ? new { required = "required" } : null)
@Html.DropDownListFor(m => m.Value, new SelectList(options, Model.SelectedValues.FirstOrDefault()), settings.Required ? new { required = "required" } : null)
break;

case ListMode.Radiobutton:
foreach (var option in options) {
if (string.IsNullOrWhiteSpace(option)) {
<label>@Html.RadioButton("Value", "", string.IsNullOrWhiteSpace(Model.Value), settings.Required ? new { required = "required" } : null)<i>@T("unset")</i></label> }
<label>@Html.RadioButton("Value", "", string.IsNullOrWhiteSpace(Model.SelectedValues.FirstOrDefault()), settings.Required ? new { required = "required" } : null)<i>@T("unset")</i></label>
}
else {
<label>@Html.RadioButton("Value", option, (option == Model.Value), settings.Required ? new { required = "required" } : null)@option</label> }
<label>@Html.RadioButton("Value", option, (option == Model.SelectedValues.FirstOrDefault()), settings.Required ? new { required = "required" } : null)@option</label>
}
}
break;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
using System;
using System.Web.Mvc;
using Orchard.Autoroute.Models;
using Orchard.CulturePicker.Services;
using Orchard.Environment.Extensions;
using Orchard.Localization.Providers;
using Orchard.Localization.Services;
using Orchard.Mvc.Extensions;

namespace Orchard.Localization.Controllers {
[OrchardFeature("Orchard.Localization.CultureSelector")]
public class UserCultureSelectorController : Controller {
private readonly ILocalizationService _localizationService;
private readonly ICultureStorageProvider _cultureStorageProvider;
public IOrchardServices Services { get; set; }

public UserCultureSelectorController(
IOrchardServices services,
ILocalizationService localizationService,
ICultureStorageProvider cultureStorageProvider) {
Services = services;
_localizationService = localizationService;
_cultureStorageProvider = cultureStorageProvider;
}

public ActionResult ChangeCulture(string culture) {
if (string.IsNullOrEmpty(culture)) {
throw new ArgumentNullException(culture);
}

var returnUrl = Utils.GetReturnUrl(Services.WorkContext.HttpContext.Request);
if (string.IsNullOrEmpty(returnUrl))
returnUrl = "";

if (_localizationService.TryGetRouteForUrl(returnUrl, out AutoroutePart currentRoutePart)
&& _localizationService.TryFindLocalizedRoute(currentRoutePart.ContentItem, culture, out AutoroutePart localizedRoutePart)) {
returnUrl = localizedRoutePart.Path;
}

_cultureStorageProvider.SetCulture(culture);
if (!returnUrl.StartsWith("~/")) {
returnUrl = "~/" + returnUrl;
}

return this.RedirectLocal(returnUrl);
}
}
}
4 changes: 2 additions & 2 deletions src/Orchard.Web/Modules/Orchard.Localization/Module.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Features:
Orchard.Localization:
Description: Enables localization of content items.
Category: Content
Dependencies: Settings
Dependencies: Settings, Orchard.Autoroute
Name: Content Localization
Orchard.Localization.DateTimeFormat:
Description: Enables PO-based translation of date/time formats and names of days and months.
Expand All @@ -30,7 +30,7 @@ Features:
Description: Enables transliteration of the autoroute slug when creating a piece of content.
Category: Content
Name: URL Transliteration
Dependencies: Orchard.Localization.Transliteration, Orchard.Autoroute
Dependencies: Orchard.Localization.Transliteration
Orchard.Localization.CultureNeutralPartsAndFields:
Description: Enables the synchronization among localizations of parts and fields specifically marked as "Culture Neutral".
Category: Content
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,11 @@
</ItemGroup>
<ItemGroup>
<Compile Include="AdminMenu.cs" />
<Compile Include="Controllers\AdminCultureSelectorController.cs" />
<Compile Include="Extensions\Constants.cs" />
<Compile Include="Controllers\AdminController.cs" />
<Compile Include="Controllers\TransliterationAdminController.cs" />
<Compile Include="Controllers\AdminCultureSelectorController.cs" />
<Compile Include="Controllers\UserCultureSelectorController.cs" />
<Compile Include="Extensions\MetaDataExtensions.cs" />
<Compile Include="Handlers\LocalizationCultureNeutralityHandler.cs" />
<Compile Include="Models\TransliterationSpecificationRecord.cs" />
Expand Down Expand Up @@ -120,6 +121,7 @@
<Compile Include="Services\LocalizationService.cs" />
<Compile Include="Services\TransliterationService.cs" />
<Compile Include="Events\TransliterationSlugEventHandler.cs" />
<Compile Include="Services\Utils.cs" />
<Compile Include="Settings\LocalizationCultureNeutralityEditorEvents.cs" />
<Compile Include="Settings\LocalizationCultureNeutralitySettings.cs" />
<Compile Include="ViewModels\ContentLocalizationsViewModel.cs" />
Expand Down Expand Up @@ -196,8 +198,7 @@
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Content Include="Views\UserCultureSelector.cshtml" />
<Content Include="Views\DefinitionTemplates\LocalizationCultureNeutralitySettings.cshtml" />
</ItemGroup>
<PropertyGroup>
Expand Down Expand Up @@ -233,4 +234,4 @@
</FlavorProperties>
</VisualStudio>
</ProjectExtensions>
</Project>
</Project>