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

Products Category Laravel Package

baks-dev/products-category

A PHP module for managing product categories, with cover image uploads, configuration assets, and Doctrine migration support. Install via Composer, run baks:assets:install, and manage database schema changes with Doctrine migrations.

View on GitHub
Deep Wiki
Context7

Getting Started

Read this first: it is not a Laravel package. Despite the framing, every command in the README is Symfony: bin/console, baks:assets:install, doctrine:migrations:*, and the internals are Doctrine ORM entities with Symfony bundle config. There is no service provider, no artisan, no vendor:publish, no Eloquent, and no Blade views. If the target app is Laravel, treat this as "a Doctrine-based domain module you must bridge," not a drop-in. If the app is Symfony, everything below is straightforward.

Minimal path to a running install (Symfony host):

composer require baks-dev/products-category
# register the bundle in config/bundles.php (check the package's own composer.json
# for the bundle class name or a recipe/manifest hint)
php bin/console baks:assets:install
sudo mkdir -p public/upload/product_category_cover && sudo chmod 773 public/upload/product_category_cover
php bin/console doctrine:migrations:diff
php bin/console doctrine:migrations:migrate
php bin/phpunit --group=products-category

Where to look in vendor/baks-dev/products-category/, in this order:

  1. src/Resources/config/ — service definitions, Doctrine mapping, routing. This is the real documentation.
  2. src/Entity/ — the category entity, the parent/child relation, and the cover value object. Read this before writing any query.
  3. src/Repository/ — what query methods already exist; do not hand-roll DQL until you've read them.
  4. src/Form/ and src/Controller/ — if present, they define the expected admin flow and validation.
  5. translations/ — expect Russian; check whether category names are translatable or just the UI strings.

First use case to validate end-to-end: create a root category with a child and a cover image through whatever admin surface exists, then render the tree on a product listing page. If all three work, the install is sound. If the cover writes to disk but 404s, it's a permissions/web-root problem, not a package problem.

Implementation Patterns

Treat the entities as the source of truth; extend around them, not through them. The package owns the schema. Your app should hold the foreign key to the category ID and join outward. Trying to subclass or re-map the entity into an Eloquent model will cost you more than it saves.

Tree access. For a category module the daily work is almost always read-heavy tree rendering:

// Preferred: a repository method the package already exposes.
$tree = $categoryRepository->findAll(); // then build in memory if the set is small
// Avoid per-node lazy loading of children — that is the N+1 you will hit first.

If the package doesn't ship a tree query, add one in your own repository/service that selects the whole table once and assembles the tree in PHP, or use a recursive CTE if you're on Postgres. Cache the assembled tree (Redis or framework cache) and invalidate on category create/update/delete via an event subscriber. Categories change rarely; the tree is read on nearly every page.

Cover uploads. The README's public/upload/product_category_cover with chmod 773 is a hardcoded local-filesystem assumption. Two things to do on day one:

  • Wrap or decorate whatever service handles the cover write so you can swap in object storage (S3) later without touching the entity.
  • Add a cleanup listener: deleting a category through the ORM will not delete the file on disk. Orphaned covers accumulate fast in staging.

Bridging into a Laravel app, if you must: run Doctrine alongside Eloquent with a separate connection config, expose the categories through a thin read API (a Laravel controller + a small Doctrine repository wrapper), and keep the write path inside the Symfony/Doctrine side or in an admin route group. Never let two ORMs own the same table. The realistic seam is: package owns product_category* tables, Laravel reads them through DB facade queries or a read-only repository, and Laravel's own migrations never touch those tables.

Extending behavior. Use decoration and event subscribers rather than edits:

# config/services.yaml — decorate, don't replace
App\ProductCategory\CachedCategoryRepository:
    decorates: 'BaksDev\Products\Category\Repository\...'
    arguments: ['@.inner']

Same for validation: if the package's form types are too thin (no max depth, no cycle guard), add a custom constraint and attach it at your controller/form layer instead of patching vendor code.

Testing. php bin/phpunit --group=products-category is the smoke test — run it after every composer update. Add your own fixtures for the edge cases the package almost certainly doesn't cover: circular parent references, very deep trees, cover files that fail to write.

Gotchas and Tips

  • Version 7.4.12 is not Laravel 7.4. It's the package's own semver. The README's php 8.4+ badge is the real constraint — this will not install on PHP 8.2/8.3 projects.
  • baks:assets:install copies files, not symlinks. Re-run it after every composer update, and add it to your deploy script, or you'll ship stale or missing assets on the second deploy.
  • Two migration systems. If the host app is Laravel, doctrine:migrations:diff and artisan migrate are separate ledgers. Decide which one owns which tables before you generate anything, or you'll get duplicate-table errors that are painful to unwind.
  • chmod 773 is unusual (group-writable, world-writable). In containers, do this in an entrypoint or mount the directory as a volume — building it into the image means it disappears on the next build. Also confirm your web server user is in that group; 773 without group membership still fails.
  • Review the generated diff before migrating. With zero dependents there's no crowd-sourced knowledge of naming collisions. Rename the package's tables if product_category or categories already exists in your schema.
  • Pin the exact version and commit composer.lock. Single maintainer, 0 stars, near-weekly releases with changelogs that read v7.4.12 / v7.4.12. There is no changelog signal to tell you what broke. Upgrade deliberately, on a branch, with the test group passing.
  • Fork-and-vendor is the sane contingency. MIT license, so if you hit an unfixed bug you can pull it in as a path repository instead of waiting. Budget for this rather than assuming upstream responsiveness.
  • Localization is on you. Russian docs plus likely Russian-only UI strings. If category names need to be multilingual, add a translation table keyed by category ID now — retrofitting after content exists is the expensive version.
  • Debugging on the Symfony side: bin/console debug:container | grep -i category to confirm services registered, bin/console cache:clear after any config change, and check config/bundles.php first when you get "service not found." On the Laravel side, a BindingResolutionException-style failure usually means the bundle isn't registered at all.
  • Template overrides: if the package ships Twig templates, override via templates/bundles/<BundleName>/... rather than editing vendor/.
  • Access control is not in the box. No RBAC per category, no ownership. Wire your own gate/policy in front of every mutating route, including cover upload — an unauthenticated upload endpoint with a 773 directory is an obvious abuse vector.
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.
andydefer/laravel-notification
adachsoft/cli-process-tester
jhaskell13/laraflow
sebastienheyd/boilerplate-media-manager
ccast/tagixo-primix
pretendtrue/laravel-builder
sawmainek/laravel-scout-tntsearch-driver
tomshaw/laravel-calendar-table
dibakar/laravel-ownership
steadrun/laravel-monitor
labyrinthe/connect-laravel
elmogy/layan
drewdan/sentinel-client
dskripchenko/laravel-llm
fatryst/nuonuo
stevenay/myanfont
gmostafa/php-graphql-client
xeviant/paystack
snowsoft/faker
meditationsteps/blogetc