public void Constructor_ShouldAcceptNullValues() { ContentVersion contentVersion = new ContentVersion(null, null, VersionStatus.NotCreated, DateTime.MinValue, null, null, int.MinValue, null, false, false); Assert.IsNotNull(contentVersion); }
public async Task <string> GetContentTreeId(ContentVersion version) { return(await GetContentTreeId(version.ContentType, version.ContentId, version.VersionCode)); }
public async Task <ContentTree> CreateContentTree(ContentVersion info) { return(await CreateContentTree(info.ContentType, info.ContentId, info.VersionCode)); }
public async Task PublishDraftVersion(ContentVersion version) { await PublishDraftVersion(version.ContentType, version.ContentId, version.VersionCode); }
public async Task DeleteVersion(ContentVersion version) { await DeleteVersion(version.ContentType, version.ContentId, version.VersionCode); }
public ContentVersionModifiedEvent(Content content, ContentVersion contentVersion) : base() { Content = content; ContentVersion = contentVersion; }
private void SeedHomePage(string homePageId) { // init version & content tree var publishedVersion = new ContentVersion { ContentId = homePageId, ContentType = HtmlDbSeedConstants.ContentType_SitePage, VersionLabel = "Master Page Content Added", UserId = "admin", Status = ContentStatus.Published, }; var contentTree = new ContentTree(publishedVersion); _dbContext.ContentVersions.Add(publishedVersion); _dbContext.ContentTrees.Add(contentTree); // styles var topImageStyle = new ContentStyle { FullWidth = true, BackgroundClass = SiteTemplateConstants.Backgrounds.Default, }; var topGridStyle = new ContentStyle { BackgroundClass = SiteTemplateConstants.Backgrounds.Default, PaddingTop = SiteTemplateConstants.RootContentPaddingTop, PaddingBottom = SiteTemplateConstants.RootContentPaddingBottom }; var heroUnitStyle = new ContentStyle { BackgroundClass = SiteTemplateConstants.Backgrounds.Fancy, PaddingTop = SiteTemplateConstants.RootContentPaddingTop, PaddingBottom = SiteTemplateConstants.RootContentPaddingBottom }; var bottomGridStyle = new ContentStyle { BackgroundClass = SiteTemplateConstants.Backgrounds.Contrast, PaddingTop = SiteTemplateConstants.RootContentPaddingTop, PaddingBottom = SiteTemplateConstants.RootContentPaddingBottom }; // content nodes var homePageContentNodes = new ContentNode[] { // full width zone with image new ContentNode(topImageStyle) { Id = Guid.NewGuid().ToString(), ContentTreeId = contentTree.Id, Zone = "body", Index = 0, WidgetId = HtmlDbSeedConstants.WidgetId_Image_InspirationImageMain, WidgetType = "image", ViewId = "image-fitted", Locked = false, }, // 4 images in a grid new ContentNode(topGridStyle) { Id = Guid.NewGuid().ToString(), ContentTreeId = contentTree.Id, ParentId = null, Zone = "body", Index = 1, WidgetId = null, WidgetType = "zone", ViewId = "zone-4", Locked = false, ChildNodes = new ContentNode[] { new ContentNode { Id = Guid.NewGuid().ToString(), ContentTreeId = contentTree.Id, Zone = "cell-1", Index = 0, WidgetId = HtmlDbSeedConstants.WidgetId_Image_InspirationImage1, WidgetType = "image", ViewId = "image-fitted", Locked = false }, new ContentNode { Id = Guid.NewGuid().ToString(), ContentTreeId = contentTree.Id, Zone = "cell-2", Index = 1, WidgetId = HtmlDbSeedConstants.WidgetId_Image_InspirationImage2, WidgetType = "image", ViewId = "image-fitted", Locked = false }, new ContentNode { Id = Guid.NewGuid().ToString(), ContentTreeId = contentTree.Id, Zone = "cell-3", Index = 2, WidgetId = HtmlDbSeedConstants.WidgetId_Image_InspirationImage3, WidgetType = "image", ViewId = "image-fitted", Locked = false }, new ContentNode { Id = Guid.NewGuid().ToString(), ContentTreeId = contentTree.Id, Zone = "cell-4", Index = 3, WidgetId = HtmlDbSeedConstants.WidgetId_Image_InspirationImage4, WidgetType = "image", ViewId = "image-fitted", Locked = false } } }, // Hero Unit new ContentNode(heroUnitStyle) { Id = Guid.NewGuid().ToString(), ContentTreeId = contentTree.Id, ParentId = null, Zone = "body", Index = 2, WidgetId = null, WidgetType = "zone", ViewId = "zone-1", Locked = false, ChildNodes = new ContentNode[] { new ContentNode { Id = Guid.NewGuid().ToString(), ContentTreeId = contentTree.Id, Zone = "cell-1", Index = 1, WidgetId = HtmlDbSeedConstants.WidgetId_Hero_InspirationWelcome, WidgetType = "hero", ViewId = "hero-hero1", Locked = false, } } }, // 4 more images in a grid new ContentNode(bottomGridStyle) { Id = Guid.NewGuid().ToString(), ContentTreeId = contentTree.Id, ParentId = null, Zone = "body", Index = 3, WidgetId = null, WidgetType = "zone", ViewId = "zone-4", Locked = false, ChildNodes = new ContentNode[] { new ContentNode { Id = Guid.NewGuid().ToString(), ContentTreeId = contentTree.Id, Zone = "cell-1", Index = 0, WidgetId = HtmlDbSeedConstants.WidgetId_Image_InspirationImage5, WidgetType = "image", ViewId = "image-fitted", Locked = false }, new ContentNode { Id = Guid.NewGuid().ToString(), ContentTreeId = contentTree.Id, Zone = "cell-2", Index = 1, WidgetId = HtmlDbSeedConstants.WidgetId_Image_InspirationImage6, WidgetType = "image", ViewId = "image-fitted", Locked = false }, new ContentNode { Id = Guid.NewGuid().ToString(), ContentTreeId = contentTree.Id, Zone = "cell-3", Index = 2, WidgetId = HtmlDbSeedConstants.WidgetId_Image_InspirationImage7, WidgetType = "image", ViewId = "image-fitted", Locked = false }, new ContentNode { Id = Guid.NewGuid().ToString(), ContentTreeId = contentTree.Id, Zone = "cell-4", Index = 3, WidgetId = HtmlDbSeedConstants.WidgetId_Image_InspirationImage8, WidgetType = "image", ViewId = "image-fitted", Locked = false } } } }; _dbContext.ContentNodes.AddRange(homePageContentNodes); _dbContext.SaveChanges(); }
public void CopyContentProperties_ValidInput_ReturnsSuccessCopyStatus() { // Arrange var testLanguage = CultureInfo.GetCultureInfo(testLanguageCode); // Source page setup var sourcePageReference = new ContentReference(sourcePageId); const string firstSourceValue = "Some source value"; const string secondSourceValue = "other source value"; var sourcePage = new PageData { Property = { new PropertyString { Name = "PageName", Value = "Source Page" }, new PropertyContentReference { Name = "PageLink", Value = sourcePageReference }, new PropertyString { Name = firstProperty, Value = firstSourceValue, IsPropertyData = true, IsLanguageSpecific = true }, new PropertyString { Name = secondProperty, Value = secondSourceValue, IsPropertyData = true } } }; _stubContentLoader.Get <PageData>(sourcePageReference, testLanguage).Returns(sourcePage); // Destination page setup var destinationPageReference = new ContentReference(destinationPageId); var destinationPage = new PageData { Property = { new PropertyString { Name = "PageName", Value = "Destination Page" }, new PropertyContentReference { Name = "PageLink", Value = destinationPageReference }, new PropertyString { Name = firstProperty, Value = "", IsPropertyData = true, IsLanguageSpecific = true }, new PropertyString { Name = secondProperty, Value = "", IsPropertyData = true } } }; _stubContentLoader.Get <PageData>(destinationPageReference, testLanguage).Returns(destinationPage); // Copy request setup var request = new ContentCopyRequestDetail { Source = sourcePageId, Destination = destinationPageId, Properties = new List <string> { firstProperty, secondProperty }, CultureCode = testLanguageCode }; // Draft setup var pendingCommonDraft = new ContentVersion(destinationPageReference, "draft", VersionStatus.Published, DateTime.Now, "test", "sample user", destinationPageId, testLanguageCode, true, true); _stubContentVersionRepository.LoadCommonDraft(destinationPageReference, testLanguageCode).Returns(pendingCommonDraft); _stubContentRepository.Save(Arg.Any <PageData>(), SaveAction.CheckOut, AccessLevel.Edit).Returns(destinationPageReference); // Act var result = _propertyService.CopyContentProperties(request); // Assert Assert.IsTrue(result.Success); }
public override void SaveOrUpdate(ContentItem item) { if (_readonly) { throw new Exception("Repository is in read only mode"); } try { lock (this) { if (item.ID == 0) { if (Database.All(x => x.Value != item)) { item.ID = Database.Count > 0 ? AllContentItems.Max(f => f.ID) + 1 : 1; } } var old = Database.ContainsKey(item.ID) ? Database[item.ID] : null; if (old != null && !System.Object.ReferenceEquals(old, item)) { // ALTERNATIVE (old as IUpdatable<ContentItem>).UpdateFrom(item); var oldParent = old.Parent; if (oldParent != null) { _logger.InfoFormat("Removing old version of {0}:{1} from {2}:{3}", item.ID, GetContentItemName(item), oldParent.ID, GetContentItemName(oldParent)); old.AddTo(null); item.AddTo(oldParent); // will be overridden by final run of unresolved links } var oldChildPageIds = old.Children.Where(i => i.IsPage).Select(i => i.ID).ToArray(); foreach (var oldChildPageId in oldChildPageIds) { if (Database.ContainsKey(oldChildPageId)) { var oldChildPage = Database[oldChildPageId]; if (item.Children.Any(i => i.ID == oldChildPageId)) { var itemToRemove = item.Children.First(i => i.ID == oldChildPageId); item.Children.Remove(itemToRemove); } _logger.InfoFormat("Transfering children from old to new version of {0}:{1}", item.ID, GetContentItemName(item)); oldChildPage.AddTo(item); old.Children.Remove(oldChildPage); } else { _logger.Error(string.Format("Unable to link child page {0} to item {1}.", oldChildPageId, item.ID)); } } ContentVersion.ReorderBySortOrderRecursive(item); #if DEBUG var oldChildren = old.Children.Select(c => c.ID).ToList(); var newChildren = item.Children.Select(c => c.ID).ToList(); if (!(newChildren.All(oldChildren.Contains) && oldChildren.All(newChildren.Contains))) { _logger.DebugFormat("Replacing data {0} - children {1} -> {2}", item.ID, string.Join(",", oldChildren), string.Join(",", newChildren)); } #endif Delete(old); } _logger.DebugFormat("Adding or Replacing item {0}:{1}", item.ID, item.Name); Database[item.ID] = item; if (item.IsPage) { InternalDeleteFiles(GetPath(item, true)); var path = Path.Combine(DataDirectoryPhysical, GetPath(item)); _logger.InfoFormat("Creating file \"{0}\"", path); XmlPersistenceUtility.SaveXml(exporter, item, path); } else if (item.Parent != null) { SaveOrUpdate(item.Parent); // TODO optimize multiple saves during import by creating a real xml transaction on the page level } else { throw new ArgumentException("Invalid item: not a page and parent = null"); } } } catch (Exception ex) { _logger.Error("SaveOrUpdate failed on " + item, ex); } }
private static bool IsPublished(ContentVersion version) { return(version != null && version.Status == VersionStatus.Published); }
public void CopyContentProperties_PropertyTypeMismatch_ReturnsFailureStatus() { // Arrange var testLanguage = CultureInfo.GetCultureInfo(testLanguageCode); // Source page setup var sourcePageReference = new ContentReference(sourcePageId); var sourcePage = new PageData { Property = { new PropertyString { Name = "PageName", Value = "Source Page" }, new PropertyContentReference { Name = "PageLink", Value = sourcePageReference }, new PropertyString { Name = firstProperty, Value = "Some value", IsPropertyData = true, IsLanguageSpecific = true } } }; _stubContentLoader.Get <PageData>(sourcePageReference, testLanguage).Returns(sourcePage); // Destination page setup var destinationPageReference = new ContentReference(destinationPageId); var destinationPage = new PageData { Property = { new PropertyString { Name = "PageName", Value = "Destination Page" }, new PropertyContentReference { Name = "PageLink", Value = destinationPageReference }, new PropertyNumber { Name = firstProperty, Value = 12345, IsPropertyData = true, IsLanguageSpecific = true } } }; _stubContentLoader.Get <PageData>(destinationPageReference, testLanguage).Returns(destinationPage); // Copy request setup var request = new ContentCopyRequestDetail { Source = sourcePageId, Destination = destinationPageId, Properties = new List <string> { firstProperty, secondProperty }, CultureCode = testLanguageCode }; // Draft setup var pendingCommonDraft = new ContentVersion(destinationPageReference, "draft", VersionStatus.Published, DateTime.Now, "test", "sample user", destinationPageId, testLanguageCode, true, true); _stubContentVersionRepository.LoadCommonDraft(destinationPageReference, testLanguageCode).Returns(pendingCommonDraft); // Act var result = _propertyService.CopyContentProperties(request); // Assert Assert.IsFalse(result.Success); }
public ActionResult Edit(ContentEditViewModel model) { Content content = null; if (ModelState.IsValid) { ContentVersion latestVersion = null; if (model.ContentId == null) { // Create a new Content Object if there is none var c = new Content { Version = 1, EditPermissionId = null, Published = DateTime.MinValue, PublishedByUserId = null, Created = DateTime.Now, AuthorUserId = User.Identity.GetUserId<int>(), UnparsedContent = "", StylesheetCss = "" }; content = _entities.Contents.Add(c); var v = new ContentVersion { ContentId = content.Id, UserId = content.AuthorUserId, UnparsedContent = "", StylesheetCode = "", Title = "", Description = "", Teaser = "", Notes = "" }; latestVersion = _entities.ContentVersions.Add(v); _entities.SaveChanges(); model.ContentId = content.Id; var url = new ContentUrl { Url = String.Format("inhalt/{0}", content.Id), ContentId = content.Id, Type = UrlType.System, Enabled = true }; _entities.ContentUrls.Add(url); content.DefaultUrl = url; } else { // Try to find the existing content object var result = _entities.Contents .Include("EditPermission") .Include("Boilerplates") .Include("BoilerplatesUsed") .Where(c => c.Id == model.ContentId); if (result.Any()) { content = result.First(); if (content.EditPermission != null && !User.IsInRole(content.EditPermission.Name)) { return RedirectToRoute("ContentIndex"); } } else { return RedirectToRoute("ContentIndex"); } } if (User.IsInRole("artikel-administrator")) { if (model.Status == ContentStatus.Published && content.Status != ContentStatus.Published) { // Publish the content content.Published = DateTime.Now; content.PublishedByUserId = User.Identity.GetUserId<int>(); } else if (model.Status != ContentStatus.Published && content.Status == ContentStatus.Published) { // Unpublish the content content.Published = DateTime.MinValue; content.PublishedByUserId = null; } var permission = _entities.Roles.FirstOrDefault(r => r.Id == model.PermissionId); if (permission != null && permission.Metapermission.Name == "mitarbeiter") { content.EditPermissionId = model.PermissionId; } if (string.IsNullOrEmpty(model.Url) && model.Status == ContentStatus.Published) { if (model.Type == ContentType.News) { // Default url is /news/-/1234 model.Url = "-"; } } if (!string.IsNullOrEmpty(model.Url)) { model.Url = model.Url.Trim('/'); if (model.Type == ContentType.News && !Regex.IsMatch(model.Url, @"news/[a-zA-Z0-9_\-/]+/\d+")) { model.Url = String.Format("news/{0}/{1}", model.Url, content.Id); } if (content.DefaultUrl == null || content.DefaultUrl.Url != model.Url) { var duplicates = _entities.ContentUrls .Where(u => u.Url == model.Url); if (!duplicates.Any() || duplicates.First().Enabled == false) { _entities.ContentUrls.RemoveRange(duplicates); var url = new ContentUrl { ContentId = content.Id, Enabled = true, Type = UrlType.Default, Url = model.Url }; if (content.DefaultUrl != null && content.DefaultUrl.Type == UrlType.Default) { content.DefaultUrl.Type = UrlType.Alternative; } content.DefaultUrl = _entities.ContentUrls.Add(url); } else { ModelState.AddModelError("Url", "Die gewählte URL existiert bereits."); } } } } else { // Normal editors cannot change these options model.HomePageOptions = content.HomePageOptions; model.PermissionId = content.EditPermissionId; model.Url = content.DefaultUrl.Url; // Normal editors cannot un-publish content if (model.Status != ContentStatus.Published && content.Status == ContentStatus.Published) { model.Status = content.Status; } } // Update Database Fields model.UpdateContent(content); content.Updated = DateTime.Now; int userId; if (content.Version > 0) { latestVersion = latestVersion ?? _entities.ContentVersions.Where(v => v.ContentId == content.Id).OrderByDescending(v => v.Updated).First(); userId = latestVersion.UserId; } else { userId = content.AuthorUserId; } try { content.CompileLess(); } catch (ArgumentException) { ViewBag.Error = "Dein artikelspezifischer CSS-Code enthält Fehler und wurde daher nicht in den Artikel übernommen (aber in der Datenbank gespeichert)."; } content.Parse(); // Calculate Changes int updateCharsDeleted = 0; int updateCharsInserted = 0; double updateMagnificance = 0; if (latestVersion != null) { var dmp = new diff_match_patch(); var diffs = dmp.diff_main(latestVersion.UnparsedContent ?? "", model.UnparsedContent ?? ""); foreach (var diffItem in diffs.Where(diffItem => diffItem.text.Trim().Length != 0)) { switch (diffItem.operation) { case Operation.DELETE: { updateCharsDeleted += diffItem.text.Length; break; } case Operation.INSERT: { updateCharsInserted += diffItem.text.Length; break; } } } updateMagnificance = Math.Min(updateCharsInserted * 0.9 / Math.Max(1, latestVersion.UnparsedContent.Length) + updateCharsDeleted * 0.1 / Math.Max(1, latestVersion.UnparsedContent.Length), 1); updateMagnificance = Math.Min(1, Math.Tan(updateMagnificance)); } // If the user was not the one who updated last we have to create a new version if (userId != User.Identity.GetUserId<int>()) { content.Version++; latestVersion = new ContentVersion { ContentId = content.Id, Title = content.Title, Version = content.Version, UnparsedContent = content.UnparsedContent, ParsedContent = content.ParsedContent, Description = content.Description, StylesheetCss = content.StylesheetCss, StylesheetCode = content.StylesheetCode, Teaser = content.Teaser, UserId = User.Identity.GetUserId<int>(), Note = content.Notes, Updated = DateTime.Now, UpdateMagnificance = updateMagnificance, UpdateCharsChanged = updateCharsInserted, UpdateCharsDeleted = updateCharsDeleted }; _entities.ContentVersions.Add(latestVersion); } else { if (latestVersion != null) { model.UpdateContentVersion(latestVersion); latestVersion.Version = content.Version; latestVersion.ParsedContent = content.ParsedContent; latestVersion.StylesheetCss = content.StylesheetCss; latestVersion.Updated = DateTime.Now; latestVersion.UpdateMagnificance = updateMagnificance; latestVersion.UpdateCharsChanged = updateCharsInserted; latestVersion.UpdateCharsDeleted = updateCharsDeleted; } } // Save all Changes _entities.SaveChanges(); } model.Saved = ModelState.IsValid; model.Categories = model.Categories ?? _entities.ContentCategories.OrderBy(c => c.OrderingPosition); model.IsContentAdministrator = User.IsInRole("artikel-administrator"); // Remove status options the user cannot use var statusOptions = Enum.GetValues(typeof(ContentStatus)) .OfType<ContentStatus>(); if (content != null) { if (!model.IsContentAdministrator) { statusOptions = content.Status == ContentStatus.Published ? statusOptions.Where(e => e == ContentStatus.Published) : statusOptions.Where(e => e != ContentStatus.Published); } } else { statusOptions = statusOptions.Where(e => e != ContentStatus.Published); } model.ContentStatusList = statusOptions.Select(e => new SelectListItem { Text = e.GetDisplayName(), Value = ((int)e).ToString() }); model.ContentPermissionList = _entities.Roles .Where(r => r.Metapermission.Name == "mitarbeiter") .Select(r => new SelectListItem { Text = r.FriendlyName, Value = r.Id.ToString() }); return View("~/Areas/mitarbeit/Views/Content/Edit.cshtml", model); }
public void SetVersion(string version, DateTime modifiedDate) { ContentVersion = new ContentVersion { Version = version, ReleaseDate = modifiedDate }; }
public Task <IEnumerable <string> > GetCultureCodesAsync(ContentVersion prevVersion = null) { var key = $"{ContentVersion?.ReleaseDate}|{ContentVersion?.Version}"; return(Task.FromResult(Data[key].Keys.AsEnumerable())); }
public Task <ContentVersion> CheckForChangesAsync(ContentVersion prevVersion = null, CancellationToken token = default) { return(GetVersionAsync()); }
public Task <IEnumerable <ContentItem> > GetAllContentItemsAsync(string cultureCode, ContentVersion prevVersion = null) { var key = $"{ContentVersion?.ReleaseDate}|{ContentVersion?.Version}"; lock (_lockObject) { GetAllContentItemsInvokeCount++; if (!Data.ContainsKey(key)) { Data[key] = new Dictionary <string, Dictionary <string, ContentItem> >(); } if (!Data[key].ContainsKey(cultureCode)) { Data[key][cultureCode] = new Dictionary <string, ContentItem>(); } } return(Task.FromResult(Data[key][cultureCode].Values.AsEnumerable())); }