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);
        }
Beispiel #2
0
 private object ConvertValue(SingleArticleField article, CallContext ctx)
 {
     return(Convert(article.GetItem(ctx.Filter), ctx, true));
 }
Beispiel #3
0
        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);
        }
Beispiel #4
0
        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);
        }
        /// <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);
                }
            }
        }