Knowledge Base Module Development for 1C-Bitrix
A knowledge base differs from an FAQ in structural depth: it is a hierarchy of sections, full-featured articles with formatting, search, and versioning. An FAQ is a flat list of answers to specific questions. A knowledge base is documentation, guides, and instructions with cross-references. Building it on infoblocks is possible, but "Change History", "Print Version", "Helpfulness Rating", and support integration are all separate development tasks.
Data Model
Module vendor.knowledgebase:
-
b_vendor_kb_section— sections: id, parent_id, name, slug, description, sort, icon, access_level (public/registered/group), is_active -
b_vendor_kb_article— articles: id, section_id, title, slug, body (HTML/Markdown), excerpt, author_id, status (draft/review/published), views, helpful_count, not_helpful_count, created_at, updated_at, published_at -
b_vendor_kb_revision— article revisions: id, article_id, body, author_id, created_at, change_summary -
b_vendor_kb_attachment— article file attachments: id, article_id, file_id, name -
b_vendor_kb_tagandb_vendor_kb_article_tag— tags and relationships
Article Versioning
A new revision is created on every save:
class ArticleService
{
public function update(int $articleId, array $fields, int $editorId, string $changeSummary = ''): void
{
$current = ArticleTable::getById($articleId)->fetch();
// Save the previous version
RevisionTable::add([
'ARTICLE_ID' => $articleId,
'BODY' => $current['BODY'],
'AUTHOR_ID' => $editorId,
'CHANGE_SUMMARY' => $changeSummary ?: 'Update',
'CREATED_AT' => new DateTime(),
]);
// Update the main record
ArticleTable::update($articleId, array_merge($fields, [
'UPDATED_AT' => new DateTime(),
]));
}
public function rollback(int $articleId, int $revisionId): void
{
$revision = RevisionTable::getById($revisionId)->fetch();
$this->update($articleId, ['BODY' => $revision['BODY']], 0, 'Rollback to revision #' . $revisionId);
}
}
Version history is stored indefinitely. To save space, old revisions can be archived by an agent (keeping the last N + monthly snapshots).
Section Hierarchy and Navigation
Sections build a tree of unlimited nesting (adjacency list, parent_id). Breadcrumbs and sidebar navigation are built recursively from the tree. For performance the entire tree is cached with the tag kb_tree:
$tree = \Vendor\KB\TreeBuilder::getTree(); // from cache or from DB
// When any section changes: Cache::invalidateTag('kb_tree')
Full-Text Search
Search across article titles and bodies via PostgreSQL:
-- When an article is published/updated
UPDATE b_vendor_kb_article
SET fts_vector = to_tsvector('english', title || ' ' || strip_tags(body))
WHERE id = :id;
-- Search query
SELECT id, title, ts_headline('english', body, q) AS excerpt
FROM b_vendor_kb_article, to_tsquery('english', :query) q
WHERE fts_vector @@ q AND status = 'published'
ORDER BY ts_rank(fts_vector, q) DESC
LIMIT 20;
Results are returned with an automatically generated excerpt with highlighted matches (ts_headline).
Access Control
Section access_level:
-
public— available to everyone -
registered— only for authenticated users -
group— only for users in a specified Bitrix group (theaccess_groupsfield in the section)
Inheritance: if a section is restricted, all its child sections and articles are automatically restricted. The check happens in the component middleware.
Print Version and PDF
The vendor:kb.article.print component delivers the page without navigation, optimized for printing. PDF generation is done via mPDF; a "Download PDF" link is added to each article. The PDF is cached in the filesystem and invalidated when the article is updated.
Integration with the Ticket System
When viewing an article — a block "Didn't find an answer? Open a ticket". The ticket is created in vendor.tickets (the ticket system module) with the "link to KB article" field pre-filled. This allows support staff to see the context of the request.
Development Timeline
| Stage | Duration |
|---|---|
| ORM tables, section hierarchy | 1 day |
| Article versioning, rollback | 2 days |
| Full-text search (PostgreSQL tsvector) | 2 days |
| Access control | 1 day |
| Print version, PDF | 1 day |
| Site components (list, article, search) | 2 days |
| Admin interface | 2 days |
| Testing | 1 day |
Total: 12 working days. Integration with the ticket system — +1 day.







