cartalyst/nested-sets
Cartalyst Nested Sets adds an efficient nested set implementation to Laravel Eloquent models, making it easy to store, query, and manipulate hierarchical data with fast ancestor, descendant, and tree operations via a simple trait.
This release is mostly a compatibility milestone (PHP 7.4 minimum, PHP 8 support) plus a fix for a presenter-resolution bug that bit people running 7.4. The day-to-day API is unchanged, so if you're already using the package the upgrade is a composer.json bump plus a test run.
1. Check your PHP floor before anything else. v7.0.0 raises the minimum to PHP 7.4. If you're still on 7.2/7.3 anywhere (including CI images, Dockerfiles, or a config.platform.php entry in composer.json), Composer will refuse the upgrade — and if you force it with --ignore-platform-reqs you'll get fatals rather than a clean error. Pin those projects to the 6.x line until they're on 7.4+.
2. Install and confirm the version actually resolved.
composer require <vendor>/<package>:^7.0
composer show <vendor>/<package> # confirm 7.x, not a silent 6.x hold-back
php -v # confirm 7.4+ or 8.x
3. Look at three things first, in this order:
Presenter class — this is the contract every presenter you write extends, and it tells you which methods (__get, present, decorate, etc.) are available for delegation.4. First use case: formatting for the view layer. The canonical entry point is a model that has display logic scattered across Blade templates — currency formatting, date presentation, full names, status badges. Move that into a presenter class, bind it to the model, and call it from the template. That's a ten-minute change that immediately shows you whether the package fits your codebase's conventions.
Model-to-presenter binding. Most presenter packages resolve by convention (e.g. App\Models\User → App\Presenters\UserPresenter) or via an explicit declaration on the model. Convention is less boilerplate but means a presenter class appears "for free" when someone creates the file — a real source of surprise in larger teams. Pick one style and document it; mixing is how you end up with two presenters for the same model and no idea which is live.
Keep presenters pure and dependency-light. The healthiest pattern is a presenter that takes the model and returns strings/arrays — no queries, no auth(), no now() buried inside. Where you need collaborators, constructor-inject them (the container typically resolves presenters, so this works) rather than reaching for facades. If a presenter needs a query, that's usually a sign the value belongs on the model as an accessor or in a query scope.
Use presenters at the edges, not in domain logic. Presenters are a view concern. Use them in Blade, in API resources, in mail templates. Don't let a service class or a job depend on a presenter — that couples your business logic to display formatting and makes the presenter hard to change later.
Compose rather than inherit. When presentation logic grows (a user presenter that formats name, address, and subscription status), prefer small presenter classes composed together over one 400-line presenter with a deep inheritance chain. It also keeps the base-class upgrade surface small — relevant here, since a major version is exactly when base-class internals are free to change.
Testing. Presenters are the easiest thing in a Laravel app to unit test: instantiate with a model (or a plain stub), assert on returned strings. If you're upgrading, this is also your cheapest regression net for the 7.4 presenter-resolution fix — instantiate through the real resolution path (e.g. via the model accessor) rather than new UserPresenter($user) in at least one test, otherwise you're not exercising the code that changed.
API resources. If you expose presenters through JsonResource, be explicit about which fields you pull. Presenters returning arrays plus a resource that spreads them is a fast route to accidentally leaking a field.
The 7.4 presenter bug is the reason to upgrade, not just the PHP 8 support. The release notes call out "presenter not being properly set on PHP 7.4" — that's a resolution/lifecycle problem, and its symptoms are ugly: null presenter errors, or a presenter that silently returns the raw model value instead of the formatted one. If anyone on your team reported "the presenter just doesn't work on my machine" while on 7.4, this is very likely the cause. Verify the fix by exercising a model that goes through the presenter path in a test, not just by checking composer show.
"PHP 8 support" is not the same as "PHP 8 clean." PHP 8 introduced named arguments, which break on parameter names changing, and tightened several type-juggling behaviours. If your own presenter subclasses use loose signatures, add : string/: mixed return types and keep parameter names stable — or you'll find out about it when someone calls your presenter with named arguments. Run your suite on both 7.4 and 8.x if you support both.
Lock files in multi-app repos. If several Laravel apps share a package or you have a monorepo, a major bump can land in one composer.lock and not another. Grep for the package across the repo after upgrading.
Presenter attributes can shadow model attributes. Most implementations delegate __get to presenter methods first. A presenter method named name() will silently override the name column in templates — you get formatted output where you expected raw data, or vice versa. Watch for this especially if someone adds a presenter method with a column's name during a refactor.
Serialization doesn't follow automatically. toArray(), toJson(), and queue payloads on the model generally won't include presenter output. If the JSON API needs the formatted value, do it in the resource, explicitly — don't assume the presenter is in the serialization path.
N+1 hiding in presenters. A presenter that touches $this->model->subscription->plan->name will happily lazy-load per row in a table of 50 users. Grep presenters for relationship access and make sure the controller eager-loads accordingly; the presenter's readability makes the query cost easy to forget.
Extension points worth knowing before you upgrade. The config file (naming convention / namespace) and the model-side presenter declaration are the two hooks people actually customize. If your app subclasses the base presenter to override resolution or add helpers, diff that subclass against the new base class on upgrade — a major version is where those internals are most likely to have shifted, and the PHP 8 work touches the same code paths.
Debugging resolution failures. When a presenter "isn't being applied," check in this order: (1) the class name/namespace actually matches the configured convention, (2) Composer's autoloader has been dumped after adding the class, (3) you're on 7.0.0+ if the runtime is 7.4, (4) the model isn't returning a cached/raw attribute that bypasses the presenter delegation.
How can I help you explore Laravel packages today?