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

Conditional Laravel Package

omitobisam/conditional

Conditional is a Laravel package for expressive conditional validation. It lets you apply rules only when specified conditions are met, keeping complex form request logic readable, reusable, and easy to maintain.

View on GitHub
Deep Wiki
Context7

Getting Started

Install the package via Composer:

composer require omitobisam/conditional

You will land on the 2.0.0 major release. The published notes for it are thin — a 1.x→master merge, a new GitHub Actions workflow (php.yml), and the 2.x branch merge — so before you write code against it, open the compare view (1.3.0...2.0.0 on the repo) and the composer.json in the tagged release to confirm the PHP constraint and that the terminal method is still resolve(). The 1.x-era README snippets floating around the web may not match.

There is no service provider or config file to publish — this is a pure utility library.

The first place to look is the package namespace (Omitobisam\Conditional) and the README usage block for the 2.0.0 tag specifically; the entry point is a fluent builder that turns a boolean into an expressive if/else chain instead of a ternary or nested if.

Minimal first use case — replace a nested ternary in a controller or presenter:

use Omitobisam\Conditional\Conditional;

return Conditional::when($user->isAdmin())
    ->then(fn () => $this->adminDashboard())
    ->else(fn () => $this->userDashboard())
    ->resolve();

If that smoke test fails on 2.0.0, the failure is almost certainly a renamed entry point or terminal method rather than a logic error — check the release diff before debugging your own closures.

Implementation Patterns

Guard-style branch selection. Because branches are closures, only the winning branch executes. This makes it a drop-in replacement for if/else where the branches perform side effects or expensive work:

Conditional::when($order->isPaid())
    ->then(fn () => $this->ship($order))
    ->else(fn () => $this->requestPayment($order))
    ->resolve();

Chaining multiple conditions. The package really earns its keep when you would otherwise nest ternaries or use elseif. Chain when() calls in priority order and finish with a single fallback:

return Conditional::when($score >= 90)
    ->then(fn () => 'A')
    ->when($score >= 80)
    ->then(fn () => 'B')
    ->when($score >= 70)
    ->then(fn () => 'C')
    ->else(fn () => 'F')
    ->resolve();

HTTP response builders. It is very natural in controllers returning different response types:

return Conditional::when($request->expectsJson())
    ->then(fn () => response()->json($data))
    ->else(fn () => view('dashboard', compact('data')))
    ->resolve();

Feature flags and config-driven behavior. Combine with config() or a feature-flag service to pick implementations. Wrap the resolution in a small named method in your service class so the fluent call stays testable and the flag source stays injectable.

API Resources / presenters. Use it inside toArray() to keep transformation logic flat instead of stacking ternaries for labels, badge colors, and visibility.

Composition tip. Keep each branch closure short; if a branch grows past a few lines, extract it into a private method. The fluent API is for readability, not for hiding multi-step logic.

Testing tip. Assert the resolved value, not the internals. Because branches are closures, a feature test against the endpoint naturally covers the correct-branch path; a unit test can call resolve() with mocked conditions directly. On 2.0.0, add one cheap assertion-level test that exercises the full when/then/else/resolve chain — it doubles as your upgrade canary if a later 2.x patch renames something.

Gotchas and Tips

  • 2.0.0 is a major bump with a one-line changelog. No migration guide, no listed breaking changes, and no linked diff detail in the release notes beyond the PR titles. Treat it as breaking until proven otherwise: read the 1.3.0...2.0.0 compare, confirm the public method names, and pin the exact version ("omitobisam/conditional": "2.0.0") rather than using ^2.0 until you've validated the API surface you depend on.
  • Check the new CI workflow, not the old README, for PHP support. The release adds .github/workflows/php.yml; that matrix is now the most reliable statement of which PHP versions are actually tested. Older docs mentioning 7.4 may be stale for 2.0.0 — verify against composer.json's require.php before putting this in a legacy codebase.
  • Pass closures, not evaluated values. The whole point of the API is lazy evaluation of branches. Writing ->then($this->ship($order)) invokes ship() immediately, defeating the purpose and often causing side effects in the untaken branch. Always wrap: ->then(fn () => $this->ship($order)).
  • Method names drift between majors. resolve vs get, else vs otherwise — small packages rename terminals across majors. After upgrading to 2.0.0, grep your codebase for every Conditional:: call site and let the smoke test in Getting Started confirm the chain still reads as documented for this tag.
  • Keep branch return types aligned. resolve() returns whatever the taken closure returns, so mixing Response and View in a controller is fine at PHP level but confusing to consumers. Enforce a common type or Responsable interface at the boundary.
  • Ordering matters. In a when()->then()->when()->then()->else() chain, the first truthy condition wins. Put the most specific/least likely conditions first, otherwise a broad when($user) shadows everything after it.
  • Debugging chains. When a chain resolves unexpectedly, temporarily replace each ->then(...) with ->then(fn () => 'A'), 'B', etc. and dump the result — the winning branch becomes immediately visible without xdebug.
  • No community safety net. Zero dependents and a modest star count mean you're largely on your own for issues — and a 2.0.0 release with a terse changelog is exactly the scenario that argues for insulation. Wrap the package behind a small internal helper class (e.g. App\Support\Conditional) so you can swap it for a plain match or ternary if the package stalls or the next major surprises you.
  • Static analysis. Add the package to your PHPStan baseline or write a tiny stub if your analyzer complains about the dynamic resolve() return type. Consider @mixin/generics in your wrapper to keep IDE autocompletion. Re-run the analyzer after the 2.0.0 upgrade — a major bump can change inferred signatures.
  • match is the built-in alternative. For simple equality-based branching on PHP 8, match is native, faster, and free of dependency risk. Reach for this package when you need closures, chained boolean conditions, or a Laravel-friendly fallback that reads better than nested ternaries.
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