graham-campbell/viewer
Graham Campbell's Viewer is a PHP package for rendering views with a simple, flexible API. It integrates with Laravel and provides a clean way to manage view rendering, making it easy to add reusable templates and view logic to your applications.
Establish what you actually have before touching a template. Two artifacts describe this package and they disagree: the Packagist blurb advertises a file browser (disks, MIME types, inline previews) while the repository tagline says "View Is A View Workaround For Laravel 4.1." The blurb is generated copy. The code is a view-resolution shim. Trust src/, not the description.
Minimal steps:
Pin the current state.
composer show graham-campbell/viewer # exact version + commit hash
composer why graham-campbell/viewer # what pulled it in
Commit composer.lock alongside this. The only published tag is 0.2.0-alpha — a pre-1.0 alpha cut after the project moved to the GrahamDeprecated org. A routine composer update must not be allowed to float you onto it.
Find the registration point. In Laravel 4.1 this is app/config/app.php → providers, and aliases if a facade was registered. That entry is your entire day-to-day interaction with this package.
Read the provider class in vendor/graham-campbell/viewer/src/ and classify the mechanism — this single fact determines everything downstream:
Your first real use case is characterization, not adoption. You want to know exactly what view resolution does today so you can change it without regressing templates. Drop this in a route closure or a test:
Route::get('/_diag/view', function () {
$finder = App::make('view')->getFinder();
return dd($finder->getPaths(), $finder->getHints());
});
Then assert the behavior you find:
$path = App::make('view')->getFinder()->find('home');
// path precedence, namespaces, package-vs-app override order, missing-view behavior
Cover four things: path precedence, namespaced/package views, override ordering between package and app views, and what happens on a missing view (exception vs. silently rendering the wrong file). This is cheap, needs no upgrade business case, and de-risks every later step.
Treat it as ambient infrastructure, never a library you call. You do not use anything from this package in application code. Call sites stay View::make('home', $data) / view('home') — the shim only patches resolution underneath them. If you find yourself importing from it, that is the signal to isolate and replace it.
Pattern 1 — Map effective behavior onto native config, then delete the provider. This is the preferred path on any framework version. The native equivalents for everything a Laravel 4.1 view workaround patches:
// app/config/view.php
'paths' => array(__DIR__.'/../views', base_path('themes/default')),
// or at runtime, in a service provider's boot()
View::addLocation(base_path('themes/default'));
View::addNamespace('Blog', base_path('modules/Blog/views'));
Share globals with View::share('key', $value) or a view composer rather than whatever hook the shim offered. Do not port the shim forward — port its behavior.
Pattern 2 — Keep it running while the upgrade is blocked. If the host application genuinely cannot leave Laravel 4.1 yet, pin hard and make the dependency visible:
composer.json (not a range, not the alpha tag).Pattern 3 — Removal as one tracked unit of work. Sequence: characterization tests green → provider removed from app/config/app.php → alias removed from aliases → composer remove graham-campbell/viewer → tests still green → clear compiled views (rm app/storage/views/* on 4.1; php artisan view:clear on 5.x+). The effort belongs to the framework upgrade, not to the package.
Integration cautions:
View::, view->, singleton('view'), and bindShared('view'). Two packages rebinding the same key gives you order-dependent resolution that is genuinely expensive to diagnose.aliases, not just providers. A facade alias registered here can collide with a newer framework alias mid-upgrade.composer.json constraint block before accepting the alpha — PHP requirement, illuminate/* ranges, PSR-4 mappings. With no upstream to patch, an unexamined constraint change can move what resolves in your lockfile irreversibly.Silent mis-resolution is the primary failure mode. The wrong template renders, or a stale compiled view is served, with no error at all. Highest risk because it is invisible until a user sees it. When a view resolves unexpectedly, work in this order:
php artisan view:clear (5.x+) or rm -f app/storage/views/* (4.1).dump(App::make('view')->getFinder()->getPaths());
dump(App::make('view')->getFinder()->getHints());
app/config/app.php for a competing view binding.aliases for a facade collision.The version string is a warning, not a detail. 0.2.0-alpha means no API stability commitment. The release's entire substance is PHP 5.6 and HHVM compatibility — it widens the runtime envelope, not the framework one. PHP 5.6 hit EOL in December 2018; HHVM dropped PHP support in 2018. A headline capability of "runs on two retired runtimes" tells you where this project's center of gravity sits.
A post-deprecation alpha is a worse signal than silence. It invites a false "actively maintained" reading from a changelog that mentions only unspecified Composer tweaks. Diff those tweaks before taking the tag.
Description drift is a red flag, not a docs bug. If your code depends on what the file-browser blurb describes, it does not depend on this package. Look for the real source — this artifact will not deliver it.
No CVE path. Zero stars, zero dependents, no issue triage, no active maintainer. Any vulnerability in Laravel 4.1 or its transitive dependencies is unaddressable by design. That is a platform risk to escalate through the framework-upgrade conversation — do not let it become a package-level scoping discussion.
Do not extend it. The instinct to add a hook or subclass the shim is the trap. The extension point you want is the framework's native view configuration (paths, namespaces, composers, View::share). The correct move is always replacement, never integration. Budget zero for porting it forward.
How can I help you explore Laravel packages today?