scafera/translate
Scafera Translate is a Laravel/PHP package for managing multilingual translations with a clean, consistent API. It helps you organize and serve language strings so your application stays localized, maintainable, and easy to scale as your project grows. Designed to fit naturally into Laravel projects...
At a glance, this release only tightens failure handling around a missing translations directory, so the assessment below is grounded in that behaviour plus standard Laravel translation-package conventions.
composer require <vendor>/<package> and let package discovery register the service provider.php artisan vendor:publish --tag=<package>-config) — this is the first file to read, since it almost certainly holds the translations path, loader selection, and any cache settings.boot()/register() for how it resolves the translation service — that binding is where ServiceNotFoundException originated prior to v1.0.2.php artisan config:clear and hit a page with a missing/extra lang directory to confirm the fix behaves as described (no exception, graceful degradation).If your app already ships a populated lang/ directory, the upgrade is a drop-in patch with no API surface change.
Directory-agnostic bootstrapping. The v1.0.2 fix implies the package previously assumed the translations directory existed at resolution time. Treat the directory as optional in your own code too:
// config/<package>.php
'path' => env('TRANSLATIONS_PATH', lang_path()),
This keeps local dev, CI, and container builds consistent without relying on the package's new null-safety to paper over a misconfigured path.
Guard in CI rather than at runtime. Because a missing directory now resolves silently instead of throwing, promote the check into a test:
it('ships translation files', function () {
expect(is_dir(lang_path()))->toBeTrue()
->and(glob(lang_path('en/*.php')))->not->toBeEmpty();
});
Per-environment wiring. Local: default lang_path(). Production: a read-only path baked into the image. If you use a DB or remote translation source, bind your custom loader in a dedicated provider registered after the package provider so yours wins.
Deploy pipeline integration. Add the directory (or at least a .gitkeep) to your build artifact and verify it survives docker build — the classic failure is COPY globs that drop empty directories, which is exactly the scenario this patch was written for.
Testing. Point the config at a fixture directory in phpunit.xml via env var, and use config()->set() in setUp() for per-test overrides instead of mutating files on disk.
ServiceNotFoundException; you get empty strings or raw keys in the UI. Watch for untranslated keys in staging — they are the real signal now. Consider asserting __('some.known.key') !== 'some.known.key' in a smoke test.php artisan <package>:cache style commands after upgrading.config:cache freezes the resolved path. If the directory is created later in the boot sequence (e.g. by a deployment script running after artisan optimize), the cached config points at a location that may not exist yet at request time. Clear and rebuild caches as the final deploy step.Translator::extend() hook in the provider; that is the supported seam for custom sources. Avoid subclassing the package's service directly — internal bindings are what shifted between 1.0.1 and 1.0.2.^1.0 is reasonable; there is no migration or republish step indicated.How can I help you explore Laravel packages today?