Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Categorizer Bundle Laravel Package

sylius/categorizer-bundle

Sylius Categorizer Bundle adds flexible categorization to Symfony and Sylius apps. Build hierarchical category trees, assign categories to any Doctrine entity, and manage categorized resources through reusable models, repositories, and UI integration.

View on GitHub
Deep Wiki
Context7

Getting Started

Do not start a new project with this package. The repository is archived, the description literally reads DEPRACATED, and the last supported stack is Symfony 2.x / PHP 5.x. There are zero dependents on Packagist, which means you will not find examples, StackOverflow answers, or a community to lean on. Treat this as a legacy artifact you inherit, not a tool you adopt.

Minimal steps if you find it in an existing composer.json:

  1. Locate the version actually installed — the API changed more than once between 1.x and 2.x:
    composer show sylius/categorizer-bundle
    grep -R "sylius_categorizer" app/config/config.yml
    
  2. Read the bundle config first, not the docs. The README on the archived repo is stale; the extension class (DependencyInjection/SyliusCategorizerExtension.php) and Resources/config/doctrine/model/*.orm.xml are the source of truth for class overrides, drivers, and tree strategy.
  3. Find the model layer. You are looking for Sylius\Bundle\CategorizerBundle\Model\Taxonomy and Category, the CategorizableInterface / Categorizable trait, and the repositories under Doctrine/ORM.
  4. Map it to the modern equivalent before touching anything. This bundle was replaced by SyliusTaxonomyBundle (Taxonomy + Taxon), and in current Sylius the taxonomy model lives in core (Sylius\Component\Taxonomy). Any feature request or bug fix you plan should be written against the successor API, then back-ported — not the other way around.

First real use case in a legacy app: a product (or any domain entity) is "categorizable", categories live in a nested-set tree inside named taxonomies, and you render/query that tree for navigation and filtering. Confirm that is still the shape of your data before writing code:

// Legacy: attach taxonomy to an entity
class Product implements CategorizableInterface
{
    use Categorizable; // provides getCategories()/setCategories()
}

Implementation Patterns

Entity composition over inheritance. The trait/interface pair is the intended integration point — your model implements CategorizableInterface and uses the Categorizable trait, then you map the collection in your own Doctrine XML/YAML. Do not extend the bundle's concrete Category class directly unless you are happy owning its tree annotations forever.

Taxonomy-scoped trees, not one global tree. Categories belong to a Taxonomy; tree operations (move, reorder, levels) are always relative to a taxonomy root. Query patterns look like:

$taxonomy = $taxonomyRepository->findOneBy(['name' => 'main']);
$children = $categoryRepository->getChildren($parent, true); // direct children / whole subtree

Service-layer, not controller logic. Use the bundle's manager services rather than touching the tree repository directly — they wrap the Gedmo/Doctrine tree listener and keep the nested-set lft/rgt/root/level columns consistent:

$manager = $container->get('sylius_categorizer.manager.category');
$manager->move($category, $newParent);

Seeding via fixtures. Build taxonomies and categories in data fixtures (doctrine:fixtures:load) rather than creating them through admin UI on every environment. Trees are cheap to build in fixtures and expensive to repair afterwards.

Slug-driven lookups. Use Category slugs (generated by the Sluggable listener) for front-end routing and filtering instead of IDs, and always resolve within a taxonomy scope so two taxonomies can both have a shoes category.

Form integration through aliases. The bundle registers form types under names like sylius_categorizer_taxonomy and sylius_categorizer_category. Embed them via createNamed/get('form.factory') patterns rather than instantiating type classes by FQCN — this is the one place where upgrading the bundle silently breaks you, because aliases were renamed between versions.

Configuration shape. Expect something like:

sylius_categorizer:
    driver: doctrine/orm
    engine: doctrine/orm
    classes:
        taxonomy: Acme\AppBundle\Entity\Taxonomy
        category: Acme\AppBundle\Entity\Category

Override classes here — never by editing vendor files — otherwise any composer operation wipes your customization.

Gotchas and Tips

  • Nested set corruption is the #1 failure mode. Direct $em->remove() / $em->persist() on a category bypasses the tree listener and leaves dangling lft/rgt values. Always go through the manager. After a bad import, run doctrine:tree-recover (Gedmo) and verify with getLevel() on children.
  • cascade: ["persist", "remove"] on the categorizable collection is a footgun. Deleting one product can cascade into deleting shared category entities. Map the owning side as inversedBy-only and control deletion explicitly.
  • Deleting a category with children fails or orphans them depending on your onDelete FK setup. Decide policy up front: reparent children (move each one) or block deletion in the admin controller.
  • The bundle's name is misspelled everywhere. categorizer vs taxonomy vs taxon — config keys, service IDs, and folder names do not agree between versions. Grep the actual DependencyInjection extension before trusting any tutorial snippet.
  • No PHP 8 / Symfony 5+ compatibility. Typed properties, ArrayCollection return types, and the old ->get() container calls will break on a modern runtime. If you must run it, pin the runtime in composer.json (platform.php) and accept that you cannot upgrade the rest of the app independently.
  • No security patching. Archived means any CVE in this dependency chain stays open. Budget for migration rather than for hardening.
  • Extension point that actually works: override the entity classes in sylius_categorizer.classes.* and add your own fields (image, description, position) via your app's mapping. Subclassing the bundle's form types is the second option; overriding services in services.yml with decorates is the third. Anything else means forking — and a fork of an archived repo is a maintenance cost with no upstream.
  • Migration target, in order of preference: (1) SyliusTaxonomyBundle on the last Sylius version that supports it, (2) core Sylius\Component\Taxonomy if you are on modern Sylius, (3) if you are not actually on Sylius, gedmo/doctrine-extensions Tree + a small taxonomy entity of your own — you do not need this bundle to get nested categories, and the 200 lines it saves are not worth a deprecated dependency.
  • Write the data migration before the code migration. Taxonomy → Taxonomy is easy; Category → Taxon needs a slug/position/parent mapping script and a tree rebuild. Do it on a copy of production data and diff the rendered navigation before switching over.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
laravel2580/idehelpers
delatbabel/viewpages
anavel/gettext
muhamadrezaar/highcharts
delatbabel/keylists
frankkessler/salesforce-laravel-oauth2-rest
anavel/foundation
wdmtech/enviricons
eii/laravel-captcha
muka/shape-reader
tdt/json
refinery29/php-cs-fixer-config
hotmeteor/eco-env
mvaliolahi/hydrate
wearede/tbcpay-php
parsnick/steak
thibaud-dauce/mattermost-php
multilinguals/apollo-client
antaresbr/collection
kr0lik/phpstan-rules