Download the PHP package aliziodev/laravel-taxonomy without Composer

On this page you can find all versions of the php package aliziodev/laravel-taxonomy. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package laravel-taxonomy

Laravel Taxonomy

codecov Tests Code Quality
Latest Version on Packagist Total Downloads PHP Version Laravel Version Ask DeepWiki

Manage categories, tags and any hierarchical structure in Laravel. Terms live in one table, attach to any model through a polymorphic pivot, and hierarchies are maintained as a nested set so ancestor and descendant lookups stay a single query.

🇮🇩 Dokumentasi Bahasa Indonesia

Contents

Requirements

Requirement Version
PHP 8.2 or newer
Laravel 11, 12 or 13

Installation

taxonomy:install publishes the config and the migration. Pass --force to overwrite files that already exist — without it, existing files are left untouched and the command tells you so.

To publish individually:

Configuration

config/taxonomy.php, with the shipped defaults:

morph_type is the one setting to get right up front. It decides whether the pivot stores taxonomable_id as an integer, UUID or ULID, and it cannot be changed after you migrate without rewriting the table. Use numeric for the usual auto-incrementing keys.

migrations.autoload controls whether the package registers its migration path with php artisan migrate. Disable it when you run migrations per tenant connection:

Quick start

Add the trait to any model that should carry taxonomies:

Working with taxonomies

The Taxonomy facade proxies TaxonomyManager and exposes exactly these methods:

The facade is not an Eloquent builder. Taxonomy::where(...) and friends do not exist on it. For query building, import the model instead:

Model scopes: type(), root(), ordered(), roots(), atDepth(), nestedSetOrder().

Bulk imports

create() costs four to seven queries per row — a slug check, a parent or max(rgt) lookup, the range updates that widen the nested set, the insert, and a cache bump. Fine for a handful of rows, painful for a seeder.

bulkCreate() resolves slugs in memory, inserts in chunks, and renumbers the nested set once at the end:

Measured on 10,000 rows:

Time Queries
create() in a loop, flat 14.8s 40,000
bulkCreate(), flat 0.95s 32
create() in a loop, nested 22.0s 59,980
bulkCreate(), nested 1.0s 37

Both paths produce the same tree; only the number of round trips differs.

It accepts any iterable, so a generator keeps memory flat on large imports:

Rows take name and type (required), plus optional slug, description, parent_id, sort_order, meta, created_at and updated_at. Slugs are generated and de-duplicated against both the batch and the rows already in the table; an explicit slug that is already taken raises DuplicateSlugException, exactly as create() would.

Model events are not fired. That is the trade for the speed. If you rely on observers, or on anything hooked into creating/created, keep using create(). Everything the package itself does in those hooks — slug generation, nested set values, cache invalidation — bulkCreate() does for you.

Attaching to models

Each accepts an id, a Taxonomy, an array, or any collection:

These take taxonomy ids or models, not slugs. Passing a slug string attaches nothing. Resolve it first: Taxonomy::findBySlug('featured', TaxonomyType::Tag).

Reading and checking:

Type-specific variants

Every attach/detach/sync/toggle has an *OfType twin that only touches terms of one type, leaving the rest of the model's taxonomies alone:

Ids that are not of the given type are skipped — that filtering is the point of these methods.

Query scopes

Scopes chain, so combining them is an AND:

filterByTaxonomies() takes a keyed array, handy for request filters:

Hierarchies

Hierarchy is stored twice: as parent_id, and as nested-set lft/rgt/depth columns kept in sync automatically on create, update, delete and restore.

getAncestors()/getDescendants() read lft/rgt and are the fastest option. ancestors()/descendants() follow parent_id and stay correct even if the nested set has drifted — use them if you write to the table outside the model.

Refresh before using the nested-set variants on a model you already held. Adding a child widens its parent's rgt in the database, and an instance loaded before that still carries the old bounds — getDescendants() then returns an empty collection with no error:

descendants() is keyed on the id, so it is immune to this.

Trees:

Types

TaxonomyType ships Category, Tag, Color, Size, Unit, Type, Brand, Model, Variant. Everywhere a type is accepted you may pass the enum or a plain string, so custom types need no registration:

List them in config so tooling and the rebuild command know about them:

Enum helpers:

Metadata

meta is a JSON column, cast to array:

There is no translation layer; meta is a reasonable home for translations:

Caching

tree(), flatTree() and getNestedTree() are cached for cache.ttl (24 hours by default) and invalidated automatically whenever a taxonomy is created, updated, deleted, restored, moved, or rebuilt.

Invalidation works by bumping a version key, so entries expire logically rather than being enumerated and deleted — that keeps it correct on cache stores without tag support.

Do not wrap these calls in another Cache::remember(). A second, unversioned layer will not see the package's invalidation and will serve stale trees.

Multi-tenancy

Two things need attention.

1. Isolate the cache. Cache keys are global unless you say otherwise, so without a scope one tenant can be served another tenant's tree. Register a resolver:

Or point taxonomy.cache.scope at an invokable class — a class name rather than a closure, so the config survives php artisan config:cache:

With no scope registered the keys are unchanged from earlier releases, so single-tenant apps need no action.

2. Scope the data yourself. The package ships no tenant_id column. Add one, and replace the unique index — the shipped unique(['slug', 'type', 'deleted_at']) otherwise stops two tenants using the same slug within a type:

Then point the package at a model carrying your scope:

It must extend the package's Taxonomy — that is where slug generation and nested-set maintenance live.

The *OfType methods validate the ids you pass without applying global scopes, so a taxonomy shared across tenants is not silently discarded. The flip side: an id from another tenant will attach if your application passes it through. Validate user input, e.g. Rule::exists() scoped to the tenant.

Slugs and exceptions

Slugs are generated from the name and are unique within a type, so a featured category and a featured tag can coexist.

Two exceptions, both extending TaxonomyException:

MissingSlugException is thrown when slugs.generate is false and no slug was supplied.

Soft deletes interact with uniqueness through two settings: consider_trashed decides whether trashed rows block a slug, and regenerate_on_restore decides whether restoring a row with a now-taken slug renames it or throws.

Console commands

taxonomy:rebuild-nested-set recomputes lft, rgt and depth. You need it only if rows were written outside the model — direct SQL, a raw seeder, a bulk import. It rebuilds every type when no type is given, uses one transaction per type, and clears the caches afterwards. --force is required when running non-interactively.

Examples

Troubleshooting

Attaching does nothing, no error. You are probably passing slugs. These methods take ids or models; resolve slugs with Taxonomy::findBySlug() first.

Call to undefined method ... where() on the facade. The facade proxies TaxonomyManager, not Eloquent. Import Models\Taxonomy for query building.

Wrong column type on the pivot. morph_type must match your models' keys and is fixed at migration time. Check it before your first migrate.

Tree looks stale. It should invalidate itself; if you write rows with raw SQL, call Taxonomy::clearCacheForType() and, if lft/rgt are involved, php artisan taxonomy:rebuild-nested-set.

Ancestors or descendants look wrong. The nested set has drifted, usually from direct SQL writes. Run the rebuild command, or use ancestors()/descendants(), which follow parent_id.

Upgrading

See UPGRADE.md. Notable in 2.11: cache isolation for multi-tenant apps, and custom relationship names are deprecated for removal in 3.0.

Contributing

See CONTRIBUTING.md. Commits follow Conventional Commits; releases and the changelog are generated from them.

Security

Report vulnerabilities to [email protected] rather than the public tracker.

License

MIT. See LICENSE.


All versions of laravel-taxonomy with dependencies

PHP Build Version
Package Version
Requires php Version ^8.2|^8.3
illuminate/contracts Version ^11.0|^12.0|^13.0
illuminate/support Version ^11.0|^12.0|^13.0
illuminate/database Version ^11.0|^12.0|^13.0
laravel/framework Version ^11.0|^12.0|^13.0
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package aliziodev/laravel-taxonomy contains the following files

Loading the files please wait ...