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

fooino/core

A lightweight core package for Laravel/PHP projects, bundling shared utilities, service providers, and sensible configuration defaults. It simplifies common setup tasks and provides a stable foundation for Fooino-based applications, helping you focus on building features instead of boilerplate.

View on GitHub
Deep Wiki
Context7

Getting Started

  • Install with composer require <vendor>/<package> and confirm the package registers its constants eagerly. Sentinel constants are typically exposed through a files autoload entry in the package's composer.json, so if the constants are undefined after install, run composer dump-autoload before debugging anything else.
  • Look first at the package's constants definition file (usually src/constants.php, src/Sentinel.php, or similar). v1.6.0 adds UNKNOWN, INVALID, UNDEFINED, NOT_FOUND, and HIDDEN as global constants — verify their exact names, namespace (global vs. class constants), and underlying values before writing code against them.
  • First real use case: replace ambiguous null/false/'' returns from a service or repository with a sentinel. A cache or lookup method that currently returns null on a miss can return NOT_FOUND instead, letting callers distinguish "no result" from "not queried yet" (UNKNOWN) or "result was filtered" (HIDDEN).
  • Start with one boundary — a repository method or an API transformer — rather than sprinkling sentinels across the domain. Confirm the value survives your DTOs, casts, and JSON layer before expanding usage.

Implementation Patterns

Boundary returns instead of null. Use sentinels at the edges of your application (repositories, HTTP clients, cache wrappers) and convert to null/exceptions at the domain boundary. This keeps null meaningful internally while giving callers richer information at the edge.

public function find(string $key): mixed
{
    $hit = $this->store->get($key);

    return $hit === null ? NOT_FOUND : $hit;
}

Guard clauses over nested conditionals. A match (true) or early-return chain reads well with sentinels because each constant maps to a distinct branch:

return match ($result) {
    NOT_FOUND => $this->missingResponse(),
    INVALID   => $this->validationResponse(),
    HIDDEN    => $this->forbiddenResponse(),
    default   => $this->okResponse($result),
};

Serialization control in API resources. HIDDEN is naturally an instruction to omit a key rather than emit a value. Handle it in your JsonResource/transformer so it never leaks into the payload:

public function toArray($request): array
{
    return collect($this->fields)
        ->reject(fn ($v) => $v === HIDDEN)
        ->all();
}

Validation and parsing layers. Map a failed parse to INVALID and an unparseable/unknown shape to UNDEFINED, keeping the two distinct so you can log them differently (client error vs. upstream contract violation).

Config and feature-flag defaults. UNKNOWN is useful for tri-state flags where false would wrongly imply "explicitly disabled" — e.g. an entitlement check that hasn't been resolved yet.

Testing. Assert with assertSame(NOT_FOUND, $result) rather than assertEquals, and prefer factory helpers or fixture methods that return the constants so refactors stay centralized.

Optional wrapping. If you need behaviour on sentinels, wrap them in a small enum or value object with isSentinel(): bool, and keep the raw constants for comparisons. This gives you static analysis and IDE completion without giving up the cheap global checks.

Gotchas and Tips

  • Global namespace collisions. These are global constants, not namespaced ones. If your app or another package already defines NOT_FOUND or HIDDEN, you will get a fatal redeclaration error or silently pick up the wrong value depending on load order. Grep your codebase and vendor/ for define('NOT_FOUND' and similar before upgrading. Guard with defined() in bootstrap code that might load twice.
  • Strict comparison is mandatory. Sentinel values are scalars (likely strings). Loose comparison with ==, or in_array() without the strict flag, will produce false positives against 0, '', or false. Always use === and in_array($v, [...], true).
  • Truthiness traps. If a sentinel is a non-empty string, if ($value) evaluates true — a HIDDEN or INVALID value will be treated as valid data. Never rely on truthiness for sentinel checks.
  • Don't persist them. Sentinels should not reach database columns, cache payloads you later deserialize as user data, or queued job payloads unless the column is explicitly designed for it. Convert to null or a string state at the persistence boundary; otherwise your data layer fills with magic strings that only this package understands.
  • Casts and serialization. Eloquent casts, json_encode, and Collection::toArray() all pass scalars through untouched, so sentinels will serialize. If you rely on HIDDEN for omission, enforce it in the transformer, not in the model.
  • Eager loading. Because constants are autoloaded via files, they are available in config files, service providers, and migrations — but not in code that runs before Composer's autoloader (e.g. some artisan bootstrap paths, or PHPUnit bootstrap files that bypass vendor/autoload.php).
  • Debugging. A sentinel dumps identically to its literal value in var_dump/dd, so logs lose intent. Log the constant name explicitly ('lookup' => 'NOT_FOUND') or wrap in a small enum when the distinction matters for observability.
  • Upgrade risk. v1.6.0 is additive only — no breaking changes, no deprecations — so upgrading is safe. The one real risk is the new global names colliding with existing app constants; audit that before deploying. If you cannot rename yours, define the package's constants conditionally or alias your own.
  • Static analysis. Global constants are weakly typed and often invisible to PHPStan/Psalm. Add @var docblocks or a stub file, or expose them through a class constant that mirrors the global so your analysis baseline stays clean.
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.
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons