Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Control Laravel Package

orchestra/control

Orchestra Control adds a Laravel admin control panel to Orchestra Platform, providing resource-based CRUD scaffolding, navigation menus, and extension hooks so you can build consistent back-office interfaces quickly.

View on GitHub
Deep Wiki
Context7

Getting Started

orchestra/control is not a drop-in admin panel — it is the control-panel layer of Orchestra Platform. Treat the first hour as a platform-fit verification, not an installation.

Prerequisites (verify, don't assume):

composer show orchestra/control orchestra/foundation orchestra/authorization
php artisan --version   # v5.0.0 targets Laravel 7
php -v

Control v5.0.0 is a Laravel 7 compatibility line. If you are on Laravel 8+, stop here and evaluate Filament/Nova instead. If you are on Orchestra, confirm that orchestra/foundation ships Orchestra\Foundation\Jobs\SyncDefaultAuthorization — Control v5 depends on that class at the dispatch site, so Control and Foundation move together.

Minimal boot:

composer require orchestra/control:^5.0
php artisan vendor:publish --provider="Orchestra\Control\ControlServiceProvider"
php artisan migrate

Then walk the admin surface at the package's configured route prefix (conventionally /admin or /orchestra). Confirm with:

php artisan route:list | grep -iE 'user|role|acl'

Where to look first, in this order:

  1. vendor/orchestra/control/routes/ — the entire admin surface is route definitions mapped onto resource controllers. This file is the package's API.
  2. vendor/orchestra/control/src/Http/Controllers/ — user list/create/edit and role assignment flows.
  3. vendor/orchestra/control/resources/views/ — Blade scaffolding you will override, not edit.
  4. config/orchestra/ after publishing — middleware, route prefix, menu/widget registration.

First use case: log in as a user holding the platform's admin ability, open the Users screen, create a user, assign a role, and confirm the role's abilities gate a route you control. That single loop exercises routing, ACL binding, view scaffolding, and authorization — the four things this package exists to provide. If any leg fails, you have found a platform-fit problem before writing application code.

Implementation Patterns

1. Extend the admin surface by adding routes, not by editing vendor code. The package's controllers are thin and convention-bound. Add your own admin screens beside them rather than subclassing:

// app/Http/Controllers/Admin/ReportController.php
namespace App\Http\Controllers\Admin;

class ReportController extends Controller
{
    public function index()
    {
        return view('admin.reports.index');
    }
}

Register under the same middleware group and prefix the package uses so navigation and theming stay consistent.

2. Override views by publishing, then namespacing. Blade views are the primary customisation seam. Publish and override rather than patching:

php artisan vendor:publish --tag=orchestra-control-views

Then keep your overrides in resources/views/vendor/orchestra/control/. This survives composer update; editing vendor/ does not.

3. Menus and widgets are registration, not markup. Admin navigation is composed from registrations, not hand-written <ul> trees. Register your new screen where the package's menu service is bootstrapped — typically in a service provider's boot() — so it appears alongside Users and Roles with consistent styling and permission filtering.

4. Consume the ACL from your application code. The day-to-day value is that your feature code can delegate authorization to Orchestra's ACL rather than reimplementing roles:

if (! $user->hasRole('editor')) {
    abort(403);
}

Before committing, verify whether Orchestra's ACL bridges to Laravel's native Gate/policies or is a bespoke store. If it is bespoke, define policies that delegate to the ACL so your controllers use idiomatic $this->authorize(...) and stay framework-portable.

5. Migrate the ACL sync: Synchronizer → SyncDefaultAuthorization. v5.0.0 removes Orchestra\Control\Command\Synchronizer. Sweep everything that ran it:

grep -rn "Command\\\\Synchronizer\|control:synchronize\|Synchronizer" \
    app/ database/ routes/ config/ deploy/ .github/ docker/ Makefile

Replace with the job. Where the old command's exit code gated a deploy or seeder, use synchronous dispatch — otherwise your pipeline goes green against unsynced permissions:

use Orchestra\Foundation\Jobs\SyncDefaultAuthorization;

// deploy / seeder context: must not proceed until synced
dispatch_sync(new SyncDefaultAuthorization);

// normal app context: queued, fine
SyncDefaultAuthorization::dispatch();

Flush ability caches immediately after sync completes — stale grants are a security incident, not a UI bug.

6. Test against Testbench. The package is explicitly Testbench-friendly, and so should be your admin customisations:

public function test_admin_can_list_users()
{
    $this->actingAs($this->adminUser())
         ->get('/admin/users')
         ->assertOk();
}

public function test_non_admin_cannot_list_users()
{
    $this->actingAs($this->plainUser())
         ->get('/admin/users')
         ->assertForbidden();
}

Always write the negative case. The package provisions permissions; a regression that widens access is the failure mode that matters.

Gotchas and Tips

Pin Control and Foundation together. SyncDefaultAuthorization lives in Foundation. Upgrading one without the other fails at the dispatch site with a class-not-found or dispatch error, often only at deploy time. One branch, one PR, one lockfile.

Do not alias the removed class back in. Rebinding Synchronizer in the container to make old code compile decouples your codebase from the real implementation and creates drift. Convert the call sites.

Queued sync means eventual consistency for permissions. Something an operator used to invoke explicitly is now something your app dispatches. Budget for workers in every environment including CI, plus retries, monitoring, and a failed-jobs runbook. If you cannot run workers, this design is wrong for you.

ACL migrations and repeated syncs must be idempotent. Test on production-shaped permission data. Repeated syncs should converge, not accumulate duplicate roles or grants. If the package ships default role names, namespace your application roles away from them or the sync will overwrite your grants on every run.

Sweep beyond application code. Deploy scripts, cron entries, seeders, runbooks, and CI configs all reference the old synchronizer. grep the whole repo, not just app/.

Laravel 7 is end-of-life. You are inheriting the framework patch burden indefinitely. Name an owner, set a security-patching plan, and define an exit path before this becomes load-bearing in production.

Route collisions are silent. If your app already owns /admin or an admin.* route-name prefix, the package's resource routes will collide. Check php artisan route:list before and after install, and reconcile middleware groups explicitly.

Adoption signal is near zero — no dependents, no community corpus. Debugging will be reading vendor/ source, not searching forums. Read the package's routes and controllers early; they are short and are the de facto documentation.

View/route caching after install:

php artisan route:clear && php artisan route:cache
php artisan view:clear && php artisan optimize

Most "my new admin screen 404s" and "my Blade override doesn't apply" reports are stale caches.

Verify these before commitment (the release notes do not answer them): whether a maintained line exists beyond v5.0.0; supported PHP versions; whether SyncDefaultAuthorization is queued by default or requires a config toggle; whether ACL migrations are safe to re-run; whether the ACL integrates with native Gate/policies; and how ability caches are invalidated after sync.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons