cimple-admin/forms
cimple-admin/forms is a lightweight Laravel/PHP package for defining, validating, and rendering configurable admin forms with reusable fields, validation rules, and Blade components. It helps developers streamline CRUD screens, backend data entry, and form management in Cimple Admin-style applicatio...
This is a low-traffic, pre-1.0 package (0 stars, last release Feb 2023), so treat the source as the documentation. Budget half an hour to read the form and field classes before you write anything real.
composer require cimple-admin/forms:^0.2.11 — pin the exact patch. At 0.2.x the maintainer ships behavioural fixes in patch numbers (v0.2.11 is one), so ^0.2 will move you under your feet.config/app.php manually — a missing provider surfaces as a "class not found" on your first form class, not as a helpful error.php artisan vendor:publish and publish both the config and the Blade views. Publish the views before you style anything; otherwise you will be fighting the package's markup through CSS overrides.Write two tests before you go further: the happy path, and the "all optional fields left blank" path. The second is the regression class this release addressed.
One form class per model per context. CreateUserForm and EditUserForm extending a shared UserForm base keeps the common fields in one place while letting edit add the "leave blank to keep current password" rule. Resist a single god-form with if ($mode === ...).
Keep rules next to fields. The whole value proposition is that a field's label, type, validation, and rendering live in one fluent declaration. The moment you push rules back into a FormRequest, you have two sources of truth and the package is just an expensive HTML helper.
Thin controllers. The controller should do three things: hand the request data to the form, call the form's validate/initialize step, then persist. Anything else — normalising input, defaulting values, deciding which fields apply — belongs in the form class.
Compose, don't inherit deeply. Named helper methods that add a related cluster of fields (addAddressFields(), addBillingFields()) compose better than a three-level inheritance chain, and they make it obvious which fields a given screen actually got.
Reuse across create/edit by binding the model, not by branching. The same field definitions should render populated values on edit and empty on create; if you find yourself writing if ($model) inside field definitions, the package is probably already handling it via model binding and you are working around it.
Customise rendering through the published views. Per-field overrides are tempting, but published Blade partials are the supported extension point and survive a composer update. If you need a field type the package doesn't ship, add a custom field class — not a hacked view.
Test the form class, not just the endpoint. Instantiate the form in a unit test, feed it an array, assert the rule set and the rendered fragment. Form-class tests catch the "I added a field but forgot the rule" mistake cheaply.
v0.2.11 is a behaviour change, not just a bug fix. The changelog line (one sentence, in Chinese) says initialization validation no longer silently passes when everything is filtered out. Concretely: if every supplied value is dropped during filtering, you used to proceed with no validation error; now you get one. Any path that legitimately submits an empty or all-blank form — a "show everything" default view, a background job that fills only a few fields — will start throwing after the upgrade. Grep for those call sites before deploying.
Distinguish "no input at all" from "input that filtered down to nothing." These are different requests with different correct responses. The release only covers the second. Decide deliberately what an entirely absent submission means in your app and document it, or your logs will conflate the two.
Falsy filters eat legitimate values. Conditions and field values of 0, '0', false, and [] are the classic casualties of a truthiness check in the filtering step. If status = 0 or quantity = 0 is a real value in your domain, write a test that proves it survives.
Debugging the new error: dump the field/condition set immediately after filtering and immediately before validation. Almost always the filter is dropping something you expected to keep (a null coalesce, a falsy check, an empty() call), not the validator being wrong.
Pre-1.0 discipline. Read the actual diff on every 0.2.x bump, not the changelog. A one-line note can hide a change to rejection semantics across every form in your app. Pin the version and upgrade deliberately in a branch.
Extension points: prefer custom field classes and custom validation rules over subclassing the initializer. Subclassing couples you to internals that are demonstrably still moving at 0.2.x. If you must temporarily restore the old permissive behaviour, look for a config flag first and leave a ticket to remove the override — the permissive path is exactly the one that lets an unvalidated write through.
No community safety net. Zero stars and a last release over a year old means no Stack Overflow answers and no upstream fixes you didn't write. For anything load-bearing, fork it into your own vendor namespace rather than depending on the Packagist package, and record the upstream commit you forked from.
How can I help you explore Laravel packages today?