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

Core Laravel Package

hoa/core

Hoa\Core is the foundational library of the Hoa modular PHP ecosystem, supplying autoloading, error and exception handling, event management, and shared utilities that other Hoa packages depend on. It provides a lightweight base for structured, extensible PHP applications.

View on GitHub
Deep Wiki
Context7

Getting Started

Before writing a line of integration code, confirm you actually need this. hoa/core is archived, its last tagged release is from November 2015, it has no dependents on Packagist, and it predates PSR-4/PSR-11 adoption. It is not a Laravel package — there is no service provider, no facade, no config file, and no package discovery. In a current Laravel app it will fight Composer, not cooperate with it.

If you are here because a legacy module already depends on it, or you are evaluating it for a port, do this first:

  1. Prototype outside Laravel. Create a throwaway directory with composer require hoa/core:~1.15 (pin the exact 1.x tag from Packagist — it is flagged abandoned there) and a single index.php. Confirm it boots at all on your PHP version. Most of the 2015 code will emit deprecations or fatal on PHP 8.x.
  2. Read four files, in this order: Core.php (the singleton and registerAutoloader() bootstrap), Autoloader.php (its spl_autoload_register implementation), Consistency.php (design-by-contract assertions), and Protocol.php (the hoa:// stream-wrapper registry). Event.php and Parameter.php are secondary.
  3. Bootstrap it explicitly — never rely on Composer to wire it up:
    require_once __DIR__.'/vendor/hoa/core/Core.php';
    \Hoa\Core::registerAutoloader();
    
  4. Pick one first use case. The only concept in this package that maps onto something a Laravel developer does every day is Hoa\Core\Consistency — precondition/postcondition checks in a domain service or a legacy port:
    use Hoa\Core\Consistency;
    
    Consistency::assert(
        Consistency::isInt($quantity) && $quantity > 0,
        'Quantity must be a positive integer, got %s.',
        $quantity
    );
    
    Everything else (hoa:// paths, the event bus, the parameter bag) duplicates something Laravel or Symfony already gives you with support and Octane safety. If that assessment is right for your case, stop here and use the native equivalent instead — you have lost nothing.

Implementation Patterns

Adapter-first, always. Treat hoa/core as an untrusted third-party boundary. Expose one small interface in your app (QuantityGuard, LegacyStreamResolver, etc.) with a single implementation that calls Hoa, and inject that. This lets you delete the dependency later by swapping the binding, and it keeps Hoa\Core\* imports out of your domain code.

Service provider as the only integration point. Register the autoloader and any hoa:// protocols in register(), and keep the provider conditional on a config flag so test environments and CI never touch it:

public function register(): void
{
    if (! config('legacy.hoa.enabled')) {
        return;
    }
    require_once base_path('vendor/hoa/core/Core.php');
    \Hoa\Core::registerAutoloader();
    $this->app->singleton(LegacyStreamResolver::class);
}

Resist the urge to add Hoa\Core to config/app.php providers globally.

Event bridge, one direction only. Hoa\Core\Event is a static channel/bucket bus. If a legacy module fires events you need in Laravel, forward them into the framework dispatcher rather than consuming Laravel events inside Hoa:

\Hoa\Core\Event::register(
    'legacy.order.placed',
    'app',
    function ($bucket) {
        event(new OrderPlaced($bucket->getData()));
    }
);

Never make Laravel's dispatcher depend on Hoa's registry — it is process-global static state and will leak between requests.

Parameter bag as a config shim. Hoa\Core\Parameter is a nested key/value bag with ArrayAccess. Map it to a plain array once at the boundary (iterator_to_array-style flattening, or read specific keys) and pass arrays into your app. Do not let Hoa\Core\Parameter instances escape into controllers or jobs.

Stream protocol only when porting. Hoa\Core\Protocol::register($scheme, $wrapperClass) registers a PHP stream wrapper so file_get_contents('hoa://Library/...') resolves through Hoa's path configuration. If you are porting a legacy module that hardcodes hoa://, keep the protocol and add a thin resolver that also understands Storage::disk() paths. For greenfield code, use Laravel's filesystem disks — the stream abstraction buys you nothing here.

Consistency assertions belong in tests and domain guards, not controllers. Use them where you would otherwise write throw new InvalidArgumentException; in feature tests, prefer native assert(), Pest expectations, or Laravel validation, because Hoa's failures surface as Hoa\Core\Exception and will not match Laravel's validation error shape.

Strangler-fig migration. Port one call site at a time behind the adapter, run the legacy and native implementations side by side in a feature test, then delete the Hoa path. Given the package's age, plan for the whole dependency to be gone within a release cycle or two.

Gotchas and Tips

  • Archived means no fixes. Treat every use as a fork you own. The license is BSD-3-Clause, so copying the ~200 lines of Consistency into app/Support/ with attribution is usually cheaper than installing the whole package.
  • PHP 8 will bite. Code from 2015 relies on patterns removed or deprecated since: dynamic properties on classes without #[AllowDynamicProperties], curly-brace string offsets, create_function-era idioms in adjacent Hoa packages, and loose is_* checks that now emit warnings. Test on your exact runtime before committing.
  • hoa:// fails silently. If the protocol is not registered, or Hoa\Core\Configuration does not define the expected roots (hoa://Application, hoa://Data, hoa://Library, hoa://Etc), file_get_contents returns false rather than throwing. Always check the return value and log the resolved path. Paths are case-sensitive.
  • Global static state. Hoa\Core is a singleton; Protocol and Event are static registries. Under Octane, Swoole, or even queue workers that boot once, registrations persist across requests and listeners accumulate. Re-register (and Event::unregister) per boot, or keep Hoa strictly out of long-lived workers.
  • Composer conflicts. Hoa's own autoloader bypasses Composer's optimized classmap, so composer dump-autoload -o and --classmap-authoritative can behave unpredictably. If you can, skip registerAutoloader() and let Composer's PSR-4 mapping find the classes; verify the namespace-to-path mapping actually holds in your installed tag.
  • Exception mapping. Hoa\Core\Exception extends \Exception but carries none of the context Laravel's handler expects (no render, no HTTP status, no report). Catch Hoa\Core\Exception\Idle / Runtime / Logic at the adapter boundary and rethrow as InvalidArgumentException or RuntimeException so the default handler and your logs behave.
  • No PSR-3, PSR-11, or PSR-14. Do not try to bridge Hoa's event bus into the container as a replacement dispatcher; it has no priorities you can reason about, no propagation control, and no queue support.
  • Debugging tip: Consistency::assert() messages include the raw expression, which is useful but noisy. Wrap assertions in a try/catch at the boundary and log the expression with a correlation ID if you are chasing a legacy failure.
  • Pin hard. If you must install, use an exact tag ("hoa/core": "1.15.x"), never a caret range, and commit the lockfile. There will be no 1.16.
  • The real day-to-day answer: replace it. symfony/event-dispatcher or Laravel's own Dispatcher for events, symfony/options-resolver for parameter bags, league/flysystem for streams, webmozart/assert or native assertions for contract checks. Each is maintained, PSR-compliant, and safe under Octane — which hoa/core is not.
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.
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
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core