hoathis/symfony-ruler-bundle
Symfony bundle that integrates Hoa\Ruler, a lightweight business rules engine, into Symfony applications. Define and evaluate dynamic rules with service configuration and dependency injection support for cleaner, configurable business logic.
Architecture fit — Effectively zero at the packaging layer. hoathis/symfony-ruler-bundle is a Symfony2 bundle: a Bundle subclass plus a DI Extension and a configuration tree that registers Hoa\Ruler\Ruler, a Context, and an Asserter as container services. Laravel has no bundle concept, no AppKernel, and no Configuration tree — none of that wiring is loadable in a Laravel app. The only genuinely portable asset is the underlying hoa/ruler library, which the bundle merely instantiates. Adopting "this package" in Laravel really means discarding the package and re-implementing its ~100 lines of glue as a service provider.
Integration feasibility — Low, and the effort is misattributed. A viable path requires: (a) drop the bundle entirely, (b) require hoa/ruler directly, (c) author a RulerServiceProvider + config/ruler.php + optional facade, (d) validate the full Hoa dependency tree (hoa/compiler, hoa/ustring, hoa/math, hoa/consistency, hoa/stream) against the target PHP runtime. Step (d) is the risk, not step (c).
Technical risk — High and concentrated in three areas. Maintenance: archived, last release 2016-12-05, 15 stars, 0 dependents — there is no upstream to fix anything. License: NOASSERTION means GitHub could not detect a license file; Hoa projects were generally BSD-3-Clause, but legal must confirm before this ships in a commercial product. Runtime: the Hoa stack is dormant (last meaningful activity ~2017) and predates PHP 8; expect deprecation failures, dynamic-property warnings, and possible hard breaks on 8.1+. hoa/compiler is also a heavyweight PEG/lexer stack with known parse-time cost and memory growth, which matters if rules are evaluated per request.
Key questions
Gate/Policy/Validator already expresses?NOASSERTION?symfony/expression-language satisfy the same use case with an actively maintained, PHP 8-ready, single-dependency alternative?Stack fit — Poor as a bundle, moderate as a library, and outclassed by a maintained alternative. Primary recommendation: symfony/expression-language. It is actively maintained, PHP 8 compatible, a small dependency, and already the engine behind Symfony's validator and security expressions — well understood, with typed exceptions and a sandbox mode for untrusted expressions. Secondary: a thin in-house rules layer over Validator + Gate if rules are developer-authored. Only pursue hoa/ruler if a non-PHP, human-readable DSL is a hard, documented requirement.
Migration path — If the DSL requirement is confirmed: require hoa/ruler directly, register Hoa\Ruler\Ruler and a Context as singletons in a RulerServiceProvider, publish config/ruler.php mapping named rules to rule strings, and expose a single RuleEvaluator interface (evaluate(string $rule, array $context): bool) behind a facade. Store rule strings in config or a rules table — never inline in controllers. Critically, keep the engine behind that interface so swapping to ExpressionLanguage later is a one-class change.
Compatibility — Read the composer.json PHP constraint first; it will almost certainly be 5.x-era and require a --ignore-platform-reqs install on PHP 8.2/8.3, which is a red flag, not a workaround. Run the dependency tree through PHPStan and a PHPUnit smoke suite on the actual target version before committing. Verify hoa/compiler behavior under Octane/long-running workers. Confirm no transitive package relies on removed functions (each(), create_function) or implicit-nullable signatures.
Sequencing
NOASSERTION.hoa/ruler on the production PHP version, with a parse benchmark and a memory check.symfony/expression-language; compare ergonomics and error quality.RuleEvaluator with contract tests on the rule grammar.Maintenance — You own it outright. Zero upstream means any parser or compiler defect is yours to patch in a vendored fork, and Composer security advisories will never surface for it. Either commit to a fork-and-maintain model with a named owner, or accept it as a frozen, unpatched dependency — and document which.
Support — No maintainer, no issue triage, no security disclosure channel, no CVE feed. On-call has no external escalation path for a parser incident; triage falls entirely to the internal team. This is the single strongest argument against adoption.
Scaling — Rule evaluation is lex → parse → AST per call. Ruler does not cache compiled rules, so on a hot path you must memoize ASTs keyed by a hash of the rule string (Redis/APCu), or you pay parsing cost on every request. Watch resident memory in queue workers and Octane — the Hoa compiler has historically shown growth under sustained load. Cap rule-string length and complexity to bound worst-case parse time.
Failure modes — Malformed rule strings throw at evaluation time, surfacing as 500s unless wrapped; undefined context keys evaluate ambiguously rather than erroring clearly; DSL operator precedence can produce subtly wrong booleans that tests won't catch without explicit truth-table coverage; and if the fork is ever patched, semantics can drift silently. symfony/expression-language fails more loudly and legibly on all four.
Ramp-up — The DSL surface is small; a senior engineer is productive in about a day using the (stale) Hoa documentation. Debugging lexer/parser errors is the real cost — error messages are poor and the internals are undocumented. Budget one sprint covering both the spike and the fallback evaluation, and pre-commit to the fallback so the spike cannot become a sunk-cost adoption. Net recommendation: reject the bundle as a Laravel dependency; evaluate hoa/ruler only against a confirmed non-developer-authoring requirement, with symfony/expression-language as the default.
How can I help you explore Laravel packages today?