public static function get_article($condition, array $parameters)
    {
        $row = self::$db_querier->select_single_row_query('SELECT articles.*, member.*, notes.average_notes, notes.number_notes, note.note
		FROM ' . ArticlesSetup::$articles_table . ' articles
		LEFT JOIN ' . DB_TABLE_MEMBER . ' member ON member.user_id = articles.author_user_id 
		LEFT JOIN ' . DB_TABLE_AVERAGE_NOTES . ' notes ON notes.id_in_module = articles.id AND notes.module_name = \'articles\'
		LEFT JOIN ' . DB_TABLE_NOTE . ' note ON note.id_in_module = articles.id AND note.module_name = \'articles\' AND note.user_id = ' . AppContext::get_current_user()->get_id() . '
		' . $condition, $parameters);
        $article = new Article();
        $article->set_properties($row);
        return $article;
    }
    private function build_table()
    {
        $table_model = new SQLHTMLTableModel(ArticlesSetup::$articles_table, 'table', array(new HTMLTableColumn(LangLoader::get_message('form.title', 'common'), 'title'), new HTMLTableColumn(LangLoader::get_message('category', 'categories-common'), 'id_category'), new HTMLTableColumn(LangLoader::get_message('author', 'common'), 'display_name'), new HTMLTableColumn(LangLoader::get_message('form.date.creation', 'common'), 'date_created'), new HTMLTableColumn(LangLoader::get_message('status', 'common'), 'published'), new HTMLTableColumn('')), new HTMLTableSortingRule('date_created', HTMLTableSortingRule::DESC));
        $table = new HTMLTable($table_model);
        $table_model->set_caption($this->lang['articles_management']);
        $results = array();
        $result = $table_model->get_sql_results('articles
			LEFT JOIN ' . DB_TABLE_AVERAGE_NOTES . ' notes ON notes.id_in_module = articles.id AND notes.module_name = \'articles\'
			LEFT JOIN ' . DB_TABLE_NOTE . ' note ON note.id_in_module = articles.id AND note.module_name = \'articles\' AND note.user_id = ' . AppContext::get_current_user()->get_id() . '
			LEFT JOIN ' . DB_TABLE_MEMBER . ' member ON member.user_id = articles.author_user_id', array('*', 'articles.id'));
        foreach ($result as $row) {
            $article = new Article();
            $article->set_properties($row);
            $category = $article->get_category();
            $user = $article->get_author_user();
            $edit_link = new LinkHTMLElement(ArticlesUrlBuilder::edit_article($article->get_id()), '', array('title' => LangLoader::get_message('edit', 'common')), 'fa fa-edit');
            $delete_link = new LinkHTMLElement(ArticlesUrlBuilder::delete_article($article->get_id()), '', array('title' => LangLoader::get_message('delete', 'common'), 'data-confirmation' => 'delete-element'), 'fa fa-delete');
            $user_group_color = User::get_group_color($user->get_groups(), $user->get_level(), true);
            $author = $user->get_id() !== User::VISITOR_LEVEL ? new LinkHTMLElement(UserUrlBuilder::profile($user->get_id()), $user->get_display_name(), !empty($user_group_color) ? array('style' => 'color: ' . $user_group_color) : array(), UserService::get_level_class($user->get_level())) : $user->get_display_name();
            $br = new BrHTMLElement();
            $dates = '';
            if ($article->get_publishing_start_date() != null && $article->get_publishing_end_date() != null) {
                $dates = LangLoader::get_message('form.date.start', 'common') . ' ' . $article->get_publishing_start_date()->format(Date::FORMAT_DAY_MONTH_YEAR_HOUR_MINUTE) . $br->display() . LangLoader::get_message('form.date.end', 'common') . ' ' . $article->get_publishing_end_date()->format(Date::FORMAT_DAY_MONTH_YEAR_HOUR_MINUTE);
            } else {
                if ($article->get_publishing_start_date() != null) {
                    $dates = $article->get_publishing_start_date()->format(Date::FORMAT_DAY_MONTH_YEAR_HOUR_MINUTE);
                } else {
                    if ($article->get_publishing_end_date() != null) {
                        $dates = LangLoader::get_message('until', 'main') . ' ' . $article->get_publishing_end_date()->format(Date::FORMAT_DAY_MONTH_YEAR_HOUR_MINUTE);
                    }
                }
            }
            $start_and_end_dates = new SpanHTMLElement($dates, array(), 'smaller');
            $results[] = new HTMLTableRow(array(new HTMLTableRowCell(new LinkHTMLElement(ArticlesUrlBuilder::display_article($category->get_id(), $category->get_rewrited_name(), $article->get_id(), $article->get_rewrited_title()), $article->get_title()), 'left'), new HTMLTableRowCell(new LinkHTMLElement(ArticlesUrlBuilder::display_category($category->get_id(), $category->get_rewrited_name()), $category->get_name())), new HTMLTableRowCell($author), new HTMLTableRowCell($article->get_date_created()->format(Date::FORMAT_DAY_MONTH_YEAR_HOUR_MINUTE)), new HTMLTableRowCell($article->get_status() . $br->display() . ($dates ? $start_and_end_dates->display() : '')), new HTMLTableRowCell($edit_link->display() . $delete_link->display())));
        }
        $table->set_rows($table_model->get_number_of_matching_rows(), $results);
        $this->view->put('table', $table->display());
    }
    private function build_view($request)
    {
        $now = new Date();
        $authorized_categories = ArticlesService::get_authorized_categories(Category::ROOT_CATEGORY);
        $config = ArticlesConfig::load();
        $mode = $request->get_getstring('sort', 'desc');
        $field = $request->get_getstring('field', 'date');
        $sort_mode = $mode == 'asc' ? 'ASC' : 'DESC';
        switch ($field) {
            case 'title':
                $sort_field = 'title';
                break;
            case 'view':
                $sort_field = 'number_view';
                break;
            case 'com':
                $sort_field = 'number_comments';
                break;
            case 'note':
                $sort_field = 'average_notes';
                break;
            case 'author':
                $sort_field = 'display_name';
                break;
            default:
                $sort_field = 'date_created';
                break;
        }
        $condition = 'WHERE id_category IN :authorized_categories
		' . (!ArticlesAuthorizationsService::check_authorizations()->moderation() ? ' AND author_user_id = :user_id' : '') . '
		AND (published = 0 OR (published = 2 AND (publishing_start_date > :timestamp_now OR (publishing_end_date != 0 AND publishing_end_date < :timestamp_now))))';
        $parameters = array('authorized_categories' => $authorized_categories, 'user_id' => AppContext::get_current_user()->get_id(), 'timestamp_now' => $now->get_timestamp());
        $page = AppContext::get_request()->get_getint('page', 1);
        $pagination = $this->get_pagination($condition, $parameters, $field, $mode, $page);
        $result = PersistenceContext::get_querier()->select('SELECT articles.*, member.*, com.number_comments, notes.number_notes, notes.average_notes, note.note 
		FROM ' . ArticlesSetup::$articles_table . ' articles
		LEFT JOIN ' . DB_TABLE_MEMBER . ' member ON member.user_id = articles.author_user_id
		LEFT JOIN ' . DB_TABLE_COMMENTS_TOPIC . ' com ON com.id_in_module = articles.id AND com.module_id = "articles"
		LEFT JOIN ' . DB_TABLE_AVERAGE_NOTES . ' notes ON notes.id_in_module = articles.id AND notes.module_name = "articles"
		LEFT JOIN ' . DB_TABLE_NOTE . ' note ON note.id_in_module = articles.id AND note.module_name = "articles" AND note.user_id = :user_id
		' . $condition . '
		ORDER BY ' . $sort_field . ' ' . $sort_mode . '
		LIMIT :number_items_per_page OFFSET :display_from', array_merge($parameters, array('number_items_per_page' => $pagination->get_number_items_per_page(), 'display_from' => $pagination->get_display_from())));
        $nbr_articles_pending = $result->get_rows_count();
        $this->build_form($field, $mode);
        $this->view->put_all(array('C_PENDING' => true, 'C_MOSAIC' => $config->get_display_type() == ArticlesConfig::DISPLAY_MOSAIC, 'C_NO_ARTICLE_AVAILABLE' => $nbr_articles_pending == 0));
        if ($nbr_articles_pending > 0) {
            $this->view->put_all(array('C_ARTICLES_FILTERS' => true, 'C_COMMENTS_ENABLED' => $config->are_comments_enabled(), 'C_NOTATION_ENABLED' => $config->is_notation_enabled(), 'C_PAGINATION' => $pagination->has_several_pages(), 'PAGINATION' => $pagination->display()));
            while ($row = $result->fetch()) {
                $article = new Article();
                $article->set_properties($row);
                $this->build_keywords_view($article);
                $this->view->assign_block_vars('articles', $article->get_tpl_vars());
                $this->build_sources_view($article);
            }
        }
        $result->dispose();
        $this->view->put('FORM', $this->form->display());
    }
    private function build_articles_listing_view(Date $now, $field, $mode, $page, $subcategories_page)
    {
        $sort_mode = $mode == 'asc' ? 'ASC' : 'DESC';
        switch ($field) {
            case 'title':
                $sort_field = 'title';
                break;
            case 'view':
                $sort_field = 'number_view';
                break;
            case 'com':
                $sort_field = 'number_comments';
                break;
            case 'note':
                $sort_field = 'average_notes';
                break;
            case 'author':
                $sort_field = 'display_name';
                break;
            default:
                $sort_field = 'date_created';
                break;
        }
        $condition = 'WHERE id_category = :id_category 
		AND (published = 1 OR (published = 2 AND publishing_start_date < :timestamp_now AND (publishing_end_date > :timestamp_now OR publishing_end_date = 0)))';
        $parameters = array('id_category' => $this->get_category()->get_id(), 'timestamp_now' => $now->get_timestamp());
        $pagination = $this->get_pagination($condition, $parameters, $field, $mode, $page, $subcategories_page);
        $result = PersistenceContext::get_querier()->select('SELECT articles.*, member.*, com.number_comments, notes.average_notes, notes.number_notes, note.note
		FROM ' . ArticlesSetup::$articles_table . ' articles
		LEFT JOIN ' . DB_TABLE_MEMBER . ' member ON member.user_id = articles.author_user_id
		LEFT JOIN ' . DB_TABLE_COMMENTS_TOPIC . ' com ON com.id_in_module = articles.id AND com.module_id = \'articles\'
		LEFT JOIN ' . DB_TABLE_AVERAGE_NOTES . ' notes ON notes.id_in_module = articles.id AND notes.module_name = \'articles\'
		LEFT JOIN ' . DB_TABLE_NOTE . ' note ON note.id_in_module = articles.id AND note.module_name = \'articles\' AND note.user_id = :user_id
		' . $condition . '
		ORDER BY ' . $sort_field . ' ' . $sort_mode . '
		LIMIT :number_items_per_page OFFSET :display_from', array_merge($parameters, array('user_id' => AppContext::get_current_user()->get_id(), 'number_items_per_page' => $pagination->get_number_items_per_page(), 'display_from' => $pagination->get_display_from())));
        $this->view->put_all(array('C_MOSAIC' => $this->config->get_display_type() == ArticlesConfig::DISPLAY_MOSAIC, 'C_COMMENTS_ENABLED' => $this->config->are_comments_enabled(), 'C_NOTATION_ENABLED' => $this->config->is_notation_enabled(), 'C_ARTICLES_FILTERS' => true, 'C_DISPLAY_CATS_ICON' => $this->config->are_cats_icon_enabled(), 'C_PAGINATION' => $pagination->has_several_pages(), 'C_NO_ARTICLE_AVAILABLE' => $result->get_rows_count() == 0, 'C_ONE_ARTICLE_AVAILABLE' => $result->get_rows_count() == 1, 'C_TWO_ARTICLES_AVAILABLE' => $result->get_rows_count() == 2, 'PAGINATION' => $pagination->display(), 'ID_CAT' => $this->get_category()->get_id(), 'U_EDIT_CATEGORY' => $this->get_category()->get_id() == Category::ROOT_CATEGORY ? ArticlesUrlBuilder::configuration()->rel() : ArticlesUrlBuilder::edit_category($this->get_category()->get_id())->rel()));
        while ($row = $result->fetch()) {
            $article = new Article();
            $article->set_properties($row);
            $this->build_keywords_view($article);
            $this->view->assign_block_vars('articles', $article->get_tpl_vars());
            $this->build_sources_view($article);
        }
        $result->dispose();
    }