BetterCms.Module.Blog.Services.DefaultBlogMLService.ImportCategories C# (CSharp) Method

ImportCategories() private method

private ImportCategories ( BlogMLBlog categories, IEnumerable blogs, List &newCategoriesTreeList, List &newCategoriesList, bool ReuseExistingCategories, bool RecreateCategoryTree ) : Guid>.IDictionary
categories BlogMLBlog
blogs IEnumerable
newCategoriesTreeList List
newCategoriesList List
ReuseExistingCategories bool
RecreateCategoryTree bool
return Guid>.IDictionary
        private IDictionary<string, Guid> ImportCategories(BlogMLBlog.CategoryCollection categories, 
                                                           IEnumerable<BlogMLPost> blogs,
                                                           ref List<CategoryTree> newCategoriesTreeList,
                                                           ref List<Category> newCategoriesList, 
                                                           bool ReuseExistingCategories, 
                                                           bool RecreateCategoryTree)
        {
            var dictionary = new Dictionary<string, Guid>();
            if (categories.Count == 0)
            {
                // old export method when only categories ids are exported
                var oldExistingCategoriesIds = new List<Guid>();
                blogs.Select(t => t.Categories).ForEach(
                    t =>
                    {
                        for (int i = 0; i < t.Count; i++)
                        {
                            Guid parsedGuid;
                            if (Guid.TryParse(t[i].Ref, out parsedGuid) && !oldExistingCategoriesIds.Contains(parsedGuid))
                            {
                                oldExistingCategoriesIds.Add(parsedGuid);
                            }
                        }
                    });
                oldExistingCategoriesIds = repository.AsQueryable<Category>().Where(t => oldExistingCategoriesIds.Contains(t.Id)).Select(t => t.Id).ToList();
                oldExistingCategoriesIds.ForEach(t => dictionary.Add(t.ToString(), t));
                return dictionary;
            }


            if (RecreateCategoryTree)
            {
                // sort categories that parents would be first
                for (int i = 0; i < categories.Count; i++)
                {
                    for (int j = 0; j < categories.Count; j++)
                    {
                        if (categories[i].ID == categories[j].ParentRef && i > j)
                        {
                            var tmp = categories[j];
                            categories[j] = categories[i];
                            categories[i] = tmp;
                        }
                    }
                }
                var newIdsForCategories = new Dictionary<string, Guid>();
                // regenerate new ids for category tree
                foreach (var category in categories)
                {
                    if (!newIdsForCategories.ContainsKey(category.ID))
                    {
                        newIdsForCategories.Add(category.ID, Guid.NewGuid());
                    }
                    if (!string.IsNullOrEmpty(category.ParentRef) && !newIdsForCategories.ContainsKey(category.ParentRef))
                    {
                        newIdsForCategories.Add(category.ParentRef, Guid.NewGuid());
                    }
                }
                foreach (var category in categories)
                {
                    category.ID = newIdsForCategories[category.ID].ToString();
                    if (!string.IsNullOrEmpty(category.ParentRef))
                    {
                        category.ParentRef = newIdsForCategories[category.ParentRef].ToString();
                    }
                }
                var refrencedCategoriesIds = new List<Guid>();
                foreach (var blog in blogs)
                {
                    for (int i = 0; i < blog.Categories.Count; i++)
                    {
                        var category = blog.Categories[i];
                        // it may be that category is deleted but it is still linked to blog and that link is not deleted
                        if (newIdsForCategories.ContainsKey(category.Ref))
                        {
                            var newCategoryId = newIdsForCategories[category.Ref];
                            category.Ref = newCategoryId.ToString();
                            refrencedCategoriesIds.Add(newCategoryId);
                        }
                    }
                }

                Guid testParseGuid;
                var oldIdsCategories = newIdsForCategories.Keys.Where(t => Guid.TryParse(t, out testParseGuid)).Select(t => new Guid(t)).ToList();
                var existingCategoriesIdsFuture = repository.AsQueryable<Category>().Select(t => t.Id).Where(t => oldIdsCategories.Contains(t)).ToFuture();
                var availableFor = repository.AsQueryable<CategorizableItem>().ToFuture().ToList();
                var existingCategoriesIds = existingCategoriesIdsFuture.ToList();

                // creates categories trees
                foreach (var categoryTree in categories.Where(c => string.IsNullOrEmpty(c.ParentRef)))
                {
                    var newTree = new CategoryTree
                    {
                        Title = categoryTree.Title,
                        CreatedOn = categoryTree.DateCreated,
                        ModifiedOn = categoryTree.DateModified,
                        Id = new Guid(categoryTree.ID)
                    };
                    newTree.AvailableFor = new List<CategoryTreeCategorizableItem>();
                    foreach (var categorizableItem in availableFor)
                    {
                        newTree.AvailableFor.Add(new CategoryTreeCategorizableItem { CategorizableItem = categorizableItem, CategoryTree = newTree });
                    }
                    newCategoriesTreeList.Add(newTree);
                }

                // create categories
                foreach (var category in categories.Where(t => !string.IsNullOrEmpty(t.ParentRef)))
                {
                    var categoryParentId = new Guid(category.ParentRef);
                    var newParentCategoryTree = newCategoriesTreeList.FirstOrDefault(t => t.Id == categoryParentId);
                    var newCategory = new Category
                    {
                        Name = category.Title,
                        CreatedOn = category.DateCreated,
                        ModifiedOn = category.DateModified,
                        Id = new Guid(category.ID),
                        CategoryTree = newParentCategoryTree
                    };
                    newCategoriesList.Add(newCategory);
                }

                // set references for category, category tree
                foreach (var category in newCategoriesList.Where(t => t.CategoryTree == null))
                {
                    category.CategoryTree = newCategoriesList.First(t => t.Id.ToString() == categories.First(c => c.ID == category.Id.ToString()).ParentRef).CategoryTree;
                }
                foreach (var tree in newCategoriesTreeList)
                {
                    tree.Categories = newCategoriesList.Where(t => t.CategoryTree != null && t.CategoryTree.Id == tree.Id).ToList();
                }
                foreach (var child in newCategoriesList)
                {
                    var parentId = new Guid(categories.First(t => t.ID == child.Id.ToString()).ParentRef);
                    var parentCategory = newCategoriesList.FirstOrDefault(t => t.Id == parentId);
                    if (parentCategory != null)
                    {
                        child.ParentCategory = parentCategory;
                        parentCategory.ChildCategories = parentCategory.ChildCategories ?? new List<Category>();
                        parentCategory.ChildCategories.Add(child);
                    }
                }

                // generate category for empty category tree
                foreach (var categoryTree in newCategoriesTreeList.Where(t => t.Categories != null && t.Categories.Count == 0))
                {
                    var category = new Category
                    {
                        Id = categoryTree.Id,
                        CreatedOn = categoryTree.CreatedOn,
                        ModifiedOn = categoryTree.ModifiedOn,
                        Name = categoryTree.Title,
                        CategoryTree = categoryTree
                    };
                    categoryTree.Id = Guid.NewGuid();
                    categoryTree.Categories.Add(category);
                    newCategoriesList.Add(category);
                }

                // removing referenced categories that they would not be saved and adding existing category id from db
                foreach (var existingCategoriesId in existingCategoriesIds)
                {
                    refrencedCategoriesIds.Remove(newIdsForCategories[existingCategoriesId.ToLowerInvariantString()]);
                    dictionary.Add(existingCategoriesId.ToString(), existingCategoriesId);
                    foreach (var blog in blogs)
                    {
                        for (int i = 0; i < blog.Categories.Count; i++)
                        {
                            if (blog.Categories[i].Ref == newIdsForCategories[existingCategoriesId.ToLowerInvariantString()].ToLowerInvariantString())
                            {
                                blog.Categories[i].Ref = existingCategoriesId.ToLowerInvariantString();
                            }
                        }
                    }
                }

                // filter, save only categories who are related to imported blogs
                newCategoriesTreeList = newCategoriesTreeList.Where(t => t.Categories.Any(z => refrencedCategoriesIds.Contains(z.Id))).ToList();
                newCategoriesList =
                    newCategoriesList.Where(t => t.CategoryTree != null && t.CategoryTree.Categories.Any(z => refrencedCategoriesIds.Contains(z.Id))).ToList();
                // save new records
                foreach (var category in newCategoriesList)
                {
                    dictionary.Add(category.Id.ToString(), category.Id);
                    unitOfWork.Session.Save(category);
                }
                foreach (var tree in newCategoriesTreeList)
                {
                    unitOfWork.Session.Save(tree);
                }
            } else if (ReuseExistingCategories)
            {
                // Get used categories names and ids (key id, value name)
                var catNames = new Dictionary<string, string>();
                foreach (var blog in blogs)
                {
                    for (int i = 0; i < blog.Categories.Count; i++)
                    {
                        var categoryId = blog.Categories[i].Ref;
                        if (!catNames.ContainsKey(categoryId) && blogs.Any(t => BlogHasCategory(t, categoryId)))
                        {
                            catNames.Add(categoryId, (categories.FirstOrDefault(t => t.ID == categoryId) ?? new BlogMLCategory()).Title);
                        }
                    }
                }

                var existingCategoriesByIdsFuture = repository.AsQueryable<Category>().Where(t => catNames.Keys.Contains(t.Id.ToString())).ToFuture();
                var existingCategoriesByNamesFuture = repository.AsQueryable<Category>().Where(t => catNames.Values.Contains(t.Name)).ToFuture();
                // Get categories by ids
                var existingCategoriesByIds = existingCategoriesByIdsFuture.ToList();
                // Get categories by names
                var existingCategoriesByNames = existingCategoriesByNamesFuture.ToList();
                foreach (var catName in catNames)
                {
                    var category = existingCategoriesByIds.FirstOrDefault(t => t.Id.ToLowerInvariantString() == catName.Key);
                    category = category ?? existingCategoriesByNames.FirstOrDefault(t => t.Name == catName.Value);
                    if (category != null)
                    {
                        dictionary.Add(catName.Key, category.Id);
                    }
                }
            }

            return dictionary;
        }