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

Ucc Laravel Package

rybakdigital/ucc

Universal Class Collection (UCC) is a set of dependency-free, framework-agnostic PHP 5.4-5.6 utility classes offering reusable modules for config handling, encryption and hashing, basic and pseudo data type validation with custom constraints, filter criteria, and sort definitions. Install via Compos...

View on GitHub
Deep Wiki
Context7

Getting Started

UCC ("Universal Class Collection") is a small, framework-agnostic library of plain PHP utility classes: a config reader, crypt/hash helpers, and basic/pseudo type validators. It is not a Laravel package — there is no service provider, no facade, no auto-discovery. You install it and wire it up yourself, which is exactly how you should treat it: a bag of well-scoped helpers, not a framework extension.

Install it and pin it:

composer require rybakdigital/ucc

Because there is no semver contract to rely on (0 stars, 0 dependents, last tag 2025-01-09), lock the exact version in composer.json rather than using ^:

"rybakdigital/ucc": "1.0.0"

Where to look first. The repo's docs/ folder is the real API surface — the README only lists the categories. Read in this order:

  1. docs/Config.md — the config utility, closest analogue to Illuminate\Config\Repository.
  2. docs/Hash.md — crypt/decrypt helpers, closest analogue to Illuminate\Encryption\Encrypter.
  3. docs/BasicTypes.md and docs/PseudoTypes.md — validators/constraint helpers.

Open the actual source alongside the docs before trusting either; the docs are old (Travis, Gitter, waffle.io badges) and the stated requirements in the README are PHP 5.4–5.6, which almost certainly does not match your runtime.

First use case. The most defensible first adoption is the type validators, because they are pure functions with no I/O, no config, and no crypto to get wrong. Use them to validate untrusted input in a place where Laravel's validator is awkward — e.g. inside a Rule object, a job payload sanitizer, or a console command parsing arguments:

use RybakDigital\Ucc\Data\Types\BasicTypes; // confirm namespace in docs/BasicTypes.md

$validator = new BasicTypes();

if (! $validator->isInt($payload['count'])) {
    throw new InvalidArgumentException('count must be an integer');
}

Once the validators are in and tested, evaluate Config and Hash separately — each of those competes directly with a mature Laravel component, so only adopt them where Laravel's version doesn't fit (see below).

Implementation Patterns

Wrap in a service provider, always

Never new these classes at call sites. Bind them once so you can swap, mock, and audit them in one place:

// app/Providers/UccServiceProvider.php
namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use RybakDigital\Ucc\Config\Config;
use RybakDigital\Ucc\Crypt\Hash;

class UccServiceProvider extends ServiceProvider
{
    public function register(): void
    {
        $this->app->singleton(Hash::class, function ($app) {
            return new Hash(
                base64_decode($app['config']->get('ucc.hash_key'))
            );
        });

        $this->app->bind(Config::class, function ($app) {
            return new Config($app->basePath('resources/ucc'));
        });
    }
}

Register it in bootstrap/providers.php (Laravel 11+) or config/app.php. This also gives you a single file to delete on the day you decide to drop the package.

Use Config only for non-Laravel config sources

Laravel's config() is cached, environment-aware, and dotted-path aware. Do not replace it with UCC's Config. The legitimate use case is reading config that lives outside config/ and outside the Laravel cache lifecycle — e.g. a drop-in resources/ucc/*.json deployed by ops, or a config file that must be readable by both a Laravel app and a non-Laravel script sharing the same codebase. That portability is the whole selling point of "pure PHP, no 3rd-party dependencies."

Wrap the Hash class behind your own interface

Give it a narrow contract so the rest of your app never imports a UCC namespace:

interface SecretBox
{
    public function seal(string $plaintext): string;
    public function open(string $ciphertext): string;
}

final class UccSecretBox implements SecretBox
{
    public function __construct(private Hash $hash) {}

    public function seal(string $plaintext): string
    {
        return $this->hash->encrypt($plaintext);
    }

    public function open(string $ciphertext): string
    {
        return $this->hash->decrypt($ciphertext);
    }
}

Bind SecretBox to UccSecretBox. If you later migrate to Illuminate\Encryption\Encrypter, you change one binding plus a data migration — not every call site. Read the encrypt/decrypt implementation yourself before shipping this; you are trusting an unaudited, zero-dependent library with confidentiality, and that's a decision to make deliberately, not by default.

Use validators as Laravel Rule objects

The cleanest way to consume BasicTypes/PseudoTypes in a Laravel codebase is to adapt them into ValidationRule implementations, so they compose with built-in rules:

use Illuminate\Contracts\Validation\ValidationRule;
use RybakDigital\Ucc\Data\Types\BasicTypes;

final class UccBasicType implements ValidationRule
{
    public function __construct(private BasicTypes $types, private string $method) {}

    public function validate(string $attribute, mixed $value, \Closure $fail): void
    {
        if (! $this->types->{$this->method}($value)) {
            $fail("The {$attribute} field is not a valid {$this->method}.");
        }
    }
}

Then 'count' => [new UccBasicType($types, 'isInt')]. Resolve $types from the container in your FormRequest::rules() — but note rules() on FormRequest can't easily take constructor deps, so prefer building the rules in a small factory or use app(BasicTypes::class) inline.

Test with a fake, not a mock of internals

Because these are plain classes with (likely) concrete methods, bind a hand-written fake in tests rather than fighting PHPUnit mocks:

$this->app->instance(SecretBox::class, new FakeSecretBox());

For validator tests, just instantiate the real class — pure functions need no doubling.

Gotchas and Tips

PHP version constraint will block the install. The README declares PHP 5.4/5.5/5.6. On PHP 8.x, Composer may refuse to install. Check the actual composer.json require block before assuming. If it's genuinely pinned to ~5.4, your options are: fork and widen the constraint, use --ignore-platform-reqs (risky — the code may use removed features like each(), create_function, or non-Throwable exceptions), or vendor the two or three classes you need directly into app/Support/. Vendoring is often the honest answer for a library this small.

License is NOASSERTION. GitHub could not identify a recognized license. That is a legal blocker for a commercial product until a human confirms terms. Check for a LICENSE file in the repo root; if there isn't one, the default is all-rights-reserved and you should not ship it. This is the single highest-risk item here and it has nothing to do with code quality.

Zero dependents means zero field testing. Nobody else is running this in production. Treat every class as unproven: write your own unit tests around the exact behavior you depend on, so a patch release or a fork can't silently change semantics. composer audit will tell you nothing useful here — there's no dependency tree — so pair it with a static analysis pass (phpstan/psalm) on the vendor directory.

Import collisions with Laravel. Hash and Config are loaded names in most Laravel apps. Alias on import or, better, keep UCC imports confined to your adapter classes:

use RybakDigital\Ucc\Crypt\Hash as UccHash;

No caching in the Config utility. Laravel's config() is cached by config:cache; a naive file-reading Config class probably re-reads on every access. If you call it in a request loop, cache the parsed result yourself in a singleton or Cache::remember. Also confirm whether it throws or returns null on a missing key — pick one behavior and normalize it in your wrapper rather than scattering null checks.

Key management is on you. The crypt class takes a key as a constructor argument; there's no config publishing, no env var convention, no key rotation. Wire it from config('ucc.hash_key') sourced from an env var, and never from a value committed to the repo. If you need key rotation or authenticated encryption guarantees, use Illuminate\Encryption instead — it's audited, supports key rotation via previous_keys, and is maintained.

Debugging: log the ciphertext, never the plaintext. When crypt round-trips fail, the usual cause is encoding (base64 vs raw binary) differences between how you store the value and what the class returns. Inspect bin2hex() of the ciphertext, not the cleartext, and confirm your DB column is text/longText — not varchar(255), which truncates longer payloads and produces confusing decrypt failures.

Extension points are minimal by design. These are concrete classes with no interfaces. If you find yourself wanting to subclass them, that's a signal to write your own adapter and keep UCC as one implementation detail. That adapter is your extension point.

Pin and monitor. Set a calendar reminder to re-check the repo before your next major upgrade. A project with a 2025 tag on PHP 5.x-era code and dead CI badges is likely to go quiet again; know that going in, and keep the blast radius to your adapter layer.

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.
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route