public void Test_Binding_To_Model_With__bindable_Converter_roots() { Run(() => { QPModelBindingValueProvider.ThrowOnErrors = true; var control = ValidationHelper.GetXaml <Group>("QA.Core.Models.Tests.Xaml.EntityEditor_BindableConverter.xaml"); var model = new Article { ContentId = 1, Id = 123 }; model.Fields.Add("Test", new PlainArticleField { FieldName = "Test", Value = "testvalue" }); var mu = new MultiArticleField { FieldName = "TestItems" }; mu.Items.Add(223, new Article { Id = 223, ContentId = 2, ContentDisplayName = "test1" }); mu.Items.Add(224, new Article { Id = 224, ContentId = 2, ContentDisplayName = "test1" }); model.Fields.Add("TestItems", mu); control.DataContext = model; var ec = (EntityCollection)control.Items[2]; var label = (Label)ec.GetChildren().First(); Assert.AreEqual("testvalue-test1", label.Title); }); }
private ArticleField DeserializeEntityField(EntityField fieldInDef, Quantumart.QP8.BLL.Field qpField, IProductDataSource productDataSource, DBConnector connector, Context context) { string fieldName = fieldInDef.FieldName ?? qpField.Name; ArticleField articleField; if (qpField.RelationType == RelationType.OneToMany) { articleField = new SingleArticleField { Item = DeserializeArticle(productDataSource.GetContainer(fieldName), fieldInDef.Content, connector, context), Aggregated = qpField.Aggregated, SubContentId = fieldInDef.Content.ContentId }; } else if (qpField.RelationType == RelationType.ManyToMany || qpField.RelationType == RelationType.ManyToOne) { var multiArticleField = new MultiArticleField { SubContentId = fieldInDef.Content.ContentId }; var containersCollection = productDataSource.GetContainersCollection(fieldName); if (containersCollection != null) { foreach (Article article in containersCollection.Select(x => DeserializeArticle(x, fieldInDef.Content, connector, context))) { multiArticleField.Items.Add(article.Id, article); } } articleField = multiArticleField; } else { throw new Exception(string.Format("Field definition id={0} has EntityField type but its RelationType is not valid", fieldInDef.FieldId)); } return(articleField); }
private IEnumerable <object> ConvertValue(MultiArticleField article, CallContext ctx) { return(article .GetArticlesSorted(ctx.Filter) .Select(x => Convert(x, ctx))); }
private Article GetProduct(JToken productToken, JToken contentToken) { int contentId = contentToken.Value <int>("ContentId"); int statusTypeId = productToken.Value <int>("STATUS_TYPE_ID"); string statusName = _statusProvider.GetStatusName(statusTypeId); bool isPublished = statusName == PublishedStatusd; var product = new Article { Id = productToken.Value <int>("Id"), Archived = productToken.Value <bool>("ARCHIVE"), Visible = productToken.Value <bool>("VISIBLE"), IsPublished = isPublished, Status = statusName, Created = productToken.Value <DateTime>("CREATED"), Modified = productToken.Value <DateTime>("MODIFIED"), ContentId = contentId, ContentName = contentToken.Value <string>("ContentName"), ContentDisplayName = contentToken.Value <string>("ContentDisplayName"), }; foreach (var fieldToken in contentToken["PlainField"]) { var plainField = new PlainArticleField { ContentId = product.ContentId, PlainFieldType = GetFieldType(fieldToken) }; var numberType = GetNumberType(fieldToken); UpdateField(plainField, fieldToken); SetValue(plainField, productToken, numberType); product.Fields[plainField.FieldName] = plainField; } foreach (var fieldToken in contentToken["EntityField"]) { var fieldType = GetFieldType(fieldToken); if (fieldType == PlainFieldType.M2MRelation || fieldType == PlainFieldType.M2ORelation) { var multiField = new MultiArticleField { ContentId = product.ContentId }; UpdateField(multiField, fieldToken); var articleTokens = productToken[multiField.FieldName]; if (articleTokens != null) { foreach (var articleToken in articleTokens) { var childContentToken = fieldToken["Content"]; var article = GetProduct(articleToken, childContentToken); multiField.Items.Add(article.Id, article); } } product.Fields[multiField.FieldName] = multiField; } else if (fieldType == PlainFieldType.O2MRelation) { var singleField = new SingleArticleField { ContentId = product.ContentId }; UpdateField(singleField, fieldToken); var articleToken = productToken[singleField.FieldName]; if (articleToken != null) { var childContentToken = fieldToken["Content"]; var article = GetProduct(articleToken, childContentToken); singleField.Item = article; } product.Fields[singleField.FieldName] = singleField; } else { throw new Exception($"EntityField has unsupportable type {fieldType}"); } } foreach (var fieldToken in contentToken["ExtensionField"]) { var extensionField = new ExtensionArticleField { ContentId = product.ContentId }; UpdateField(extensionField, fieldToken); var extensionId = productToken.Value <int>(extensionField.FieldName); var childContentToken = fieldToken["Contents"].FirstOrDefault(c => c.Value <int>("ContentId") == extensionId); if (childContentToken != null) { var article = GetProduct(productToken, childContentToken); article.Id = 0; extensionField.Value = childContentToken.Value <string>("ContentId"); extensionField.Item = article; product.Fields[extensionField.FieldName] = extensionField; } } foreach (var fieldToken in contentToken["BackwardRelationField"]) { var backwardField = new BackwardArticleField { ContentId = product.ContentId, }; UpdateField(backwardField, fieldToken); var articleToken = productToken[backwardField.FieldName]; if (articleToken != null) { foreach (var t in articleToken) { var childContentToken = fieldToken["Content"]; var article = GetProduct(t, childContentToken); backwardField.Items.Add(article.Id, article); } } product.Fields[backwardField.FieldName] = backwardField; } return(product); }
private ArticleField CloneField(ArticleField field, string fieldName, Dictionary <Article, Article> articleMap) { var pField = field as PlainArticleField; var sField = field as SingleArticleField; var mField = field as MultiArticleField; var eField = field as ExtensionArticleField; var bField = field as BackwardArticleField; var vField = field as VirtualArticleField; var vmField = field as VirtualMultiArticleField; ArticleField clonnedField; if (pField != null) { clonnedField = new PlainArticleField { NativeValue = pField.NativeValue, Value = pField.Value, PlainFieldType = pField.PlainFieldType }; } else if (eField != null) { clonnedField = new ExtensionArticleField { Aggregated = eField.Aggregated, SubContentId = eField.SubContentId, Item = eField.Item == null ? null : articleMap[eField.Item], Value = eField.Value }; } else if (sField != null) { clonnedField = new SingleArticleField { Aggregated = sField.Aggregated, SubContentId = sField.SubContentId, Item = sField.Item == null ? null : articleMap[sField.Item] }; } else if (bField != null) { clonnedField = new BackwardArticleField { SubContentId = bField.SubContentId, Items = bField.Items.ToDictionary(itm => itm.Key, itm => articleMap[itm.Value]), RelationGroupName = bField.RelationGroupName }; } else if (mField != null) { clonnedField = new MultiArticleField { SubContentId = mField.SubContentId, Items = mField.Items.ToDictionary(itm => itm.Key, itm => articleMap[itm.Value]) }; } else if (vField != null) { clonnedField = new VirtualArticleField { Fields = vField.Fields }; } else if (vmField != null) { clonnedField = new VirtualMultiArticleField { VirtualArticles = vmField.VirtualArticles .Select(f => CloneField(f, fieldName, articleMap) as VirtualArticleField) .ToArray() }; } else { throw new Exception($"Cant't process field {field.FieldName} for localization"); } clonnedField.FieldName = fieldName; clonnedField.ContentId = field.ContentId; clonnedField.FieldId = field.FieldId; clonnedField.CustomProperties = field.CustomProperties; clonnedField.FieldDisplayName = field.FieldDisplayName; return(clonnedField); }
public static MultiArticleField AddArticle(this MultiArticleField field, Article child, string fieldDisplayName = "") { field.Items.Add(child.Id, child); return(field); }
// ReSharper disable once InconsistentNaming public ActionResult Index(int content_item_id, string actionCode, bool live = false, string[] filters = null, bool includeRelevanceInfo = true, bool localize = false, string lang = null, bool changeLang = false ) { ViewBag.HostId = _qpHelper.HostId; if (content_item_id <= 0) { ViewBag.Message = ProductCardStrings.СontentItemIdPositive; return(View()); } var sw = Stopwatch.StartNew(); var originalProduct = _productService.GetProductById(content_item_id, live); var product = originalProduct; var cultures = new CultureInfo[0]; var currentCulture = CultureInfo.InvariantCulture; var productLoadedIn = sw.ElapsedMilliseconds; if (product == null) { ViewBag.Message = ProductCardStrings.ProductNotFound; return(View()); } if (localize) { cultures = _localizationService.GetCultures(); if (lang == null) { var cookie = Request.Cookies[actionCode + DefaultCultureKey]; currentCulture = (string.IsNullOrEmpty(cookie) || changeLang) ? cultures[0] : CultureInfo.GetCultureInfo(cookie); } else { currentCulture = CultureInfo.GetCultureInfo(lang); Response.Cookies.Append(actionCode + DefaultCultureKey, lang); } product = _localizationService.Localize(product, currentCulture); } var productLocalized = sw.ElapsedMilliseconds; var control = ObjectFactoryBase.Resolve <IProductControlProvider>().GetControlForProduct(product); if (control == null) { ViewBag.Message = ProductCardStrings.ProductIsNotVisual; return(View()); } var controlLoadedIn = sw.ElapsedMilliseconds; filters = filters ?? new string[] {}; var allFilter = new AllFilter(filters.Select(ObjectFactoryBase.Resolve <IArticleFilter>).ToArray()); product = ArticleFilteredCopier.Copy(product, allFilter); if (localize) { originalProduct = ArticleFilteredCopier.Copy(originalProduct, allFilter); } var productCopied = sw.ElapsedMilliseconds; var relevanceResolved = productCopied; if (includeRelevanceInfo) { var relevanceService = ObjectFactoryBase.Resolve <IProductRelevanceService>(); relevanceResolved = sw.ElapsedMilliseconds; var relevanceItems = relevanceService.GetProductRelevance(localize ? originalProduct : product, live, localize); var relevanceField = new MultiArticleField() { FieldName = "Relevance" }; var id = 0; product.AddField(relevanceField); foreach (var relevanceItem in relevanceItems) { var localizedRelevanceArticle = new Article(); if (Equals(relevanceItem.Culture, CultureInfo.InvariantCulture)) { AddRelevanceData(product, relevanceItem); } relevanceField.Items.Add(++id, localizedRelevanceArticle); AddRelevanceData(localizedRelevanceArticle, relevanceItem); } var isRelevant = relevanceItems.All(r => r.Relevance == ProductRelevance.Relevant); if (!isRelevant) { product.AddPlainField("IsRelevant", false, ProductCardStrings.ProductRelevance); } } var relevanceLoaded = sw.ElapsedMilliseconds; IModelPostProcessor processor = new HierarchySorter(new HierarchySorterParameter { Domain = 100, ConstructHierarchy = true, ParentRelativePath = "Parent", PathToCollection = "Parameters", PathToSortOrder = "SortOrder", PropertyToSet = "NewSortOrder" }); product = processor.ProcessModel(product); var hierarchySorted = sw.ElapsedMilliseconds; product.AddArticle("Diagnostics", new Article() .AddPlainField("ProductLoaded", productLoadedIn, ProductCardStrings.ProductLoaded) .AddPlainField("ProductLocalized", productLocalized, ProductCardStrings.ProductLocalized) .AddPlainField("ControlLoaded", controlLoadedIn, ProductCardStrings.ControlLoaded) .AddPlainField("ProductCopied", productCopied, ProductCardStrings.ProductCopied) .AddPlainField("RelevanceResolved", relevanceResolved, ProductCardStrings.RelevanceResolved) .AddPlainField("RelevanceLoaded", relevanceLoaded, ProductCardStrings.RelevanceLoaded) .AddPlainField("HierarchySorted", hierarchySorted, ProductCardStrings.HierarchySorted)); control.DataContext = product; return(View("Index", new CardModel { Control = control, Cultures = cultures, CurrentCultute = currentCulture })); }
/// <exception cref="ArgumentNullException" /> /// <exception cref="InvalidOperationException" /> private void ProcessArticlesTree(Article newArticle, Article existingArticle, Content definition) { if (newArticle == null || !_filter.Matches(newArticle)) { return; } if (!_filter.Matches(existingArticle)) { existingArticle = null; } if (definition == null) { throw new ArgumentNullException(nameof(definition)); } ValidateDates(newArticle, existingArticle); ArticleData newArticleUpdateData = new ArticleData { ContentId = definition.ContentId, Id = newArticle.Id }; List <int> plainFieldIds = definition.Fields .Where(x => x is PlainField) .Select(x => x.FieldId) .ToList(); if (definition.LoadAllPlainFields) { plainFieldIds.AddRange( _fieldService.List(definition.ContentId) .Where(x => x.RelationType == RelationType.None && definition.Fields.All(y => y.FieldId != x.Id)) .Select(x => x.Id)); } // TODO: исключаем Readonly поля var updatedFields = newArticle.Fields.Values .OfType <PlainArticleField>() .Where(x => plainFieldIds.Contains(x.FieldId.Value) && (existingArticle == null || existingArticle.Fields.Values .OfType <PlainArticleField>() .All(y => y.FieldId != x.FieldId || !HasEqualNativeValues(x, y)))) .Select(x => new FieldData { Id = x.FieldId.Value, Value = x.Value }); newArticleUpdateData.Fields.AddRange(updatedFields); var associationFieldsInfo = ( from fieldDef in definition.Fields.OfType <Association>() join field in newArticle.Fields.Values on fieldDef.FieldId equals field.FieldId select new { field, oldField = existingArticle?.Fields.Values.SingleOrDefault(x => x.FieldId == field.FieldId), fieldDef }).ToArray(); foreach (var fieldToSyncInfo in associationFieldsInfo) { if (fieldToSyncInfo.fieldDef is BackwardRelationField backwardRelationFieldDef) { BackwardArticleField oldField = (BackwardArticleField)fieldToSyncInfo.oldField; BackwardArticleField field = (BackwardArticleField)fieldToSyncInfo.field; int[] idsToAdd = field.GetArticles(_filter) .Where(x => oldField == null || oldField.GetArticles(_filter).All(y => y.Id != x.Id)) .Select(x => x.Id) .ToArray(); int[] idsToRemove = oldField?.GetArticles(_filter) .Select(x => x.Id) .Where(x => field.GetArticles(_filter).All(y => y.Id != x)) .ToArray() ?? new int[0]; if (idsToAdd.Any()) { _updateData.AddRange(idsToAdd.Select(x => new ArticleData { Id = x, ContentId = backwardRelationFieldDef.Content.ContentId, Fields = new List <FieldData> { new FieldData { Id = field.FieldId.Value, ArticleIds = new[] { newArticle.Id } } } })); } if (idsToRemove.Any()) { if (backwardRelationFieldDef.DeletingMode == DeletingMode.Delete) { foreach (int idToRemove in idsToRemove) { _articlesToDelete[idToRemove] = backwardRelationFieldDef.Content; } } else { _updateData.AddRange(idsToRemove.Select(x => new ArticleData { Id = x, ContentId = backwardRelationFieldDef.Content.ContentId })); } } } else if (fieldToSyncInfo.fieldDef is ExtensionField extensionFieldDef) { ExtensionArticleField oldField = (ExtensionArticleField)fieldToSyncInfo.oldField; ExtensionArticleField field = (ExtensionArticleField)fieldToSyncInfo.field; if (oldField == null || field.Value != oldField.Value) { newArticleUpdateData.Fields.Add(new FieldData { Id = extensionFieldDef.FieldId, Value = field.Value, ArticleIds = field.Item == null ? null : new[] { field.Item.Id } }); if (oldField?.Item != null) { _articlesToDelete[oldField.Item.Id] = extensionFieldDef .ContentMapping[oldField.Item.ContentId]; } } } else if (fieldToSyncInfo.field is SingleArticleField) { SingleArticleField oldField = (SingleArticleField)fieldToSyncInfo.oldField; SingleArticleField field = (SingleArticleField)fieldToSyncInfo.field; EntityField entityFieldDef = (EntityField)fieldToSyncInfo.fieldDef; Article item = field.GetItem(_filter); Article oldItem = oldField?.GetItem(_filter); if (item?.Id != oldItem?.Id) { newArticleUpdateData.Fields.Add(new FieldData { Id = field.FieldId.Value, ArticleIds = item == null ? null : new[] { item.Id } }); if (oldItem != null && entityFieldDef.DeletingMode == DeletingMode.Delete) { _articlesToDelete[oldItem.Id] = entityFieldDef.Content; } } } else if (fieldToSyncInfo.field is MultiArticleField) { MultiArticleField oldField = (MultiArticleField)fieldToSyncInfo.oldField; MultiArticleField field = (MultiArticleField)fieldToSyncInfo.field; EntityField entityFieldDef = (EntityField)fieldToSyncInfo.fieldDef; var items = field.GetArticles(_filter).ToArray(); var oldItems = oldField?.GetArticles(_filter).ToArray(); if (items.Length != (oldItems?.Length ?? 0) || items.Any(x => oldItems.All(y => y.Id != x.Id))) { newArticleUpdateData.Fields.Add(new FieldData { Id = field.FieldId.Value, ArticleIds = items.Select(x => x.Id).ToArray() }); if (entityFieldDef.DeletingMode == DeletingMode.Delete) { int[] idsToRemove = oldItems? .Where(x => items.All(y => y.Id != x.Id)) .Select(x => x.Id) .ToArray() ?? new int[0]; foreach (int idToRemove in idsToRemove) { _articlesToDelete[idToRemove] = entityFieldDef.Content; } } } } } if (newArticleUpdateData.Fields.Any()) { _updateData.Add(newArticleUpdateData); } foreach (var fieldInfo in associationFieldsInfo .Where(x => x.fieldDef.UpdatingMode == UpdatingMode.Update || x.fieldDef is ExtensionField)) { Article[] oldFieldsArticles = fieldInfo.oldField == null ? new Article[0] : GetChildArticles(fieldInfo.oldField, _filter).ToArray(); foreach (Article childArticle in GetChildArticles(fieldInfo.field, _filter)) { Content childArticleDef = fieldInfo.fieldDef.GetContents() .SingleOrDefault(x => x.ContentId == childArticle.ContentId); if (childArticleDef == null) { throw new InvalidOperationException($@"There is an conflict in product definition field {fieldInfo.field.FieldId} between ContentId={childArticle.ContentId} and Articleid={childArticle.Id}"); } Article oldChildArticle = oldFieldsArticles.SingleOrDefault(x => x.Id == childArticle.Id); ProcessArticlesTree(childArticle, oldChildArticle, childArticleDef); } } }