Пример #1
0
        public static IHtmlControl GetDialogueView(SiteState state,
                                                   IDataLayer forumConnection, UserStorage userStorage, LightObject user, out string title)
        {
            title = "Диалоги";

            TableLink dialogueLink = DialogueHlp.LoadDialogueLink(forumConnection,
                                                                  "user_id = @userId order by modify_time desc",
                                                                  new DbParameter("userId", user.Id)
                                                                  );

            IHtmlControl[] messageBlocks = new IHtmlControl[dialogueLink.AllRows.Length];
            int            i             = -1;

            foreach (RowLink dialog in dialogueLink.AllRows)
            {
                ++i;
                messageBlocks[i] = GetDialogBlock(forumConnection, userStorage, user, dialog, i);
            }

            return(new HPanel(
                       Decor.Title("Диалоги"),
                       new HPanel(
                           messageBlocks
                           )
                       ));
        }
Пример #2
0
        public static void SendMessage(BasketballContext context, int senderId, int recipientId, string content)
        {
            IDataLayer forumConnection = context.ForumConnection;

            DateTime createTime = DateTime.UtcNow;

            if (senderId != recipientId)
            {
                DialogueHlp.InsertMessage(forumConnection, recipientId, senderId, true, content, createTime);
            }
            DialogueHlp.InsertMessage(forumConnection, senderId, recipientId, false, content, createTime);

            if (senderId != recipientId)
            {
                DialogueHlp.UpdateDialog(forumConnection, recipientId, senderId, true, content, createTime);
            }
            DialogueHlp.UpdateDialog(forumConnection, senderId, recipientId, false, content, createTime);

            context.UpdateUnreadDialogs();
        }
Пример #3
0
        public static IHtmlControl GetAddPanel(BasketballContext context, SiteState state,
                                               LightObject user, LightObject collocutor, bool sendFromUserView)
        {
            if (user == null)
            {
                return(null);
            }

            if (user.Id == collocutor.Id)
            {
                return(null);
            }

            IHtmlControl editPanel = null;

            if (state.BlockHint == "messageAdd")
            {
                string commentValue = BasketballHlp.AddCommentFromCookie();

                editPanel = new HPanel(
                    new HTextArea("messageContent", commentValue).BoxSizing().Width("100%")
                    .Height("10em").MarginTop(5).MarginBottom(5),
                    Decor.Button("отправить")
                    .OnClick(BasketballHlp.AddCommentToCookieScript("messageContent"))
                    .Event("message_add_save", "messageData",
                           delegate(JsonData json)
                {
                    string content = json.GetText("messageContent");
                    if (StringHlp.IsEmpty(content))
                    {
                        return;
                    }

                    DialogueHlp.SendMessage(context, user.Id, collocutor.Id, content);

                    state.BlockHint = "";

                    BasketballHlp.ResetAddComment();

                    if (sendFromUserView)
                    {
                        state.Operation.Message = "Сообщение успешно отправлено";
                    }
                }
                           ),
                    new HElementControl(
                        h.Script(h.type("text/javascript"), "$('.messageContent').focus();"),
                        ""
                        )
                    ).EditContainer("messageData");
            }

            HButton moderatorButton = null;
            HPanel  moderatorPanel  = null;

            if (!sendFromUserView)
            {
                moderatorButton = new HButton("",
                                              std.BeforeAwesome(@"\f1e2", 0)
                                              ).PositionAbsolute().Right(5).Top(0)
                                  .Title("Модерирование личных сообщений").FontSize(14)
                                  .Color(state.BlockHint == correspondenceModeration ? Decor.redColor : Decor.disabledColor)
                                  .Event("correspondence_moderation_set", "", delegate
                {
                    state.SetBlockHint(correspondenceModeration);
                });

                if (state.BlockHint == correspondenceModeration)
                {
                    bool lockedCollocutor = user.Get(BasketballUserType.LockedUserIds, collocutor.Id);
                    moderatorPanel = new HPanel(
                        Decor.ButtonMidi(!lockedCollocutor ? "Заблокировать собеседника" : "Разблокировать собеседника")
                        .Event("collocutor_locked", "", delegate
                    {
                        LightObject editUser = DataBox.LoadObject(context.UserConnection, UserType.User, user.Id);
                        editUser.Set(BasketballUserType.LockedUserIds, collocutor.Id, !lockedCollocutor);
                        editUser.Box.Update();
                        context.UserStorage.Update();
                    }),
                        new HSpoiler(Decor.ButtonMidi("Удаление переписки").Block().FontBold(false),
                                     new HPanel(
                                         Decor.ButtonMidi("Удалить? (без подтверждения)")
                                         .MarginTop(5).MarginLeft(10)
                                         .Event("correspondence_delete", "", delegate
                    {
                        context.ForumConnection.GetScalar("",
                                                          "Delete From correspondence Where user_id = @userId and collocutor_id = @collocutorId",
                                                          new DbParameter("userId", user.Id), new DbParameter("collocutorId", collocutor.Id)
                                                          );

                        context.ForumConnection.GetScalar("",
                                                          "Delete From dialogue Where user_id = @userId and collocutor_id = @collocutorId",
                                                          new DbParameter("userId", user.Id), new DbParameter("collocutorId", collocutor.Id)
                                                          );

                        context.UpdateUnreadDialogs();
                    })
                                         )
                                     ).MarginTop(10)
                        ).MarginTop(10);
                }
            }

            bool locked = user.Get(BasketballUserType.LockedUserIds, collocutor.Id) ||
                          collocutor.Get(BasketballUserType.LockedUserIds, user.Id);

            return(new HPanel(
                       new HPanel(
                           Decor.ButtonMidi("Написать сообщение")
                           .Hide(locked)
                           .Event("message_add", "", delegate
            {
                state.SetBlockHint("messageAdd");
            }
                                  ),
                           new HLabel("Вы не можете отправить сообщение этому пользователю").Hide(!locked)
                           .MarginLeft(10).Color(Decor.subtitleColor),
                           moderatorButton
                           ).PositionRelative(),
                       editPanel,
                       moderatorPanel
                       ).MarginTop(10).MarginBottom(10));
        }
Пример #4
0
        public static IHtmlControl GetCorrespondenceView(SiteState state,
                                                         IDataLayer forumConnection, LightObject user, LightObject collocutor, out string title)
        {
            title = "Личные сообщения";

            int pageIndex    = state.Option.Get(OptionType.CorrespondencePageIndex);
            int messageCount = DatabaseHlp.RowCount(forumConnection, "", "correspondence",
                                                    "user_id = @userId and collocutor_id = @collocutorId",
                                                    new DbParameter("userId", user.Id), new DbParameter("collocutorId", collocutor.Id)
                                                    );
            int pageCount = BinaryHlp.RoundUp(messageCount, 5);

            HButton prevButton = null;

            if (pageCount - 1 > pageIndex)
            {
                prevButton = Decor.ButtonMidi("предыдущие").Event("page_prev", "",
                                                                  delegate
                {
                    state.Option.Set(OptionType.CorrespondencePageIndex, pageIndex + 1);
                }
                                                                  );
            }

            HButton nextButton = null;

            if (pageIndex > 0)
            {
                nextButton = Decor.ButtonMidi("следующие").Event("page_next", "",
                                                                 delegate
                {
                    state.Option.Set(OptionType.CorrespondencePageIndex, pageIndex - 1);
                }
                                                                 );
            }

            TableLink messageLink = DialogueHlp.LoadCorrespondenceLink(forumConnection,
                                                                       string.Format("user_id = @userId and collocutor_id = @collocutorId order by create_time desc limit 5 offset {0}",
                                                                                     pageIndex * 5
                                                                                     ),
                                                                       new DbParameter("userId", user.Id), new DbParameter("collocutorId", collocutor.Id)
                                                                       );

            RowLink[]           messages      = messageLink.AllRows;
            List <IHtmlControl> messageBlocks = new List <IHtmlControl>();

            if (prevButton != null || nextButton != null)
            {
                messageBlocks.Add(
                    new HPanel(
                        new HPanel(prevButton), new HPanel(nextButton)
                        ).MarginTop(5).MarginBottom(5)
                    );
            }

            for (int i = messages.Length - 1; i >= 0; --i)
            {
                //if (i == 2)
                //  messageBlocks.Add(new HAnchor("bottom"));

                messageBlocks.Add(GetMessageBlock(forumConnection, state, user, collocutor, messages[i], i));
            }

            IHtmlControl addPanel = GetAddPanel(context, state, user, collocutor, false);

            return(new HPanel(
                       GetCorrespondenceHeader(state, user, collocutor),
                       new HPanel(
                           messageBlocks.ToArray()
                           ).BorderBottom(Decor.bottomBorder),
                       addPanel
                       ));
        }
Пример #5
0
        static HElement Page(HttpContext httpContext, SiteState state, string kind, int?id)
        {
            UserHlp.DirectAuthorization(httpContext, SiteContext.Default.SiteSettings);

            LightObject currentUser = UserHlp.GetCurrentUser(httpContext, SiteContext.Default.UserStorage);

            if (currentUser != null && (BasketballHlp.IsBanned(currentUser) || currentUser.Get(UserType.NotConfirmed)))
            {
                currentUser = null;
                httpContext.Logout();
            }

            state.EditMode = httpContext.IsInRole("edit");
            state.SeoMode  = httpContext.IsInRole("seo");
            state.UserMode = currentUser != null;

            int[] foundTagIds = state.Option.Get(OptionType.FoundTagIds);
            if (foundTagIds != null && foundTagIds.Length > 0)
            {
                kind = "search";
                id   = null;
            }

            IHtmlControl adminSectionPanel = null;

            if (kind == "page")
            {
                LightSection section = store.Sections.FindSection(id);
                adminSectionPanel = DecorEdit.AdminSectionPanel(
                    state.EditMode, state.SeoMode, kind, section, false
                    );
            }

            IHtmlControl dialogBox = null;

            if (!StringHlp.IsEmpty(state.Operation.Message))
            {
                dialogBox = DecorEdit.GetDialogBox(state);
            }

            bool isForum = kind == "topic";

            if (kind == "page")
            {
                LightSection pageSection = store.Sections.FindSection(id);
                string       designKind  = pageSection.Get(SectionType.DesignKind);
                if (pageSection != null && (designKind == "forum" || designKind == "forumSection"))
                {
                    isForum = true;
                }
            }


            string    title       = "";
            string    description = "";
            SchemaOrg schema      = null;
            bool      wideContent;

            IHtmlControl centerView = ViewHlp.GetCenter(httpContext,
                                                        state, currentUser, kind, id, out title, out description, out schema, out wideContent
                                                        );

            if (centerView == null && StringHlp.IsEmpty(state.RedirectUrl))
            {
                return(null);
            }

            BasketballContext context = (BasketballContext)SiteContext.Default;

            try
            {
                if (currentUser != null && kind == "dialog" && id != null)
                {
                    if (context.UnreadDialogLink.FindRow(DialogReadType.UnreadByUserId, currentUser.Id) != null)
                    {
                        DialogueHlp.MarkReadCorrespondence(context.ForumConnection, currentUser.Id, id.Value);
                        context.UpdateUnreadDialogs();
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.WriteException(ex);
            }

            HEventPanel mainPanel = new HEventPanel(
                new HPanel(
                    new HAnchor("top"),
                    DecorEdit.AdminMainPanel(SiteContext.Default.SiteSettings, httpContext),
                    ViewHeaderHlp.GetHeader(httpContext, state, currentUser, kind, id, isForum),
                    adminSectionPanel,
                    new HPanel(
                        new HPanel(
                            centerView,
                            new HPanel(
                                ViewRightColumnHlp.GetRightColumnView(state, isForum).InlineBlock().MarginRight(15)
                                .MediaLaptop(new HStyle().Block().MarginRight(0))
                                .MediaTablet(new HStyle().InlineBlock().MarginRight(15))
                                .MediaSmartfon(new HStyle().Width("100%").MarginRight(0)),
                                ViewRightColumnHlp.GetReclameColumnView(state).InlineBlock().VAlign(true)
                                ).Hide(wideContent).PositionAbsolute().Top(13).Right(15)
                            .MediaTablet(new HStyle().Position("static").MarginTop(15))
                            //.MediaSmartfon(new HStyle().Width("100%"))
                            ).PositionRelative().Align(true)
                        .Padding(15).PaddingRight(485)
                        .WidthLimit("", kind == "" ? "727px" : "892px")
                        .MediaLaptop(new HStyle().PaddingRight(250))
                        .MediaTablet(new HStyle().PaddingRight(15))
                        .MediaSmartfon(new HStyle().PaddingLeft(5).PaddingRight(5))
                        ).MarginLeft(12).MarginRight(12).PaddingBottom(160).Background(Decor.panelBackground)
                    .BoxSizing().HeightLimit("900px", "")
                    .MediaTablet(new HStyle().MarginLeft(0).MarginRight(0))
                    ),
                ViewHlp.GetFooterView(kind == ""),
                dialogBox
                //popupPanel
                ).Width("100%").BoxSizing().Align(null).Background(Decor.pageBackground)
                                    .Padding(1)
                                    .FontFamily("Tahoma").FontSize(12); //.Color(Decor.textColor);

            if (!StringHlp.IsEmpty(state.PopupHint) || dialogBox != null)
            {
                mainPanel.OnClick(";");
                mainPanel.Event("popup_reset", "", delegate
                {
                    state.PopupHint = "";
                    state.Operation.Reset();
                });
            }

            StringBuilder css = new StringBuilder();

            std.AddStyleForFileUploaderButtons(css);

            HElement mainElement = mainPanel.ToHtml("main", css);

            SiteSettings settings = SiteContext.Default.SiteSettings;

            //string blockHint = state.BlockHint;
            //bool withCkeditor = false;
            //if (!StringHlp.IsEmpty(blockHint))
            //{
            //  withCkeditor = blockHint == "news_add" || blockHint.StartsWith("article_edit_") ||
            //    blockHint.StartsWith("news_edit_");
            //}
            //bool withFileuploader = kind == "user" || withCkeditor;

            return(h.Html
                   (
                       h.Head(
                           h.Element("title", title),
                           h.MetaDescription(description),
                           h.LinkCss(UrlHlp.FileUrl("/css/static.css")),
                           h.LinkShortcutIcon("/images/favicon.ico"),
                           h.Meta("viewport", "width=device-width"),
                           //h.LinkCss("/css/font-awesome.css"),
                           //h.LinkCss("/css/fileuploader.css"),
                           h.LinkScript("/scripts/fileuploader.js"),
                           h.LinkScript("/ckeditor/ckeditor.js?v=4113"),
                           HtmlHlp.CKEditorUpdateAll(),
                           h.Raw(store.SeoWidgets.WidgetsCode),
                           HtmlHlp.SchemaOrg(schema),
                           h.OpenGraph("type", "website"),
                           h.OpenGraph("title", title),
                           h.OpenGraph("url", description),
                           h.OpenGraph("site_name", settings.Organization),
                           h.OpenGraph("image", settings.FullUrl("/images/logo_mini.jpg"))
                           ),
                       h.Body(
                           h.Css(h.Raw(css.ToString())),
                           h.Div(
                               HtmlHlp.RedirectScript(state.RedirectUrl)
                               ),
                           //h.Div(
                           //  withFileuploader ? h.LinkScript("/scripts/fileuploader.js") : null,
                           //  withCkeditor ? h.LinkScript("/ckeditor/ckeditor.js") : null,
                           //  withCkeditor ? HtmlHlp.CKEditorUpdateAll() : null
                           //),
                           mainElement
                           //withEditor ? h.Script(h.type("text/javascript"), "console.log('withScript');") : null,
                           //!withFileuploader && withEditor ? h.LinkScript("/scripts/fileuploader.js") : null,
                           //withEditor ? h.LinkScript("/ckeditor/ckeditor.js") : null,
                           //withEditor ? HtmlHlp.CKEditorUpdateAll() : null
                           //HtmlHlp.SchemaOrg(schema),
                           )
                   ));
        }
Пример #6
0
        protected void Application_Start(object sender, EventArgs e)
        {
            string appPath   = HttpContext.Current.Server.MapPath("");
            string logFolder = ApplicationHlp.CheckAndCreateFolderPath(appPath, "Logs");

            try
            {
                Logger.EnableLogging(Path.Combine(logFolder, "site.log"), 2);

                GlobalConfiguration.Configure(WebApiConfig.Register);

                string databaseFolder = ApplicationHlp.CheckAndCreateFolderPath(appPath, "Data");

                IDataLayer userConnection = new SQLiteDataLayer(string.Format(
                                                                    connectionStringFormat, Path.Combine(databaseFolder, "user.db3")));

                IDataLayer fabricConnection = new SQLiteDataLayer(string.Format(
                                                                      connectionStringFormat, Path.Combine(databaseFolder, "fabric.db3")));

                IDataLayer messageConnection = new SQLiteDataLayer(string.Format(
                                                                       connectionStringFormat, Path.Combine(databaseFolder, "message.db3")));

                IDataLayer forumConnection = new SQLiteDataLayer(string.Format(
                                                                     connectionStringFormat, Path.Combine(databaseFolder, "forum.db3")));

                Logger.AddMessage("Подключения к базам данных успешно созданы");

                SQLiteDatabaseHlp.CheckAndCreateDataBoxTables(userConnection);
                SQLiteDatabaseHlp.CheckAndCreateDataBoxTables(fabricConnection);
                MessageHlp.CheckAndCreateMessageTables(messageConnection);
                MessageHlp.CheckAndCreateMessageTables(forumConnection);
                DialogueHlp.CheckAndCreateDialogueTables(forumConnection);

                MetaHlp.ReserveDiapasonForMetaProperty(fabricConnection);

                FabricHlp.CheckAndCreateMenu(fabricConnection, "main");

                EditorSelector sectionEditorSelector = new EditorSelector(
                    new SectionTunes("news", "Новости"),
                    new SectionTunes("articles", "Статьи"),
                    new SectionTunes("forum", "Форум"),
                    new SectionTunes("rules", "Правила").Link(),
                    new SectionTunes("forumSection", "Раздел форума")
                    );

                EditorSelector unitEditorSelector = new EditorSelector(
                    new UnitTunes("reclame", "Рекламный блок").Tile().ImageAlt().Link().Annotation()
                    );

                Shop.Engine.Site.Novosti         = "news";
                Shop.Engine.Site.DirectPageLinks = true;
                //Shop.Engine.Site.AddFolderForNews = true;

                try
                {
                    string fabricScriptPath = Path.Combine(appPath, "FabricScript.sql");
                    if (File.Exists(fabricScriptPath))
                    {
                        string script = File.ReadAllText(fabricScriptPath);
                        Logger.AddMessage("Выполняем стартовый скрипт для fabric.db3: {0}", script);
                        fabricConnection.GetScalar("", script);
                    }

                    string userScriptPath = Path.Combine(appPath, "UserScript.sql");
                    if (File.Exists(userScriptPath))
                    {
                        string script = File.ReadAllText(userScriptPath);
                        Logger.AddMessage("Выполняем стартовый скрипт для user.db3: {0}", script);
                        userConnection.GetScalar("", script);
                    }
                }
                catch (Exception ex)
                {
                    Logger.WriteException(ex, "Ошибка при выполнении стартового скрипта");
                }

                SiteContext.Default = new BasketballContext(
                    appPath, sectionEditorSelector, unitEditorSelector,
                    userConnection, fabricConnection, messageConnection, forumConnection
                    );

                SiteContext.Default.Pull.StartTask(Labels.Service,
                                                   MemoryChecker((BasketballContext)SiteContext.Default)
                                                   );

                SiteContext.Default.Pull.StartTask(Labels.Service,
                                                   SiteTasks.CleaningSessions(SiteContext.Default,
                                                                              TimeSpan.FromHours(1), TimeSpan.FromMinutes(10), TimeSpan.FromMinutes(1)
                                                                              )
                                                   );
            }
            catch (Exception ex)
            {
                Logger.WriteException(ex, "Ошибка создания подключения к базе данных:");
            }
        }
Пример #7
0
        public BasketballContext(string rootPath,
                                 EditorSelector sectionEditorSelector, EditorSelector unitEditorSelector,
                                 IDataLayer userConnection, IDataLayer fabricConnection,
                                 IDataLayer messageConnection, IDataLayer forumConnection)
        {
            this.rootPath              = rootPath;
            this.imagesPath            = Path.Combine(RootPath, "Images");
            this.userConnection        = userConnection;
            this.fabricConnection      = fabricConnection;
            this.messageConnection     = messageConnection;
            this.forumConnection       = forumConnection;
            this.sectionEditorSelector = sectionEditorSelector;
            this.unitEditorSelector    = unitEditorSelector;

            this.userStorage     = new UserStorage(userConnection);
            this.NewsStorages    = new TopicStorageCache(fabricConnection, messageConnection, NewsType.News);
            this.ArticleStorages = new TopicStorageCache(fabricConnection, messageConnection, ArticleType.Article);
            this.Forum           = new ForumStorageCache(fabricConnection, forumConnection);

            string settingsPath = Path.Combine(rootPath, "SiteSettings.config");

            if (!File.Exists(settingsPath))
            {
                this.siteSettings = new SiteSettings();
            }
            else
            {
                this.siteSettings = XmlSerialization.Load <SiteSettings>(settingsPath);
            }

            this.pull = new TaskPull(
                new ThreadLabel[] { Labels.Service },
                TimeSpan.FromMinutes(15)
                );

            this.newsCache = new Cache <Tuple <ObjectHeadBox, LightHead[]>, long>(
                delegate
            {
                ObjectHeadBox newsBox = new ObjectHeadBox(fabricConnection,
                                                          string.Format("{0} order by act_from desc", DataCondition.ForTypes(NewsType.News))
                                                          );

                int[] allNewsIds = newsBox.AllObjectIds;

                List <LightHead> actualNews = new List <LightHead>();
                for (int i = 0; i < Math.Min(22, allNewsIds.Length); ++i)
                {
                    int newsId = allNewsIds[i];
                    actualNews.Add(new LightHead(newsBox, newsId));
                }

                return(_.Tuple(newsBox, actualNews.ToArray()));
            },
                delegate { return(newsChangeTick); }
                );

            this.articlesCache = new Cache <Tuple <ObjectBox, LightObject[]>, long>(
                delegate
            {
                ObjectBox articleBox = new ObjectBox(fabricConnection,
                                                     string.Format("{0} order by act_from desc", DataCondition.ForTypes(ArticleType.Article))
                                                     );

                int[] allArticleIds = articleBox.AllObjectIds;

                ObjectBox actualBox = new ObjectBox(FabricConnection,
                                                    string.Format("{0} order by act_from desc limit 5", DataCondition.ForTypes(ArticleType.Article))
                                                    );

                List <LightObject> actualArticles = new List <LightObject>();
                foreach (int articleId in actualBox.AllObjectIds)
                {
                    actualArticles.Add(new LightObject(actualBox, articleId));
                }

                return(_.Tuple(articleBox, actualArticles.ToArray()));
            },
                delegate { return(articleChangeTick); }
                );

            this.lightStoreCache = new Cache <IStore, long>(
                delegate
            {
                LightObject contacts = DataBox.LoadOrCreateObject(fabricConnection,
                                                                  ContactsType.Contacts, ContactsType.Kind.CreateXmlIds, "main");

                LightObject seo = DataBox.LoadOrCreateObject(fabricConnection,
                                                             SEOType.SEO, SEOType.Kind.CreateXmlIds, "main");

                SectionStorage sections = SectionStorage.Load(fabricConnection);

                WidgetStorage widgets = WidgetStorage.Load(fabricConnection, siteSettings.DisableScripts);

                RedirectStorage redirects = RedirectStorage.Load(fabricConnection);

                SiteStore store = new SiteStore(sections, null, widgets, redirects, contacts, seo);
                store.Links.AddLink("register", null);
                store.Links.AddLink("passwordreset", null);

                return(store);
            },
                delegate { return(dataChangeTick); }
                );

            this.lastPublicationCommentsCache = new Cache <RowLink[], long>(
                delegate
            {
                DataTable table = messageConnection.GetTable("",
                                                             "Select Distinct article_id From message order by create_time desc limit 10"
                                                             );

                List <RowLink> lastComments = new List <RowLink>(10);
                foreach (DataRow row in table.Rows)
                {
                    int topicId = ConvertHlp.ToInt(row[0]) ?? -1;

                    if (News.ObjectById.Exist(topicId))
                    {
                        TopicStorage topic  = NewsStorages.ForTopic(topicId);
                        RowLink lastMessage = _.Last(topic.MessageLink.AllRows);
                        if (lastMessage != null)
                        {
                            lastComments.Add(lastMessage);
                        }
                    }
                    else if (Articles.ObjectById.Exist(topicId))
                    {
                        TopicStorage topic  = ArticleStorages.ForTopic(topicId);
                        RowLink lastMessage = _.Last(topic.MessageLink.AllRows);
                        if (lastMessage != null)
                        {
                            lastComments.Add(lastMessage);
                        }
                    }
                }

                return(lastComments.ToArray());
            },
                delegate { return(publicationCommentChangeTick); }
                );

            this.lastForumCommentsCache = new Cache <RowLink[], long>(
                delegate
            {
                DataTable table = forumConnection.GetTable("",
                                                           "Select Distinct article_id From message order by create_time desc limit 7"
                                                           );

                List <RowLink> lastComments = new List <RowLink>(7);
                foreach (DataRow row in table.Rows)
                {
                    int topicId = ConvertHlp.ToInt(row[0]) ?? -1;

                    TopicStorage topic  = Forum.TopicsStorages.ForTopic(topicId);
                    RowLink lastMessage = _.Last(topic.MessageLink.AllRows);
                    if (lastMessage != null)
                    {
                        lastComments.Add(lastMessage);
                    }
                }

                return(lastComments.ToArray());
            },
                delegate { return(forumCommentChangeTick); }
                );

            this.tagsCache = new Cache <TagStore, long>(
                delegate
            {
                ObjectHeadBox tagBox = new ObjectHeadBox(fabricConnection, DataCondition.ForTypes(TagType.Tag) + " order by xml_ids asc");

                return(new TagStore(tagBox));
            },
                delegate { return(tagChangeTick); }
                );

            //this.tagsCache = new Cache<Tuple<ObjectHeadBox, Dictionary<string, int>>, long>(
            //  delegate
            //  {
            //    ObjectHeadBox tagBox = new ObjectHeadBox(fabricConnection, DataCondition.ForTypes(TagType.Tag) + " order by xml_ids asc");

            //    Dictionary<string, int> tagIdByKey = new Dictionary<string, int>();
            //    foreach (int tagId in tagBox.AllObjectIds)
            //    {
            //      string tagName = TagType.DisplayName.Get(tagBox, tagId);
            //      if (StringHlp.IsEmpty(tagName))
            //        continue;

            //      string tagKey = tagName.ToLower();
            //      tagIdByKey[tagKey] = tagId;
            //    }

            //    return _.Tuple(tagBox, tagIdByKey);
            //  },
            //  delegate { return tagChangeTick; }
            //);

            this.unreadDialogCache = new Cache <TableLink, long>(
                delegate
            {
                return(DialogueHlp.LoadUnreadLink(forumConnection));
            },
                delegate { return(unreadChangeTick); }
                );

            Pull.StartTask(Labels.Service,
                           SiteTasks.SitemapXmlChecker(this, rootPath,
                                                       delegate(LinkInfo[] sectionlinks)
            {
                List <LightLink> allLinks = new List <LightLink>();
                allLinks.AddRange(
                    ArrayHlp.Convert(sectionlinks, delegate(LinkInfo link)
                {
                    return(new LightLink(link.Directory, null));
                })
                    );

                foreach (int articleId in Articles.AllObjectIds)
                {
                    LightHead article = new LightHead(Articles, articleId);
                    allLinks.Add(
                        new LightLink(UrlHlp.ShopUrl("article", articleId),
                                      article.Get(ObjectType.ActTill) ?? article.Get(ObjectType.ActFrom)
                                      )
                        );
                }

                foreach (int newsId in News.AllObjectIds)
                {
                    LightHead news = new LightHead(News, newsId);
                    allLinks.Add(
                        new LightLink(UrlHlp.ShopUrl("news", newsId),
                                      news.Get(ObjectType.ActTill) ?? news.Get(ObjectType.ActFrom)
                                      )
                        );
                }

                //foreach (int tagId in Tags.AllObjectIds)
                //{
                //  LightHead tag = new LightHead(Tags, tagId);
                //  allLinks.Add(
                //    new LightLink(string.Format("/tags?tag={0}", tagId)
                //    )
                //  );
                //}

                return(allLinks.ToArray());
            }
                                                       )
                           );
        }