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

Crud Bundle Laravel Package

gibilogic/crud-bundle

Gibilogic CRUD Bundle is a Symfony bundle that provides reusable CRUD scaffolding, helping developers quickly build create, read, update, and delete workflows with less boilerplate. It streamlines admin interfaces and backend management pages, making it easy to expose entity management in Symfony ap...

View on GitHub
Deep Wiki
Context7

Getting Started

Reality check first: this is a Symfony 2 bundle, not a Laravel package. There is no ServiceProvider, no config/*.php to publish, and no Facade. On a modern Laravel app (PHP 8+, Laravel 10/11) composer require gibilogic/crud-bundle will almost certainly fail on platform/Symfony constraints. Treat the first 15 minutes as a feasibility spike, not an install.

Minimal steps

  1. Clone the repo and read it before installing:
    git clone https://github.com/gibilogic/crud-bundle /tmp/crud-bundle
    tree -L 3 /tmp/crud-bundle
    
  2. Open, in this order:
    • composer.json — Symfony/PHP version constraints tell you whether porting is even sane.
    • DependencyInjection/ — the service definitions are the real API surface; every service id here is what you'd inject.
    • The abstract controller / CRUD service class — this is where the list/create/edit/delete workflow lives.
    • Resources/config/ (routing, services YAML) — reveals the intended route names and template conventions.
    • Tests/ if present — fastest way to learn intended usage without guessing.
  3. Decide the mode of adoption (see Gotchas): port the code vs. vendor it as reference.
  4. First use case to aim at: an admin CRUD screen over one entity — paginated index with a sort/filter whitelist, create + edit via a form object, delete with confirmation/CSRF. That is exactly the shape this bundle was built for, and it's the smallest thing that exercises every helper.

If you're porting into Laravel, map the pieces up front:

Bundle concept Laravel equivalent
CRUD service over EntityManager Repository + Model / query builder
Symfony Form type FormRequest + validation rules
Flash + redirect ->with('status', ...)
CSRF token @csrf / VerifyCsrfToken
Route YAML with app_ prefix Route::resource(...)

Implementation Patterns

1. Extend the abstract controller (Symfony-native usage, for reference/legacy apps). The bundle is designed to be subclassed: you declare the entity class, the form type, and the templates, and inherit the index/create/edit/delete actions. Override only what differs.

class ProductController extends AbstractCrudController
{
    protected function getEntityClass(): string { return Product::class; }
    protected function getFormType(): string    { return ProductType::class; }
    protected function getTemplatePrefix(): string { return 'Product:'; }
}

2. Use the CRUD service directly instead of the controller. The more useful pattern day-to-day: inject the manager into your own controller, console command, or importer, and let it own persistence so validation/flash/redirect logic doesn't leak into every action.

public function store(Request $request, CrudManager $crud)
{
    $result = $crud->create($request->validated(), Product::class);

    return $result->isSuccess()
        ? redirect()->route('products.index')->with('status', 'Created.')
        : back()->withErrors($result->errors())->withInput();
}

3. Index action as a configurable query. The pattern that pays off is a whitelist-driven index: an array of sortable columns, a set of allowed filters, and a page size — never $request->input('sort') passed straight to the query. Copy this shape even if you rewrite the internals:

$sortable = ['name', 'created_at', 'price'];
$sort = in_array($request->sort, $sortable, true) ? $request->sort : 'created_at';
$dir  = $request->dir === 'asc' ? 'asc' : 'desc';

4. Delete with a soft-delete hook. Wire a beforeDelete/afterDelete extension point (or a model event in Laravel) rather than putting cascade logic in the controller. Deletion should be a service call that returns a result, so it's testable and reusable from an artisan command.

$crud->delete($product, function ($entity) {
    $entity->archived_at = now();
});

5. Keep form handling out of the service. The bundle's form type is the boundary; the CRUD service should accept already-validated data. In Laravel terms, validate in the FormRequest, pass $request->validated() to the service. Mixing the two couples your persistence layer to the HTTP stack and makes CLI reuse painful.

6. Centralize response shaping. All the flash-and-redirect plumbing belongs in one base controller or a response helper. The moment each of the four actions does its own back()/redirect(), you've recreated the boilerplate the bundle was meant to remove.

7. Use it as a reference for query-object layering. The most portable idea in the repo is the split between a controller that only handles HTTP and a service that owns the entity lifecycle. That's worth copying into a first-party Laravel trait or base controller even if you never run a line of the original code.

Gotchas and Tips

Package discovery will not fire. There is no extra.laravel block; Laravel won't register anything automatically. Even if composer require succeeded, nothing would wire up.

Composer install will likely fail before you learn anything. The constraints target Symfony 2.x and PHP 5.x. If you want to inspect the code, clone it; if you want to test it, use a matching PHP image (php:5.6-cli) in a throwaway container.

Doctrine vs. Eloquent is not a shallow mismatch. The service layer almost certainly calls EntityManager::persist/flush. Swapping to Eloquent means rewriting the persistence boundary, not wrapping it. Budget for a real port, not an adapter.

No tests means no safety net for the port. Assume there's nothing to inherit. Write feature tests for each of the four operations first — they'll drive the port and catch regressions when you swap the persistence layer.

Route names are conventions, not magic. Symfony route YAML typically prefixes with app_ or the bundle name; the redirects in the abstract controller hardcode them. When you port, either preserve the names or update every redirect()->route() call — a silent 500 on success is a classic symptom.

CSRF is on by default in Symfony Forms but not automatically in Laravel's Route::resource. Remember @csrf in the delete form; forgetting it produces a 419 that looks like an auth bug.

Extension points are the safest thing to preserve. If the service exposes beforeSave/afterSave/beforeDelete hooks, keep that shape in your port — it's where application-specific behavior (audit logging, notifications, archival) will accumulate. Losing it forces every caller to reimplement those concerns.

Don't rely on the package's error-handling shape. Most Symfony 2–era CRUD helpers return either a boolean or throw. Pick one contract (Result object with isSuccess() and errors()) and standardize in your port — mixing the two is the fastest way to get silent failures.

Zero dependents means zero Stack Overflow. Any bug beyond a typo is a bug you own. Fork it explicitly (internal packages/ path, PSR-4 autoload) rather than depending on it, so upgrade and patch decisions stay under your control.

Attribution stays. MIT requires preserving the copyright header through forked classes. Keep the license file in the vendored directory and note the origin in the commit that introduces it.

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.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource