### 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 ```