### usage() usage example
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base
Example call to usage() showing returned language codes.
```php
$assets->usage($image); // ['en', 'de'] — languages whose content references it
```
--------------------------------
### applyStaffOnly usage example
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base
Example of using Visibility::applyStaffOnly() to fetch staff-only articles.
```php
$staffOnly = Visibility::applyStaffOnly(Article::query())->get();
```
--------------------------------
### Install package with Composer
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base/blob/main/README.md
Install the Laravel Knowledge Base package via Composer. Requires PHP 8.2+ and Laravel 11+.
```bash
composer require jeffersongoncalves/laravel-knowledge-base
```
--------------------------------
### search usage examples
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base
Examples of using the search method with different options: default search, limiting results, staff search with include_internal, and language-aware search with locale. The language-aware example shows accessing served_locale and served_translation properties.
```php
$results = $service->search('installation');
$popular = $service->search('installation', ['limit' => 5, 'visibility' => 'public']);
$all = $service->search('installation', ['include_internal' => true]); // staff search
```
```php
// Language-aware:
$german = $service->search('Passwort', ['locale' => 'de']);
foreach ($german as $article) {
echo $article->served_locale; // 'de', or 'en' when it fell back
echo $article->served_translation->title; // title in the served language
}
```
--------------------------------
### applyPublic usage example
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base
Example of using Visibility::applyPublic() to fetch a publicly visible article by slug.
```php
use Illuminate\Database\Eloquent\Builder;
use JeffersonGoncalves\KnowledgeBase\Support\Visibility;
$articles = Visibility::applyPublic(Article::query())->where('slug', $slug)->first();
```
--------------------------------
### resolve() usage example
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base
Example call to resolve() with forPublic set to true, showing output HTML with an asset URL.
```php
$html = $assets->resolve($translation->content, $article, forPublic: true);
echo $html; //
```
--------------------------------
### url() usage examples
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base
Two usage examples for the url() method. The first returns a plain URL for public articles or a signed URL otherwise. The second skips the visibility lookup by passing $public: true.
```php
$url = $assets->url($image); // plain for public articles, signed otherwise
$url = $assets->url($image, $public: true); // skip the visibility lookup
```
--------------------------------
### publicCategoryIds usage example
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base
Example of using Visibility::publicCategoryIds() to get the list of public category ids.
```php
$ids = Visibility::publicCategoryIds(); // e.g. [1, 3, 7]
```
--------------------------------
### articleIds usage example
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base
Shows how to call articleIds to get the ordered list of article IDs.
```php
$ids = $faq->articleIds(); // e.g. [1, 5, 3]
```
--------------------------------
### Create and manage a collection (Collection model)
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base/blob/main/README.md
Shows how to create a collection, add translations, add/reorder/remove articles, and get article IDs. A collection always has a version in default_locale, and a slug belongs to one collection in any language. Adding an article already in the collection is rejected; removing or deleting the collection never touches the article itself.
```php
use JeffersonGoncalves\KnowledgeBase\Models\Collection;
$faq = Collection::create([
'name' => 'Frequently asked questions',
'slug' => 'frequently-asked-questions',
]);
$faq->translations()->create([
'locale' => 'de',
'name' => 'Häufige Fragen',
'slug' => 'haeufige-fragen',
]);
$faq->addArticle($article); // appended at the end
$faq->addArticle($other, 0); // or at a given position
$faq->reorderArticles([$other, $article]);
$faq->removeArticle($article);
$faq->articleIds(); // the ids, in order
```
--------------------------------
### Listener example for ArticleFeedbackReceived
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base
Example listener that checks for negative feedback with a comment and notifies the author.
```php
use JeffersonGoncalves\KnowledgeBase\Events\ArticleFeedbackReceived;
class AlertOnNegativeFeedback
{
public function handle(ArticleFeedbackReceived $event): void
{
if (! $event->feedback->is_helpful && $event->feedback->comment) {
$event->feedback->article->author; // morphTo author
// notify the author about the negative comment
}
}
}
```
--------------------------------
### Using search() to find articles
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base
Example of calling search() with a query, locale, and limit, then iterating over results to access served_locale and served_translation properties.
```php
$results = $help->search('reset', 'de', 20);
foreach ($results as $article) {
echo $article->served_locale.' — '.$article->served_translation->title;
}
```
--------------------------------
### Pest Test Setup with Orchestra Testbench
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base/blob/main/resources/boost/skills/knowledge-base-development/SKILL.md
Set up Pest tests using the package's TestCase with Orchestra Testbench and SQLite in-memory database. This binds the TestCase to the Feature and Unit directories.
```php
use JeffersonGoncalves\KnowledgeBase\Tests\TestCase;
uses(TestCase::class)->in('Feature', 'Unit');
```
--------------------------------
### addFeedback usage examples
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base
Two usage examples for addFeedback: one with an authenticated user and comment, and one anonymous without a comment. The first passes a comment and IP address; the second passes only the article and helpfulness flag.
```php
// Authenticated helpful feedback with comment:
$service->addFeedback($article, true, $user, 'Very clear, thank you!', $request->ip());
```
```php
// Anonymous without comment:
$service->addFeedback($article, false, null, 'Needs more examples');
```
--------------------------------
### updateArticle usage example
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base
Example call to updateArticle with data, editor, change notes, and the flagOtherLocalesOutdated parameter set to true. When versioning is enabled, creates a new version and bumps current_version.
```php
$updated = $service->updateArticle($article, [
'title' => 'How to Install (Updated)',
'content' => 'Updated installation steps…',
], $editor, 'Fixed outdated instructions', flagOtherLocalesOutdated: true);
```
--------------------------------
### articleIsPubliclyVisible usage example
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base
Example of using Visibility::articleIsPubliclyVisible() to check if an article is public.
```php
$public = Visibility::articleIsPubliclyVisible($article); // bool
```
--------------------------------
### Create article usage example
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base
Resolves the KnowledgeBaseService singleton from the container and calls createArticle with article data and an author model. The data array accepts keys from Article::$fillable including category_id, title, content, visibility, and metadata.
```php
use JeffersonGoncalves\KnowledgeBase\Services\KnowledgeBaseService;
$service = app(KnowledgeBaseService::class);
$article = $service->createArticle([
'category_id' => $category->id,
'title' => 'How to Install',
'content' => 'Step 1: composer require …',
'visibility' => 'public',
'metadata' => ['difficulty' => 'beginner'],
], $user);
```
--------------------------------
### Listener example for ArticleCreated event
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base
Example listener that logs when an article is created. Uses the event's article properties.
```php
use JeffersonGoncalves\KnowledgeBase\Events\ArticleCreated;
class LogNewArticle
{
public function handle(ArticleCreated $event): void
{
Log::info('Knowledge base article created', [
'id' => $event->article->id,
'slug' => $event->article->slug,
]);
}
}
```
--------------------------------
### SlugOwnership::isTakenByAnother usage example
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base
Shows how to call `SlugOwnership::isTakenByAnother` to check if a slug is already used by another owner. The example checks for an `ArticleTranslation` with `article_id` and the slug `'installation-guide'`.
```php
$taken = SlugOwnership::isTakenByAnother(
ArticleTranslation::class,
'article_id',
$article->id,
'installation-guide',
);
```
--------------------------------
### categoryIsPubliclyVisible usage example
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base
Example of using Visibility::categoryIsPubliclyVisible() to abort with 404 if the category is not public.
```php
if (! Visibility::categoryIsPubliclyVisible($category)) {
abort(404);
}
```
--------------------------------
### addArticle usage examples
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base
Shows how to call addArticle to append an article at the end or insert at a specific position.
```php
$faq->addArticle($article); // appended at the end
$faq->addArticle($other, 0); // or at a given position
```
--------------------------------
### Route definition for GET /knowledge-base/assets/{asset}/{name?}
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base
Registers the only HTTP route, serving article assets. Enabled only when 'knowledge-base.attachments.route.enabled' is true. Uses the ServeArticleAsset controller, applies configured middleware, constrains 'asset' to a UUID, and names the route 'knowledge-base.assets.show'.
```php
Route::get(trim((string) config('knowledge-base.attachments.route.prefix', 'knowledge-base/assets'), '/').'/{asset}/{name?}', ServeArticleAsset::class)
->middleware((array) config('knowledge-base.attachments.route.middleware', []))
->whereUuid('asset')
->name(ArticleAssets::ROUTE); // 'knowledge-base.assets.show'
```
--------------------------------
### GET /knowledge-base/assets/{asset}/{name?}
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base
Serves an article asset file. The route is registered only when the configuration option `knowledge-base.attachments.route.enabled` is true. Access is controlled by article visibility; publicly visible articles require no signature, while all other articles require a valid signed URL.
```APIDOC
## [GET] /knowledge-base/assets/{asset}/{name?}
### Description
Serves an article asset file. The route is registered only when the configuration option `knowledge-base.attachments.route.enabled` is true. Access is controlled by article visibility; publicly visible articles require no signature, while all other articles require a valid signed URL.
### Method
GET
### Endpoint
/knowledge-base/assets/{asset}/{name?}
### Parameters
#### Path Parameters
- **asset** (string, UUID) - Required - The `uuid` of a `kb_article_assets` row. Constrained by `->whereUuid('asset')`.
- **name** (string) - Optional - The stored file name. Present only for readable URLs and downloads; the asset is looked up by `asset`, never by `name`.
### Response
#### Success Response (200)
`StreamedResponse` streaming the file from the disk recorded on the asset row (`kb_article_assets.disk` / `path`), with headers:
| Header | Value |
|--------|-------|
| `Content-Type` | The asset's stored `mime_type` |
| `X-Content-Type-Options` | `nosniff` |
| `Cache-Control` | `public, max-age={cache_max_age}` for a publicly visible article, `private, no-store` otherwise |
| `Content-Security-Policy` | `default-src 'none'; style-src 'unsafe-inline'; sandbox` — added only when the MIME type is `image/svg+xml` |
#### Error Responses
| Status | Condition |
|--------|-----------|
| 404 | No asset row with the given `uuid` |
| 404 | The asset's article is not publicly visible **and** the request has no valid signature |
| 404 | The stored file does not exist on its disk |
### Request Example
```php
// URL for a public article's image — plain, cacheable, never changes:
$url = $assets->url($image); // /knowledge-base/assets/6f1c…/fern-leaf-3fa2c1.jpg
// Signed, expiring URL for an internal/draft article's file:
$url = $assets->url($pdf); // /knowledge-base/assets//...?expires=...&signature=...
// Resolve stored content against current asset URLs (forPublic only drops dead references):
$html = $assets->resolve($translation->content, $article, forPublic: true);
```
```
--------------------------------
### resolveArticleBySlug usage example
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base
Example call to resolveArticleBySlug with a German locale. Returns null when not found, and the resolved slug may differ from the input slug, indicating a redirect.
```php
$resolved = $resolver->resolveArticleBySlug('reset', 'de');
if ($resolved === null) {
abort(404);
}
// $resolved->slug may differ from 'reset' → redirect
```
--------------------------------
### TranslationVerifier::drift usage example
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base
Shows how to instantiate `TranslationVerifier` via the container and call `drift()`. The example output indicates a drift in the `title` attribute for article #12 in English.
```php
use JeffersonGoncalves\KnowledgeBase\Support\TranslationVerifier;
$drift = app(TranslationVerifier::class)->drift();
// e.g. ['Article #12 [en] differs in [title].']
```
--------------------------------
### Locales::isConfigured() usage example
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base
Shows how to check if `'de'` is in `knowledge-base.locales`.
```php
Locales::isConfigured('de'); // whether 'de' is in knowledge-base.locales
```
--------------------------------
### Custom Article model implementing ArticleContract
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base/blob/main/README.md
Extends the base Article model and implements the required contract. Add custom relationships, scopes, or methods; the example adds a comments relationship.
```php
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);
}
}
```
--------------------------------
### createCategory usage example
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base
Creates a top-level category and a child category with parent_id, icon, and sort_order. If slug is empty, a unique slug is generated from name. Creation is not transactional and does not create a version row.
```php
$category = $service->createCategory(['name' => 'Getting Started']);
$child = $service->createCategory([
'name' => 'Installation',
'parent_id' => $category->id,
'icon' => 'heroicon-o-wrench',
'sort_order' => 1,
]);
```
--------------------------------
### reorderArticles usage example
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base
Shows how to call reorderArticles to set the order of articles in the collection.
```php
$faq->reorderArticles([$other, $article]); // $other moves to position 0
```
--------------------------------
### Combining Visibility Scopes with Other Constraints
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base/blob/main/README.md
Shows how to combine publiclyVisible() with other query constraints, such as filtering by slug, scoping a category's articles, or getting related articles. These queries are safe for customer-facing content.
```php
$article = $articleClass::publiclyVisible()->where('slug', $slug)->firstOrFail();
$articles = $category->articles()->publiclyVisible()->get();
$related = $article->relatedArticles()->publiclyVisible()->get();
```
--------------------------------
### Event::listen example for ArticlePublished
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base
Shows how to listen for the ArticlePublished event using Event::listen and access the article title.
```php
use Illuminate\Support\Facades\Event;
use JeffersonGoncalves\KnowledgeBase\Events\ArticlePublished;
Event::listen(function (ArticlePublished $event) {
notifySubscribers($event->article->title);
});
```
--------------------------------
### Locales::all() usage example
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base
Shows the expected return value when `knowledge-base.locales` is configured as `['en', 'de']`.
```php
Locales::all(); // ['en', 'de']
```
--------------------------------
### Calling incrementViewCount()
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base
Example usage that bumps view_count when track_views is enabled.
```php
$article->incrementViewCount(); // bumps view_count when track_views is enabled
```
--------------------------------
### Locales::searchLanguage() usage examples
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base
Shows the return values for configured and unconfigured locales: `'german'` for `'de'` and `'simple'` for `'fr'` when not configured.
```php
Locales::searchLanguage('de'); // 'german'
Locales::searchLanguage('fr'); // 'simple' (not configured)
```
--------------------------------
### Using query scopes to build category tree
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base
Uses ModelResolver to get the category class, then chains active(), root(), and ordered() scopes to fetch public category menus, and publiclyVisible() to get all publicly visible categories.
```php
use JeffersonGoncalves\KnowledgeBase\Support\ModelResolver;
$categoryClass = ModelResolver::category();
$tree = $categoryClass::active()->root()->ordered()->get(); // public category menus
$public = $categoryClass::publiclyVisible()->get();
```
--------------------------------
### GET /knowledge-base/assets/{asset uuid}/{file name}
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base/blob/main/README.md
Serves asset files stored on a private disk. Access is controlled based on article visibility: public articles allow direct access, while internal or restricted articles require a signed URL. The response is cacheable for a configurable duration.
```APIDOC
## [GET] /knowledge-base/assets/{asset uuid}/{file name}
### Description
Serves asset files stored on a private disk. Access is controlled based on article visibility: public articles allow direct access, while internal or restricted articles require a signed URL. The response is cacheable for a configurable duration.
### Method
GET
### Endpoint
/knowledge-base/assets/{asset uuid}/{file name}
### Parameters
#### Path Parameters
- **asset uuid** (string) - Required - The UUID of the asset.
- **file name** (string) - Required - The stored file name.
### Response
#### Success Response (200)
- **file** (binary) - The asset file content.
#### Error Response (404)
- **Not Found** - Returned when the asset is not publicly accessible and no valid signature is provided.
```
--------------------------------
### Custom Article Model Extending Base Article
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base/blob/main/resources/boost/skills/knowledge-base-development/SKILL.md
Example of a custom model that extends the package's Article model and implements the ArticleContract. Add custom methods, scopes, and relationships as needed.
```php
use JeffersonGoncalves\KnowledgeBase\Models\Article;
use JeffersonGoncalves\KnowledgeBase\Models\Contracts\ArticleContract;
class CustomArticle extends Article implements ArticleContract
{
// Add custom methods, scopes, relationships...
}
```
--------------------------------
### Generate asset URLs and resolve content with ArticleAssets
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base
Shows how to build URLs for article assets and resolve stored HTML against current URLs. Public article images get plain, cacheable URLs; internal/draft articles require signed, expiring URLs. The resolve method with forPublic: true drops dead references.
```php
// URL for a public article's image — plain, cacheable, never changes:
$url = $assets->url($image); // /knowledge-base/assets/6f1c…/fern-leaf-3fa2c1.jpg
// Signed, expiring URL for an internal/draft article's file:
$url = $assets->url($pdf); // /knowledge-base/assets//...?expires=...&signature=...
// Resolve stored content against current asset URLs (forPublic only drops dead references):
$html = $assets->resolve($translation->content, $article, forPublic: true);
```
--------------------------------
### Instantiate KnowledgeBaseService
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base/blob/main/README.md
Use the service container to resolve the KnowledgeBaseService instance, the recommended way to interact with the knowledge base.
```php
use JeffersonGoncalves\KnowledgeBase\Services\KnowledgeBaseService;
$service = app(KnowledgeBaseService::class);
```
--------------------------------
### Configure knowledge base settings
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base/blob/main/README.md
Set default visibility for new articles, enable versioning, feedback, and view tracking.
```php
'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
```
--------------------------------
### Using ModelResolver to get model classes and flush cache
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base
Shows how to retrieve the article and category model classes via ModelResolver, use their scopes, and flush the static cache after runtime config changes (e.g., in tests).
```php
use JeffersonGoncalves\KnowledgeBase\Support\ModelResolver;
$articleClass = ModelResolver::article();
$categoryClass = ModelResolver::category();
$published = $articleClass::published()->get();
$roots = $categoryClass::root()->ordered()->get();
// After changing knowledge-base.models at runtime (e.g. in tests):
ModelResolver::flushCache();
```
--------------------------------
### Full Configuration Reference for config/knowledge-base.php
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base/blob/main/resources/boost/skills/knowledge-base-development/SKILL.md
Complete configuration options for the package. 'table_prefix' can be null for no prefix. 'models' maps entity names to model classes. 'default_visibility' sets the default visibility. 'versioning_enabled', 'feedback_enabled', and 'track_views' toggle features. 'search_engine' selects the search backend, and 'search_results_limit' sets the maximum results.
```php
// config/knowledge-base.php
return [
'table_prefix' => 'kb_', // null for no prefix
'models' => [
'article' => Article::class,
'category' => Category::class,
'article_version' => ArticleVersion::class,
'article_feedback' => ArticleFeedback::class,
'article_relation' => ArticleRelation::class,
],
'default_visibility' => 'public',
'versioning_enabled' => true,
'feedback_enabled' => true,
'track_views' => true,
'search_engine' => 'database',
'search_results_limit' => 20,
];
```
--------------------------------
### Publish and run migrations
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base/blob/main/README.md
Publish the package migrations and run them. Before running migrate on an existing knowledge base, set knowledge-base.default_locale to the language of existing content (default en) to avoid mislabeling all articles and categories.
```bash
php artisan vendor:publish --tag="knowledge-base-migrations"
php artisan migrate
```
--------------------------------
### Publish config file
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base/blob/main/README.md
Optionally publish the configuration file to customize package settings.
```bash
php artisan vendor:publish --tag="knowledge-base-config"
```
--------------------------------
### Minimal public article page route using HelpCenter
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base/blob/main/README.md
Builds a public article page with locale validation, 404 on missing page, 301 redirect when redirectSlug is set, and passes the ArticlePage to a view. The package registers no routes or views, so the app handles rendering, fallback notices, hreflang alternates, and 404s.
```php
Route::get('/{locale}/help/articles/{slug}', function (string $locale, string $slug) {
abort_unless(in_array($locale, config('knowledge-base.locales'), true), 404);
$page = app(HelpCenter::class)->article($slug, $locale);
if ($page === null) {
abort(404);
}
if ($page->redirectSlug !== null) {
return redirect("/{$page->locale}/help/articles/{$page->redirectSlug}", 301);
}
return view('help.article', ['page' => $page]);
});
```
--------------------------------
### Using article() to fetch and serve an article
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base
Fetches an article by slug and locale, handles null with abort(404), redirects when redirectSlug is set, and passes page data to a view. The alternates array is intended for hreflang link tags.
```php
$page = $help->article('reset', 'de');
if ($page === null) abort(404);
if ($page->redirectSlug !== null) {
return redirect("/{$page->locale}/help/articles/{$page->redirectSlug}", 301);
}
return view('help.article', [
'page' => $page,
'isFallback' => $page->isFallback,
'alternates' => $page->alternates, // for
]);
```
--------------------------------
### brokenReferences() usage example
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base
Example call to brokenReferences() showing the return shape: an array keyed by locale with lists of deleted asset references still present in the content.
```php
$assets->brokenReferences($article); // ['de' => ['3f2a…', ...]] — deleted assets still referenced
```
--------------------------------
### Using HelpCenter to fetch categories, category, article, collection, and search
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base/blob/main/README.md
Composes visibility and language rules for public pages. Every result goes through Visibility and TranslationResolver; anything not publicly visible is reported as not found. Methods return nullable or list types as annotated.
```php
use JeffersonGoncalves\KnowledgeBase\Support\HelpCenter;
$help = app(HelpCenter::class);
$tree = $help->categories('de'); // list, with article counts
$category = $help->category('abrechnung', 'de'); // ?CategoryPage
$article = $help->article($slug, 'de'); // ?ArticlePage
$collection = $help->collection('haeufige-fragen', 'de'); // ?CollectionPage
$results = $help->search('reset', 'de', 20); // public, language-aware search results
```
--------------------------------
### updateArticleTranslation usage example
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base
Example call to update a German translation with a new title and change notes. The method edits the translation, records history, refreshes the article, and bumps current_version.
```php
$translation = $service->updateArticleTranslation($article, 'de', [
'title' => 'Passwort ändern',
], $editor, 'Wording');
```
--------------------------------
### Create an article
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base/blob/main/README.md
Create an article with optional SEO fields and metadata. Automatically generates a UUID, creates version 1 when versioning is enabled, and dispatches the ArticleCreated event.
```php
$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.)
```
--------------------------------
### Using collection() to list articles
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base
Fetches a collection by slug and locale, then iterates over its public articles to output each title in the served language.
```php
$page = $help->collection('haeufige-fragen', 'de');
foreach ($page->articles as $item) {
echo $item->translation->title; // title in the served language
}
```
--------------------------------
### Create Article with KnowledgeBaseService
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base/blob/main/resources/boost/skills/knowledge-base-development/SKILL.md
Instantiates the service via the container and creates an article. The $author parameter accepts any Eloquent Model.
```php
use JeffersonGoncalves\KnowledgeBase\Services\KnowledgeBaseService;
$service = app(KnowledgeBaseService::class);
$article = $service->createArticle([
'category_id' => $category->id,
'title' => 'Getting Started Guide',
'slug' => 'getting-started-guide',
'content' => 'Full article content here...',
'excerpt' => 'A brief summary.',
'visibility' => 'public',
], $author); // $author is any Eloquent Model
```
--------------------------------
### directory(): string
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base
Returns the root directory for all knowledge base files, trimmed of slashes.
```APIDOC
## directory(): string
### Description
Returns the root directory for all knowledge base files.
### Method
`directory()`
### Returns
- **string** - The root directory (default: `knowledge-base`).
```
--------------------------------
### Locales::missingTranslation() usage example
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base
Shows the default return value, which is `'fallback'`.
```php
Locales::missingTranslation(); // 'fallback' by default
```
--------------------------------
### Run test suite with composer test
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base/blob/main/README.md
Executes the project's test suite via Composer. Use this command to run all tests defined in the composer.json scripts.
```bash
composer test
```
--------------------------------
### deleteCategory usage example
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base
Soft-deletes the given category and returns the delete() result.
```php
$service->deleteCategory($category);
```
--------------------------------
### Run Tests with Pest
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base/blob/main/resources/boost/skills/knowledge-base-development/SKILL.md
Command to run the test suite using Pest.
```bash
php vendor/bin/pest
```
--------------------------------
### Resolve category page and handle redirect
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base
Fetches the German 'abrechnung' category page, aborts with 404 if null, issues a 301 redirect if a redirect slug exists, and otherwise renders the help category view with the page data.
```php
$page = $help->category('abrechnung', 'de');
if ($page === null) {
abort(404);
}
if ($page->redirectSlug !== null) {
return redirect("/de/categories/{$page->redirectSlug}", 301);
}
return view('help.category', [
'category' => $page->category,
'name' => $page->name,
'articles' => $page->articles,
]);
```
--------------------------------
### article() method signature
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base
Declares the public method that resolves a publicly visible article by slug and locale. Returns ?ArticlePage or null when not found.
```php
public function article(string $slug, string $locale): ?ArticlePage
```
--------------------------------
### HelpCenter::article
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base/blob/main/README.md
Resolves a single public article by slug and locale, returning the served translation and metadata.
```APIDOC
## HelpCenter::article
### Description
Resolves a single public article by slug and locale, returning the served translation and metadata.
### Method
article
### Parameters
- **slug** (string) - Required - The article slug
- **locale** (string) - Required - The language code (e.g., 'de')
### Response
Returns an ArticlePage object or null if not found. The ArticlePage includes translation, locale, isFallback, redirectSlug, alternates, breadcrumb, and related.
```
--------------------------------
### directory() method signature
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base
Returns the root directory for all knowledge base files from config key 'knowledge-base.attachments.directory', defaulting to 'knowledge-base', trimmed of slashes.
```php
public function directory(): string
```
--------------------------------
### updateCategory usage example
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base
Updates an existing category's name. The method fills and saves the model, then returns $category->fresh().
```php
$service->updateCategory($category, ['name' => 'Quick Start']);
```
--------------------------------
### Configure locales in config/knowledge-base.php
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base/blob/main/README.md
Sets the languages the knowledge base serves, the authoritative default locale, missing translation behavior, and PostgreSQL text-search configurations. The default locale must be included in the locales array.
```php
// config/knowledge-base.php
'locales' => ['en', 'de'], // languages the knowledge base serves
'default_locale' => 'en', // always the authoritative language; must be in locales
'missing_translation' => 'fallback', // 'fallback' (default) or 'hide'
'search_languages' => [ // PostgreSQL text-search configuration per language
'en' => 'english',
'de' => 'german',
],
```
--------------------------------
### Configure table prefix
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base/blob/main/README.md
Set the table prefix for all knowledge base tables. Set to null to use table names without a prefix.
```php
'table_prefix' => 'kb_',
```
--------------------------------
### disk(): string
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base
Returns the configured disk for new assets, as specified in the knowledge-base attachments configuration.
```APIDOC
## disk(): string
### Description
Returns the configured disk for new assets.
### Method
`disk()`
### Returns
- **string** - The configured disk name (default: `public`).
```
--------------------------------
### Locales::default() usage example
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base
Shows the expected return value when the default locale is `'en'`. Every article, category, and collection mirrors its version in this language.
```php
Locales::default(); // 'en' — every article/category/collection mirrors its version in this language
```
--------------------------------
### served(): bool
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base
Indicates whether assets are served through the package route, based on the `knowledge-base.attachments.route.enabled` configuration value.
```APIDOC
## `served(): bool`
### Description
Returns `config('knowledge-base.attachments.route.enabled', true)` — whether assets are served through the package route.
### Method
`served`
### Returns
- **bool** - `true` if the route is enabled, `false` otherwise.
```
--------------------------------
### ArticleAsset kind() and isShared() usage
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base
Shows how to call kind() to get an AssetKind enum even if the attribute was read as string, and isShared() to check if the asset is shared or default-language.
```php
$asset->kind(); // AssetKind::Image (enum), even if the attribute was read as string
$asset->isShared(); // true for shared / default-language assets
```
--------------------------------
### Publish, archive, and delete articles
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base/blob/main/README.md
Publish sets status to Published, sets published_at, and dispatches ArticlePublished. Archive sets status to Archived. Delete soft deletes the article.
```php
// 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);
```
--------------------------------
### Resolve article with fallback and staff lookup
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base
Example usage of resolveArticle. The first call resolves for locale 'de' with default publicOnly true; the second uses publicOnly: false for staff lookups that may see internal content.
```php
$resolved = $resolver->resolveArticle($article, 'de');
// $resolved?->locale // 'de', or 'en' when it fell back
// $resolved?->slug // the served version's slug
$staff = $resolver->resolveArticle($article, 'de', publicOnly: false);
```
--------------------------------
### Move assets from public disk to private disk (kb:move-assets)
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base/blob/main/README.md
Run these Artisan commands to move assets stored by version 2.0 on the public disk to the configured private disk. The --dry-run flag lists what would move without making changes; the second command copies each file, updates its record, and removes the old file.
```bash
php artisan kb:move-assets --dry-run # lists what would move
php artisan kb:move-assets # copies each file, updates its record, removes the old file
```
--------------------------------
### kb:verify-translations command usage and output
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base
Runs TranslationVerifier::drift() and prints each drift line with error(); prints 'All translations are in sync.' otherwise. Exit code 0 on success, 1 when drift found.
```bash
php artisan kb:verify-translations
# All translations are in sync. → exit 0
# Article #12 [en] differs in [title]. → exit 1
# 1 drift(s) found.
```
--------------------------------
### Store, URL, usage, broken references, and delete assets
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base/blob/main/README.md
Use the ArticleAssets service to store uploads or local files for an article, with optional language. Without a language the asset is shared; the default language is stored as shared too. url() returns the current URL (plain for public articles, signed otherwise), usage() lists languages whose current content uses it, brokenReferences() returns deleted assets still referenced, and delete() removes the file and record even while used.
```php
use JeffersonGoncalves\KnowledgeBase\Enums\AssetKind;
use JeffersonGoncalves\KnowledgeBase\Support\ArticleAssets;
$assets = app(ArticleAssets::class);
// Store an upload (or the path to a local file) for an article. Without a
// language the asset is shared; the default language is stored as shared too.
$image = $assets->store($article, $request->file('image'), AssetKind::Image);
$german = $assets->store($article, $request->file('image'), AssetKind::Image, 'de');
$pdf = $assets->store($article, $request->file('file'), AssetKind::File);
$assets->url($image); // the current URL: plain for a public article, signed otherwise
$assets->usage($image); // ['en', 'de'] — languages whose current content uses it
$assets->brokenReferences($article); // ['de' => ['']] — deleted assets still referenced
$assets->delete($image); // removes the file and the record (allowed while used)
```
--------------------------------
### search() method signature
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base
Public, language-aware search method that delegates to KnowledgeBaseService::search() with locale and optional limit. Returns a collection of Article objects.
```php
/** @return Collection */
public function search(string $query, string $locale, ?int $limit = null): Collection
```
--------------------------------
### Catch ValidationException from ArticleAssets::store()
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base
Wrap calls to ArticleAssets::store() in a try/catch for Illuminate\Validation\ValidationException. The exception is thrown when the uploaded file fails rules built from attachments.{images|files}.accepted_types and .max_size. Read $e->errors() to get validation messages, e.g. for a renamed PDF or oversized file.
```php
use Illuminate\Validation\ValidationException;
try {
$assets->store($article, $request->file('image'), AssetKind::Image);
} catch (ValidationException $e) {
// $e->errors()['file'] — e.g. the file is a renamed PDF, or too large
return back()->withErrors($e->errors());
}
```
--------------------------------
### Configure custom models
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base/blob/main/README.md
Override any model to extend default behavior. Custom models must implement the corresponding contract.
```php
'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,
'article_translation' => \App\Models\ArticleTranslation::class,
'category_translation' => \App\Models\CategoryTranslation::class,
'collection' => \App\Models\Collection::class,
'collection_translation' => \App\Models\CollectionTranslation::class,
],
```
--------------------------------
### Configure languages
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base/blob/main/README.md
Define the locales served, the authoritative default locale (must be in locales), missing translation behavior, and PostgreSQL text-search configuration per language.
```php
'locales' => ['en'], // languages the knowledge base serves
'default_locale' => 'en', // always the authoritative language; must be in locales
'missing_translation' => 'fallback', // 'fallback' or 'hide'
'search_languages' => ['en' => 'english', 'de' => 'german'], // PostgreSQL text-search config per language
```
--------------------------------
### collection() method signature
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base
Declares the public method that resolves an active collection by slug and locale. Returns ?CollectionPage or null when not found.
```php
public function collection(string $slug, string $locale): ?CollectionPage
```
--------------------------------
### KnowledgeBaseService::createArticle
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base/blob/main/README.md
Creates a new article. Automatically generates a UUID, creates version 1 when versioning is enabled, and dispatches the ArticleCreated event.
```APIDOC
## [POST] /articles
### Description
Creates a new article. Automatically generates a UUID, creates version 1 when versioning is enabled, and dispatches the ArticleCreated event.
### Method
POST
### Endpoint
/articles
### Parameters
#### Request Body
- **category_id** (integer) - Required - Category ID
- **title** (string) - Required - Article title
- **slug** (string) - Required - Article slug
- **content** (string) - Required - Article content
- **excerpt** (string) - Optional - Short excerpt
- **visibility** (string) - Optional - Visibility (public/internal)
- **seo_title** (string) - Optional - SEO title
- **seo_description** (string) - Optional - SEO description
- **seo_keywords** (string) - Optional - SEO keywords
- **metadata** (array) - Optional - Additional metadata
### Response
#### Success Response (200)
- **id** (integer) - Article ID
- **uuid** (string) - Generated UUID
- **category_id** (integer) - Category ID
- **title** (string) - Article title
- **slug** (string) - Article slug
- **content** (string) - Article content
- **excerpt** (string|null) - Excerpt
- **visibility** (string) - Visibility
- **seo_title** (string|null) - SEO title
- **seo_description** (string|null) - SEO description
- **seo_keywords** (string|null) - SEO keywords
- **metadata** (array) - Metadata
- **author** (object) - Author model
### Request Example
```php
$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.)
```
```
--------------------------------
### Prune assets with kb:prune-assets
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base/blob/main/README.md
Run php artisan kb:prune-assets to remove files under {directory}/articles/ that no asset record knows and folders whose article no longer exists. It reports asset records whose file is missing and keeps unused but valid assets. Add --dry-run to list what it would remove without removing anything. A soft-deleted article keeps its folder; files go when the article is force-deleted.
```bash
php artisan kb:prune-assets
```
--------------------------------
### Registering listeners in a service provider
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base
Shows how to bind a listener to the ArticlePublished event in a service provider's boot method.
```php
// config/.../your-service-provider
public function boot(): void
{
Event::listen(ArticlePublished::class, SendArticleNotification::class);
}
```
--------------------------------
### disk() method signature
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base
Returns the configured disk for new assets from config key 'knowledge-base.attachments.disk', defaulting to 'public'.
```php
public function disk(): string
```
--------------------------------
### HelpCenter::category
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base/blob/main/README.md
Resolves a single public category by slug and locale, returning its children and articles.
```APIDOC
## HelpCenter::category
### Description
Resolves a single public category by slug and locale, returning its children and articles.
### Method
category
### Parameters
- **slug** (string) - Required - The category slug (e.g., 'abrechnung')
- **locale** (string) - Required - The language code (e.g., 'de')
### Response
Returns a CategoryPage object or null if not found.
```
--------------------------------
### Update Article with Versioning
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base/blob/main/resources/boost/skills/knowledge-base-development/SKILL.md
Updates an article and automatically creates version 2 when versioning_enabled is true.
```php
$updated = $service->updateArticle($article, [
'title' => 'Updated Title',
'content' => 'Updated content...',
], $editor, 'Fixed typos and added examples');
// Automatically creates version 2 when versioning_enabled = true
```
--------------------------------
### Iterate categories tree with articlesCount
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base
Retrieves the German category tree via the HelpCenter singleton and prints each node's name and publicly visible article count, then iterates child nodes.
```php
$tree = app(HelpCenter::class)->categories('de');
foreach ($tree as $node) {
echo $node->name.' ('.$node->articlesCount.')';
foreach ($node->children as $child) { /* ... */ }
}
```
--------------------------------
### Available ModelResolver methods
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base/blob/main/resources/boost/skills/knowledge-base-development/SKILL.md
Lists the available resolver methods and the contract they return. Use these to access the corresponding model instances.
```php
ModelResolver::article(); // ArticleContract
ModelResolver::category(); // CategoryContract
ModelResolver::articleVersion(); // ArticleVersionContract
ModelResolver::articleFeedback(); // ArticleFeedbackContract
ModelResolver::articleRelation(); // ArticleRelationContract
```
--------------------------------
### Publish, Archive, and Delete Article
Source: https://github.com/jeffersongoncalves/laravel-knowledge-base/blob/main/resources/boost/skills/knowledge-base-development/SKILL.md
Publishing sets status to Published and dispatches ArticlePublished. Archiving sets status to Archived. Deleting soft deletes the article.
```php
$service->publishArticle($article); // Sets status=Published, dispatches ArticlePublished
$service->archiveArticle($article); // Sets status=Archived
$service->deleteArticle($article); // Soft deletes
```