diff --git a/.gitignore b/.gitignore index dacfd197..ebb71f2f 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ obj/ Install/ *.user OpenContentDnnHost/bin/ +OpenContent/lama/node_modules/ diff --git a/OpenContent-NoWebsite.sln b/OpenContent-NoWebsite.sln index 5050a729..01da5989 100644 --- a/OpenContent-NoWebsite.sln +++ b/OpenContent-NoWebsite.sln @@ -1,12 +1,17 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.25420.1 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30503.244 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenContent", "OpenContent\OpenContent.csproj", "{7D61A32C-0F21-453F-A981-BD8E5A3A5304}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenContentTests", "OpenContentTests\OpenContentTests.csproj", "{5703831E-F8C9-4832-9B06-1A2D24426CDF}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{DDFBA7DA-A5EB-47CF-952C-C2D6B8BC2951}" + ProjectSection(SolutionItems) = preProject + custom.targets = custom.targets + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -25,4 +30,7 @@ Global GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {0AEF2EF6-FF7E-4F28-A7AB-0DDB2FAE6921} + EndGlobalSection EndGlobal diff --git a/OpenContent/AlpacaFormBuilder.ascx b/OpenContent/AlpacaFormBuilder.ascx index 5da42430..00a99efe 100644 --- a/OpenContent/AlpacaFormBuilder.ascx +++ b/OpenContent/AlpacaFormBuilder.ascx @@ -49,8 +49,8 @@ newHeight, newWidth; - newHeight = $window.height() - 36; - newWidth = Math.min($window.width() - 40, 1600); + newHeight = $window.height() - 110; + newWidth = Math.min($window.width() - 110, 1600); popup.dialog("option", { close: function () { window.dnnModal.closePopUp(false, ""); }, diff --git a/OpenContent/App_LocalResources/Edit.ascx.resx b/OpenContent/App_LocalResources/Edit.ascx.resx index 86cf37a6..054df758 100644 --- a/OpenContent/App_LocalResources/Edit.ascx.resx +++ b/OpenContent/App_LocalResources/Edit.ascx.resx @@ -129,4 +129,13 @@ Copy + + Some fields are required or invalid. + + + Are you sure you want to delete this Item? + + + Are you sure you want to delete this Item (this may affect all languages)? + \ No newline at end of file diff --git a/OpenContent/BuildScripts/ModulePackage.targets b/OpenContent/BuildScripts/ModulePackage.targets index 5aa4cf95..9af64e1c 100644 --- a/OpenContent/BuildScripts/ModulePackage.targets +++ b/OpenContent/BuildScripts/ModulePackage.targets @@ -6,6 +6,26 @@ + + $(MSBuildProjectDirectory)\Properties\AssemblyInfo.cs + + + + + + + + + + + + + + + fieldLst = new List(); GetFields(newSchemaFilter, newOptionsFilter, schemaConfig, optionsConfig, fieldLst, indexConfig); + + fieldLst.Add(JsonMappingUtils.FIELD_TIMESTAMP); // Sort SchemaConfig newSchemaSort = new SchemaConfig() { diff --git a/OpenContent/Components/Caching/DnnCacheAdapter.cs b/OpenContent/Components/Caching/DnnCacheAdapter.cs index 4e6aefed..833c709c 100644 --- a/OpenContent/Components/Caching/DnnCacheAdapter.cs +++ b/OpenContent/Components/Caching/DnnCacheAdapter.cs @@ -44,7 +44,7 @@ public void ClearCache(string cacheKey) public void SyncronizeCache(OpenContentModuleConfig ocModuleConfig) { int dataModuleId = ocModuleConfig.DataModule.ModuleId; - var dataModuleHasCrossPortalData = Json.JsonExtensions.GetValue(ocModuleConfig.DataModule.ModuleInfo.OpenContentSettings().Manifest.Permissions, "AllowCrossPortalData", false); + var dataModuleHasCrossPortalData = Json.JsonExtensions.GetValue(ocModuleConfig.DataModule.ModuleInfo.OpenContentSettings().Manifest?.Permissions, "AllowCrossPortalData", false); if (dataModuleHasCrossPortalData) foreach (PortalInfo portal in PortalController.Instance.GetPortals()) { diff --git a/OpenContent/Components/Datasource/DefaultDataItem.cs b/OpenContent/Components/Datasource/DefaultDataItem.cs index c5101333..af7aac3b 100644 --- a/OpenContent/Components/Datasource/DefaultDataItem.cs +++ b/OpenContent/Components/Datasource/DefaultDataItem.cs @@ -14,6 +14,7 @@ public DefaultDataItem(JToken json) Data = json; } public string Id { get; set; } + public string Key { get; set; } public string Collection { get; set; } public string Title { get; set; } public JToken Data { get; set; } @@ -22,5 +23,6 @@ public DefaultDataItem(JToken json) public int LastModifiedByUserId { get; set; } public DateTime LastModifiedOnDate { get; set; } public object Item { get; set; } + } } \ No newline at end of file diff --git a/OpenContent/Components/Datasource/DnnUsersDataSource.cs b/OpenContent/Components/Datasource/DnnUsersDataSource.cs index 97fb7440..347af26a 100644 --- a/OpenContent/Components/Datasource/DnnUsersDataSource.cs +++ b/OpenContent/Components/Datasource/DnnUsersDataSource.cs @@ -127,13 +127,12 @@ public override IDataItems GetAll(DataSourceContext context, Select selectQuery) else { int pageIndex = 0; - int pageSize = 1000; + int pageSize = 100000; int total = 0; IEnumerable users; if (selectQuery != null) { - pageIndex = selectQuery.PageIndex; - pageSize = selectQuery.PageSize; + var ruleDisplayName = selectQuery.Query.FilterRules.FirstOrDefault(f => f.Field == "DisplayName"); var ruleRoles = selectQuery.Query.FilterRules.FirstOrDefault(f => f.Field == "Roles"); var ruleApproved = selectQuery.Query.FilterRules.FirstOrDefault(f => f.Field == "Approved"); @@ -146,8 +145,9 @@ public override IDataItems GetAll(DataSourceContext context, Select selectQuery) else { users = UserController.GetUsers(context.PortalId, pageIndex, pageSize, ref total, true, false).Cast(); - total = users.Count(); + } + var userCount = users.Count(); if (ruleRoles != null) { var roleNames = ruleRoles.MultiValue.Select(r => r.AsString).ToList(); @@ -158,16 +158,18 @@ public override IDataItems GetAll(DataSourceContext context, Select selectQuery) var val = bool.Parse(ruleApproved.Value.AsString); users = users.Where(u => u.Membership.Approved == val); } + total = users.Count(); + pageIndex = selectQuery.PageIndex; + pageSize = selectQuery.PageSize; + users = users.Skip(pageIndex * pageSize).Take(pageSize); } else { users = UserController.GetUsers(context.PortalId, pageIndex, pageSize, ref total, true, false).Cast(); } - int excluded = users.Count() - users.Count(u => u.IsInRole("Administrators")); + int excluded = users.Count(u => u.IsInRole("Administrators")); users = users.Where(u => !u.IsInRole("Administrators")); - - //users = users.Skip(pageIndex * pageSize).Take(pageSize); var dataList = new List(); foreach (var user in users) { diff --git a/OpenContent/Components/Datasource/IDataItem.cs b/OpenContent/Components/Datasource/IDataItem.cs index 5f65410e..72fac53d 100644 --- a/OpenContent/Components/Datasource/IDataItem.cs +++ b/OpenContent/Components/Datasource/IDataItem.cs @@ -6,6 +6,7 @@ namespace Satrabel.OpenContent.Components.Datasource public interface IDataItem { string Id { get; set; } + string Key { get; set; } string Collection { get; set; } string Title { get; set; } JToken Data { get; set; } diff --git a/OpenContent/Components/Datasource/OpenContentDataSource.cs b/OpenContent/Components/Datasource/OpenContentDataSource.cs index 3ed54c1f..48a8b72b 100644 --- a/OpenContent/Components/Datasource/OpenContentDataSource.cs +++ b/OpenContent/Components/Datasource/OpenContentDataSource.cs @@ -353,6 +353,10 @@ public virtual JToken Action(DataSourceContext context, string action, IDataItem { if (action == "FormSubmit") { + if (data["form"]["approvalEnabled"] != null && data["form"]["approvalEnabled"].Value() == true ) + { + data["form"]["approved"] = false; + } OpenContentController ctrl = new OpenContentController(context.PortalId); //var indexConfig = OpenContentUtils.GetIndexConfig(new FolderUri(context.TemplateFolder), "Submissions"); var content = new OpenContentInfo() @@ -369,11 +373,13 @@ public virtual JToken Action(DataSourceContext context, string action, IDataItem ctrl.AddContent(content); //Index the content item - //if (context.Index) - //{ - // LuceneController.Instance.Add(content, indexConfig); - // LuceneController.Instance.Commit(); - //} + + if (context.Index) + { + var indexConfig = OpenContentUtils.GetIndexConfig(new FolderUri(context.TemplateFolder), "Submissions"); + LuceneController.Instance.Add(content, indexConfig); + LuceneController.Instance.Commit(); + } return FormUtils.FormSubmit(data as JObject, item?.Data?.DeepClone() as JObject); } return null; @@ -460,6 +466,7 @@ private static DefaultDataItem CreateDefaultDataItem(OpenContentInfo content) return new DefaultDataItem { Id = content.Id, + Key= content.Key, Collection = content.Collection, Title = content.Title, Data = content.JsonAsJToken, diff --git a/OpenContent/Components/DnnEntitiesAPIController.cs b/OpenContent/Components/DnnEntitiesAPIController.cs index 200ab6f9..b469e76b 100644 --- a/OpenContent/Components/DnnEntitiesAPIController.cs +++ b/OpenContent/Components/DnnEntitiesAPIController.cs @@ -140,19 +140,26 @@ public HttpResponseMessage ImagesLookup(string q, string d) /// Imageses the lookup. /// /// The string that should be Contained in the name of the file (case insensitive). Use * to get all the files. - /// The Folder path to retrieve + /// The Folder path to retrieve + /// /// [ValidateAntiForgeryToken] [DnnModuleAuthorize(AccessLevel = SecurityAccessLevel.Edit)] [HttpGet] - public HttpResponseMessage ImagesLookupExt(string q, string folder) + public HttpResponseMessage ImagesLookupExt(string q, string folder, string itemKey = "") { try { - + var module = OpenContentModuleConfig.Create(ActiveModule, PortalSettings); var folderManager = FolderManager.Instance; string imageFolder = "OpenContent/Files/" + ActiveModule.ModuleID; - + if (module.Settings.Manifest.DeleteFiles) + { + if (!string.IsNullOrEmpty(itemKey)) + { + imageFolder += "/" + itemKey; + } + } if (!string.IsNullOrEmpty(folder)) { imageFolder = folder; @@ -467,6 +474,10 @@ public HttpResponseMessage CropImage(CropResizeDTO cropData) rawImageUrl = rawImageUrl.Replace(PortalSettings.HomeDirectory, ""); var file = fileManager.GetFile(ActiveModule.PortalID, rawImageUrl); string cropfolder = "OpenContent/Cropped/" + ActiveModule.ModuleID; + if (!string.IsNullOrEmpty(cropData.itemKey)) + { + cropfolder += "/" + cropData.itemKey; + } if (!string.IsNullOrEmpty(cropData.cropfolder)) { cropfolder = cropData.cropfolder; @@ -849,6 +860,7 @@ public class CropResizeDTO public CropDTO crop { get; set; } public ResizeDTO resize { get; set; } public string cropfolder { get; set; } + public string itemKey { get; set; } } public class CropResizeResultDTO { diff --git a/OpenContent/Components/Export/ExcelApiController.cs b/OpenContent/Components/Export/ExcelApiController.cs index a05a76b7..322d1453 100644 --- a/OpenContent/Components/Export/ExcelApiController.cs +++ b/OpenContent/Components/Export/ExcelApiController.cs @@ -30,69 +30,76 @@ public HttpResponseMessage GetExcel(int moduleId, int tabId) [HttpGet] public HttpResponseMessage GetExcelByQuery(int moduleId, int tabId, string queryName, string filter = null, string sort = null) { - RestSelect restSelect = new RestSelect() - { - PageIndex = 0, - PageSize = 100000 - }; - if (!string.IsNullOrEmpty(filter)) - { - restSelect.Query = JsonConvert.DeserializeObject(filter); - } - if (!string.IsNullOrEmpty(sort)) - { - restSelect.Sort = JsonConvert.DeserializeObject>(sort); - } - IEnumerable dataList = new List(); - var module = OpenContentModuleConfig.Create(moduleId, tabId, PortalSettings); - var manifest = module.Settings.Template.Manifest; - - if (!module.HasAllUsersViewPermissions()) - { - return Request.CreateResponse(HttpStatusCode.Unauthorized); - } - string filename = queryName; - bool useLucene = module.Settings.Template.Manifest.Index; - if (useLucene) + try { - var indexConfig = OpenContentUtils.GetIndexConfig(module.Settings.Template); - - QueryBuilder queryBuilder = new QueryBuilder(indexConfig); - queryBuilder.Build(module.Settings.Query, true, UserInfo.UserID, DnnLanguageUtils.GetCurrentCultureCode(), UserInfo.Social.Roles.FromDnnRoles()); - RestQueryBuilder.MergeQuery(indexConfig, queryBuilder.Select, restSelect, DnnLanguageUtils.GetCurrentCultureCode()); - IDataSource ds = DataSourceManager.GetDataSource(module.Settings.Manifest.DataSource); - var dsContext = OpenContentUtils.CreateDataContext(module, UserInfo.UserID); + RestSelect restSelect = new RestSelect() + { + PageIndex = 0, + PageSize = 100000 + }; + if (!string.IsNullOrEmpty(filter)) + { + restSelect.Query = JsonConvert.DeserializeObject(filter); + } + if (!string.IsNullOrEmpty(sort)) + { + restSelect.Sort = JsonConvert.DeserializeObject>(sort); + } + IEnumerable dataList = new List(); + var module = OpenContentModuleConfig.Create(moduleId, tabId, PortalSettings); + var manifest = module.Settings.Template.Manifest; - if (string.IsNullOrEmpty(queryName)) + if (!module.HasAllUsersViewPermissions()) { - var dsItems = ds.GetAll(dsContext, queryBuilder.Select); - dataList = dsItems.Items; - filename = dsContext.Collection; + return Request.CreateResponse(HttpStatusCode.Unauthorized); } - else + string filename = queryName; + bool useLucene = module.Settings.Template.Manifest.Index; + if (useLucene) { - var qds = ds as IDataQueries; - var query = qds?.GetQueries(dsContext).SingleOrDefault(q => q.Name == queryName); - if (query != null) + var indexConfig = OpenContentUtils.GetIndexConfig(module.Settings.Template); + + QueryBuilder queryBuilder = new QueryBuilder(indexConfig); + queryBuilder.Build(module.Settings.Query, true, UserInfo.UserID, DnnLanguageUtils.GetCurrentCultureCode(), UserInfo.Social.Roles.FromDnnRoles()); + RestQueryBuilder.MergeQuery(indexConfig, queryBuilder.Select, restSelect, DnnLanguageUtils.GetCurrentCultureCode()); + IDataSource ds = DataSourceManager.GetDataSource(module.Settings.Manifest.DataSource); + var dsContext = OpenContentUtils.CreateDataContext(module, UserInfo.UserID); + + if (string.IsNullOrEmpty(queryName)) { - var dsItems = query.GetAll(dsContext, queryBuilder.Select); + var dsItems = ds.GetAll(dsContext, queryBuilder.Select); dataList = dsItems.Items; + filename = dsContext.Collection; + } + else + { + var qds = ds as IDataQueries; + var query = qds?.GetQueries(dsContext).SingleOrDefault(q => q.Name == queryName); + if (query != null) + { + var dsItems = query.GetAll(dsContext, queryBuilder.Select); + dataList = dsItems.Items; + } } } - } - var mf = new ModelFactoryMultiple(dataList, null, manifest, null, null, module); - dynamic model = mf.GetModelAsDictionary(true); + var mf = new ModelFactoryMultiple(dataList, null, manifest, null, null, module); + dynamic model = mf.GetModelAsDictionary(true); - var rssTemplate = new FileUri(module.Settings.TemplateDir, filename + "-excel.hbs"); - string source = rssTemplate.FileExists ? FileUriUtils.ReadFileFromDisk(rssTemplate) : GenerateTemplateFromModel(model, rssTemplate); - - HandlebarsEngine hbEngine = new HandlebarsEngine(); - string res = hbEngine.Execute(source, model); + var rssTemplate = new FileUri(module.Settings.TemplateDir, filename + "-excel.hbs"); + string source = rssTemplate.FileExists ? FileUriUtils.ReadFileFromDisk(rssTemplate) : GenerateTemplateFromModel(model, rssTemplate); - var fileBytes = ExcelUtils.CreateExcel(res); - return ExcelUtils.CreateExcelResponseMessage(filename + ".xlsx", fileBytes); + HandlebarsEngine hbEngine = new HandlebarsEngine(); + string res = hbEngine.Execute(source, model); + var fileBytes = ExcelUtils.CreateExcel(res); + return ExcelUtils.CreateExcelResponseMessage(filename + ".xlsx", fileBytes); + } + catch (Exception e) + { + App.Services.Logger.Error(e); + throw; + } } [AllowAnonymous] diff --git a/OpenContent/Components/FeatureController.cs b/OpenContent/Components/FeatureController.cs index 31a8b702..192d1e82 100644 --- a/OpenContent/Components/FeatureController.cs +++ b/OpenContent/Components/FeatureController.cs @@ -17,6 +17,7 @@ using System.Linq; using DotNetNuke.Common; using System; +using System.Collections; using DotNetNuke.Services.Search.Entities; using Newtonsoft.Json.Linq; using DotNetNuke.Entities.Portals; @@ -42,6 +43,11 @@ public string ExportModule(int moduleId) { string xml = ""; OpenContentController ctrl = new OpenContentController(PortalSettings.Current.PortalId); + + var tabModules = ModuleController.Instance.GetTabModulesByModule(moduleId); + + Hashtable moduleSettings = tabModules.Any() ? tabModules.First().ModuleSettings : new Hashtable(); + var items = ctrl.GetContents(moduleId); xml += ""; foreach (var item in items) @@ -52,6 +58,15 @@ public string ExportModule(int moduleId) xml += "" + XmlUtils.XMLEncode(item.Id) + ""; xml += ""; } + + foreach (DictionaryEntry moduleSetting in moduleSettings) + { + xml += ""; + xml += "" + XmlUtils.XMLEncode(moduleSetting.Key.ToString()) + ""; + xml += "" + XmlUtils.XMLEncode(moduleSetting.Value.ToString()) + ""; + xml += ""; + } + xml += ""; return xml; } @@ -83,6 +98,23 @@ public void ImportModule(int moduleId, string content, string version, int userI } } } + var settings = xml.SelectNodes("moduleSetting"); + if (settings != null) + { + foreach (XmlNode setting in settings) + { + XmlNode settingName = setting.SelectSingleNode("settingName"); + XmlNode settingValue = setting.SelectSingleNode("settingValue"); + + if (!string.IsNullOrEmpty(settingName?.InnerText)) + { + ModuleController.Instance.UpdateModuleSetting(moduleId, settingName.InnerText, settingValue?.InnerText ?? ""); + } + } + } + module = OpenContentModuleConfig.Create(moduleId, Null.NullInteger, PortalSettings.Current); + + LuceneUtils.ReIndexModuleData(module); } #region ModuleSearchBase diff --git a/OpenContent/Components/FileUploadController.cs b/OpenContent/Components/FileUploadController.cs index aae42682..6741bbd1 100644 --- a/OpenContent/Components/FileUploadController.cs +++ b/OpenContent/Components/FileUploadController.cs @@ -81,7 +81,8 @@ public HttpResponseMessage UploadEasyImage() } return new HttpResponseMessage { - Content = new StringContent(JsonConvert.SerializeObject(new ImageStatus{ + Content = new StringContent(JsonConvert.SerializeObject(new ImageStatus + { Default = statuses[0].url })) }; @@ -130,11 +131,20 @@ private void UploadWholeFile(HttpContextBase context, ICollection s if (IsAllowedExtension(fileName)) { bool? overwrite = null; + + var module = OpenContentModuleConfig.Create(ActiveModule, PortalSettings); if (!string.IsNullOrEmpty(context.Request.Form["overwrite"])) { overwrite = context.Request.Form["overwrite"] == "true"; } string uploadfolder = "OpenContent/Files/" + ActiveModule.ModuleID; + if (module.Settings.Manifest.DeleteFiles) + { + if (!string.IsNullOrEmpty(context.Request.Form["itemKey"])) + { + uploadfolder += "/" + context.Request.Form["itemKey"]; + } + } if (!string.IsNullOrEmpty(context.Request.Form["uploadfolder"])) { uploadfolder = context.Request.Form["uploadfolder"]; diff --git a/OpenContent/Components/Form/FormUtils.cs b/OpenContent/Components/Form/FormUtils.cs index 77c9da24..91c437e0 100644 --- a/OpenContent/Components/Form/FormUtils.cs +++ b/OpenContent/Components/Form/FormUtils.cs @@ -316,6 +316,8 @@ public static JObject FormSubmit(JObject form, SettingsDTO settings, JObject ite try { subject = hbs.Execute(notification.EmailSubject, data); + subject = HttpUtility.HtmlDecode(subject); + } catch (Exception ex) { diff --git a/OpenContent/Components/Handlebars/HandlebarsEngine.cs b/OpenContent/Components/Handlebars/HandlebarsEngine.cs index 5901e7de..d8b33401 100644 --- a/OpenContent/Components/Handlebars/HandlebarsEngine.cs +++ b/OpenContent/Components/Handlebars/HandlebarsEngine.cs @@ -16,6 +16,7 @@ using Satrabel.OpenContent.Components.Logging; using Newtonsoft.Json.Linq; using System.Text.RegularExpressions; +using DotNetNuke.Common.Utilities; namespace Satrabel.OpenContent.Components.Handlebars { @@ -1048,6 +1049,8 @@ private static void RegisterIfInHelper(IHandlebars hbs) } }); } + + private static readonly Regex RemoveInlineStylesRegEx = new Regex("", RegexOptions.Compiled | RegexOptions.Multiline); private static void RegisterConvertHtmlToTextHelper(HandlebarsDotNet.IHandlebars hbs) { hbs.RegisterHelper("convertHtmlToText", (writer, context, parameters) => @@ -1055,7 +1058,13 @@ private static void RegisterConvertHtmlToTextHelper(HandlebarsDotNet.IHandlebars try { string html = parameters[0].ToString(); - string res = DotNetNuke.Services.Mail.Mail.ConvertToText(html); + //string res = DotNetNuke.Services.Mail.Mail.ConvertToText(html); + + var formattedHtml = HtmlUtils.FormatText(html, true); + //var styleLessHtml = HtmlUtils.RemoveInlineStyle(formattedHtml); + var styleLessHtml = RemoveInlineStylesRegEx.Replace(formattedHtml, string.Empty); + string res = HtmlUtils.StripTags(styleLessHtml, true); + writer.WriteSafeString(res); } catch (Exception) diff --git a/OpenContent/Components/InitAPIController.cs b/OpenContent/Components/InitAPIController.cs index 21af8c82..729523fd 100644 --- a/OpenContent/Components/InitAPIController.cs +++ b/OpenContent/Components/InitAPIController.cs @@ -49,12 +49,12 @@ public List GetPortals() var listItems = new List(); foreach (var item in portals) { - var li = new PortalDto() - { - Text = item.PortalName, - PortalId= item.PortalID - }; - listItems.Add(li); + var li = new PortalDto() + { + Text = item.PortalName, + PortalId = item.PortalID + }; + listItems.Add(li); } return listItems.OrderBy(x => x.Text).ToList(); } @@ -82,7 +82,7 @@ public List GetModules() if (!tab.IsNeutralCulture && tab.CultureCode != DnnLanguageUtils.GetCurrentCultureCode()) { // skip other cultures - //continue; + //continue; } else { @@ -254,6 +254,15 @@ public ModuleStateDto SaveTemplate(SaveDto input) settings = ActiveModule.OpenContentSettings(); } } + // filter settings + var filterFilename = templateManifest.MainTemplateUri().PhysicalFullDirectory + "\\" + "filter-data.json"; + if (File.Exists(filterFilename)) + { + var settingContent = File.ReadAllText(filterFilename); + mc.UpdateModuleSetting(ActiveModule.ModuleID, "query", settingContent); + ActiveModule.ModuleSettings["query"] = settingContent; + settings = ActiveModule.OpenContentSettings(); + } bool defaultData = false; if (templateManifest.DataNeeded()) { diff --git a/OpenContent/Components/Lucene/Config/FieldConfigUtils.cs b/OpenContent/Components/Lucene/Config/FieldConfigUtils.cs index 112cb37e..355a21ae 100644 --- a/OpenContent/Components/Lucene/Config/FieldConfigUtils.cs +++ b/OpenContent/Components/Lucene/Config/FieldConfigUtils.cs @@ -7,6 +7,7 @@ using Newtonsoft.Json.Linq; using Satrabel.OpenContent.Components.Datasource.Search; using Satrabel.OpenContent.Components.FileIndexer; +using Satrabel.OpenContent.Components.Lucene.Mapping; namespace Satrabel.OpenContent.Components.Lucene.Config { @@ -99,6 +100,11 @@ public static SortRule CreateSortRule(FieldConfig parentFieldConfig, string cult var fieldConfig = GetField(parentFieldConfig, field); var cultureSuffix = fieldConfig != null && fieldConfig.MultiLanguage ? "." + cultureCode : string.Empty; var indexType = GetFieldType(fieldConfig != null ? fieldConfig.IndexType : string.Empty); + if (field == JsonMappingUtils.FIELD_TIMESTAMP) + { + indexType = FieldTypeEnum.DATETIME; + } + var rule = new SortRule() { Field = field + cultureSuffix, diff --git a/OpenContent/Components/Lucene/LuceneController.cs b/OpenContent/Components/Lucene/LuceneController.cs index b7c2bf7a..b540e516 100644 --- a/OpenContent/Components/Lucene/LuceneController.cs +++ b/OpenContent/Components/Lucene/LuceneController.cs @@ -32,7 +32,8 @@ public LuceneService Store private LuceneController() { - _serviceStoreInstance = new LuceneService(App.Config.LuceneIndexFolder, JsonMappingUtils.GetAnalyser()); + var lang = System.Configuration.ConfigurationManager.AppSettings["LuceneDefaultCulture"]; + _serviceStoreInstance = new LuceneService(App.Config.LuceneIndexFolder, JsonMappingUtils.GetAnalyser(lang)); } public static void ClearInstance() diff --git a/OpenContent/Components/Lucene/Mapping/JsonMappingUtils.cs b/OpenContent/Components/Lucene/Mapping/JsonMappingUtils.cs index ba0ffe24..99916d3c 100644 --- a/OpenContent/Components/Lucene/Mapping/JsonMappingUtils.cs +++ b/OpenContent/Components/Lucene/Mapping/JsonMappingUtils.cs @@ -74,14 +74,16 @@ public static Filter GetTypeFilter(string type, Query filter) return resultFilter; } - public static Analyzer GetAnalyser(string cultureCode="") + public static Analyzer GetAnalyser(string cultureCode = "") { - if (cultureCode.StartsWith("fr")) - return new FrenchAnalyzer(global::Lucene.Net.Util.Version.LUCENE_30); - else if (cultureCode.StartsWith("nl")) - return new DutchAnalyzer(global::Lucene.Net.Util.Version.LUCENE_30); - else - return new StandardAnalyzer(global::Lucene.Net.Util.Version.LUCENE_30); + if (!string.IsNullOrEmpty(cultureCode)) + { + if (cultureCode.StartsWith("fr")) + return new FrenchAnalyzer(global::Lucene.Net.Util.Version.LUCENE_30); + else if (cultureCode.StartsWith("nl")) + return new DutchAnalyzer(global::Lucene.Net.Util.Version.LUCENE_30); + } + return new StandardAnalyzer(global::Lucene.Net.Util.Version.LUCENE_30); } public static TermQuery CreateTypeQuery(string type) diff --git a/OpenContent/Components/Lucene/Mapping/JsonObjectMapper.cs b/OpenContent/Components/Lucene/Mapping/JsonObjectMapper.cs index 20920bbc..1f394ba5 100644 --- a/OpenContent/Components/Lucene/Mapping/JsonObjectMapper.cs +++ b/OpenContent/Components/Lucene/Mapping/JsonObjectMapper.cs @@ -210,13 +210,18 @@ private static void Add(Document doc, string prefix, JToken token, FieldConfig f } else { + + var val = SelectQueryDefinition.RemoveDiacritics(value.Value.ToString()); + val = val.Replace('-', ' '); // concider '-' as a space + val = val.Replace(',', ' '); // concider ',' as a space + //var val = LuceneUtils.CleanupText(value.Value.ToString()); if (index) { - doc.Add(new Field(prefix, value.Value.ToString(), Field.Store.NO, Field.Index.ANALYZED)); + doc.Add(new Field(prefix, val, Field.Store.NO, Field.Index.ANALYZED)); } if (sort) { - doc.Add(new Field("@" + prefix, Truncate(value.Value.ToString(), 100), Field.Store.NO, Field.Index.NOT_ANALYZED)); + doc.Add(new Field("@" + prefix, Truncate(val, 100), Field.Store.NO, Field.Index.NOT_ANALYZED)); } } break; diff --git a/OpenContent/Components/Manifest/Manifest.cs b/OpenContent/Components/Manifest/Manifest.cs index 4003699f..a8d90792 100644 --- a/OpenContent/Components/Manifest/Manifest.cs +++ b/OpenContent/Components/Manifest/Manifest.cs @@ -73,6 +73,10 @@ public Dictionary AdditionalDataDefinition [JsonProperty(PropertyName = "advanced")] public bool Advanced { get; set; } + [JsonProperty(PropertyName = "deleteFiles")] + public bool DeleteFiles { get; set; } + + public bool HasTemplates => (Templates != null); public FolderUri ManifestDir { get; set; } diff --git a/OpenContent/Components/Manifest/TemplateManifest.cs b/OpenContent/Components/Manifest/TemplateManifest.cs index ad777964..2658f7e3 100644 --- a/OpenContent/Components/Manifest/TemplateManifest.cs +++ b/OpenContent/Components/Manifest/TemplateManifest.cs @@ -35,6 +35,9 @@ public class TemplateManifest [JsonProperty(PropertyName = "collection")] public string Collection { get; set; } = "Items"; + [JsonProperty(PropertyName = "disableEdit")] + public bool DisableEdit { get; set; } + public bool IsListTemplate => Type == "multiple"; public TemplateKey Key { get; private set; } diff --git a/OpenContent/Components/OpenContentAPIController.cs b/OpenContent/Components/OpenContentAPIController.cs index bc79738b..dc9b862a 100644 --- a/OpenContent/Components/OpenContentAPIController.cs +++ b/OpenContent/Components/OpenContentAPIController.cs @@ -27,6 +27,8 @@ using Satrabel.OpenContent.Components.Manifest; using Satrabel.OpenContent.Components.Datasource; using Satrabel.OpenContent.Components.Dnn; +using DotNetNuke.Services.FileSystem; +using Satrabel.OpenContent.Components.Common; #endregion @@ -94,8 +96,14 @@ public HttpResponseMessage Edit(string id) } json["options"]["form"]["buttons"] = newButtons; } - if (dsItem != null) + string itemKey; + if (dsItem == null) + { + itemKey= ObjectId.NewObjectId().ToString(); + } + else { + itemKey = dsItem.Key; json["data"] = dsItem.Data; if (json["schema"]["properties"]["ModuleTitle"] is JObject) { @@ -125,6 +133,7 @@ public HttpResponseMessage Edit(string id) context["alpacaCulture"] = AlpacaEngine.AlpacaCulture(currentLocale.Code); context["bootstrap"] = App.Services.CreateGlobalSettingsRepository(PortalSettings.PortalId).GetEditLayout() != AlpacaLayoutEnum.DNN; context["horizontal"] = App.Services.CreateGlobalSettingsRepository(PortalSettings.PortalId).GetEditLayout() == AlpacaLayoutEnum.BootstrapHorizontal; + context["itemKey"] = itemKey; json["context"] = context; //todo: can't we do some of these checks at the beginning of this method to fail faster? @@ -669,14 +678,17 @@ public HttpResponseMessage ReOrder(List ids) return Request.CreateResponse(HttpStatusCode.OK, new { isValid = true }); int i = 1; + string errorOccured = ""; foreach (var id in ids) { if (id == "-1") continue; // ignore items explicitly marked with id -1; var dsItem = ds.Get(dsContext, id); if (dsItem == null) { - Utils.DebuggerBreak(); // this should never happen: investigate! - throw new Exception($"Reorder failed. Unknown item {id}. Reindex module and try again."); + Utils.DebuggerBreak(); // item not found. investigate! + errorOccured = $"Reorder failed. Unknown item {id}. Reindex module and try again."; + App.Services.Logger.Error(errorOccured); + continue; } var json = dsItem.Data; @@ -684,7 +696,7 @@ public HttpResponseMessage ReOrder(List ids) { #region Normalize irregulatities with SortIndex field // if old data-format (single-language) detected. Migrate to ML version. - if (json["SortIndex"] == null || json["SortIndex"].Type != JTokenType.Object) + if (json["SortIndex"] == null || json["SortIndex"].Type != JTokenType.Object) { json["SortIndex"] = new JObject(); } @@ -710,7 +722,8 @@ public HttpResponseMessage ReOrder(List ids) } return Request.CreateResponse(HttpStatusCode.OK, new { - isValid = true + isValid = string.IsNullOrEmpty(errorOccured), + errorMsg = errorOccured }); } catch (Exception exc) @@ -838,6 +851,35 @@ public HttpResponseMessage Delete(JObject json) ds.Delete(dsContext, content); } App.Services.CacheAdapter.SyncronizeCache(module); + + if (module.IsListMode() && module.Settings.Manifest.DeleteFiles) + { + string uploadfolder = "OpenContent/Files/" + ActiveModule.ModuleID; + if (module.IsListMode()) + { + uploadfolder += "/" + content.Key;// json["_id"].ToString(); + } + var folderManager = FolderManager.Instance; + var fileManager = FileManager.Instance; + var moduleFolder = folderManager.GetFolder(PortalSettings.PortalId, uploadfolder); + var files = folderManager.GetFiles(moduleFolder); + fileManager.DeleteFiles(files); + folderManager.DeleteFolder(moduleFolder); + + uploadfolder = "OpenContent/Cropped/" + ActiveModule.ModuleID; + if (module.IsListMode()) + { + uploadfolder += "/" + content.Key;// json["_id"].ToString(); + } + moduleFolder = folderManager.GetFolder(PortalSettings.PortalId, uploadfolder); + if (moduleFolder != null) + { + files = folderManager.GetFiles(moduleFolder); + fileManager.DeleteFiles(files); + folderManager.DeleteFolder(moduleFolder); + } + } + return Request.CreateResponse(HttpStatusCode.OK, ""); } catch (Exception exc) diff --git a/OpenContent/Components/Render/ModelFactoryBase.cs b/OpenContent/Components/Render/ModelFactoryBase.cs index ce50d0f4..ca46ebf9 100644 --- a/OpenContent/Components/Render/ModelFactoryBase.cs +++ b/OpenContent/Components/Render/ModelFactoryBase.cs @@ -12,6 +12,7 @@ using Satrabel.OpenContent.Components.TemplateHelpers; using System; using System.Collections.Generic; +using System.Collections.Specialized; using System.Diagnostics; using System.IO; using System.Linq; @@ -195,7 +196,7 @@ protected void EnhanceSelect2(JObject model, bool onlyData) - protected void ExtendModel(JObject model, bool onlyData, bool onlyMainData) + protected void ExtendModel(JObject model, bool onlyData, bool onlyMainData, string id=null) { if (_module.CanvasUnavailable) onlyData = true; @@ -224,7 +225,13 @@ protected void ExtendModel(JObject model, bool onlyData, bool onlyMainData) var indexConfig = OpenContentUtils.GetIndexConfig(_module.Settings.TemplateDir, item.Key); QueryBuilder queryBuilder = new QueryBuilder(indexConfig); var u = PortalSettings.Current.UserInfo; - queryBuilder.Build(item.Value.Query, true, u.UserID, DnnLanguageUtils.GetCurrentCultureCode(), u.Social.Roles.FromDnnRoles()); + NameValueCollection queryString = null; + if (item.Value.Query["RelatedField"] != null) + { + queryString = new NameValueCollection(); + queryString.Add(item.Value.Query["RelatedField"].ToString(), id); + } + queryBuilder.Build(item.Value.Query, true, u.UserID, DnnLanguageUtils.GetCurrentCultureCode(), u.Social.Roles.FromDnnRoles(), queryString); select = queryBuilder.Select; } IDataItems dataItems = _ds.GetAll(dsColContext, select); @@ -258,10 +265,11 @@ protected void ExtendModel(JObject model, bool onlyData, bool onlyMainData) try { var jsonSettings = JToken.Parse(_settingsJson); - if (DnnLanguageUtils.GetPortalLocales(_portalId).Count > 1) - { - JsonUtils.SimplifyJson(jsonSettings, GetCurrentCultureCode()); - } + //if (DnnLanguageUtils.GetPortalLocales(_portalId).Count > 1) + //{ + // JsonUtils.SimplifyJson(jsonSettings, GetCurrentCultureCode()); + //} + JsonUtils.SimplifyJson(jsonSettings, GetCurrentCultureCode()); model["Settings"] = jsonSettings; } catch (Exception ex) @@ -288,7 +296,7 @@ protected void ExtendModel(JObject model, bool onlyData, bool onlyMainData) context["ModuleId"] = _module.ViewModule.ModuleId; context["GoogleApiKey"] = App.Services.CreateGlobalSettingsRepository(_portalId).GetGoogleApiKey(); context["ModuleTitle"] = _module.ViewModule.ModuleTitle; - var editIsAllowed = !_manifest.DisableEdit && IsEditAllowed(-1); + var editIsAllowed = !_manifest.DisableEdit && !_templateManifest.DisableEdit && IsEditAllowed(-1); context["IsEditable"] = editIsAllowed; //allowed to edit the item or list (meaning allow Add) context["IsEditMode"] = IsEditMode; context["PortalId"] = _portalId; @@ -296,6 +304,9 @@ protected void ExtendModel(JObject model, bool onlyData, bool onlyMainData) context["HomeDirectory"] = _module.HomeDirectory; context["HTTPAlias"] = _module.HostName; context["PortalName"] = _module.PortalName; + context["TemplatePath"] = _module.Settings.TemplateDir.UrlFolder; + context["TemplateName"] = (String.IsNullOrEmpty(_manifest.Title) ? Path.GetFileName(_templateManifest.MainTemplateUri().FolderPath) : _manifest.Title) +" - "+ (string.IsNullOrEmpty(_templateManifest.Title) ? _templateManifest.Key.ShortKey : _templateManifest.Title); + //context["TemplateName"] = _templateManifest.MainTemplateUri().UrlFilePath ; } } @@ -304,6 +315,7 @@ private JObject GetAdditionalData(bool onlyData) if (_additionalData == null && _manifest.AdditionalDataDefined()) { _additionalData = new JObject(); + var _additionalDataContext = _additionalData["Context"] = new JObject(); foreach (var item in _manifest.AdditionalDataDefinition) { var dataManifest = item.Value; @@ -319,12 +331,17 @@ private JObject GetAdditionalData(bool onlyData) additionalDataJson = json; //optionally add editurl for AdditionalData. Only for Single items (not arrays) - if (!onlyData && json is JObject && IsEditMode) + if (!onlyData && json is JObject && IsEditMode) { var context = new JObject(); context["EditUrl"] = GetAdditionalDataEditUrl(item.Key); additionalDataJson["Context"] = context; } + if (!onlyData) + { + var context = _additionalDataContext[item.Value.ModelKey ?? item.Key] = new JObject(); + context["EditUrl"] = GetAdditionalDataEditUrl(item.Key); + } } if (!App.Services.CreateGlobalSettingsRepository(_portalId).GetLegacyHandlebars()) _additionalData[(item.Value.ModelKey ?? item.Key)] = additionalDataJson; diff --git a/OpenContent/Components/Render/ModelFactoryMultiple.cs b/OpenContent/Components/Render/ModelFactoryMultiple.cs index 5b972131..c4410bd7 100644 --- a/OpenContent/Components/Render/ModelFactoryMultiple.cs +++ b/OpenContent/Components/Render/ModelFactoryMultiple.cs @@ -103,7 +103,7 @@ public override JToken GetModelAsJson(bool onlyData = false, bool onlyMainData = } else { - var editStatus = !_manifest.DisableEdit && IsEditAllowed(item.CreatedByUserId); + var editStatus = !_manifest.DisableEdit && !_templateManifest.DisableEdit && IsEditAllowed(item.CreatedByUserId); context["IsEditable"] = editStatus; if (HasEditPermissions(item.CreatedByUserId)) { diff --git a/OpenContent/Components/Render/ModelFactorySingle.cs b/OpenContent/Components/Render/ModelFactorySingle.cs index 98d4418c..347198c5 100644 --- a/OpenContent/Components/Render/ModelFactorySingle.cs +++ b/OpenContent/Components/Render/ModelFactorySingle.cs @@ -39,7 +39,7 @@ public override JToken GetModelAsJson(bool onlyData = false, bool onlyMainData = var model = _dataJson as JObject; var enhancedModel = new JObject(); ExtendSchemaOptions(enhancedModel, onlyData || onlyMainData); - ExtendModel(enhancedModel, onlyData, onlyMainData); + ExtendModel(enhancedModel, onlyData, onlyMainData, _data?.Id); ExtendModelSingle(enhancedModel); EnhanceSelect2(model, onlyData); EnhanceImages(model); @@ -57,9 +57,12 @@ private void ExtendModelSingle(JObject model) { context["DetailUrl"] = GenerateDetailUrl(_data, model, _manifest, GetCurrentCultureCode(), _detailTabId); context["Id"] = _data.Id; - var editIsAllowed = !_manifest.DisableEdit && IsEditAllowed(_data.CreatedByUserId); + var editIsAllowed = !_manifest.DisableEdit && !_templateManifest.DisableEdit && IsEditAllowed(_data.CreatedByUserId); context["EditUrl"] = editIsAllowed ? _module.EditUrl("id", _data.Id, _module.ViewModule.ModuleId) : ""; + + } + //context["Comments"] = "comments..."; } } } diff --git a/OpenContent/Components/Render/RenderEngine.cs b/OpenContent/Components/Render/RenderEngine.cs index 8edbf33f..f65c305d 100644 --- a/OpenContent/Components/Render/RenderEngine.cs +++ b/OpenContent/Components/Render/RenderEngine.cs @@ -695,7 +695,7 @@ public List GetMenuActions() bool isDetailPageRequest = _renderinfo.IsDetailPageRequest; //Add item / Edit Item - if (templateDefined && template.DataNeeded() && !_settings.Manifest.DisableEdit) + if (templateDefined && template.DataNeeded() && !_settings.Manifest.DisableEdit && !template.DisableEdit) { string title = App.Services.Localizer.GetString(isListPageRequest ? "Add.Action" : "Edit.Action", ResourceFile); if (!string.IsNullOrEmpty(_settings.Manifest.Title)) @@ -714,7 +714,7 @@ public List GetMenuActions() } //Add AdditionalData manage actions - if (templateDefined && template.Manifest.AdditionalDataDefined() && !_settings.Manifest.DisableEdit) + if (templateDefined && template.Manifest.AdditionalDataDefined() && !_settings.Manifest.DisableEdit && !template.DisableEdit) { foreach (var addData in template.Manifest.AdditionalDataDefinition) { @@ -865,7 +865,7 @@ public List GetMenuActions() //Edit Raw Data if (templateDefined && _settings.Manifest != null && - (template.DataNeeded() || template.SettingsNeeded() || template.Manifest.AdditionalDataDefined()) && !_settings.Manifest.DisableEdit) + (template.DataNeeded() || template.SettingsNeeded() || template.Manifest.AdditionalDataDefined()) && !_settings.Manifest.DisableEdit && !template.DisableEdit) { actions.Add( new MenuAction( diff --git a/OpenContent/Components/Settings/OpenContentSettings.cs b/OpenContent/Components/Settings/OpenContentSettings.cs index 907f70f9..70cba820 100644 --- a/OpenContent/Components/Settings/OpenContentSettings.cs +++ b/OpenContent/Components/Settings/OpenContentSettings.cs @@ -45,7 +45,7 @@ public OpenContentSettings(ComponentSettingsInfo moduleSettings) /// public Manifest.Manifest Manifest { get; } - public FolderUri TemplateDir => TemplateKey.TemplateDir; + public FolderUri TemplateDir => TemplateKey?.TemplateDir; public string Data { get; } diff --git a/OpenContent/Components/TemplateHelpers/Images/ImageHelper.cs b/OpenContent/Components/TemplateHelpers/Images/ImageHelper.cs index dcdc9d9c..3a8aeb25 100644 --- a/OpenContent/Components/TemplateHelpers/Images/ImageHelper.cs +++ b/OpenContent/Components/TemplateHelpers/Images/ImageHelper.cs @@ -16,6 +16,25 @@ namespace Satrabel.OpenContent.Components.TemplateHelpers { public static class ImageHelper { + //static bool DnnImageHandlerExist = AppDomain.CurrentDomain.GetAssemblies().Any(a => a.FullName.StartsWith(assemblyName) == "DotNetNuke.Services.GeneratedImage.DnnImageHandler, DotNetNuke"); + + //static bool DnnImageHandlerExist = (from assembly in AppDomain.CurrentDomain.GetAssemblies() + // from type in assembly.GetTypes() + // where type.Name == "DotNetNuke.Services.GeneratedImage.DnnImageHandler, DotNetNuke" + // select type).Any(); + + + static bool DnnImageHandlerExist = Type.GetType("DotNetNuke.Services.GeneratedImage.DnnImageHandler, DotNetNuke") != null; + + //static bool ImageProcessorExist = AppDomain.CurrentDomain.GetAssemblies().Any(a => a.FullName == "ImageProcessor.Web.HttpModules.ImageProcessingModule, ImageProcessor.Web"); + + //static bool ImageProcessorExist = (from assembly in AppDomain.CurrentDomain.GetAssemblies() + // from type in assembly.GetTypes() + // where type.Name == "ImageProcessor.Web.HttpModules.ImageProcessingModule, ImageProcessor.Web" + // select type).Any(); + + static bool ImageProcessorExist = Type.GetType("ImageProcessor.Web.HttpModules.ImageProcessingModule, ImageProcessor.Web") != null; + public static bool IsImageFile(this IFileInfo file) { return (Globals.glbImageFileTypes + ",").IndexOf(file.Extension.ToLower().Replace(".", "") + ",") > -1; @@ -91,7 +110,21 @@ public static string GetImageUrl(IFileInfo file, Ratio requestedCropRatio) if (ModuleDefinitionController.GetModuleDefinitionByFriendlyName("OpenFiles") == null) { - return DnnFileUtils.ToUrl(file); + var fileurl = DnnFileUtils.ToUrl(file); + if (!fileurl.Contains("LinkClick")) + { + if (ImageProcessorExist) + { + fileurl = fileurl.RemoveQueryParams(); + return fileurl.AppendQueryParams($"width={requestedCropRatio.Width}&height={requestedCropRatio.Height}&mode=crop"); + } + else if (DnnImageHandlerExist) + { + fileurl = fileurl.RemoveQueryParams(); + return $"/DnnImageHandler.ashx?mode=file&file={fileurl}&resizemode=Crop&w={requestedCropRatio.Width}&h={requestedCropRatio.Height}"; + } + } + return fileurl; } var url = file.ToLinkClickSafeUrl(); url = url.RemoveQueryParams(); //imageprocessor does not tolerate unknow querystrings (for security reasons). Remove them diff --git a/OpenContent/Components/TemplateHelpers/Images/ImageUriFactory.cs b/OpenContent/Components/TemplateHelpers/Images/ImageUriFactory.cs index 328579e3..21302901 100644 --- a/OpenContent/Components/TemplateHelpers/Images/ImageUriFactory.cs +++ b/OpenContent/Components/TemplateHelpers/Images/ImageUriFactory.cs @@ -17,11 +17,19 @@ public static ImageUri CreateImageUri(dynamic imageInfo) { if (imageInfo?["ImageId"] != null) { - retval = CreateImageUri(Convert.ToString(imageInfo["ImageId"])); //it might be an enhanced image object + retval = CreateImageUri(Convert.ToString(imageInfo["ImageId"])); // it might be an enhanced image object + } + else if (imageInfo?["url"] != null) + { + retval = CreateImageUri(Convert.ToString(imageInfo["url"])); // it might be an imageX object + } + else if (imageInfo?["id"] != null) + { + retval = CreateImageUri(Convert.ToString(imageInfo["id"])); // it might be an imageX object } else { - retval = CreateImageUri(Convert.ToString(imageInfo)); //it might be just the image Id + retval = CreateImageUri(Convert.ToString(imageInfo)); // it might be just the image Id } } catch (Exception ex) diff --git a/OpenContent/Components/TemplateHelpers/RazorUtils.cs b/OpenContent/Components/TemplateHelpers/RazorUtils.cs index 4afe56b6..1fbd0235 100644 --- a/OpenContent/Components/TemplateHelpers/RazorUtils.cs +++ b/OpenContent/Components/TemplateHelpers/RazorUtils.cs @@ -1,5 +1,5 @@ using System; -using System.Diagnostics; +using System.Collections.Generic; using System.Globalization; using System.Text; @@ -48,6 +48,25 @@ public static string ProtectEmail(this string email, string subject = "", string return result; } + /// + /// Replace all occurences of a set of email addresses with their protected mailto version + /// + /// a list of email addresses + /// an html string in which we replace all the given email addresses with there protected mailto version + /// + public static string ProtectEmails(IEnumerable emailaddresses, string content) + { + var retval = content; + foreach (var emailaddress in emailaddresses) + { + if (retval.Contains(emailaddress)) + { + retval = retval.Replace(emailaddress, emailaddress.ProtectEmail()); + } + } + return retval; + } + /// /// Formats the date time, just like the HandleBarHelper formatDateTime does. /// diff --git a/OpenContent/Components/Utils/OpenContentUtils.cs b/OpenContent/Components/Utils/OpenContentUtils.cs index 429184c5..a8be462b 100644 --- a/OpenContent/Components/Utils/OpenContentUtils.cs +++ b/OpenContent/Components/Utils/OpenContentUtils.cs @@ -60,6 +60,13 @@ public static string GetSkinTemplateFolder(PortalSettings portalSettings, string return SkinPath + moduleSubDir + "/Templates/"; } + public static string GetHostTemplateFolder(PortalSettings portalSettings, string moduleSubDir) + { + var hostPath = "~/Portals/_Default/"; + + return hostPath + moduleSubDir + "/Templates/"; + } + public static List GetTemplates(PortalSettings portalSettings, int moduleId, string selectedTemplate, string moduleSubDir) { return GetTemplates(portalSettings, moduleId, new FileUri(selectedTemplate), moduleSubDir); @@ -153,7 +160,7 @@ public static List ListOfTemplatesFiles(PortalSettings portalSettings, { FileUri manifestFileUri = FileUri.FromPath(manifestFile); var manifest = ManifestUtils.LoadManifestFileFromCacheOrDisk(manifestFileUri); - if (manifest != null && manifest.HasTemplates ) + if (manifest != null && manifest.HasTemplates) { manifestTemplateFound = true; if (advanced || !manifest.Advanced) @@ -213,86 +220,100 @@ public static List ListOfTemplatesFiles(PortalSettings portalSettings, //if (!string.IsNullOrEmpty(portalSettings.ActiveTab.SkinPath)) { basePath = HostingEnvironment.MapPath(GetSkinTemplateFolder(portalSettings, moduleSubDir)); - if (Directory.Exists(basePath)) + + dirs = GetDirs(selectedTemplate, otherModuleTemplate, advanced, basePath, dirs, lst, "Skin"); + } + // Host + { + basePath = HostingEnvironment.MapPath(GetHostTemplateFolder(portalSettings, moduleSubDir)); + dirs = GetDirs(selectedTemplate, otherModuleTemplate, advanced, basePath, dirs, lst, "Host"); + } + return lst; + } + + private static string[] GetDirs(TemplateManifest selectedTemplate, FileUri otherModuleTemplate, bool advanced, string basePath, string[] dirs, List lst, string folderType) + { + if (Directory.Exists(basePath)) + { + dirs = Directory.GetDirectories(basePath); + if (otherModuleTemplate != null /*&& */ ) { - dirs = Directory.GetDirectories(basePath); - if (otherModuleTemplate != null /*&& */ ) + var selDir = otherModuleTemplate.PhysicalFullDirectory; + if (!dirs.Contains(selDir)) { - var selDir = otherModuleTemplate.PhysicalFullDirectory; - if (!dirs.Contains(selDir)) - { - selDir = Path.GetDirectoryName(selDir); - } - if (dirs.Contains(selDir)) - dirs = new string[] { selDir }; - else - dirs = new string[] { }; + selDir = Path.GetDirectoryName(selDir); } + if (dirs.Contains(selDir)) + dirs = new string[] { selDir }; + else + dirs = new string[] { }; + } - foreach (var dir in dirs) - { - string templateCat = "Skin"; + foreach (var dir in dirs) + { + string templateCat = folderType; - IEnumerable files = Directory.EnumerateFiles(dir, "*.*", SearchOption.AllDirectories); - IEnumerable manifestfiles = files.Where(s => s.EndsWith("manifest.json")); - var manifestTemplateFound = false; + IEnumerable files = Directory.EnumerateFiles(dir, "*.*", SearchOption.AllDirectories); + IEnumerable manifestfiles = files.Where(s => s.EndsWith("manifest.json")); + var manifestTemplateFound = false; - if (manifestfiles.Any()) + if (manifestfiles.Any()) + { + foreach (string manifestFile in manifestfiles) { - foreach (string manifestFile in manifestfiles) + FileUri manifestFileUri = FileUri.FromPath(manifestFile); + var manifest = ManifestUtils.LoadManifestFileFromCacheOrDisk(manifestFileUri); + if (manifest != null && manifest.HasTemplates) { - FileUri manifestFileUri = FileUri.FromPath(manifestFile); - var manifest = ManifestUtils.LoadManifestFileFromCacheOrDisk(manifestFileUri); - if (manifest != null && manifest.HasTemplates) + manifestTemplateFound = true; + foreach (var template in manifest.Templates) { - manifestTemplateFound = true; - foreach (var template in manifest.Templates) + FileUri templateUri = new FileUri(manifestFileUri.FolderPath, template.Key); + string templateName = Path.GetDirectoryName(manifestFile).Substring(basePath.Length).Replace("\\", " / "); + if (!String.IsNullOrEmpty(template.Value.Title)) + { + if (advanced) + templateName = templateName + " - " + template.Value.Title; + } + var item = new ListItem((templateCat == "Site" ? "" : templateCat + " : ") + templateName, templateUri.FilePath); + if (selectedTemplate != null && templateUri.FilePath.ToLowerInvariant() == selectedTemplate.Key.ToString().ToLowerInvariant()) { - FileUri templateUri = new FileUri(manifestFileUri.FolderPath, template.Key); - string templateName = Path.GetDirectoryName(manifestFile).Substring(basePath.Length).Replace("\\", " / "); - if (!String.IsNullOrEmpty(template.Value.Title)) - { - if (advanced) - templateName = templateName + " - " + template.Value.Title; - } - var item = new ListItem((templateCat == "Site" ? "" : templateCat + " : ") + templateName, templateUri.FilePath); - if (selectedTemplate != null && templateUri.FilePath.ToLowerInvariant() == selectedTemplate.Key.ToString().ToLowerInvariant()) - { - item.Selected = true; - } - lst.Add(item); - if (!advanced) break; + item.Selected = true; } + lst.Add(item); + if (!advanced) break; } } } - if (!manifestTemplateFound) + } + if (!manifestTemplateFound) + { + var scriptfiles = + Directory.EnumerateFiles(dir, "*.*", SearchOption.AllDirectories) + .Where(s => s.EndsWith(".cshtml") || s.EndsWith(".vbhtml") || s.EndsWith(".hbs")); + foreach (string script in scriptfiles) { - var scriptfiles = - Directory.EnumerateFiles(dir, "*.*", SearchOption.AllDirectories) - .Where(s => s.EndsWith(".cshtml") || s.EndsWith(".vbhtml") || s.EndsWith(".hbs")); - foreach (string script in scriptfiles) + string scriptName = script.Remove(script.LastIndexOf(".")).Replace(basePath, ""); + if (scriptName.ToLower().EndsWith("template")) scriptName = scriptName.Remove(scriptName.LastIndexOf("\\")); + else scriptName = scriptName.Replace("\\", " - "); + + FileUri templateUri = FileUri.FromPath(script); + var item = new ListItem(templateCat + " : " + scriptName, templateUri.FilePath); + if (selectedTemplate != null + && templateUri.FilePath.ToLowerInvariant() == selectedTemplate.Key.ToString().ToLowerInvariant()) { - string scriptName = script.Remove(script.LastIndexOf(".")).Replace(basePath, ""); - if (scriptName.ToLower().EndsWith("template")) scriptName = scriptName.Remove(scriptName.LastIndexOf("\\")); - else scriptName = scriptName.Replace("\\", " - "); - - FileUri templateUri = FileUri.FromPath(script); - var item = new ListItem(templateCat + " : " + scriptName, templateUri.FilePath); - if (selectedTemplate != null - && templateUri.FilePath.ToLowerInvariant() == selectedTemplate.Key.ToString().ToLowerInvariant()) - { - item.Selected = true; - } - lst.Add(item); + item.Selected = true; } + lst.Add(item); } } - } + } - return lst; + + return dirs; } + public static List GetTemplates(PortalSettings portalSettings, int moduleId, TemplateManifest selectedTemplate, string moduleSubDir) { string basePath = HostingEnvironment.MapPath(GetSiteTemplateFolder(portalSettings, moduleSubDir)); @@ -352,6 +373,25 @@ public static List GetTemplates(PortalSettings portalSettings, int mod } } } + { + basePath = HostingEnvironment.MapPath(GetHostTemplateFolder(portalSettings, moduleSubDir)); + if (Directory.Exists(basePath)) + { + foreach (var dir in Directory.GetDirectories(basePath)) + { + string templateCat = "Host"; + string scriptName = dir; + scriptName = templateCat + ":" + scriptName.Substring(scriptName.LastIndexOf("\\") + 1); + string scriptPath = FolderUri.ReverseMapPath(dir); + var item = new ListItem(scriptName, scriptPath); + if (selectedTemplate != null && scriptPath.ToLowerInvariant() == selectedTemplate.Key.ToString().ToLowerInvariant()) + { + item.Selected = true; + } + lst.Add(item); + } + } + } return lst; } @@ -512,9 +552,9 @@ public static DataSourceContext CreateDataContext(OpenContentModuleConfig module TabId = module.ViewModule.TabId, TabModuleId = module.ViewModule.TabModuleId, ModuleId = module.DataModule.ModuleId, - TemplateFolder = module.Settings.TemplateDir.FolderPath, + TemplateFolder = module.Settings.TemplateDir?.FolderPath, UserId = userId, - Config = module.Settings.Manifest.DataSourceConfig, + Config = module.Settings.Manifest?.DataSourceConfig, Index = template?.Manifest?.Index ?? false, Options = options, Single = single, diff --git a/OpenContent/Edit.ascx b/OpenContent/Edit.ascx index e1aadedf..3a676473 100644 --- a/OpenContent/Edit.ascx +++ b/OpenContent/Edit.ascx @@ -4,7 +4,7 @@
    - +
  • @@ -21,6 +21,11 @@
+