diff --git a/Directory.Build.props b/Directory.Build.props index 55de1cddb..4f8e3aedd 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,6 +1,6 @@ - 9.1.0-beta1 + 9.1.0 Piranha CMS Piranha CMS Copyright (c) .NET Foundation and Contributors diff --git a/core/Piranha.AspNetCore/PiranhaMiddleware.cs b/core/Piranha.AspNetCore/PiranhaMiddleware.cs index d573116ba..c91aee0b5 100644 --- a/core/Piranha.AspNetCore/PiranhaMiddleware.cs +++ b/core/Piranha.AspNetCore/PiranhaMiddleware.cs @@ -110,7 +110,7 @@ public override async Task Invoke(HttpContext context, IApi api, IApplicationSer service.Site.Culture = site.Culture; service.Site.Sitemap = await api.Sites.GetSitemapAsync(site.Id); - // Set prefered hostname & prefix + // Set preferred hostname & prefix var siteHost = GetMatchingHost(site, hostname); service.Site.Host = siteHost[0]; service.Site.SitePrefix = siteHost[1]; @@ -225,7 +225,7 @@ public override async Task Invoke(HttpContext context, IApi api, IApplicationSer { App.PostTypes.GetById(post.TypeId); - // Onlyc cache published posts + // Only cache published posts if (post.IsPublished) { service.CurrentPost = post; diff --git a/core/Piranha.Manager.Localization/Resources/Alias.zh.resx b/core/Piranha.Manager.Localization/Resources/Alias.zh.resx index 62e0d45b5..7d50c6207 100644 --- a/core/Piranha.Manager.Localization/Resources/Alias.zh.resx +++ b/core/Piranha.Manager.Localization/Resources/Alias.zh.resx @@ -13,36 +13,36 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - 别名 + 別名 - 添加新别名 + 新增別名 - 别名网址 + 別名網址 - 别名网址必填。 + 別名網址是必填項。 - 重定向网址 + 導向網址 - 重定向网址必填。 + 導向網址是必填項。 永久 - 是否确定删除此别名? + 是否確定要刪除此別名? - 重定向是否永久 + 這個導向網址應該是永久的 - 该别名已成功加入列表 + 該別名已加入列表中 - 该别名已成功删除 + 該別名已成功刪除 diff --git a/core/Piranha.Manager.Localization/Resources/Content.zh.resx b/core/Piranha.Manager.Localization/Resources/Content.zh.resx index fb08a6fc7..59f1a2aa8 100644 --- a/core/Piranha.Manager.Localization/Resources/Content.zh.resx +++ b/core/Piranha.Manager.Localization/Resources/Content.zh.resx @@ -13,33 +13,33 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - 摘要 + 摘录 - 關鍵值索引 + 关键值索引 - 關鍵值流程 + 关键值流程 - 關鍵值優先 + 关健值优先 - 主要圖片 + 主要图像 - 搜尋引擎優先 + 与同一站点中的其他内容相比,搜索引擎优先级。 - 本內容已成功刪除 + 内容已成功删除 - 刪除內容時發生錯誤 + 删除内容时发生错误 - 本內容已成功儲存 + 内容已成功保存 - 儲存內容時發生錯誤 + 保存内容时发生错误 diff --git a/core/Piranha.Manager.Localization/Resources/General.zh.resx b/core/Piranha.Manager.Localization/Resources/General.zh.resx index 32589f954..8cdf4cebc 100644 --- a/core/Piranha.Manager.Localization/Resources/General.zh.resx +++ b/core/Piranha.Manager.Localization/Resources/General.zh.resx @@ -13,16 +13,16 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - 添加 + 新增 - 高级选项 + 進階 全部 - 发生了一个错误 + 發生錯誤 取消 @@ -31,34 +31,34 @@ 内容 - 继续 + 繼續 - 内容类型 + 內容類型 - 拷贝 + 複製 - 语系 + 語系 - 默认 + 預設值 - 删除 + 刪除 - 说明 + 說明 - 详细信息 + 詳細資料 尺寸 - 下载 + 下載 草稿 @@ -67,103 +67,103 @@ 草稿 - 电子邮件地址 + 電子郵件 - 电子邮件地址是必须的。 + 電子郵件是必填項。 - 档名 + 檔案名稱 - + 高度 - 编辑 + 編輯 - + 空值 - 基本 + 一般 - 基本讯息 + 基本資訊 - 历史 + 歷史紀錄 - 内部 Id + 內部編號 - 是默认值 + 預設網站 - 语系 + 語系 - 语系 + 語系 - 登录 + 登入 - 注销 + 登出 - 看来这里没有项目,点击上面的按钮开始! + 目前沒有內容,請點擊上面的按鍵進行操作! - 看来这里没有项目,点击下面的按钮开始! + 目前沒有內容,請點擊下面的按鍵進行操作! - 似乎这里没有项目,点击左边的按钮开始! + 目前沒有內容,請點擊左邊的按鍵進行操作! - 主要内容 + 主要內容 - 已修改 + 修改日期 - 名称 + 用戶名稱 - 名称为必填项 + 用戶名稱為必填項。 - 新建标签页打开自定义网址 + 於新分頁開啟自訂網址 - 密码 + 密碼 永久 - 权限 + 權限 像素 - 预览 + 預覽 - 发布 + 發布 - 发布日期 + 發布日期 - 重定向 + 導向 - 重定向类型 + 導向模式 - 还原 + 復原 角色 @@ -172,87 +172,87 @@ 路由 - 保存 + 儲存 - 已排程 + 排程日期 - 搜索中... + 搜尋 ... - 选择模块... + 選擇區塊 - 设置 + 設定 - 搜索引擎优化 + 搜尋引擎優化 - 共享 + 分享 尺寸 - 网址标识 + 網址後綴 - 系统 + 系統 - 临时的 + 臨時 - 标题 + 標題 更新 - 更新密码 + 更新密碼 - 用户名 + 用戶名稱 - 用户名是必填项 + 用戶名稱為必填項。 - 名称为必填项 + 標題為必填項。 - 类型 + 類型 - 取消发布 + 取消發布 - 已取消发布 + 未發佈 - 用户 + 用戶 版本 - 宽度 + 寬度 - 归档和评论 + 存檔及評論 作者 - 评论 + 評論 - 已创建 + 建立日期 - 用户名或密码不正确。 + 用戶名稱或密碼不正確 diff --git a/core/Piranha.Manager.Localization/Resources/Media.zh.resx b/core/Piranha.Manager.Localization/Resources/Media.zh.resx index 3fd8d3088..a245dda52 100644 --- a/core/Piranha.Manager.Localization/Resources/Media.zh.resx +++ b/core/Piranha.Manager.Localization/Resources/Media.zh.resx @@ -13,78 +13,78 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - 创建文件夹 + 新增檔案夾 - 将文件拖放到此处,或点击上传。 + 將檔案拖至此處,或點擊這裡進行上傳。 - 下载媒体文件 + 下載媒體檔案 - 文件夹名称 + 資料夾名稱 - 文件夹名称是必填的。 + 名稱為必填項 - 相册 + 圖庫 - 媒体 + 媒體 - 媒体预览不可用 + 媒體預覽功能未啟用 - 在新标签中打开媒体 + 新標簽打開鏈接 - 选择媒体 + 選取媒體 - 您的浏览器不支持视频标签。 + 您的瀏覽器不支援 HTML5 影片播放標籤。 列表 - 首选尺寸 + 首選尺寸 - 原始文件 + 原始 - 横屏模式 + 橫式 - 头像 + 直式 - 宽屏模式 + 寬螢幕 - 方形 + 正方形 - 您确定要删除选定的媒体吗? + 確定要刪除已選擇的媒體? - 删除选中项目 + 移除所選項目 - 媒体文件已成功移动。 + 檔案已成功移動。 - 媒体文件已成功移动。 + 檔案已成功移動。 - 找不到媒体文件。 + 找不到此檔案。 - 媒体文件已成功删除 + 檔案刪除成功 - 媒体文件已成功删除 + 檔案刪除成功 diff --git a/core/Piranha.Manager.Localization/Resources/Menu.zh.resx b/core/Piranha.Manager.Localization/Resources/Menu.zh.resx index 7f37a7f5f..a7748e31d 100644 --- a/core/Piranha.Manager.Localization/Resources/Menu.zh.resx +++ b/core/Piranha.Manager.Localization/Resources/Menu.zh.resx @@ -16,39 +16,39 @@ 内容 - 设置 + 設定 - 系统 + 系統 - 网页 + 頁面 - 媒体 + 媒體 - 别名 + 別名 - 站点 + 網站 - 配置 + 設置 - 模块 + 模組 - 注销 + 登出 - 评论 + 評論 角色 - 用户 + 用戶 diff --git a/core/Piranha.Manager.Localization/Resources/Module.zh.resx b/core/Piranha.Manager.Localization/Resources/Module.zh.resx index 13ad25005..4fb798ca7 100644 --- a/core/Piranha.Manager.Localization/Resources/Module.zh.resx +++ b/core/Piranha.Manager.Localization/Resources/Module.zh.resx @@ -13,9 +13,9 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - 模块 + 模組 - 程序包链接 + 套件程式網址 diff --git a/core/Piranha.Manager.Localization/Resources/Security.zh.resx b/core/Piranha.Manager.Localization/Resources/Security.zh.resx index 0b3c98226..1e3442535 100644 --- a/core/Piranha.Manager.Localization/Resources/Security.zh.resx +++ b/core/Piranha.Manager.Localization/Resources/Security.zh.resx @@ -13,43 +13,43 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - 用户名已被其他用户使用。 + 用戶名稱已被使用。 - 电子邮件地址已被其他用户使用。 + 電子郵件已被使用。 - 找不到用户。 + 找不到該用戶。 - 电子邮件地址是必须的。 + 電子郵件是必填項。 - 新密码不匹配。 + 輸入的密碼不一致。 - 创建新用户时必须输入密码。 + 建立新用戶時密碼為必填項。 - 无法保存用户。 + 該用戶更新失敗。 - 用户已保存。 + 用戶已儲存。 - 您确定要删除此用户吗? + 是否確定要刪除該用戶? - 用户已被删除。 + 該用戶已被刪除。 - 无法删除您自己。 + 不能刪除自己。 - 新密码 + 新的密碼 - 确认密码 + 確認密碼 diff --git a/core/Piranha.Manager.Localization/Resources/Site.zh.resx b/core/Piranha.Manager.Localization/Resources/Site.zh.resx index c89517adb..bc967cc31 100644 --- a/core/Piranha.Manager.Localization/Resources/Site.zh.resx +++ b/core/Piranha.Manager.Localization/Resources/Site.zh.resx @@ -13,27 +13,27 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - 添加站点 + 新增網站 - 您确定吗? + 是否確定要刪除嗎? - 编辑站点 + 編輯網站 - 主机名 + 主機名稱 - 标识 + 商標 - 如果这是安装的默认站点。 + 設置為預設網站。 - 请输入站点名称以确认。 + 請確認本網站的名稱。 - 这个动作将 <strong>不能</strong> 回复,将永久删除 {{ title }} 站点及所有 <strong>页面</strong>、<strong>存档</strong>及 <strong>帖子</strong> 內容。 + 這個動作<strong>不能</strong>被回復,將永久刪除 {{ title }} 網站及所有<strong>頁面</strong>、<strong>存檔</strong>及<strong>貼文</strong>內容。 diff --git a/core/Piranha.Manager/Controllers/CommentApiController.cs b/core/Piranha.Manager/Controllers/CommentApiController.cs index 58673b031..c6ec6be81 100644 --- a/core/Piranha.Manager/Controllers/CommentApiController.cs +++ b/core/Piranha.Manager/Controllers/CommentApiController.cs @@ -18,7 +18,7 @@ namespace Piranha.Manager.Controllers { /// - /// Api controller for alias management. + /// Api controller for comment management. /// [Area("Manager")] [Route("manager/api/comment")] diff --git a/core/Piranha.Manager/Controllers/ConfigApiController.cs b/core/Piranha.Manager/Controllers/ConfigApiController.cs index 7ac3ce116..c7d1b83a0 100644 --- a/core/Piranha.Manager/Controllers/ConfigApiController.cs +++ b/core/Piranha.Manager/Controllers/ConfigApiController.cs @@ -16,7 +16,7 @@ namespace Piranha.Manager.Controllers { /// - /// Api controller for alias management. + /// Api controller for config management. /// [Area("Manager")] [Route("manager/api/config")] diff --git a/core/Piranha.Manager/Controllers/LanguageApiController.cs b/core/Piranha.Manager/Controllers/LanguageApiController.cs index c0c55f8f9..1bed97259 100644 --- a/core/Piranha.Manager/Controllers/LanguageApiController.cs +++ b/core/Piranha.Manager/Controllers/LanguageApiController.cs @@ -19,7 +19,7 @@ namespace Piranha.Manager.Controllers { /// - /// Api controller for alias management. + /// Api controller for language management. /// [Area("Manager")] [Route("manager/api/language")] diff --git a/core/Piranha.Manager/Controllers/MediaApiController.cs b/core/Piranha.Manager/Controllers/MediaApiController.cs index ed8698802..fa6779884 100644 --- a/core/Piranha.Manager/Controllers/MediaApiController.cs +++ b/core/Piranha.Manager/Controllers/MediaApiController.cs @@ -22,7 +22,7 @@ namespace Piranha.Manager.Controllers { /// - /// Api controller for alias management. + /// Api controller for media management. /// [Area("Manager")] [Route("manager/api/media")] @@ -61,7 +61,7 @@ public async Task Get(Guid id) /// /// Gets the image url for the specified dimensions. /// - /// The unqie id + /// The unique id /// The optional width /// The optional height /// The public url @@ -109,7 +109,7 @@ public async Task SaveMeta(MediaListModel.MediaItem model) return Ok(new StatusMessage { Type = StatusMessage.Success, - Body = _localizer.Media["The meta information was succesfully updated"] + Body = _localizer.Media["The meta information was successfully updated"] }); } else diff --git a/core/Piranha.Manager/Controllers/ModuleApiController.cs b/core/Piranha.Manager/Controllers/ModuleApiController.cs index 19e5fe72a..e9abb1c01 100644 --- a/core/Piranha.Manager/Controllers/ModuleApiController.cs +++ b/core/Piranha.Manager/Controllers/ModuleApiController.cs @@ -17,7 +17,7 @@ namespace Piranha.Manager.Controllers { /// - /// Api controller for alias management. + /// Api controller for module management. /// [Area("Manager")] [Route("manager/api/module")] diff --git a/core/Piranha.Manager/Controllers/PostApiController.cs b/core/Piranha.Manager/Controllers/PostApiController.cs index d20301558..3feef652e 100644 --- a/core/Piranha.Manager/Controllers/PostApiController.cs +++ b/core/Piranha.Manager/Controllers/PostApiController.cs @@ -20,7 +20,7 @@ namespace Piranha.Manager.Controllers { /// - /// Api controller for page management. + /// Api controller for post management. /// [Area("Manager")] [Route("manager/api/post")] diff --git a/core/Piranha.Manager/Models/MediaListModel.cs b/core/Piranha.Manager/Models/MediaListModel.cs index ad2b35091..227bbbe4c 100644 --- a/core/Piranha.Manager/Models/MediaListModel.cs +++ b/core/Piranha.Manager/Models/MediaListModel.cs @@ -140,7 +140,7 @@ public class MediaItem public Guid? CurrentFolderId { get; set; } /// - /// Gets/sets the optinal folder name + /// Gets/sets the optional folder name /// public string CurrentFolderName { get; set; } diff --git a/core/Piranha.Manager/Module.cs b/core/Piranha.Manager/Module.cs index 3133eb07a..e29812826 100644 --- a/core/Piranha.Manager/Module.cs +++ b/core/Piranha.Manager/Module.cs @@ -51,7 +51,7 @@ public sealed class Module : IModule new PermissionItem { Name = Permission.PagesDelete, Title = "Delete Pages", Category = "Pages" }, new PermissionItem { Name = Permission.PagesEdit, Title = "Edit Pages", Category = "Pages" }, new PermissionItem { Name = Permission.PagesPublish, Title = "Publish Pages", Category = "Pages" }, - new PermissionItem { Name = Permission.PagesSave, Title = "Pages - Save", Category = "Pages" }, + new PermissionItem { Name = Permission.PagesSave, Title = "Save Pages", Category = "Pages" }, new PermissionItem { Name = Permission.Posts, Title = "List Posts", Category = "Posts" }, new PermissionItem { Name = Permission.PostsAdd, Title = "Add Posts", Category = "Posts" }, new PermissionItem { Name = Permission.PostsDelete, Title = "Delete Posts", Category = "Posts" }, diff --git a/core/Piranha.Manager/Piranha.Manager.csproj b/core/Piranha.Manager/Piranha.Manager.csproj index 7b29910b8..c129dfe31 100644 --- a/core/Piranha.Manager/Piranha.Manager.csproj +++ b/core/Piranha.Manager/Piranha.Manager.csproj @@ -7,6 +7,10 @@ Manager panel for Piranha CMS for AspNetCore + + 9.1.1 + + true diff --git a/core/Piranha.Manager/Services/PageService.cs b/core/Piranha.Manager/Services/PageService.cs index 49b8ab285..9c09ee993 100644 --- a/core/Piranha.Manager/Services/PageService.cs +++ b/core/Piranha.Manager/Services/PageService.cs @@ -77,7 +77,7 @@ public async Task GetList() } /// - /// Gets the hierachical page structure for the specified site. + /// Gets the hierarchical page structure for the specified site. /// /// The site id /// The structure diff --git a/core/Piranha/Extend/ContentGroupAttribute.cs b/core/Piranha/Extend/ContentGroupAttribute.cs index 5fcb132a9..ca9bfbfb4 100644 --- a/core/Piranha/Extend/ContentGroupAttribute.cs +++ b/core/Piranha/Extend/ContentGroupAttribute.cs @@ -34,7 +34,7 @@ public string Title if (string.IsNullOrWhiteSpace(Id)) { - Id = Utils.GenerateInteralId(value); + Id = Utils.GenerateInternalId(value); } } } diff --git a/core/Piranha/Piranha.csproj b/core/Piranha/Piranha.csproj index 229f1d75e..c84ef48a4 100644 --- a/core/Piranha/Piranha.csproj +++ b/core/Piranha/Piranha.csproj @@ -6,6 +6,10 @@ Core package for Piranha CMS for .NET Core + + 9.1.1 + + true diff --git a/core/Piranha/Repositories/ILanguageRespository.cs b/core/Piranha/Repositories/ILanguageRespository.cs index 56146585c..dfbce2672 100644 --- a/core/Piranha/Repositories/ILanguageRespository.cs +++ b/core/Piranha/Repositories/ILanguageRespository.cs @@ -31,9 +31,9 @@ public interface ILanguageRepository Task GetById(Guid id); /// - /// Gets the default side. + /// Gets the default model. /// - /// The modell + /// The model Task GetDefault(); /// diff --git a/core/Piranha/Repositories/IMediaRepository.cs b/core/Piranha/Repositories/IMediaRepository.cs index 7932e4be0..693bb7c20 100644 --- a/core/Piranha/Repositories/IMediaRepository.cs +++ b/core/Piranha/Repositories/IMediaRepository.cs @@ -61,7 +61,7 @@ public interface IMediaRepository Task GetFolderById(Guid id); /// - /// Gets the hierachical media structure. + /// Gets the hierarchical media structure. /// /// The media structure Task GetStructure(); diff --git a/core/Piranha/Services/ContentService.cs b/core/Piranha/Services/ContentService.cs index ab3cc7ffb..ccdb56be7 100644 --- a/core/Piranha/Services/ContentService.cs +++ b/core/Piranha/Services/ContentService.cs @@ -221,6 +221,13 @@ public Task GetTranslationStatusByGroupAsync(string groupId) /// The optional language id public async Task SaveAsync(T model, Guid? languageId = null) where T : GenericContent { + // Make sure we have valid content type + var type = App.ContentTypes.GetById(model.TypeId); + if (type == null) + { + throw new ValidationException("Content type is missing"); + } + // Make sure we have an Id if (model.Id == Guid.Empty) { @@ -238,11 +245,14 @@ public async Task SaveAsync(T model, Guid? languageId = null) where T : Gener Validator.ValidateObject(model, context, true); // Ensure category - if (model is ICategorizedContent categorizedModel) + if (type.UseCategory) { - if (categorizedModel.Category == null || (string.IsNullOrWhiteSpace(categorizedModel.Category.Title) && string.IsNullOrWhiteSpace(categorizedModel.Category.Slug))) + if (model is ICategorizedContent categorizedModel) { - throw new ValidationException("The Category field is required"); + if (categorizedModel.Category == null || (string.IsNullOrWhiteSpace(categorizedModel.Category.Title) && string.IsNullOrWhiteSpace(categorizedModel.Category.Slug))) + { + throw new ValidationException("The Category field is required"); + } } } diff --git a/core/Piranha/Services/ISiteService.cs b/core/Piranha/Services/ISiteService.cs index 48309d767..0e52dced7 100644 --- a/core/Piranha/Services/ISiteService.cs +++ b/core/Piranha/Services/ISiteService.cs @@ -47,7 +47,7 @@ public interface ISiteService /// /// Gets the default side. /// - /// The modell, or NULL if it doesnt exist + /// The model, or NULL if it doesnt exist Task GetDefaultAsync(); /// @@ -66,7 +66,7 @@ public interface ISiteService Task GetContentByIdAsync(Guid id) where T : SiteContent; /// - /// Gets the hierachical sitemap structure. + /// Gets the hierarchical sitemap structure. /// /// The optional site id /// If only published items should be included diff --git a/core/Piranha/Services/LanguageService.cs b/core/Piranha/Services/LanguageService.cs index 5562b40c3..6bb54605b 100644 --- a/core/Piranha/Services/LanguageService.cs +++ b/core/Piranha/Services/LanguageService.cs @@ -119,7 +119,7 @@ public async Task SaveAsync(Language model) { // Make sure we have a default site var def = await _repo.GetDefault().ConfigureAwait(false); - if (def == null || def.Id == model.Id) + if (def == null || def.Id == model.Id) model.IsDefault = true; } diff --git a/core/Piranha/Services/SiteService.cs b/core/Piranha/Services/SiteService.cs index 044f8474f..e71630ca8 100644 --- a/core/Piranha/Services/SiteService.cs +++ b/core/Piranha/Services/SiteService.cs @@ -244,7 +244,7 @@ public async Task GetContentByIdAsync(Guid id) where T : SiteContent } /// - /// Gets the hierachical sitemap structure. + /// Gets the hierarchical sitemap structure. /// /// The optional site id /// If only published items should be included @@ -307,7 +307,7 @@ public async Task SaveAsync(Site model) // Ensure InternalId if (string.IsNullOrWhiteSpace(model.InternalId)) { - model.InternalId = Utils.GenerateInteralId(model.Title); + model.InternalId = Utils.GenerateInternalId(model.Title); } // Ensure InternalId uniqueness diff --git a/core/Piranha/Utils.cs b/core/Piranha/Utils.cs index b35195d8f..b8427aff9 100644 --- a/core/Piranha/Utils.cs +++ b/core/Piranha/Utils.cs @@ -119,7 +119,7 @@ public static string GenerateSlug(string str, bool hierarchical = true) /// /// The string /// The internal id - public static string GenerateInteralId(string str) + public static string GenerateInternalId(string str) { var ti = new CultureInfo("en-US", false).TextInfo; return ti.ToTitleCase(GenerateSlug(str).Replace('-', ' ')).Replace(" ", ""); diff --git a/data/Piranha.Data.EF/Db.cs b/data/Piranha.Data.EF/Db.cs index 0ca98e20f..debb6e67e 100644 --- a/data/Piranha.Data.EF/Db.cs +++ b/data/Piranha.Data.EF/Db.cs @@ -23,7 +23,7 @@ public abstract class Db : DbContext, IDb where T : Db private static volatile bool IsInitialized = false; /// - /// The object mutext used for initializing the context. + /// The object mutex used for initializing the context. /// private static readonly object Mutex = new object(); diff --git a/data/Piranha.Data.EF/Piranha.Data.EF.csproj b/data/Piranha.Data.EF/Piranha.Data.EF.csproj index eed93b2c4..f21098cc1 100644 --- a/data/Piranha.Data.EF/Piranha.Data.EF.csproj +++ b/data/Piranha.Data.EF/Piranha.Data.EF.csproj @@ -6,6 +6,10 @@ Data components for Entity Framework Core + + 9.1.1 + + true diff --git a/data/Piranha.Data.EF/Repositories/ContentRepository.cs b/data/Piranha.Data.EF/Repositories/ContentRepository.cs index 850564c6c..eb6f6785b 100644 --- a/data/Piranha.Data.EF/Repositories/ContentRepository.cs +++ b/data/Piranha.Data.EF/Repositories/ContentRepository.cs @@ -203,89 +203,95 @@ public async Task Save(T model, Guid languageId) where T : Models.GenericCont if (type != null) { // Ensure category - if (model is Models.ICategorizedContent categorized) + if (type.UseCategory) { - var category = await _db.Taxonomies - .FirstOrDefaultAsync(c => c.Id == categorized.Category.Id) - .ConfigureAwait(false); - - if (category == null) + if (model is Models.ICategorizedContent categorized) { - if (!string.IsNullOrWhiteSpace(categorized.Category.Slug)) - { - category = await _db.Taxonomies - .FirstOrDefaultAsync(c => c.GroupId == type.Group && c.Slug == categorized.Category.Slug && c.Type == TaxonomyType.Category) - .ConfigureAwait(false); - } - if (category == null && !string.IsNullOrWhiteSpace(categorized.Category.Title)) - { - category = await _db.Taxonomies - .FirstOrDefaultAsync(c => c.GroupId == type.Group && c.Title == categorized.Category.Title && c.Type == TaxonomyType.Category) - .ConfigureAwait(false); - } - - if (category == null) - { - category = new Taxonomy - { - Id = categorized.Category.Id != Guid.Empty ? categorized.Category.Id : Guid.NewGuid(), - GroupId = type.Group, - Type = TaxonomyType.Category, - Title = categorized.Category.Title, - Slug = Utils.GenerateSlug(categorized.Category.Title), - Created = DateTime.Now, - LastModified = DateTime.Now - }; - await _db.Taxonomies.AddAsync(category).ConfigureAwait(false); - } - categorized.Category.Id = category.Id; - categorized.Category.Title = category.Title; - categorized.Category.Slug = category.Slug; - } - } - - // Ensure tags - if (model is Models.ITaggedContent tagged) - { - foreach (var t in tagged.Tags) - { - var tag = await _db.Taxonomies - .FirstOrDefaultAsync(tg => tg.Id == t.Id) + var category = await _db.Taxonomies + .FirstOrDefaultAsync(c => c.Id == categorized.Category.Id) .ConfigureAwait(false); - if (tag == null) + if (category == null) { - if (!string.IsNullOrWhiteSpace(t.Slug)) + if (!string.IsNullOrWhiteSpace(categorized.Category.Slug)) { - tag = await _db.Taxonomies - .FirstOrDefaultAsync(tg => tg.GroupId == type.Group && tg.Slug == t.Slug && tg.Type == TaxonomyType.Tag) + category = await _db.Taxonomies + .FirstOrDefaultAsync(c => c.GroupId == type.Group && c.Slug == categorized.Category.Slug && c.Type == TaxonomyType.Category) .ConfigureAwait(false); } - if (tag == null && !string.IsNullOrWhiteSpace(t.Title)) + if (category == null && !string.IsNullOrWhiteSpace(categorized.Category.Title)) { - tag = await _db.Taxonomies - .FirstOrDefaultAsync(tg => tg.GroupId == type.Group && tg.Title == t.Title && tg.Type == TaxonomyType.Tag) + category = await _db.Taxonomies + .FirstOrDefaultAsync(c => c.GroupId == type.Group && c.Title == categorized.Category.Title && c.Type == TaxonomyType.Category) .ConfigureAwait(false); } - if (tag == null) + if (category == null) { - tag = new Taxonomy + category = new Taxonomy { - Id = t.Id != Guid.Empty ? t.Id : Guid.NewGuid(), + Id = categorized.Category.Id != Guid.Empty ? categorized.Category.Id : Guid.NewGuid(), GroupId = type.Group, - Type = TaxonomyType.Tag, - Title = t.Title, - Slug = Utils.GenerateSlug(t.Title), + Type = TaxonomyType.Category, + Title = categorized.Category.Title, + Slug = Utils.GenerateSlug(categorized.Category.Title), Created = DateTime.Now, LastModified = DateTime.Now }; - await _db.Taxonomies.AddAsync(tag).ConfigureAwait(false); + await _db.Taxonomies.AddAsync(category).ConfigureAwait(false); + } + categorized.Category.Id = category.Id; + categorized.Category.Title = category.Title; + categorized.Category.Slug = category.Slug; + } + } + } + + // Ensure tags + if (type.UseTags) + { + if (model is Models.ITaggedContent tagged) + { + foreach (var t in tagged.Tags) + { + var tag = await _db.Taxonomies + .FirstOrDefaultAsync(tg => tg.Id == t.Id) + .ConfigureAwait(false); + + if (tag == null) + { + if (!string.IsNullOrWhiteSpace(t.Slug)) + { + tag = await _db.Taxonomies + .FirstOrDefaultAsync(tg => tg.GroupId == type.Group && tg.Slug == t.Slug && tg.Type == TaxonomyType.Tag) + .ConfigureAwait(false); + } + if (tag == null && !string.IsNullOrWhiteSpace(t.Title)) + { + tag = await _db.Taxonomies + .FirstOrDefaultAsync(tg => tg.GroupId == type.Group && tg.Title == t.Title && tg.Type == TaxonomyType.Tag) + .ConfigureAwait(false); + } + + if (tag == null) + { + tag = new Taxonomy + { + Id = t.Id != Guid.Empty ? t.Id : Guid.NewGuid(), + GroupId = type.Group, + Type = TaxonomyType.Tag, + Title = t.Title, + Slug = Utils.GenerateSlug(t.Title), + Created = DateTime.Now, + LastModified = DateTime.Now + }; + await _db.Taxonomies.AddAsync(tag).ConfigureAwait(false); + } + t.Id = tag.Id; } - t.Id = tag.Id; + t.Title = tag.Title; + t.Slug = tag.Slug; } - t.Title = tag.Title; - t.Slug = tag.Slug; } } @@ -329,33 +335,36 @@ public async Task Save(T model, Guid languageId) where T : Models.GenericCont } } - if (model is Models.ITaggedContent taggedModel) + if (type.UseTags) { - // Remove tags - var removedTags = new List(); - foreach (var tag in content.Tags) + if (model is Models.ITaggedContent taggedModel) { - if (!taggedModel.Tags.Any(t => t.Id == tag.TaxonomyId)) + // Remove tags + var removedTags = new List(); + foreach (var tag in content.Tags) { - removedTags.Add(tag); + if (!taggedModel.Tags.Any(t => t.Id == tag.TaxonomyId)) + { + removedTags.Add(tag); + } + } + foreach (var removed in removedTags) + { + content.Tags.Remove(removed); } - } - foreach (var removed in removedTags) - { - content.Tags.Remove(removed); - } - // Add tags - foreach (var tag in taggedModel.Tags) - { - if (!content.Tags.Any(t => t.ContentId == content.Id && t.TaxonomyId == tag.Id)) + // Add tags + foreach (var tag in taggedModel.Tags) { - var contentTaxonomy = new ContentTaxonomy + if (!content.Tags.Any(t => t.ContentId == content.Id && t.TaxonomyId == tag.Id)) { - ContentId = content.Id, - TaxonomyId = tag.Id - }; - content.Tags.Add(contentTaxonomy); + var contentTaxonomy = new ContentTaxonomy + { + ContentId = content.Id, + TaxonomyId = tag.Id + }; + content.Tags.Add(contentTaxonomy); + } } } } diff --git a/data/Piranha.Data.EF/Repositories/LanguageRepository.cs b/data/Piranha.Data.EF/Repositories/LanguageRepository.cs index 0e5e8837b..8554bdc70 100644 --- a/data/Piranha.Data.EF/Repositories/LanguageRepository.cs +++ b/data/Piranha.Data.EF/Repositories/LanguageRepository.cs @@ -72,9 +72,9 @@ public async Task GetById(Guid id) } /// - /// Gets the default side. + /// Gets the default model. /// - /// The modell + /// The model public async Task GetDefault() { return await _db.Languages diff --git a/data/Piranha.Data.EF/Services/ContentService.cs b/data/Piranha.Data.EF/Services/ContentService.cs index 659c4ce30..043dd0e79 100644 --- a/data/Piranha.Data.EF/Services/ContentService.cs +++ b/data/Piranha.Data.EF/Services/ContentService.cs @@ -220,7 +220,17 @@ public TContent Transform(T model, Models.ContentTypeBase type, TContent dest { if (content is ICategorized categorizedContent) { - categorizedContent.CategoryId = categorized.Category.Id; + if (type is Models.ContentType contentType) + { + if (contentType.UseCategory) + { + categorizedContent.CategoryId = categorized.Category.Id; + } + } + else + { + categorizedContent.CategoryId = categorized.Category.Id; + } } } diff --git a/examples/RazorWeb/Models/Content/Banner.cs b/examples/RazorWeb/Models/Content/Banner.cs index 18cf7fa7e..1084443ea 100644 --- a/examples/RazorWeb/Models/Content/Banner.cs +++ b/examples/RazorWeb/Models/Content/Banner.cs @@ -13,13 +13,9 @@ namespace RazorWeb.Models { - [ContentGroup(Title = "Banners", Icon = "fas fa-star", IsHidden = true)] - public abstract class Banner : Content, ICategorizedContent + [ContentGroup(Title = "Banners", Icon = "fas fa-star")] + public abstract class Banner : Content where T : Banner { - /// - /// Gets/sets the banner category. - /// - public Taxonomy Category { get; set; } } } \ No newline at end of file diff --git a/examples/RazorWeb/Seed.cs b/examples/RazorWeb/Seed.cs index df1bd9110..9d160c4a4 100644 --- a/examples/RazorWeb/Seed.cs +++ b/examples/RazorWeb/Seed.cs @@ -360,14 +360,12 @@ await api.Media.SaveAsync(new Piranha.Models.StreamMediaContent // Add a banner var banner = await Models.ImageBanner.CreateAsync(api); banner.Title = "Welcome to Piranha"; - banner.Category = "Images"; banner.PrimaryImage = images[0].id; banner.Excerpt = "This is a descriptive text"; await api.Content.SaveAsync(banner); // Translate the banner to another language banner.Title = "Välkommen till Piranha"; - banner.Category = "Bilder"; banner.Excerpt = "Det här är en beskrivande text"; await api.Content.SaveAsync(banner, lang2Id); } diff --git a/identity/Piranha.AspNetCore.Identity/Controllers/UserController.cs b/identity/Piranha.AspNetCore.Identity/Controllers/UserController.cs index b2a25aa66..ce9d69ce2 100644 --- a/identity/Piranha.AspNetCore.Identity/Controllers/UserController.cs +++ b/identity/Piranha.AspNetCore.Identity/Controllers/UserController.cs @@ -238,7 +238,7 @@ public async Task Save([FromBody] UserEditModel model) /// The user id [HttpGet] [Route("/manager/user/delete/{id:Guid}")] - [Authorize(Policy = Permissions.UsersSave)] + [Authorize(Policy = Permissions.UsersDelete)] public async Task Delete(Guid id) { diff --git a/test/Piranha.Tests/Utils/InternalId.cs b/test/Piranha.Tests/Utils/InternalId.cs index 760b7d699..907bb033e 100644 --- a/test/Piranha.Tests/Utils/InternalId.cs +++ b/test/Piranha.Tests/Utils/InternalId.cs @@ -14,9 +14,10 @@ namespace Piranha.Tests.Utils { public class InternalId { + //corrected to GenerateInternalId [Fact] public void ToTitleCase() { - Assert.Equal("MyTestValue", Piranha.Utils.GenerateInteralId("mY test vAlUE")); + Assert.Equal("MyTestValue", Piranha.Utils.GenerateInternalId("mY test vAlUE")); } } }