Search by

jeffersongoncalves / laravel-knowledge-base

jeffersongoncalves

A Laravel package for building knowledge bases with articles, categories, versioning, and feedback

v1.0.4 2026-05-23 17:00 UTC

README

Laravel Knowledge Base

Laravel Knowledge Base

Latest Version on Packagist GitHub Tests Action Status GitHub Code Style Action Status PHPStan Total Downloads Buy Me A Coffee

A Laravel package for building knowledge bases with articles, categories, versioning, feedback, and search.

Features

  • Article Management — Create, update, publish, archive, and soft-delete articles with UUID and slug routing
  • Hierarchical Categories — Nested parent/child categories with ordering and activation control
  • Article Versioning — Automatic version history tracking with editor attribution and change notes
  • User Feedback — Helpful/not helpful voting with optional comments, supports authenticated and anonymous users
  • Related Articles — Many-to-many article relationships with sort ordering
  • Full-Text Search — Database-powered search across published articles by title and content
  • SEO Fields — Built-in SEO title, description, and keywords per article
  • Customizable Models — Override any model via config while maintaining contract compliance
  • Table Prefix — Configurable table prefix to avoid naming collisions (default: kb_)
  • Translations — English and Brazilian Portuguese out of the box

Requirements

  • PHP 8.2+
  • Laravel 11+

Installation

composer require jeffersongoncalves/laravel-knowledge-base

Publish and run migrations:

php artisan vendor:publish --tag="knowledge-base-migrations"
php artisan migrate

Publish the config (optional):

php artisan vendor:publish --tag="knowledge-base-config"

Configuration

The config file (config/knowledge-base.php) covers:

Table Prefix

'table_prefix' => 'kb_',

Set to null to use table names without a prefix.

Custom Models

Override any model to extend the default behavior. Custom models must implement the corresponding contract:

'models' => [
    'article' => \App\Models\Article::class,
    'category' => \App\Models\Category::class,
    'article_version' => \App\Models\ArticleVersion::class,
    'article_feedback' => \App\Models\ArticleFeedback::class,
    'article_relation' => \App\Models\ArticleRelation::class,
],

Knowledge Base Settings

'default_visibility' => 'public',   // default visibility for new articles
'versioning_enabled' => true,       // track article version history
'feedback_enabled' => true,         // allow user feedback
'track_views' => true,              // track article view counts

Search

'search_engine' => 'database',      // search engine type
'search_results_limit' => 20,       // max results per search

Usage

Using the Service

The KnowledgeBaseService is the recommended way to interact with the knowledge base:

use JeffersonGoncalves\KnowledgeBase\Services\KnowledgeBaseService;

$service = app(KnowledgeBaseService::class);

Creating Categories

// Auto-generates slug from name
$category = $service->createCategory([
    'name' => 'Getting Started',
]);

// With custom slug and parent
$child = $service->createCategory([
    'name' => 'Installation',
    'slug' => 'installation-guide',
    'parent_id' => $category->id,
    'description' => 'How to install the application',
    'icon' => 'heroicon-o-wrench',
    'sort_order' => 1,
]);

// Update
$service->updateCategory($category, ['name' => 'Quick Start']);

// Delete (soft delete)
$service->deleteCategory($category);

Creating Articles

$article = $service->createArticle([
    'category_id' => $category->id,
    'title' => 'How to Install',
    'slug' => 'how-to-install',
    'content' => 'Step 1: Run composer require...',
    'excerpt' => 'Quick installation guide.',
    'visibility' => 'public',
    'seo_title' => 'Installation Guide - My App',
    'seo_description' => 'Learn how to install My App step by step.',
    'seo_keywords' => 'install, setup, getting started',
    'metadata' => ['difficulty' => 'beginner'],
], $author); // $author is any Eloquent Model (User, Admin, etc.)

This automatically:

  • Generates a UUID
  • Creates version 1 (when versioning enabled)
  • Dispatches ArticleCreated event

Updating Articles

$updated = $service->updateArticle($article, [
    'title' => 'How to Install (Updated)',
    'content' => 'Updated installation steps...',
], $editor, 'Fixed outdated instructions');

When versioning is enabled, this creates a new version entry with the editor and change notes.

Publishing & Archiving

// Publish — sets status to Published, sets published_at, dispatches ArticlePublished
$service->publishArticle($article);

// Archive — sets status to Archived
$service->archiveArticle($article);

// Delete — soft deletes
$service->deleteArticle($article);

Feedback

// Authenticated helpful feedback
$service->addFeedback($article, true, $user, 'Very clear, thank you!', '127.0.0.1');

// Anonymous not-helpful feedback
$service->addFeedback($article, false, null, 'Needs more examples');

// Anonymous without comment
$service->addFeedback($article, true);

Feedback automatically increments helpful_count or not_helpful_count on the article and dispatches ArticleFeedbackReceived.

Search

// Basic search (only published articles)
$results = $service->search('installation');

// With filters
$results = $service->search('installation', [
    'category_id' => 1,
    'visibility' => 'public',
    'limit' => 10,
]);

Results are ordered by view_count descending (most popular first).

Using Models Directly

For queries outside the service, use ModelResolver:

use JeffersonGoncalves\KnowledgeBase\Support\ModelResolver;

$articleClass = ModelResolver::article();
$categoryClass = ModelResolver::category();

// Article scopes
$published = $articleClass::published()->get();
$drafts = $articleClass::draft()->get();
$archived = $articleClass::archived()->get();
$internal = $articleClass::byVisibility(ArticleVisibility::Internal)->get();

// Category scopes
$active = $categoryClass::active()->get();
$roots = $categoryClass::root()->get();
$ordered = $categoryClass::ordered()->get();
$tree = $categoryClass::active()->root()->ordered()->get();

// Relationships
$article->category;
$article->author;
$article->versions;
$article->feedback;
$article->relatedArticles;

$category->parent;
$category->children;
$category->articles;

// View tracking
$article->incrementViewCount();

Extending Models

Create custom models that implement the required contract:

namespace App\Models;

use JeffersonGoncalves\KnowledgeBase\Models\Article as BaseArticle;
use JeffersonGoncalves\KnowledgeBase\Models\Contracts\ArticleContract;

class Article extends BaseArticle implements ArticleContract
{
    // Add custom relationships, scopes, methods...

    public function comments()
    {
        return $this->hasMany(Comment::class);
    }
}

Then update the config:

// config/knowledge-base.php
'models' => [
    'article' => \App\Models\Article::class,
    // ...
],

Events

Event Payload When
ArticleCreated $article After article creation via service
ArticlePublished $article After publishing via service
ArticleFeedbackReceived $article, $feedback After feedback submission

Listen to events in your EventServiceProvider or with listeners:

use JeffersonGoncalves\KnowledgeBase\Events\ArticlePublished;

class SendArticleNotification
{
    public function handle(ArticlePublished $event): void
    {
        // Notify subscribers about the new article
        $article = $event->article;
    }
}

Enums

ArticleStatus

Value Label (en) Label (pt_BR)
draft Draft Rascunho
published Published Publicado
archived Archived Arquivado

ArticleVisibility

Value Label (en) Label (pt_BR)
public Public Público
internal Internal Interno
use JeffersonGoncalves\KnowledgeBase\Enums\ArticleStatus;
use JeffersonGoncalves\KnowledgeBase\Enums\ArticleVisibility;

$status = ArticleStatus::Published;
$status->label(); // 'Published' or 'Publicado'

$visibility = ArticleVisibility::Internal;
$visibility->label(); // 'Internal' or 'Interno'

Database Tables

All tables use the configured prefix (default: kb_):

Table Description
kb_categories Hierarchical article categories
kb_articles Knowledge base articles
kb_article_versions Article version history
kb_article_feedback User feedback on articles
kb_article_relations Related articles (pivot)

Testing

composer test

Changelog

Please see CHANGELOG for more information on what has changed recently.

Contributing

Please see CONTRIBUTING for details.

Security Vulnerabilities

Please review our security policy on how to report security vulnerabilities.

Credits

License

The MIT License (MIT). Please see License File for more information.