visiosoft/global_helper-extension
VisioSoft Global Helper Extension is a Laravel/PHP package that extends global helper utilities for convenient, reusable functions across your application. It aims to simplify common coding tasks and integrate easily into existing projects.
visiosoft/global_helper-extension is a Streams Platform (PyroCMS/OpenClassify lineage) addon that ships a bundle of global PHP helper functions — the kind of small utilities (setting()-style accessors, string/date formatting, image/URL helpers, etc.) that OpenClassify templates call directly. It has no stars and no dependents, so treat it as "read the source first, then use."
Minimal setup:
composer require visiosoft/global_helper-extension
Because it is an addon, the package must run inside an app that already has the Streams Platform (pyrocms/streams-platform or the visiosoft/streams-platform fork OpenClassify uses). On a bare Laravel app it will install but the helpers may reference Streams services and fail at call time.
Where to look first, in this order:
composer.json — check the autoload.files entry. That tells you exactly which file defines the global functions. That file is the package's public API.src/*ServiceProvider.php — what it binds, what it registers (Blade directives, config merges, addon manifest).src/Helpers/ or resources/helpers.php — read every function signature before using any of them.config/ — any publishable config keys the helpers read.If the service provider is not auto-discovered (older Streams addons sometimes aren't), register it in config/app.php providers or via the addon's composer.json extra.streams block, then:
php artisan vendor:publish --provider="Visiosoft\GlobalHelperExtension\GlobalHelperExtensionServiceProvider"
php artisan config:clear
First use case: replace a hand-rolled helper in a Blade view with the package's version. For example, if you currently do number_format($price, 2) scattered across views, find the matching global helper and centralize on it so formatting stays consistent across the classifieds UI.
Global functions are convenient in Blade and controllers; they are painful in domain code. Keep them at the presentation boundary:
{{-- resources/views/listing/show.blade.php --}}
<img src="{{ global_helper_image($listing->cover, 'thumb') }}" alt="">
<span>{{ global_helper_price($listing->price, $listing->currency) }}</span>
In a controller or job, prefer a thin wrapper so you can test and swap later:
final class ListingPresenter
{
public function price(Listing $listing): string
{
return global_helper_price($listing->price, $listing->currency);
}
}
Because the package is unmaintained-ish and version-pinned, guard calls at boot boundaries so a missing function degrades instead of fataling:
if (function_exists('global_helper_price')) {
// use package helper
} else {
// fallback to your own formatter
}
This is the single most useful pattern for a 0-star dependency: it lets you keep the package optional and drop it without a rewrite.
The natural home for these helpers is a Streams field formatter or a view composer that decorates entries before they hit the view:
// in a view composer or presenter
$view->with('displayPrice', global_helper_price($entry->price));
This keeps Streams' raw field values intact (important — Streams caches and reuses entry objects) while formatting only at render time.
setting() / config()Most helpers in this family read a value and format it. Feed them config-driven values rather than hardcoding:
global_helper_price($listing->price, setting('streams::currencies.default', 'EUR'));
Create one file in your app — app/Support/Helpers.php — that re-exports the package functions you actually use, with your own names:
function app_price(...$args) { return global_helper_price(...$args); }
Now a grep for global_helper_ gives you the full blast radius when you need to migrate off the package. This is the difference between a one-hour upgrade and a one-week one.
Global functions can't be mocked cleanly. Wrap them (pattern 1) and test the wrapper:
public function test_price_presenter_formats_currency(): void
{
$this->assertSame('€1,200.00', (new ListingPresenter)->price($listing));
}
If a helper touches the container (app(), config(), setting()), resolve it inside the function body — not at file load — so tests with a booted app work.
Composer files autoload runs before the app boots. Helpers are defined at autoloader include time, so a function body cannot rely on anything being registered yet. Reading config/settings inside the function is fine; doing it at the top level of the helpers file is not. If you see a helper that captures a value in a global at include time, expect stale values after config:cache.
Name collisions are the real risk. Global helpers frequently shadow Laravel/Streams helpers or each other (str_*, setting, human_date, image). If you get "cannot redeclare function" or "undefined function" only in some environments, check which package's autoload.files loads first — Composer resolves this by package install order, which is not stable across machines. Pinning the package and running composer dump-autoload -o in a clean environment is the fix.
Editing the helpers file does nothing until autoload is regenerated. composer dump-autoload after any change, and php artisan config:clear / config:cache when helpers read config.
Opcache in production. Because these are plain functions, opcache will hold the old version until restart. If a deploy "doesn't take," restart PHP-FPM.
Addon registration quirks. Streams addons often need to be present under addons/ (not just vendor/) or listed in the app's addon manifest to be booted. If helpers are undefined despite composer require succeeding, this is almost always why. Check php artisan addon:list (or the Streams equivalent) for the extension.
Vendor the helpers if you depend on them. Zero stars, zero dependents, a single 2024 release, and no issue activity means abandonment risk is real. The functions are typically a few dozen lines each — copying the ones you use into app/Support/ removes the dependency entirely and is often cheaper than tracking upstream. Preserve the license header.
Watch for Streams-typed arguments. Helpers that accept $entry, $field, or $stream won't validate what you pass; you'll get a null or a silent wrong-format rather than an exception. Dump inputs in a Tinker session (php artisan tinker) before wiring into a loop.
Extension point: the service provider is your hook. Bind your own override before the package's provider, or register a Blade directive alias so templates can call @price($x) while you control the implementation internally. This lets you adopt the package's API surface in views today and swap the implementation later without touching templates.
Debugging checklist when a helper misbehaves: (1) function_exists() check, (2) confirm the provider is booted (php artisan about or a temporary dd() in register()), (3) confirm autoload.files points at the file you think, (4) check for a duplicate definition from another addon, (5) config:clear + opcache reset.
How can I help you explore Laravel packages today?