### Complete Controller Example Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/api-reference/facades.md This example demonstrates a full controller setup for managing pages, handling drafts, publishing, and public views using Revisor middleware and methods. ```php validate([ 'title' => 'required|string', 'content' => 'required|string', ]); $page->update($validated); // Auto-publishes based on config or model setting if ($request->boolean('publish_immediately')) { $page->publish(); } return redirect()->route('pages.admin.show', $page); } // Publish a draft // Route: POST /admin/pages/{page}/publish (with DraftMiddleware) public function publish(Page $page) { if (!$page->isDraftTableRecord()) { abort(404); // Expected draft } $page->publish(); return redirect() ->route('pages.admin.show', $page) ->with('message', 'Page published successfully'); } // Show a draft (admin) // Route: GET /admin/pages/{page} (with DraftMiddleware) public function show(Page $page) { return view('pages.admin.show', compact('page')); } // Public view - show published only // Route: GET /pages/{page} (with PublishedMiddleware) public function publicShow(Page $page) { // Middleware enforces published context // $page is from published table if (!$page->isPublished()) { abort(404); // Safety check } return view('pages.public.show', compact('page')); } // Preview with optional draft view // Route: GET /preview/{page} (with DraftableMiddleware) public function preview(Page $page) { // DraftableMiddleware allows ?draft parameter // $page might be from draft or published $isDraft = $page->isDraftTableRecord(); $isRevised = $page->isRevised(); $isDraftMarked = request()->has('draft'); return view('pages.preview', compact( 'page', 'isDraft', 'isRevised', 'isDraftMarked' )); } // Revert to version // Route: POST /admin/pages/{page}/revert/{versionId} public function revertToVersion(Page $page, $versionId) { // Work in draft context (middleware) if (!$page->isDraftTableRecord()) { abort(404); } $page->revertToVersion($versionId); return redirect() ->route('pages.admin.show', $page) ->with('message', 'Reverted to previous version'); } // List versions // Route: GET /admin/pages/{page}/versions public function versions(Page $page) { // Work in draft context (middleware) if (!$page->isDraftTableRecord()) { abort(404); } // Get all versions for this draft $versions = $page->versionRecords() ->orderBy('version_number', 'desc') ->get(); $currentVersion = $page->currentVersionRecord; return view('pages.admin.versions', compact( 'page', 'versions', 'currentVersion' )); } // API: List published pages // Route: GET /api/pages (with PublishedMiddleware) public function apiList() { $pages = Page::paginate(15); return response()->json($pages); } // API: Get page with optional draft // Route: GET /api/pages/{id} public function apiShow($id) { // Check for draft parameter if (request()->has('draft') && auth()->check()) { Revisor::draftContext(); } else { Revisor::publishedContext(); } $page = Page::find($id); if (!$page) { return response()->json(['error' => 'Not found'], 404); } return response()->json($page); } // API: Create new draft page // Route: POST /api/pages (requires auth) public function apiStore(Request $request) { // Explicitly use draft context $page = Revisor::withDraftContext(function () use ($request) { ``` -------------------------------- ### Controller Example with DraftableMiddleware Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/api-reference/middleware.md Demonstrates how a controller can access content that is either published or in draft, depending on the middleware's context. ```php class PageController extends Controller { public function show(Page $page) { // $page comes from either published or draft table // depending on ?draft parameter if ($page->isUnpublishedOrRevised()) { $status = 'Draft or Revised'; } else { $status = 'Published'; } return view('pages.show', compact('page', 'status')); } } ``` -------------------------------- ### Controller Example with DraftMiddleware Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/api-reference/middleware.md Demonstrates how a controller interacts with Revisor models when DraftMiddleware is applied. Queries and updates will target draft tables. ```php class PageController extends Controller { // Assuming DraftMiddleware is applied to this route group public function index() { // Queries pages_drafts table automatically $pages = Page::all(); return view('pages.index', compact('pages')); } public function edit(Page $page) { // $page is from pages_drafts due to middleware return view('pages.edit', compact('page')); } public function update(Request $request, Page $page) { // Updates pages_drafts automatically $page->update($request->validated()); return redirect()->route('pages.index'); } } ``` -------------------------------- ### Controller Example with PublishedMiddleware Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/api-reference/middleware.md Illustrates how a controller functions when PublishedMiddleware is active. All Revisor model operations will target the published tables. ```php class PageController extends Controller { // Assuming PublishedMiddleware is applied public function index() { // Queries pages_published table automatically $pages = Page::all(); return response()->json($pages); } public function show(Page $page) { // $page is from pages_published due to middleware return response()->json($page); } } ``` -------------------------------- ### Route Protection for Publishing Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/errors.md This example shows how to protect a route that publishes a page using the `auth` middleware to ensure a user is authenticated. ```php Route::middleware('auth')->post('/pages/{page}/publish', function (Page $page) { return $page->publish(); // Safe, user is authenticated }); ``` -------------------------------- ### Install Laravel Revisor Source: https://github.com/indracollective/laravel-revisor/blob/main/README.md Install the Laravel Revisor package using Composer. This command adds the core functionality for draft, publishing, and versioning Eloquent models. ```bash composer require indracollective/laravel-revisor ``` -------------------------------- ### Querying with Default Context Source: https://github.com/indracollective/laravel-revisor/blob/main/docs/managing-context.md Example of querying a model when the default context is active. This will query the table associated with the default context. ```php // this will query the pages_drafts table $page = Page::first(); ``` -------------------------------- ### Careful Querying When Deleting Versions Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/errors.md This example demonstrates a safe way to delete version records by ensuring the current version is never deleted. ```php // Or query carefully when deleting $page->versionRecords() ->where('is_current', 0) // Never delete current version ->delete(); ``` -------------------------------- ### facades.md Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/SUMMARY.txt Usage examples and documentation for the Revisor Facade, providing a static interface to the Revisor service. ```APIDOC ## Revisor Facade ### Description The `Revisor` facade provides convenient static access to the underlying Revisor service. It mirrors many of the service class methods. ### Usage ```php use Indra evisor acades\Revisor; // Process a model Revisor::process($model); // Get revision history $history = Revisor::getHistory($model); // Get configuration $configValue = Revisor::getConfig('some_key'); ``` ### Methods #### `process(Model $model)` ##### Description Processes a given Eloquent model using the Revisor service. ##### Parameters - **`$model`** (Model) - Required - The Eloquent model instance to process. ##### Return Type `void` #### `getHistory(Model $model)` ##### Description Retrieves the revision history for a given Eloquent model. ##### Parameters - **`$model`** (Model) - Required - The Eloquent model instance. ##### Return Type `array` #### `getConfig(string $key)` ##### Description Retrieves a specific configuration value for the Revisor service. ##### Parameters - **`$key`** (string) - Required - The configuration key to retrieve. ##### Return Type `mixed` ``` -------------------------------- ### Registering Versioning Event Listeners Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/model-integration.md Sets up event listeners for 'savedNewVersion' and 'revertedToVersion' eloquent events. Includes example listener methods for logging and event dispatching. ```php listen('eloquent.savedNewVersion: ' . Page::class, [self::class, 'onVersionSaved']); $events->listen('eloquent.revertedToVersion: ' . Page::class, [self::class, 'onVersionReverted']); } public function onVersionSaved($page, $version) { ActivityLog::create([ 'user_id' => auth()->id(), 'model_type' => Page::class, 'model_id' => $page->id, 'action' => 'version_created', 'properties' => [ 'version_number' => $version->version_number, ], ]); // Notify subscribers of changes event(new PageVersionCreated($page, $version)); } public function onVersionReverted($page, $version) { ActivityLog::create([ 'user_id' => auth()->id(), 'model_type' => Page::class, 'model_id' => $page->id, 'action' => 'version_reverted', 'properties' => [ 'reverted_to_version' => $version->version_number, 'current_version' => $page->version_number, ], ]); event(new PageVersionReverted($page, $version)); } } ``` -------------------------------- ### Install Laravel Revisor Filament Support Source: https://github.com/indracollective/laravel-revisor/blob/main/README.md Install the FilamentPHP support package for Laravel Revisor using Composer. This is required if you intend to use Revisor with FilamentPHP. ```bash composer require indracollective/laravel-revisor-filament ``` -------------------------------- ### Registering Publishing Event Listeners Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/model-integration.md Sets up event listeners for 'publishing', 'published', and 'unpublished' eloquent events on the Page model. Includes example listener methods. ```php listen('eloquent.publishing: ' . Page::class, [self::class, 'onPublishing']); $events->listen('eloquent.published: ' . Page::class, [self::class, 'onPublished']); $events->listen('eloquent.unpublished: ' . Page::class, [self::class, 'onUnpublished']); } public function onPublishing($page) { // Validate before publishing if (!$page->isValidForPublishing()) { // Return false to cancel return false; } logger()->info("Publishing page {$page->id}"); } public function onPublished($page) { // Clear relevant caches Cache::forget("page:{$page->id}"); Cache::forget("pages:all"); // Send notifications Notification::send($page->admins, new PagePublished($page)); logger()->info("Page {$page->id} published successfully"); } public function onUnpublished($page) { // Clean up any published-specific data Cache::forget("page:{$page->id}"); logger()->info("Page {$page->id} unpublished"); } } // Register in App\Providers\EventServiceProvider protected $subscribe = [ PageEventListener::class, ]; ``` -------------------------------- ### getVersionTable Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/api-reference/has-revisor-trait.md Gets the version table name. ```APIDOC ## getVersionTable ### Description Gets the version table name. ### Method `public function getVersionTable(): string` ### Returns `string` — Version table name ### Usage Example ```php echo $page->getVersionTable(); // 'pages_versions' ``` ``` -------------------------------- ### middleware.md Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/SUMMARY.txt Guide to using the Revisor middleware, explaining its purpose and how to integrate it into the Laravel application. ```APIDOC ## Revisor Middleware ### Description The Revisor middleware can be used to apply Revisor functionality to specific routes or groups of routes. It typically handles the processing of requests that involve model revisions. ### Usage Add the middleware to your `app/Http/Kernel.php` file or apply it directly to routes: ```php // In app/Http/Kernel.php (protected $routeMiddleware) 'revisor' => // Applying to a route Route::get('/resource/{id}', function ($id) { // ... })->middleware('revisor'); ``` ### Parameters This middleware typically does not require explicit parameters in the route definition itself, as its behavior is often configured globally or through model attributes. ``` -------------------------------- ### Event Listener to Cancel Version Creation Based on Version Count Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/errors.md This example shows a `savingNewVersion` event listener that prevents new version creation if a limit of 1000 versions is reached. ```php Page::savingNewVersion(function ($page) { if ($page->versionRecords()->count() >= 1000) { return false; // Cancel if too many versions } }); $result = $page->saveNewVersion(); if ($result === false) { echo "Version creation was cancelled"; } ``` -------------------------------- ### Revisor Facade API Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/SUMMARY.txt Documentation for the Revisor facade, including static method proxying, usage patterns, controller examples, and testing with facades. ```APIDOC ## Revisor Facade ### Description The Revisor facade provides a convenient static interface to the Revisor service, simplifying common operations and offering usage patterns, controller examples, and testing utilities. ### Methods - **Static Method Proxying**: All public methods of the Revisor service are accessible via the facade. - **Usage Patterns**: Examples demonstrating common ways to use the facade. - **Controller Examples**: Complete examples for integrating with controllers. - **Testing**: Guidance on testing components that utilize the Revisor facade. ``` -------------------------------- ### Setup Model with HasRevisor Trait Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/INDEX.md Integrate the HasRevisor trait into your Eloquent model to enable Revisor functionality. Ensure the model implements the HasRevisorContract and defines the base table name. ```php use Indra\Revisor\Concerns\HasRevisor; use Indra\Revisor\Contracts\HasRevisor as HasRevisorContract; class Page extends Model implements HasRevisorContract { use HasRevisor; protected string $baseTable = 'pages'; } ``` -------------------------------- ### Getting the Current Version Record Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/quick-reference.md Access the record representing the current version of the model. This is the active state of the content. ```php $page->currentVersionRecord ``` -------------------------------- ### Setting and Getting Revisor Context Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/types.md Demonstrates how to set the active Revisor context globally and retrieve the current context. Useful for controlling read/write operations. ```php use Indra\Revisor\Enums\RevisorContext; use Indra\Revisor\Facades\Revisor; // Set the active context globally Revisor::setContext(RevisorContext::Draft); // Get the current active context $context = Revisor::getContext(); // Returns RevisorContext or null // Check context equality if ($context === RevisorContext::Draft) { // Handle draft context } ``` -------------------------------- ### Cancel Publishing via Event Listener Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/errors.md This example demonstrates how to cancel a publishing operation by returning `false` from a `publishing` model event listener. ```php Page::publishing(function ($page) { if (!auth()->check()) { return false; // Cancel publish } }); ``` -------------------------------- ### Complete Routing Example with Revisor Middleware Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/api-reference/middleware.md This snippet illustrates how to apply Revisor's middleware to different route groups, controlling access to published pages, drafts, and admin functionalities. It also shows API route configurations. ```php use Illuminate\Support\Facades\Route; use Indra\Revisor\Middleware\DraftMiddleware; use Indra\Revisor\Middleware\PublishedMiddleware; use Indra\Revisor\Middleware\DraftableMiddleware; use App\Http\Controllers\PageController; // Public routes - show published pages only Route::middleware(PublishedMiddleware::class)->group(function () { Route::get('/pages', [PageController::class, 'index']); Route::get('/pages/{page}', [PageController::class, 'show']); }); // Preview routes - optionally show drafts Route::middleware(DraftableMiddleware::class)->group(function () { Route::get('/preview/{page}', [PageController::class, 'preview']); }); // Admin routes - always work with drafts Route::middleware(['auth', DraftMiddleware::class])->group(function () { Route::get('/admin/pages', [PageController::class, 'admin_index']); Route::get('/admin/pages/{page}/edit', [PageController::class, 'edit']); Route::patch('/admin/pages/{page}', [PageController::class, 'update']); // Publish route can override middleware context Route::post('/admin/pages/{page}/publish', function (Page $page) { return $page->publish(); // Works with draft record }); }); // API routes with explicit context control Route::prefix('api')->group(function () { // Published API Route::middleware(PublishedMiddleware::class)->group(function () { Route::get('/pages', [PageController::class, 'api_list']); }); // Draft API for editors Route::middleware(['auth:api', DraftMiddleware::class])->group(function () { Route::get('/drafts', [PageController::class, 'api_drafts']); Route::patch('/drafts/{page}', [PageController::class, 'api_update']); }); }); ``` -------------------------------- ### Get Prunable Versions Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/api-reference/has-revisor-trait.md Retrieves version records that are candidates for pruning based on the `keepVersions` setting. The query logic adapts to the `keepVersions` configuration. ```php public function prunableVersions(): HasMany ``` ```php $draft = Page::withDraftContext()->find(1); $toDelete = $draft->prunableVersions; foreach ($toDelete as $version) { $version->delete(); } ``` -------------------------------- ### Retrieving All Version Records Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/quick-reference.md Get a collection of all historical version records for a given model. This is helpful for auditing or browsing past states. ```php $page->versionRecords ``` -------------------------------- ### Get Version Table Name Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/api-reference/revisor.md Retrieves the name of the version table for a given base table name. Assumes default configuration for table name suffixes. ```php $tableName = Revisor::getVersionTableFor('pages'); // Returns: 'pages_versions' (with default config) ``` -------------------------------- ### Get Suffixed Table Name with Context Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/api-reference/revisor.md Gets the suffixed table name for a given base table and an optional Revisor context. Defaults to the active context if none is provided. ```php use Indra\Revisor\Enums\RevisorContext; // With explicit context $draftTable = Revisor::getSuffixedTableNameFor('pages', RevisorContext::Draft); // Returns: 'pages_drafts' // With active context (defaults to Published) $currentTable = Revisor::getSuffixedTableNameFor('pages'); // Returns: 'pages_published' (default context) ``` -------------------------------- ### Importing and Using the Revisor Facade Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/api-reference/facades.md Demonstrates how to import the Revisor facade and call its methods for context management. ```php use Indra\Revisor\Facades\Revisor; Revisor::getContext(); Revisor::draftContext(); ``` -------------------------------- ### Retrieve All Versions from a Draft Model Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/model-integration.md Fetch all version records associated with a draft model using the `versionRecords` relationship. You can also query specific versions or get the current version. ```php $draft = Page::withDraftContext()->find(1); // Get all versions $versions = $draft->versionRecords; // Query versions $oldVersions = $draft->versionRecords() ->where('version_number', '<', $draft->version_number) ->orderBy('version_number', 'desc') ->get(); // Get current version $current = $draft->currentVersionRecord; ``` -------------------------------- ### Applying Middleware by Alias Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/api-reference/middleware.md Demonstrates how to apply middleware using their registered aliases in route definitions. ```php Route::middleware('draft')->group(function () { // Draft context routes }); ``` -------------------------------- ### getPublishedTable Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/api-reference/has-revisor-trait.md Gets the published table name. ```APIDOC ## getPublishedTable ### Description Gets the published table name. ### Method `public function getPublishedTable(): string` ### Returns `string` — Published table name ### Usage Example ```php echo $page->getPublishedTable(); // 'pages_published' ``` ``` -------------------------------- ### getDraftTable Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/api-reference/has-revisor-trait.md Gets the draft table name. ```APIDOC ## getDraftTable ### Description Gets the draft table name. ### Method `public function getDraftTable(): string` ### Returns `string` — Draft table name ### Usage Example ```php echo $page->getDraftTable(); // 'pages_drafts' ``` ``` -------------------------------- ### Pattern 3: Nested Context Switching Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/api-reference/facades.md Demonstrates nesting context switches, showing how the facade correctly restores the previous context after nested operations complete. ```php use Indra\Revisor\Facades\Revisor; Revisor::publishedContext(); Revisor::withDraftContext(function () { Revisor::withVersionContext(function () { // Inside version context $versions = Page::all(); }); // Back to draft context $drafts = Page::all(); }); // Back to published context $pages = Page::all(); ``` -------------------------------- ### getSuffixedTableNameFor Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/api-reference/revisor.md Gets the suffixed table name for a given base table and context. ```APIDOC ## getSuffixedTableNameFor ### Description Gets the suffixed table name for a given base table and context. ### Method `public function getSuffixedTableNameFor(string $baseTableName, ?RevisorContext $context = null): string` ### Parameters #### Path Parameters - **baseTableName** (string) - Required - Base table name - **context** (RevisorContext|null) - Optional - Context enum. Defaults to the active context. ### Returns `string` - The suffixed table name ### Usage Example ```php use Indra\Revisor\Enums\RevisorContext; // With explicit context $draftTable = Revisor::getSuffixedTableNameFor('pages', RevisorContext::Draft); // Returns: 'pages_drafts' // With active context (defaults to Published) $currentTable = Revisor::getSuffixedTableNameFor('pages'); // Returns: 'pages_published' (default context) ``` ``` -------------------------------- ### getDraftTableFor Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/api-reference/revisor.md Gets the name of the draft table for the given base table name. ```APIDOC ## getDraftTableFor ### Description Gets the name of the draft table for the given base table name. ### Method `public function getDraftTableFor(string $baseTableName): string` ### Parameters #### Path Parameters - **baseTableName** (string) - Required - Base table name ### Returns `string` - The suffixed draft table name ### Usage Example ```php $tableName = Revisor::getDraftTableFor('pages'); // Returns: 'pages_drafts' (with default config) ``` ``` -------------------------------- ### getPublishedTableFor Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/api-reference/revisor.md Gets the name of the published table for the given base table name. ```APIDOC ## getPublishedTableFor ### Description Gets the name of the published table for the given base table name. ### Method `public function getPublishedTableFor(string $baseTableName): string` ### Parameters #### Path Parameters - **baseTableName** (string) - Required - Base table name ### Returns `string` - The suffixed published table name ### Usage Example ```php $tableName = Revisor::getPublishedTableFor('pages'); // Returns: 'pages_published' (with default config) ``` ``` -------------------------------- ### Combining Multiple Middlewares and Overriding Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/api-reference/middleware.md Demonstrates how middleware precedence works and how query scopes can override the context set by the last applied middleware. ```php // Only the last middleware applied affects the global context Route::middleware([ DraftMiddleware::class, PublishedMiddleware::class, // This wins ])->group(function () { // All requests use Published context }); // Use query scopes to override Page::withDraftContext()->get(); // Uses draft context ``` -------------------------------- ### getVersionTableFor Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/api-reference/revisor.md Gets the name of the version table for the given base table name. ```APIDOC ## getVersionTableFor ### Description Gets the name of the version table for the given base table name. ### Method `public function getVersionTableFor(string $baseTableName): string` ### Parameters #### Path Parameters - **baseTableName** (string) - Required - Base table name ### Returns `string` - The suffixed version table name ### Usage Example ```php $tableName = Revisor::getVersionTableFor('pages'); // Returns: 'pages_versions' (with default config) ``` ``` -------------------------------- ### getAllTablesFor Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/api-reference/revisor.md Gets all three table names for a given base table name as a collection. ```APIDOC ## getAllTablesFor ### Description Gets all three table names for a given base table name as a collection. ### Method `public function getAllTablesFor(string $baseTableName): Collection` ### Parameters #### Path Parameters - **baseTableName** (string) - Required - Base table name ### Returns `Illuminate\Support\Collection` - Collection of three table names [versions, drafts, published] ### Usage Example ```php $tables = Revisor::getAllTablesFor('pages'); // Returns: Collection(['pages_versions', 'pages_drafts', 'pages_published']) $tables->each(function ($tableName) { // Process each table }); ``` ``` -------------------------------- ### Create Page with Facade Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/api-reference/facades.md Demonstrates creating a new page resource using the Page facade within a controller method. It includes input validation for title and content. ```php return Page::create($request->validate([ 'title' => 'required|string', 'content' => 'required|string', ])); }); return response()->json($page, 201); } } ``` -------------------------------- ### Manual Middleware Registration in Kernel Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/api-reference/middleware.md Shows how to manually register middleware aliases in `app/Http/Kernel.php` for explicit use in route definitions. ```php // In app/Http/Kernel.php protected $routeMiddleware = [ // ... 'draft' => \Indra\Revisor\Middleware\DraftMiddleware::class, 'published' => \Indra\Revisor\Middleware\PublishedMiddleware::class, 'draftable' => \Indra\Revisor\Middleware\DraftableMiddleware::class, ]; ``` -------------------------------- ### Override Versioning Settings Per Model Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/configuration.md Demonstrates how to set specific versioning behaviors for individual models using instance methods. This allows for fine-grained control over version retention and publishing. ```php class Page extends Model implements HasRevisorContract { use HasRevisor; protected function boot() { parent::boot(); // This instance will auto-publish and keep 20 versions $this->publishOnCreated(true); $this->keepVersions(20); } } ``` -------------------------------- ### prunableVersions Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/api-reference/has-revisor-trait.md Gets versions that should be pruned based on the `keepVersions` setting. The returned query depends on the `keepVersions` setting. ```APIDOC ## prunableVersions ### Description Gets versions that should be pruned based on the `keepVersions` setting. ### Method `public function prunableVersions(): HasMany` ### Returns `HasMany` — Relationship to prunable versions ### Description Details The returned query depends on the `keepVersions` setting: - If int: Returns oldest versions beyond the keep limit - If false: Returns all versions - If true: Returns no versions (nothing to prune) ### Usage Example ```php $draft = Page::withDraftContext()->find(1); $toDelete = $draft->prunableVersions; foreach ($toDelete as $version) { $version->delete(); } ``` ``` -------------------------------- ### versionRecords Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/api-reference/has-revisor-trait.md Gets all version records for this draft. This method returns a HasMany relationship to all versions associated with a draft. ```APIDOC ## versionRecords ### Description Gets all version records for this draft. ### Method `public function versionRecords(): HasMany` ### Returns `HasMany` — Relationship to all versions ### Usage Example ```php $draft = Page::withDraftContext()->find(1); // Get all versions $versions = $draft->versionRecords; // Query versions $oldVersions = $draft->versionRecords() ->where('version_number', '<', 10) ->get(); ``` ``` -------------------------------- ### Run Migrations Source: https://github.com/indracollective/laravel-revisor/blob/main/docs/preparing-your-models.md Execute your database migrations, including those generated for Revisor, using this Artisan command. ```bash php artisan migrate ``` -------------------------------- ### Create Table Schemas for Versioning Source: https://github.com/indracollective/laravel-revisor/blob/main/docs/introduction.md Use this migration helper to create separate tables for published, draft, and versioned records of a model. It automatically includes necessary metadata columns. ```php public function up(): void { Revisor::createTableSchemas('pages', function (Blueprint $table) { $table->id(); $table->string('title'); }); } ``` -------------------------------- ### Get All Version Records Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/api-reference/has-revisor-trait.md Retrieves all version records associated with a draft. This method returns a HasMany relationship. ```php public function versionRecords(): HasMany ``` ```php $draft = Page::withDraftContext()->find(1); // Get all versions $versions = $draft->versionRecords; // Query versions $oldVersions = $draft->versionRecords() ->where('version_number', '<', 10) ->get(); ``` -------------------------------- ### getContext Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/api-reference/revisor.md Gets the current active RevisorContext. It can optionally return a default context if no context is explicitly set. ```APIDOC ## getContext ### Description Gets the current active `RevisorContext`. If `$orDefaultContext` is true, it returns the default context when none is explicitly set. Otherwise, it returns null if no context is set. ### Method ```php public function getContext(bool $orDefaultContext = true): ?RevisorContext ``` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters #### Method Parameters - **$orDefaultContext** (bool) - Optional - If true, returns the default context when none is explicitly set. ### Returns `RevisorContext|null` — Active context or null if no context is set and `$orDefaultContext` is false ### Usage Example ```php use Indra\Revisor\Facades\Revisor; use Indra\Revisor\Enums\RevisorContext; // Get active context, defaulting to Published $context = Revisor::getContext(); // Returns: RevisorContext::Published (default) // Get only explicitly set context $context = Revisor::getContext(orDefaultContext: false); // Returns: null if not explicitly set ``` ``` -------------------------------- ### Middleware Classes API Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/SUMMARY.txt Documentation for the Revisor middleware classes, including DraftMiddleware, PublishedMiddleware, and DraftableMiddleware, with routing examples. ```APIDOC ## Middleware Classes ### Description This section documents the middleware classes provided by Laravel Revisor, which help control access and behavior based on draft or published states. ### Middleware - **DraftMiddleware**: Ensures access to draft content. - **PublishedMiddleware**: Restricts access to published content. - **DraftableMiddleware**: Enables draft functionality for specific routes or models. ### Routing Examples Provides complete examples of how to integrate these middleware classes into your Laravel application's routes. ``` -------------------------------- ### Publish a Record Source: https://github.com/indracollective/laravel-revisor/blob/main/docs/publishing.md Demonstrates the basic method to publish a draft record. This updates the draft record and copies it to the published table. ```php $page = Page::create([...]); $page->publish(); echo $page->isPublished(); // true ``` -------------------------------- ### Configure Versioning Settings Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/configuration.md Manage versioning behavior, including when new versions are saved and how many old versions to retain. This section allows fine-tuning of the version history management. ```php 'versioning' => [ 'save_new_version_on_created' => true, 'save_new_version_on_updated' => true, 'keep_versions' => 10, 'table_columns' => [ 'is_current' => 'is_current', 'version_number' => 'version_number', 'record_id' => 'record_id', ], ], ``` -------------------------------- ### Accessing Model Revisor Context Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/types.md Illustrates how to get and set the Revisor context on models that implement the HasRevisor interface. ```php $model->getRevisorContext(): ?RevisorContext $model->setRevisorContext(?RevisorContext $context): static ``` -------------------------------- ### Versioning Configuration: Keep All Versions Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/configuration.md Configure the package to retain all historical versions of a record. This setting is useful when you need a complete audit trail. ```php 'versioning' => [ 'save_new_version_on_created' => true, 'save_new_version_on_updated' => true, 'keep_versions' => true, // Never prune old versions 'table_columns' => [ 'is_current' => 'is_current', 'version_number' => 'version_number', 'record_id' => 'record_id', ], ], ``` -------------------------------- ### Accessing HasRevisor Model Properties Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/types.md Demonstrates how to access properties related to publishing and versioning on models implementing the HasRevisor interface. ```php $page = Page::first(); // Retrieves published version by default // Publishing attributes echo $page->is_published; // true echo $page->published_at; // Carbon instance echo $page->publisher_name; // "John Doe" // Versioning attributes echo $page->is_current; // true echo $page->version_number; // 5 // In version context $version = Page::withVersionContext()->first(); echo $version->record_id; // Points to the draft record ID ``` -------------------------------- ### Manual Publishing with Validation Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/model-integration.md Demonstrates manual publishing of a model instance within a controller. Includes a basic validation check before calling the 'publish' method to ensure data integrity. ```php class PageController extends Controller { public function publish(Page $page) { // Validate before publishing if (!$page->title || !$page->content) { return back()->withErrors('Page must have title and content'); } $page->publish(); return redirect() ->route('pages.show', $page) ->with('message', 'Page published successfully'); } } ``` -------------------------------- ### currentVersionRecord Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/api-reference/has-revisor-trait.md Gets the current version record, which is marked with `is_current = true`. This method returns a HasOne relationship to the current version. ```APIDOC ## currentVersionRecord ### Description Gets the current version record (marked with `is_current = true`). ### Method `public function currentVersionRecord(): HasOne` ### Returns `HasOne` — Relationship to the current version ### Usage Example ```php $draft = Page::withDraftContext()->find(1); $currentVersion = $draft->currentVersionRecord; echo $currentVersion->version_number; ``` ``` -------------------------------- ### Using Revisor Facade via Config Alias Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/api-reference/facades.md Illustrates accessing the Revisor facade using its configuration alias, assuming it's registered in config/app.php. ```php // In config/app.php, automatically registered as 'Revisor' Revisor::getContext(); // If you 'use' the config alias ``` -------------------------------- ### Manual Versioning Source: https://github.com/indracollective/laravel-revisor/blob/main/docs/versioning.md Manually create a new version record by calling the saveNewVersion() method on the draft record. ```php $page = Page::create([...]); echo $page->versions()->count(); // 1 $page->saveNewVersion(); echo $page->versions()->count(); // 2 ``` -------------------------------- ### withVersionContext Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/api-reference/revisor.md Executes a callback within the 'Version' context. This is a convenience method for temporarily setting the context to version. ```APIDOC ## withVersionContext ### Description Executes a callback within the `Version` context. The context is automatically restored after the callback completes. ### Method ```php public function withVersionContext(callable $callback): mixed ``` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters #### Method Parameters - **$callback** (callable) - Required - Closure to execute. ### Returns `mixed` — The return value of the callback ### Usage Example ```php Revisor::withVersionContext(function () { return Page::all(); // From pages_versions }); ``` ``` -------------------------------- ### getBaseTable Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/api-reference/has-revisor-trait.md Gets the base table name without suffixes. It uses the `$baseTable` property if defined, otherwise derives it from the class name. ```APIDOC ## getBaseTable ### Description Gets the base table name without suffixes. ### Method `public function getBaseTable(): string` ### Returns `string` — Base table name ### Description Details Uses the `$baseTable` property if defined, otherwise derives from the class name. ### Usage Example ```php echo $page->getBaseTable(); // 'pages' ``` ``` -------------------------------- ### Creating a New Version Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/quick-reference.md Manually create a new version of the current record. This is useful for preserving specific states of your content. ```php $page->saveNewVersion() ``` -------------------------------- ### Get Base Table Name Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/api-reference/has-revisor-trait.md Retrieves the base table name for the model, excluding any suffixes. It prioritizes the `$baseTable` property if defined. ```php public function getBaseTable(): string ``` ```php echo $page->getBaseTable(); // 'pages' ``` -------------------------------- ### Get Current Version Record Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/api-reference/has-revisor-trait.md Retrieves the current version record, identified by `is_current = true`. This method returns a HasOne relationship. ```php public function currentVersionRecord(): HasOne ``` ```php $draft = Page::withDraftContext()->find(1); $currentVersion = $draft->currentVersionRecord; echo $currentVersion->version_number; ``` -------------------------------- ### Enable Auto-Publish on Creation Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/api-reference/has-revisor-trait.md Configure a model instance to automatically publish new records upon creation. This setting overrides global configuration for the specific instance. ```php $page = new Page(); $page->publishOnCreated(true); $page->title = 'New Page'; $page->save(); // Will auto-publish on creation ``` -------------------------------- ### Get Published Record Relationship Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/api-reference/has-revisor-trait.md Retrieves the one-to-one relationship to the published record of a model. This method should not be called on an already published record. ```php public function publishedRecord(): HasOne ``` ```php $draft = Page::withDraftContext()->find(1); $published = $draft->publishedRecord; $draft = Page::withDraftContext()->with('publishedRecord')->find(1); ``` -------------------------------- ### Model Events: Versioning Lifecycle Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/api-reference/has-revisor-trait.md Register callbacks for various stages of version creation, synchronization, and reversion. Version creation and reversion can be cancelled. ```php public static function savingNewVersion(string|Closure $callback): void public static function savedNewVersion(string|Closure $callback): void public static function syncingToCurrentVersion(string|Closure $callback): void public static function syncedToCurrentVersion(string|Closure $callback): void public static function revertingToVersion(string|Closure $callback): void public static function revertedToVersion(string|Closure $callback): void ``` ```php Page::savingNewVersion(function ($page) { // Can return false to cancel version creation }); Page::savedNewVersion(function ($page, $version) { Log::info('Created version ' . $version->version_number); }); Page::revertingToVersion(function ($page, $version) { // Called before revert }); Page::revertedToVersion(function ($page, $version) { // Called after revert completes }); ``` -------------------------------- ### Get Current Revisor Context Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/api-reference/revisor.md Retrieves the current active RevisorContext. Optionally returns the default context if none is explicitly set. ```php use Indra\Revisor\Facades\Revisor; use Indra\Revisor\Enums\RevisorContext; // Get active context, defaulting to Published $context = Revisor::getContext(); // Returns: RevisorContext::Published (default) // Get only explicitly set context $context = Revisor::getContext(orDefaultContext: false); // Returns: null if not explicitly set ``` -------------------------------- ### Create Revisor Tables with Basic Columns Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/api-reference/revisor.md Use `createTableSchemas` to generate draft, published, and version tables. The callback defines the columns for all three tables. ```php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; use Indra\Revisor\Facades\Revisor; use Indra\Revisor\Enums\RevisorContext; return new class extends Migration { public function up(): void { // Basic usage Revisor::createTableSchemas('pages', function (Blueprint $table) { $table->id(); $table->string('title'); $table->text('content'); }); } }; ``` -------------------------------- ### Getting the Published Record Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/quick-reference.md Retrieve the currently published version of a draft record. This is useful for comparing draft changes with the live version. ```php $draft->publishedRecord ``` -------------------------------- ### Access Published Record Directly Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/errors.md Demonstrates how to obtain the published record directly by using the withPublishedContext() method. ```php $published = Page::withPublishedContext()->find(1); ``` -------------------------------- ### Auto-Publish on Create Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/quick-reference.md Configure a model to automatically publish itself immediately after it is created and saved. This is useful for content that should be live by default. ```php $page = new Page(); $page->publishOnCreated(true); $page->save(); // Publishes automatically ``` -------------------------------- ### Retrieve Current Version Record Source: https://github.com/indracollective/laravel-revisor/blob/main/docs/versioning.md Get the current version record for a draft or published record using the currentVersion HasOne relationship. ```php $page->currentVersion; ``` -------------------------------- ### Configuration Keys for Versioning Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/quick-reference.md Access configuration settings related to the versioning feature. These control aspects like auto-versioning, the number of versions to keep, and table column names. ```php config('revisor.versioning.save_new_version_on_created') // bool config('revisor.versioning.save_new_version_on_updated') // bool config('revisor.versioning.keep_versions') // int|bool config('revisor.versioning.table_columns.is_current') config('revisor.versioning.table_columns.version_number') config('revisor.versioning.table_columns.record_id') ``` -------------------------------- ### Versioning Model Events Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/quick-reference.md Listen for events related to the versioning process. These events allow you to execute logic before and after creating new versions or reverting to existing ones. ```php Page::savingNewVersion(fn($page) => ...) // Before version create Page::savedNewVersion(fn($page, $v) => ...) // After version create Page::revertingToVersion(fn($page, $v) => ...) // Before revert Page::revertedToVersion(fn($page, $v) => ...) // After revert ``` -------------------------------- ### Get Version Table Name Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/api-reference/has-revisor-trait.md Retrieves the specific table name used for version history records. This is important for accessing historical data. ```php public function getVersionTable(): string ``` ```php echo $page->getVersionTable(); // 'pages_versions' ``` -------------------------------- ### Get Published Table Name Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/api-reference/has-revisor-trait.md Retrieves the specific table name used for published records. This is useful for queries targeting live content. ```php public function getPublishedTable(): string ``` ```php echo $page->getPublishedTable(); // 'pages_published' ``` -------------------------------- ### Define Admin and Public Routes Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/quick-reference.md Use middleware to define routes that are always drafts for administrators or always published for the public. This ensures appropriate access control based on the route's purpose. ```php Route::middleware("Indra\Revisor\Middleware\DraftMiddleware::class) ->group(fn() => Route::resource('pages', PageController::class)); Route::middleware("Indra\Revisor\Middleware\PublishedMiddleware::class) ->group(fn() => Route::get('pages/{page}', [PageController::class, 'show'])); ``` -------------------------------- ### Preview Drafts with Middleware Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/quick-reference.md Apply the DraftableMiddleware to a route to allow previewing draft versions of a resource. This middleware conditionally shows the draft if a 'draft' query parameter is present, otherwise it shows the published version. ```php // GET /pages/1?draft → Shows draft // GET /pages/1 → Shows published Route::middleware("Indra\Revisor\Middleware\DraftableMiddleware::class) ->get('pages/{page}', [PageController::class, 'show']); ``` -------------------------------- ### Configuration Keys for Context and Tables Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/quick-reference.md Access configuration settings that define the default Revisor context and table naming conventions. These are fundamental for Revisor's operation. ```php config('revisor.default_context') // RevisorContext config('revisor.table_suffixes') // Array ``` -------------------------------- ### Getting the Published Table Name Source: https://github.com/indracollective/laravel-revisor/blob/main/_autodocs/quick-reference.md Retrieve the name of the database table used for storing published records. This is essential for direct database interactions. ```php $page->getPublishedTable() ``` ```php Revisor::getPublishedTableFor('pages') ```