コード例 #1
0
        public Article DeserializeProductXml(XDocument productXml, Models.Configuration.Content definition)
        {
            var rootProductElement = productXml.Root?.Elements().First().Elements().First();

            var productDeserializer = ObjectFactoryBase.Resolve <IProductDeserializer>();

            return(productDeserializer.Deserialize(new XmlProductDataSource(rootProductElement), definition));
        }
コード例 #2
0
 public int?CloneProduct(
     int productId, Models.Configuration.Content contentDefinition, Dictionary <string, string> actionParameters)
 {
     using (var transaction = CreateTransaction())
     {
         int?clonedProductId = CloneProductImpl(productId, contentDefinition, actionParameters);
         transaction.Commit();
         return(clonedProductId);
     }
 }
コード例 #3
0
        public Article Deserialize(IProductDataSource productDataSource, Models.Configuration.Content definition)
        {
            using (var cs = new QPConnectionScope(_customer.ConnectionString, (Quantumart.QP8.Constants.DatabaseType)_customer.DatabaseType))
            {
                _cacheItemWatcher.TrackChanges();

                _contentService.LoadStructureCache(_contextStorage);

                var connector = new DBConnector(cs.DbConnection);

                var context = new Context();
                var article = DeserializeArticle(productDataSource, definition, connector, context);
                context.UpdateExtensionArticles();
                return(article);
            }
        }
コード例 #4
0
        private Article DeserializeArticle(IProductDataSource productDataSource, Models.Configuration.Content definition, DBConnector connector, Context context)
        {
            if (productDataSource == null)
            {
                return(null);
            }

            int id = productDataSource.GetArticleId();

            context.TakeIntoAccount(id);

            var qpContent = _contentService.Read(definition.ContentId);

            Article article = new Article
            {
                Id                 = id,
                ContentName        = qpContent.NetName,
                Modified           = productDataSource.GetModified(),
                ContentId          = definition.ContentId,
                ContentDisplayName = qpContent.Name,
                PublishingMode     = definition.PublishingMode,
                IsReadOnly         = definition.IsReadOnly,
                Visible            = true
            };

            foreach (Field fieldInDef in definition.Fields.Where(x => !(x is BaseVirtualField) && !(x is Dictionaries)))
            {
                var field = DeserializeField(fieldInDef, _fieldService.Read(fieldInDef.FieldId), productDataSource, connector, context);

                article.Fields[field.FieldName] = field;
            }

            if (definition.LoadAllPlainFields)
            {
                var qpFields = _fieldService.List(definition.ContentId);

                foreach (var plainFieldFromQp in qpFields.Where(x => x.RelationType == RelationType.None && definition.Fields.All(y => y.FieldId != x.Id)))
                {
                    article.Fields[plainFieldFromQp.Name] = DeserializeField(new PlainField {
                        FieldId = plainFieldFromQp.Id
                    }, plainFieldFromQp, productDataSource, connector, context);
                }
            }

            return(article);
        }
コード例 #5
0
        private ArticleField DeserializeExtensionField(ExtensionField fieldInDef, Quantumart.QP8.BLL.Field qpField, IProductDataSource productDataSource, DBConnector connector, Context context)
        {
            var extensionArticleField = new ExtensionArticleField();

            string fieldName = string.IsNullOrEmpty(fieldInDef.FieldName) ? qpField.Name : fieldInDef.FieldName;

            string contentName = productDataSource.GetString(fieldName);

            if (!string.IsNullOrEmpty(contentName))
            {
                Models.Configuration.Content valueDef = fieldInDef.ContentMapping.Values.FirstOrDefault(x => _contentService.Read(x.ContentId).NetName == contentName);

                if (valueDef == null)
                {
                    throw new Exception(
                              $"'{contentName}' value is not found in an available extension content list, id = {fieldInDef.FieldId}");
                }

                extensionArticleField.Value        = valueDef.ContentId.ToString();
                extensionArticleField.SubContentId = valueDef.ContentId;

                IProductDataSource extensionDataSource = productDataSource.GetExtensionContainer(fieldName, contentName);

                extensionArticleField.Item = DeserializeArticle(extensionDataSource, valueDef, connector, context);

                if (extensionArticleField.Item.Id == productDataSource.GetArticleId())
                {
                    var id = GetExtensionId(connector, valueDef.ContentId, fieldInDef.FieldId, extensionArticleField.Item.Id);

                    if (id.HasValue)
                    {
                        extensionArticleField.Item.Id = id.Value;
                    }
                    else
                    {
                        context.AddExtensionArticle(extensionArticleField.Item.Id, extensionArticleField.Item);
                        extensionArticleField.Item.Id = default(int);
                    }
                }
            }

            return(extensionArticleField);
        }
コード例 #6
0
        private void GetProductsToBeProcessed <T>(
            Article article,
            Models.Configuration.Content definition,
            Dictionary <int, Product <T> > dictionary,
            Func <Association, T> selectMode,
            T mode,
            Func <Article, bool> filter,
            bool excludeArchive
            )
            where T : struct
        {
            var entityFields        = definition == null ? new Association[0] : definition.Fields.OfType <Association>().ToArray();
            var fieldDefinitions    = entityFields.ToDictionary(f => f.FieldId, ContentSelector <T>);
            var fieldModes          = entityFields.ToDictionary(f => f.FieldId, selectMode);
            var backwardFieldValues = GetBackwardFieldValues(article, entityFields.OfType <BackwardRelationField>(), excludeArchive);

            var product = new Product <T>(article, fieldModes, backwardFieldValues);

            if (!dictionary.ContainsKey(article.Id))
            {
                dictionary.Add(article.Id, product);
            }

            var root = dictionary.Values.First().Article;

            var relatedFields = (from fv in article.FieldValues.Concat(backwardFieldValues)
                                 join ef in entityFields on fv.Field.Id equals ef.FieldId
                                 where selectMode(ef).Equals(mode)
                                 select fv)
                                .ToArray();

            //LogFieldValues(article.FieldValues, "ContentId = " + article.ContentId + " IsAggregated = " + article.IsAggregated);

            var relatedItems = (from fv in relatedFields
                                from id in fv.RelatedItems
                                where !dictionary.ContainsKey(id) && fv.Field.ExactType != FieldExactTypes.Classifier
                                let f = fv.Field
                                        let contentId = backwardFieldValues.Contains(fv) ? f.ContentId : f.RelateToContentId ?? 0
                                                        group new { Id = id, FieldId = f.Id, Relation = f.RelationType } by contentId into g
                                select new { ContentId = g.Key, RelatedItems = g })
                               .ToArray();

            foreach (var item in relatedItems)
            {
                var ids        = item.RelatedItems.Select(itm => itm.Id).Distinct().ToArray();
                var articleMap = ArticleService.List(item.ContentId, ids, excludeArchive).ToDictionary(a => a.Id);

                foreach (var relatedItem in item.RelatedItems)
                {
                    if (articleMap.TryGetValue(relatedItem.Id, out var relatedArticle) && filter(relatedArticle))
                    {
                        Models.Configuration.Content def = null;
                        fieldDefinitions.TryGetValue(relatedItem.FieldId, out def);

                        if (relatedItem.Relation != RelationType.ManyToMany || relatedArticle.ContentId != root.ContentId)
                        {
                            GetProductsToBeProcessed(relatedArticle, def, dictionary, selectMode, mode, filter, excludeArchive);

                            var relatedProduct = dictionary[relatedArticle.Id];

                            var backwardFields = from fv in relatedFields
                                                 where fv.Field.RelationType == RelationType.ManyToOne
                                                 join pfv in relatedProduct.Article.FieldValues on fv.Field.BackRelationId equals pfv.Field.Id
                                                 select pfv;

                            foreach (var fv in backwardFields)
                            {
                                relatedProduct.BackwardMap[fv.Field.Id] = true;
                            }
                        }
                    }
                }
            }

            foreach (var fv in backwardFieldValues)
            {
                var currentMode = product.GetCloningMode(fv.Field);

                if (currentMode.HasValue && currentMode.Value.Equals(mode))
                {
                    var products = fv.RelatedItems.Where(id => dictionary.ContainsKey(id)).Select(id => dictionary[id]);

                    foreach (var p in products)
                    {
                        p.BackwardMap[fv.Field.Id] = true;
                    }
                }
            }

            var aggregatedArticles = product.Article.AggregatedArticles.ToArray();

            for (int i = 0; i < aggregatedArticles.Length; i++)
            {
                int id = aggregatedArticles[i].Id;

                if (dictionary.ContainsKey(id))
                {
                    aggregatedArticles[i] = dictionary[id].Article;
                }
            }

            product.Article.AggregatedArticles = aggregatedArticles;
        }
コード例 #7
0
        private int?CloneProductImpl(
            int productId, Models.Configuration.Content contentDefinition, Dictionary <string, string> actionParameters)
        {
            _cacheItemWatcher.TrackChanges();

            DoWithLogging(
                () => ArticleService.LoadStructureCache(),
                "Loading structure cache"
                );


            var article = DoWithLogging(
                () => ArticleService.Read(productId),
                "Reading root article for product {id}", productId
                );

            if (!Filter(article))
            {
                return(null);
            }

            var checkResult = DoWithLogging(
                () => ArticleService.CheckRelationSecurity(article.ContentId, new[] { productId }, false),
                "Checking relation security for product {id}", productId
                );

            if (!checkResult[productId])
            {
                throw new ProductException(productId, nameof(TaskStrings.NoRelationAccess));
            }

            if (contentDefinition == null)
            {
                contentDefinition = _definitionService.GetDefinitionForContent(0, article.ContentId);
            }
            if (actionParameters == null)
            {
                actionParameters = new Dictionary <string, string>();
            }

            var productDefinition = new ProductDefinition {
                StorageSchema = contentDefinition
            };

            UpdateDefinition(article, productDefinition, actionParameters);

            var productsById = DoWithLogging(
                () => GetProductsToBeProcessed(
                    article, productDefinition, ef => ef.CloningMode, CloningMode.Copy, Filter, true),
                "Receving articles to be cloned for product {id}", productId
                );

            var clearFieldIds = actionParameters.GetClearFieldIds();

            var missedAggArticles = PrepareProducts(productsById, clearFieldIds);

            MapProducts(productsById[productId], productsById);

            var result = DoWithLogging(
                () => SaveProducts(productId, productsById, missedAggArticles),
                "Cloning {count} articles for product {id}", productsById.Count, productId
                );

            return(result);
        }