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

Utilities Bundle Laravel Package

kunstmaan/utilities-bundle

A small Symfony utility bundle from Kunstmaan providing shared helper classes for slug generation, string and class manipulation, and common file/URL tasks. Useful across Kunstmaan bundles and handy for everyday backend work in Symfony projects.

View on GitHub
Deep Wiki
Context7

Getting Started

First, the reality check: this is a Symfony bundle from 2014, with 12 stars and 0 dependents. It contains roughly two small classes — a Cipher and a ShellHelper — wrapped in a Symfony Bundle subclass and a DI extension. It does not ship a Laravel service provider, config, or facade. You will spend more time wiring it than rewriting it.

Minimal steps

  1. Check installability before anything else:
    composer require kunstmaan/utilities-bundle --dry-run
    
    If it fails on symfony/symfony ~2.x constraints (likely on any PHP 8 / Laravel 9+ project), do not fight it — copy the two service classes into app/Support/ and move on. You lose nothing; the bundle adds no behaviour beyond those classes.
  2. Read the source first. The entire package is a few hundred lines in vendor/kunstmaan/utilities-bundle/. Look at the cipher class and the shell helper class — that's the whole API surface.
  3. If it does install, register a thin Laravel provider rather than the Symfony bundle:
    // app/Providers/UtilitiesServiceProvider.php
    public function register(): void
    {
        $this->app->singleton(Cipher::class, fn () => new Cipher(
            config('services.kunstmaan_utilities.cipher_key')
        ));
    
        $this->app->singleton(ShellHelper::class, fn () => new ShellHelper());
    }
    
  4. Put the key in .env (UTILITIES_CIPHER_KEY=...) and expose it via config/services.php. Never hardcode it; the class needs the exact key length.

First use case: encode an opaque token — an invite token, an unsubscribe link parameter, a stored third-party credential — into a string you can put in a URL, and decode it back on the way in. That is the one thing this package genuinely simplifies, and it's a five-minute integration.

Implementation Patterns

Always wrap the cipher behind your own service. The class returns raw binary from encode(), which will corrupt the moment it hits a URL, a cookie, a JSON column, or a log line. Encode at the boundary, once:

class TokenCipher
{
    public function __construct(private Cipher $cipher) {}

    public function encrypt(string $value): string
    {
        return rtrim(strtr(base64_encode($this->cipher->encode($value)), '+/', '-_'), '=');
    }

    public function decrypt(string $token): ?string
    {
        $raw = base64_decode(strtr($token, '-_', '+/'), true);

        return $raw === false ? null : $this->cipher->decode($raw);
    }
}

Use it for reversible data only. Passwords → Hash::make(). Anything that has to resist tampering → Laravel's built-in Crypt (AES-256-CBC with an HMAC) or encrypt()/decrypt(). The Kunstmaan cipher is unauthenticated, so treat it as obfuscation plus confidentiality, never integrity.

Shell helper: fire-and-forget work without a queue worker. The useful pattern is launching a long-running Artisan command out of band and tracking its PID:

$pid = $shell->runInBackground(sprintf(
    'php %s artisan reports:build %d > /dev/null 2>&1 &',
    escapeshellarg(base_path()),
    $report->id
));

$report->update(['pid' => $pid, 'started_at' => now()]);

Then a scheduled command polls isRunning($pid) and calls killProcess($pid) after a timeout, updating the row state. This is a legitimate escape hatch on hosts where you can't run queue:work persistently — but it is strictly worse than a real queue: no retries, no backoff, no failure visibility, no serialization safety.

Escape everything, structurally. The shell helper takes a command string. There is no argument array. Every interpolated value goes through escapeshellarg(), and any command name through escapeshellcmd(). If a value originates from a request, and you skip this, you've written a remote code execution vulnerability.

Keep PID bookkeeping in your own table. Add pid, started_at, finished_at, status. Don't rely on the helper to remember anything — it doesn't.

Testing: fake your own TokenCipher and a ProcessRunner interface in tests. Don't try to fake the vendor classes; they'll be gone after the first refactor.

Gotchas and Tips

  • mcrypt is gone. The cipher is built on mcrypt_*, removed from PHP in 7.2. On any modern runtime it's a fatal error, not a deprecation. PECL mcrypt exists but is unmaintained and a poor bet on PHP 8.
  • You probably cannot decrypt old data with OpenSSL. "Rijndael 256" here means a 256-bit block, not AES-256 (128-bit block). OpenSSL only exposes AES block sizes, so openssl_decrypt will not reproduce these ciphertexts. If you have live data, migrate with phpseclib's Rijndael implementation (which supports arbitrary block sizes) in a one-off script: decrypt, then re-encrypt with Crypt::encryptString(). Do not attempt a byte-compatible reimplementation by hand.
  • No IV, no MAC. Likely a fixed or zero IV, meaning identical plaintexts produce identical ciphertexts — an attacker can spot duplicates in your database. Combined with unauthenticated CBC, that's a padding-oracle invitation if decryption errors ever leak to a user.
  • Silent key mangling. mcrypt pads or truncates keys to the required length without complaint. A 30-character key in .env will "work" and produce data you can't decrypt after you fix the key to 32 characters. Validate the length at boot.
  • isRunning() and PID reuse. These helpers typically shell out to ps -p <pid>. After a reboot, PIDs get recycled and a stale row will report "running" for an unrelated process — and killProcess() will kill it. Store the process start time alongside the PID, or write a lock/status file from the child process instead.
  • Unix-only. ps, kill, & and > /dev/null don't exist on Windows. Anyone developing on Windows will get confusing failures that don't reproduce in production.
  • Background children lose context. No .env guarantees, no cwd, different user under FPM, no PATH to your PHP binary. Always use absolute paths and cd into the app root.
  • Disabled functions. exec/shell_exec are commonly in disable_functions on shared hosting — check php -i | grep disable_functions before designing around this.
  • Symfony DI bleed-through. If you install the bundle properly, it expects kunstmaan_utilities.cipher.key in a Symfony YAML config and a compiled container. Laravel has neither, so you'd be pulling symfony/http-kernel into a Laravel app just to satisfy autoloading. Not worth it.
  • Unmaintained, no security response. Last release 2014. Fork the two classes into app/Support, add types, drop mcrypt, add a proper IV and HMAC, and you'll have something better in an afternoon. Treat this package as a reference implementation, not a dependency.
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.
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle